📄 sptdec.cpp
字号:
/*************************************************************************
This software module was originally developed by
Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
(date: Augest, 1997)
and also edited by
David B. Shu (dbshu@hrl.com), Hughes Electronics/HRL Laboratories
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:
sptdec.cpp
Abstract:
Sprite decoder.
Revision History:
*************************************************************************/
#include <stdio.h>
#include <fstream.h>
#include <math.h>
#include "typeapi.h"
#include "codehead.h"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "global.hpp"
#include "mode.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_
#ifdef __PC_COMPILER_
#define IOSBINARY ios::binary
#else
#define IOSBINARY ios::bin
#endif // __PC_COMPILER_
Int CVideoObjectDecoder::decodeSpt ()
{
//David Shu: please insert your stuff in this function
assert (m_vopmd.vopPredType == SPRITE);
if (m_iNumOfPnts > 0)
decodeWarpPoints ();
// Begin: modified by Hughes 4/9/98
if (m_sptMode != BASIC_SPRITE)
decodeSpritePieces ();
// End: modified by Hughes 4/9/98
if (m_iNumOfPnts > 0) {
CRct rctWarp = (m_volmd.fAUsage != RECTANGLE)? m_rctCurrVOPY : CRct (0, 0, m_ivolWidth, m_ivolHeight);
if(m_iNumOfPnts==2 || m_iNumOfPnts==3) {
FastAffineWarp (rctWarp, rctWarp / 2, m_uiWarpingAccuracy, m_iNumOfPnts);
}
else {
CPerspective2D perspYA (m_iNumOfPnts, m_rgstSrcQ, m_rgstDstQ, m_uiWarpingAccuracy);
warpYA (perspYA, rctWarp, m_uiWarpingAccuracy);
CSiteD rgstSrcQUV [4], rgstDstQUV [4];
for (Int i = 0; i < m_iNumOfPnts; i++) {
rgstSrcQUV [i] = (m_rgstSrcQ [i] - CSiteD (0.5, 0.5)) / 2;
rgstDstQUV [i] = (m_rgstDstQ [i] - CSiteD (0.5, 0.5)) / 2;
}
CPerspective2D perspUV (m_iNumOfPnts, rgstSrcQUV, rgstDstQUV, m_uiWarpingAccuracy);
warpUV (perspUV, rctWarp / 2, m_uiWarpingAccuracy);
}
}
return TRUE;
}
Void CVideoObjectDecoder::decodeWarpPoints ()
{
assert (m_iNumOfPnts > 0);
// Dest corner points MV decoding
Int rgiU [4], rgiV [4], rgiDU [4], rgiDV [4];
Int rgiWrpPnt0Del [2];
CInBitStream* pibstrmWrpPt0 = m_pentrdecSet->m_pentrdecWrpPnt -> bitstream ();
Int j;
for (j = 0; j < m_iNumOfPnts; j++) {
for (UInt iXorY = 0; iXorY < 2; iXorY++) {
Long lSz = m_pentrdecSet->m_pentrdecWrpPnt->decodeSymbol();
Int iSign = pibstrmWrpPt0->peekBits (1); //get the sign
if (iSign == 1)
rgiWrpPnt0Del[iXorY] = pibstrmWrpPt0->getBits (lSz);
else {
Int iAbsWrpPnt0Del = ~(pibstrmWrpPt0->getBits (lSz)); //get the magnitude
Int iMask = ~(0xFFFFFFFF << lSz); //mask out the irrelavent bits
rgiWrpPnt0Del[iXorY] = -1 * (iAbsWrpPnt0Del & iMask); //masking and signing
}
assert (rgiWrpPnt0Del[iXorY] >= -16383 && rgiWrpPnt0Del[iXorY] <= 16383);
Int iMarker = pibstrmWrpPt0->getBits(1);
assert(iMarker==1);
}
rgiDU [j] = rgiWrpPnt0Del[0];
rgiDV [j] = rgiWrpPnt0Del[1];
}
// create Src VOP bounding box
switch (m_iNumOfPnts) {
case 1:
m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
break;
case 2:
m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
m_rgstSrcQ [1] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.top);
break;
case 3:
m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
m_rgstSrcQ [1] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.top);
m_rgstSrcQ [2] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.bottom);
break;
case 4:
m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
m_rgstSrcQ [1] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.top);
m_rgstSrcQ [2] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.bottom);
m_rgstSrcQ [3] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.bottom);
break;
}
// Dest corner points reconstruction
rgiU [0] = rgiDU [0]; rgiV [0] = rgiDV [0];
rgiU [1] = rgiDU [1] + rgiU [0]; rgiV [1] = rgiDV [1] + rgiV [0];
rgiU [2] = rgiDU [2] + rgiU [0]; rgiV [2] = rgiDV [2] + rgiV [0];
rgiU [3] = rgiDU [3] + rgiU [2] + rgiU [1] - rgiU [0]; rgiV [3] = rgiDV [3] + rgiV [2] + rgiV [1] - rgiV [0];
for (j = 0; j < m_iNumOfPnts; j++) {
m_rgstDstQ [j].x = (rgiU [j] + 2 * m_rgstSrcQ [j].x) / 2.0;
m_rgstDstQ [j].y = (rgiV [j] + 2 * m_rgstSrcQ [j].y) / 2.0;
}
}
Void CVideoObjectDecoder::decodeInitSprite ()
// decode initial sprite piece and initialize MB status array
{
Int iMod = m_rctSpt.width % MB_SIZE;
Int iSptWidth = (iMod > 0) ? m_rctSpt.width + MB_SIZE - iMod : m_rctSpt.width;
iMod = m_rctSpt.height () % MB_SIZE;
Int iSptHeight = (iMod > 0) ? m_rctSpt.height () + MB_SIZE - iMod : m_rctSpt.height ();
// Begin: modified by Hughes 4/9/98
// m_rctSptExp = m_pvopcRefQ1->whereY();
if (m_sptMode == BASIC_SPRITE)
{
m_rctCurrVOPY = CRct (0, 0, iSptWidth, iSptHeight);
m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
decode ();
if (m_iNumOfPnts > 0) {
swapRefQ1toSpt ();
changeSizeofCurrQ (m_rctDisplayWindow);
}
m_pbitstrmIn->flush (8);
return ;
}
// end: modified by Hughes 4/9/98
m_rctSptQ = CRct (0, 0, iSptWidth, iSptHeight) ; // save sprite object information
Int iNumMBX = iSptWidth / MB_SIZE; //for the whole sprite
Int iNumMBY = iSptHeight / MB_SIZE;//for the whole sprite
m_ppPieceMBstatus = new SptMBstatus* [iNumMBY];
m_ppUpdateMBstatus = new SptMBstatus* [iNumMBY];
// dshu: [v071] Begin of modification
Int iNumMB = iNumMBX * iNumMBY;
m_rgmbmdSprite = new CMBMode [iNumMB];
// dshu: [v071] end of modification
m_rgmbmdSpt = new CMBMode* [iNumMBY];
m_rgpmbmCurr_Spt = new MacroBlockMemory** [iNumMBY];
// Begin: modified by Hughes 4/9/98
Int iMBY;
// Int iMBX, iMBY;
// end: modified by Hughes 4/9/98
Int iMB, iBlk;
Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
// Allocate MB hole status array and reconstructed MB array
for (iMBY = 0; iMBY < iNumMBY; iMBY++) {
m_ppPieceMBstatus[iMBY] = new SptMBstatus [iNumMBX];
m_ppUpdateMBstatus[iMBY] = new SptMBstatus [iNumMBX];
m_rgmbmdSpt[iMBY] = new CMBMode [iNumMBX];
m_rgpmbmCurr_Spt[iMBY] = new MacroBlockMemory* [iNumMBX];
for (iMB = 0; iMB < iNumMBX; iMB++) {
m_rgpmbmCurr_Spt[iMBY][iMB] = new MacroBlockMemory;
m_rgpmbmCurr_Spt[iMBY][iMB]->rgblkm = new BlockMemory [nBlk];
for (iBlk = 0; iBlk < nBlk; iBlk++) {
(m_rgpmbmCurr_Spt[iMBY][iMB]->rgblkm) [iBlk] = new Int [(BLOCK_SIZE << 1) - 1];
}
// Begin: modified by Hughes 4/9/98
m_ppPieceMBstatus[iMBY][iMB] = NOT_DONE;
m_ppUpdateMBstatus[iMBY][iMB] = NOT_DONE;
// end: modified by Hughes 4/9/98
}
}
// Begin: modified by Hughes 4/9/98
CRct rctSptQ48 = m_pvopcRefQ1->whereY();
m_pvopcSptQ = new CVOPU8YUVBA (m_volmd.fAUsage, rctSptQ48);
m_pvopcSptQ -> shift (m_rctSpt.left, m_rctSpt.top); // change to absolute value in sprite coordinates
m_pbitstrmIn->flush ();
m_tPiece = 0;
m_rctCurrVOPY = m_rctSptQ;
m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
if (m_volmd.fAUsage != RECTANGLE) {
m_iNumMBRef = iNumMB;
m_iNumMBXRef = iNumMBX;
m_iNumMBYRef = iNumMBY;
m_iOffsetForPadY = m_rctRefFrameY.offset (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -