videoeditorengine/h263decoder/src/core.cpp
changeset 9 d87d32eab1a9
parent 0 951a5db380a0
--- a/videoeditorengine/h263decoder/src/core.cpp	Fri Jan 29 14:08:33 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1357 +0,0 @@
-/*
-* 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 decoder core functions.
-*
-*/
-
-
-/* 
- * Includes 
- */
-#include "h263dConfig.h"
-#include "vdc263.h"
-#include "core.h"
-#include "debug.h"
-#include "decblock.h" /* for dblFree and dblLoad */
-#include "decgob.h"
-#include "decpich.h"
-#include "h263dapi.h" /* for H263D_BC_MUX_MODE_SEPARATE_CHANNEL and H263D_ERD_ */
-#include "stckheap.h"
-#include "sync.h"
-#include "vdeims.h"
-#include "vdeimb.h"
-#include "viddemux.h"
-#include "biblin.h"
-#include "MPEG4Transcoder.h"
-
-
-/*
- * Typedefs and structs
- */
-
-/* This structure is used to indicate the expected decoding position. */
-typedef enum {
-   EDP_START_OF_FRAME,
-   EDP_START_OF_GOB_SEGMENT,
-   EDP_START_OF_SLICE_SEGMENT,
-   EDP_END_OF_FRAME
-} vdcExpectedDecodingPosition_t;
-
-
-/*
- * Local function prototypes
- */ 
-
-int vdcFillImageBuffers(
-   vdcInstance_t *instance,
-   int numOfCodedMBs,
-   vdeImb_t *imbP);
-
-
-/*
- * Global functions
- */
-
-/* {{-output"vdcClose.txt"}} */
-/*
- * vdcClose
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *
- * Function:
- *    This function closes the instance. The function frees all the resources
- *    allocated for the instance. The instance handle is no longer valid
- *    after calling this function.
- *
- * Returns:
- *    >= 0                       if the function was successful
- *    < 0                        if an error occured
- *
- */
-
-int vdcClose(vdcHInstance_t hInstance)
-/* {{-output"vdcClose.txt"}} */
-{
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-   int retValue = VDC_OK;
-
-   if (instance == NULL)
-      return retValue;
-
-   mvcFree(&instance->mvcData);
-
-   if ( instance->prevPicHeader != NULL )
-      free( instance->prevPicHeader );
-
-   aicFree(&instance->aicData);
-
-              
-   if ( instance->user_data != NULL )
-      free( instance->user_data );
-
-
-   vdcDealloc(instance);
-
-   return retValue;
-}
-
-
-/* {{-output"vdcDecodeFrame.txt"}} */
-/*
- * vdcDecodeFrame
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *
- *    inBuffer                   pointer to bit buffer, the current position
- *                               of the buffer must start with a PSC
- *
- * Function:
- *    The vdcDecodeFrame function implements the decoding process described
- *    in the H.263 recommendation (version 2). However, it does not support
- *    the following features of the recommendation:
- *       decoding using the H.261 standard (bit 2 in PTYPE),
- *       source format changes during a video sequence.
- *
- *    The function decodes the next frame in
- *    the buffer (inBuffer) meaning that the decoding continues until the next
- *    PSC or EOS is found or until the end of the buffer is not reached.
- *
- * Returns:
- *    VDC_OK                     if the function was succesful
- *    VDC_OK_BUT_BIT_ERROR       if bit errors were detected but
- *                               decoded frames are provided by concealing
- *                               the errors
- *    VDC_OK_BUT_FRAME_USELESS   if severe bit errors were detected
- *                               (no concealment was possible) or
- *                               the bitstream ended unexpectedly
- *    VDC_ERR                    if a processing error occured,
- *                               the instance should be closed
- *
- */
-
-
-int vdcDecodeFrame(vdcHInstance_t hInstance, bibBuffer_t *inBuffer, bibBuffer_t *outBuffer,
-                   bibBufferEdit_t *bufEdit, int aColorEffect, TBool aGetDecodedFrame,
-                   CMPEG4Transcoder *hTranscoder)
-
-/* {{-output"vdcDecodeFrame.txt"}} */
-{
-   int prevGN = -1;           /* GOB number of the latest decoded GOB */
-   int prevGNWithHeader = -1; /* GOB number of the latest decoded GOB with
-                                 a GOB header */
-
-   int numStuffBits;          /* Number of stuffing bits before the sync code */
-
-   int sncCode;               /* the latest synchronization code, see 
-                                 sncCheckSync for the possible values */
-
-   int rtr = -1;              /* reference tr, 0.. */
-   int trp = -1;              /* tr for prediction, -1 if not indicated in 
-                                 the bitstream */
-
-   int retValue = VDC_OK;     /* return value of this function */
-
-
-   int16 error = 0;           /* Used to pass error codes from the sync module */
-
-   u_char
-      *currYFrame = NULL,     /* current P frame */
-      *currUFrame = NULL,
-      *currVFrame = NULL,
-      *refYFrame = NULL,      /* reference frame */
-      *refUFrame = NULL,
-      *refVFrame = NULL;
-
-   u_char *fCodedMBs = NULL;  /* Pointer to table, which indicates coded \
-                                 macroblocks by non-zero value */
-   int numOfCodedMBs = 0;     /* The number of coded macroblocks */
-
-   int *quantParams = NULL;   /* Pointer to table, in which the quantization
-                                 parameter for each macroblock is stored */
-
-   int decStatus = 0;         /* Decoding status, returned from decgob.c */
-   int corruptedSegments = 0; /* counter for corrupted segments */
-   int decodedSegments = 0;   /* counter for decoded segments (used in slice mode) */
-   int headerSuccess = 0;     /* success of picture header */
-   int numDecodedMBs = 0;     /* Total number of decoded MBs */
-   int numMBsInFrame = 0;     /* Number of MBs in frame */
-
-
-   vdcExpectedDecodingPosition_t expectedDecodingPosition;
-                              /* Tells in which part of the bitstream
-                                 the decoding should be */
-
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-                              /* instance data */
-      
-   vdcAssert(instance != NULL);
-
-   /* Initializations */
-
-   instance->currFrame = NULL;
-   expectedDecodingPosition = EDP_START_OF_FRAME;
-   instance->pictureParam.prevTR = instance->pictureParam.tr;
-
-   /* Main loop */
-   for (;;) {
-      int bitErrorIndication = 0;
-
-      sncCode = sncCheckSync(inBuffer, &numStuffBits, &error);
-
-      /* If sncCheckSync failed */
-      if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
-         deb1p("vdcDecodeFrame: ERROR - sncCheckSync returned %d.\n", error);
-         retValue = VDC_ERR;
-         goto exitFunction;
-      }
-
-      /* If EOS was got */
-      if (sncCode == SNC_EOS)
-         instance->fEOS = 1;
-
-      /* If frame ends appropriately */
-      if (expectedDecodingPosition == EDP_END_OF_FRAME &&
-         (sncCode == SNC_PSC || sncCode == SNC_EOS || 
-          sncCode == SNC_STUFFING || error == ERR_BIB_NOT_ENOUGH_DATA )) {
-         goto exitFunction;
-      }
-
-      /* Else if frame (or stream) data ends suddenly */
-      else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
-         retValue = VDC_OK_BUT_BIT_ERROR;
-         goto exitFunction;
-      }
-
-      /* Else if EOS was reached */
-      else if (sncCode == SNC_EOS) {
-         /* The current frame is useless since it ends before it is complete.
-            On the other hand, there is no point in concealing it since
-            it is the last frame of the sequence. */
-         retValue = VDC_OK_BUT_FRAME_USELESS;
-         goto exitFunction;
-      }
-
-      /* Else if frame starts as expected */
-      else if (expectedDecodingPosition == EDP_START_OF_FRAME &&
-         sncCode == SNC_PSC) {
-
-         dphInParam_t pichIn;
-         dphInOutParam_t pichInOut;
-         dphOutParam_t pichOut;
-
-         pichIn.numStuffBits = numStuffBits;
-         pichIn.fNeedDecodedFrame = aGetDecodedFrame | hTranscoder->NeedDecodedYUVFrame();
-
-         pichIn.fReadBits = 1;
-         pichInOut.vdcInstance = instance;
-         pichInOut.inBuffer = inBuffer;
-
-         if ( instance->fRPS ) {
-            /* Store the previous TR for VRC needs */
-            if ( instance->nOfDecodedFrames > 0 )
-               trp = instance->pictureParam.tr;
-            else
-               trp = -1;
-         }
-         /* Get picture header */
-         headerSuccess = dphGetPictureHeader(&pichIn, &pichInOut, &pichOut, &bitErrorIndication);
-
-         if (headerSuccess != DPH_OK) {
-            
-            deb("vdcDecodeFrame: Header decoding unsuccessful due to errors, picture will be discarded.\n");
-            retValue = VDC_OK_BUT_FRAME_USELESS;
-            goto exitFunction;
-         }
-
-         numMBsInFrame = renDriNumOfMBs(instance->currFrame->imb->drawItem);
-
-         currYFrame = pichOut.currYFrame;
-         currUFrame = pichOut.currUFrame;
-         currVFrame = pichOut.currVFrame;
-
-         numOfCodedMBs = 0;
-         fCodedMBs = renDriCodedMBs(instance->currFrame->imb->drawItem);
-         memset(fCodedMBs, 0, numMBsInFrame * sizeof(u_char));
-
-         /* Initialize quantization parameter array */
-         quantParams = instance->currFrame->imb->yQuantParams;
-         memset(quantParams, 0, numMBsInFrame * sizeof(int));
-
-         /* If this is the first frame and callback function has been set, report frame size */ 
-         if (instance->nOfDecodedFrames == 0 && instance->reportPictureSizeCallback) {
-            h263dReportPictureSizeCallback_t cb = 
-               (h263dReportPictureSizeCallback_t)instance->reportPictureSizeCallback;
-            cb(instance->hParent, instance->pictureParam.lumWidth, instance->pictureParam.lumHeight);
-         }
-
-         /* If picture header was ok */
-         if (headerSuccess == DPH_OK)
-         {
-            /* Get and decode Supplemental Enhancement Information */
-            int seiSuccess = dphGetSEI(instance, inBuffer, &bitErrorIndication);
-
-            /* If fatal error while reading SEI */
-            if (seiSuccess < 0) {
-               retValue = VDC_ERR;
-               deb("vdcDecodeFrame: dphGetSEI failed.\n");
-               goto exitFunction;
-            }
-
-            /* Else if bit error while reading SEI */
-            else if (seiSuccess == DPH_OK_BUT_BIT_ERROR) {
-               /* We can't trust that the 1st segment can be decoded.
-                  Thus, let's continue with the 2nd segment. */
-               if ( instance->pictureParam.fSS )
-                  expectedDecodingPosition = EDP_START_OF_SLICE_SEGMENT;
-               else
-                  expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
-               sncCode = sncSeekSync(inBuffer, &error);
-               if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
-                  retValue = VDC_ERR;
-                  deb("vdcDecodeFrame: sncSeekSync failed.\n");
-                  goto exitFunction;
-               }
-               continue;
-            }
-
-
-         }
-
-         if ( hTranscoder->H263PictureHeaderEnded(&pichOut, &pichInOut) != VDC_OK )
-            {
-              retValue = VDC_ERR;
-              goto exitFunction;
-            }
-
-         if (instance->pictureParam.fSS)
-         /* Decode the 1st Slice segment - not supported */
-         {
-             retValue = VDC_OK_BUT_FRAME_USELESS;
-             goto exitFunction;
-         }
-         else
-         /* Decode the 1st GOB segment */
-         {
-            dgobGOBSegmentInParam_t dgobi;
-            dgobGOBSegmentInOutParam_t dgobio;
-
-            dgobi.numStuffBits = 0;
-            dgobi.pictParam = &instance->pictureParam;
-            dgobi.inBuffer = inBuffer;
-
-            dgobi.outBuffer = outBuffer;
-            dgobi.bufEdit = bufEdit;
-
-            dgobi.iColorEffect = aColorEffect; 
-            dgobi.iGetDecodedFrame=aGetDecodedFrame;
-            dgobio.StartByteIndex=0;
-            dgobio.StartBitIndex=7;
-
-            /* fGFIDShouldChange not relevant here */
-
-            dgobio.prevGNWithHeader = 0;
-            dgobio.prevGN = 0;
-            /* dgobio.gfid, not relevant here */
-            dgobio.fCodedMBs = fCodedMBs;
-            dgobio.numOfCodedMBs = numOfCodedMBs;
-            dgobio.quantParams = quantParams;
-            dgobio.mvcData = &instance->mvcData;
-            dgobio.imageStore = instance->imageStore;
-            dgobio.trp = pichOut.trp;
-            dgobio.rtr = 0; /* not relevant since no reference frame exists yet */
-            dgobio.refY = refYFrame;
-            dgobio.refU = refUFrame;
-            dgobio.refV = refVFrame;
-            dgobio.currPY = currYFrame;
-            dgobio.currPU = currUFrame;
-            dgobio.currPV = currVFrame;
-
-            /* the first GOB doesn't have a header */
-            hTranscoder->H263GOBSliceHeaderBegin();
-            hTranscoder->H263GOBSliceHeaderEnded(NULL, NULL);
-
-            decStatus = dgobGetAndDecodeGOBSegmentContents(&dgobi, 
-               instance->pictureParam.pictureType != VDX_PIC_TYPE_I,
-               pichOut.pquant, &dgobio, hTranscoder);
-
-            if (decStatus < 0) {
-               retValue = VDC_ERR;
-               goto exitFunction;
-            }
-
-            hTranscoder->H263OneGOBSliceWithHeaderEnded();
-
-            prevGNWithHeader = dgobio.prevGNWithHeader;
-            prevGN = dgobio.prevGN;
-            numOfCodedMBs = dgobio.numOfCodedMBs;
-            trp = dgobio.trp;
-            rtr = dgobio.rtr;
-            refYFrame = dgobio.refY;
-            refUFrame = dgobio.refU;
-            refVFrame = dgobio.refV;
-            if (prevGN == instance->pictureParam.numGOBs - 1)
-               expectedDecodingPosition = EDP_END_OF_FRAME;
-            else
-               expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
-         }
-      }
-   
-      /* Else if GOB segment starts as expected */
-      else if (expectedDecodingPosition == EDP_START_OF_GOB_SEGMENT &&
-         sncCode == SNC_GBSC) {
-
-         dgobGOBSegmentInParam_t dgobi;
-         dgobGOBSegmentInOutParam_t dgobio;
-
-         dgobi.numStuffBits = numStuffBits;
-         dgobi.pictParam = &instance->pictureParam;
-         dgobi.inBuffer = inBuffer;
-
-         dgobi.outBuffer = outBuffer;
-         dgobi.bufEdit = bufEdit;
-
-         dgobi.iColorEffect = aColorEffect; 
-         dgobi.iGetDecodedFrame= aGetDecodedFrame;
-         if(prevGN==-1)
-         {
-             dgobio.StartByteIndex=0;
-             dgobio.StartBitIndex=7;
-         }
-         else
-         {
-             dgobio.StartByteIndex=dgobi.inBuffer->getIndex;
-             dgobio.StartBitIndex=dgobi.inBuffer->bitIndex;
-         }
-
-
-         /* fGFIDShouldChange, see below */
-
-         dgobio.prevGNWithHeader = prevGNWithHeader;
-         dgobio.prevGN = prevGN;
-         /* dgobio.gfid, see below */
-         dgobio.fCodedMBs = fCodedMBs;
-         dgobio.numOfCodedMBs = numOfCodedMBs;
-         dgobio.quantParams = quantParams;
-         dgobio.mvcData = &instance->mvcData;
-         dgobio.imageStore = instance->imageStore;
-         dgobio.trp = trp;
-         dgobio.rtr = rtr;
-         dgobio.refY = refYFrame;
-         dgobio.refU = refUFrame;
-         dgobio.refV = refVFrame;
-         dgobio.currPY = currYFrame;
-         dgobio.currPU = currUFrame;
-         dgobio.currPV = currVFrame;
-
-         dgobi.fGFIDShouldChange = instance->fGFIDShouldChange;
-         dgobio.gfid = instance->gfid;
-
-         /* Get and decode GOB segment */
-         decStatus = dgobGetAndDecodeGOBSegment(&dgobi, &dgobio, hTranscoder);
-
-         if (decStatus == DGOB_ERR) {
-            retValue = VDC_ERR;
-            goto exitFunction;
-         }
-         if ( instance->fGFIDShouldChange ) {
-            instance->gfid = dgobio.gfid;
-            instance->fGFIDShouldChange = 0;
-         }
-
-         prevGNWithHeader = dgobio.prevGNWithHeader;
-         prevGN = dgobio.prevGN;
-         numOfCodedMBs = dgobio.numOfCodedMBs;
-         trp = dgobio.trp;
-
-
-         rtr = dgobio.rtr;
-
-         refYFrame = dgobio.refY;
-         refUFrame = dgobio.refU;
-         refVFrame = dgobio.refV;
-
-         if (prevGN == instance->pictureParam.numGOBs - 1)
-            expectedDecodingPosition = EDP_END_OF_FRAME;
-         else
-            expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
-      }
-
-      /* Else if Slice segment starts as expected */
-      else if (expectedDecodingPosition == EDP_START_OF_SLICE_SEGMENT &&
-         sncCode == SNC_GBSC) {
-         /* slides not supported */
-         retValue = VDC_OK_BUT_FRAME_USELESS;
-         goto exitFunction;
-
-      }
-
-      /* Else decoding is out of sync */
-      else {
-         switch (expectedDecodingPosition) {
-
-            case EDP_START_OF_FRAME:
-               /* No PSC */
-               /* Check if GFID could be used to recover the picture header */
-               {
-                  dphInParam_t pichIn;
-                  dphInOutParam_t pichInOut;
-                  dphOutParam_t pichOut;
-
-                  pichIn.numStuffBits = numStuffBits;
-                  pichIn.fReadBits = 0;
-
-                  pichInOut.vdcInstance = instance;
-                  pichInOut.inBuffer = inBuffer;
-
-                  headerSuccess = dphGetPictureHeader(&pichIn, &pichInOut, &pichOut, &bitErrorIndication);
-                  if ( headerSuccess == DPH_OK) {
-                     /* Header recovery was successful, start decoding from the next GOB available */
-                     if ( instance->pictureParam.fSS ) {
-                        expectedDecodingPosition = EDP_START_OF_SLICE_SEGMENT;
-                        /* decSlice does not increment these */
-                        decodedSegments++;
-                        corruptedSegments++;
-                     }
-                     else
-                        expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
-                     deb1p("vdcDecodeFrame: Header successfully recovered after PSC loss. FrameNum %d\n",instance->frameNum);
-                     currYFrame = pichOut.currYFrame;
-                     currUFrame = pichOut.currUFrame;
-                     currVFrame = pichOut.currVFrame;
-                     numMBsInFrame = renDriNumOfMBs(instance->currFrame->imb->drawItem);
-                     numOfCodedMBs = 0;
-                     numDecodedMBs = 0;
-                     fCodedMBs = renDriCodedMBs(instance->currFrame->imb->drawItem);
-                     memset(fCodedMBs, 0, numMBsInFrame * sizeof(u_char));
-
-                     /* Initialize quantization parameter array */
-                     quantParams = instance->currFrame->imb->yQuantParams;
-                     memset(quantParams, 0, numMBsInFrame * sizeof(int));
-
-                     /* If this is the first frame and callback function has been set, report frame size */ 
-                     if (instance->nOfDecodedFrames == 0 && instance->reportPictureSizeCallback) {
-                        h263dReportPictureSizeCallback_t cb = 
-                           (h263dReportPictureSizeCallback_t)instance->reportPictureSizeCallback;
-                        cb(instance->hParent, instance->pictureParam.lumWidth, instance->pictureParam.lumHeight);
-                     }
-
-                     continue;
-                  }
-                  else {
-                     retValue = VDC_OK_BUT_FRAME_USELESS;
-                     deb1p("vdcDecodeFrame: Header recovery unsuccessful after PSC loss. FrameNum %d\n",instance->frameNum);
-                     goto exitFunction;
-                  }
-               }
-            case EDP_START_OF_GOB_SEGMENT:
-               if ( sncCode == SNC_PSC ) {
-                  retValue = VDC_OK_BUT_BIT_ERROR;
-                  goto exitFunction;
-               }
-               else {
-                  /* 
-                   * Picture header recovery used next picture header 
-                   * => we are not at the position of GBSC => search the next one 
-                   * This is caused by a erdRestorePictureHeader that does not synchronize 
-                   * bit buffer to GOB headers that have bitErrorIndication != 0.
-                   * This may be considered as a , and it might be good to change it later on.
-                   * This seeking should solve the problem, although maybe not in the most elegant way
-                   */
-                  sncSeekSync( inBuffer, &error );
-                  continue;
-               }
-           default :
-            {
-            
-                retValue = VDC_OK_BUT_FRAME_USELESS;
-                 goto exitFunction;
-            }
-
-         }
-      }
-   }
-
-   exitFunction:
-
-
-   /* If frame(s) not useless */
-   if (retValue == VDC_OK || retValue == VDC_OK_BUT_BIT_ERROR) {
-
-      if (!corruptedSegments && (numDecodedMBs > 0 || prevGN > 0 || instance->pictureParam.numGOBs == 1))
-         retValue = VDC_OK;
-      else {
-         retValue = VDC_OK_BUT_FRAME_USELESS;
-         deb1p("vdcDecodeFrame: Frame useless, too many corrupted segments. FrameNum %d\n",instance->frameNum);
-      }
-   }
-
-   /* If decoding ok and frame not useless */
-   if ( retValue == VDC_OK || retValue == VDC_OK_BUT_BIT_ERROR ) {
-
-
-       /* stuff bits here 'END OF FRAME' -->*/
-         bibStuffBits(outBuffer); 
-       /* <-- */
-
-      if ( instance->nOfDecodedFrames < 0xffffffff )
-         instance->nOfDecodedFrames++;
-
-      if (vdcFillImageBuffers(
-         instance, 
-         numOfCodedMBs, 
-         instance->currFrame->imb) < 0)
-         retValue = VDC_ERR;
-
-
-
-   }
-   if ( retValue == VDC_OK_BUT_FRAME_USELESS ) {
-      /* GFID of the next frame can be whatever, since this frame was useless */
-      instance->gfid = -1; 
-   }
-   if ( instance->fGFIDShouldChange
-        && (    (instance->pictureParam.fSS && decodedSegments == 1) 
-             || (!instance->pictureParam.fSS && prevGNWithHeader <= 0) 
-           )
-      ) 
-   {
-      /* GFID of the next frame can be whatever, since this frame didn't have any GFID's and GFID was supposed to change */
-      instance->gfid = -1; 
-   }
-
-   /* If a fatal error occurred */
-   if (retValue < 0) {
-      /* Return frame buffers for decoded output images,
-         as they are useless for the caller and 
-         as the caller cannot get a handle to return them */
-      if (instance->currFrame)
-         vdeImsPutFree(instance->imageStore, instance->currFrame);
-   }
-
-   return retValue;
-}
-
-
-/* {{-output"vdcDecodePictureHeader.txt"}} */
-/*
- * vdcDecodePictureHeader
- *
- * Parameters:
- *    hInstance                  I: handle of instance data
- *                               (May set instance->errorVar if bit errors.)
- *
- * Function:
- *    
- *
- * Note:
- *    This function does not recover corrupted picture headers (by means of
- *    GFID or redundant picture header copies).
- *
- * Returns:
- *    See above.
- */
-
-int vdcDecodePictureHeader(
-   vdcHInstance_t hInstance,
-   bibBuffer_t *inBuffer,
-   vdxPictureHeader_t *header,
-   vdxSEI_t *sei)
-{
-   int
-      retValue = VDC_OK, 
-      sncCode,
-      numStuffBits,
-      bitErrorIndication = 0;
-
-   int16
-      error = 0;
-
-   u_int32
-      pictureStartPosition;
-
-   vdcInstance_t 
-      *instance = (vdcInstance_t *) hInstance;
-
-   /* The function is implemented by calling stateless Video Demultiplexer
-      (vdx) functions. Consequently, the function does not have sophisticated
-      logic to track illegal/corrupted parameters based on the previous
-      picture header. It cannot recover corrupted picture headers either.
-
-      Alternatively, the function could have been implemented by creating
-      an identical copy of the Video Decoder Core instance and by using
-      "Decode Picture Header" (dph) module functions. However, as there is
-      no instance copying functions implemented, the former alternative
-      was chosen.
-
-      This function was targeted for getting the picture type and 
-      Nokia-proprietary Annex N scalability layer information encapsulated
-      in Supplemental Enhancement Information in an error-free situation.
-      For this purpose, the former and simpler solution is more than 
-      adequate. */
-
-   pictureStartPosition = bibNumberOfFlushedBits(inBuffer);
-   sncCode = sncCheckSync(inBuffer, &numStuffBits, &error);
-
-   /* If sncCheckSync failed */
-   if (error) {
-      deb1p("vdcDecodeFrame: ERROR - sncCheckSync returned %d.\n", error);
-      retValue = VDC_ERR;
-      goto exitFunction;
-   }
-
-   /* Else if EOS was got */
-   else if (sncCode == SNC_EOS) {
-      retValue = VDC_OK_BUT_FRAME_USELESS;
-      goto exitFunction;
-   }
-
-   /* Else if frame starts as expected */
-   else if (sncCode == SNC_PSC) {
-      int
-         picHdrStatus,
-         seiStatus;
-
-      vdxGetPictureHeaderInputParam_t
-         picHdrIn;
-
-      picHdrIn.numStuffBits = numStuffBits;
-      picHdrIn.fCustomPCF = 0;
-      picHdrIn.fScalabilityMode = 0;
-      picHdrIn.fRPS = instance->fRPS;
-      picHdrIn.flushBits = bibFlushBits;
-      picHdrIn.getBits = bibGetBits;
-      picHdrIn.showBits = bibShowBits;
-
-      /* Get picture header */
-      picHdrStatus = vdxGetPictureHeader(
-         inBuffer, 
-         &picHdrIn,
-         header,
-         &bitErrorIndication);
-
-      /* If the header was not successfully retrieved */
-      if (picHdrStatus < 0) {
-         retValue = VDC_ERR;
-         goto exitFunction;
-      }
-      else if (picHdrStatus != VDX_OK) {
-         retValue = VDC_OK_BUT_BIT_ERROR;
-         goto exitFunction;
-      }
-
-      /* Get and decode Supplemental Enhancement Information */
-      seiStatus = vdxGetAndParseSEI(
-         inBuffer,
-         instance->pictureParam.fPLUSPTYPE,
-         instance->numAnnexNScalabilityLayers,
-         sei,
-         &bitErrorIndication);
-
-      /* If error while reading SEI */
-      if (seiStatus < 0) {
-         retValue = VDC_ERR;
-         goto exitFunction;
-      }
-      else if (seiStatus != VDX_OK) {
-         retValue = VDC_OK_BUT_BIT_ERROR;
-         goto exitFunction;
-      }
-   }
-
-   /* Else no valid frame start */
-   else
-      retValue = VDC_OK_BUT_FRAME_USELESS;
-
-   exitFunction:
-
-   /* Reset the bit buffer to its original position */
-   bibRewindBits(
-      bibNumberOfFlushedBits(inBuffer) - pictureStartPosition,
-      inBuffer, &error);
-
-   if (error)
-      retValue = VDC_ERR;
-
-   return retValue;
-}
-
-
-/* {{-output"vdcFree.txt"}} */
-/*
- * vdcFree
- *    
- *
- * Parameters:
- *    None.
- *
- * Function:
- *    This function deinitializes the Video Decoder Core module.
- *    Any functions of this module must not be called after vdcFree (except 
- *    vdcLoad).
- *
- * Returns:
- *    >= 0  if succeeded
- *    < 0   if failed
- *
- *    
- */
-
-int vdcFree(void)
-/* {{-output"vdcFree.txt"}} */
-{
-   if (dblFree() < 0)
-      return VDC_ERR;
-
-   return VDC_OK;
-}
-
-
-/* {{-output"vdcGetImsItem.txt"}} */
-/*
- * vdcGetImsItem
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *    index                      output frame number,
- *                               should be 0 for I and P frames
- *
- * Function:
- *    This function returns a pointer to the requested output frame.
- *
- * Returns:
- *    a pointer to a image store item which corresponds to the passed output
- *    frame index, or
- *    NULL if the function fails
- *
- */
-
-vdeImsItem_t *vdcGetImsItem(vdcHInstance_t hInstance, int index)
-/* {{-output"vdcGetImsItem.txt"}} */
-{
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-   int numOutputFrames = vdcGetNumberOfOutputFrames(hInstance);
-
-   vdcAssert(instance);
-   vdcAssert(index >= 0);
-
-   if (index >= numOutputFrames)
-      return NULL;
-
-   return instance->currFrame;
-}
-
-   
-/* {{-output"vdcGetNumberOfAnnexNScalabilityLayers.txt"}} */
-/*
- * vdcGetNumberOfAnnexNScalabilityLayers
- *
- * Parameters:
- *    hInstance                  I: handle of instance data
- *
- * Function:
- *    Returns the number of Nokia-proprietary Annex N temporal scalability
- *    layers.
- *
- * Returns:
- *    See above.
- */
-
-int vdcGetNumberOfAnnexNScalabilityLayers(
-   vdcHInstance_t hInstance)
-/* {{-output"vdcGetNumberOfAnnexNScalabilityLayers.txt"}} */
-{
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
-   vdcAssert(instance);
-
-   return instance->numAnnexNScalabilityLayers;
-}
-
-
-/* {{-output"vdcGetNumberOfOutputFrames.txt"}} */
-/*
- * vdcGetNumberOfOutputFrames
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *
- * Function:
- *    This function returns the number of output frames which were produced
- *    during the latest vdcDecodeFrame. 
- *
- * Returns:
- *    0 if vdcDecodeFrame failed to produce any output frames
- *    1 for I and P frames
- *
- */
-
-int vdcGetNumberOfOutputFrames(vdcHInstance_t hInstance)
-/* {{-output"vdcGetNumberOfOutputFrames.txt"}} */
-{
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
-   vdcAssert(instance);
-
-   return ((instance->currFrame) ? 1 : 0);
-}
-
-
-/* {{-output"vdcGetTR.txt"}} */
-/*
- * vdcGetTR
- *    
- *
- * Parameters:
- *    inpBuffer                  buffer containing the frame data,
- *                               must start with a PSC
- *    tr                         temporal reference
- *
- * Function:
- *    Gets the temporal reference field from the input buffer.
- *    Notice that the validity of the bitstream is not checked.
- *    This function does not support enhanced temporal reference
- *    (ETR) defined in section 5.1.8 of the H.263 recommendation.
- *
- * Returns:
- *    Nothing
- *
- *    
- */
-
-void vdcGetTR(void *inpBuffer, u_int8 *tr)
-/* {{-output"vdcGetTR.txt"}} */
-{
-   const u_char 
-      *tmpBuffer = (u_char *) inpBuffer;
-
-   *tr = (u_int8) (((tmpBuffer[2] & 2) << 6) | ((tmpBuffer[3] & 252) >> 2));
-}
-
-
-/* {{-output"vdcIsEOSReached.txt"}} */
-/*
- * vdcIsEOSReached
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *
- * Function:
- *    This function returns 1 if the EOS code has been reached during
- *    the decoding. Otherwise, it returns 0.
- *
- * Returns:
- *    See above.
- *
- */
-
-int vdcIsEOSReached(vdcHInstance_t hInstance)
-/* {{-output"vdcIsEOSReached.txt"}} */
-{
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
-   vdcAssert(instance);
-
-   return instance->fEOS;
-}
-
-
-/* {{-output"vdcIsINTRA.txt"}} */
-/*
- * vdcIsINTRA
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *    frameStart                 pointer to memory chunk containing a frame
- *    frameLength                number of bytes in frame
- *
- * Function:
- *    This function returns 1 if the passed frame is an INTRA frame.
- *    Otherwise the function returns 0.
- *
- * Returns:
- *    See above.
- *
- *    
- */
-
-int vdcIsINTRA(
-   vdcHInstance_t hInstance,
-   void *frameStart,
-   unsigned frameLength)
-/* {{-output"vdcIsINTRA.txt"}} */
-{
-   bibBuffer_t *tmpBitBuffer;
-   int fINTRA = 0, bitErrorIndication, syncCode, vdxStatus;
-   int16 error = 0;
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-   vdxGetPictureHeaderInputParam_t vdxIn;
-   vdxPictureHeader_t vdxOut;
-
-   vdcAssert(instance);
-
-   tmpBitBuffer = bibCreate(frameStart, frameLength, &error);
-   if (!tmpBitBuffer || error)
-      return 0;
-
-   syncCode = sncCheckSync(tmpBitBuffer, &(vdxIn.numStuffBits), &error);
-
-   if (syncCode == SNC_PSC && error == 0) {
-
-      /* Note: Needs to be changed when support for custom PCF or scalability mode
-         is added */
-      vdxIn.fCustomPCF = 0; 
-      vdxIn.fScalabilityMode = 0;
-      vdxIn.fRPS = instance->fRPS;
-      vdxIn.flushBits = bibFlushBits;
-      vdxIn.getBits = bibGetBits;
-      vdxIn.showBits = bibShowBits;
-
-      vdxStatus = vdxGetPictureHeader(tmpBitBuffer, &vdxIn, &vdxOut, 
-         &bitErrorIndication);
-
-      if (vdxStatus >= 0 && bitErrorIndication == 0)
-         fINTRA = (vdxOut.pictureType == VDX_PIC_TYPE_I);
-   }
-
-   bibDelete(tmpBitBuffer, &error);
-
-   return fINTRA;
-}
-
-
-/* {{-output"vdcIsINTRAGot.txt"}} */
-/*
- * vdcIsINTRAGot
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *
- * Function:
- *    This function returns 1 if the an INTRA frame has been decoded
- *    during the lifetime of the instance. Otherwise, it returns 0.
- *
- * Returns:
- *    See above.
- *
- *    
- */
-
-int vdcIsINTRAGot(vdcHInstance_t hInstance)
-/* {{-output"vdcIsEOSReached.txt"}} */
-{
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
-   vdcAssert(instance);
-
-   return instance->fIntraGot;
-}
-
-
-/* {{-output"vdcLoad.txt"}} */
-/*
- * vdcLoad
- *    
- *
- * Parameters:
- *    None.
- *
- * Function:
- *    This function initializes the Video Decoder Core module meaning
- *    all the data common to all Video Decoder Core instances.
- *    vdcLoad has to be called before any other function of this module
- *    is used.
- *
- * Returns:
- *    >= 0  if succeeded
- *    < 0   if failed
- *
- *    
- */
-
-int vdcLoad(void)
-/* {{-output"vdcLoad.txt"}} */
-{
-   if (dblLoad() < 0)
-      return VDC_ERR;
-
-   return VDC_OK;
-}
-
-
-/* {{-output"vdcOpen.txt"}} */
-/*
- * vdcOpen
- *    
- *
- * Parameters:
- *    imageStore                 pointer to image store instance
- *    numReferenceFrames         1 if the Reference Picture Selection (RPS)
- *                               mode (Annex N) should not be used,
- *                               >1 tells how many reference images
- *                               are stored in the RPS mode
- *    fudInstance                pointer to Fast Update module instance
- *    hParent                    handle of Video Decoder Engine instance
- *                               that created this VDC instance
- *
- * Function:
- *    This function creates and initializes a new Video Decoder Core instance.
- *
- * Returns:
- *    a handle to the created instance,
- *    or NULL if the function fails
- *
- *    
- */
-
-vdcHInstance_t vdcOpen(
-   vdeIms_t *imageStore, 
-   int numReferenceFrames,
-   void *hParent)
-{
-   vdcInstance_t *instance;
-
-   vdcAssert(numReferenceFrames >= 1);
-
-   instance = (vdcInstance_t *) vdcMalloc(sizeof(vdcInstance_t));
-   if (!instance)
-      return NULL;
-   memset(instance, 0, sizeof(vdcInstance_t));
-
-   instance->prevPicHeader = (vdxPictureHeader_t *)vdcMalloc( sizeof( vdxPictureHeader_t ));
-   if ( instance->prevPicHeader == NULL ) {
-      deb("vdcOpen, MALLOC for prevPicHeader failed.\n");
-      goto errPHOpen;
-   }
-   instance->fPrevPicHeaderReliable = 1;
-
-   instance->imageStore = imageStore;
-
-   instance->numAnnexNScalabilityLayers = -1; /* Indicates no decoded frames */
-
-   instance->fGFIDShouldChange = 0;
-   instance->gfid = -1;
-
-   instance->nOfDecodedFrames = 0;
-
-   instance->hParent = hParent;
-   instance->snapshotStatus = -1;
-
-   return (vdcHInstance_t) instance;
-
-   /* Error cases: release everything in reverse order */
-   errPHOpen:
-
-   vdcDealloc(instance);
-   return NULL;
-}
-/* {{-output"vdcOpen.txt"}} */
-
-
-/* {{-output"vdcRestartVideo.txt"}} */
-/*
- * vdcRestartVideo
- *    
- *
- * Parameters:
- *    hInstance                  handle of instance data
- *
- * Function:
- *    Resets the instance data but does not deallocate the allocated buffers.
- *    After this function vdcDecodeFrame can be called as if no data for this
- *    instance has been decoded.
- *
- * Note:
- *    This function is obsolete and not used anymore. If it is needed again,
- *    it should be re-implemented.
- *
- * Returns:
- *    Nothing
- *
- *    
- */
-
-void vdcRestartVideo(vdcHInstance_t hInstance)
-/* {{-output"vdcRestartVideo.txt"}} */
-{
-   vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
-   if (instance)
-      memset(instance, 0, sizeof(vdcInstance_t));
-}
-
-
-
-
-
-/*
- * Local functions
- */
-
-/*
- * vdcFillCommonPartsOfImb
- *    
- *
- * Parameters:
- *    instance                   instance data
- *    numOfCodedMBs              number of coded macroblocks
- *    imb                        pointer to image buffer to fill
- *
- * Function:
- *    This function fills the passed image buffer according to the latest
- *    decoding results. Only those parts of the image buffer are filled
- *    which can be composed with the presence of another image buffer,
- *    e.g. the P image buffer corresponding to the B image buffer.
- *
- * Returns:
- *    Nothing
- *
- *    
- */
-
-static void vdcFillCommonPartsOfImb(
-   vdcInstance_t *instance, 
-   int numOfCodedMBs,
-   vdeImb_t *imb)
-{
-   vdcAssert(imb);
-   vdcAssert(instance);
-
-   imb->drawItem->param.dwFlags = 0;
-   imb->drawItem->param.lTime = instance->frameNum;
-
-   /* Note: for now, convert whole frame */
-   imb->drawItem->extParam.flags = 0;
-   /* Else one could convert just coded MBs as follows: */
-      /* imb->drawItem->extParam.flags = (fBPart) ? 0 : REN_EXTDRAW_NEW_SOURCE; */
-
-   imb->drawItem->extParam.rate = 30000;
-   imb->drawItem->extParam.scale = 1001;
-   imb->drawItem->extParam.numOfCodedMBs = numOfCodedMBs;
-
-   /* imb->drawItem->retFrame and imb->drawItem->retFrameParam are set by
-      the caller */
-
-   imb->fReferenced = 1;
-   imb->tr = instance->pictureParam.tr;
-}
-
-
-/*
- * vdcFillImageBuffers
- *    
- *
- * Parameters:
- *    instance                   instance data
- *    numOfCodedMBs              number of coded macroblocks
- *    imbP                       pointer to image buffer of P or I frame
- *
- * Function:
- *    This function fills the passed image buffers according to the latest
- *    decoding results.
- *
- * Returns:
- *    >= 0                       if the function was successful
- *    < 0                        if an error occured
- *
- *    
- */
-
-/* Codec and renderer dependent */
-int vdcFillImageBuffers(
-   vdcInstance_t *instance, 
-   int numOfCodedMBs,
-   vdeImb_t *imbP)
-{
-   /* Table to convert from lumiance quantization parameter to chrominance
-      quantization parameter if Modified Quantization (Annex T) is in use. */
-   static const int yToUVQuantizer[32] = 
-      {0,1,2,3,4,5,6,6,7,8,9,9,10,10,11,11,12,
-       12,12,13,13,13,14,14,14,14,14,15,15,15,
-       15,15};
-
-   int
-      firstQPIndex,        /* the index of the first non-zero quantizer */
-
-      *yQuantParams = imbP->yQuantParams,
-                           /* array of Y quantizers in scan-order */
-
-      *uvQuantParams = imbP->uvQuantParams,
-                           /* array of UV quantizers in scan-order */
-
-      numMBsInPicture,     /* number of macroblocks in the image */
-
-      i;                   /* loop variable */
-
-   vdcAssert(imbP);
-   vdcAssert(instance);
-
-   /*
-    * Fill basic stuff
-    */
-
-   vdcFillCommonPartsOfImb(instance, numOfCodedMBs, imbP);
-
-   /*
-    * Calculate quantizer arrays for loop/post-filtering
-    */
-
-   numMBsInPicture = instance->pictureParam.lumMemWidth * 
-      instance->pictureParam.lumMemHeight / 256;
-
-   /* Get the index of the first non-zero quantizer in scan-order */
-   for (firstQPIndex = 0; firstQPIndex < numMBsInPicture; firstQPIndex++) {
-      if (yQuantParams[firstQPIndex] > 0)
-         break;
-   }
-
-   /* Assert that at least one macroblock is decoded successfully */
-   vdcAssert(firstQPIndex < numMBsInPicture);
-
-   /* Replace the first zero quantizers with the first non-zero quantizer
-      (in scan-order) */
-   for (i = 0; i < firstQPIndex; i++)
-      yQuantParams[i] = yQuantParams[firstQPIndex];
-
-   /* Replace all other zero quantizers with the predecessor (in scan-order) */
-   for (i = firstQPIndex; i < numMBsInPicture; i++) {
-      if (yQuantParams[i] == 0)
-         yQuantParams[i] = yQuantParams[i - 1];
-   }
-
-   /* If Modified Quantization is in use */
-   if (instance->pictureParam.fMQ) {
-      /* Convert Y quantizers to UV quantizers */
-      for (i = 0; i < numMBsInPicture; i++)
-         uvQuantParams[i] = yToUVQuantizer[yQuantParams[i]];
-   }
-   else
-      /* Copy Y quantizers to UV quantizers */
-      memcpy(uvQuantParams, yQuantParams, numMBsInPicture * sizeof(int));
-
-
-   return VDC_OK;
-}
-
-// End of File