📄 umc_h264_pack.cpp
字号:
bool is_left_avail = cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num>=0;
bool is_top_avail = cur_mb.CurrentBlockNeighbours.mb_above.mb_num>=0;
if (IS_B_SLICE(slice_type))
{
if(is_left_avail &&
(m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype != MBTYPE_SKIPPED))
left_c = 1;
if(is_top_avail &&
(m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype != MBTYPE_SKIPPED))
top_c = 1;
pBitstream->EncodeSingleBin_CABAC (left_c+top_c+ctxIdxOffset[MB_SKIP_FLAG_B], 1);
} else {
if(is_left_avail && (m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype != MBTYPE_SKIPPED))
left_c = 1;
if(is_top_avail && (m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype != MBTYPE_SKIPPED))
top_c = 1;
pBitstream->EncodeSingleBin_CABAC (left_c+top_c+ctxIdxOffset[MB_SKIP_FLAG_P_SP], 1);
}
/*m_cur_mb.LocalMacroblockInfo->cbp = m_pCurrentFrame->pMBData[uMB].cbp_bits =
m_pCurrentFrame->pMBData[uMB].uChromaNC =
m_pCurrentFrame->pMBData[uMB].uLumaAC = */
prev_dquant = 0;
}
cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_SKIPPED;
/* uCBP = 0;
cur_mb.LocalMacroblockInfo->cbp_luma = 0;
cur_mb.LocalMacroblockInfo->cbp_chroma = 0;
cur_mb.LocalMacroblockInfo->cbp = 0;
*/ } else {
// Code the number of skipped MBs (mb_skip_run) and reset the counter
if (m_PicParamSet.entropy_coding_mode)
{
Ipp32s left_c=0, top_c = 0;
bool is_left_avail = cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num>=0;
bool is_top_avail = cur_mb.CurrentBlockNeighbours.mb_above.mb_num>=0;
if (IS_B_SLICE(slice_type))
{
if(is_left_avail &&
(m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype != MBTYPE_SKIPPED))
left_c = 1;
if(is_top_avail &&
(m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype != MBTYPE_SKIPPED))
top_c = 1;
pBitstream->EncodeSingleBin_CABAC (left_c+top_c+ctxIdxOffset[MB_SKIP_FLAG_B], 0);
} else {
if(is_left_avail && (m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num].mbtype != MBTYPE_SKIPPED))
left_c = 1;
if(is_top_avail && (m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentBlockNeighbours.mb_above.mb_num].mbtype != MBTYPE_SKIPPED))
top_c = 1;
pBitstream->EncodeSingleBin_CABAC (left_c+top_c+ctxIdxOffset[MB_SKIP_FLAG_P_SP], 0);
}
if (m_SliceHeader.MbaffFrameFlag && ((curr_slice->m_CurMBAddr&1)==0 &&
cur_mb.GlobalMacroblockInfo->mbtype!=MBTYPE_SKIPPED ||
((curr_slice->m_CurMBAddr&1)==1 && cur_mb.GlobalMacroblockInfo->mbtype!=MBTYPE_SKIPPED &&
cur_mb.GlobalMacroblockPairInfo->mbtype==MBTYPE_SKIPPED)))
{
Ipp32s left_mb_field = cur_mb.CurrentMacroblockNeighbours.mb_A >= 0?
GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentMacroblockNeighbours.mb_A]):0;
Ipp32s top_mb_field= cur_mb.CurrentMacroblockNeighbours.mb_B >= 0?
GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[cur_mb.CurrentMacroblockNeighbours.mb_B]):0;
pBitstream->MBFieldModeInfo_CABAC(pGetMBFieldDecodingFlag(cur_mb.GlobalMacroblockInfo),
left_mb_field,top_mb_field);
}
} else {
pBitstream->PutVLCCode(curr_slice->m_uSkipRun);
if (m_SliceHeader.MbaffFrameFlag && ((curr_slice->m_CurMBAddr&1)==0 &&
cur_mb.GlobalMacroblockInfo->mbtype!=MBTYPE_SKIPPED ||
((curr_slice->m_CurMBAddr&1)==1 && cur_mb.GlobalMacroblockInfo->mbtype!=MBTYPE_SKIPPED &&
cur_mb.GlobalMacroblockPairInfo->mbtype==MBTYPE_SKIPPED)))
{
pBitstream->PutBit(pGetMBFieldDecodingFlag(cur_mb.GlobalMacroblockInfo));
}
}
curr_slice->m_uSkipRun = 0;
if (bIntra)
{
// Encode Advanced Intra Coding type
if (mb_type == MBTYPE_INTRA_16x16)
{
Encode_AIC_Type_16x16(curr_slice );
// Always Send Delta_QP for Intra 16x16 mode (needed for DC coeffs)
if (m_PicParamSet.entropy_coding_mode)
{
Ipp32s prevMB = (cur_mb.uMB > 0)? curr_slice->m_prev_dquant != 0 : 0;
pBitstream->DQuant_CABAC(cur_mb.LocalMacroblockInfo->QP - iLastXmittedQP, prevMB);
}
else
pBitstream->PutDQUANT(cur_mb.LocalMacroblockInfo->QP, iLastXmittedQP);
prev_dquant = cur_mb.LocalMacroblockInfo->QP - iLastXmittedQP;
iLastXmittedQP = cur_mb.LocalMacroblockInfo->QP;
}
else if (mb_type == MBTYPE_INTRA)
{
Encode_AIC_Type(curr_slice );
Encode_CBP(curr_slice);
if (uCBP > 0) { // Only Send Delta_QP if there are residuals to follow.
if (m_PicParamSet.entropy_coding_mode)
{
Ipp32s prevMB = (cur_mb.uMB > 0)? curr_slice->m_prev_dquant !=0: 0;
pBitstream->DQuant_CABAC(cur_mb.LocalMacroblockInfo->QP - iLastXmittedQP, prevMB);
}
else
pBitstream->PutDQUANT(cur_mb.LocalMacroblockInfo->QP, iLastXmittedQP);
prev_dquant = cur_mb.LocalMacroblockInfo->QP - iLastXmittedQP;
iLastXmittedQP = cur_mb.LocalMacroblockInfo->QP;
} else {
// Set QP correctly for Loop filter, since it is not transmitted, decoder will use
// m_iLastXmittedQP.
cur_mb.LocalMacroblockInfo->QP = iLastXmittedQP;
prev_dquant = 0;
}
}
else if (mb_type == MBTYPE_PCM) {
Encode_PCM_MB(curr_slice);
// Set QP correctly for Loop filter, since it is not transmitted, decoder will use
// m_iLastXmittedQP.
prev_dquant = 0;
cur_mb.LocalMacroblockInfo->QP = iLastXmittedQP;
} else {
}
} else { // INTRA
bool noSubMbPartSizeLessThan8x8Flag = true;
if ((mb_type == MBTYPE_INTER) || (mb_type == MBTYPE_SKIPPED) || (mb_type == MBTYPE_INTER_8x8) ||
(mb_type == MBTYPE_INTER_8x8_REF0) ||
(mb_type == MBTYPE_INTER_16x8) || (mb_type == MBTYPE_INTER_8x16)) {
// Encode MB type
noSubMbPartSizeLessThan8x8Flag = Encode_Inter_Type(curr_slice);
} else { // B Slice
noSubMbPartSizeLessThan8x8Flag = Encode_BiPred_Type(curr_slice);
}
// Encode MB Motion Vectors
Encode_MB_Vectors(curr_slice);
// Write CBP
Encode_CBP(curr_slice);
if (uCBP > 0) { // Only Send Delta_QP if there are residuals to follow.
if( m_PicParamSet.transform_8x8_mode_flag
// && pGetMB8x8TSPackFlag(cur_mb.GlobalMacroblockInfo)
&& (cur_mb.LocalMacroblockInfo->cbp & 0xf)
&& noSubMbPartSizeLessThan8x8Flag
&& (mb_type != MBTYPE_DIRECT || m_SeqParamSet.direct_8x8_inference_flag)
) {
Encode_transform_size_8x8_flag(curr_slice);
} else {
// For correct packing of the successor MB's
pSetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo, 0);
}
if (m_PicParamSet.entropy_coding_mode)
{
Ipp32s prevMB = (cur_mb.uMB > 0)? curr_slice->m_prev_dquant !=0: 0;
pBitstream->DQuant_CABAC(cur_mb.LocalMacroblockInfo->QP - iLastXmittedQP, prevMB);
}
else
pBitstream->PutDQUANT(cur_mb.LocalMacroblockInfo->QP, iLastXmittedQP);
prev_dquant = cur_mb.LocalMacroblockInfo->QP-iLastXmittedQP;
iLastXmittedQP = cur_mb.LocalMacroblockInfo->QP;
} else {
// Set QP correctly for Loop filter, since it is not transmitted, decoder will use
// m_iLastXmittedQP.
prev_dquant = 0;
cur_mb.LocalMacroblockInfo->QP = iLastXmittedQP;
// For correct packing of the successor MB's
pSetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo, 0);
}
} // INTER
} // not skipped
} // not INTRA slice
return ps;
} // Put_MBHeader
////////////////////////////////////////////////////////////////////////////////
//
// Init_VLC_LUTs
//
////////////////////////////////////////////////////////////////////////////////
template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::Init_VLC_LUTs()
{
Ipp32s i;
for (i = 0; i < 48; i++)
{
enc_cbp_intra[dec_cbp_intra[i]] = (Ipp8u)i;
enc_cbp_inter[dec_cbp_inter[i]] = (Ipp8u)i;
}
for (i = 0; i < 16; i++)
{
enc_cbp_intra_monochrome[dec_cbp_intra_monochrome[i]] = (Ipp8u)i;
enc_cbp_inter_monochrome[dec_cbp_inter_monochrome[i]] = (Ipp8u)i;
}
} // Init_VLC_LUTs
////////////////////////////////////////////////////////////////////////////////
//
// Encode_CBP
//
////////////////////////////////////////////////////////////////////////////////
template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::Encode_CBP(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice)
{
H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
CH264pBs<PixType,CoeffsType> *pBitstream = curr_slice->m_pbitstream;
if (m_PicParamSet.entropy_coding_mode)
{
Ipp32s nBNum;
Ipp32s nTop, nLeft;
Ipp32u left_c, top_c;
Ipp32u mask;
Ipp32s cbp = cur_mb.LocalMacroblockInfo->cbp;
for(Ipp32s i = 0; i < 2; i++)
{
for(Ipp32s j = 0; j < 2; j++)
{
if (!i)
{
// get number of above macroblock
nTop = cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
if (0 <= nTop)
{
nBNum = cur_mb.CurrentBlockNeighbours.mb_above.block_num;
top_c = (m_mbinfo.mbs[nTop].cbp &
(1 << (subblock_block_ss[nBNum + j * 2])) || m_pCurrentFrame->m_mbinfo.mbs[nTop].mbtype == MBTYPE_PCM) ? (0) : (1);
}
else
top_c = 0;
}
else
top_c = (cbp & (1 << j)) ? (0) : (1);
if (!j)
{
// get number of left macroblock
nLeft = cur_mb.CurrentBlockNeighbours.mbs_left[i * 2].mb_num;
if (0 <= nLeft)
{
nBNum = cur_mb.CurrentBlockNeighbours.mbs_left[i * 2].block_num;
left_c = (m_mbinfo.mbs[nLeft].cbp &
(1 << (subblock_block_ss[nBNum])) || m_pCurrentFrame->m_mbinfo.mbs[nLeft].mbtype == MBTYPE_PCM) ? (0) : (1);
}
else
left_c = 0;
}
else
left_c = (cbp & (1 << (2 * i))) ? (0) : (1);
mask = (1 << (2 * i + j));
Ipp32s ctxIdxInc = left_c + 2 * top_c;
pBitstream->EncodeSingleBin_CABAC(ctxIdxOffset[CODED_BLOCK_PATTERN_LUMA] + ctxIdxInc,(cbp&mask) != 0);
}
}
if(m_PicParamSet.chroma_format_idc) {
// CHROMA part
nTop = cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
if (0 <= nTop)
{
top_c = (m_mbinfo.mbs[nTop].cbp > 15 || m_pCurrentFrame->m_mbinfo.mbs[nTop].mbtype==MBTYPE_PCM) ? (1) : (0);
}
else
top_c = 0;
// obtain number of left macroblock
nLeft = cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num;
if (0 <= nLeft)
{
left_c = (m_mbinfo.mbs[nLeft].cbp > 15 || m_pCurrentFrame->m_mbinfo.mbs[nLeft].mbtype==MBTYPE_PCM) ? (1) : (0);
}
else
left_c = 0;
Ipp32s ctxIdxInc = left_c + 2 * top_c;
pBitstream->EncodeSingleBin_CABAC(ctxIdxOffset[CODED_BLOCK_PATTERN_CHROMA] + ctxIdxInc,cbp>15);
if (cbp>15)
{
if (top_c)
top_c = ((m_mbinfo.mbs[nTop].cbp >> 4) == 2 || m_pCurrentFrame->m_mbinfo.mbs[nTop].mbtype==MBTYPE_PCM) ? (1) : (0);
if (left_c)
left_c = ((m_mbinfo.mbs[nLeft].cbp >> 4) == 2 || m_pCurrentFrame->m_mbinfo.mbs[nLeft].mbtype==MBTYPE_PCM) ? (1) : (0);
ctxIdxInc = left_c + 2 * top_c;
pBitstream->EncodeSingleBin_CABAC(ctxIdxOffset[CODED_BLOCK_PATTERN_CHROMA] + ctxIdxInc+4,((cbp>>4) == 2));
}
}
} else {
Ipp32s length;
MBTypeValue mb_type = cur_mb.GlobalMacroblockInfo->mbtype;
Ipp32s cbp = cur_mb.LocalMacroblockInfo->cbp;
if (mb_type == MBTYPE_INTRA)
cbp = (m_PicParamSet.chroma_format_idc)? enc_cbp_intra[cbp]
: enc_cbp_intra_monochrome[cbp];
else
cbp = (m_PicParamSet.chroma_format_idc)? enc_cbp_inter[cbp]
: enc_cbp_inter_monochrome[cbp];
length = pBitstream->PutVLCCode(cbp);
}
} // Encode_CBP
////////////////////////////////////////////////////////////////////////////////
//
// Encode_Inter_Type
//
////////////////////////////////////////////////////////////////////////////////
template <class PixType, class CoeffsType>
bool H264CoreEncoder<PixType,CoeffsType>::Encode_Inter_Type(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice)
{
Ipp32s N, length;
EnumSliceType slice_type = curr_slice->m_slice_type;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -