📄 mbdec.cpp
字号:
/*************************************************************************
This software module was originally developed by
Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
Bruce Lin (blin@microsoft.com), Microsoft Corporation
Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
Simon Winder (swinder@microsoft.com), Microsoft Corporation
(date: March, 1996)
and edited by
Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center
in the course of development of the MPEG-4 Video (ISO/IEC 14496-2).
This software module is an implementation of a part of one or more MPEG-4 Video tools
as specified by the MPEG-4 Video.
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video.
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents.
The original developer of this software module and his/her company,
the subsequent editors and their companies,
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation.
Copyright is not released for non MPEG-4 Video conforming products.
Microsoft retains full right to use the code for his/her own purpose,
assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products.
This copyright notice must be included in all copies or derivative works.
Copyright (c) 1996, 1997.
Module Name:
MBDec.cpp
Abstract:
MacroBlock level decoder
Revision History:
May. 9 1998: add boundary by Hyundai Electronics
Cheol-Soo Park (cspark@super5.hyundai.co.kr)
*************************************************************************/
#include "typeapi.h"
#include "codehead.h"
#include "mode.hpp"
#include "global.hpp"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "vopses.hpp"
#include "vopsedec.hpp"
#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#endif // __MFC_
Void CVideoObjectDecoder::swapCurrAndRightMBForShape ()
{
CVOPU8YUVBA* pvopcTmp = m_pvopcCurrMB;
m_pvopcCurrMB = m_pvopcRightMB;
m_pvopcRightMB = pvopcTmp;
m_ppxlcCurrMBBY = (PixelC*) m_pvopcCurrMB->pixelsBY ();
m_ppxlcCurrMBBUV = (PixelC*) m_pvopcCurrMB->pixelsBUV ();
m_ppxlcRightMBBY = (PixelC*) m_pvopcRightMB->pixelsBY ();
m_ppxlcRightMBBUV = (PixelC*) m_pvopcRightMB->pixelsBUV ();
}
Void CVideoObjectDecoder::copyFromPredForYAndRefForCToCurrQ (
CoordI x, CoordI y,
PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV,
CRct *prctMVLimit
)
{
Int iUnit = sizeof(PixelC); // NBIT: for memcpy
// needs limiting to reference area bounding box
limitMVRangeToExtendedBBFullPel(x,y,prctMVLimit,MB_SIZE);
Int iOffsetUV = (y / 2 + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + x / 2 + EXPANDUV_REF_FRAME;
const PixelC* ppxlcPredMBY = m_ppxlcPredMBY;
const PixelC* ppxlcRefMBU = m_pvopcRefQ0->pixelsU () + iOffsetUV;
const PixelC* ppxlcRefMBV = m_pvopcRefQ0->pixelsV () + iOffsetUV;
CoordI iY;
for (iY = 0; iY < BLOCK_SIZE; iY++) {
memcpy (ppxlcCurrQMBY, ppxlcPredMBY, MB_SIZE*iUnit);
memcpy (ppxlcCurrQMBU, ppxlcRefMBU, BLOCK_SIZE*iUnit);
memcpy (ppxlcCurrQMBV, ppxlcRefMBV, BLOCK_SIZE*iUnit);
ppxlcCurrQMBY += m_iFrameWidthY; ppxlcPredMBY += MB_SIZE;
ppxlcCurrQMBU += m_iFrameWidthUV; ppxlcRefMBU += m_iFrameWidthUV;
ppxlcCurrQMBV += m_iFrameWidthUV; ppxlcRefMBV += m_iFrameWidthUV;
memcpy (ppxlcCurrQMBY, ppxlcPredMBY, MB_SIZE*iUnit);
ppxlcCurrQMBY += m_iFrameWidthY; ppxlcPredMBY += MB_SIZE;
}
}
Void CVideoObjectDecoder::copyAlphaFromPredToCurrQ (
CoordI x, CoordI y,
PixelC* ppxlcCurrQMBA
)
{
const PixelC* ppxlcPredMBA = m_ppxlcPredMBA;
CoordI iY;
for (iY = 0; iY < MB_SIZE; iY++) {
memcpy (ppxlcCurrQMBA, ppxlcPredMBA, MB_SIZE);
ppxlcCurrQMBA += m_iFrameWidthY;
ppxlcPredMBA += MB_SIZE;
}
}
// for Direct and Interpolate mode in B-VOP
Void CVideoObjectDecoder::averagePredAndAddErrorToCurrQ (
PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV
)
{
CoordI ix, iy, ic = 0;
for (iy = 0; iy < MB_SIZE; iy++) {
for (ix = 0; ix < MB_SIZE; ix++, ic++) {
ppxlcCurrQMBY [ix] = m_rgiClipTab [
((m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1) +
m_ppxliErrorMBY [ic]
];
}
ppxlcCurrQMBY += m_iFrameWidthY;
}
ic = 0;
for (iy = 0; iy < BLOCK_SIZE; iy++) {
for (ix = 0; ix < BLOCK_SIZE; ix++, ic++) {
ppxlcCurrQMBU [ix] = m_rgiClipTab [
((m_ppxlcPredMBU [ic] + m_ppxlcPredMBBackU [ic] + 1) >> 1) +
m_ppxliErrorMBU [ic]
];
ppxlcCurrQMBV [ix] = m_rgiClipTab [
((m_ppxlcPredMBV [ic] + m_ppxlcPredMBBackV [ic] + 1) >> 1) +
m_ppxliErrorMBV [ic]
];
}
ppxlcCurrQMBU += m_iFrameWidthUV;
ppxlcCurrQMBV += m_iFrameWidthUV;
}
}
Void CVideoObjectDecoder::averagePredAndAssignToCurrQ (
PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV
)
{
CoordI ix, iy, ic = 0;
for (iy = 0; iy < MB_SIZE; iy++) {
for (ix = 0; ix < MB_SIZE; ix++, ic++)
ppxlcCurrQMBY [ix] = (m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1; // don't need to clip
ppxlcCurrQMBY += m_iFrameWidthY;
}
ic = 0;
for (iy = 0; iy < BLOCK_SIZE; iy++) {
for (ix = 0; ix < BLOCK_SIZE; ix++, ic++) {
ppxlcCurrQMBU [ix] = (m_ppxlcPredMBU [ic] + m_ppxlcPredMBBackU [ic] + 1) >> 1;
ppxlcCurrQMBV [ix] = (m_ppxlcPredMBV [ic] + m_ppxlcPredMBBackV [ic] + 1) >> 1;
}
ppxlcCurrQMBU += m_iFrameWidthUV;
ppxlcCurrQMBV += m_iFrameWidthUV;
}
}
// texture and overhead
// Intra
Void CVideoObjectDecoder::decodeTextureIntraMB (
CMBMode* pmbmd, CoordI iMBX, CoordI iMBY,
PixelC* ppxlcCurrFrmQY, PixelC* ppxlcCurrFrmQU, PixelC* ppxlcCurrFrmQV)
{
assert (pmbmd != NULL);
if (pmbmd -> m_rgTranspStatus [0] == ALL)
return;
assert (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ);
Int iQP = pmbmd->m_stepSize;
Int iDcScalerY, iDcScalerC;
if (iQP <= 4) {
iDcScalerY = 8;
iDcScalerC = 8;
}
else if (iQP >= 5 && iQP <= 8) {
iDcScalerY = 2 * iQP;
iDcScalerC = (iQP + 13) / 2;
}
else if (iQP >= 9 && iQP <= 24) {
iDcScalerY = iQP + 8;
iDcScalerC = (iQP + 13) / 2;
}
else {
iDcScalerY = 2 * iQP - 16;
iDcScalerC = iQP - 6;
}
assert (iQP > 0);
// more bogus technology
assert (pmbmd -> m_stepSizeDelayed > 0);
if (pmbmd -> m_stepSizeDelayed >= grgiDCSwitchingThreshold [m_vopmd.iIntraDcSwitchThr])
pmbmd->m_bCodeDcAsAc = TRUE;
else
pmbmd->m_bCodeDcAsAc = FALSE;
//for intra pred
MacroBlockMemory* pmbmLeft = NULL;
MacroBlockMemory* pmbmTop = NULL;
MacroBlockMemory* pmbmLeftTop = NULL;
CMBMode* pmbmdLeft = NULL;
CMBMode* pmbmdTop = NULL;
CMBMode* pmbmdLeftTop = NULL;
Int iMBTop = iMBY - 1;
// dshu: begin of modification
if (m_uiSprite == 1 && m_vopmd.SpriteXmitMode != STOP) {
assert (pmbmd->m_iVideoPacketNumber == 0);
if (iMBTop >= 0)
(pmbmd - m_iNumMBX)->m_iVideoPacketNumber = 0;
if (iMBX > 0)
(pmbmd - 1)->m_iVideoPacketNumber = 0;
if (iMBTop >= 0 && iMBX > 0)
(pmbmd - m_iNumMBX - 1)->m_iVideoPacketNumber = 0 ;
}
// dshu: end of modification
if (iMBTop >= 0) {
if (pmbmd->m_iVideoPacketNumber == (pmbmd - m_iNumMBX)->m_iVideoPacketNumber) {
pmbmTop = m_rgpmbmAbove [iMBX];
pmbmdTop = pmbmd - m_iNumMBX;
}
}
if (iMBX > 0) {
if (pmbmd->m_iVideoPacketNumber == (pmbmd - 1)->m_iVideoPacketNumber) {
pmbmLeft = m_rgpmbmCurr [iMBX - 1];
pmbmdLeft = pmbmd - 1;
}
}
if (iMBTop >= 0 && iMBX > 0) {
if (pmbmd->m_iVideoPacketNumber == (pmbmd - m_iNumMBX - 1)->m_iVideoPacketNumber) {
pmbmLeftTop = m_rgpmbmAbove [iMBX - 1];
pmbmdLeftTop = pmbmd - m_iNumMBX - 1;
}
}
PixelC* rgchBlkDst = NULL;
Int iWidthDst;
Int iDcScaler;
Int* rgiCoefQ;
for (Int iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
if (iBlk < (UInt) U_BLOCK) {
if (pmbmd -> m_rgTranspStatus [iBlk] == ALL)
continue;
switch (iBlk)
{
case (Y_BLOCK1):
rgchBlkDst = ppxlcCurrFrmQY;
break;
case (Y_BLOCK2):
rgchBlkDst = ppxlcCurrFrmQY + BLOCK_SIZE;
break;
case (Y_BLOCK3):
rgchBlkDst = ppxlcCurrFrmQY + m_iFrameWidthYxBlkSize;
break;
case (Y_BLOCK4):
rgchBlkDst = ppxlcCurrFrmQY + m_iFrameWidthYxBlkSize + BLOCK_SIZE;
break;
}
iWidthDst = m_iFrameWidthY;
iDcScaler = iDcScalerY;
}
else {
iWidthDst = m_iFrameWidthUV;
rgchBlkDst = (iBlk == U_BLOCK) ? ppxlcCurrFrmQU: ppxlcCurrFrmQV;
iDcScaler = iDcScalerC;
}
rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
BlockMemory blkmPred = NULL;
Int iQpPred = iQP; //default to current if no pred
decideIntraPred (blkmPred,
pmbmd,
iQpPred,
(BlockNum) iBlk,
pmbmLeft,
pmbmTop,
pmbmLeftTop,
m_rgpmbmCurr [iMBX],
pmbmdLeft,
pmbmdTop,
pmbmdLeftTop);
decodeIntraBlockTexture (rgchBlkDst,
iWidthDst,
iQP,
iDcScaler,
iBlk,
m_rgpmbmCurr [iMBX],
pmbmd,
blkmPred, //for intra-pred
iQpPred);
/*BBM// Added for Boundary by Hyundai(1998-5-9)
if (m_vopmd.bInterlace && pmbmd->m_bMerged [0]) {
Int iDstBlk = 0;
switch (iBlk) {
case (Y_BLOCK1):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -