📄 umc_h264_segment_decoder_decode_mb_types.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) 2003-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_H264_VIDEO_DECODER)
#include "umc_h264_segment_decoder.h"
#include "umc_h264_dec.h"
#include "umc_h264_bitstream_inlines.h"
#include "vm_debug.h"
#include "umc_h264_dec_tables.h"
namespace UMC
{
///////////////////////////////////////////////////////////////////////////////
// lookup table to translate B frame type code to MB type
const
Ipp8u CodeToMBTypeB[] =
{
MBTYPE_DIRECT, // 0
MBTYPE_FORWARD,
MBTYPE_BACKWARD,
MBTYPE_BIDIR,
MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16, // 5
MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16,
MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16,
MBTYPE_INTER_16x8, // 10
MBTYPE_INTER_8x16,
MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16,
MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16, // 15
MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16,
MBTYPE_INTER_16x8,
MBTYPE_INTER_8x16,
MBTYPE_INTER_16x8, // 20
MBTYPE_INTER_8x16,
MBTYPE_INTER_8x8
};
// lookup table to extract prediction direction from MB type code for
// 16x8 and 8x16 MB types. Contains direction for first and second
// subblocks at each entry.
const
Ipp8u CodeToBDir[][2] =
{
{D_DIR_FWD, D_DIR_FWD},
{D_DIR_BWD, D_DIR_BWD},
{D_DIR_FWD, D_DIR_BWD},
{D_DIR_BWD, D_DIR_FWD},
{D_DIR_FWD, D_DIR_BIDIR},
{D_DIR_BWD, D_DIR_BIDIR},
{D_DIR_BIDIR, D_DIR_FWD},
{D_DIR_BIDIR, D_DIR_BWD},
{D_DIR_BIDIR, D_DIR_BIDIR}
};
// lookup table to translate B frame 8x8 subblock code to type and
// prediction direction
static
const struct
{
Ipp8u type;
Ipp8u dir;
} CodeToSBTypeAndDir[] =
{
{SBTYPE_DIRECT, D_DIR_DIRECT},
{SBTYPE_8x8, D_DIR_FWD},
{SBTYPE_8x8, D_DIR_BWD},
{SBTYPE_8x8, D_DIR_BIDIR},
{SBTYPE_8x4, D_DIR_FWD},
{SBTYPE_4x8, D_DIR_FWD},
{SBTYPE_8x4, D_DIR_BWD},
{SBTYPE_4x8, D_DIR_BWD},
{SBTYPE_8x4, D_DIR_BIDIR},
{SBTYPE_4x8, D_DIR_BIDIR},
{SBTYPE_4x4, D_DIR_FWD},
{SBTYPE_4x4, D_DIR_BWD},
{SBTYPE_4x4, D_DIR_BIDIR}
};
const
Ipp32s NIT2LIN[16] =
{
0, 1, 4, 5,
2, 3, 6, 7,
8, 9,12,13,
10,11,14,15
};
void H264SegmentDecoder::DecodeMBFieldDecodingFlag_CAVLC(void)
{
Ipp32u bit = m_pBitStream->Get1Bit();
pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,
m_cur_mb.GlobalMacroblockPairInfo,
bit);
} // void H264SegmentDecoder::DecodeMBFieldDecodingFlag_CAVLC(void)
void H264SegmentDecoder::DecodeMBFieldDecodingFlag(void)
{
Ipp32s iFirstMB = m_pSlice->GetFirstMBNumber();
Ipp32s iCurrentField = 0;
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);
} // void H264SegmentDecoder::DecodeMBFieldDecodingFlag(void)
Ipp32u H264SegmentDecoder::DecodeMBSkipRun_CAVLC(void)
{
return (Ipp32u) m_pBitStream->GetVLCElement(false);
} // Ipp32u H264SegmentDecoder::DecodeMBSkipRun_CAVLC(void)
void H264SegmentDecoder::DecodeMBTypeISlice_CAVLC(void)
{
Ipp32u uCodeNum;
uCodeNum = m_pBitStream->GetVLCElement(false);
// the macroblock has I_NxN type
if (0 == uCodeNum)
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
// the macroblock has I_16x16 type
else if (25 != uCodeNum)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
original_mb_type = (Ipp8u) (uCodeNum - 1);
// set the CBP
{
uCodeNum -= 1;
if (12 <= uCodeNum)
{
m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
uCodeNum -= 12;
}
else
m_cur_mb.LocalMacroblockInfo->cbp = 0x00;
uCodeNum <<= 2;
m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));
}
}
// the macroblock has PCM type
else
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
} // void H264SegmentDecoder::DecodeMBTypeISlice_CAVLC(void)
void H264SegmentDecoder::DecodeMBTypePSlice_CAVLC(void)
{
Ipp32u uCodeNum;
uCodeNum = m_pBitStream->GetVLCElement(false);
// the macroblock has inter type
if (5 > uCodeNum)
{
switch (uCodeNum)
{
case 0:
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_FORWARD;
break;
case 1:
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_16x8;
break;
case 2:
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTER_8x16;
break;
case 3:
case 4:
m_cur_mb.GlobalMacroblockInfo->mbtype = (Ipp8u) ((uCodeNum == 4) ?
MBTYPE_INTER_8x8_REF0 :
MBTYPE_INTER_8x8);
// read subblock types
{
Ipp32s subblock;
Ipp32s sbtype;
for (subblock = 0; subblock < 4; subblock++)
{
uCodeNum = m_pBitStream->GetVLCElement(false);
switch (uCodeNum)
{
case 0:
sbtype = SBTYPE_8x8;
break;
case 1:
sbtype = SBTYPE_8x4;
break;
case 2:
sbtype = SBTYPE_4x8;
break;
case 3:
sbtype = SBTYPE_4x4;
break;
default:
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = (Ipp8u) sbtype;
}
}
break;
}
}
else
{
uCodeNum -= 5;
// the macroblock has I_NxN type
if (0 == uCodeNum)
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
// the macroblock has I_16x16 type
else if (25 != uCodeNum)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
original_mb_type = (Ipp8u) (uCodeNum - 1);
// set the CBP
{
uCodeNum -= 1;
if (12 <= uCodeNum)
{
m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
uCodeNum -= 12;
}
else
m_cur_mb.LocalMacroblockInfo->cbp = 0x00;
uCodeNum <<= 2;
m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));
}
}
// the macroblock has PCM type
else
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
}
} // void H264SegmentDecoder::DecodeMBTypePSlice_CAVLC(void)
void H264SegmentDecoder::DecodeMBTypeBSlice_CAVLC(void)
{
Ipp32u uCodeNum;
uCodeNum = m_pBitStream->GetVLCElement(false);
// the macroblock has inter type
if (uCodeNum < 23)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = CodeToMBTypeB[uCodeNum];
if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_16x8 ||
m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x16)
{
// direction for the two subblocks
m_cur_mb.LocalMacroblockInfo->sbdir[0] = CodeToBDir[(uCodeNum-4)>>1][0];
m_cur_mb.LocalMacroblockInfo->sbdir[1] = CodeToBDir[(uCodeNum-4)>>1][1];
}
else if (m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_INTER_8x8)
{
// read subblock types and prediction direction
Ipp32u subblock;
for (subblock = 0; subblock < 4; subblock++)
{
uCodeNum = m_pBitStream->GetVLCElement(false);
if (uCodeNum < 13)
{
m_cur_mb.GlobalMacroblockInfo->sbtype[subblock] = CodeToSBTypeAndDir[uCodeNum].type;
m_cur_mb.LocalMacroblockInfo->sbdir[subblock] = CodeToSBTypeAndDir[uCodeNum].dir;
}
else
throw h264_exception(UMC_ERR_INVALID_STREAM);
}
}
}
else
{
uCodeNum -= 23;
// the macroblock has I_NxN type
if (0 == uCodeNum)
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
// the macroblock has I_16x16 type
else if (25 != uCodeNum)
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
original_mb_type = (Ipp8u) (uCodeNum - 1);
// set the CBP
{
uCodeNum -= 1;
if (12 <= uCodeNum)
{
m_cur_mb.LocalMacroblockInfo->cbp = 0x0f;
uCodeNum -= 12;
}
else
m_cur_mb.LocalMacroblockInfo->cbp = 0x00;
uCodeNum <<= 2;
m_cur_mb.LocalMacroblockInfo->cbp = (Ipp8u) (m_cur_mb.LocalMacroblockInfo->cbp | (uCodeNum & 0x30));
}
}
// the macroblock has PCM type
else
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
}
} // void H264SegmentDecoder::DecodeMBTypeBSlice_CAVLC(void)
void H264SegmentDecoder::DecodeMacroBlockType(IntraType *pMBIntraTypes,
Ipp32s *MBSkipCount, // On entry if < 0, run of skipped MBs has just been completed
// On return, zero or skip MB run count read from bitstream
Ipp32s *PassFDFDecode)
{
Ipp32u uCodeNum;
// interpretation of code depends upon slice type
if (m_pSliceHeader->slice_type == INTRASLICE)
{
if (m_pSliceHeader->MbaffFrameFlag)
{
if ((m_CurMBAddr & 1)==0)
{
Ipp32u bit = m_pBitStream->Get1Bit();
pSetPairMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,m_cur_mb.GlobalMacroblockPairInfo,bit);
}
}
else
{
pSetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo,0);
}
uCodeNum = m_pBitStream->GetVLCElement(false);
if (uCodeNum == 0)
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
else if (uCodeNum == 25)
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
else
{
m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
uCodeNum--;
}
} // intra
else
{ // not Intra
if (*MBSkipCount >= 0) //actually it has to be = 0
{
VM_ASSERT(*MBSkipCount<=0);
uCodeNum = m_pBitStream->GetVLCElement(false);
// skipped MB count
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -