⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_core_enc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            memcpy(&cur_mb.mb[mbType].MBmvs[32],cur_mb.MVs[LIST_0+2]->MotionVectors,sizeof(H264MotionVector)*16);
            memcpy(&cur_mb.mb[mbType].MBmvs[48],cur_mb.MVs[LIST_1+2]->MotionVectors,sizeof(H264MotionVector)*16);
            memcpy(&cur_mb.mb[mbType].MBridx[0],cur_mb.RefIdxs[LIST_0]->RefIdxs,sizeof(T_RefIdx)*16);
            memcpy(&cur_mb.mb[mbType].MBridx[16],cur_mb.RefIdxs[LIST_1]->RefIdxs,sizeof(T_RefIdx)*16);

            if( mbType == MBTYPE_INTRA ){
                cur_mb.mb[mbType].ssd = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, cur_mb.mb4x4.reconstruct, 16 );
            }else if( mbType == MBTYPE_INTRA_16x16 ){
                cur_mb.mb[mbType].ssd = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, cur_mb.mb16x16.reconstruct, 16 );
            }else{
                cur_mb.mb[mbType].ssd = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, cur_mb.mbInter.reconstruct, 16 );
            }
            cur_mb.mb[mbType].ssd += lambda*mb_bits;
//            if( mbType == MBTYPE_INTRA ) cur_mb.mb[mbType].ssd += lambda*24*24; //handicap from JVT

//            printf("uMB=%d mb_bits=%d mbtype=%d sad/ssd 16x16=%d  %d    4x4=%d %d\n",uMB, mb_bits, mbType, cur_mb.mb[MBTYPE_INTRA_16x16].sad, cur_mb.mb[MBTYPE_INTRA_16x16].ssd, cur_mb.mb[MBTYPE_INTRA].sad, cur_mb.mb[MBTYPE_INTRA].ssd );
            if( m_PicParamSet.entropy_coding_mode ){
               cur_mb.mb[mbType].bitstream->CopyContext_CABAC(*pBitstream);
            }

//           if( xi == 3 && mbType==MBTYPE_INTRA ){
            if( xi == 3 ){
                //Save mb params
                pBitstream->SetState(pStartBits, uStartBitOffset);
                *pStartBits = (Ipp8u)((*pStartBits >> (8-uStartBitOffset)) << (8-uStartBitOffset));
                if( m_PicParamSet.entropy_coding_mode ){
                    pBitstream->RestoreContext_CABAC();
                }

                //curr_slice->m_iLastXmittedQP = iLastQP; // Restore the last xmitted QP
                curr_slice->m_uSkipRun = uSaved_Skip_Run;   // Restore the skip run
                cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
                if( mbType == MBTYPE_INTRA ){
                    cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
                    cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
                }else{
                    cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
                    cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uIntraCBP4x4;
                    memcpy( cur_mb.intra_types, cur_mb.mb[MBTYPE_INTRA].intra_types, 16);
                }
//            }else   if( slice_type != INTRASLICE && IS_INTRA_MBTYPE(mbType) && cur_mb.mb[MBTYPE_INTER].sad < bestSAD*1.4 ){
            }else if( slice_type != INTRASLICE && xi == 2 ){
                pBitstream->SetState(pStartBits, uStartBitOffset);
                *pStartBits = (Ipp8u)((*pStartBits >> (8-uStartBitOffset)) << (8-uStartBitOffset));
                if( m_PicParamSet.entropy_coding_mode ){
                    pBitstream->RestoreContext_CABAC();
                }
                cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
                cur_mb.GlobalMacroblockInfo->mbtype = curr_slice->m_InterMBType;
                cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uInterCBP4x4;
                curr_slice->m_uSkipRun = uSaved_Skip_Run;   // Restore the skip run
                cur_mb.LocalMacroblockInfo->intra_chroma_mode = 0;

                memcpy(cur_mb.MVs[LIST_0]->MotionVectors,&MBmvs[0],sizeof(H264MotionVector)*16);
                memcpy(cur_mb.MVs[LIST_1]->MotionVectors,&MBmvs[16],sizeof(H264MotionVector)*16);
                memcpy(cur_mb.MVs[LIST_0+2]->MotionVectors,&MBmvs[32],sizeof(H264MotionVector)*16);
                memcpy(cur_mb.MVs[LIST_1+2]->MotionVectors,&MBmvs[48],sizeof(H264MotionVector)*16);
                memcpy(cur_mb.RefIdxs[LIST_0]->RefIdxs,&MBridx[0],sizeof(T_RefIdx)*16);
                memcpy(cur_mb.RefIdxs[LIST_1]->RefIdxs,&MBridx[16],sizeof(T_RefIdx)*16);
            }else  break;

            xi--;
            }while(xi>0);


            // **Take the best RD optimized
            // Take with less bits
            if( xi != 3 ){

//            printf("uMB=%d %f mb_bits= I16: %d  I4: %d sad/ssd I16=%d  %d    I4=%d %d   err: I16=%f  I4=%f\n",uMB,lambda,cur_mb.mb[MBTYPE_INTRA_16x16].bits,cur_mb.mb[MBTYPE_INTRA].bits , cur_mb.mb[MBTYPE_INTRA_16x16].sad, cur_mb.mb[MBTYPE_INTRA_16x16].ssd, cur_mb.mb[MBTYPE_INTRA].sad, cur_mb.mb[MBTYPE_INTRA].ssd, err2, err1 );
/*               if( cur_mb.mb[MBTYPE_INTER].bits < cur_mb.mb[MBTYPE_INTRA_16x16].bits && cur_mb.mb[MBTYPE_INTER].bits < cur_mb.mb[MBTYPE_INTRA].bits ){
                    mbType = curr_slice->m_InterMBType;
                }else  if( cur_mb.mb[MBTYPE_INTRA].bits < cur_mb.mb[MBTYPE_INTRA_16x16].bits ) {
                    mbType = MBTYPE_INTRA;
                }  else {
                    mbType = MBTYPE_INTRA_16x16;
                }
*/
                if( slice_type != INTRASLICE && cur_mb.mb[MBTYPE_INTER].ssd < cur_mb.mb[MBTYPE_INTRA_16x16].ssd && cur_mb.mb[MBTYPE_INTER].ssd < cur_mb.mb[MBTYPE_INTRA].ssd ){
                    mbType = curr_slice->m_InterMBType;
                }else  if( cur_mb.mb[MBTYPE_INTRA].ssd < cur_mb.mb[MBTYPE_INTRA_16x16].ssd ) {
                    mbType = MBTYPE_INTRA;
                }  else {
                    mbType = MBTYPE_INTRA_16x16;
                }

//                printf(" min type = %d %d %d strm_size=%d  %x\n", mbType, cur_mb.mb[MBTYPE_INTRA].bits, cur_mb.mb[MBTYPE_INTRA_16x16].bits, cur_mb.mb[mbType].stream_size,pStartBits+cur_mb.mb[mbType].stream_size-1);
                if( mbType != cur_mb.GlobalMacroblockInfo->mbtype ){
                    cur_mb.GlobalMacroblockInfo->mbtype = mbType;
                    if( !IS_INTRA_MBTYPE(mbType) ) mbType = MBTYPE_INTER;
                    curr_slice->m_uSkipRun = cur_mb.mb[mbType].skip_run;
                    memcpy(cur_mb.LocalMacroblockInfo,&(cur_mb.mb[mbType].locInfo),sizeof(H264MacroblockLocalInfo));
                    memcpy(cur_mb.GlobalMacroblockInfo,&(cur_mb.mb[mbType].globInfo),sizeof(H264MacroblockGlobalInfo));
                    memcpy(cur_mb.MacroblockCoeffsInfo, &(cur_mb.mb[mbType].coeffInfo),sizeof(H264MacroblockCoeffsInfo));
                    memcpy( pStartBits, cur_mb.mb[mbType].stream, cur_mb.mb[mbType].stream_size);
                    Ipp8u* pEndBits = pStartBits+cur_mb.mb[mbType].stream_size-1;
                    Ipp32u uEndBitOffset = cur_mb.mb[mbType].stream_offset;
                    *pEndBits = (Ipp8u)((*pEndBits >> (8-uEndBitOffset)) << (8-uEndBitOffset));
                    pBitstream->SetState( pEndBits, uEndBitOffset);
                    memcpy( cur_mb.intra_types, cur_mb.mb[mbType].intra_types, 16);
                    if( m_PicParamSet.entropy_coding_mode ){
                      pBitstream->CopyContext_CABAC(*(cur_mb.mb[mbType].bitstream));
                    }
                    mb_bits = cur_mb.mb[mbType].bits;
                    memcpy(cur_mb.MVs[LIST_0]->MotionVectors,&cur_mb.mb[mbType].MBmvs[0],sizeof(H264MotionVector)*16);
                    memcpy(cur_mb.MVs[LIST_1]->MotionVectors,&cur_mb.mb[mbType].MBmvs[16],sizeof(H264MotionVector)*16);
                    memcpy(cur_mb.MVs[LIST_0+2]->MotionVectors,&cur_mb.mb[mbType].MBmvs[32],sizeof(H264MotionVector)*16);
                    memcpy(cur_mb.MVs[LIST_1+2]->MotionVectors,&cur_mb.mb[mbType].MBmvs[48],sizeof(H264MotionVector)*16);
                    memcpy(cur_mb.RefIdxs[LIST_0]->RefIdxs,&cur_mb.mb[mbType].MBridx[0],sizeof(T_RefIdx)*16);
                    memcpy(cur_mb.RefIdxs[LIST_1]->RefIdxs,&cur_mb.mb[mbType].MBridx[16],sizeof(T_RefIdx)*16);
               }
            }
            mbType = cur_mb.GlobalMacroblockInfo->mbtype;

            //copy reconstruct
            if( IS_INTRA_MBTYPE(mbType) ){
                if( mbType == MBTYPE_INTRA ){
                    if( pGetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo) ){
                        ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mb8x8.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
                    }else{
                        ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mb4x4.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
                    }
                }else{
                    ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mb16x16.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
                }
                ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaIntra.reconstruct, 16*sizeof(PixType),
                    (Ipp8u*)m_pCurrentFrame->m_pUPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
                    cur_mb.mbPitchPixels*sizeof(PixType));
                ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaIntra.reconstruct+8), 16*sizeof(PixType),
                    (Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
                    cur_mb.mbPitchPixels*sizeof(PixType));
                if( m_info.chroma_format_idc == 2 ){
                    ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaIntra.reconstruct+8*16, 16*sizeof(PixType),
                        (Ipp8u*)m_pCurrentFrame->m_pYPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
                        cur_mb.mbPitchPixels*sizeof(PixType));
                    ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaIntra.reconstruct+8+8*16), 16*sizeof(PixType),
                        (Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
                        cur_mb.mbPitchPixels*sizeof(PixType));
                }
            }else{
                ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mbInter.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
                ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaInter.reconstruct, 16*sizeof(PixType),
                    (Ipp8u*)m_pCurrentFrame->m_pUPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
                    cur_mb.mbPitchPixels*sizeof(PixType));
                ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaInter.reconstruct+8), 16*sizeof(PixType),
                    (Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
                    cur_mb.mbPitchPixels*sizeof(PixType));
                if( m_info.chroma_format_idc == 2 ){
                    ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaInter.reconstruct+8*16, 16*sizeof(PixType),
                        (Ipp8u*)m_pCurrentFrame->m_pYPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
                        cur_mb.mbPitchPixels*sizeof(PixType));
                    ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaInter.reconstruct+8+8*16), 16*sizeof(PixType),
                        (Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
                        cur_mb.mbPitchPixels*sizeof(PixType));
                }
            }
#endif /* H264_RD_OPT */


//            printf("%d;%d\n", uMB, mb_bits);

//            mbtype_stat[cur_mb.GlobalMacroblockInfo->mbtype]++;
#ifdef H264_STAT
            hstats.addMB( slice_type, curr_slice->m_cur_mb.GlobalMacroblockInfo->mbtype, curr_slice->m_cur_mb.GlobalMacroblockInfo->sbtype, pGetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo), mb_bits);
#endif

            // Should not recompress for CABAC
            if (!m_PicParamSet.entropy_coding_mode && (mb_bits > MB_RECODE_THRESH) && m_info.rate_controls.method == H264_RCM_QUANT)
            {
                // OK, this is bad, it's not compressing very much!!!
                // TBD: Tune this decision to QP...  Higher QPs will progressively trash PSNR,
                // so if they are still using a lot of bits, then PCM coding is extra attractive.

                // We're going to be recoding this MB, so reset some stuff.
                pBitstream->SetState(pStartBits, uStartBitOffset);    // Reset the BS
                // Zero out unused bits in buffer before OR in next op
                // This removes dependency on buffer being zeroed out.
                *pStartBits = (Ipp8u)((*pStartBits >> (8-uStartBitOffset)) << (8-uStartBitOffset));

                curr_slice->m_iLastXmittedQP = iLastQP; // Restore the last xmitted QP
                curr_slice->m_uSkipRun = uSaved_Skip_Run;   // Restore the skip run

                // If the QP has only been adjusted up 0 or 1 times, and QP != 51
                if (((cur_mb.LocalMacroblockInfo->QP -
                      m_PicParamSet.pic_init_qp + curr_slice->m_slice_qp_delta) < 2) &&
                    (cur_mb.LocalMacroblockInfo->QP != 51))
                {
                    // Quantize more and try again!
                    cur_mb.LocalMacroblockInfo->QP++;
                    uRecompressMB = 1;
                } else {
                    // Code this block as a PCM MB next time around.
                    uUsePCM = 1;
                    uRecompressMB = 0;
                    // Reset the MB QP value to the "last transmitted QP"
                    // Since no DeltaQP will be transmitted for a PCM block
                    // This is important, since the Loop Filter will use the
                    // this value in filtering this MB
                    cur_mb.LocalMacroblockInfo->QP = curr_slice->m_iLastXmittedQP;
                }

            } else
                uRecompressMB = 0;
        } while (uRecompressMB);        // End of the MB recompression loop.

        // If the above MB encoding failed to efficiently predict the MB, then
        // code it as raw pixels using the mb_type = PCM
        if (uUsePCM)
        {
            cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
            cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;

            memset(cur_mb.MacroblockCoeffsInfo->numCoeff, 16, 24);

            Ipp32s  k;     // block number, 0 to 15
            for (k = 0; k < 16; k++) {
                cur_mb.intra_types[k] = 2;
                cur_mb.MVs[LIST_0]->MotionVectors[k] = null_mv;
                cur_mb.MVs[LIST_1]->MotionVectors[k] = null_mv;
                cur_mb.RefIdxs[LIST_0]->RefIdxs[k] = -1;
                cur_mb.RefIdxs[LIST_1]->RefIdxs[k] = -1;
            }

            Put_MBHeader(curr_slice);   // PCM values are written in the MB Header.
        }

/*
        if (!m_pbitstream->CheckBsLimit())
        {
            // If the buffer is filled, break out of encoding loop
            // Encoder::CompressFrame will write a blank frame to the bitstream.
            goto done;
        }*/

        if (m_PicParamSet.entropy_coding_mode){
          //  pBitstream->EncodeFinalSingleBin_CABAC( (uMB==uFirstMB + uNumMBs - 1) || (m_pCurrentFrame->m_mbinfo.mbs[uMB + 1].slice_id != slice_num) );
            ReconstuctCBP(&cur_mb);
        }
    }   // loop over MBs

#ifndef NO_FINAL_SKIP_RUN
    // Check if the last N MBs were skip blocks.  If so, write a final skip run
    // NOTE!  This is _optional_.  The encoder is not required to do this, and
    // decoders need to be able to handle it either way.

    // Even though skip runs are not written for I Slices, m_uSkipRun can only be
    // non-zero for non-I slices, so the following test is OK.
    if (curr_slice->m_uSkipRun !=0 && m_info.entropy_coding_mode==0) {
        pBitstream->PutVLCCode(curr_slice->m_uSkipRun);
    }

#endif // NO_FINAL_SKIP_RUN

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -