Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

891 lines
27 KiB

/* *************************************************************************
** INTEL Corporation Proprietary Information
**
** This listing is supplied under the terms of a license
** agreement with INTEL Corporation and may not be copied
** nor disclosed except in accordance with the terms of
** that agreement.
**
** Copyright (c) 1995, 1996 Intel Corporation.
** All Rights Reserved.
**
** *************************************************************************
*/
/*****************************************************************************
*
* d1mblk.cpp
*
* DESCRIPTION:
* Decoder macro block functions
*
* Routines: Prototypes in:
* H263DecodeMBHeader d1dec.h
* H263DecodeMBData d1dec.h
*/
// $Header: S:\h26x\src\dec\d1mblk.cpv 1.23 20 Dec 1996 16:58:06 RHAZRA $
// $Log: S:\h26x\src\dec\d1mblk.cpv $
//
// Rev 1.23 20 Dec 1996 16:58:06 RHAZRA
// Fixed bitstream docoding for the case where MB stuffing is inserted
// between MBs. This was identified by a PTEL bitstream. This fix needs
// to be verified with our other tests.
//
// Rev 1.22 16 Dec 1996 14:41:46 RHAZRA
//
// Changed a bitstream error ASSERT to a bonafide error
//
// Rev 1.21 18 Nov 1996 17:12:22 MBODART
// Replaced all debug message invocations with Active Movie's DbgLog.
//
// Rev 1.20 07 Nov 1996 15:44:08 SCDAY
//
// Added MMX_ClipAndScale to replace Raj's glue code
//
// Rev 1.19 04 Nov 1996 10:28:10 RHAZRA
// Changed the IDCT scaling table to be a DWORD table (with rounding
// factored in) that is declared as a static.
//
// Rev 1.18 31 Oct 1996 08:58:28 SCDAY
// Raj added support for MMX decoder
//
// Rev 1.17 26 Sep 1996 12:35:06 RHAZRA
// Forced the decoder to use the IA version of VLD_RLD_IQ routine even
// when MMX is on (since we don't have a corresponding MMX routine ... yet)
//
// Rev 1.16 05 Aug 1996 11:00:26 MBODART
//
// H.261 decoder rearchitecture:
// Files changed: d1gob.cpp, d1mblk.{cpp,h}, d1dec.{cpp,h},
// filelist.261, h261_32.mak
// New files: d1bvriq.cpp, d1idct.cpp
// Obsolete files: d1block.cpp
// Work still to be done:
// Update h261_mf.mak
// Optimize uv pairing in d1bvriq.cpp and d1idct.cpp
// Fix checksum code (it doesn't work now)
// Put back in decoder stats
//
// Rev 1.15 18 Mar 1996 17:02:12 AKASAI
//
// Added pragma code_seg("IACODE2") and changed the timing statistics.
// At one point changed GET_VAR_BITS into subroutine to save code
// space but it didn't so left it as a macro.
//
// Rev 1.14 26 Dec 1995 17:42:14 DBRUCKS
// changed bTimerIsOn to bTimingThisFrame
//
// Rev 1.13 26 Dec 1995 12:50:00 DBRUCKS
//
// fix copyright
// add timing code
// comment out define of DEBUG_MBLK
//
// Rev 1.12 05 Dec 1995 10:19:46 SCDAY
//
// Added assembler version of Spatial Loop Filter
//
// Rev 1.11 03 Nov 1995 11:44:30 AKASAI
//
// Changed the processing of MB checksum and MBA stuffing. Changed
// GET_VAR_BITS & GET_GT8_BITS for how to detect MBA stuffing code.
//
// Rev 1.10 01 Nov 1995 13:43:48 AKASAI
//
// Added support for loop filter. New routines call LpFilter,
// BlockAddSpecial and BlockCopySpecial.
//
// Rev 1.9 27 Oct 1995 18:17:20 AKASAI
//
// Put in fix "hack" to keep the block action stream pointers
// in sync between d1dec and d1mblk. With skip macro blocks some
// macroblocks were being processed multiple times. Still a problem
// when gob ends with a skip macroblock.
//
// Rev 1.8 26 Oct 1995 15:36:28 SCDAY
//
// Delta frames partially working -- changed main loops to accommodate
// skipped macroblocks by detecting next startcode
//
// Rev 1.7 17 Oct 1995 11:28:56 SCDAY
// Added error message if (MBA stuffing code found && Checksum not enabled)
//
// Rev 1.6 16 Oct 1995 16:28:02 AKASAI
// Fixed bug when CHECKSUM_MACRO_BLOCK_DETAIL & CHECKSUM_MACRO_BLOCK are
// both defined.
//
// Rev 1.5 16 Oct 1995 13:53:24 SCDAY
//
// Added macroblock level checksum
//
// Rev 1.4 06 Oct 1995 15:32:54 SCDAY
//
// Integrated with latest AKK d1block
//
// Rev 1.3 22 Sep 1995 14:48:46 SCDAY
//
// added more mblock header and data decoding
//
// Rev 1.2 20 Sep 1995 09:52:22 SCDAY
//
// eliminated a warning
//
// Rev 1.1 19 Sep 1995 15:24:10 SCDAY
//
// added H261 MBA parsing
//
// Rev 1.0 11 Sep 1995 13:51:52 SCDAY
// Initial revision.
//
// Rev 1.11 25 Aug 1995 09:16:32 DBRUCKS
// add ifdef DEBUG_MBLK
//
// Rev 1.10 23 Aug 1995 19:12:02 AKASAI
// Fixed gNewTAB_CBPY table building. Was using 8 as mask instead of 0xf.
//
// Rev 1.9 18 Aug 1995 15:03:22 CZHU
//
// Output more error message when DecodeBlock returns error.
//
// Rev 1.8 16 Aug 1995 14:26:54 CZHU
//
// Changed DWORD adjustment back to byte oriented reading.
//
// Rev 1.7 15 Aug 1995 09:54:18 DBRUCKS
// improve stuffing handling and add debug msg
//
// Rev 1.6 14 Aug 1995 18:00:40 DBRUCKS
// add chroma parsing
//
// Rev 1.5 11 Aug 1995 17:47:58 DBRUCKS
// cleanup
//
// Rev 1.4 11 Aug 1995 16:12:28 DBRUCKS
// add ptr check to MB data
//
// Rev 1.3 11 Aug 1995 15:10:58 DBRUCKS
// finish INTRA mb header parsing and callblock
//
// Rev 1.2 03 Aug 1995 14:30:26 CZHU
// Take block level operations out to d3block.cpp
//
// Rev 1.1 02 Aug 1995 10:21:12 CZHU
// Added asm codes for VLD of TCOEFF, inverse quantization, run-length decode.
//
// Rev 1.0 31 Jul 1995 13:00:08 DBRUCKS
// Initial revision.
//
// Rev 1.2 31 Jul 1995 11:45:42 CZHU
// changed the parameter list
//
// Rev 1.1 28 Jul 1995 16:25:52 CZHU
//
// Added per block decoding framework.
//
// Rev 1.0 28 Jul 1995 15:20:16 CZHU
// Initial revision.
//Block level decoding for H.26x decoder
#include "precomp.h" // rearch idct
/*****************************************************************************
*
* GET_VAR_BITS
*
* Read a variable number of bits using a lookup table.
*
* The input count should be the number of bits used to index the table.
* The output count is the number of bits in that symbol.
*
* The table should be initialized such that all don't care symbols match to
* the same value. Thus if the table is indexed by 6-bits a two bit symbol
* 01XX XX will be used to initialize all entries 0100 00 -> 0111 11. These
* entries will include an 8-bit length in the least significant byte.
*
* uCount - IN
* fpu8 - IN and OUT
* uWork - IN and OUT
* uBitsReady - IN and OUT
* uResult - OUT
* uCode - OUT
* fpTable - IN
*/
#define GET_VAR_BITS(uCount, fpu8, uWork, uBitsReady, uResult, uCode, uBitCount, fpTable) { \
while (uBitsReady < uCount) { \
uWork <<= 8; \
uBitsReady += 8; \
uWork |= *fpu8++; \
} \
/* calculate how much to shift off */ \
/* and get the code */ \
uCode = uBitsReady - uCount; \
uCode = (uWork >> uCode); \
/* read the data */ \
uResult = fpTable[uCode]; \
/* count of bits used */ \
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \
/* H.261 tables are reverse order from H.263 */ \
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \
uBitCount = uResult & 0xff00; \
uBitCount >>= 8; \
/* bits remaining */ \
uBitsReady = uBitsReady - uBitCount; \
/* special case for stuffing processing */ \
/* if (uBitsReady < 0) */ \
/* kluged to test for negative */ \
if (uBitsReady > 33) \
/* if (bStuffing) */ \
{ \
uWork <<= 8; \
uBitsReady += 8; \
uWork |= *fpu8++; \
} \
/* end special case for stuffing */ \
uWork &= GetBitsMask[uBitsReady]; \
}
#define GET_GT8_BITS(uCount, fpu8, uWork, uBitsReady, uResult, uCode, uBitCount, fpTable) { \
while (uBitsReady < uCount) { \
uWork <<= 8; \
uBitsReady += 8; \
uWork |= *fpu8++; \
} \
/* calculate how much to shift off */ \
/* and get the code */ \
uCode = uBitsReady - uCount; \
uCode = (uWork >> uCode); \
/* read the data */ \
uResult = fpTable[uCode]; \
/* count of bits used */ \
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \
/* H.261 tables are reverse order from H.263 */ \
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \
uBitCount = uResult & 0xff00; \
if ((uBitCount & 0x8000) == 0) /* if not negative */ \
{ \
uBitCount >>= 8; \
/* bits remaining */ \
uBitsReady = uBitsReady - uBitCount; \
/* special case for stuffing processing */ \
/* if (uBitsReady < 0) */ \
/* kluged to test for negative */ \
if (uBitsReady > 33) \
/* if (bStuffing) */ \
{ \
uWork <<= 8; \
uBitsReady += 8; \
uWork |= *fpu8++; \
} \
/* end special case for stuffing */ \
uWork &= GetBitsMask[uBitsReady]; \
} \
else \
uWork &= GetBitsMask[uBitsReady-8]; \
}
extern void BlockCopy(
U32 uDstBlock,
U32 uSrcBlock);
extern void BlockCopySpecial(
U32 uDstBlock,
U32 uSrcBlock);
extern void BlockAdd (
U32 uResidual,
U32 uRefBlock,
U32 uDstBlock);
extern void BlockAddSpecial (
U32 uResidual,
U32 uRefBlock,
U32 uDstBlock);
T_pFunc_VLD_RLD_IQ_Block pFunc_VLD_RLD_IQ_Block[2] = {VLD_RLD_IQ_Block,VLD_RLD_IQ_Block}; // New rearch
//T_pFunc_VLD_RLD_IQ_Block pFunc_VLD_RLD_IQ_Block[2] = {VLD_RLD_IQ_Block, MMX_VLD_RLD_IQ_Block}; // New rearch
/*****************************************************************************
*
* H263DecodeMBHeader
*
* Decode the MB header
*/
#pragma code_seg("IACODE1")
I32 H263DecodeMBHeader(
T_H263DecoderCatalog FAR * DC,
BITSTREAM_STATE FAR * fpbsState,
U32 * uReadChecksum)
{
I32 iReturn = ICERR_ERROR;
U8 FAR * fpu8;
U32 uBitsReady;
U32 uWork;
U32 uResult;
U32 uCode;
U32 uBitCount;
int bStuffing;
#define START_CODE 0xff18
#define STUFFING_CODE 0x0b22
//#define DEBUG_MBLK -- Turn this on with a define in the makefile.
#ifndef RING0
#ifdef DEBUG_MBLK
char buf120[120];
int iLength;
#endif
#endif
GET_BITS_RESTORE_STATE(fpu8, uWork, uBitsReady, fpbsState)
/* MBA --------------- */
/* ********************************************* */
/* minor table decode (>8 bits) not fully tested */
/* to do note: */
/* this is hacked */
/* change >8 bit processing to use major/minor */
/* tables and ONE GET_BITS routine */
/* ********************************************* */
ReadMBA:
bStuffing = 0;
GET_GT8_BITS(8, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, gTAB_MBA_MAJOR);
if (uResult == STUFFING_CODE)
{ /* is stuffing code */
bStuffing = 1;
/* do MB checksum stuff here */
#ifdef CHECKSUM_MACRO_BLOCK
GET_BITS_SAVE_STATE(fpu8, uWork, uBitsReady, fpbsState)
/* might want to move this to a separate function for readability */
GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult);
if (uResult == 1)
{
GET_FIXED_BITS(8, fpu8, uWork, uBitsReady, uResult);
if (uResult == 1)
{ /* indicates TCOEFF checksum processing */
/* read off all but the real checksum data */
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
/* now get real checksum data */
/* run */
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
*uReadChecksum = ((uResult & 0xff) << 24);
/* level */
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
*uReadChecksum = (*uReadChecksum | ((uResult & 0xff) << 16));
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
*uReadChecksum = (*uReadChecksum | ((uResult & 0xff) << 8));
/* sign */
GET_FIXED_BITS(9, fpu8, uWork, uBitsReady, uResult);
*uReadChecksum = (*uReadChecksum | (uResult & 0xff));
GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult);
}
else
{
DBOUT("ERROR :: H261MBChecksum :: Invalid Checksum Data :: ERROR");
iReturn = ICERR_ERROR;
goto done;
}
}
else
{
GET_BITS_RESTORE_STATE(fpu8, uWork, uBitsReady, fpbsState)
goto ReadMBA;
}
#else /* is MBA stuffing, but checksum not enabled */
GET_BITS_SAVE_STATE(fpu8, uWork, uBitsReady, fpbsState)
// GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult);
/*if (uResult == 1) {
DbgLog((LOG_ERROR, HDBG_ALWAYS, TEXT("ERROR :: Stuffing code found, Checksum not enabled :: ERROR")));
iReturn = ICERR_ERROR;
goto done;
} */
// if (uResult == 1)
// {
// GET_BITS_RESTORE_STATE(fpu8, uWork, uBitsReady, fpbsState)
// }
// else {
//GET_BITS_RESTORE_STATE(fpu8, uWork, uBitsReady, fpbsState)
// }
#endif
} /* end if (uResult == STUFFING_CODE) */
/* try this for now */
else
{
if (uResult == START_CODE)
{
I8 temp;
temp = (I8)(uResult & 0xff);
GET_VAR_BITS(16, fpu8, uWork, uBitsReady, uResult, uCode, uBitCount, (gTAB_MBA_MINOR + temp));
if (uResult != 0x1023)
{
DBOUT("ERROR :: Invalid startcode :: ERROR");
iReturn = ICERR_ERROR;
}
else
iReturn = START_CODE;
GET_BITS_SAVE_STATE(fpu8, uWork, uBitsReady, fpbsState)
goto done;
} /* end if (uResult == START_CODE) */
else /* is not stuffing */
{ /* if uResult negative, get more bits */
if (uResult & 0x8000)
{
I8 temp;
temp = (I8)(uResult & 0xff);
GET_VAR_BITS(11, fpu8, uWork, uBitsReady, uResult, uCode, uBitCount, (gTAB_MBA_MINOR + temp));
}
DC->uMBA = (uResult & 0xff);
}/* end else is not stuffing */
}
/* When MBA==Stuffing, we jump back to the start to look for MBA */
if (bStuffing)
goto ReadMBA;
/* MTYPE ---------------------------------------- */
GET_GT8_BITS(8, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, gTAB_MTYPE_MAJOR);
if (uResult & 0x8000)
{
I8 temp;
temp = (I8)(uResult & 0xff);
GET_VAR_BITS(10, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, (gTAB_MTYPE_MINOR + temp));
}
DC->uMBType = (uResult & 0xff);
/* MQUANT ---------------------------------------- */
if (DC->uMBType == 1 || DC->uMBType == 3 || DC->uMBType == 6 || DC->uMBType == 9)
{ /* get 5-bit MQuant */
GET_FIXED_BITS(5, fpu8, uWork, uBitsReady, uResult);
DC->uMQuant = (uResult & 0xff);
}
/* MVD ------------------------------------------- */
/* reset previous motion vectors */
/* if MB 0,11,22 */
/* if MBA != 1 or */
/* if previous MB was not MC */
if (DC->uMBType >3)
{
if ((DC->uMBA != 1) || (DC->i16LastMBA == 10) || (DC->i16LastMBA == 21))
DC->i8MVDH = DC->i8MVDV = 0;
/* get X motion vector */
GET_GT8_BITS(8, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, gTAB_MVD_MAJOR);
if (uResult & 0x8000)
{
I8 temp;
temp = (I8)(uResult & 0xff);
GET_VAR_BITS(11, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, (gTAB_MVD_MINOR + temp));
}
/* convert and make incremental */
DC->i8MVDH = gTAB_MV_ADJUST[DC->i8MVDH + (I8)(uResult & 0xff) + 32];
/* get Y motion vector */
GET_GT8_BITS(8, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, gTAB_MVD_MAJOR);
if (uResult & 0x8000)
{
I8 temp;
temp = (I8)(uResult & 0xff);
GET_VAR_BITS(11, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, (gTAB_MVD_MINOR + temp));
}
/* convert and make incremental */
DC->i8MVDV = gTAB_MV_ADJUST[DC->i8MVDV + (I8)(uResult & 0xff) + 32];
} /* end if (DC->MBType > 3) */
else
DC->i8MVDH = DC->i8MVDV = 0;
/* CBP --------------------------------------------- */
/* brute force method */
DC->uCBP = 0; /* for MType = 4 or 7 */
if (DC->uMBType == 2 || DC->uMBType == 3 || DC->uMBType == 5 || DC->uMBType == 6 || DC->uMBType == 8 || DC->uMBType == 9)
{ /* get CBP */
GET_VAR_BITS(9, fpu8, uWork, uBitsReady, uResult,
uCode, uBitCount, gTAB_CBP);
DC->uCBP = (uResult & 0xff);
} /* end get CBP */
else
if (DC->uMBType < 2) /* is intra */
DC->uCBP = 63; /* force CBP to 63 */
GET_BITS_SAVE_STATE(fpu8, uWork, uBitsReady, fpbsState)
iReturn = ICERR_OK;
#ifndef RING0
#ifdef DEBUG_MBLK
iLength = wsprintf(buf120, "MBType=%ld MQuant=%ld MVDH=%ld MVDV=%ld CBP=%ld",
DC->uMBType,
DC->uMQuant,
DC->i8MVDH,
DC->i8MVDV,
DC->uCBP);
DBOUT(buf120);
ASSERT(iLength < 120);
#endif
#endif
done:
return iReturn;
} /* end H263DecodeMBHeader() */
#pragma code_seg()
/*****************************************************************************
*
* H263DecodeMBData
*
* Decode each of the blocks in this macro block
*/
#pragma code_seg("IACODE1")
I32 H263DecodeMBData(
T_H263DecoderCatalog FAR * DC,
T_BlkAction FAR * fpBlockAction,
I32 iBlockNumber,
BITSTREAM_STATE FAR * fpbsState,
U8 FAR * fpu8MaxPtr,
U32 * uReadChecksum,
U32 **pN, // New rearch
T_IQ_INDEX ** pRUN_INVERSE_Q) // New rearch
{
I32 iResult = ICERR_ERROR;
int iCBP = (int) DC->uCBP;
int i;
U32 uBitsReady;
U32 uBitsReadIn;
U32 uBitsReadOut;
U8 u8Quant; /* quantization level for this block */
U8 FAR * fpu8;
U32 uByteCnt;
I8 mvx, mvy, mvx2, mvy2;
T_pFunc_VLD_RLD_IQ_Block pFunc_VLD =pFunc_VLD_RLD_IQ_Block[0];
U32 uCheckSum; /* checksum data returned from DecodeBlock */
#ifdef CHECKSUM_MACRO_BLOCK_DETAIL
char buf80[80];
int iMBDLength;
#endif
#ifdef CHECKSUM_MACRO_BLOCK
char buff80[80];
int iLength;
#endif
#ifdef DECODE_STATS
U32 uStartLow = DC->uStartLow;
U32 uStartHigh = DC->uStartHigh;
U32 uElapsed;
U32 uBefore;
U32 uDecodeBlockSum = 0;
U32 uLoopFilterSum = 0;
U32 uBlockCopySum = 0;
U32 uBlockCopySpSum = 0;
U32 uBlockAddSum = 0;
U32 uBlockAddSpSum = 0;
int bTimingThisFrame = DC->bTimingThisFrame;
DEC_TIMING_INFO * pDecTimingInfo = NULL;
#endif
/* On input the pointer points to the next byte. */
/* We need to change it to */
/* point to the current word on a 32-bit boundary. */
fpu8 = fpbsState->fpu8 - 1; /* point to the current byte */
uBitsReady = fpbsState->uBitsReady;
while (uBitsReady >= 8) {
fpu8--;
uBitsReady -= 8;
}
uBitsReadIn = 8 - uBitsReady;
u8Quant = (U8) (DC->uMQuant);
if (DC->uMBType > 1)
{
/* calculate motion vectors */
mvx = DC->i8MVDH;
mvy = DC->i8MVDV;
// calculate UV blocks MV
mvx2 = mvx / 2;
mvy2 = mvy / 2;
fpBlockAction->i8MVX = mvx;
fpBlockAction->i8MVY = mvy;
// duplicate other 3 Y blocks
fpBlockAction[1].i8MVX = mvx;
fpBlockAction[1].i8MVY = mvy;
fpBlockAction[2].i8MVX = mvx;
fpBlockAction[2].i8MVY = mvy;
fpBlockAction[3].i8MVX = mvx;
fpBlockAction[3].i8MVY = mvy;
// init UV blocks
fpBlockAction[4].i8MVX = mvx2;
fpBlockAction[4].i8MVY = mvy2;
fpBlockAction[5].i8MVX = mvx2;
fpBlockAction[5].i8MVY = mvy2;
}
uCheckSum = 0; /* Init MB Checksum */
for (i = 0; i < 6; i++)
{
if (DC->uMBType <= 1) /* is intra */
fpBlockAction->u8BlkType = BT_INTRA;
else
if (iCBP & 0x20) /* if coded */
fpBlockAction->u8BlkType = BT_INTER;
else
fpBlockAction->u8BlkType = BT_EMPTY;
if (fpBlockAction->u8BlkType != BT_EMPTY)
{
fpBlockAction->u8Quant = u8Quant;
ASSERT(fpBlockAction->pCurBlock != NULL);
ASSERT(fpBlockAction->uBlkNumber == (U32)iBlockNumber);
/*----- DecodeBlock ----*/
#ifdef DECODE_STATS
TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
#endif
#ifdef CHECKSUM_MACRO_BLOCK
// uBitsReadOut = DecodeBlock(fpBlockAction, fpu8, uBitsReadIn, (U32)DC+DC->uMBBuffer+i*256, fpBlockAction->pCurBlock, &uCheckSum);
#else
// rearch
uBitsReadOut = (*pFunc_VLD) ( fpBlockAction,
fpu8,
uBitsReadIn,
(U32 *) *pN,
(U32 *) *pRUN_INVERSE_Q);
// rearch
#endif
#ifdef DECODE_STATS
TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uDecodeBlockSum)
#endif
if (uBitsReadOut == 0)
{
DBOUT("ERROR :: H263DecodeMBData :: Error decoding a Y block :: ERROR");
DBOUT("ERROR :: DecodeBlock return 0 bits read....");
goto done;
}
uByteCnt = uBitsReadOut >> 3; /* divide by 8 */
uBitsReadIn = uBitsReadOut & 0x7; /* mod 8 */
fpu8 += uByteCnt;
/* New for rearch */
ASSERT ( **pN < 65 );
////////////////////////////////////////////////
// End hack //
////////////////////////////////////////////////
*pRUN_INVERSE_Q += **pN;
if ((0xf & fpBlockAction->u8BlkType) != BT_INTER)
**pN += 65;
(*pN)++;
/* end of new rearch */
/* allow the pointer to address up to four beyond */
/* the end reading by DWORD using postincrement. */
/* changed for detection of stuffing code at */
/* end of frame */
// ASSERT(fpu8 <= (fpu8MaxPtr+14));
if (fpu8 > (fpu8MaxPtr+14))
{
iResult = ICERR_ERROR; // probably not needed
goto done;
}
} /* end if not empty */
else /* is empty */
{ /* zero out intermediate data structure and advance pointers */
/* New for rearch */
**pN = 0;
(*pN)++;
/* end of new rearch */
}
fpBlockAction++;
iCBP <<= 1;
iBlockNumber++;
} /* end for each block in macroblock */
#ifdef CHECKSUM_MACRO_BLOCK
/* Compare checksum */
if ((uCheckSum != *uReadChecksum) && (*uReadChecksum != 0))
{
iLength = wsprintf(buff80,"WARNING:MB CheckSum miss match, Enc Checksum=0x%x Dec Checksum=0x%x",
*uReadChecksum, uCheckSum);
DBOUT(buff80);
ASSERT(iLength < 80);
}
#ifdef CHECKSUM_MACRO_BLOCK_DETAIL
iMBDLength = wsprintf(buf80,"Block=%d CheckSum=0x%x", i, uCheckSum);
DBOUT(buf80);
ASSERT(iMBDLength < 80);
#endif
#endif
/* restore the scanning pointers to point to the next byte */
/* and set the uWork and uBitsReady values. */
while (uBitsReadIn > 8)
{
fpu8++;
uBitsReadIn -= 8;
}
fpbsState->uBitsReady = 8 - uBitsReadIn;
fpbsState->uWork = *fpu8++; /* store the data and point to next byte */
fpbsState->uWork &= GetBitsMask[fpbsState->uBitsReady];
fpbsState->fpu8 = fpu8;
#ifdef DECODE_STATS
if (bTimingThisFrame)
{
pDecTimingInfo = DC->pDecTimingInfo + DC->uStatFrameCount;
pDecTimingInfo->uDecodeBlock += uDecodeBlockSum;
pDecTimingInfo->uLoopFilter += uLoopFilterSum;
pDecTimingInfo->uBlockCopy += uBlockCopySum;
pDecTimingInfo->uBlockCopySp += uBlockCopySpSum;
pDecTimingInfo->uBlockAdd += uBlockAddSum;
pDecTimingInfo->uBlockAddSp += uBlockAddSpSum;
}
#endif
iResult = ICERR_OK;
done:
return iResult;
} /* H263DecodeMBData() */
#pragma code_seg()
/*****************************************************************************
*
* H263IDCTandMC
*
* Inverse Discrete Cosine Transform and
* Motion Compensation for each block
*
*/
#pragma code_seg("IACODE2")
void H263IDCTandMC(
T_H263DecoderCatalog FAR *DC,
T_BlkAction FAR *fpBlockAction,
int iBlock,
int iMBNum, // AP-NEW
int iGOBNum, // AP-NEW
U32 *pN,
T_IQ_INDEX *pRUN_INVERSE_Q,
T_MBInfo *fpMBInfo, // AP-NEW
int iEdgeFlag
)
{
I32 pRef;
I32 mvx, mvy;
ASSERT(*pN != 65);
if (*pN < 65) // Inter block
{
// first do motion compensation
// result will be pointed to by pRef
mvx = fpBlockAction[iBlock].i8MVX;
mvy = fpBlockAction[iBlock].i8MVY;
pRef = fpBlockAction[iBlock].pRefBlock + (I32) mvx + PITCH * (I32) mvy;
// now do the inverse transform (where appropriate) & combine
if (*pN > 0) // and, of course, < 65.
{
// Get residual block; output at DC+DC->uMBBuffer+BLOCK_BUFFER_OFFSET
// Finally add the residual to the reference block
// TODO
DecodeBlock_IDCT(
(U32)pRUN_INVERSE_Q,
*pN,
fpBlockAction[iBlock].pCurBlock, // not used here
(U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET);// inter output
if (fpMBInfo->i8MBType >=7)
{
// do spatial loop filter
LoopFilter((U8 *)pRef, (U8*)DC+DC->uFilterBBuffer, PITCH);
BlockAddSpecial((U32)DC+DC->uMBBuffer + BLOCK_BUFFER_OFFSET,
(U32)DC+DC->uFilterBBuffer,
fpBlockAction[iBlock].pCurBlock);
}
else
{
BlockAdd(
(U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET, // output
pRef, // prediction
fpBlockAction[iBlock].pCurBlock); // destination
}
}
else // *pN == 0, so no transform coefficients for this block
{
// Just copy motion compensated reference block
if (fpMBInfo->i8MBType >=7)
{
// do spatial loop filter
LoopFilter((U8 *)pRef, (U8*)DC+DC->uFilterBBuffer, PITCH);
//MMX_LoopFilter((U8 *)pRef, (U8*)DC+DC->uFilterBBuffer, 8);
BlockCopySpecial(fpBlockAction[iBlock].pCurBlock,
(U32)DC+DC->uFilterBBuffer);
}
else
BlockCopy(
fpBlockAction[iBlock].pCurBlock, // destination
pRef); // prediction
}
}
else // *pN >= 65, hence intRA
{
// TODO
DecodeBlock_IDCT(
(U32)pRUN_INVERSE_Q,
*pN,
fpBlockAction[iBlock].pCurBlock, // intRA transform output
(U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET);
} // end if (*pN < 65) ... else ...
}
// End IDCTandMC
////////////////////////////////////////////////////////////////////////////////
#pragma code_seg()