📄 umc_h264_gen_enc.cpp
字号:
// fprintf(stderr," B: costP1=%d costP2=%d prevCost=%d | Intra %d %d\n", costP1, costP2, prevCostPP, eFrameSeq[i-1]->numIntraMBs, eFrameSeq[i-1]->numMBs);
if( costP1 > prevCostPP*2 || eFrameSeq[i-1]->numIntraMBs > ((180*eFrameSeq[i-1]->numMBs)>>9)){
eFrameSeq[i-1]->m_PicCodType = PREDPIC; //Set previous to P frame and break GOP
if( m_Analyse & ANALYSE_SCENECUT && eFrameSeq[i-1]->numIntraMBs > ((505*eFrameSeq[i-1]->numMBs)>>9) ){
eFrameSeq[i-1]->m_PicCodType = INTRAPIC;
//Convert to P
for( k = 1 ;k<i-1; k++ ){
eFrameSeq[k]->m_PicCodType = PREDPIC;
}
m_bMakeNextFrameIDR = true;
m_uIntraFrameInterval = m_info.key_frame_controls.interval + 1 + i - 1;
}
//Change last to B frame
eFrameSeq[profile_frequency]->m_PicCodType = BPREDPIC;
Ipp32s center = i==3 ? 0 : (i)>>1;
for( k=1; k<i-1; k++ ){
eFrameSeq[k]->m_RefPic = false;
if( k == center && m_info.treat_B_as_reference) eFrameSeq[k]->m_RefPic = true;
}
for( k = i-1, m=0; k<=profile_frequency; k++,m++ ){
eFrameSeq[m] = eFrameSeq[k];
}
for( ;m<=profile_frequency; m++ ) eFrameSeq[m] = NULL;
m_iProfileIndex = (i == profile_frequency) ? 2:i;
// fprintf(stderr," B break cent: %d i: %d idx: %d\n", center, i, m_iProfileIndex);
break;
}
prevCostPP = costP2;
}
// fprintf(stderr, " Bc: i=%d idx=%d\n",i,m_iProfileIndex);
if( i == profile_frequency+1 ){
eFrameSeq[0] = eFrameSeq[profile_frequency];
if( m_Analyse & ANALYSE_SCENECUT && eFrameSeq[0]->numIntraMBs > ((505*eFrameSeq[0]->numMBs)>>9) ){
eFrameSeq[0]->m_PicCodType = INTRAPIC;
//Convert to P
for( i = 1 ;i<=profile_frequency; i++ ){
eFrameSeq[i]->m_PicCodType = PREDPIC;
}
m_bMakeNextFrameIDR = true;
m_uIntraFrameInterval = m_info.key_frame_controls.interval + 1 + (profile_frequency + 1) - 1;
}
Ipp32s center = (profile_frequency+1)>>1;
for( i = 1 ;i<=profile_frequency; i++ ){
eFrameSeq[i]->m_RefPic = false;
if( i == center && m_info.treat_B_as_reference ) eFrameSeq[center]->m_RefPic = true;
eFrameSeq[i] = NULL;
}
}
}else{
// fprintf(stderr,"no b check\n");
//If P coded picture is better just set it and give encoder possibility to encode it
eFrameSeq[1]->m_PicCodType = PREDPIC;
//Change last to B frame
eFrameSeq[profile_frequency]->m_PicCodType = BPREDPIC;
//Move B frames array
for( i = 0; i<profile_frequency; i++ ){
eFrameSeq[i] = eFrameSeq[i+1];
}
//Set index to beginning of type array
m_iProfileIndex = 0; //To be next P frame
eFrameSeq[profile_frequency]=NULL;
if( m_Analyse & ANALYSE_SCENECUT && eFrameSeq[0]->numIntraMBs > ((505*eFrameSeq[0]->numMBs)>>9) ){
eFrameSeq[0]->m_PicCodType = INTRAPIC;
m_bMakeNextFrameIDR = true;
m_uIntraFrameInterval = m_info.key_frame_controls.interval + 1 + 1 - 1;
}
}
// fprintf(stderr, " POC P Index %d: %d\n", m_iProfileIndex, eFrameSeq[0]->PicOrderCnt(0,3));
//Check scenecut
}
}else{
eFrameSeq[frame_index]=m_pCurrentFrame;
/* m_PicClass = REFERENCE_PIC;
m_pReconstructFrame = m_pCurrentFrame;
End_Picture(); //Expand Plane
*/ }
/* fprintf(stderr, "POCs: ");
for( Ipp32s i = 0; i<=profile_frequency; i++ )
if( eFrameSeq[i] )
fprintf(stderr," %d", eFrameSeq[i]->PicOrderCnt(0,3));
else
fprintf(stderr," %s", "NULL");
fprintf(stderr,"\n");
*/
}
/* if( m_Analyse & ANALYSE_SCENECUT ){
if( eFrameSeq[i+1]->numIntraMBs > ((385*eFrameSeq[i+1]->numMBs)>>9) ){
Ipp32s s;
eFrameSeq[i+1]->m_PicCodType = INTRAPIC;
for(s=i; s>=0 && (eFrameSeq[s]->m_PicCodType != PREDPIC || eFrameSeq[s]->m_PicCodType != INTRAPIC); s-- )
eFrameSeq[i]->m_PicCodType = PREDPIC;
lref = i+1;
i++;
continue;
}else if( eFrameSeq[i]->numIntraMBs > ((385*eFrameSeq[i]->numMBs)>>9) ){
Ipp32s s;
eFrameSeq[i]->m_PicCodType = INTRAPIC;
for(s=i-1; s>=0 && (eFrameSeq[s]->m_PicCodType != PREDPIC || eFrameSeq[s]->m_PicCodType != INTRAPIC); s-- )
eFrameSeq[s]->m_PicCodType = PREDPIC;
lref = i;
continue;
}
}
*/
} else {
return UMC_ERR_INVALID_STREAM;
}
}else{
if (m_pLastFrame && m_pLastFrame->m_PicCodType == BPREDPIC )
{
m_pLastFrame->m_PicCodType = PREDPIC;
m_l1_cnt_to_start_B = 1;
}
}
if (UMC_OK == ps) {
m_pCurrentFrame = m_cpb.findOldestToEncode(&m_dpb, m_l1_cnt_to_start_B, m_info.treat_B_as_reference);
if (m_pCurrentFrame){
if (m_pCurrentFrame->m_bIsIDRPic) m_uFrameCounter = 0;
m_pCurrentFrame->setFrameNum(m_uFrameCounter);
// if( m_pCurrentFrame->m_PicCodType != BPREDPIC || m_info.treat_B_as_reference )
if( m_pCurrentFrame->m_PicCodType != BPREDPIC || m_pCurrentFrame->m_RefPic )
m_uFrameCounter++; // Increment for next time through
// perform noise reduction on the YUV12 video buffer
m_noisepf->DoFiltering(
m_pCurrentFrame->m_pYPlane,
m_pCurrentFrame->m_pUPlane,
m_pCurrentFrame->m_pVPlane,
m_pCurrentFrame->pitchPixels(),
m_pCurrentFrame->pitchPixels(),
m_pCurrentFrame->uWidth,
m_pCurrentFrame->uHeight);
MoveFromCPBToDPB();
notes &= ~H264_ECN_NO_FRAME;
} else {
cnotes |= H264_ECN_NO_FRAME;
return UMC_ERR_NOT_ENOUGH_DATA;
}
EnumPicCodType ePictureType = m_pCurrentFrame->m_PicCodType;
EnumPicClass ePic_Class;
// Determine the Pic_Class. Right now this depends on ePictureType, but that could change
// to permit disposable P frames, for example.
switch (ePictureType)
{
case INTRAPIC:
if (m_pCurrentFrame->m_bIsIDRPic || m_uFrames_Num == 0)
{
// Right now, only the first INTRAPIC in a sequence is an IDR Frame
ePic_Class = IDR_PIC;
m_l1_cnt_to_start_B = m_info.num_ref_to_start_code_B_slice;
} else {
ePic_Class = REFERENCE_PIC;
}
break;
case PREDPIC:
ePic_Class = REFERENCE_PIC;
break;
case BPREDPIC:
ePic_Class = m_info.treat_B_as_reference && m_pCurrentFrame->m_RefPic ? REFERENCE_PIC : DISPOSABLE_PIC;
break;
default:
// Unsupported Picture Type
VM_ASSERT(false);
ePic_Class = IDR_PIC;
break;
}
// ePictureType is a reference variable. It is updated by
// CompressFrame if the frame is internally forced to a key frame.
ps = CompressFrame(ePictureType, ePic_Class, dst);
dst->SetTime( m_pCurrentFrame->pts_start, m_pCurrentFrame->pts_end);
if (dst->GetDataSize() > 0){
if (ePictureType == INTRAPIC){ // Tell the environment we just generated a key frame
notes |= H264_ECN_KEY_FRAME;
}else if (ePictureType == BPREDPIC){ // Tell the environment we just generated a B frame
notes |= H264_ECN_B_FRAME;
}
}
if (ps == UMC_OK && dst->GetDataSize() == 0 && (flags & H264_ECF_LAST_FRAME)){
notes |= H264_ECN_NO_FRAME;
}
}
if(ps == UMC_OK) {
m_pCurrentFrame->setWasEncoded();
}
CleanDPB();
if(ps==UMC_OK) m_info.numEncodedFrames++;
return ps;
}
// This function frees the encoder's "dimension-dependent" allocations.
template <class PixType, class CoeffsType> Status H264CoreEncoder<PixType,CoeffsType>::End_Sequence()
{
Status ps = UMC_OK;
if (m_bBuffersAllocated)
{
Deallocate_Buffers();
m_bBuffersAllocated = false;
}
return ps;
}
/**********************************************************************
* EncoderH264 destructor.
**********************************************************************/
template <class PixType, class CoeffsType>
H264CoreEncoder<PixType, CoeffsType>::~H264CoreEncoder()
{
Close();
Free_Core_Memory();
// release the noise reduction prefilter
if( m_noisepf != NULL ) delete m_noisepf;
m_noisepf = NULL;
if (m_EmptyThreshold) {
ippsFree(m_EmptyThreshold);
m_EmptyThreshold = NULL;
}
if(m_DirectBSkipMEThres) {
ippsFree(m_DirectBSkipMEThres);
m_DirectBSkipMEThres = NULL;
}
if(m_PSkipMEThres) {
ippsFree(m_PSkipMEThres);
m_PSkipMEThres = NULL;
}
if(m_BestOf5EarlyExitThres) {
ippsFree(m_BestOf5EarlyExitThres);
m_BestOf5EarlyExitThres = NULL;
}
if (m_bBuffersAllocated)
{
Deallocate_Buffers();
m_bBuffersAllocated = false;
}
if( eFrameType != NULL ){
delete [] eFrameType;
eFrameType = NULL;
}
if( eFrameSeq != NULL ){
delete [] eFrameSeq;
eFrameSeq = NULL;
}
#ifdef H264_STAT
hstats.printStat();
#endif
}
// ==================================================================================
template <class PixType, class CoeffsType> void H264CoreEncoder<PixType,CoeffsType>::Deallocate_Buffers()
{
if (m_pbitstreams)
{
Ipp32s i;
for(i = 0; i < m_info.num_slices*((m_info.coding_type == 1) + 1); i++) { //TODO fix for PicAFF/AFRM
if (m_pbitstreams[i]) {
delete m_pbitstreams[i];
m_pbitstreams[i] = NULL;
}
}
H264_Free(m_pbitstreams);
m_pbitstreams = NULL;
}
m_bScratchBufferAllocated = false;
if (m_pAllocEncoderInst)
{
H264_Free(m_pAllocEncoderInst);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -