📄 umc_avs_dec_decompressor_dec_b.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) 2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
#include "umc_avs_dec_decompressor.h"
#include "umc_avs_sequence_header.h"
#include "umc_avs_picture_header.h"
#include "umc_avs_slice_header.h"
#include "umc_avs_dec_bit_stream.h"
#include "umc_avs_dec_mb_info.h"
#include "umc_avs_dec_tables.h"
namespace UMC
{
void AVSDecompressor::DecompressBMacroBlocksRow(void)
{
MbMax = m_decCtx.MbIndex + m_decCtx.MbWidth;
// we can use MbIndex either from decoding and reconstructing contexts
MbIndex = m_decCtx.MbIndex;
PrepareNeighbours(&m_decCtx);
PrepareDecoding();
PrepareReconstruction();
do
{
ResetMacroblock();
// try to get number of skipped macroblocks
if (-1 == m_decCtx.SkipMbCount)
{
if (1 == m_decCtx.m_pPicHeader->skip_mode_flag)
{
m_decCtx.SkipMbCount = GetUE(&m_decCtx.m_stream);
}
}
// the previous macroblock was skipped or skip_mb_run is 0,
// so this one is decoded
if (0 == m_decCtx.SkipMbCount)
{
m_decCtx.SkipMbCount -= 1;
}
// decode next macroblock
if (0 >= m_decCtx.SkipMbCount)
{
// set coeffs buffers
m_pWriteCoeffs = m_decCtx.m_pCoeffs;
m_pReadCoeffs = m_recCtx.m_pCoeffs;
DecodeBMacroBlockType();
// call appropriate routines
switch (m_pMbInfo->MbType)
{
case I_8x8:
DecodeIMacroBlock();
ReconstructIMacroBlock();
break;
case B_Skip:
DecodeSkipBMacroBlock();
ReconstructBMacroBlock();
break;
default:
DecodeBMacroBlock();
ReconstructBMacroBlock();
break;
};
}
// next macroblock is skipped
else
{
DecodeSkipBMacroBlock();
ReconstructBMacroBlock();
m_decCtx.SkipMbCount -= 1;
}
MbIndex += 1;
AdvanceNeighbours();
AdvanceDecoding();
AdvanceReconstruction();
} while (MbIndex < MbMax);
// update context
FinalizeDecoding();
FinalizeReconstruction();
} // void AVSDecompressor::DecompressBMacroBlocksRow(void)
void AVSDecompressor::DecodeBMacroBlockType(void)
{
Ipp32u MbTypeIndex;
// get entopy element
MbTypeIndex = GetUE(&(m_decCtx.m_stream));
if (m_decCtx.m_pPicHeader->skip_mode_flag)
MbTypeIndex += 1;
if (24 <= MbTypeIndex)
{
// actually, it is an INTRA macroblock
// error protection
if (63 + 24 < MbTypeIndex)
throw (int) 0;
m_pMbInfo->MbType = I_8x8;
m_pMbInfo->MbCBP = CBPOfMacroblock[AVS_INTRA][MbTypeIndex - 24];
}
else
{
// set default parameters for P macroblock
m_pMbInfo->MbType = TypesOfBMacroblocks[MbTypeIndex].MbType;
m_pMbInfo->MvNum = TypesOfBMacroblocks[MbTypeIndex].MvNum;
m_pMbInfo->MbCBP = AVS_CBP_UNKNOWN;
memcpy(m_pMbInfo->predType,
TypesOfBMacroblocks[MbTypeIndex].predType,
sizeof(m_pMbInfo->predType));
m_pMbInfo->divType = TypesOfBMacroblocks[MbTypeIndex].divType;
}
m_pMbInfo->QP = m_decCtx.PreviousQP;
} // void AVSDecompressor::DecodeBMacroBlockType(void)
void AVSDecompressor::DecodeBMacroBlock(void)
{
Ipp32s i;
if (B_Direct_16x16 != m_pMbInfo->MbType)
{
// decode block types
if (B_8x8 == m_pMbInfo->MbType)
{
for (i = 0; i < 4; i += 1)
{
Ipp32u predType;
// decode block type
predType = (Ipp8u) GetBits(&m_decCtx.m_stream, 2);
if (PredDirect != predType)
m_pMbInfo->MvNum += 1;
// correct the 'symmetrical' block prediction type,
// because our consts differ slightly from the standard's consts.
if (3 == predType)
predType = PredSym;
m_pMbInfo->predType[i] = (Ipp8u) predType;
}
}
// decode reference indecies
if ((0 == m_decCtx.m_pPicHeader->picture_reference_flag) &&
(0 == m_decCtx.m_pPicHeader->picture_structure))
{
// field structure - indecies are 1 bit wide
for (i = 0; i < m_pMbInfo->MvNum; i += 1)
{
m_refIdx[i] = (Ipp8u) GetBit(&m_decCtx.m_stream);
}
// clone reference indices
SpecifyRefIndiciesBSlice();
}
// decode motion vectors
for (i = 0; i < m_pMbInfo->MvNum; i += 1)
{
mv_diff[i].vector.x = (Ipp16s) GetSE(&m_decCtx.m_stream);
mv_diff[i].vector.y = (Ipp16s) GetSE(&m_decCtx.m_stream);
}
// reconstruct motion vectors
ReconstructMotionVectorsBSlice();
}
else
{
// reconstruct direct motion vectors
ReconstructMotionVectorsBSliceDirect();
}
// decode weighting prediction flag
if (m_decCtx.m_pSlcHeader->mb_weighting_flag)
{
m_pMbInfo->weighting_prediction = (Ipp8u) GetBit(&m_decCtx.m_stream);
}
else
{
// if mb_weighting flag is zero,
// macroblock weighting prediction flag is equal to slice_weighting_flag
m_pMbInfo->weighting_prediction = (Ipp8u) m_decCtx.m_pSlcHeader->slice_weighting_flag;
}
if (AVS_CBP_UNKNOWN == m_pMbInfo->MbCBP)
{
Ipp32u uTemp;
Ipp32s mb_qp_delta = 0;
// decode coded block pattern
uTemp = GetUE(&m_decCtx.m_stream);
// error handling
if (63 < uTemp)
throw (int) 0;
m_pMbInfo->MbCBP = CBPOfMacroblock[AVS_INTER][uTemp];
if (AVS_CHROMA_422_FORMAT == m_decCtx.m_pSeqHeader->chroma_format)
{
uTemp = GetUE(&m_decCtx.m_stream);
m_pMbInfo->MbCBP |= uTemp << 6;
}
// decode quantization parameter
if ((m_pMbInfo->MbCBP) &&
(0 == m_decCtx.FixedQP))
{
mb_qp_delta = GetSE(&m_decCtx.m_stream);
if (63 < mb_qp_delta + 32)
throw (int) 0;
m_pMbInfo->QP += mb_qp_delta;
m_decCtx.PreviousQP += mb_qp_delta;
}
}
// decode blocks coefficients
{
Ipp32u uBlockMask = 1;
// decode luminance blocks
for (i = 0; i < 4; i += 1, uBlockMask += uBlockMask)
{
if (m_pMbInfo->MbCBP & uBlockMask)
{
Ipp32s iNumCoeffs;
ippiDecodeLumaBlockInter_AVS_1u16s(&m_decCtx.m_stream.src,
&m_decCtx.m_stream.offset,
&iNumCoeffs,
m_pWriteCoeffs,
m_decCtx.ScanType);
m_pMbInfo->NumCoeffs[i] = (Ipp8u) iNumCoeffs;
m_pWriteCoeffs += 64;
}
}
// decode chrominance blocks
for (; i < m_decCtx.iNumberOfBlocks; i += 1, uBlockMask += uBlockMask)
{
if (m_pMbInfo->MbCBP & uBlockMask)
{
Ipp32s iNumCoeffs;
ippiDecodeChromaBlock_AVS_1u16s(&m_decCtx.m_stream.src,
&m_decCtx.m_stream.offset,
&iNumCoeffs,
m_pWriteCoeffs,
m_decCtx.ScanType);
m_pMbInfo->NumCoeffs[i] = (Ipp8u) iNumCoeffs;
m_pWriteCoeffs += 64;
}
}
}
} // void AVSDecompressor::DecodeBMacroBlock(void)
void AVSDecompressor::DecodeSkipBMacroBlock(void)
{
// correct MB type & parameters
m_pMbInfo->MbType = B_Skip;
memset(m_pMbInfo->predType, PredBiDir, sizeof(m_pMbInfo->predType));
m_pMbInfo->QP = m_decCtx.PreviousQP;
m_pMbInfo->divType = Div_16x16;
// decode direct motion vectors
ReconstructMotionVectorsBSliceDirect();
} // void AVSDecompressor::DecodeSkipBMacroBlock(void)
void AVSDecompressor::SpecifyRefIndiciesBSlice(void)
{
eAVSPredType predType;
Ipp32u dir;
Ipp32s iRefNum = 0;
// cycle on directions
predType = PredForward;
for (dir = AVS_FORWARD; dir <= AVS_BACKWARD; dir += 1)
{
// clone reference indecies
switch (m_pMbInfo->divType)
{
// all block have the same reference index
case Div_16x16:
if (m_pMbInfo->predType[0] & predType)
{
m_pMbInfo->refIdx[dir][0] = (Ipp8u) m_refIdx[iRefNum];
m_pMbInfo->refIdx[dir][1] = (Ipp8u) m_refIdx[iRefNum];
m_pMbInfo->refIdx[dir][2] = (Ipp8u) m_refIdx[iRefNum];
m_pMbInfo->refIdx[dir][3] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
break;
// top blocks have index 0,
// bottom blocks have index 1
case Div_16x8:
if (m_pMbInfo->predType[0] & predType)
{
m_pMbInfo->refIdx[dir][0] = (Ipp8u) m_refIdx[iRefNum];
m_pMbInfo->refIdx[dir][1] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
if (m_pMbInfo->predType[2] & predType)
{
m_pMbInfo->refIdx[dir][2] = (Ipp8u) m_refIdx[iRefNum];
m_pMbInfo->refIdx[dir][3] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
break;
// left blocks have index 0,
// right blocks have index 1
case Div_8x16:
if (m_pMbInfo->predType[0] & predType)
{
m_pMbInfo->refIdx[dir][0] = (Ipp8u) m_refIdx[iRefNum];
m_pMbInfo->refIdx[dir][2] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
if (m_pMbInfo->predType[1] & predType)
{
m_pMbInfo->refIdx[dir][1] = (Ipp8u) m_refIdx[iRefNum];
m_pMbInfo->refIdx[dir][3] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
break;
// every block has its own reference index
default:
if (m_pMbInfo->predType[0] & predType)
{
m_pMbInfo->refIdx[dir][0] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
if (m_pMbInfo->predType[1] & predType)
{
m_pMbInfo->refIdx[dir][1] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
if (m_pMbInfo->predType[2] & predType)
{
m_pMbInfo->refIdx[dir][2] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
if (m_pMbInfo->predType[3] & predType)
{
m_pMbInfo->refIdx[dir][3] = (Ipp8u) m_refIdx[iRefNum];
iRefNum += 1;
}
break;
}
// set other direction
predType = PredBackward;
}
} // void AVSDecompressor::SpecifyRefIndiciesBSlice(void)
} // namespace UMC
#endif // #if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -