/* ************************************************************************* ** 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 Intel Corporation. ** All Rights Reserved. ** ** ************************************************************************* */ /***************************************************************************** * * d3pict.cpp * * Description: * This modules contains the picture header parsing routines * * Routines: * H263ReadPictureHeader * * Data: */ /* $Header: S:\h26x\src\dec\d3pict.cpv 1.21 05 Feb 1997 12:24:30 JMCVEIGH $ * $Log: S:\h26x\src\dec\d3pict.cpv $ // // Rev 1.21 05 Feb 1997 12:24:30 JMCVEIGH // Support for latest H.263+ draft bitstream spec. // // Rev 1.20 16 Dec 1996 17:42:56 JMCVEIGH // Existence of extended PTYPE implies improved PB-frame mode if // a PB-frame. Also, initialized H.263+ optional flags if EPTYPE not // read. // // Rev 1.19 11 Dec 1996 14:59:12 JMCVEIGH // // Allow deblocking filter in reading of picture header. // // Rev 1.18 09 Dec 1996 18:02:10 JMCVEIGH // Added support for arbitrary frame sizes. // // Rev 1.17 31 Oct 1996 10:18:22 KLILLEVO // changed one (commented out) DBOUT to DbgLog // // Rev 1.16 20 Oct 1996 15:49:50 AGUPTA2 // Adjusted DbgLog trace levels; 4:Frame, 5:GOB, 6:MB, 8:everything // // Rev 1.15 20 Oct 1996 14:05:54 AGUPTA2 // Minor change in one of the DbgLog calls. // // // Rev 1.14 20 Oct 1996 13:21:44 AGUPTA2 // Changed DBOUT into DbgLog. ASSERT is not changed to DbgAssert. // // // Rev 1.13 30 May 1996 10:16:32 KLILLEVO // removed to variables only needed for DEBUG_DECODER // // Rev 1.12 30 May 1996 10:14:44 KLILLEVO // removed one debug statement // // Rev 1.11 24 May 1996 10:47:00 KLILLEVO // added ifdef _DEBUG arounf wsprintf // // Rev 1.10 03 May 1996 13:06:36 CZHU // // Check bit 2 for packet loss errors to trigger packet loss recovery // // Rev 1.9 18 Dec 1995 12:49:54 RMCKENZX // added copyright notice & log stamp */ #include "precomp.h" /* BIT field Constants */ const int BITS_PICTURE_STARTCODE = 22; #ifdef SIM_OUT_OF_DATE const int BITS_TR = 5; #else const int BITS_TR = 8; #endif const int BIT_ONE_VAL = 1; const int BIT_TWO_VAL = 0; const int BITS_PTYPE_SOURCE_FORMAT = 3; #ifdef H263P // H.263+ draft, document LBC-96-358R3 const int BITS_EPTYPE_RESERVED = 5; const int EPTYPE_RESERVED_VAL = 1; const int BITS_CSFMT_PARC = 4; // Custom source format pixel aspect ratio code const int BITS_CSFMT_FWI = 9; // Custom source format frame width indication const int BIT_CSFMT_14_VAL = 1; // Prevents start code emulation const int BITS_CSFMT_FHI = 9; // Custom source format frame height indication const int BITS_PAR_WIDTH = 8; // Pixel aspect ratio width const int BITS_PAR_HEIGHT = 8; // Pixel aspect ratio height #endif const int BITS_PQUANT = 5; const int BITS_TRB = 3; const int BITS_DBQUANT = 2; const int BITS_PSPARE = 8; //not includeing the following PEI /* PSC_VALUE - 0000 0000 0000 0000 - 1000 00xx xxxx xxxx */ const U32 PSC_VALUE = (0x00008000 >> (32-BITS_PICTURE_STARTCODE)); /* We only want to search so far before it is considered an error */ const int MAX_LOOKAHEAD_NUMBER = 256; /* number of bits */ /***************************************************************************** * * H263DecodePictureHeader * * Read and parse the picture header - updating the fpbsState if the read * succeeds. * * Returns an ICERR_STATUS */ extern I32 H263DecodePictureHeader( T_H263DecoderCatalog FAR * DC, U8 FAR * fpu8, U32 uBitsReady, U32 uWork, BITSTREAM_STATE FAR * fpbsState) { I32 iReturn; int iLookAhead; U32 uResult; U32 uData; int iSpareCount; FX_ENTRY("H263DecodePictureHeader") // PSC ---------------------------------------- GET_FIXED_BITS((U32) BITS_PICTURE_STARTCODE, fpu8, uWork, uBitsReady, uResult); iLookAhead = 0; while (uResult != PSC_VALUE) { uResult = uResult << 1; uResult &= GetBitsMask[BITS_PICTURE_STARTCODE]; GET_ONE_BIT(fpu8, uWork, uBitsReady, uData); uResult |= uData; iLookAhead++; if (iLookAhead > MAX_LOOKAHEAD_NUMBER) { ERRORMESSAGE(("%s: Missing PSC\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } } GET_FIXED_BITS((U32) BITS_TR, fpu8, uWork, uBitsReady, uResult); DC->uTempRefPrev = DC->uTempRef; DC->uTempRef = uResult; // PTYPE ---------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); if (uResult != BIT_ONE_VAL) { ERRORMESSAGE(("%s: PTYPE bit 1 error\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); if (uResult != BIT_TWO_VAL) { ERRORMESSAGE(("%s: PTYPE bit 2 error\r\n", _fx_)); //#ifdef LOSS_RECOVERY GET_BITS_SAVE_STATE(fpu8, uWork, uBitsReady, fpbsState); iReturn = PACKET_FAULT; //#endif goto done; } GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bSplitScreen = (U16) uResult; GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bCameraOn = (U16) uResult; GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bFreezeRelease = (U16) uResult; GET_FIXED_BITS((U32) BITS_PTYPE_SOURCE_FORMAT, fpu8, uWork, uBitsReady, uResult); #ifdef H263P // We don't need to check that the frame dimensions are supported here. // This is handled in DecompressQuery() // Custom format is forbidden in PTYPE if (uResult == SRC_FORMAT_FORBIDDEN || uResult == SRC_FORMAT_CUSTOM) { ERRORMESSAGE(("%s: Forbidden src format\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } #else #ifdef USE_BILINEAR_MSH26X if (uResult == SRC_FORMAT_FORBIDDEN) #else if (uResult == SRC_FORMAT_FORBIDDEN || uResult > SRC_FORMAT_CIF) #endif { ERRORMESSAGE(("%s: Src format not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } #endif DC->uPrevSrcFormat = DC->uSrcFormat; DC->uSrcFormat = uResult; #ifdef H263P // We don't support changes in the source format between frames. However, // if either the current or previous source format in PTYPE indicates // extended PTYPE, we do not know if the actual format (i.e., frame size) // has changed, yet if (DC->bReadSrcFormat && DC->uPrevSrcFormat != DC->uSrcFormat && DC->uSrcFormat != SRC_FORMAT_EPTYPE) #else if (DC->bReadSrcFormat && DC->uPrevSrcFormat != DC->uSrcFormat) #endif { ERRORMESSAGE(("%s: Src format not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } #ifdef H263P // The actual source format has not been read if this is the // first frame and we detected an extended PTYPE if (DC->bReadSrcFormat || DC->uSrcFormat != SRC_FORMAT_EPTYPE) // We have read the actual source format, so mark flag as true. DC->bReadSrcFormat = 1; #else DC->bReadSrcFormat = 1; #endif GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bKeyFrame = (U16) !uResult; GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bUnrestrictedMotionVectors = (U16) uResult; GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bArithmeticCoding = (U16) uResult; GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bAdvancedPrediction = (U16) uResult; // If bit 12 is set to "1", bit 10 shall be set to "1" as well. (5.1.3 p14) /* if (DC->bAdvancedPrediction && !DC->bUnrestrictedMotionVectors) { ERRORMESSAGE(("%s: Warning: bit 12 is one and bit 10 is zero\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } */ GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bPBFrame = (U16) uResult; // If bit 9 is set to "0", bit 13 shall be set to "0" as well." (5.1.3 p11) if (DC->bKeyFrame && DC->bPBFrame) { ERRORMESSAGE(("%s: A key frame can not be a PB frame\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } #ifdef H263P // EPTYPE -------------------------------------- if (DC->uSrcFormat == SRC_FORMAT_EPTYPE) { // Extended PTYPE detected in PTYPE. // We need to read the source format (again) and the optional mode flags. GET_FIXED_BITS((U32) BITS_PTYPE_SOURCE_FORMAT, fpu8, uWork, uBitsReady, uResult); if (uResult == SRC_FORMAT_FORBIDDEN || uResult == SRC_FORMAT_RESERVED) { ERRORMESSAGE(("%s: Forbidden or reserved src format\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } DC->uSrcFormat = uResult; // DC->uPrevSrcFormat has already been saved // Check to make sure that the picture size has not changed between frames. if (DC->bReadSrcFormat && DC->uPrevSrcFormat != DC->uSrcFormat) { ERRORMESSAGE(("%s: Src format changed\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } DC->bReadSrcFormat = 1; // The actual source format has finally been read // Optional modes: // Custom PCF --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bCustomPCF = (U16) uResult; if (DC->bCustomPCF) { ERRORMESSAGE(("%s: Custom PCF not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Advanced intra coding --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bAdvancedIntra = (U16) uResult; if (DC->bAdvancedIntra) { ERRORMESSAGE(("%s: Advanced intra coding not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Deblocking filter --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bDeblockingFilter = (U16) uResult; // Slice structured --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bSliceStructured = (U16) uResult; if (DC->bSliceStructured) { ERRORMESSAGE(("%s: Slice structured mode not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Improved PB-frames --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bImprovedPBFrames = (U16) uResult; // Back channel operation --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bBackChannel = (U16) uResult; if (DC->bBackChannel) { ERRORMESSAGE(("%s: Back-channel operation not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Scalability --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bScalability = (U16) uResult; if (DC->bScalability) { ERRORMESSAGE(("%s: Scalability mode not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // True B-frame mode --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bTrueBFrame = (U16) uResult; if (DC->bTrueBFrame) { ERRORMESSAGE(("%s: True B-frames not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Reference-picture resampling --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bResampling = (U16) uResult; if (DC->bResampling) { ERRORMESSAGE(("%s: Reference-picture resampling not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Reduced-resolution update --------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bResUpdate = (U16) uResult; if (DC->bResUpdate) { ERRORMESSAGE(("%s: Reduced resolution update not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Resevered bits GET_FIXED_BITS((U32) BITS_EPTYPE_RESERVED, fpu8, uWork, uBitsReady, uResult); if (uResult != EPTYPE_RESERVED_VAL) { ERRORMESSAGE(("%s: Invalid reserved code in EPTYPE\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } } // end if (DC->uSrcFormat == SRC_FORMAT_EPTYPE) else // end if (DC->uSrcFormat == SRC_FORMAT_EPTYPE) { // We might never read these optional flags, so set them to // false if not extended PTYPE DC->bImprovedPBFrames = FALSE; DC->bAdvancedIntra = FALSE; DC->bDeblockingFilter = FALSE; DC->bSliceStructured = FALSE; DC->bCustomPCF = FALSE; DC->bBackChannel = FALSE; DC->bScalability = FALSE; DC->bTrueBFrame = FALSE; DC->bResampling = FALSE; DC->bResUpdate = FALSE; } // CSFMT -------------------------------------- if (DC->uSrcFormat == SRC_FORMAT_CUSTOM) { // Custom source format detected. We need to read the aspect ratio // code and the frame width and height indications. // Pixel aspect ratio code GET_FIXED_BITS((U32) BITS_CSFMT_PARC, fpu8, uWork, uBitsReady, uResult); U16 uPARC = (U16)uResult; // Frame width indication GET_FIXED_BITS((U32) BITS_CSFMT_FWI, fpu8, uWork, uBitsReady, uResult); // The number of pixels per line is given by (FWI+1)*4. We do not // support cases where the picture width differs from that given in the // DC->uActualFrameWidth parameter. if (DC->uActualFrameWidth != ((uResult + 1) << 2)) { ERRORMESSAGE(("%s: Frame width change not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Bit 13 must be "1" to prevent start code emulation GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); if (uResult != BIT_CSFMT_14_VAL) { ERRORMESSAGE(("%s: CSFMT bit 13 != 1\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // Frame height indication GET_FIXED_BITS((U32) BITS_CSFMT_FHI, fpu8, uWork, uBitsReady, uResult); // The number of lines is given by (FHI+1)*4. We do not // support cases where the picture height differs from that given in the // DC->uActualFrameHeight parameter. if (DC->uActualFrameHeight != ((uResult + 1) << 2)) { ERRORMESSAGE(("%s: Frame height change not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } switch (uPARC) { case PARC_SQUARE: DC->uPARWidth = 1; DC->uPARHeight = 1; break; case PARC_CIF: DC->uPARWidth = 12; DC->uPARHeight = 11; break; case PARC_10_11: DC->uPARWidth = 10; DC->uPARHeight = 11; break; case PARC_EXTENDED: GET_FIXED_BITS((U32) BITS_PAR_WIDTH, fpu8, uWork, uBitsReady, uResult); DC->uPARWidth = uResult; if (DC->uPARWidth == 0) { ERRORMESSAGE(("%s: Forbidden pixel aspect ratio width\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } GET_FIXED_BITS((U32) BITS_PAR_HEIGHT, fpu8, uWork, uBitsReady, uResult); DC->uPARHeight = uResult; if (DC->uPARHeight == 0) { ERRORMESSAGE(("%s: Forbidden pixel aspect ratio height\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } break; default: ERRORMESSAGE(("%s: Unsupported pixel aspect ratio code\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } } // end if (DC->uSrcFormat == SRC_FORMAT_CUSTOM) #endif // H263P // PQUANT -------------------------------------- GET_FIXED_BITS((U32) BITS_PQUANT, fpu8, uWork, uBitsReady, uResult); DC->uPQuant = uResult; // CPM ----------------------------------------- GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); DC->bCPM = (U16) uResult; if (DC->bCPM) { ERRORMESSAGE(("%s: Continuous Presence Multipoint is not supported\r\n", _fx_)); iReturn = ICERR_ERROR; goto done; } // PLCI ---------------------------------------- if (DC->bCPM) { // TBD("TBD: PLCI"); iReturn = ICERR_ERROR; goto done; } if (DC->bPBFrame) { GET_FIXED_BITS((U32) BITS_TRB, fpu8, uWork, uBitsReady, uResult); DC->uBFrameTempRef = uResult; GET_FIXED_BITS((U32) BITS_DBQUANT, fpu8, uWork, uBitsReady, uResult); DC->uDBQuant = uResult; } else { DC->uBFrameTempRef = 12345678; /* clear the values */ DC->uDBQuant = 12345678; } // skip spare bits iSpareCount = 0; GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); while (uResult) { GET_FIXED_BITS((U32) BITS_PSPARE, fpu8, uWork, uBitsReady, uResult); GET_ONE_BIT(fpu8, uWork, uBitsReady, uResult); iSpareCount += BITS_PSPARE; } DEBUGMSG(ZONE_DECODE_PICTURE_HEADER, ("%s: TR=%ld SS=%d CAM=%d FRZ=%d SRC=%ld PCT=%d UMV=%d AC=%d AP=%d PB=%d CPM=%d PQ=%ld TRB=%ld DBQ=%ld Spare=%d\r\n", _fx_, DC->uTempRef, DC->bSplitScreen, DC->bCameraOn, DC->bFreezeRelease, DC->uSrcFormat, !DC->bKeyFrame, DC->bUnrestrictedMotionVectors, DC->bArithmeticCoding, DC->bAdvancedPrediction, DC->bPBFrame, DC->bCPM, DC->uPQuant, DC->uBFrameTempRef, DC->uDBQuant, iSpareCount)); #ifdef H263P DEBUGMSG(ZONE_DECODE_PICTURE_HEADER, ("%s: DF=%d TB=%d\r\n", _fx_, DC->bDeblockingFilter, DC->bTrueBFrame)); if (DC->uSrcFormat == SRC_FORMAT_CUSTOM) { DEBUGMSG(ZONE_DECODE_PICTURE_HEADER, ("%s: PARW=%ld PARH=%ld FWI=%ld FHI=%ld\r\n", _fx_, DC->uPARWidth, DC->uPARHeight, (DC->uActualFrameWidth >> 2) - 1, (DC->uActualFrameHeight >> 2) - 1)); } #endif // H263P GET_BITS_SAVE_STATE(fpu8, uWork, uBitsReady, fpbsState); iReturn = ICERR_OK; done: return iReturn; } /* end H263DecodePictureHeader() */