📄 umc_avs_dec_decompressor_dec_p.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::DecodePMacroBlockType(void)
{
Ipp32u MbTypeIndex;
// get entopy element
MbTypeIndex = GetUE(&(m_decCtx.m_stream));
if (m_decCtx.m_pPicHeader->skip_mode_flag)
MbTypeIndex += 1;
if (5 <= MbTypeIndex)
{
// actually, it is an INTRA macroblock
// error protection
if (63 + 5 < MbTypeIndex)
throw (int) 0;
m_pMbInfo->MbType = I_8x8;
m_pMbInfo->MbCBP = CBPOfMacroblock[AVS_INTRA][MbTypeIndex - 5];
}
else
{
// set default parameters for P macroblock
m_pMbInfo->MbType = TypesOfPMacroblocks[MbTypeIndex].MbType;
m_pMbInfo->MvNum = TypesOfPMacroblocks[MbTypeIndex].MvNum;
m_pMbInfo->MbCBP = AVS_CBP_UNKNOWN;
memset(m_pMbInfo->predType, PredForward, sizeof(m_pMbInfo->predType));
m_pMbInfo->divType = TypesOfPMacroblocks[MbTypeIndex].divType;
}
m_pMbInfo->QP = m_decCtx.PreviousQP;
} // void AVSDecompressor::DecodePMacroBlockType(void)
void AVSDecompressor::DecodePMacroBlock(void)
{
Ipp32s i;
// decode reference indecies
if ((0 == m_decCtx.m_pPicHeader->picture_reference_flag) &&
(I_PICTURE_START_CODE != m_decCtx.m_pPicHeader->picture_start_code))
{
// frame structure - indecies are 1 bit wide
if (m_decCtx.m_pPicHeader->picture_structure)
{
for (i = 0; i < m_pMbInfo->MvNum; i += 1)
{
m_refIdx[i] = (Ipp8u) GetBit(&m_decCtx.m_stream);
}
}
// field structure - indecies are 2 bit wide
else
{
for (i = 0; i < m_pMbInfo->MvNum; i += 1)
{
m_refIdx[i] = (Ipp8u) GetBits(&m_decCtx.m_stream, 2);
}
}
// clone reference indices
SpecifyRefIndiciesPSlice();
}
// 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);
}
ReconstructMotionVectorsPSlice();
// 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 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 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::DecodePMacroBlock(void)
void AVSDecompressor::DecodeSkipPMacroBlock(void)
{
// correct MB type & parameters
m_pMbInfo->MbType = P_16x16;
m_pMbInfo->MvNum = 1;
memset(m_pMbInfo->predType, PredForward, sizeof(m_pMbInfo->predType));
m_pMbInfo->QP = m_decCtx.PreviousQP;
m_pMbInfo->divType = Div_16x16;
// decode motion vector
// there is quite a complex condition for zero motion vector.
// first of all, when one of neighbours is absent,
// otherwise when any of them use default reference index for
// forward prediction and the motion vector is zero.
if ((NULL == m_pMbInfoTop) ||
((0 == m_pMbInfoTop->refIdx[AVS_FORWARD][2]) &&
(m_pMbInfoTop->predType[2] & PredForward) &&
(0 == m_pMbInfoTop->mv[AVS_FORWARD][2].scalar)))
{
m_mvPred.scalar = 0;
}
else if ((NULL == m_pMbInfoLeft) ||
((0 == m_pMbInfoLeft->refIdx[AVS_FORWARD][1]) &&
(m_pMbInfoLeft->predType[1] & PredForward) &&
(0 == m_pMbInfoLeft->mv[AVS_FORWARD][1].scalar)))
{
m_mvPred.scalar = 0;
}
else
{
GetMotionVectorPredictor16x16(PredForward);
}
m_pMbInfo->mv[0][0] = m_mvPred;
m_pMbInfo->mv[0][1] = m_mvPred;
m_pMbInfo->mv[0][2] = m_mvPred;
m_pMbInfo->mv[0][3] = m_mvPred;
} // void AVSDecompressor::DecodeSkipPMacroBlock(void)
void AVSDecompressor::SpecifyRefIndiciesPSlice(void)
{
// clone reference indecies
switch (m_pMbInfo->divType)
{
// all block have the same reference index
case Div_16x16:
m_pMbInfo->refIdx[AVS_FORWARD][0] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][1] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][2] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][3] = (Ipp8u) m_refIdx[0];
break;
// top blocks have index 0,
// bottom blocks have index 1
case Div_16x8:
m_pMbInfo->refIdx[AVS_FORWARD][0] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][1] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][2] = (Ipp8u) m_refIdx[1];
m_pMbInfo->refIdx[AVS_FORWARD][3] = (Ipp8u) m_refIdx[1];
break;
// left blocks have index 0,
// right blocks have index 1
case Div_8x16:
m_pMbInfo->refIdx[AVS_FORWARD][0] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][1] = (Ipp8u) m_refIdx[1];
m_pMbInfo->refIdx[AVS_FORWARD][2] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][3] = (Ipp8u) m_refIdx[1];
break;
// every block has its own reference index
default:
m_pMbInfo->refIdx[AVS_FORWARD][0] = (Ipp8u) m_refIdx[0];
m_pMbInfo->refIdx[AVS_FORWARD][1] = (Ipp8u) m_refIdx[1];
m_pMbInfo->refIdx[AVS_FORWARD][2] = (Ipp8u) m_refIdx[2];
m_pMbInfo->refIdx[AVS_FORWARD][3] = (Ipp8u) m_refIdx[3];
break;
}
} // void AVSDecompressor::SpecifyRefIndiciesPSlice(void)
} // namespace UMC
#endif // #if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -