📄 umc_h264_pack.cpp
字号:
//// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2004 - 2005 Intel Corporation. All Rights Reserved.//#include "umc_h264_video_encoder.h"#include "umc_h264_tables.h"#include "vm_debug.h"using namespace UMC_H264_ENCODER;namespace UMC{// Encoder CBP tables, created from decoder CBP tablesstatic Ipp8u enc_cbp_intra[64];static Ipp8u enc_cbp_inter[64];#define Multiply_DMV(m_mv_start,min_x,max_x,step_x,min_y,max_y,step_y,mv) \if(m_PicParamSet.entropy_coding_mode) \{ \ T_ECORE_BIGMV *tmv=m_mv_start; \ int i,j; \ /*printf("\nMB:%d vec%d,%d\n",uMB,mv.iMVx,mv.iMVy);*/\ for (i=min_y;i<max_y;i+=step_y) \ for (j=min_x;j<max_x;j+=step_x) \ { \ int index=i*uWidthIn4x4Blocks+j; \ /*printf("%d ",index);*/ \ tmv[index].iMVx=mv.iMVx; \ tmv[index].iMVy=mv.iMVy; \ } \}//////////////////////////////////////////////////////////////////////////////////// PutVLC_MBHeader//// Writes one MB header to the bitstream.//////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::ReconstuctCBP(Ipp32u uMB){ const Ipp8u ICBPTAB[6] = {0,16,32,15,31,47}; if (m_pCurrentFrame->pMBData[uMB].uMBType == MBTYPE_INTRA_16x16) { int N = CALC_16x16_INTRA_MB_TYPE(INTRASLICE, m_pCurrentFrame->pAIMode[m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex], m_pCurrentFrame->pMBData[uMB].uChromaNC, m_pCurrentFrame->pMBData[uMB].uLumaAC)-1; m_pCurrentFrame->pMBData[uMB].uCBP = ICBPTAB[N>>2]; }}Status H264VideoEncoder::PutVLC_MBHeader(Ipp32u uMB){ Status ps = UMC_OK; bool bIntra; MB_Type uMBType; Ipp8u uCBP=m_pCurrentFrame->pMBData[uMB].uCBP; Ipp32u uCBP4x4; uMBType = m_pCurrentFrame->pMBData[uMB].uMBType; m_pCurrentFrame->pMBData[uMB].uMBSkipFlag = 0; T_ECORE_BIGMV NullMV={0,0}; Multiply_DMV(&m_pCurrentFrame->pDMVL0[m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex],0,4,1,0,4,1,NullMV); Multiply_DMV(&m_pCurrentFrame->pDMVL1[m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex],0,4,1,0,4,1,NullMV); // set CBP for the MB based upon coded block bits. uCBP4x4 = m_pCurrentFrame->pMBData[uMB].uCBP4x4; if ((uMBType != MBTYPE_INTRA_16x16) && (uMBType != MBTYPE_PCM)) { uCBP = (Ipp8u) ((((uCBP4x4 >> 0) | (uCBP4x4 >> 1) | (uCBP4x4 >> 2) | (uCBP4x4 >> 3)) & 1) | // 8x8 - 0 (((uCBP4x4 >> 3) | (uCBP4x4 >> 4) | (uCBP4x4 >> 5) | (uCBP4x4 >> 6)) & 2) | // 8x8 - 1 (((uCBP4x4 >> 6) | (uCBP4x4 >> 7) | (uCBP4x4 >> 8) | (uCBP4x4 >> 9)) & 4) | // 8x8 - 2 (((uCBP4x4 >> 9) | (uCBP4x4 >> 10) | (uCBP4x4 >> 11) | (uCBP4x4 >> 12)) & 8)); // 8x8 - 3 uCBP += (m_pCurrentFrame->pMBData[uMB].uChromaNC << 4); m_pCurrentFrame->pMBData[uMB].uCBP = uCBP; } else { m_pCurrentFrame->pMBData[uMB].uCBP = 0; } // Shift the CBP to match the decoder in the deblocking filter... m_pCurrentFrame->pMBData[uMB].uCBP4x4 = ((uCBP4x4 & 0xffff)<<1); bIntra = IS_INTRA_MBTYPE(uMBType); if (m_SliceHeader.slice_type == INTRASLICE) { // INTRA slice // Encode Advanced Intra Coding type if (uMBType == MBTYPE_INTRA_16x16) { Encode_AIC_Type_16x16(uMB); // Always Send Delta_QP for Intra 16x16 mode (needed for DC coeffs) if (m_PicParamSet.entropy_coding_mode) { /*int left_c = Get_Left_Value(uMB,m_pCurrentFrame->pMBData[uMB-1].uMBQPDelta!=0,0); m_pbitstream->DQuant_CABAC(m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP, left_c );*/ int prevMB = (uMB > 0)? m_pCurrentFrame->pMBData[uMB-1].uMBQPDelta!=0: 0; m_pbitstream->DQuant_CABAC(m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP, prevMB); } else m_pbitstream->PutDQUANT(m_pCurrentFrame->pMBData[uMB].uMBQP, m_uLastXmittedQP); m_pCurrentFrame->pMBData[uMB].uMBQPDelta = m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP; m_uLastXmittedQP = m_pCurrentFrame->pMBData[uMB].uMBQP; } else if (uMBType == MBTYPE_INTRA) { Encode_AIC_Type(uMB); Encode_CBP(uMB); if (uCBP > 0) { // Only Send Delta_QP if there are residuals to follow. if (m_PicParamSet.entropy_coding_mode) { /*int left_c = Get_Left_Value(uMB,m_pCurrentFrame->pMBData[uMB-1].uMBQPDelta!=0,0); m_pbitstream->DQuant_CABAC(m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP, left_c );*/ int prevMB = (uMB > 0)? m_pCurrentFrame->pMBData[uMB-1].uMBQPDelta!=0: 0; m_pbitstream->DQuant_CABAC(m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP, prevMB); } else m_pbitstream->PutDQUANT(m_pCurrentFrame->pMBData[uMB].uMBQP, m_uLastXmittedQP); m_pCurrentFrame->pMBData[uMB].uMBQPDelta = m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP; m_uLastXmittedQP = m_pCurrentFrame->pMBData[uMB].uMBQP; } else { // Set QP correctly for Loop filter, since it is not transmitted, decoder will use // m_uLastXmittedQP. m_pCurrentFrame->pMBData[uMB].uMBQP = m_uLastXmittedQP; m_pCurrentFrame->pMBData[uMB].uMBQPDelta = 0; } } else if (uMBType == MBTYPE_PCM) { Encode_PCM_MB(uMB); // Set QP correctly for Loop filter, since it is not transmitted, decoder will use // m_uLastXmittedQP. m_pCurrentFrame->pMBData[uMB].uMBQP = m_uLastXmittedQP; m_pCurrentFrame->pMBData[uMB].uMBQPDelta = 0; } else { } } else { //if (!IS_INTRA_MBTYPE(m_pCurrentFrame->pMBData[uMB].uMBType)) // m_pCurrentFrame->pMBData[uMB].uChromaType = 0; // Non-INTRA // COD // check for skipped MB if ((uCBP == 0) && ((MBTYPE_DIRECT == uMBType) || ((MBTYPE_INTER == uMBType) && Skip_MV_Predicted(uMB, NULL)))) { // Skipped m_uSkipRun++; // Set QP correctly for Loop filter, since it is not transmitted, decoder will use // m_uLastXmittedQP. m_pCurrentFrame->pMBData[uMB].uMBQPDelta = 0; m_pCurrentFrame->pMBData[uMB].uMBQP = m_uLastXmittedQP; m_pCurrentFrame->pMBData[uMB].uMBSkipFlag = 1; if (m_PicParamSet.entropy_coding_mode) { T_EncodeMBData *left_mb,*top_mb,*cur_mb; cur_mb=&m_pCurrentFrame->pMBData[uMB]; left_mb= Get_Left_Value(uMB,&m_pCurrentFrame->pMBData[uMB-1],NULL); top_mb= Get_Top_Value(uMB,&m_pCurrentFrame->pMBData[uMB-uWidthInMBs],NULL); m_pbitstream->MBSkipFlagInfo_CABAC(m_SliceHeader.slice_type,cur_mb,left_mb,top_mb,1); //if (m_pCurrentFrame->pMBData[uMB].uMBType !=MBTYPE_DIRECT) // m_pCurrentFrame->pMBData[uMB].uMBType = MBTYPE_SKIPPED; /*m_pCurrentFrame->pMBData[uMB].uCBP = m_pCurrentFrame->pMBData[uMB].cbp_bits = m_pCurrentFrame->pMBData[uMB].uChromaNC = m_pCurrentFrame->pMBData[uMB].uLumaAC = m_pCurrentFrame->pMBData[uMB].DC16x16Coeffs = */ m_pCurrentFrame->pMBData[uMB].uMBQPDelta = 0; } } else { // Code the number of skipped MBs (mb_skip_run) and reset the counter if (m_PicParamSet.entropy_coding_mode) { T_EncodeMBData *left_mb,*top_mb,*cur_mb; cur_mb=&m_pCurrentFrame->pMBData[uMB]; left_mb= Get_Left_Value(uMB,&m_pCurrentFrame->pMBData[uMB-1],NULL); top_mb= Get_Top_Value(uMB,&m_pCurrentFrame->pMBData[uMB-uWidthInMBs],NULL); m_pbitstream->MBSkipFlagInfo_CABAC(m_SliceHeader.slice_type,cur_mb,left_mb,top_mb,0); } else { m_pbitstream->PutVLCCode(m_uSkipRun); } m_uSkipRun = 0; if (bIntra) { // Encode Advanced Intra Coding type if (uMBType == MBTYPE_INTRA_16x16) { Encode_AIC_Type_16x16(uMB); // Always Send Delta_QP for Intra 16x16 mode (needed for DC coeffs) if (m_PicParamSet.entropy_coding_mode) { int prevMB = (uMB > 0)? m_pCurrentFrame->pMBData[uMB-1].uMBQPDelta!=0: 0; m_pbitstream->DQuant_CABAC(m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP, prevMB); } else m_pbitstream->PutDQUANT(m_pCurrentFrame->pMBData[uMB].uMBQP, m_uLastXmittedQP); m_pCurrentFrame->pMBData[uMB].uMBQPDelta = m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP; m_uLastXmittedQP = m_pCurrentFrame->pMBData[uMB].uMBQP; } else if (uMBType == MBTYPE_INTRA) { Encode_AIC_Type(uMB); Encode_CBP(uMB); if (uCBP > 0) { // Only Send Delta_QP if there are residuals to follow. if (m_PicParamSet.entropy_coding_mode) { int prevMB = (uMB > 0)? m_pCurrentFrame->pMBData[uMB-1].uMBQPDelta!=0: 0; m_pbitstream->DQuant_CABAC(m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP, prevMB); } else m_pbitstream->PutDQUANT(m_pCurrentFrame->pMBData[uMB].uMBQP, m_uLastXmittedQP); m_pCurrentFrame->pMBData[uMB].uMBQPDelta = m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP; m_uLastXmittedQP = m_pCurrentFrame->pMBData[uMB].uMBQP; } else { // Set QP correctly for Loop filter, since it is not transmitted, decoder will use // m_uLastXmittedQP. m_pCurrentFrame->pMBData[uMB].uMBQP = m_uLastXmittedQP; m_pCurrentFrame->pMBData[uMB].uMBQPDelta = 0; } } else if (uMBType == MBTYPE_PCM) { Encode_PCM_MB(uMB); // Set QP correctly for Loop filter, since it is not transmitted, decoder will use // m_uLastXmittedQP. m_pCurrentFrame->pMBData[uMB].uMBQPDelta = 0; m_pCurrentFrame->pMBData[uMB].uMBQP = m_uLastXmittedQP; } else { } } // INTRA else { if ((uMBType == MBTYPE_INTER) || (uMBType == MBTYPE_INTER_8x8) || (uMBType == MBTYPE_INTER_8x8_REF0) || (uMBType == MBTYPE_INTER_16x8) || (uMBType == MBTYPE_INTER_8x16)) { // Encode MB type Encode_Inter_Type(uMB); } else { // B Slice Encode_BiPred_Type(uMB); } // Encode MB Motion Vectors Encode_MB_Vectors(uMB); // Write CBP Encode_CBP(uMB); if (uCBP > 0) { // Only Send Delta_QP if there are residuals to follow. if (m_PicParamSet.entropy_coding_mode) { int prevMB = (uMB > 0)? m_pCurrentFrame->pMBData[uMB-1].uMBQPDelta!=0: 0; m_pbitstream->DQuant_CABAC(m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP, prevMB); } else m_pbitstream->PutDQUANT(m_pCurrentFrame->pMBData[uMB].uMBQP, m_uLastXmittedQP); m_pCurrentFrame->pMBData[uMB].uMBQPDelta = m_pCurrentFrame->pMBData[uMB].uMBQP-m_uLastXmittedQP; m_uLastXmittedQP = m_pCurrentFrame->pMBData[uMB].uMBQP; } else { // Set QP correctly for Loop filter, since it is not transmitted, decoder will use // m_uLastXmittedQP. m_pCurrentFrame->pMBData[uMB].uMBQPDelta = 0; m_pCurrentFrame->pMBData[uMB].uMBQP = m_uLastXmittedQP; } } // INTER } // not skipped } // not INTRA slice return ps;} // PutVLC_MBHeader//////////////////////////////////////////////////////////////////////////////////// Init_VLC_LUTs//////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Init_VLC_LUTs(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -