📄 umc_h264_redual_decoder_templates.h
字号:
/*
//
// 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)
#ifndef __UMC_H264_RESIDUAL_DECODER_TEMPLATES_H
#define __UMC_H264_RESIDUAL_DECODER_TEMPLATES_H
#include "umc_h264_dec_internal_cabac.h"
namespace UMC
{
// turn off the "code is not reachable from preceding code" remark
#pragma warning(disable : 128)
// turn off the "conditional expression is constant" warning
#pragma warning(disable: 280)
#pragma warning(disable: 4127)
enum
{
LUMA_BLOCK_8X8_0 = 0x01,
LUMA_BLOCK_8X8_1 = 0x02,
LUMA_BLOCK_8X8_2 = 0x04,
LUMA_BLOCK_8X8_3 = 0x08,
CHROMA_AC_BLOCKS = 0x20,
CHROMA_DC_AC_BLOCKS = 0x30
};
template <typename Coeffs, Ipp32s color_format, Ipp32s is_field>
class ResidualDecoderCAVLC
{
public:
typedef Coeffs * CoeffsPtr;
virtual ~ResidualDecoderCAVLC() {}
void DecodeCoefficients8x8_CAVLC(H264SegmentDecoderMultiThreaded * sd)
{
Ipp64u blockcbp;
Ipp32u u8x8block = 1;
Ipp32s uBlock;
Ipp32u uBlockBit;
Ipp32u uNC;
Ipp32u uAboveIndex;
Ipp32u uLeftIndex;
Coeffs TempCoeffs[16];
Ipp16s sNumCoeff;
Ipp32s bFieldDecodeFlag = pGetMBFieldDecodingFlag(sd->m_cur_mb.GlobalMacroblockInfo);
CoeffsPtr pCurCoeffs;
bool advance_to_next_block=false;
Ipp8u bf = sd->m_pCurrentFrame->m_PictureStructureForDec<FRM_STRUCTURE || bFieldDecodeFlag;
Ipp8u cbp = sd->m_cur_mb.LocalMacroblockInfo->cbp;
// Initialize blockcbp bits from input cbp (from the bitstream)
blockcbp = 0; // no coeffs
for (uBlock=0; uBlock<5; uBlock++)
{
if (cbp & u8x8block)
blockcbp |= blockcbp_table[uBlock];
u8x8block <<= 1;
}
if (cbp & u8x8block)
{
switch(color_format)
{
case 1:
blockcbp |= CONST_LL(0x3ff0000) << 1;
break;
case 2:
blockcbp |= CONST_LL(0x3ffff0000) << 1;
break;
case 3:
blockcbp |= CONST_LL(0x3ffffffff0000) << 1;
break;
}
}
uBlock = 1; // start block loop with first luma 4x4
uBlockBit = 2;
blockcbp >>= 1;
for (uBlock = 1; uBlock<FIRST_DC_CHROMA; uBlock++)
{
uAboveIndex = BlockNumToMBColLuma[uBlock];
uLeftIndex = BlockNumToMBRowLuma[uBlock];
pCurCoeffs = TempCoeffs;
sNumCoeff = 0;
if ((blockcbp & 1) != 0)
{
uNC = sd->GetBlocksLumaContext(uAboveIndex,uLeftIndex);
// Get CAVLC-code coefficient info from bitstream. Following call
// updates pbs, bitOffset, sNumCoeff, sNumTrOnes, TrOneSigns,
// and uTotalZero and fills CoeffBuf and uRunBeforeBuf.
memset(TempCoeffs, 0, 16*sizeof(Coeffs));
sd->m_pBitStream->GetCAVLCInfoLuma(uNC,
16,
sNumCoeff,
&pCurCoeffs,
bf);
#ifdef STORE_VLC
FILE *fp=fopen(__VLC_FILE__,"a+t");
if (fp)
{
fprintf(fp,"I4 L %d %d\n",uNC,sNumCoeff);
fclose(fp);
}
#endif
//copy coeffs from tempbuffer
for (Ipp32s i=0;i<16;i++)
{
CoeffsPtr coeffsPtr = (CoeffsPtr)sd->m_pCoeffBlocksWrite;
coeffsPtr[hp_scan8x8[bf][((uBlock-1)&3)+i*4]] = TempCoeffs[mp_scan4x4[bf][i]];
}
advance_to_next_block = true;
sd->m_cur_mb.LocalMacroblockInfo->cbp4x4_luma |= uBlockBit;
}
if ((uBlock&3)==0 && advance_to_next_block) //end of 8x8 block
{
sd->m_pCoeffBlocksWrite += 64*(sizeof(Coeffs) / sizeof(sd->m_pCoeffBlocksWrite[0]));
advance_to_next_block=false;
}
// Update num coeff storage for predicting future blocks
sd->m_cur_mb.MacroblockCoeffsInfo->numCoeff[uLeftIndex * 4 + uAboveIndex] = (Ipp8u) sNumCoeff;
blockcbp >>= 1;
uBlockBit <<= 1;
} // uBlock
if (!color_format)
return;
for (uBlock = FIRST_DC_CHROMA; uBlock < FIRST_AC_CHROMA; uBlock++)
{
if ((blockcbp & 1) != 0)
{
switch(color_format)
{
case 1:
sd->m_pBitStream->GetCAVLCInfoChroma0(sNumCoeff, (CoeffsPtr*)&sd->m_pCoeffBlocksWrite);
break;
case 2:
sd->m_pBitStream->GetCAVLCInfoChroma2(sNumCoeff, (CoeffsPtr*)&sd->m_pCoeffBlocksWrite);
break;
case 3:
sd->m_pBitStream->GetCAVLCInfoChroma4(sNumCoeff, (CoeffsPtr*)&sd->m_pCoeffBlocksWrite, 0);
break;
default:
sNumCoeff = 0;
VM_ASSERT(false);
throw h264_exception(UMC_ERR_INVALID_STREAM);
};
#ifdef STORE_VLC
FILE *fp=fopen(__VLC_FILE__,"a+t");
if (fp)
{
fprintf(fp,"I4 CDC %d %d\n",0,sNumCoeff);
fclose(fp);
}
#endif
sd->m_cur_mb.LocalMacroblockInfo->cbp4x4_chroma[uBlock - FIRST_DC_CHROMA] |= (sNumCoeff ? 1 : 0);
}
blockcbp >>= 1;
// Can't early exit without setting numcoeff for rest of blocks
if ((blockcbp == 0) && (uBlock == (FIRST_AC_CHROMA - 1)))
{
// no AC chroma coeffs, set chrroma NumCoef buffers to zero and exit
//pMB->numCoeff[16]=pMB->numCoeff[17]=pMB->numCoeff[18]=pMB->numCoeff[19]=
//pMB->numCoeff[20]=pMB->numCoeff[21]=pMB->numCoeff[22]=pMB->numCoeff[23]=0;
return;
}
} // uBlock
uBlockBit = 2;
Ipp32s colorFactor;
switch(color_format)
{
case 1:
colorFactor = 1;
break;
case 2:
colorFactor = 2;
break;
case 3:
colorFactor = 4;
break;
default:
colorFactor = 0;
VM_ASSERT(false);
};
for (uBlock = FIRST_AC_CHROMA; uBlock < FIRST_AC_CHROMA + 8*colorFactor; uBlock++)
{
if (uBlock == (FIRST_AC_CHROMA + 4*colorFactor))
uBlockBit = 2;
uAboveIndex = BlockNumToMBColChromaAC[color_format][uBlock-FIRST_AC_CHROMA];
uLeftIndex = BlockNumToMBRowChromaAC[color_format][uBlock-FIRST_AC_CHROMA];
Ipp32u addval = uBlock >= (FIRST_AC_CHROMA + 4*colorFactor) ?
(FIRST_AC_CHROMA + 4*colorFactor - 3) : 16;
sNumCoeff = 0;
if ((blockcbp & 1) != 0)
{
switch(color_format)
{
case 1:
uNC = sd->GetBlocksChromaContextBMEH(uAboveIndex, uLeftIndex, uBlock >= (FIRST_AC_CHROMA + 4*colorFactor));
break;
case 2:
uNC = sd->GetBlocksChromaContextH2(uAboveIndex, uLeftIndex, uBlock >= (FIRST_AC_CHROMA + 4*colorFactor));
break;
case 3:
uNC = sd->GetBlocksChromaContextH4(uAboveIndex, uLeftIndex, uBlock >= (FIRST_AC_CHROMA + 4*colorFactor));
break;
default:
uNC = 0;
VM_ASSERT(false);
throw h264_exception(UMC_ERR_INVALID_STREAM);
};
// Get CAVLC-code coefficient info from bitstream. Following call
// updates pbs, bitOffset, sNumCoeff, sNumTrOnes, TrOneSigns,
// and uTotalZero and fills CoeffBuf and uRunBeforeBuf.
sd->m_pBitStream->GetCAVLCInfoLuma(uNC,
15,
sNumCoeff,
(CoeffsPtr*)&sd->m_pCoeffBlocksWrite,
bf);
#ifdef STORE_VLC
FILE *fp=fopen(__VLC_FILE__,"a+t");
if (fp)
{
fprintf(fp,"I4 CAC %d %d\n",uNC,sNumCoeff);
fclose(fp);
}
#endif
sd->m_cur_mb.LocalMacroblockInfo->cbp4x4_chroma[uBlock >= (FIRST_AC_CHROMA + 4*colorFactor)]
|= (sNumCoeff ? uBlockBit : 0);
}
// Update num coeff storage for predicting future blocks
sd->m_cur_mb.MacroblockCoeffsInfo->numCoeff[uLeftIndex * 2 * (1 + (Ipp32s)(color_format == 3))
+ uAboveIndex + addval] = (Ipp8u)sNumCoeff;
blockcbp >>= 1;
uBlockBit <<= 1;
} // uBlock
// update buffer position pointer
} // void DecodeCoefficients8x8_CAVLC(H264SegmentDecoderMultiThreaded * sd)
#define SET_TO_ZERO_COEFFS_NUMBER(x_pos, y_pos) \
{ \
pNumCoeffsArray[(y_pos) * 4 + x_pos] = (Ipp8u) 0; \
pNumCoeffsArray[(y_pos) * 4 + x_pos + 1] = (Ipp8u) 0; \
pNumCoeffsArray[(y_pos + 1) * 4 + x_pos] = (Ipp8u) 0; \
pNumCoeffsArray[(y_pos + 1) * 4 + x_pos + 1] = (Ipp8u) 0; \
}
#define DECODE_EXTERNAL_LUMA_BLOCK_CAVLC(x_pos, y_pos, block_num) \
{ \
Ipp16s iCoeffsNumber; \
/* to be honest, VLCContext is an average of coeffs numbers \
of neighbouring blocks */ \
Ipp32s iVCLContext; \
iVCLContext = sd->GetBlocksLumaContextExternal(); \
/* decode block coeffs */ \
sd->m_pBitStream->GetCAVLCInfoLuma(iVCLContext, \
iMaxNum, \
iCoeffsNumber, \
(CoeffsPtr *) &sd->m_pCoeffBlocksWrite, \
bf); \
/* update final CBP */ \
uFinalCBP |= (iCoeffsNumber) ? (1 << (block_num + 1)) : (0); \
/* update a num coeff storage for a prediction of future blocks */ \
pNumCoeffsArray[(y_pos) * 4 + x_pos] = (Ipp8u) iCoeffsNumber; \
}
#define DECODE_TOP_LUMA_BLOCK_CAVLC(x_pos, y_pos, block_num) \
{ \
Ipp16s iCoeffsNumber; \
/* to be honest, VLCContext is an average of coeffs numbers \
of neighbouring blocks */ \
Ipp32s iVCLContext; \
iVCLContext = sd->GetBlocksLumaContextTop(x_pos, pNumCoeffsArray[x_pos - 1]); \
/* decode block coeffs */ \
sd->m_pBitStream->GetCAVLCInfoLuma(iVCLContext, \
iMaxNum, \
iCoeffsNumber, \
(CoeffsPtr *) &sd->m_pCoeffBlocksWrite, \
bf); \
/* update final CBP */ \
uFinalCBP |= (iCoeffsNumber) ? (1 << (block_num + 1)) : (0); \
/* update a num coeff storage for a prediction of future blocks */ \
pNumCoeffsArray[(y_pos) * 4 + x_pos] = (Ipp8u) iCoeffsNumber; \
}
#define DECODE_LEFT_LUMA_BLOCK_CAVLC(x_pos, y_pos, block_num) \
{ \
Ipp16s iCoeffsNumber; \
/* to be honest, VLCContext is an average of coeffs numbers \
of neighbouring blocks */ \
Ipp32s iVCLContext; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -