📄 umc_h264_segment_decoder_decode_mb_types_cabac.cpp
字号:
// see subclause 9.3.3.1.1.8 of the h264 standard
// get left macrobock condition
nNum = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num;
if (0 <= nNum)
{
if (IS_INTRA_MBTYPE(m_gmbinfo->mbs[nNum].mbtype) && m_mbinfo.mbs[nNum].IntraTypes.intra_chroma_mode)
condTermFlagA = 1;
}
// get above macroblock condition
nNum = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
if (0 <= nNum)
{
if (IS_INTRA_MBTYPE(m_gmbinfo->mbs[nNum].mbtype) && m_mbinfo.mbs[nNum].IntraTypes.intra_chroma_mode)
condTermFlagB = 1;
}
ctxIdxInc = condTermFlagA + condTermFlagB;
}
// decode chroma mode
{
Ipp32u nVal;
nVal = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[INTRA_CHROMA_PRED_MODE] +
ctxIdxInc);
if (nVal)
{
nVal = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[INTRA_CHROMA_PRED_MODE] +
3);
if (nVal)
{
nVal = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[INTRA_CHROMA_PRED_MODE] +
3) + 1;
}
nVal += 1;
}
m_cur_mb.LocalMacroblockInfo->IntraTypes.intra_chroma_mode = (Ipp8u) nVal;
}
} // void H264SegmentDecoder::DecodeIntraPredChromaMode_CABAC(void)
Ipp32u H264SegmentDecoder::DecodeMBSkipFlag_CABAC(Ipp32s ctxIdx)
{
Ipp32s mbAddrA = -1, mbAddrB = -1;
Ipp32s iFirstMB = m_pSlice->GetFirstMBNumber();
// obtain neigbouring blocks
if (0 == m_pSliceHeader->MbaffFrameFlag)
{
// obtain left macroblock addres
if ((m_CurMB_X) &&
(iFirstMB <= m_CurMBAddr - 1))
mbAddrA = m_CurMBAddr - 1;
// obtain above macroblock addres
if ((m_CurMB_Y) &&
(iFirstMB <= m_CurMBAddr - mb_width))
mbAddrB = m_CurMBAddr - mb_width;
}
else
{
Ipp32s iCurrentField = 0;
//
// determine type of current macroblock
// See subclause 7.4.4 of H.264 standard
//
if (0 == (m_CurMBAddr & 1))
{
Ipp32s mbAddr;
// try to get left MB pair info
mbAddr = m_CurMBAddr - 2;
if ((iFirstMB <= mbAddr) &&
(m_CurMB_X))
{
iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddr]);
}
else
{
// get above MB pair info
mbAddr = m_CurMBAddr - mb_width * 2;
if ((iFirstMB <= mbAddr) &&
(m_CurMB_Y))
iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[mbAddr]);
}
pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,
m_cur_mb.GlobalMacroblockPairInfo,
iCurrentField);
}
else
iCurrentField = GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_CurMBAddr]);
//
// calculate neighbouring blocks
// See table 6-4 of H.264 standard
//
// top MB from macroblock pair
if (0 == (m_CurMBAddr & 1))
{
// determine A macroblock
if ((m_CurMB_X) &&
(iFirstMB <= m_CurMBAddr - 2))
mbAddrA = m_CurMBAddr - 2;
// determine B macroblock
if ((m_CurMB_Y) &&
(iFirstMB <= m_CurMBAddr - mb_width * 2))
{
if (iCurrentField &
GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_CurMBAddr - mb_width * 2]))
mbAddrB = m_CurMBAddr - mb_width * 2;
else
mbAddrB = m_CurMBAddr - mb_width * 2 + 1;
}
}
// bottom MB from macroblock pair
else
{
// determine A macroblock
if ((m_CurMB_X) &&
(iFirstMB <= m_CurMBAddr - 2))
{
if (iCurrentField == GetMBFieldDecodingFlag(m_gmbinfo->mbs[m_CurMBAddr - 2]))
mbAddrA = m_CurMBAddr - 2;
else
mbAddrA = m_CurMBAddr - 3;
}
// determine B macroblock
if (0 == iCurrentField)
mbAddrB = m_CurMBAddr - 1;
else
{
if ((m_CurMB_Y) &&
(iFirstMB <= m_CurMBAddr - mb_width * 2))
{
mbAddrB = m_CurMBAddr - mb_width * 2;
}
}
}
}
// decode skip flag
{
Ipp32s condTermFlagA = 0, condTermFlagB = 0;
Ipp32s ctxIdxInc;
// obtain left macroblock info
if ((0 <= mbAddrA) &&
(!GetMBSkippedFlag(m_gmbinfo->mbs[mbAddrA])))
condTermFlagA = 1;
// obtain above macroblock info
if ((0 <= mbAddrB) &&
(!GetMBSkippedFlag(m_gmbinfo->mbs[mbAddrB])))
condTermFlagB = 1;
ctxIdxInc = condTermFlagA + condTermFlagB;
return m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[ctxIdx] + ctxIdxInc);
}
} // Ipp32u H264SegmentDecoder::DecodeMBSkipFlag_CABAC(Ipp32s ctxIdx)
static
Ipp32s PREDMBTYPETBL[] =
{
MBTYPE_FORWARD, MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16,MBTYPE_INTER_8x8,
-1, MBTYPE_INTRA,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_INTRA_16x16,MBTYPE_INTRA_16x16,
MBTYPE_PCM, MBTYPE_PCM, MBTYPE_PCM
};
static
Ipp32s SBTYPETBL[] =
{
SBTYPE_8x8, SBTYPE_8x4, SBTYPE_4x8, SBTYPE_4x4
};
void H264SegmentDecoder::DecodeMBTypeISlice_CABAC(void)
{
Ipp32s condTermFlagA = 0, condTermFlagB = 0;
Ipp32s mbAddr;
Ipp32s ctxIdxInc;
Ipp32s mb_type;
// get left macroblock type
mbAddr = m_cur_mb.CurrentBlockNeighbours.mbs_left[0].mb_num;
if (0 <= mbAddr)
{
if (MBTYPE_INTRA != m_gmbinfo->mbs[mbAddr].mbtype)
condTermFlagA = 1;
}
// get abouve macroblock type
mbAddr = m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num;
if (0 <= mbAddr)
{
if (MBTYPE_INTRA != m_gmbinfo->mbs[mbAddr].mbtype)
condTermFlagB = 1;
}
ctxIdxInc = condTermFlagA + condTermFlagB;
if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + ctxIdxInc))
{
// we have I_NxN macroblock type
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
}
else
{
if (0 == m_pBitStream->DecodeSymbolEnd_CABAC())
{
Ipp32u code;
// luma CBP bit
if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 3))
{
m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
mb_type = 16;
}
else
{
m_cur_mb.LocalMacroblockInfo->cbp = 0x00;
mb_type = 0;
}
// chroma CBP bits
if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 4))
{
if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 5))
{
m_cur_mb.LocalMacroblockInfo->cbp |= 0x20;
mb_type |= 12;
}
else
{
m_cur_mb.LocalMacroblockInfo->cbp |= 0x10;
mb_type |= 8;
}
}
// prediction bits
code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 6);
code = (code << 1) |
m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_I] + 7);
mb_type |= code;
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
original_mb_type = (Ipp8u) mb_type;
}
else
{
// we have I_PCM macroblock type
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
}
}
} // void H264SegmentDecoder::DecodeMBTypeISlice_CABAC(Ipp32u *pMBIntraTypes,
static
Ipp8u MBTypesInPSlice[] =
{
MBTYPE_FORWARD,
MBTYPE_INTER_8x8,
MBTYPE_INTER_8x16,
MBTYPE_INTER_16x8
};
void H264SegmentDecoder::DecodeMBTypePSlice_CABAC(void)
{
// macroblock has P type
if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + 0))
{
Ipp32u code;
code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + 1);
code = m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + code + 2) +
code * 2;
// See table 9-28 of H.264 standard
// for translating bin string (code) to mb_type
m_cur_mb.GlobalMacroblockInfo->mbtype = (Ipp8u) MBTypesInPSlice[code];
// decode subblock types
if (MBTYPE_INTER_8x8 == m_cur_mb.GlobalMacroblockInfo->mbtype)
{
Ipp32s subblock;
Ipp32u uCodeNum;
for (subblock = 0; subblock < 4; subblock++)
{
// block type decoding
if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[SUB_MB_TYPE_P_SP] + 0))
uCodeNum = 0;
else
{
if (m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[SUB_MB_TYPE_P_SP] + 1))
uCodeNum = 3 - m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[SUB_MB_TYPE_P_SP] + 2);
else
uCodeNum = 1;
}
m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = (Ipp8u) SBTYPETBL[uCodeNum];
}
}
}
// decode intra macroblock type in P slice
else
{
// macroblock has I_NxN type
if (0 == m_pBitStream->DecodeSingleBin_CABAC(ctxIdxOffset[MB_TYPE_P_SP] + 3))
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -