--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/h263decoder/src/viddemux.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,4111 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:
+* H.263 bitstream parsing.
+*
+*/
+
+
+
+/*
+ * Includes
+ */
+
+#include "h263dConfig.h"
+#include "viddemux.h"
+#include "vdxint.h"
+#include "debug.h"
+#include "biblin.h"
+/* MVE */
+#include "MPEG4Transcoder.h"
+
+/*
+ * Defines
+ */
+
+#ifdef DEB_STDOUT
+/* Use back-channel debug output file when printing back-channel related
+ messages. */
+#include <stdio.h>
+extern FILE *bcmDebFile;
+#endif
+
+
+/*
+ * Module-scope typedefs
+ */
+
+/* Another type for VLC (variable length code) lookup tables used in
+ Annex I implementation.*/
+typedef struct {
+ u_char LAST; /* see section 5.4.2 of the H.263 recommendation */
+ u_char RUN; /* to understand LAST, RUN and LEVEL */
+ u_char LEVEL;
+ u_char len; /* actual length of code in bits */
+} vdxVLCTableNew_t;
+
+
+/*
+ * Global constants
+ */
+
+/* Used to convert a luminance block index defined in section 4.2.1
+ of the H.263 recommendation to a coded block pattern mask (see sections
+ 5.3.4 and 5.3.5 of the H.263 recommendation.
+ See also macros section in viddemux.h. */
+const int vdxBlockIndexToCBPYMask[5] = {0, 8, 4, 2, 1};
+const int vdxYBlockIndexToCBPBMask[5] = {0, 32, 16, 8, 4};
+
+
+/*
+ * Local function prototypes
+ */
+
+/* Picture Layer */
+
+static int vdxActAfterIncorrectSEI(
+ bibBuffer_t *inBuffer,
+ int fPLUSPTYPE,
+ int *fLast,
+ int *bitErrorIndication);
+
+static void vdxStandardSourceFormatToFrameSize(int sourceFormat, int *width, int *height);
+
+/* Slice Layer */
+int vdxFrameSizeToPictureFormat(int width, int height);
+
+/* Macroblock Layer */
+
+static int vdxGetIntraMode(bibBuffer_t *inBuffer,int *index,
+ int *bitErrorIndication);
+
+static int vdxUMVGetMVD(bibBuffer_t *inBuffer,int *mvdx10,
+ int *bitErrorIndication);
+
+static int vdxGetNormalMODB(bibBuffer_t *inBuffer, int *index,
+ int *bitErrorIndication);
+
+static int vdxGetImpPBMODB(bibBuffer_t *inBuffer, int *index,
+ int *bitErrorIndication);
+
+
+
+
+/*
+ * Picture Layer Global Functions
+ */
+
+/* {{-output"vdxGetPictureHeader.txt"}} */
+/*
+ * vdxGetPictureHeader
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * inpParam input parameters
+ * header output parameters: picture header
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the H.263 picture header.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxGetPictureHeader(
+ bibBuffer_t *inBuffer,
+ const vdxGetPictureHeaderInputParam_t *inpParam,
+ vdxPictureHeader_t *header,
+ int *bitErrorIndication)
+/* {{-output"vdxGetPictureHeader.txt"}} */
+{
+ bibFlushBits_t
+ flushBits;
+ bibGetBits_t
+ getBits;
+ int
+ numBitsGot,
+ bits1To5OfPTYPE,
+ sourceFormat;
+ int16
+ bibError = 0;
+ u_int32 tmp = 0; /* temporary variable for reading some redundant bits */
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(inpParam != NULL);
+ vdxAssert(inpParam->flushBits != NULL);
+ vdxAssert(inpParam->getBits != NULL);
+ vdxAssert(header != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ flushBits = inpParam->flushBits;
+ getBits = inpParam->getBits;
+
+ memset(header, 0, sizeof(vdxPictureHeader_t));
+ *bitErrorIndication = 0;
+
+ /* Assume that the existence of a PSC has been checked,
+ it is the next code in the buffer, and
+ its byte alignment has been checked */
+
+ /* Flush stuffing (PSTUF) */
+ if (inpParam->numStuffBits) {
+ flushBits(inpParam->numStuffBits, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ }
+
+ /* Flush PSC */
+ flushBits(22, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ /* PSC cannot contain fatal bit errors (checked earlier) */
+ header->numBits += 22;
+
+ *bitErrorIndication = 0;
+
+ /* TR */
+ header->tr = (int) getBits(8, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ header->numBits += 8;
+
+
+ #ifdef DEB_STDOUT
+ if (bcmDebFile)
+ deb1f(bcmDebFile, "TR %d\n", header->tr);
+ #endif
+
+ /* The first 5 bits from PTYPE */
+ bits1To5OfPTYPE = (int) getBits(5, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 5;
+
+
+ /* PTYPE bit 1 should be 1 */
+ if ((bits1To5OfPTYPE & 16) == 0 ) {
+ deb0p("ERROR. PTYPE bit 1 invalid.\n");
+ goto exitAfterBitError;
+ }
+
+ /* PTYPE bit 2 should be 0 for distinction with H.261 */
+ if (bits1To5OfPTYPE & 8) {
+ deb0p("ERROR. PTYPE bit 2 indicates H.261.\n");
+ goto exitAfterBitError;
+ }
+
+ /* PTYPE bit 3, Split Screen Indicator */
+ header->fSplitScreen = ((bits1To5OfPTYPE & 4) > 0);
+
+ /* PTYPE bit 4, Document camera indicator */
+ header->fDocumentCamera = ((bits1To5OfPTYPE & 2) > 0);
+
+ /* PTYPE bit 5, Freeze Picture Release */
+ header->fFreezePictureRelease = (bits1To5OfPTYPE & 1);
+
+ /* PTYPE bits 6 - 8, Source Format */
+ sourceFormat = (int) getBits(3, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 3;
+
+
+ /* If H.263 version 1 */
+ if (sourceFormat >= 1 && sourceFormat <= 5) {
+ int bits9To13OfPTYPE;
+
+ header->fPLUSPTYPE = 0;
+
+ vdxStandardSourceFormatToFrameSize(sourceFormat, &header->lumWidth, &header->lumHeight);
+
+ /* PTYPE bits 9 - 13 */
+ bits9To13OfPTYPE = (int) getBits(5, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 5;
+
+
+ /* PTYPE bit 9, Picture coding type */
+ header->pictureType = ((bits9To13OfPTYPE & 16) > 0);
+
+ /* PTYPE bit 10, Unrestricted motion vector mode */
+ header->fUMV = ((bits9To13OfPTYPE & 8) > 0);
+
+ /* PTYPE bit 11, Syntax-based Arithmetic Coding mode */
+ header->fSAC = ((bits9To13OfPTYPE & 4) > 0);
+
+ /* PTYPE bit 12, Advanced prediction mode */
+ header->fAP = ((bits9To13OfPTYPE & 2) > 0);
+
+ /* PTYPE bit 13, PB-frames mode */
+
+ /* If PTYPE bit 9 indicates a P-picture */
+ if (header->pictureType) {
+ /* Check if it is actually a PB-picture */
+ if (bits9To13OfPTYPE & 1)
+ header->pictureType = VDX_PIC_TYPE_PB;
+ }
+
+ /* Else PTYPE bit 9 indicates an I-picture */
+ else {
+ /* Check that bit 13 is 0 */
+ if (bits9To13OfPTYPE & 1) {
+ deb0p("ERROR. PTYPE bit 9 and 13 mismatch.\n");
+ goto exitAfterBitError;
+ }
+ }
+ }
+
+ /* Else if H.263 version 2 (PLUSPTYPE) */
+ else if (sourceFormat == 7) {
+ int bits4To9OfMPPTYPE;
+
+ header->fPLUSPTYPE = 1;
+
+ /* UFEP */
+ header->ufep = (int) getBits(3, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 3;
+
+
+ if (header->ufep > 1) {
+ deb0p("ERROR. UFEP illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* If UFEP = '001' */
+ if (header->ufep) {
+ int bits4To18OfOPPTYPE;
+
+ /* OPPTYPE bits 1 - 3, Source format */
+ sourceFormat = (int) getBits(3, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 3;
+
+
+
+ if (sourceFormat >= 1 && sourceFormat <= 5) {
+ header->fCustomSourceFormat = 0;
+ vdxStandardSourceFormatToFrameSize(sourceFormat,
+ &header->lumWidth, &header->lumHeight);
+ }
+
+ else if (sourceFormat == 6)
+ header->fCustomSourceFormat = 1;
+
+ else {
+ deb0p("ERROR. Source format illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* OPPTYPE bits 4 - 18 */
+ bits4To18OfOPPTYPE = (int) getBits(15, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 15;
+
+
+ /* OPPTYPE bit 4, Custom PCF */
+ header->fCustomPCF = ((bits4To18OfOPPTYPE & 0x4000) > 0);
+
+ /* OPPTYPE bit 5, Unrestricted Motion Vector mode */
+ header->fUMV = ((bits4To18OfOPPTYPE & 0x2000) > 0);
+
+ /* OPPTYPE bit 6, Syntax-based Arithmetic Coding mode */
+ header->fSAC = ((bits4To18OfOPPTYPE & 0x1000) > 0);
+
+ /* OPPTYPE bit 7, Advanced Prediction mode */
+ header->fAP = ((bits4To18OfOPPTYPE & 0x0800) > 0);
+
+ /* OPPTYPE bit 8, Advanced INTRA Coding mode */
+ header->fAIC = ((bits4To18OfOPPTYPE & 0x0400) > 0);
+
+ /* OPPTYPE bit 9, Deblocking filter mode */
+ header->fDF = ((bits4To18OfOPPTYPE & 0x0200) > 0);
+
+ /* OPPTYPE bit 10, Slice Structured mode */
+ header->fSS = ((bits4To18OfOPPTYPE & 0x0100) > 0);
+
+ /* OPPTYPE bit 11, Reference Picture Selection mode */
+ header->fRPS = ((bits4To18OfOPPTYPE & 0x0080) > 0);
+
+ /* OPPTYPE bit 12, Independent Segment Decoding mode */
+ header->fISD = ((bits4To18OfOPPTYPE & 0x0040) > 0);
+
+ /* OPPTYPE bit 13, Alternative Inter VLC mode */
+ header->fAIV = ((bits4To18OfOPPTYPE & 0x0020) > 0);
+
+ /* OPPTYPE bit 14, Modified Quantization mode */
+ header->fMQ = ((bits4To18OfOPPTYPE & 0x0010) > 0);
+
+ /* OPPTYPE bits 15 - 18 must be '1000' */
+ if ((bits4To18OfOPPTYPE & 0x000F) != 8) {
+ deb0p("ERROR. OPPTYPE bits 15 - 18 illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* Mode interaction restrictions, see section 5.1.4.6 of
+ the H.263 recommendation */
+ if (header->fSAC && (header->fAIV || header->fMQ || header->fUMV)) {
+ deb0p("ERROR. Illegal bit pattern (section 5.1.4.6).\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ /* MPPTYPE, bits 1 - 3, Picture type code */
+ header->pictureType = (int) getBits(3, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 3;
+
+
+ if (header->pictureType >= 6) {
+ deb0p("ERROR. Picture type code illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* MPPTYPE, bits 4 - 9 */
+ bits4To9OfMPPTYPE = (int) getBits(6, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 6;
+
+
+ /* MPPTYPE bit 4, Reference Picture Resampling mode */
+ header->fRPR = ((bits4To9OfMPPTYPE & 32) > 0);
+
+ /* MPPTYPE bit 5, Reduced-Resolution Update mode */
+ header->fRRU = ((bits4To9OfMPPTYPE & 16) > 0);
+
+ /* RPR/RRU must not be set for I or EI-pictures.
+ (See section 5.1.4.5 of the H.263 recommendation.) */
+ if ((header->fRPR || header->fRRU) &&
+ (header->pictureType == VDX_PIC_TYPE_I ||
+ header->pictureType == VDX_PIC_TYPE_EI)) {
+ deb0p("ERROR. RPR or RRU is set for I or EI.\n");
+ goto exitAfterBitError;
+ }
+
+ /* MPPTYPE bit 6, Rounding type */
+ header->rtype = ((bits4To9OfMPPTYPE & 8) > 0);
+
+ /* RTYPE must be 0 if other than P, Improved PB or EP picture
+ (see section 5.1.4.3 of the H.263 recommendation */
+
+ /* MPPTYPE bits 7 - 9, must be '001' */
+ if ((bits4To9OfMPPTYPE & 7) != 1) {
+ deb0p("ERROR. MPPTYPE bits 7 - 9 illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* CPM */
+ header->cpm = (int) getBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if (header->cpm) {
+ /* PSBI */
+ header->psbi = (int) getBits(2, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 2;
+
+
+ }
+
+ if (header->fCustomSourceFormat) {
+ int parCode, fExtendedPAR = 0, pwi, phi;
+
+ /* CPFMT bits 1 - 4, Pixel Aspect Ratio code */
+ parCode = (int) getBits(4, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 4;
+
+
+
+ switch (parCode) {
+
+ case 1: /* Square */
+ header->parWidth = 1;
+ header->parHeight = 1;
+ break;
+
+ case 2: /* CIF for 4:3 picture */
+ header->parWidth = 12;
+ header->parHeight = 11;
+ break;
+
+ case 3: /* 525-type for 4:3 picture */
+ header->parWidth = 10;
+ header->parHeight = 11;
+ break;
+
+ case 4: /* CIF stretched for 16:9 picture */
+ header->parWidth = 16;
+ header->parHeight = 11;
+ break;
+
+ case 5: /* 525-type stretched for 16:9 picture */
+ header->parWidth = 40;
+ header->parHeight = 33;
+ break;
+
+ case 15: /* extended PAR */
+ fExtendedPAR = 1;
+ break;
+
+ default:
+ deb0p("ERROR. PAR code illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* CPFMT bits 5 - 13, picture width indication */
+ pwi = (int) getBits(9, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 9;
+
+
+ header->lumWidth = ((pwi + 1) <<2 /** 4*/);
+
+ /* CPFMT bit 14 must be 1 */
+ tmp = getBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if ( tmp == 0 ) {
+ deb0p("ERROR. CPFMT bit 14 is 0.\n");
+ goto exitAfterBitError;
+ }
+
+ /* CPFMT bits 15 - 23, picture height indication */
+ phi = (int) getBits(9, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 9;
+
+
+ if (phi == 0 || phi > 288) {
+ deb0p("ERROR. PHI illegal.\n");
+ goto exitAfterBitError;
+ }
+ header->lumHeight = (phi <<2 /** 4*/);
+
+ if (fExtendedPAR) {
+ /* EPAR bits 1 - 8, PAR Width */
+ header->parWidth = (int) getBits(8, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 8;
+
+
+ if (header->parWidth == 0) {
+ deb0p("ERROR. PAR width illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* EPAR bits 9 - 16, PAR Height */
+ header->parHeight = (int) getBits(8, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 8;
+
+
+ if (header->parHeight == 0) {
+ deb0p("ERROR. PAR height illegal.\n");
+ goto exitAfterBitError;
+ }
+ }
+ } /* endif (customSourceFormat) */
+
+ if (header->fCustomPCF) {
+ int clockConversionCode;
+ u_int32 clockDivisor, conversionFactor;
+
+ /* CPCFC bit 1, Clock conversion code */
+ clockConversionCode = (int) getBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if (clockConversionCode)
+ conversionFactor = 1001;
+ else
+ conversionFactor = 1000;
+
+ /* CPCFC bits 2 - 8, Clock divisor */
+ clockDivisor = getBits(7, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 7;
+
+
+ if (clockDivisor == 0) {
+ deb0p("ERROR. Illegal clock divisor.\n");
+ goto exitAfterBitError;
+ }
+
+ header->pcfRate = 1800000LU;
+ header->pcfScale = clockDivisor * conversionFactor;
+ }
+
+ else {
+ /* CIF clock frequency */
+ header->pcfRate = 2997;
+ header->pcfScale = 100;
+ }
+
+ if (header->fCustomPCF || (!header->ufep && inpParam->fCustomPCF)) {
+ int etr;
+
+ /* ETR */
+ etr = (int) getBits(2, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 2;
+
+
+
+ header->tr |= (etr << 8);
+ }
+
+ if (header->fUMV) {
+ /* UUI */
+ tmp = getBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if ( tmp )
+ header->fUMVLimited = 1;
+
+ else {
+ tmp = getBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if ( tmp )
+ header->fUMVLimited = 0;
+ else {
+ /* '00' forbidden */
+ deb0p("ERROR. Illegal UUI.\n");
+ goto exitAfterBitError;
+ }
+ }
+
+
+ }
+
+ if (header->fSS) {
+ /* SSS */
+ tmp = (int) getBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+ header->fRectangularSlices = tmp;
+ header->numBits += 1;
+
+ header->fArbitrarySliceOrdering = (int) getBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ /* Mode interaction restriction, see section 5.1.4.6 of
+ the H.263 recommendation */
+ if (header->fISD && !header->fRectangularSlices) {
+ deb0p("ERROR. Illegal bit pattern (section 5.1.4.6).\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ if (inpParam->fScalabilityMode) {
+ /* ELNUM */
+ header->elnum = (int) getBits(4, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 4;
+
+ }
+
+ if (inpParam->fScalabilityMode && header->ufep) {
+ /* RLNUM */
+ header->rlnum = (int) getBits(4, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 4;
+
+ }
+
+ if (header->fRPS) {
+ /* RPSMF */
+ header->rpsMode = (int) getBits(3, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 3;
+
+
+ if (header->rpsMode < 4) {
+ deb0p("ERROR. Illegal RPSMF.\n");
+ goto exitAfterBitError;
+ }
+
+ header->rpsMode -= 4; /* 4..7 --> 0..3 */
+ }
+
+ /* If no OPPTYPE but RPS was previously on or RPS signaled in OPPTYPE */
+ if ((inpParam->fRPS && header->ufep == 0) || header->fRPS) {
+ /* TRPI */
+ header->trpi = (int) getBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if (header->trpi) {
+ /* TRP */
+ header->trp = (int) getBits(10, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 10;
+
+
+ deb2f(bcmDebFile, "TRPI in picture header. TR = %d, TRP = %d.\n",
+ header->tr, header->trp);
+ }
+
+ /* Code following the standard */
+
+ /* BCI */
+ tmp = getBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if ( tmp ) {
+ /* BCM not supported */
+ deb0p("ERROR. BCM not supported.\n");
+ goto exitAfterBitError;
+ }
+
+ else {
+ tmp = getBits(1, inBuffer, &numBitsGot,bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if ( !tmp ) {
+ /* BCI '00' is illegal */
+ deb0p("ERROR. Illegal BCI.\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ }
+
+ if (header->fRPR) {
+ /* RPRP not supported */
+ deb0p("ERROR. RPRP not supported.\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ else {
+ deb0p("ERROR. Source format illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* PQUANT */
+ header->pquantPosition = header->numBits;
+ header->pquant = (int) getBits(5, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 5;
+
+
+ if (header->pquant == 0) {
+ deb0p("ERROR. PQUANT illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ if (!header->fPLUSPTYPE) {
+ /* CPM */
+ header->cpm = (int) getBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 1;
+
+
+ if (header->cpm) {
+ /* PSBI */
+ header->psbi = (int) getBits(2, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 2;
+
+
+ }
+ }
+
+ /* If PB-frame */
+ if (header->pictureType == VDX_PIC_TYPE_PB ||
+ header->pictureType == VDX_PIC_TYPE_IPB) {
+
+ /* TRB */
+
+ /* If custom picture clock frequence is used */
+ if (header->fCustomPCF || inpParam->fCustomPCF) {
+ header->trb = (int) getBits(5, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 5;
+
+
+ }
+
+ else {
+ header->trb = (int) getBits(3, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 3;
+
+
+ }
+
+ if (header->trb == 0) {
+ deb0p("ERROR. TRB illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* DBQUANT */
+ header->dbquant = (int) getBits(2, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ header->numBits += 2;
+
+
+ }
+
+
+ /* Check success and return */
+
+
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+ exitAfterBitError:
+ if (bibError && bibError != ERR_BIB_NOT_ENOUGH_DATA)
+ return VDX_ERR_BIB;
+ return VDX_OK_BUT_BIT_ERROR;
+}
+
+
+/* {{-output"vdxFlushSEI.txt"}} */
+/*
+ * vdxFlushSEI
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function discards (flushes) all consequent PEI/PSUPP pairs.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxFlushSEI(
+ bibBuffer_t *inBuffer,
+ int *bitErrorIndication )
+/* {{-output"vdxFlushSEI.txt"}} */
+{
+ int
+ numBitsGot;
+ int16
+ bibError = 0;
+ u_int32
+ pei,
+ psupp;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ do {
+ /* PEI */
+ pei = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ if (pei) {
+ /* PSUPP */
+ psupp = bibGetBits(8, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ // ignore the value of psupp; this is flush-function
+ if ( psupp )
+ {
+ }
+
+
+ }
+ } while (pei);
+
+ return VDX_OK;
+
+}
+
+
+/* {{-output"vdxGetSEI.txt"}} */
+/*
+ * vdxGetSEI
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ *
+ * ftype FTYPE field as defined in table L.1 of H.263,
+ * -1 if the value is not valid
+ *
+ * dsize DSIZE as defined in section L.2 of H.263
+ *
+ * parameterData an array of (min) 16 entries,
+ * filled with dsize octets of parameter data
+ *
+ * fLast set to 1 if the first PEI indicates that
+ * no PSUPPs follow. Otherwise 0.
+ *
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets supplemental enhancement information as defined
+ * in Annex L of H.263.
+ *
+ * Note:
+ * The start code emulation prevention necessity using "Do Nothing" function
+ * is not checked. See section L.3 of H.263 for more details.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxGetSEI(
+ bibBuffer_t *inBuffer,
+ int *ftype,
+ int *dsize,
+ u_char *parameterData,
+ int *fLast,
+ int *bitErrorIndication)
+/* {{-output"vdxGetSEI.txt"}} */
+{
+ int
+ numBitsGot,
+ paramNum,
+ lftype, /* local FTYPE */
+ ldsize; /* local DSZIE */
+ int16
+ bibError = 0;
+ u_int32
+ pei;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(ftype != NULL);
+ vdxAssert(dsize != NULL);
+ vdxAssert(parameterData != NULL);
+ vdxAssert(fLast != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ *ftype = -1;
+ *dsize = 0;
+
+ /* PEI */
+ pei = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ if (pei) {
+ *fLast = 0;
+
+ /* FTYPE */
+ lftype = (int) bibGetBits(4, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ /* DSIZE */
+ ldsize = (int) bibGetBits(4, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+ }
+
+ else {
+ *fLast = 1;
+ return VDX_OK;
+ }
+
+ for (paramNum = 0; paramNum < ldsize; paramNum++) {
+ /* PEI */
+ pei = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ if (!pei) {
+ deb0p("ERROR. DSIZE does not match with PEI.\n");
+ *fLast = 1;
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* PSUPP containing parameter data */
+ parameterData[paramNum] = (u_char) bibGetBits(8, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+ }
+
+ *ftype = lftype;
+ *dsize = ldsize;
+
+ return VDX_OK;
+
+}
+
+
+/* {{-output"vdxGetAndParseSEI.txt"}} */
+/*
+ * vdxGetAndParseSEI
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ *
+ * fPLUSPTYPE indicates if PLUSPTYPE is in use
+ *
+ * numScalabilityLayers -1 if the very first picture,
+ * 0 if Annex N scalability layers not in use,
+ * 2..15 if Annex N scalability layers in use
+ *
+ * sei parsed SEI data
+ *
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets supplemental enhancement information as defined
+ * in Annex L and W of H.263 and returns the parsed data.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ */
+
+int vdxGetAndParseSEI(
+ bibBuffer_t *inBuffer,
+ int fPLUSPTYPE,
+ int numScalabilityLayers,
+ vdxSEI_t *sei,
+ int *bitErrorIndication)
+/* {{-output"vdxGetAndParseSEI.txt"}} */
+{
+ int
+ ret = VDX_OK, /* Temporary variable to carry return values */
+ fSecondFTYPESet = 0, /* 1 = Extended FTYPE in use,
+ 0 = Annex L/W FTYPE in use,
+ see L.15 for further details */
+ ftype, /* FTYPE as in section L.2 of H.263 */
+ dsize, /* DSIZE as in section L.2 of H.263 */
+ fLast, /* 1 if PEI is zero, 0 otherwise */
+ cont = 0, /* CONT as in section W.6 of H.263 */
+ ebit, /* EBIT as in section W.6 of H.263 */
+ mtype, /* MTYPE as in section W.6 of H.263 */
+ prevCONT = 0, /* CONT field in the previous picture msg */
+ prevMTYPE = -1; /* MTYPE in the previous picture msg */
+
+ u_char
+ parameterData[16];
+
+ /* Initialize output data */
+ sei->fFullPictureFreezeRequest = 0;
+ sei->fFullPictureSnapshot = 0;
+ sei->snapshotId = 0;
+ sei->snapshotStatus = 255;
+ sei->scalabilityLayer = -1;
+ sei->numScalabilityLayers = 0;
+ memset(sei->prevPicHeader, 0, VDX_MAX_BYTES_IN_PIC_HEADER);
+ sei->numBytesInPrevPicHeader = 0;
+ sei->numBitsInLastByteOfPrevPicHeader = 0;
+ sei->fPrevPicHeaderTooLarge = 0;
+
+ do {
+ /* Get supplemental enhancement information */
+ ret = vdxGetSEI(inBuffer, &ftype, &dsize, parameterData, &fLast,
+ bitErrorIndication);
+
+ /* If fatal error or bit error */
+ if (ret != VDX_OK)
+ return ret;
+
+ /* If the previous FTYPE indicated Extended Function Type */
+ if (fSecondFTYPESet) {
+
+ /* Let's discard FTYPE/DSIZE and parameters as suggested in
+ section L.15 of H.263 Recommendation to allow backward
+ compatibility to to-be-defined set of extended FTYPEs. */
+
+ /* The next expected FTYPE is a normal one defined in Annex L/W. */
+ fSecondFTYPESet = 0;
+
+ continue;
+ }
+
+ switch (ftype) {
+
+ /* If "Reserved" */
+ case 0:
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ break;
+
+ /* If "Do Nothing" */
+ case 1:
+
+ if (dsize != 0) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Full-Picture Freeze Request */
+ case 2:
+ if (dsize != 0) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ else
+ sei->fFullPictureFreezeRequest = 1;
+
+ break;
+
+ /* If Partial-Picture Freeze Request */
+ case 3:
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Resizing Partial-Picture Freeze Request */
+ case 4:
+ if (dsize != 8) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Partial-Picture Freeze-Release Request */
+ case 5:
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Full-Picture Snapshot Tag */
+ case 6:
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ else {
+ int i;
+ sei->fFullPictureSnapshot = 1;
+ /* store 32-bit snapshot ID, first byte is the least significant */
+ for (i = 0; i < 4; i++)
+ sei->snapshotId |= (parameterData[i] << (i<<3 /**8*/));
+ }
+
+ break;
+
+ /* If Partial-Picture Snapshot Tag */
+ case 7:
+ if (dsize != 8) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Video Time Segment Start Tag */
+ case 8:
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Video Time Segment End Tag */
+ case 9:
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Progressive Refinement Segment Start Tag */
+ case 10:
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Progressive Refinement Segment End Tag */
+ case 11:
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Chroma Keying Information */
+ case 12:
+ if (dsize < 1 || dsize > 9) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Fixed-Point IDCT */
+ case 13:
+ if (dsize != 1) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ break;
+
+ /* If Picture Message */
+ case 14:
+ /* DSIZE shall be at least 1 to carry CONT, EBIT, and MTYPE */
+ if (dsize < 1) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ else {
+ cont = ( (parameterData[0] & 0x80) >> 7 );
+ ebit = ( (parameterData[0] & 0x70) >> 4 );
+ mtype = (parameterData[0] & 0x0f);
+
+ if (mtype < 1 || mtype > 5) {
+ /* Non-text message, check restriction in W.6.2 */
+ if (ebit != 0 && (cont == 1 || dsize == 1)) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ break;
+ }
+ }
+
+ /* If the previous picture message indicated that the data
+ continues in the next picture message, but the current
+ message type differs from the previous one
+ (restricted in section W.6.1 of the H.263 Recommendation */
+ if (prevCONT && mtype != prevMTYPE) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ break;
+ }
+
+ /* If arbitrary binary data */
+ if (mtype == 0) {
+
+ /* Proprietary snapshot status indication */
+ if (parameterData[1] == 83 && parameterData[2] == 115) {
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ break;
+ }
+ sei->snapshotStatus = parameterData[3];
+ }
+
+ /* Proprietary Annex N scalability layer
+ indication */
+ else if (parameterData[1] == 83 && parameterData[2] == 108) {
+ if (dsize != 4) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ break;
+ }
+ sei->scalabilityLayer = parameterData[3] >> 4;
+ sei->numScalabilityLayers = parameterData[3] & 15;
+
+ /* If less than two scalability layers or
+ max number of scalability layers changes during
+ the sequence */
+ if (sei->numScalabilityLayers < 2 ||
+ (numScalabilityLayers >= 0 &&
+ sei->numScalabilityLayers !=
+ numScalabilityLayers)) {
+
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ break;
+ }
+ }
+ }
+
+ /* Else if Previous Picture Header Repetition */
+ else if (mtype == 7) {
+ int
+ firstIndexToWrite,
+ numBytesToWrite;
+
+ if (sei->numBytesInPrevPicHeader == 0)
+ /* The first two bytes of PSC = 0x00 0x00 */
+ sei->numBytesInPrevPicHeader = 2;
+
+ firstIndexToWrite = sei->numBytesInPrevPicHeader;
+ numBytesToWrite = dsize - 1;
+ sei->numBitsInLastByteOfPrevPicHeader = 8 - ebit;
+
+ /* If buffer would overflow */
+ if (firstIndexToWrite + numBytesToWrite >
+ VDX_MAX_BYTES_IN_PIC_HEADER) {
+ numBytesToWrite =
+ VDX_MAX_BYTES_IN_PIC_HEADER - firstIndexToWrite;
+ sei->numBitsInLastByteOfPrevPicHeader = 8;
+ sei->fPrevPicHeaderTooLarge = 1;
+ }
+
+ if (numBytesToWrite) {
+ memcpy(
+ &sei->prevPicHeader[firstIndexToWrite],
+ ¶meterData[1],
+ numBytesToWrite);
+
+ sei->numBytesInPrevPicHeader += numBytesToWrite;
+ }
+ }
+
+ prevCONT = cont;
+ prevMTYPE = mtype;
+ }
+ break;
+
+ /* If Extended Function Type */
+ case 15:
+ if (dsize != 0) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ fSecondFTYPESet = 1;
+
+ break;
+ }
+ } while (!fLast && ret == VDX_OK);
+
+ /* If a picture message was not completed and the fault has not been
+ tracked earlier */
+ if (prevCONT && ret == VDX_OK) {
+ ret = vdxActAfterIncorrectSEI(
+ inBuffer, fPLUSPTYPE, &fLast, bitErrorIndication);
+ }
+
+ return ret;
+}
+
+
+/*
+ * GOB Layer Global Functions
+ */
+
+/* {{-output"vdxGetGOBHeader.txt"}} */
+/*
+ * vdxGetGOBHeader
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * inpParam input parameters
+ * header output parameters: GOB header
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ * Function:
+ * This function reads the H.263 GOB header.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxGetGOBHeader(
+ bibBuffer_t *inBuffer,
+ const vdxGetGOBHeaderInputParam_t *inpParam,
+ vdxGOBHeader_t *header,
+ int *bitErrorIndication,
+ int aColorEffect,
+ int* aStartByteIndex,
+ int* aStartBitIndex, CMPEG4Transcoder *hTranscoder)
+/* {{-output"vdxGetGOBHeader.txt"}} */
+{
+ int
+ numBitsGot;
+ int16
+ bibError = 0;
+ u_int32
+ tmp = 0; /* temporary variable for reading some redundant bits */
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(inpParam != NULL);
+ vdxAssert(header != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ memset(header, 0, sizeof(vdxGOBHeader_t));
+ *bitErrorIndication = 0;
+
+ /* Assume that the existence of a GBSC has been checked, and
+ it is the next code in the buffer */
+
+ /* Flush stuffing (GSTUF) */
+ if (inpParam->numStuffBits)
+ {
+ bibFlushBits(inpParam->numStuffBits, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ // if chroma has been removed and GSTUF is there, skip GSTUF bits to point to byte-aligned GBSC
+ if(aColorEffect==1 || aColorEffect==2)
+ {
+ (*aStartByteIndex)++;
+ *aStartBitIndex = 7;
+ }
+ }
+
+ /* MVE */
+ hTranscoder->H263GOBSliceHeaderBegin();
+
+ /* Flush GBSC */
+ bibFlushBits(17, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ /* GBSC cannot contain fatal bit errors (checked earlier) */
+
+ /* GN */
+ header->gn = (int) bibGetBits(5, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If the GN field contains a fatal bit error or
+ the value of GN is not in the valid range 1..24.
+ This range is defined in section 5.2.3 of the standard.
+
+ Notice that in general case one cannot assume that the maximum GN
+ of the picture is the same as in the previous picture (GOB) since
+ a picture header may have been lost and the header could have contained
+ an indication of a picture format change. Therefore we have to stick
+ to the overall maximum GN, equal to 24, here. */
+
+ if ( header->gn == 0 /* PSC */ ||
+ header->gn > 24) {
+ deb0p("ERROR. GN illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ if (inpParam->fCPM) {
+ /* GSBI */
+ header->gsbi = (int) bibGetBits(2, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ }
+ /* GFID */
+ header->gfid = (int) bibGetBits(2, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* GQUANT */
+ header->gquant = (int) bibGetBits(5, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ if (header->gquant == 0) {
+ deb0p("ERROR. Illegal GQUANT.\n");
+ goto exitAfterBitError;
+ }
+
+ if (inpParam->fRPS) {
+ /* TRI */
+ header->tri = (int) bibGetBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If TR present */
+ if (header->tri) {
+ /* TR */
+ if (inpParam->fCustomPCF)
+ header->tr = (int) bibGetBits(10, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ else
+ header->tr = (int) bibGetBits(8, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ }
+
+ /* TRPI */
+ header->trpi = (int) bibGetBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If TRP present */
+ if (header->trpi) {
+ /* TRP */
+ header->trp = (int) bibGetBits(10, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ deb2f(bcmDebFile, "TRPI in GOB header. GN = %d, TRP = %d.\n",
+ header->gn, header->trp);
+ }
+
+ /* BCI */
+ /* Code following the standard */
+
+ /* BCI */
+ tmp = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ if ( tmp ) {
+ /* BCM not supported */
+ deb0p("ERROR. BCM not supported.\n");
+ goto exitAfterBitError;
+ }
+
+ else {
+ tmp = bibGetBits(1, inBuffer, &numBitsGot,bitErrorIndication, &bibError);
+
+
+ if ( !tmp ) {
+ /* BCI '00' is illegal */
+ deb0p("ERROR. Illegal BCI.\n");
+ goto exitAfterBitError;
+ }
+ }
+
+
+ }
+
+ /* Check success and return */
+
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+ exitAfterBitError:
+ if (bibError && bibError != ERR_BIB_NOT_ENOUGH_DATA)
+ return VDX_ERR_BIB;
+
+ return VDX_OK_BUT_BIT_ERROR;
+}
+
+/*
+ * Slice Layer Global Functions
+ */
+
+/* {{-output"vdxGetSliceHeader.txt"}} */
+/*
+ * vdxGetSliceHeader
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * inpParam input parameters
+ * header output parameters: Slice header
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ * Function:
+ * This function reads the H.263 Slice header.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ */
+
+int vdxGetSliceHeader(
+ bibBuffer_t *inBuffer,
+ const vdxGetSliceHeaderInputParam_t *inpParam,
+ vdxSliceHeader_t *header,
+ int *bitErrorIndication)
+/* {{-output"vdxGetSliceHeader.txt"}} */
+{
+ int
+ numBitsGot;
+ int16
+ bibError = 0;
+ u_int32
+ tmp = 0; /* temporary variable for reading some redundant bits */
+
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(inpParam != NULL);
+ vdxAssert(header != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ memset(header, 0, sizeof(vdxSliceHeader_t));
+ *bitErrorIndication = 0;
+
+ if (!inpParam->sliceHeaderAfterPSC) {
+ /* Flush stuffing (GSTUF) */
+ if (inpParam->numStuffBits)
+ bibFlushBits(inpParam->numStuffBits, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+ /* Flush SSC */
+ /* Assume that the existence of a SSC has been checked, and
+ it is the next code in the buffer */
+
+ bibFlushBits(17, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ /* SSC cannot contain fatal bit errors (checked earlier) */
+ }
+
+ /* Read SEPB1 (K.2.3) */
+ tmp = (int) bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ if (tmp != 1) {
+ deb0p("ERROR. SEPB1 illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* SSBI */
+ if ((inpParam->fCPM) && (!inpParam->sliceHeaderAfterPSC)) {
+ header->ssbi = (int) bibGetBits(4, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If the SSBI field contains a fatal bit error or
+ the value of SSBI is not in the valid range 9..12.
+ This range is defined in Table K.1/H.263 */
+ if ( tmp < 9 ||
+ tmp > 12) {
+ deb0p("ERROR. SSBI illegal.\n");
+ goto exitAfterBitError;
+ }
+ /* Set emulated GN value */
+ header->gn = header->ssbi + 16;
+ /* Set sub-bitstream number */
+ if (header->gn < 29)
+ header->sbn = header->ssbi - 9;
+ else
+ header->sbn = 3;
+ }
+
+
+ /* MBA */
+ header->mba = (int) bibGetBits(inpParam->mbaFieldWidth, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If the MBA field contains a fatal bit error or
+ the value of MBA is larger than Max Value defined in Table K.2/H.263 */
+ if ( header->mba > inpParam->mbaMaxValue) {
+ deb0p("ERROR. MBA illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* SEPB2 */
+ if (inpParam->sliceHeaderAfterPSC) {
+ if (inpParam->fRectangularSlices) {
+ tmp = (int) bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ if (tmp != 1) {
+ deb0p("ERROR. SEPB1 illegal.\n");
+ goto exitAfterBitError;
+ }
+ }
+ }
+ else {
+ if (inpParam->fCPM) {
+ if (inpParam->mbaFieldWidth > 9) {
+ tmp = (int) bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ if (tmp != 1) {
+ deb0p("ERROR. SEPB1 illegal.\n");
+ goto exitAfterBitError;
+ }
+ }
+ }
+ else {
+ if (inpParam->mbaFieldWidth > 11) {
+ tmp = (int) bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ if (tmp != 1) {
+ deb0p("ERROR. SEPB1 illegal.\n");
+ goto exitAfterBitError;
+ }
+ }
+ }
+ }
+
+ /* SQUANT */
+ if (!inpParam->sliceHeaderAfterPSC) {
+ header->squant = (int) bibGetBits(5, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ if ( bibError )
+ return VDX_ERR_BIB;
+
+ /* If the SQUANT field contains a fatal bit error or
+ the value of SQUANT is between 1 and 31 */
+ if ( header->squant == 0) {
+ deb0p("ERROR. SQUANT illegal.\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ /* SWI */
+ if (inpParam->fRectangularSlices) {
+ header->swi = (int) bibGetBits(inpParam->swiFieldWidth, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If the MBA field contains a fatal bit error or
+ the value of MBA is larger than Max Value defined in Table K.2/H.263 */
+ if ( header->swi > inpParam->swiMaxValue) {
+ deb0p("ERROR. SWI illegal.\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ /* Read SEPB3 */
+ tmp = (int) bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ if (tmp != 1) {
+ deb0p("ERROR. SEPB3 illegal.\n");
+ goto exitAfterBitError;
+ }
+
+ /* GFID */
+ if (!inpParam->sliceHeaderAfterPSC) {
+ header->gfid = (int) bibGetBits(2, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ }
+
+ if (!inpParam->sliceHeaderAfterPSC && inpParam->fRPS) {
+ /* TRI */
+ header->tri = (int) bibGetBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If TR present */
+ if (header->tri) {
+ /* TR */
+/* if (inpParam->fCustomPCF)
+ header->tr = (int) bibGetBits(10, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+ else*/
+ header->tr = (int) bibGetBits(8, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ }
+
+ /* TRPI */
+ header->trpi = (int) bibGetBits(1, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ /* If TRP present */
+ if (header->trpi) {
+ /* TRP */
+ header->trp = (int) bibGetBits(10, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ deb2f(bcmDebFile, "TRPI in GOB header. GN = %d, TRP = %d.\n",
+ header->gn, header->trp);
+ }
+
+ /* BCI */
+ /* Code following the standard */
+
+ /* BCI */
+ tmp = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ if ( tmp ) {
+ /* BCM not supported */
+ deb0p("ERROR. BCM not supported.\n");
+ goto exitAfterBitError;
+ }
+
+ else {
+ tmp = bibGetBits(1, inBuffer, &numBitsGot,bitErrorIndication, &bibError);
+
+
+ if ( !tmp ) {
+ /* BCI '00' is illegal */
+ deb0p("ERROR. Illegal BCI.\n");
+ goto exitAfterBitError;
+ }
+ }
+
+
+ }
+
+ /* Check success and return */
+
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+ exitAfterBitError:
+ if (bibError && bibError != ERR_BIB_NOT_ENOUGH_DATA)
+ return VDX_ERR_BIB;
+
+ return VDX_OK_BUT_BIT_ERROR;
+}
+/* {{-output"vdxGetMBAandSWIValues.txt"}} */
+/*
+ * vdxGetIMBLayer
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * inpParam input parameters
+ * outParam output parameters
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ * Function:
+ * This function reads the macroblock layer data of an INTRA macroblock.
+ *
+ * Returns:
+ * Nothing
+ *
+ */
+
+void vdxGetMBAandSWIValues(
+ int width,
+ int height,
+ int fRRU,
+ int *mbaFieldWidth,
+ int *mbaMaxValue,
+ int *swiFieldWidth,
+ int *swiMaxValue
+ )
+{
+ int
+ pictureFormat;
+
+ pictureFormat = vdxFrameSizeToPictureFormat(width, height);
+
+ if (fRRU) {
+ switch (pictureFormat) {
+ case 0:
+ /* sub-QCIF */
+ *mbaFieldWidth = 5;
+ *mbaMaxValue = 11;
+ *swiFieldWidth = 3;
+ *swiMaxValue = 3;
+ break;
+ case 1:
+ /* QCIF */
+ *mbaFieldWidth = 6;
+ *mbaMaxValue = 29;
+ *swiFieldWidth = 3;
+ *swiMaxValue = 5;
+ break;
+ case 2:
+ /* CIF */
+ *mbaFieldWidth = 7;
+ *mbaMaxValue = 98;
+ *swiFieldWidth = 4;
+ *swiMaxValue = 10;
+ break;
+ case 3:
+ /* 4CIF */
+ *mbaFieldWidth = 9;
+ *mbaMaxValue = 395;
+ *swiFieldWidth = 5;
+ *swiMaxValue = 21;
+ break;
+ case 4:
+ /* 16CIF */
+ *mbaFieldWidth = 11;
+ *mbaMaxValue = 1583;
+ *swiFieldWidth = 6;
+ *swiMaxValue = 43;
+ break;
+ case 5:
+ /* 2048x1152 */
+ *mbaFieldWidth = 12;
+ *mbaMaxValue = 2303;
+ *swiFieldWidth = 6;
+ *swiMaxValue = 63;
+ break;
+ }
+ }
+ else {
+ switch (pictureFormat) {
+ case 0:
+ /* sub-QCIF */
+ *mbaFieldWidth = 6;
+ *mbaMaxValue = 47;
+ *swiFieldWidth = 4;
+ *swiMaxValue = 7;
+ break;
+ case 1:
+ /* QCIF */
+ *mbaFieldWidth = 7;
+ *mbaMaxValue = 98;
+ *swiFieldWidth = 4;
+ *swiMaxValue = 10;
+ break;
+ case 2:
+ /* CIF */
+ *mbaFieldWidth = 9;
+ *mbaMaxValue = 395;
+ *swiFieldWidth = 5;
+ *swiMaxValue = 21;
+ break;
+ case 3:
+ /* 4CIF */
+ *mbaFieldWidth = 11;
+ *mbaMaxValue = 1583;
+ *swiFieldWidth = 6;
+ *swiMaxValue = 43;
+ break;
+ case 4:
+ /* 16CIF */
+ *mbaFieldWidth = 13;
+ *mbaMaxValue = 6335;
+ *swiFieldWidth = 7;
+ *swiMaxValue = 87;
+ break;
+ case 5:
+ /* 2048x1152 */
+ *mbaFieldWidth = 14;
+ *mbaMaxValue = 9215;
+ *swiFieldWidth = 7;
+ *swiMaxValue = 127;
+ break;
+ }
+ }
+}
+
+/*
+ * Macroblock Layer Global Functions
+ */
+
+/* {{-output"vdxGetIMBLayer.txt"}} */
+/*
+ * vdxGetIMBLayer
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * inpParam input parameters
+ * outParam output parameters
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ * Function:
+ * This function reads the macroblock layer data of an INTRA macroblock.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+
+int vdxGetIMBLayer(
+ bibBuffer_t *inBuffer,
+ bibBuffer_t *outBuffer,
+ bibBufferEdit_t *bufEdit,
+ int /*aColorEffect*/,
+ int * /*aStartByteIndex*/,
+ int * /*aStartBitIndex*/,
+ TBool /*aGetDecodedFrame*/,
+ const vdxGetIMBLayerInputParam_t *inpParam,
+ vdxIMBLayer_t *outParam,
+ int *bitErrorIndication, CMPEG4Transcoder *hTranscoder)
+
+/* {{-output"vdxGetIMBLayer.txt"}} */
+{
+ int
+ mcbpcIndex,
+ cbpyIndex,
+ retValue = VDX_OK,
+ fDQUANT = 0,
+ fINTRAMODE,
+ bitsGot = 0;
+ int16 bibError = 0;
+
+ int StartByteIndex;
+ int StartBitIndex;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(inpParam != NULL);
+ vdxAssert(outParam != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ /* MVE */
+ vdxIMBListItem_t *MBinstance;
+ // Create new MBInstance for the next MB
+ MBinstance = (vdxIMBListItem_t *) malloc(sizeof(vdxIMBListItem_t));
+ if (!MBinstance)
+ {
+ deb("ERROR - vdxGetIMBLayer::MBinstance creation failed\n");
+ return H263D_ERROR;
+ }
+ memset(MBinstance, 0, sizeof(vdxIMBListItem_t));
+
+ /* Loop while MCBPC indicates stuffing */
+ do {
+
+ StartByteIndex = inBuffer->getIndex;
+ StartBitIndex = inBuffer->bitIndex;
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,0,inBuffer->getIndex,inBuffer->bitIndex); // 0: mcbpc
+
+ retValue = vdxGetMCBPCIntra(inBuffer, &mcbpcIndex, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ /* MVE */
+ /* remember to output the MB stufffing bits!! */
+ if (mcbpcIndex == 8)
+ {
+ /* copy data from inbuffer to outbuffer */
+ bufEdit->copyMode = CopyWhole; // copy whole
+ CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
+ }
+ } while (mcbpcIndex == 8);
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,0,inBuffer->getIndex,inBuffer->bitIndex); // 0: mcbpc
+
+ /* CBPC (2 LSBs of MCBPC) */
+ outParam->cbpc = mcbpcIndex & 3;
+
+ /* DQUANT is given for MCBPC indexes 4..7 */
+ fDQUANT = mcbpcIndex & 4;
+
+ /* MB Type*/
+ outParam->mbType = (mcbpcIndex <4)?3:4;
+
+ /* INTRA_MODE */
+ if (inpParam->fAIC)
+ {
+ retValue = vdxGetIntraMode(inBuffer,&fINTRAMODE,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ outParam->predMode = fINTRAMODE;
+ }
+
+ /* ac_pred_flag (1 bit) */
+ if (inpParam->fMPEG4) {
+ outParam->ac_pred_flag = (u_char) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ }
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); // 2: cbpy
+
+ /* CBPY */
+ retValue = vdxGetCBPY(inBuffer, &cbpyIndex, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ outParam->cbpy = cbpyIndex;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); // 2: cbpy
+ VDT_SET_START_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+
+ if (fDQUANT) {
+ retValue = vdxUpdateQuant(inBuffer, inpParam->fMQ, inpParam->quant,
+ &outParam->quant, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ }
+
+ /* Else no DQUANT */
+ else
+ outParam->quant = inpParam->quant;
+
+ /* Color Toning */
+ hTranscoder->AfterMBLayer(outParam->quant);
+
+exitFunction:
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+ outParam->mcbpc = mcbpcIndex;
+
+ MBinstance->mcbpc = mcbpcIndex;
+ MBinstance->quant = outParam->quant;
+ MBinstance->cbpc = outParam->cbpc;
+ MBinstance->cbpy = outParam->cbpy;
+ MBinstance->ac_pred_flag = outParam->ac_pred_flag;
+ MBinstance->dquant = fDQUANT ? outParam->quant - inpParam->quant : 0;
+
+ hTranscoder->OneIMBDataStarted(MBinstance);
+ free(MBinstance);
+
+ return retValue;
+}
+
+
+/* {{-output"vdxGetPPBMBLayer.txt"}} */
+/*
+ * vdxGetPPBMBLayer
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * inpParam input parameters
+ * outParam output parameters
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ * Function:
+ * This function reads the macroblock layer data of an INTER macroblock.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+
+int vdxGetPPBMBLayer(
+ bibBuffer_t *inBuffer,
+ bibBuffer_t *outBuffer,
+ bibBufferEdit_t *bufEdit,
+ int /*aColorEffect*/,
+ int */*aStartByteIndex*/,
+ int */*aStartBitIndex*/,
+ TBool /*aGetDecodedFrame*/,
+ int * /*bwMBType*/,
+ const vdxGetPPBMBLayerInputParam_t *inpParam,
+ vdxPPBMBLayer_t *outParam,
+ int *bitErrorIndication, CMPEG4Transcoder *hTranscoder)
+
+/* {{-output"vdxGetPPBMBLayer.txt"}} */
+{
+ static const int mbTypeToMBClass[6] =
+ {VDX_MB_INTER, VDX_MB_INTER, VDX_MB_INTER,
+ VDX_MB_INTRA, VDX_MB_INTRA, VDX_MB_INTER};
+
+ static const int mbTypeToDQUANTI[6] =
+ {0, 1, 0, 0, 1, 1};
+
+ int
+ numBitsGot,
+ retValue = VDX_OK,
+ mcbpc,
+ mbType,
+ mbClass,
+ fDQUANT = 0,
+ fMVD,
+ numMVs,
+ fCBPB,
+ fMVDB,
+ cbpyIndex,
+ fINTRAMODE;
+ int16
+ bibError = 0;
+ u_int32
+ bits;
+
+ int StartByteIndex;
+ int StartBitIndex;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(inpParam != NULL);
+ vdxAssert(inpParam->pictureType == VDX_PIC_TYPE_P ||
+ inpParam->pictureType == VDX_PIC_TYPE_PB||
+ inpParam->pictureType == VDX_PIC_TYPE_IPB);
+ vdxAssert(outParam != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ /* MVE */
+// int startByteIndex = inBuffer->getIndex;
+// int startBitIndex = inBuffer->bitIndex;
+
+ vdxPMBListItem_t *MBinstance;
+ // Create new MBInstance for the next MB
+ MBinstance = (vdxPMBListItem_t *) malloc(sizeof(vdxPMBListItem_t));
+ if (!MBinstance)
+ {
+ deb("ERROR - vdxGetPMBLayer::MBinstance creation failed\n");
+ goto exitFunction;
+ }
+ memset(MBinstance, 0, sizeof(vdxPMBListItem_t));
+ VDT_SET_START_POSITION(MBinstance,11,0,7); // 11: MB stuffing bits
+ VDT_SET_END_POSITION(MBinstance,11,0,7); // 11: MB stuffing bits
+
+ /* Set default output values */
+ memset(outParam, 0, sizeof(vdxPPBMBLayer_t));
+ outParam->quant = inpParam->quant;
+
+ /* Loop while MCBPC indicates stuffing */
+ do {
+
+ // note: stufffing includes COD+MCBPC in P frames
+ StartByteIndex = inBuffer->getIndex;
+ StartBitIndex = inBuffer->bitIndex;
+
+ /* COD */
+ bits = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ outParam->fCodedMB = (int) bits ^ 1;
+
+ /* If not coded (i.e. if COD == 1) */
+ if (bits)
+ goto exitFunction;
+
+ /* Else coded (i.e. if COD == 0) */
+ else {
+ /* MCBPC */
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,0,inBuffer->getIndex,inBuffer->bitIndex); // 0: mcbpc
+
+ retValue = vdxGetMCBPCInter(
+ inBuffer,
+ inpParam->fPLUSPTYPE,
+ inpParam->fAP || inpParam->fDF,
+ inpParam->fFirstMBOfPicture,
+ &mcbpc,
+ bitErrorIndication);
+
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ /* See section 5.3.2 of the H.263 recommendation to find out
+ the details of this illegal codeword check. */
+ if (mcbpc == 20 &&
+ inpParam->pictureType == VDX_PIC_TYPE_IPB &&
+ inpParam->fCustomSourceFormat &&
+ inpParam->fFirstMBOfPicture)
+ {
+ deb0p("ERROR. Illegal MCBPC stuffing.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* MVE */
+ /* remember to output the MB stufffing bits!! */
+ if (mcbpc == 20)
+ {
+ // copy data from inbuffer to outbuffer
+ bufEdit->copyMode = CopyWhole; // copy whole
+ CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
+ }
+ }
+ } while (mcbpc == 20);
+
+ /* Decrease indexes > 20 to enable consistent MCBPC handling */
+ if (mcbpc > 20)
+ mcbpc--;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,0,inBuffer->getIndex,inBuffer->bitIndex); // 0: mcbpc
+
+ /* CBPC (2 LSBs of MCBPC) */
+ outParam->cbpc = mcbpc & 3;
+
+ /* MCBPC --> MB type & included data elements */
+ mbType = outParam->mbType = mcbpc / 4;
+ mbClass = outParam->mbClass = mbTypeToMBClass[mbType];
+ fDQUANT = mbTypeToDQUANTI[mbType];
+ /* MVD is included always for PB-frames and always if MB type is INTER */
+ fMVD = inpParam->pictureType != VDX_PIC_TYPE_P || mbClass == VDX_MB_INTER;
+ numMVs = outParam->numMVs =
+ (fMVD) ?
+ ((mbType == 2 || mbType == 5) ? 4 : 1) :
+ 0;
+
+ /* 4 MVs can be present only when in Advanced Prediction or Deblocking
+ Filter mode */
+ if (numMVs == 4 && !inpParam->fAP && !inpParam->fDF) {
+ deb0p("ERROR. Illegal MCBPC.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* INTRA_MODE */
+ if ((inpParam->fAIC)&&((mbType == 3) || (mbType == 4)))
+ {
+ retValue = vdxGetIntraMode(inBuffer,&fINTRAMODE,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ outParam->predMode = fINTRAMODE;
+ }
+
+ if (inpParam->pictureType == VDX_PIC_TYPE_PB) {
+ int modbIndex;
+ /* MODB */
+ retValue = vdxGetNormalMODB(inBuffer, &modbIndex, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ fCBPB = (int) (modbIndex & 2);
+ fMVDB = outParam->fMVDB = (int) (modbIndex > 0);
+ }
+ else if (inpParam->pictureType == VDX_PIC_TYPE_IPB)
+ {
+ int modbIndex;
+ /* MODB in Improved PB mode */
+ retValue = vdxGetImpPBMODB(inBuffer,&modbIndex,bitErrorIndication);
+ fCBPB = (int) (modbIndex & 1);
+ fMVDB = outParam->fMVDB = (int) ((modbIndex & 2)>>1);
+ outParam->IPBPredMode = (int) (modbIndex / 2);
+ }
+ else {
+ fCBPB = 0;
+ fMVDB = outParam->fMVDB = 0;
+ }
+
+ if (fCBPB) {
+ /* CBPB */
+ outParam->cbpb = (int) bibGetBits(6, inBuffer, &numBitsGot,
+ bitErrorIndication, &bibError);
+
+
+ }
+ else
+ outParam->cbpb = 0;
+
+ /* ac_pred_flag (1 bit) */
+ if (inpParam->fMPEG4) {
+ if (mbClass == VDX_MB_INTRA) {
+ outParam->ac_pred_flag = (u_char) bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ }
+ }
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); // 2: cbpy
+
+ /* CBPY */
+ retValue = vdxGetCBPY(inBuffer, &cbpyIndex, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ if (mbClass == VDX_MB_INTER)
+ /* Convert index to INTER CBPY */
+ outParam->cbpy = 15 - cbpyIndex;
+
+ else
+ outParam->cbpy = cbpyIndex;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); // 2: cbpy
+ VDT_SET_START_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+
+ if (fDQUANT) {
+ /* Get DQUANT and update QUANT */
+ retValue = vdxUpdateQuant(inBuffer, inpParam->fMQ, inpParam->quant,
+ &outParam->quant, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ }
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+ VDT_SET_START_POSITION(MBinstance,10,inBuffer->getIndex,inBuffer->bitIndex); // 10: mv
+
+ /* Color Toning */
+ hTranscoder->AfterMBLayer(outParam->quant);
+
+
+ if (fMVD) {
+ int i;
+
+ /* If no new Annex D is in use */
+ if (!inpParam->fPLUSPTYPE || !inpParam->fUMV) {
+
+ if (inpParam->fMPEG4) {
+ for (i = 0; i < numMVs; i++) {
+ retValue = vdxGetScaledMVD(inBuffer,inpParam->f_code,&outParam->mvdx[i],bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ retValue = vdxGetScaledMVD(inBuffer,inpParam->f_code,&outParam->mvdy[i],bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ }
+ } else {
+ for (i = 0; i < numMVs; i++) {
+ retValue = vdxGetMVD(inBuffer, &outParam->mvdx[i], bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ retValue = vdxGetMVD(inBuffer, &outParam->mvdy[i], bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ }
+ }
+ }
+
+ else if (inpParam->fPLUSPTYPE && inpParam->fUMV) /* Annex D */
+ {
+ for (i = 0; i < numMVs; i++)
+ {
+ retValue = vdxUMVGetMVD(inBuffer,&outParam->mvdx[i],bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ retValue = vdxUMVGetMVD(inBuffer,&outParam->mvdy[i],bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ if ((outParam->mvdx[i] == 5) && (outParam->mvdy[i] == 5))
+ /* Read "Prevent Start Code Emulation bit" if 000000 occurs */
+ {
+ bits = bibGetBits(1,inBuffer,&numBitsGot,bitErrorIndication,
+ &bibError);
+
+
+ if (!bits) {
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ }
+ }
+ }
+ }
+
+ if (fMVDB) {
+ int i;
+ if (!inpParam->fPLUSPTYPE || !inpParam->fUMV)
+ {
+ retValue = vdxGetMVD(inBuffer,&outParam->mvdbx,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ retValue = vdxGetMVD(inBuffer,&outParam->mvdby,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ }
+ else if (inpParam->fPLUSPTYPE && inpParam->fUMV) /* Annex D */
+ {
+ for (i = 0; i < numMVs; i++)
+ {
+ retValue = vdxUMVGetMVD(inBuffer,&outParam->mvdbx,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ retValue = vdxUMVGetMVD(inBuffer,&outParam->mvdby,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ if ((outParam->mvdbx == 5) && (outParam->mvdby == 5))
+ /* Read "Prevent Start Code Emulation bit" if 000000 occurs */
+ {
+ bits = bibGetBits(1,inBuffer,&numBitsGot,bitErrorIndication,
+ &bibError);
+
+ if (!bits) {
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ }
+ }
+ }
+ }
+
+
+
+exitFunction:
+
+ /* MVE */
+ /* PB frame is not allowed !!! */
+ VDT_SET_END_POSITION(MBinstance,10,inBuffer->getIndex,inBuffer->bitIndex); // 10: mv
+ outParam->mcbpc = mcbpc;
+
+ for (int i = 0; i < outParam->numMVs; i++)
+ {
+ MBinstance->mvx[i] = outParam->mvdx[i];
+ MBinstance->mvy[i] = outParam->mvdy[i];
+ }
+
+ MBinstance->mcbpc = outParam->mcbpc;
+ MBinstance->fCodedMB = (unsigned char)outParam->fCodedMB ;
+ MBinstance->mbType = outParam->mbType;
+ MBinstance->mbClass = outParam->mbClass;
+ MBinstance->quant = outParam->quant;
+ MBinstance->cbpc = outParam->cbpc;
+ MBinstance->cbpy = outParam->cbpy;
+ MBinstance->ac_pred_flag = outParam->ac_pred_flag;
+ MBinstance->numMVs = outParam->numMVs;
+ MBinstance->dquant = fDQUANT ? outParam->quant - inpParam->quant : 0;
+
+ hTranscoder->OnePMBDataStarted(MBinstance);
+ free(MBinstance);
+
+ return retValue;
+}
+
+
+/*
+ * Block Layer Global Functions
+ */
+
+/* {{-output"vdxGetIntraDCTBlock.txt"}} */
+/*
+ * vdxGetIntraDCTBlock
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * fCodedBlock 0 if COD is 1, 1 if COD is 0
+ * block DCT coefficients of the block
+ * in zigzag order
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ * fMQ flag for Modified Quantization
+ * qp quantization parameter
+ *
+ * Function:
+ * This function gets the DCT coefficients for one INTRA block.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxGetIntraDCTBlock(
+ bibBuffer_t *inBuffer,
+ int fCodedBlock,
+ int *block,
+ int *bitErrorIndication,
+ int fMQ,
+ int qp)
+/* {{-output"vdxGetIntraDCTBlock.txt"}} */
+{
+ int
+ numBitsGot,
+ retValue = VDX_OK;
+ int16
+ bibError = 0;
+ u_int32
+ bits;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(block != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ /* MVE */
+ int fEscapeCodeUsed = 0;
+
+ /* INTRADC */
+ bits = bibGetBits(8, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+ block[0] = (int) (bits << 3);
+
+ /* If (FLC == 1111 1111) */
+ if (block[0] == 2040)
+ block[0] = 1024;
+
+
+ if (fCodedBlock)
+ retValue = vdxGetDCTBlock(inBuffer, 1, 0, block, bitErrorIndication, fMQ,qp, &fEscapeCodeUsed);
+
+ else
+ memset(block + 1, 0, 63 * sizeof(int));
+
+ return retValue;
+
+
+}
+
+
+/* {{-output"vdxGetDCTBlock.txt"}} */
+/*
+ * vdxGetDCTBlock
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * startIndex the first index in block where to put data
+ * fMPEG4EscapeCodes use MPEG-4 escape codes (3 alternatives)
+ * block array for block (length 64)
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ * fMQ
+ * qp
+ * fEscapeCodeUsed
+ * Function:
+ * This function reads a block from bit buffer using Huffman codes listed
+ * in TCOEF table. The place, where the block is read is given as a
+ * pointer parameter.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+int vdxGetDCTBlock(
+ bibBuffer_t *inBuffer,
+ int startIndex,
+ u_char fMPEG4EscapeCodes,
+ int *block,
+ int *bitErrorIndication,
+ int fMQ,
+ int qp,
+ int *fEscapeCodeUsed)
+/* {{-output"vdxGetDCTBlock.txt"}} */
+{
+ /* Lookup tables: val field contains
+ 1 bit for LAST, 8 bits for RUN and 4 bits for LEVEL */
+ static const vdxVLCTable_t tcoefTab0[] = {
+ {4225,7}, {4209,7}, {4193,7}, {4177,7}, {193,7}, {177,7},
+ {161,7}, {4,7}, {4161,6}, {4161,6}, {4145,6}, {4145,6},
+ {4129,6}, {4129,6}, {4113,6}, {4113,6}, {145,6}, {145,6},
+ {129,6}, {129,6}, {113,6}, {113,6}, {97,6}, {97,6},
+ {18,6}, {18,6}, {3,6}, {3,6}, {81,5}, {81,5},
+ {81,5}, {81,5}, {65,5}, {65,5}, {65,5}, {65,5},
+ {49,5}, {49,5}, {49,5}, {49,5}, {4097,4}, {4097,4},
+ {4097,4}, {4097,4}, {4097,4}, {4097,4}, {4097,4}, {4097,4},
+ {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2},
+ {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2},
+ {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2},
+ {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2},
+ {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2},
+ {1,2}, {1,2}, {17,3}, {17,3}, {17,3}, {17,3},
+ {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3},
+ {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3},
+ {33,4}, {33,4}, {33,4}, {33,4}, {33,4}, {33,4},
+ {33,4}, {33,4}, {2,4}, {2,4}, {2,4}, {2,4},
+ {2,4}, {2,4}, {2,4}, {2,4}
+ };
+
+ static const vdxVLCTable_t tcoefTab1[] = {
+ {9,10}, {8,10}, {4481,9}, {4481,9}, {4465,9}, {4465,9},
+ {4449,9}, {4449,9}, {4433,9}, {4433,9}, {4417,9}, {4417,9},
+ {4401,9}, {4401,9}, {4385,9}, {4385,9}, {4369,9}, {4369,9},
+ {4098,9}, {4098,9}, {353,9}, {353,9}, {337,9}, {337,9},
+ {321,9}, {321,9}, {305,9}, {305,9}, {289,9}, {289,9},
+ {273,9}, {273,9}, {257,9}, {257,9}, {241,9}, {241,9},
+ {66,9}, {66,9}, {50,9}, {50,9}, {7,9}, {7,9},
+ {6,9}, {6,9}, {4353,8}, {4353,8}, {4353,8}, {4353,8},
+ {4337,8}, {4337,8}, {4337,8}, {4337,8}, {4321,8}, {4321,8},
+ {4321,8}, {4321,8}, {4305,8}, {4305,8}, {4305,8}, {4305,8},
+ {4289,8}, {4289,8}, {4289,8}, {4289,8}, {4273,8}, {4273,8},
+ {4273,8}, {4273,8}, {4257,8}, {4257,8}, {4257,8}, {4257,8},
+ {4241,8}, {4241,8}, {4241,8}, {4241,8}, {225,8}, {225,8},
+ {225,8}, {225,8}, {209,8}, {209,8}, {209,8}, {209,8},
+ {34,8}, {34,8}, {34,8}, {34,8}, {19,8}, {19,8},
+ {19,8}, {19,8}, {5,8}, {5,8}, {5,8}, {5,8}
+ };
+
+ static const vdxVLCTable_t tcoefTab2[] = {
+ {4114,11}, {4114,11}, {4099,11}, {4099,11}, {11,11}, {11,11},
+ {10,11}, {10,11}, {4545,10}, {4545,10}, {4545,10}, {4545,10},
+ {4529,10}, {4529,10}, {4529,10}, {4529,10}, {4513,10}, {4513,10},
+ {4513,10}, {4513,10}, {4497,10}, {4497,10}, {4497,10}, {4497,10},
+ {146,10}, {146,10}, {146,10}, {146,10}, {130,10}, {130,10},
+ {130,10}, {130,10}, {114,10}, {114,10}, {114,10}, {114,10},
+ {98,10}, {98,10}, {98,10}, {98,10}, {82,10}, {82,10},
+ {82,10}, {82,10}, {51,10}, {51,10}, {51,10}, {51,10},
+ {35,10}, {35,10}, {35,10}, {35,10}, {20,10}, {20,10},
+ {20,10}, {20,10}, {12,11}, {12,11}, {21,11}, {21,11},
+ {369,11}, {369,11}, {385,11}, {385,11}, {4561,11}, {4561,11},
+ {4577,11}, {4577,11}, {4593,11}, {4593,11}, {4609,11}, {4609,11},
+ {22,12}, {36,12}, {67,12}, {83,12}, {99,12}, {162,12},
+ {401,12}, {417,12}, {4625,12}, {4641,12}, {4657,12}, {4673,12},
+ {4689,12}, {4705,12}, {4721,12}, {4737,12}, {7167,7},
+ {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7},
+ {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7},
+ {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7},
+ {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7},
+ {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7},
+ {7167,7}
+ };
+
+ static const int inter_max_level[2][64] = {
+ {12, 6, 4, 3, 3, 3, 3, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0},
+
+ {3, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}
+ };
+
+ static const int inter_max_run0[13] = { 999,
+ 26, 10, 6, 2, 1, 1,
+ 0, 0, 0, 0, 0, 0
+ };
+
+ static const int inter_max_run1[4] = { 999, 40, 1, 0 };
+
+ int
+ numBitsGot, /* number of bits got from bit buffer */
+ retValue = VDX_OK,
+ code, /* bits got from bit buffer */
+ index, /* index to zigzag table running from 1 to 63 */
+ run, /* RUN code */
+ level; /* LEVEL code */
+
+ int16
+ bibError = 0;
+
+ u_int32
+ last, /* LAST code (see standard) */
+ sign, /* sign for level */
+ tmp; /* temporary variable for reading some redundant bits */
+
+ vdxVLCTable_t const *tab; /* pointer to lookup table */
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(startIndex == 0 || startIndex == 1);
+ vdxAssert(block != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ /* Reset all coefficients to zero in order to avoid writing
+ zeros one by one during run-length decoding */
+ memset(&block[startIndex], 0, (64 - startIndex) * sizeof(int));
+
+ index = startIndex;
+
+ /* MVE */
+ *fEscapeCodeUsed = 0;
+
+ do {
+ /* Read next codeword */
+ code = (int) bibShowBits(12, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ /* Select the right table and index for the codeword */
+ if (code >= 512)
+ tab = &tcoefTab0[(code >> 5) - 16];
+ else if (code >= 128)
+ tab = &tcoefTab1[(code >> 2) - 32];
+ else if (code >= 8)
+ tab = &tcoefTab2[code - 8];
+ else {
+ deb("ERROR - illegal TCOEF\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* Flush the codeword from the buffer */
+ bibFlushBits(tab->len, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ if (tab->val == 7167) /* ESCAPE */
+ {
+
+
+ /* the following is modified for 3-mode escape */
+ if(fMPEG4EscapeCodes) {
+
+ int run_offset=0,
+ level_offset=0;
+
+ code = (int) bibShowBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ if (code<=2) {
+
+ /* escape modes: level or run is offset */
+ if (code==2) run_offset=1;
+ else level_offset=1;
+
+ /* Flush the escape code from the buffer */
+ if (run_offset)
+ bibFlushBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ else
+ bibFlushBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ /* Read next codeword */
+ code = (int) bibShowBits(12, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+
+ /* Select the right table and index for the codeword */
+ if (code >= 512)
+ tab = &tcoefTab0[(code >> 5) - 16];
+ else if (code >= 128)
+ tab = &tcoefTab1[(code >> 2) - 32];
+ else if (code >= 8)
+ tab = &tcoefTab2[code - 8];
+ else {
+ deb("ERROR - illegal TCOEF\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ bibFlushBits(tab->len, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ run = (tab->val >> 4) & 255;
+ level = tab->val & 15;
+ last = (tab->val >> 12) & 1;
+
+ /* need to add back the max level */
+ if (level_offset)
+ level = level + inter_max_level[last][run];
+ else if (last)
+ run = run + inter_max_run1[level]+1;
+ else
+ run = run + inter_max_run0[level]+1;
+
+ sign = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+
+ if (sign)
+ level = -level;
+
+ } else {
+
+ /* Flush the codeword from the buffer */
+ bibFlushBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+
+ /* LAST */
+ last = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+
+ /* RUN */
+ run = (int) bibGetBits(6, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ /* MARKER BIT */
+ tmp = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError);
+
+
+ if(!tmp) {
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ /* LEVEL */
+ level = (int) bibGetBits(12, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ /* MARKER BIT */
+ tmp = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError);
+
+
+ if ( !tmp ) {
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* 0000 0000 0000 and 1000 0000 0000 is forbidden unless in MQ mode */
+ if (level == 0 || level == 2048) {
+ deb("ERROR - illegal level.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* Codes 1000 0000 0001 .. 1111 1111 1111 */
+ if (level > 2048)
+ level -= 4096;
+
+ } /* flc */
+
+ } else { /* !fMPEG4EscapeCodes */
+
+ /* MVE */
+ *fEscapeCodeUsed = 1;
+
+ /* LAST */
+ last = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ /* RUN */
+ run = (int) bibGetBits(6, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ /* LEVEL */
+ level = (int) bibGetBits(8, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ /* Codes 1000 0001 .. 1111 1111 */
+ if (level > 128)
+ level -= 256;
+
+
+ /* 0000 0000 is forbidden, 1000 0000 is forbidden unless in MQ mode */
+ if (level == 0) {
+ deb("ERROR - illegal level.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ if (level == 128)
+ {
+ if (fMQ)
+ {
+ level = (int) bibGetBits(11,inBuffer,&numBitsGot,
+ bitErrorIndication,&bibError);
+
+
+ level = ((level&0x003F) <<5) | (level >> 6);
+ if (level>1023) level -= 2048;
+
+ /* See section T.5 of the H.263 recommendation to understand
+ this restriction. */
+ if (((level > -127) && (level < 127)) || (qp >= 8))
+ {
+ deb("ERROR - illegal extended level.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ }
+ else
+ {
+ deb("ERROR - illegal level.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ }
+ } /* End fMPEG4EscapeCodes switch */
+ }
+
+ else {
+ run = (tab->val >> 4) & 255;
+ level = tab->val & 15;
+ last = (tab->val >> 12) & 1;
+
+ sign = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ if (sign)
+ level = -level;
+ }
+
+ /* If too many coefficients */
+ if (index + run > 63) {
+ deb("ERROR - too many TCOEFs.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* Do run-length decoding */
+
+ /* Note: No need to set coeffs to zero since they are already reset
+ in the beginning of the function */
+ index += run;
+
+ block[index++] = level;
+
+ } while (!last);
+
+ exitFunction:
+
+ /* Note: No need to set the rest of the coefficients to zero since
+ they are already reset in the beginning of the function */
+
+ if (!bibError)
+ return retValue;
+
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+ else if ( *bitErrorIndication ) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+ else
+ return VDX_ERR_BIB;
+}
+
+
+
+/*
+ * Picture Layer Local Functions
+ */
+
+/*
+ * vdxActAfterIncorrectSEI
+ *
+ * Parameters:
+ * inBuffer B: Bit Buffer instance
+ * fPLUSPTYPE I: signals the existence of PLUSPTYPE
+ * fLast B: set to 1 if SEI flushed,
+ * otherwise not changed
+ * bitErrorIndication B: bit error indication, see biterr.h for
+ * the possible values
+ *
+ * Function:
+ * Problem: H.263 v1 did not specify FTYPE/DSIZE values, but rather
+ * any data can be transfered in PSUPP. Section 5.1.3 of
+ * H.263 Recommendation specifies that Annex L and Annex W supplemental
+ * enhancement functions can be used also if PLUSPTYPE is not in use.
+ * Consequently, if PLUSPTYPE is not in use and if the bit-stream
+ * violates FTYPE/DSIZE (or any other) rules defined in Annex L or
+ * Annex W, we do not know if the far-end encoder is transmitting
+ * proprietary PSUPP values (allowed in H.263 v1) or if a bit error
+ * has hit the SEI data that actually follows Annex L/W.
+ *
+ * This function is called after an illegal Annex L/W parameter has
+ * been detected. The function acts as follows:
+ * - If PLUSPTYPE is in use, there must be
+ * a bit error, and the function signals the error.
+ * - If PLUSPTYPE is not in use, there is
+ * a bit error or the far-end encoder uses proprietary PSUPP values.
+ * The function flushes all PSUPP fields and returns without error
+ * indication.
+ * NOTE: This scheme could be improved if the decoder knows that
+ * the far-end encoder is always following Annex L/W.
+ *
+ * Returns:
+ * VDX_OK
+ * VDX_OK_BUT_BIT_ERROR
+ * VDX_ERR
+ */
+
+static int vdxActAfterIncorrectSEI(
+ bibBuffer_t *inBuffer,
+ int fPLUSPTYPE,
+ int *fLast,
+ int *bitErrorIndication)
+{
+ /* If Annex L/W is in use for sure */
+ if (fPLUSPTYPE) {
+
+ /* Return indication of bit error */
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else Annex L/W is not necessarily on */
+ else {
+
+ /* We are out of sync due to bit error or
+ do not understand the non-standard PEI/PSUPP syntax
+ --> flush the rest of PEI/PSUPP pairs */
+
+ *fLast = 1;
+
+ return vdxFlushSEI(inBuffer, bitErrorIndication);
+ }
+}
+
+
+/*
+ * vdxStandardSourceFormatToFrameSize
+ *
+ *
+ * Parameters:
+ * sourceFormat the three source format bits
+ * width luminance image width
+ * height luminance image height
+ *
+ * Function:
+ * This function converts the source format bits to luminance image size.
+ *
+ * Returns:
+ * Nothing.
+ *
+ *
+ *
+ */
+
+static void vdxStandardSourceFormatToFrameSize(int sourceFormat, int *width, int *height)
+{
+ vdxAssert(sourceFormat >= 1 && sourceFormat <= 5);
+
+ switch (sourceFormat) {
+ case 1: /* sub-QCIF */
+ *width = 128;
+ *height = 96;
+ break;
+ case 2: /* QCIF */
+ *width = 176;
+ *height = 144;
+ break;
+ case 3: /* CIF */
+ *width = 352;
+ *height = 288;
+ break;
+ case 4: /* 4CIF */
+ *width = 704;
+ *height = 576;
+ break;
+ case 5: /* 16 CIF */
+ *width = 1408;
+ *height = 1152;
+ break;
+ }
+}
+
+
+/*
+ * Slice Layer Local Functions
+ */
+
+/*
+ * vdxFrameSizeToPictureFormat
+ *
+ *
+ * Parameters:
+ * width luminance image width
+ * height luminance image height
+ *
+ * Function:
+ * This function converts luminance image size to picture format.
+ *
+ * Returns:
+ * Source format
+ *
+ *
+ */
+
+int vdxFrameSizeToPictureFormat(int width, int /*height*/)
+{
+ if (width <= 128)
+ return 0; /* sub-QCIF */
+ else if (width <= 176)
+ return 1; /* QCIF */
+ else if (width <= 352)
+ return 2; /* CIF */
+ else if (width <= 704)
+ return 3; /* 4CIF */
+ else if (width <= 1408)
+ return 4; /* 16CIF */
+ else if (width <= 2048)
+ return 5; /* 2048x1152 */
+ else
+ return -1; /* Should never happen */
+}
+
+/*
+ * Macroblock Layer Local Functions
+ */
+
+/*
+ * vdxGetCBPY
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * index index to the CBPY table of H.263
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the CBPY code.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxGetCBPY(bibBuffer_t *inBuffer, int *index,
+ int *bitErrorIndication)
+{
+ static const vdxVLCTable_t tabCBPY[48] = {
+ {-1,0}, {-1,0}, {6,6}, {9,6}, {8,5}, {8,5}, {4,5}, {4,5},
+ {2,5}, {2,5}, {1,5}, {1,5}, {0,4}, {0,4}, {0,4}, {0,4},
+ {12,4}, {12,4}, {12,4}, {12,4}, {10,4},{10,4},{10,4},{10,4},
+ {14,4}, {14,4}, {14,4}, {14,4}, {5,4}, {5,4}, {5,4}, {5,4},
+ {13,4}, {13,4}, {13,4}, {13,4}, {3,4}, {3,4}, {3,4}, {3,4},
+ {11,4}, {11,4}, {11,4}, {11,4}, {7,4}, {7,4}, {7,4}, {7,4}
+ };
+
+ int bitsGot, code;
+ int16 ownError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(index != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibShowBits(6, inBuffer, &bitsGot, bitErrorIndication,
+ &ownError);
+
+
+ if (code >= 48) {
+ /* bit pattern = 11xxxx */
+ bibFlushBits(2, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ *index = 15;
+ return VDX_OK;
+ }
+
+ if (code < 2) {
+ deb("vlcGetCBPY: ERROR - illegal code.\n");
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ bibFlushBits(tabCBPY[code].len, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+
+ *index = tabCBPY[code].val;
+
+ if (ownError)
+ return VDX_ERR_BIB;
+
+ return VDX_OK;
+}
+
+
+/*
+ * vdxGetMCBPCInter
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * fPLUSPTYPE flag to indicate if PLUSPTYPE is present
+ * fFourMVsPossible flag to indicate if four motion vectors per
+ * macroblock is allowed
+ * fFirstMBOfPicture flag to indicate if the current macroblock
+ * is the first one of the picture in scan-order
+ * index index to the MCBPC table for P-pictures
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the MCBPC code for P-pictures.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+int vdxGetMCBPCInter(
+ bibBuffer_t *inBuffer,
+ int fPLUSPTYPE,
+ int fFourMVsPossible,
+ int fFirstMBOfPicture,
+ int *index,
+ int *bitErrorIndication)
+{
+ static const vdxVLCTable_t tabMCBPCInter[256] = {
+ {-1,0}, /* 0 = illegal */
+ {20,9}, /* 1 = 0000 0000 1 = stuffing */
+ {19,9}, /* 2 = 0000 0001 0 */
+ {18,9}, /* 3 = 0000 0001 1 */
+ {17,9}, /* 4 = 0000 0010 0 */
+ {7,9}, /* 5 = 0000 0010 1 */
+ {14,8}, {14,8}, /* 6..7 = 0000 0011 x */
+ {13,8}, {13,8}, /* 8..9 = 0000 0100 x */
+ {11,8}, {11,8}, /* 10..11 = 0000 0101 x */
+ {15,7}, {15,7}, {15,7}, {15,7}, /* 12..15 = 0000 011x x */
+ {10,7}, {10,7}, {10,7}, {10,7}, /* 16..19 = 0000 100x x */
+ { 9,7}, { 9,7}, { 9,7}, { 9,7}, /* 20..23 = 0000 101x x */
+ { 6,7}, { 6,7}, { 6,7}, { 6,7}, /* 24..27 = 0000 110x x */
+ { 5,7}, { 5,7}, { 5,7}, { 5,7}, /* 28..31 = 0000 111x x */
+ {16,6}, {16,6}, {16,6}, {16,6},
+ {16,6}, {16,6}, {16,6}, {16,6}, /* 32..39 = 0001 00xx x */
+ { 3,6}, { 3,6}, { 3,6}, { 3,6},
+ { 3,6}, { 3,6}, { 3,6}, { 3,6}, /* 40..47 = 0001 01xx x */
+ {12,5}, {12,5}, {12,5}, {12,5}, {12,5}, {12,5},
+ {12,5}, {12,5}, {12,5}, {12,5}, {12,5}, {12,5},
+ {12,5}, {12,5}, {12,5}, {12,5}, /* 48..63 = 0001 1xxx x */
+ { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4},
+ { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4},
+ { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4},
+ { 2,4}, { 2,4}, { 2,4}, { 2,4}, { 2,4}, /* 64..95 = 0010 xxxx x */
+ { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4},
+ { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4},
+ { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4},
+ { 1,4}, { 1,4}, { 1,4}, { 1,4}, { 1,4}, /* 96..127 = 0011 xxxx x */
+ {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3},
+ {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3},
+ {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3},
+ {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3},
+ {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3},
+ {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3},
+ {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3}, {8,3},
+ {8,3}, {8,3}, /* 128..191 = 010x xxxx x */
+ {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3},
+ {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3},
+ {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3},
+ {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3},
+ {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3},
+ {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3},
+ {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3}, {4,3},
+ {4,3}, {4,3}, {4,3} /* 192..255 = 011x xxxx x */
+ };
+
+ /* Indices 21 - 24 of the MCBPC table for P-pictures,
+ 4 least significant bits from the maximum of 13 are used for indexing */
+ static const vdxVLCTable_t tabMCBPCInterIndices21To24[16] = {
+ {-1,0}, {-1,0}, {-1,0}, {-1,0},
+ {-1,0}, {-1,0}, {-1,0}, {-1,0}, /* 0000 0000 00xx x, illegal */
+ {21,11}, {21,11}, {21,11}, {21,11}, /* 0000 0000 010x x */
+ {22,13}, /* 0000 0000 0110 0 */
+ {-1,0}, /* 0000 0000 0110 1, illegal */
+ {23,13}, /* 0000 0000 0111 0 */
+ {24,13} /* 0000 0000 0111 1 */
+ };
+
+ int bitsGot, code;
+ int16 ownError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(index != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibShowBits(9, inBuffer, &bitsGot, bitErrorIndication,
+ &ownError);
+
+
+ /* If index == 0 */
+ if (code >= 256) {
+ /* bit pattern = 1xxx xxxx x */
+ bibFlushBits(1, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ *index = 0;
+ return VDX_OK;
+ }
+
+ /* If illegal code or indices 21 - 24 */
+ if (code == 0) {
+ /* 0000 0000 0 (indices 21 - 24 in MCBPC table for P-pictures)
+ can only be present if the conditions listed in section 5.3.2 of
+ the H.263 recommendation are fulfilled. Otherwise, the bit pattern
+ is considered an illegal codeword. */
+
+ /* If indices 21 - 24 */
+ if (fPLUSPTYPE && fFourMVsPossible && !fFirstMBOfPicture) {
+
+ /* Note: The following restriction is given in section 5.3.2 of
+ the H.263 recommendation: "Also, encoders shall not allow an MCBPC
+ code for macroblock type 5 to immediately follow seven consecutive
+ zeros in the bitstream (as can be caused by particular INTRADC codes
+ followed by COD=0), in order to prevent start code emulation."
+ This condition is not checked in the decoder, since it would require
+ relatively complex code structure and it is considered relatively
+ improbable. */
+
+ /* Read 13 bits */
+ code = (int) bibShowBits(13, inBuffer, &bitsGot, bitErrorIndication,
+ &ownError);
+
+
+ /* Note: We already know that the first 9 bits are zero, thus code
+ cannot be larger than 15. */
+
+ *index = tabMCBPCInterIndices21To24[code].val;
+
+ /* If illegal bit pattern */
+ if (*index == -1) {
+ deb("vlcGetMCBPCInter: ERROR - illegal code.\n");
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ bibFlushBits(tabMCBPCInterIndices21To24[code].len, inBuffer, &bitsGot,
+ bitErrorIndication, &ownError);
+ }
+
+ /* Else illegal code */
+ else {
+ deb("vlcGetMCBPCInter: ERROR - illegal code.\n");
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+ }
+
+ /* Else indices 1 - 20 */
+ else {
+ bibFlushBits(tabMCBPCInter[code].len, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+
+ *index = tabMCBPCInter[code].val;
+ }
+
+
+ if (ownError)
+ return VDX_ERR_BIB;
+
+ return VDX_OK;
+}
+
+
+/*
+ * vdxGetMCBPCIntra
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * index index to the MCBPC table for I-pictures
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the MCBPC code for I-pictures.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxGetMCBPCIntra(bibBuffer_t *inBuffer, int *index,
+ int *bitErrorIndication)
+{
+ static const vdxVLCTable_t tabMCBPCIntra[64] = {
+ {-1,0}, /* illegal */
+ {5,6},
+ {6,6},
+ {7,6},
+ {4,4}, {4,4}, {4,4}, {4,4},
+ {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3},
+ {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3},
+ {3,3}, {3,3}, {3,3}, {3,3}, {3,3}, {3,3}, {3,3}, {3,3}
+ };
+
+ int bitsGot, code;
+ int16 ownError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(index != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibShowBits(9, inBuffer, &bitsGot, bitErrorIndication,
+ &ownError);
+
+
+ if (code == 1) {
+ /* macroblock stuffing */
+ bibFlushBits(9, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ *index = 8;
+ return VDX_OK;
+ }
+
+ code >>= 3; /* remove unnecessary bits */
+
+ if (code == 0) {
+ deb("vlcGetMCBPCIntra: ERROR - illegal code.\n");
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ if (code >= 32) {
+ /* bit pattern = 1xxxxx */
+ bibFlushBits(1, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ *index = 0;
+ return VDX_OK;
+ }
+
+ bibFlushBits(tabMCBPCIntra[code].len, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+
+ *index = tabMCBPCIntra[code].val;
+
+ if (ownError)
+ return VDX_ERR_BIB;
+
+ return VDX_OK;
+}
+
+
+/*
+ * vdxGetMVD
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * mvdx10 the leftmost vector value from the motion
+ * vector VLC table multiplied by 10 to avoid
+ * non-integer numbers.
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the MVD code.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+int vdxGetMVD(bibBuffer_t *inBuffer, int *mvdx10,
+ int *bitErrorIndication)
+{
+ static const vdxVLCTable_t tabMVD0[14] = {
+ {15,4}, /* 0001 0 */
+ {-15,4}, /* 0001 1 */
+ {10,3}, {10,3}, /* 0010 */
+ {-10,3}, {-10,3}, /* 0011 */
+ {5,2}, {5,2}, {5,2}, {5,2}, /* 010 */
+ {-5,2}, {-5,2}, {-5,2}, {-5,2} /* 011 */
+ };
+
+ static const vdxVLCTable_t tabMVD1[96] = {
+ {60,10}, {-60,10},
+ {55,10}, {-55,10},
+ {50,9}, {50,9}, {-50,9}, {-50,9},
+ {45,9}, {45,9}, {-45,9}, {-45,9},
+ {40,9}, {40,9}, {-40,9}, {-40,9},
+ {35,7}, {35,7}, {35,7}, {35,7}, {35,7}, {35,7}, {35,7}, {35,7},
+ {-35,7}, {-35,7}, {-35,7}, {-35,7}, {-35,7}, {-35,7}, {-35,7}, {-35,7},
+ {30,7}, {30,7}, {30,7}, {30,7}, {30,7}, {30,7}, {30,7}, {30,7},
+ {-30,7}, {-30,7}, {-30,7}, {-30,7}, {-30,7}, {-30,7}, {-30,7}, {-30,7},
+ {25,7}, {25,7}, {25,7}, {25,7}, {25,7}, {25,7}, {25,7}, {25,7},
+ {-25,7}, {-25,7}, {-25,7}, {-25,7}, {-25,7}, {-25,7}, {-25,7}, {-25,7},
+ {20,6}, {20,6}, {20,6}, {20,6}, {20,6}, {20,6}, {20,6}, {20,6},
+ {20,6}, {20,6}, {20,6}, {20,6}, {20,6}, {20,6}, {20,6}, {20,6},
+ {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6},
+ {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6}, {-20,6}
+ };
+
+ static const vdxVLCTable_t tabMVD2[] = {
+ {160,12}, {-160,12}, {155,12}, {-155,12},
+ {150,11}, {150,11}, {-150,11}, {-150,11},
+ {145,11}, {145,11}, {-145,11}, {-145,11},
+ {140,11}, {140,11}, {-140,11}, {-140,11},
+ {135,11}, {135,11}, {-135,11}, {-135,11},
+ {130,11}, {130,11}, {-130,11}, {-130,11},
+ {125,11}, {125,11}, {-125,11}, {-125,11},
+ {120,10}, {120,10}, {120,10}, {120,10},
+ {-120,10}, {-120,10}, {-120,10}, {-120,10},
+ {115,10}, {115,10}, {115,10}, {115,10},
+ {-115,10}, {-115,10}, {-115,10}, {-115,10},
+ {110,10}, {110,10}, {110,10}, {110,10},
+ {-110,10}, {-110,10}, {-110,10}, {-110,10},
+ {105,10}, {105,10}, {105,10}, {105,10},
+ {-105,10}, {-105,10}, {-105,10}, {-105,10},
+ {100,10}, {100,10}, {100,10}, {100,10},
+ {-100,10}, {-100,10}, {-100,10}, {-100,10},
+ {95,10}, {95,10}, {95,10}, {95,10},
+ {-95,10}, {-95,10}, {-95,10}, {-95,10},
+ {90,10}, {90,10}, {90,10}, {90,10},
+ {-90,10}, {-90,10}, {-90,10}, {-90,10},
+ {85,10}, {85,10}, {85,10}, {85,10},
+ {-85,10}, {-85,10}, {-85,10}, {-85,10},
+ {80,10}, {80,10}, {80,10}, {80,10},
+ {-80,10}, {-80,10}, {-80,10}, {-80,10},
+ {75,10}, {75,10}, {75,10}, {75,10},
+ {-75,10}, {-75,10}, {-75,10}, {-75,10},
+ {70,10}, {70,10}, {70,10}, {70,10},
+ {-70,10}, {-70,10}, {-70,10}, {-70,10},
+ {65,10}, {65,10}, {65,10}, {65,10},
+ {-65,10}, {-65,10}, {-65,10}, {-65,10}
+ };
+ int code, bitsGot;
+ int16 ownError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(mvdx10 != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+
+
+ if (code) {
+ *mvdx10 = 0;
+ return VDX_OK;
+ }
+
+ code = (int) bibShowBits(12, inBuffer, &bitsGot, bitErrorIndication,
+ &ownError);
+
+
+ if (code >= 512) {
+ code = (code >> 8) - 2;
+ bibFlushBits(tabMVD0[code].len, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+
+ *mvdx10 = tabMVD0[code].val;
+ return VDX_OK;
+ }
+
+ if (code >= 128) {
+ code = (code >> 2) - 32;
+ bibFlushBits(tabMVD1[code].len, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+
+
+ *mvdx10 = tabMVD1[code].val;
+ return VDX_OK;
+ }
+
+ /* If illegal code, return bit error.
+ In Table 14/H.263, the illegal codes are 0000 0000 000x x and 0000 0000 0010 0.
+ In Table B-12/MPEG-4 Visual, Section B.1.3, 0000 0000 0010 0 is legal.
+ To simplify the source code, 0000 0000 0010 0 is considered legal in H.263 too */
+ if ((code -= 4) < 0) {
+ deb("vlcGetMVD: ERROR - illegal code.\n");
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ bibFlushBits(tabMVD2[code].len, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+
+
+ *mvdx10 = tabMVD2[code].val;
+ return VDX_OK;
+}
+
+
+/*
+ * vdxUMVGetMVD
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * mvdx10 the leftmost vector value from the motion
+ * vector VLC table multiplied by 10 to avoid
+ * non-integer numbers.
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the MVD code when unrestricted motion vector mode
+ * is in use and PLUSTYPE is present.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally,but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ */
+
+static int vdxUMVGetMVD(bibBuffer_t *inBuffer,int *mvdx10,
+ int *bitErrorIndication)
+{
+ int code,bitsGot;
+ int16 ownError = 0;
+ int sign;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(mvdx10 != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,&ownError);
+
+
+ if (code) {
+ *mvdx10 = 0;
+ return VDX_OK;
+ }
+
+ code = (int) bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,&ownError);
+
+ code += 2;
+
+ while (bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,&ownError)
+ )
+ {
+ code <<=1;
+ code = code + bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,&ownError);
+ }
+
+
+ sign = (code & 0x0001)?-5:5;
+ code >>=1;
+ *mvdx10 = sign*code;
+ return VDX_OK;
+}
+
+/*
+ * vdxGetNormalMODB
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * index index to the MODB table
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the MODB code. The function should be used
+ * in PB-frames mode (Annex G).
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+static int vdxGetNormalMODB(bibBuffer_t *inBuffer, int *index,
+ int *bitErrorIndication)
+{
+ int bitsGot, code;
+ int16 ownError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(index != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibShowBits(2, inBuffer, &bitsGot, bitErrorIndication,
+ &ownError);
+
+
+ if (code < 2) {
+ /* code = 0 */
+ bibFlushBits(1, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ *index = 0;
+ return VDX_OK;
+ }
+ else {
+ /* code = 10 or 11 */
+ bibFlushBits(2, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ *index = code - 1;
+ return VDX_OK;
+ }
+}
+
+/*
+ * vdxGetImpPBMODB
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * index index to the MODB table
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the MODB code. This function should be used
+ * in improved PB-frames mode (Annex M).
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally,but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ */
+
+static int vdxGetImpPBMODB(bibBuffer_t *inBuffer,int *index,
+ int *bitErrorIndication)
+{
+ int bitsGot,code;
+ int16 ownError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(index != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,
+ &ownError);
+
+
+
+ if (code == 0)
+ {
+ /* Bidirectional Prediction: code = 0 */
+ *index = 0;
+ return VDX_OK;
+ }
+ else
+ {
+ code = (int) bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,
+ &ownError);
+
+ if (code == 0)
+ {
+ /* Bidirectional Prediction: code = 10 */
+ *index = 1;
+ return VDX_OK;
+ }
+ else
+ {
+ code = (int) bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,
+ &ownError);
+
+
+ if (code == 0)
+ {
+ /* Forward Prediction: code = 110 */
+ *index = 2;
+ return VDX_OK;
+ }
+ else
+ {
+ code = (int) bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,
+ &ownError);
+
+
+ if (code == 0)
+ {
+ /* Forward Prediction: code = 1110 */
+ *index = 3;
+ return VDX_OK;
+ }
+ else
+ {
+ code = (int) bibGetBits(1,inBuffer,&bitsGot,bitErrorIndication,
+ &ownError);
+
+
+ /* Backward Prediction: code = 11110 or 11111 */
+ *index = 4+code;
+ return VDX_OK;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * vdxUpdateQuant
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * fMQ non-zero if the Modified Quantization mode
+ * (Annex T) is in use, otherwise zero
+ * quant the quantization parameter for the previous
+ * macroblock
+ * newQuant the updated quantization parameter for
+ * the current macroblock
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the DQUANT field and updated the current quantization
+ * parameter appropriately.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+int vdxUpdateQuant(
+ bibBuffer_t *inBuffer,
+ int fMQ,
+ int quant,
+ int *newQuant,
+ int *bitErrorIndication)
+{
+ int
+ numBitsGot;
+ int16
+ bibError = 0;
+ u_int32
+ bits;
+ static const int changeOfQuant[2][32] =
+ {{0,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,
+ -2,-2,-2,-2,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3},
+ {0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,1,-5}};
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(newQuant != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ /* DQUANT */
+ if (!fMQ) {
+ bits = bibGetBits(2, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+
+ switch (bits) {
+ case 0: *newQuant = quant - 1; break;
+ case 1: *newQuant = quant - 2; break;
+ case 2: *newQuant = quant + 1; break;
+ case 3: *newQuant = quant + 2; break;
+ }
+
+ /* Clip QUANT to legal range */
+ if (*newQuant < 1)
+ *newQuant = 1;
+ else if (*newQuant > 31)
+ *newQuant = 31;
+ }
+ else
+ {
+ bits = bibGetBits(1,inBuffer,&numBitsGot,bitErrorIndication,
+ &bibError);
+
+
+ if (bits)
+ {
+ bits = bibGetBits(1,inBuffer,&numBitsGot,bitErrorIndication,
+ &bibError);
+
+ *newQuant = quant + changeOfQuant[bits][quant];
+ }
+ else
+ {
+ bits = bibGetBits(5,inBuffer,&numBitsGot,bitErrorIndication,
+ &bibError);
+
+ *newQuant = bits;
+ }
+ }
+
+ return VDX_OK;
+}
+
+
+/*
+ * vdxGetIntraMode
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * index index to the INTRA_MODE parameter for I-pictures
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the INTRA_MODE field from the MB header..
+ * This field exists iff annex I is in use..
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally,but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ */
+
+
+static int vdxGetIntraMode(bibBuffer_t *inBuffer,int *index,
+ int *bitErrorIndication)
+
+{
+ int bitsGot,code;
+ int16 ownError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(index != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ code = (int) bibShowBits(2,inBuffer,&bitsGot,bitErrorIndication,
+ &ownError);
+
+
+ if (code > 1) {
+ /* Bitpattern 1x */
+ bibFlushBits(2,inBuffer,&bitsGot,bitErrorIndication,&ownError);
+ *index = code - 1;
+ return VDX_OK;
+ }
+
+ bibFlushBits(1,inBuffer,&bitsGot,bitErrorIndication,&ownError);
+ *index = 0;
+ return VDX_OK;
+}
+
+
+/*
+ * Block Layer Local Functions
+ */
+
+
+
+
+
+int vdxChangeBlackAndWhiteHeaderIntraIMB(bibBufferEdit_t *bufEdit,
+ int mcbpcIndex,
+ int StartByteIndex,
+ int StartBitIndex)
+{
+ int k, cur_index, new_index, cur_len, new_len, new_val;
+
+ const tVLCTable sCBPCIType[9] =
+ {
+ {1, 1}, {1, 3}, {2, 3}, {3, 3}, {1, 4},
+ {1, 6}, {2, 6}, {3, 6}, {1, 9}
+ };
+
+ // evaluate MCBPC parameters
+ int cur_cbpc = mcbpcIndex & 3;
+ int new_cbpc = 0; // cpbc=0 indicates chroma is 0
+ int mbType = (mcbpcIndex <4)?3:4;
+
+ // evaluate indices in table
+ cur_index = (mbType == 3 ? 0 : 4) + cur_cbpc;
+ new_index = (mbType == 3 ? 0 : 4) + new_cbpc;
+
+ // retrieve values
+ cur_len = sCBPCIType[cur_index].length;
+ new_len = sCBPCIType[new_index].length;
+ new_val = sCBPCIType[new_index].code;
+
+ // allocate memory for storing the parameters
+ if (!bufEdit->editParams)
+ {
+ bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+ bufEdit->numChanges=1;
+ bufEdit->copyMode = CopyWithEdit/*CopyWithEdit*/;
+ }
+ k=bufEdit->numChanges-1;
+ bufEdit->copyMode = CopyWithEdit;
+ // store the new parameters
+ bufEdit->editParams[k].StartByteIndex = StartByteIndex;
+ bufEdit->editParams[k].StartBitIndex = StartBitIndex;
+ bufEdit->editParams[k].curNumBits = cur_len;
+ bufEdit->editParams[k].newNumBits = new_len;
+ bufEdit->editParams[k].newValue = new_val;
+
+ return 0;
+}
+
+int vdxChangeBlackAndWhiteHeaderInterPMB(bibBufferEdit_t *bufEdit,
+ int mcbpcIndex,
+ int StartByteIndex,
+ int StartBitIndex)
+{
+ int k, cur_index, new_index, cur_len, new_len, new_val;
+
+ const tVLCTable sCBPCPType[21] =
+ {
+ {1, 1}, {3, 4}, {2, 4}, {5, 6},
+ {3, 3}, {7, 7}, {6, 7}, {5, 9},
+ {2, 3}, {5, 7}, {4, 7}, {5, 8},
+ {3, 5}, {4, 8}, {3, 8}, {3, 7},
+ {4, 6}, {4, 9}, {3, 9}, {2, 9},
+ {1, 9}
+ };
+
+ // evaluate MCBPC parameters
+ int cur_cbpc = mcbpcIndex & 3;
+ int new_cbpc = 0; // cpbc=0 indicates chroma is 0
+ int mbType;
+
+ mbType = mcbpcIndex / 4;
+
+ // evaluate indices in table
+ cur_index = mbType * 4 + cur_cbpc;
+ new_index = mbType * 4 + new_cbpc;
+
+ // retrieve values
+ cur_len = sCBPCPType[cur_index].length;
+ new_len = sCBPCPType[new_index].length;
+ new_val = sCBPCPType[new_index].code;
+
+ // allocate memory for storing the parameters
+ if (!bufEdit->editParams)
+ {
+ bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+ bufEdit->numChanges=1;
+ bufEdit->copyMode = CopyWithEdit/*CopyWithEdit*/;
+ }
+ k=bufEdit->numChanges-1;
+ bufEdit->copyMode = CopyWithEdit/*CopyWithEdit*/;
+ // store the new parameters
+ bufEdit->editParams[k].StartByteIndex = StartByteIndex;
+ bufEdit->editParams[k].StartBitIndex = StartBitIndex;
+ bufEdit->editParams[k].curNumBits = cur_len;
+ bufEdit->editParams[k].newNumBits = new_len;
+ bufEdit->editParams[k].newValue = new_val;
+
+ return mbType;
+}
+
+
+// End of File