videoeditorengine/h263decoder/src/core.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * H.263 decoder core functions.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 /* 
       
    22  * Includes 
       
    23  */
       
    24 #include "h263dConfig.h"
       
    25 #include "vdc263.h"
       
    26 #include "core.h"
       
    27 #include "debug.h"
       
    28 #include "decblock.h" /* for dblFree and dblLoad */
       
    29 #include "decgob.h"
       
    30 #include "decpich.h"
       
    31 #include "h263dapi.h" /* for H263D_BC_MUX_MODE_SEPARATE_CHANNEL and H263D_ERD_ */
       
    32 #include "stckheap.h"
       
    33 #include "sync.h"
       
    34 #include "vdeims.h"
       
    35 #include "vdeimb.h"
       
    36 #include "viddemux.h"
       
    37 #include "biblin.h"
       
    38 #include "MPEG4Transcoder.h"
       
    39 
       
    40 
       
    41 /*
       
    42  * Typedefs and structs
       
    43  */
       
    44 
       
    45 /* This structure is used to indicate the expected decoding position. */
       
    46 typedef enum {
       
    47    EDP_START_OF_FRAME,
       
    48    EDP_START_OF_GOB_SEGMENT,
       
    49    EDP_START_OF_SLICE_SEGMENT,
       
    50    EDP_END_OF_FRAME
       
    51 } vdcExpectedDecodingPosition_t;
       
    52 
       
    53 
       
    54 /*
       
    55  * Local function prototypes
       
    56  */ 
       
    57 
       
    58 int vdcFillImageBuffers(
       
    59    vdcInstance_t *instance,
       
    60    int numOfCodedMBs,
       
    61    vdeImb_t *imbP);
       
    62 
       
    63 
       
    64 /*
       
    65  * Global functions
       
    66  */
       
    67 
       
    68 /* {{-output"vdcClose.txt"}} */
       
    69 /*
       
    70  * vdcClose
       
    71  *    
       
    72  *
       
    73  * Parameters:
       
    74  *    hInstance                  handle of instance data
       
    75  *
       
    76  * Function:
       
    77  *    This function closes the instance. The function frees all the resources
       
    78  *    allocated for the instance. The instance handle is no longer valid
       
    79  *    after calling this function.
       
    80  *
       
    81  * Returns:
       
    82  *    >= 0                       if the function was successful
       
    83  *    < 0                        if an error occured
       
    84  *
       
    85  */
       
    86 
       
    87 int vdcClose(vdcHInstance_t hInstance)
       
    88 /* {{-output"vdcClose.txt"}} */
       
    89 {
       
    90    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
    91    int retValue = VDC_OK;
       
    92 
       
    93    if (instance == NULL)
       
    94       return retValue;
       
    95 
       
    96    mvcFree(&instance->mvcData);
       
    97 
       
    98    if ( instance->prevPicHeader != NULL )
       
    99       free( instance->prevPicHeader );
       
   100 
       
   101    aicFree(&instance->aicData);
       
   102 
       
   103               
       
   104    if ( instance->user_data != NULL )
       
   105       free( instance->user_data );
       
   106 
       
   107 
       
   108    vdcDealloc(instance);
       
   109 
       
   110    return retValue;
       
   111 }
       
   112 
       
   113 
       
   114 /* {{-output"vdcDecodeFrame.txt"}} */
       
   115 /*
       
   116  * vdcDecodeFrame
       
   117  *    
       
   118  *
       
   119  * Parameters:
       
   120  *    hInstance                  handle of instance data
       
   121  *
       
   122  *    inBuffer                   pointer to bit buffer, the current position
       
   123  *                               of the buffer must start with a PSC
       
   124  *
       
   125  * Function:
       
   126  *    The vdcDecodeFrame function implements the decoding process described
       
   127  *    in the H.263 recommendation (version 2). However, it does not support
       
   128  *    the following features of the recommendation:
       
   129  *       decoding using the H.261 standard (bit 2 in PTYPE),
       
   130  *       source format changes during a video sequence.
       
   131  *
       
   132  *    The function decodes the next frame in
       
   133  *    the buffer (inBuffer) meaning that the decoding continues until the next
       
   134  *    PSC or EOS is found or until the end of the buffer is not reached.
       
   135  *
       
   136  * Returns:
       
   137  *    VDC_OK                     if the function was succesful
       
   138  *    VDC_OK_BUT_BIT_ERROR       if bit errors were detected but
       
   139  *                               decoded frames are provided by concealing
       
   140  *                               the errors
       
   141  *    VDC_OK_BUT_FRAME_USELESS   if severe bit errors were detected
       
   142  *                               (no concealment was possible) or
       
   143  *                               the bitstream ended unexpectedly
       
   144  *    VDC_ERR                    if a processing error occured,
       
   145  *                               the instance should be closed
       
   146  *
       
   147  */
       
   148 
       
   149 
       
   150 int vdcDecodeFrame(vdcHInstance_t hInstance, bibBuffer_t *inBuffer, bibBuffer_t *outBuffer,
       
   151                    bibBufferEdit_t *bufEdit, int aColorEffect, TBool aGetDecodedFrame,
       
   152                    CMPEG4Transcoder *hTranscoder)
       
   153 
       
   154 /* {{-output"vdcDecodeFrame.txt"}} */
       
   155 {
       
   156    int prevGN = -1;           /* GOB number of the latest decoded GOB */
       
   157    int prevGNWithHeader = -1; /* GOB number of the latest decoded GOB with
       
   158                                  a GOB header */
       
   159 
       
   160    int numStuffBits;          /* Number of stuffing bits before the sync code */
       
   161 
       
   162    int sncCode;               /* the latest synchronization code, see 
       
   163                                  sncCheckSync for the possible values */
       
   164 
       
   165    int rtr = -1;              /* reference tr, 0.. */
       
   166    int trp = -1;              /* tr for prediction, -1 if not indicated in 
       
   167                                  the bitstream */
       
   168 
       
   169    int retValue = VDC_OK;     /* return value of this function */
       
   170 
       
   171 
       
   172    int16 error = 0;           /* Used to pass error codes from the sync module */
       
   173 
       
   174    u_char
       
   175       *currYFrame = NULL,     /* current P frame */
       
   176       *currUFrame = NULL,
       
   177       *currVFrame = NULL,
       
   178       *refYFrame = NULL,      /* reference frame */
       
   179       *refUFrame = NULL,
       
   180       *refVFrame = NULL;
       
   181 
       
   182    u_char *fCodedMBs = NULL;  /* Pointer to table, which indicates coded \
       
   183                                  macroblocks by non-zero value */
       
   184    int numOfCodedMBs = 0;     /* The number of coded macroblocks */
       
   185 
       
   186    int *quantParams = NULL;   /* Pointer to table, in which the quantization
       
   187                                  parameter for each macroblock is stored */
       
   188 
       
   189    int decStatus = 0;         /* Decoding status, returned from decgob.c */
       
   190    int corruptedSegments = 0; /* counter for corrupted segments */
       
   191    int decodedSegments = 0;   /* counter for decoded segments (used in slice mode) */
       
   192    int headerSuccess = 0;     /* success of picture header */
       
   193    int numDecodedMBs = 0;     /* Total number of decoded MBs */
       
   194    int numMBsInFrame = 0;     /* Number of MBs in frame */
       
   195 
       
   196 
       
   197    vdcExpectedDecodingPosition_t expectedDecodingPosition;
       
   198                               /* Tells in which part of the bitstream
       
   199                                  the decoding should be */
       
   200 
       
   201    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
   202                               /* instance data */
       
   203       
       
   204    vdcAssert(instance != NULL);
       
   205 
       
   206    /* Initializations */
       
   207 
       
   208    instance->currFrame = NULL;
       
   209    expectedDecodingPosition = EDP_START_OF_FRAME;
       
   210    instance->pictureParam.prevTR = instance->pictureParam.tr;
       
   211 
       
   212    /* Main loop */
       
   213    for (;;) {
       
   214       int bitErrorIndication = 0;
       
   215 
       
   216       sncCode = sncCheckSync(inBuffer, &numStuffBits, &error);
       
   217 
       
   218       /* If sncCheckSync failed */
       
   219       if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
       
   220          deb1p("vdcDecodeFrame: ERROR - sncCheckSync returned %d.\n", error);
       
   221          retValue = VDC_ERR;
       
   222          goto exitFunction;
       
   223       }
       
   224 
       
   225       /* If EOS was got */
       
   226       if (sncCode == SNC_EOS)
       
   227          instance->fEOS = 1;
       
   228 
       
   229       /* If frame ends appropriately */
       
   230       if (expectedDecodingPosition == EDP_END_OF_FRAME &&
       
   231          (sncCode == SNC_PSC || sncCode == SNC_EOS || 
       
   232           sncCode == SNC_STUFFING || error == ERR_BIB_NOT_ENOUGH_DATA )) {
       
   233          goto exitFunction;
       
   234       }
       
   235 
       
   236       /* Else if frame (or stream) data ends suddenly */
       
   237       else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
       
   238          retValue = VDC_OK_BUT_BIT_ERROR;
       
   239          goto exitFunction;
       
   240       }
       
   241 
       
   242       /* Else if EOS was reached */
       
   243       else if (sncCode == SNC_EOS) {
       
   244          /* The current frame is useless since it ends before it is complete.
       
   245             On the other hand, there is no point in concealing it since
       
   246             it is the last frame of the sequence. */
       
   247          retValue = VDC_OK_BUT_FRAME_USELESS;
       
   248          goto exitFunction;
       
   249       }
       
   250 
       
   251       /* Else if frame starts as expected */
       
   252       else if (expectedDecodingPosition == EDP_START_OF_FRAME &&
       
   253          sncCode == SNC_PSC) {
       
   254 
       
   255          dphInParam_t pichIn;
       
   256          dphInOutParam_t pichInOut;
       
   257          dphOutParam_t pichOut;
       
   258 
       
   259          pichIn.numStuffBits = numStuffBits;
       
   260          pichIn.fNeedDecodedFrame = aGetDecodedFrame | hTranscoder->NeedDecodedYUVFrame();
       
   261 
       
   262          pichIn.fReadBits = 1;
       
   263          pichInOut.vdcInstance = instance;
       
   264          pichInOut.inBuffer = inBuffer;
       
   265 
       
   266          if ( instance->fRPS ) {
       
   267             /* Store the previous TR for VRC needs */
       
   268             if ( instance->nOfDecodedFrames > 0 )
       
   269                trp = instance->pictureParam.tr;
       
   270             else
       
   271                trp = -1;
       
   272          }
       
   273          /* Get picture header */
       
   274          headerSuccess = dphGetPictureHeader(&pichIn, &pichInOut, &pichOut, &bitErrorIndication);
       
   275 
       
   276          if (headerSuccess != DPH_OK) {
       
   277             
       
   278             deb("vdcDecodeFrame: Header decoding unsuccessful due to errors, picture will be discarded.\n");
       
   279             retValue = VDC_OK_BUT_FRAME_USELESS;
       
   280             goto exitFunction;
       
   281          }
       
   282 
       
   283          numMBsInFrame = renDriNumOfMBs(instance->currFrame->imb->drawItem);
       
   284 
       
   285          currYFrame = pichOut.currYFrame;
       
   286          currUFrame = pichOut.currUFrame;
       
   287          currVFrame = pichOut.currVFrame;
       
   288 
       
   289          numOfCodedMBs = 0;
       
   290          fCodedMBs = renDriCodedMBs(instance->currFrame->imb->drawItem);
       
   291          memset(fCodedMBs, 0, numMBsInFrame * sizeof(u_char));
       
   292 
       
   293          /* Initialize quantization parameter array */
       
   294          quantParams = instance->currFrame->imb->yQuantParams;
       
   295          memset(quantParams, 0, numMBsInFrame * sizeof(int));
       
   296 
       
   297          /* If this is the first frame and callback function has been set, report frame size */ 
       
   298          if (instance->nOfDecodedFrames == 0 && instance->reportPictureSizeCallback) {
       
   299             h263dReportPictureSizeCallback_t cb = 
       
   300                (h263dReportPictureSizeCallback_t)instance->reportPictureSizeCallback;
       
   301             cb(instance->hParent, instance->pictureParam.lumWidth, instance->pictureParam.lumHeight);
       
   302          }
       
   303 
       
   304          /* If picture header was ok */
       
   305          if (headerSuccess == DPH_OK)
       
   306          {
       
   307             /* Get and decode Supplemental Enhancement Information */
       
   308             int seiSuccess = dphGetSEI(instance, inBuffer, &bitErrorIndication);
       
   309 
       
   310             /* If fatal error while reading SEI */
       
   311             if (seiSuccess < 0) {
       
   312                retValue = VDC_ERR;
       
   313                deb("vdcDecodeFrame: dphGetSEI failed.\n");
       
   314                goto exitFunction;
       
   315             }
       
   316 
       
   317             /* Else if bit error while reading SEI */
       
   318             else if (seiSuccess == DPH_OK_BUT_BIT_ERROR) {
       
   319                /* We can't trust that the 1st segment can be decoded.
       
   320                   Thus, let's continue with the 2nd segment. */
       
   321                if ( instance->pictureParam.fSS )
       
   322                   expectedDecodingPosition = EDP_START_OF_SLICE_SEGMENT;
       
   323                else
       
   324                   expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
       
   325                sncCode = sncSeekSync(inBuffer, &error);
       
   326                if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
       
   327                   retValue = VDC_ERR;
       
   328                   deb("vdcDecodeFrame: sncSeekSync failed.\n");
       
   329                   goto exitFunction;
       
   330                }
       
   331                continue;
       
   332             }
       
   333 
       
   334 
       
   335          }
       
   336 
       
   337          if ( hTranscoder->H263PictureHeaderEnded(&pichOut, &pichInOut) != VDC_OK )
       
   338             {
       
   339               retValue = VDC_ERR;
       
   340               goto exitFunction;
       
   341             }
       
   342 
       
   343          if (instance->pictureParam.fSS)
       
   344          /* Decode the 1st Slice segment - not supported */
       
   345          {
       
   346              retValue = VDC_OK_BUT_FRAME_USELESS;
       
   347              goto exitFunction;
       
   348          }
       
   349          else
       
   350          /* Decode the 1st GOB segment */
       
   351          {
       
   352             dgobGOBSegmentInParam_t dgobi;
       
   353             dgobGOBSegmentInOutParam_t dgobio;
       
   354 
       
   355             dgobi.numStuffBits = 0;
       
   356             dgobi.pictParam = &instance->pictureParam;
       
   357             dgobi.inBuffer = inBuffer;
       
   358 
       
   359             dgobi.outBuffer = outBuffer;
       
   360             dgobi.bufEdit = bufEdit;
       
   361 
       
   362             dgobi.iColorEffect = aColorEffect; 
       
   363             dgobi.iGetDecodedFrame=aGetDecodedFrame;
       
   364             dgobio.StartByteIndex=0;
       
   365             dgobio.StartBitIndex=7;
       
   366 
       
   367             /* fGFIDShouldChange not relevant here */
       
   368 
       
   369             dgobio.prevGNWithHeader = 0;
       
   370             dgobio.prevGN = 0;
       
   371             /* dgobio.gfid, not relevant here */
       
   372             dgobio.fCodedMBs = fCodedMBs;
       
   373             dgobio.numOfCodedMBs = numOfCodedMBs;
       
   374             dgobio.quantParams = quantParams;
       
   375             dgobio.mvcData = &instance->mvcData;
       
   376             dgobio.imageStore = instance->imageStore;
       
   377             dgobio.trp = pichOut.trp;
       
   378             dgobio.rtr = 0; /* not relevant since no reference frame exists yet */
       
   379             dgobio.refY = refYFrame;
       
   380             dgobio.refU = refUFrame;
       
   381             dgobio.refV = refVFrame;
       
   382             dgobio.currPY = currYFrame;
       
   383             dgobio.currPU = currUFrame;
       
   384             dgobio.currPV = currVFrame;
       
   385 
       
   386             /* the first GOB doesn't have a header */
       
   387             hTranscoder->H263GOBSliceHeaderBegin();
       
   388             hTranscoder->H263GOBSliceHeaderEnded(NULL, NULL);
       
   389 
       
   390             decStatus = dgobGetAndDecodeGOBSegmentContents(&dgobi, 
       
   391                instance->pictureParam.pictureType != VDX_PIC_TYPE_I,
       
   392                pichOut.pquant, &dgobio, hTranscoder);
       
   393 
       
   394             if (decStatus < 0) {
       
   395                retValue = VDC_ERR;
       
   396                goto exitFunction;
       
   397             }
       
   398 
       
   399             hTranscoder->H263OneGOBSliceWithHeaderEnded();
       
   400 
       
   401             prevGNWithHeader = dgobio.prevGNWithHeader;
       
   402             prevGN = dgobio.prevGN;
       
   403             numOfCodedMBs = dgobio.numOfCodedMBs;
       
   404             trp = dgobio.trp;
       
   405             rtr = dgobio.rtr;
       
   406             refYFrame = dgobio.refY;
       
   407             refUFrame = dgobio.refU;
       
   408             refVFrame = dgobio.refV;
       
   409             if (prevGN == instance->pictureParam.numGOBs - 1)
       
   410                expectedDecodingPosition = EDP_END_OF_FRAME;
       
   411             else
       
   412                expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
       
   413          }
       
   414       }
       
   415    
       
   416       /* Else if GOB segment starts as expected */
       
   417       else if (expectedDecodingPosition == EDP_START_OF_GOB_SEGMENT &&
       
   418          sncCode == SNC_GBSC) {
       
   419 
       
   420          dgobGOBSegmentInParam_t dgobi;
       
   421          dgobGOBSegmentInOutParam_t dgobio;
       
   422 
       
   423          dgobi.numStuffBits = numStuffBits;
       
   424          dgobi.pictParam = &instance->pictureParam;
       
   425          dgobi.inBuffer = inBuffer;
       
   426 
       
   427          dgobi.outBuffer = outBuffer;
       
   428          dgobi.bufEdit = bufEdit;
       
   429 
       
   430          dgobi.iColorEffect = aColorEffect; 
       
   431          dgobi.iGetDecodedFrame= aGetDecodedFrame;
       
   432          if(prevGN==-1)
       
   433          {
       
   434              dgobio.StartByteIndex=0;
       
   435              dgobio.StartBitIndex=7;
       
   436          }
       
   437          else
       
   438          {
       
   439              dgobio.StartByteIndex=dgobi.inBuffer->getIndex;
       
   440              dgobio.StartBitIndex=dgobi.inBuffer->bitIndex;
       
   441          }
       
   442 
       
   443 
       
   444          /* fGFIDShouldChange, see below */
       
   445 
       
   446          dgobio.prevGNWithHeader = prevGNWithHeader;
       
   447          dgobio.prevGN = prevGN;
       
   448          /* dgobio.gfid, see below */
       
   449          dgobio.fCodedMBs = fCodedMBs;
       
   450          dgobio.numOfCodedMBs = numOfCodedMBs;
       
   451          dgobio.quantParams = quantParams;
       
   452          dgobio.mvcData = &instance->mvcData;
       
   453          dgobio.imageStore = instance->imageStore;
       
   454          dgobio.trp = trp;
       
   455          dgobio.rtr = rtr;
       
   456          dgobio.refY = refYFrame;
       
   457          dgobio.refU = refUFrame;
       
   458          dgobio.refV = refVFrame;
       
   459          dgobio.currPY = currYFrame;
       
   460          dgobio.currPU = currUFrame;
       
   461          dgobio.currPV = currVFrame;
       
   462 
       
   463          dgobi.fGFIDShouldChange = instance->fGFIDShouldChange;
       
   464          dgobio.gfid = instance->gfid;
       
   465 
       
   466          /* Get and decode GOB segment */
       
   467          decStatus = dgobGetAndDecodeGOBSegment(&dgobi, &dgobio, hTranscoder);
       
   468 
       
   469          if (decStatus == DGOB_ERR) {
       
   470             retValue = VDC_ERR;
       
   471             goto exitFunction;
       
   472          }
       
   473          if ( instance->fGFIDShouldChange ) {
       
   474             instance->gfid = dgobio.gfid;
       
   475             instance->fGFIDShouldChange = 0;
       
   476          }
       
   477 
       
   478          prevGNWithHeader = dgobio.prevGNWithHeader;
       
   479          prevGN = dgobio.prevGN;
       
   480          numOfCodedMBs = dgobio.numOfCodedMBs;
       
   481          trp = dgobio.trp;
       
   482 
       
   483 
       
   484          rtr = dgobio.rtr;
       
   485 
       
   486          refYFrame = dgobio.refY;
       
   487          refUFrame = dgobio.refU;
       
   488          refVFrame = dgobio.refV;
       
   489 
       
   490          if (prevGN == instance->pictureParam.numGOBs - 1)
       
   491             expectedDecodingPosition = EDP_END_OF_FRAME;
       
   492          else
       
   493             expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
       
   494       }
       
   495 
       
   496       /* Else if Slice segment starts as expected */
       
   497       else if (expectedDecodingPosition == EDP_START_OF_SLICE_SEGMENT &&
       
   498          sncCode == SNC_GBSC) {
       
   499          /* slides not supported */
       
   500          retValue = VDC_OK_BUT_FRAME_USELESS;
       
   501          goto exitFunction;
       
   502 
       
   503       }
       
   504 
       
   505       /* Else decoding is out of sync */
       
   506       else {
       
   507          switch (expectedDecodingPosition) {
       
   508 
       
   509             case EDP_START_OF_FRAME:
       
   510                /* No PSC */
       
   511                /* Check if GFID could be used to recover the picture header */
       
   512                {
       
   513                   dphInParam_t pichIn;
       
   514                   dphInOutParam_t pichInOut;
       
   515                   dphOutParam_t pichOut;
       
   516 
       
   517                   pichIn.numStuffBits = numStuffBits;
       
   518                   pichIn.fReadBits = 0;
       
   519 
       
   520                   pichInOut.vdcInstance = instance;
       
   521                   pichInOut.inBuffer = inBuffer;
       
   522 
       
   523                   headerSuccess = dphGetPictureHeader(&pichIn, &pichInOut, &pichOut, &bitErrorIndication);
       
   524                   if ( headerSuccess == DPH_OK) {
       
   525                      /* Header recovery was successful, start decoding from the next GOB available */
       
   526                      if ( instance->pictureParam.fSS ) {
       
   527                         expectedDecodingPosition = EDP_START_OF_SLICE_SEGMENT;
       
   528                         /* decSlice does not increment these */
       
   529                         decodedSegments++;
       
   530                         corruptedSegments++;
       
   531                      }
       
   532                      else
       
   533                         expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
       
   534                      deb1p("vdcDecodeFrame: Header successfully recovered after PSC loss. FrameNum %d\n",instance->frameNum);
       
   535                      currYFrame = pichOut.currYFrame;
       
   536                      currUFrame = pichOut.currUFrame;
       
   537                      currVFrame = pichOut.currVFrame;
       
   538                      numMBsInFrame = renDriNumOfMBs(instance->currFrame->imb->drawItem);
       
   539                      numOfCodedMBs = 0;
       
   540                      numDecodedMBs = 0;
       
   541                      fCodedMBs = renDriCodedMBs(instance->currFrame->imb->drawItem);
       
   542                      memset(fCodedMBs, 0, numMBsInFrame * sizeof(u_char));
       
   543 
       
   544                      /* Initialize quantization parameter array */
       
   545                      quantParams = instance->currFrame->imb->yQuantParams;
       
   546                      memset(quantParams, 0, numMBsInFrame * sizeof(int));
       
   547 
       
   548                      /* If this is the first frame and callback function has been set, report frame size */ 
       
   549                      if (instance->nOfDecodedFrames == 0 && instance->reportPictureSizeCallback) {
       
   550                         h263dReportPictureSizeCallback_t cb = 
       
   551                            (h263dReportPictureSizeCallback_t)instance->reportPictureSizeCallback;
       
   552                         cb(instance->hParent, instance->pictureParam.lumWidth, instance->pictureParam.lumHeight);
       
   553                      }
       
   554 
       
   555                      continue;
       
   556                   }
       
   557                   else {
       
   558                      retValue = VDC_OK_BUT_FRAME_USELESS;
       
   559                      deb1p("vdcDecodeFrame: Header recovery unsuccessful after PSC loss. FrameNum %d\n",instance->frameNum);
       
   560                      goto exitFunction;
       
   561                   }
       
   562                }
       
   563             case EDP_START_OF_GOB_SEGMENT:
       
   564                if ( sncCode == SNC_PSC ) {
       
   565                   retValue = VDC_OK_BUT_BIT_ERROR;
       
   566                   goto exitFunction;
       
   567                }
       
   568                else {
       
   569                   /* 
       
   570                    * Picture header recovery used next picture header 
       
   571                    * => we are not at the position of GBSC => search the next one 
       
   572                    * This is caused by a erdRestorePictureHeader that does not synchronize 
       
   573                    * bit buffer to GOB headers that have bitErrorIndication != 0.
       
   574                    * This may be considered as a , and it might be good to change it later on.
       
   575                    * This seeking should solve the problem, although maybe not in the most elegant way
       
   576                    */
       
   577                   sncSeekSync( inBuffer, &error );
       
   578                   continue;
       
   579                }
       
   580            default :
       
   581             {
       
   582             
       
   583                 retValue = VDC_OK_BUT_FRAME_USELESS;
       
   584                  goto exitFunction;
       
   585             }
       
   586 
       
   587          }
       
   588       }
       
   589    }
       
   590 
       
   591    exitFunction:
       
   592 
       
   593 
       
   594    /* If frame(s) not useless */
       
   595    if (retValue == VDC_OK || retValue == VDC_OK_BUT_BIT_ERROR) {
       
   596 
       
   597       if (!corruptedSegments && (numDecodedMBs > 0 || prevGN > 0 || instance->pictureParam.numGOBs == 1))
       
   598          retValue = VDC_OK;
       
   599       else {
       
   600          retValue = VDC_OK_BUT_FRAME_USELESS;
       
   601          deb1p("vdcDecodeFrame: Frame useless, too many corrupted segments. FrameNum %d\n",instance->frameNum);
       
   602       }
       
   603    }
       
   604 
       
   605    /* If decoding ok and frame not useless */
       
   606    if ( retValue == VDC_OK || retValue == VDC_OK_BUT_BIT_ERROR ) {
       
   607 
       
   608 
       
   609        /* stuff bits here 'END OF FRAME' -->*/
       
   610          bibStuffBits(outBuffer); 
       
   611        /* <-- */
       
   612 
       
   613       if ( instance->nOfDecodedFrames < 0xffffffff )
       
   614          instance->nOfDecodedFrames++;
       
   615 
       
   616       if (vdcFillImageBuffers(
       
   617          instance, 
       
   618          numOfCodedMBs, 
       
   619          instance->currFrame->imb) < 0)
       
   620          retValue = VDC_ERR;
       
   621 
       
   622 
       
   623 
       
   624    }
       
   625    if ( retValue == VDC_OK_BUT_FRAME_USELESS ) {
       
   626       /* GFID of the next frame can be whatever, since this frame was useless */
       
   627       instance->gfid = -1; 
       
   628    }
       
   629    if ( instance->fGFIDShouldChange
       
   630         && (    (instance->pictureParam.fSS && decodedSegments == 1) 
       
   631              || (!instance->pictureParam.fSS && prevGNWithHeader <= 0) 
       
   632            )
       
   633       ) 
       
   634    {
       
   635       /* GFID of the next frame can be whatever, since this frame didn't have any GFID's and GFID was supposed to change */
       
   636       instance->gfid = -1; 
       
   637    }
       
   638 
       
   639    /* If a fatal error occurred */
       
   640    if (retValue < 0) {
       
   641       /* Return frame buffers for decoded output images,
       
   642          as they are useless for the caller and 
       
   643          as the caller cannot get a handle to return them */
       
   644       if (instance->currFrame)
       
   645          vdeImsPutFree(instance->imageStore, instance->currFrame);
       
   646    }
       
   647 
       
   648    return retValue;
       
   649 }
       
   650 
       
   651 
       
   652 /* {{-output"vdcDecodePictureHeader.txt"}} */
       
   653 /*
       
   654  * vdcDecodePictureHeader
       
   655  *
       
   656  * Parameters:
       
   657  *    hInstance                  I: handle of instance data
       
   658  *                               (May set instance->errorVar if bit errors.)
       
   659  *
       
   660  * Function:
       
   661  *    
       
   662  *
       
   663  * Note:
       
   664  *    This function does not recover corrupted picture headers (by means of
       
   665  *    GFID or redundant picture header copies).
       
   666  *
       
   667  * Returns:
       
   668  *    See above.
       
   669  */
       
   670 
       
   671 int vdcDecodePictureHeader(
       
   672    vdcHInstance_t hInstance,
       
   673    bibBuffer_t *inBuffer,
       
   674    vdxPictureHeader_t *header,
       
   675    vdxSEI_t *sei)
       
   676 {
       
   677    int
       
   678       retValue = VDC_OK, 
       
   679       sncCode,
       
   680       numStuffBits,
       
   681       bitErrorIndication = 0;
       
   682 
       
   683    int16
       
   684       error = 0;
       
   685 
       
   686    u_int32
       
   687       pictureStartPosition;
       
   688 
       
   689    vdcInstance_t 
       
   690       *instance = (vdcInstance_t *) hInstance;
       
   691 
       
   692    /* The function is implemented by calling stateless Video Demultiplexer
       
   693       (vdx) functions. Consequently, the function does not have sophisticated
       
   694       logic to track illegal/corrupted parameters based on the previous
       
   695       picture header. It cannot recover corrupted picture headers either.
       
   696 
       
   697       Alternatively, the function could have been implemented by creating
       
   698       an identical copy of the Video Decoder Core instance and by using
       
   699       "Decode Picture Header" (dph) module functions. However, as there is
       
   700       no instance copying functions implemented, the former alternative
       
   701       was chosen.
       
   702 
       
   703       This function was targeted for getting the picture type and 
       
   704       Nokia-proprietary Annex N scalability layer information encapsulated
       
   705       in Supplemental Enhancement Information in an error-free situation.
       
   706       For this purpose, the former and simpler solution is more than 
       
   707       adequate. */
       
   708 
       
   709    pictureStartPosition = bibNumberOfFlushedBits(inBuffer);
       
   710    sncCode = sncCheckSync(inBuffer, &numStuffBits, &error);
       
   711 
       
   712    /* If sncCheckSync failed */
       
   713    if (error) {
       
   714       deb1p("vdcDecodeFrame: ERROR - sncCheckSync returned %d.\n", error);
       
   715       retValue = VDC_ERR;
       
   716       goto exitFunction;
       
   717    }
       
   718 
       
   719    /* Else if EOS was got */
       
   720    else if (sncCode == SNC_EOS) {
       
   721       retValue = VDC_OK_BUT_FRAME_USELESS;
       
   722       goto exitFunction;
       
   723    }
       
   724 
       
   725    /* Else if frame starts as expected */
       
   726    else if (sncCode == SNC_PSC) {
       
   727       int
       
   728          picHdrStatus,
       
   729          seiStatus;
       
   730 
       
   731       vdxGetPictureHeaderInputParam_t
       
   732          picHdrIn;
       
   733 
       
   734       picHdrIn.numStuffBits = numStuffBits;
       
   735       picHdrIn.fCustomPCF = 0;
       
   736       picHdrIn.fScalabilityMode = 0;
       
   737       picHdrIn.fRPS = instance->fRPS;
       
   738       picHdrIn.flushBits = bibFlushBits;
       
   739       picHdrIn.getBits = bibGetBits;
       
   740       picHdrIn.showBits = bibShowBits;
       
   741 
       
   742       /* Get picture header */
       
   743       picHdrStatus = vdxGetPictureHeader(
       
   744          inBuffer, 
       
   745          &picHdrIn,
       
   746          header,
       
   747          &bitErrorIndication);
       
   748 
       
   749       /* If the header was not successfully retrieved */
       
   750       if (picHdrStatus < 0) {
       
   751          retValue = VDC_ERR;
       
   752          goto exitFunction;
       
   753       }
       
   754       else if (picHdrStatus != VDX_OK) {
       
   755          retValue = VDC_OK_BUT_BIT_ERROR;
       
   756          goto exitFunction;
       
   757       }
       
   758 
       
   759       /* Get and decode Supplemental Enhancement Information */
       
   760       seiStatus = vdxGetAndParseSEI(
       
   761          inBuffer,
       
   762          instance->pictureParam.fPLUSPTYPE,
       
   763          instance->numAnnexNScalabilityLayers,
       
   764          sei,
       
   765          &bitErrorIndication);
       
   766 
       
   767       /* If error while reading SEI */
       
   768       if (seiStatus < 0) {
       
   769          retValue = VDC_ERR;
       
   770          goto exitFunction;
       
   771       }
       
   772       else if (seiStatus != VDX_OK) {
       
   773          retValue = VDC_OK_BUT_BIT_ERROR;
       
   774          goto exitFunction;
       
   775       }
       
   776    }
       
   777 
       
   778    /* Else no valid frame start */
       
   779    else
       
   780       retValue = VDC_OK_BUT_FRAME_USELESS;
       
   781 
       
   782    exitFunction:
       
   783 
       
   784    /* Reset the bit buffer to its original position */
       
   785    bibRewindBits(
       
   786       bibNumberOfFlushedBits(inBuffer) - pictureStartPosition,
       
   787       inBuffer, &error);
       
   788 
       
   789    if (error)
       
   790       retValue = VDC_ERR;
       
   791 
       
   792    return retValue;
       
   793 }
       
   794 
       
   795 
       
   796 /* {{-output"vdcFree.txt"}} */
       
   797 /*
       
   798  * vdcFree
       
   799  *    
       
   800  *
       
   801  * Parameters:
       
   802  *    None.
       
   803  *
       
   804  * Function:
       
   805  *    This function deinitializes the Video Decoder Core module.
       
   806  *    Any functions of this module must not be called after vdcFree (except 
       
   807  *    vdcLoad).
       
   808  *
       
   809  * Returns:
       
   810  *    >= 0  if succeeded
       
   811  *    < 0   if failed
       
   812  *
       
   813  *    
       
   814  */
       
   815 
       
   816 int vdcFree(void)
       
   817 /* {{-output"vdcFree.txt"}} */
       
   818 {
       
   819    if (dblFree() < 0)
       
   820       return VDC_ERR;
       
   821 
       
   822    return VDC_OK;
       
   823 }
       
   824 
       
   825 
       
   826 /* {{-output"vdcGetImsItem.txt"}} */
       
   827 /*
       
   828  * vdcGetImsItem
       
   829  *    
       
   830  *
       
   831  * Parameters:
       
   832  *    hInstance                  handle of instance data
       
   833  *    index                      output frame number,
       
   834  *                               should be 0 for I and P frames
       
   835  *
       
   836  * Function:
       
   837  *    This function returns a pointer to the requested output frame.
       
   838  *
       
   839  * Returns:
       
   840  *    a pointer to a image store item which corresponds to the passed output
       
   841  *    frame index, or
       
   842  *    NULL if the function fails
       
   843  *
       
   844  */
       
   845 
       
   846 vdeImsItem_t *vdcGetImsItem(vdcHInstance_t hInstance, int index)
       
   847 /* {{-output"vdcGetImsItem.txt"}} */
       
   848 {
       
   849    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
   850    int numOutputFrames = vdcGetNumberOfOutputFrames(hInstance);
       
   851 
       
   852    vdcAssert(instance);
       
   853    vdcAssert(index >= 0);
       
   854 
       
   855    if (index >= numOutputFrames)
       
   856       return NULL;
       
   857 
       
   858    return instance->currFrame;
       
   859 }
       
   860 
       
   861    
       
   862 /* {{-output"vdcGetNumberOfAnnexNScalabilityLayers.txt"}} */
       
   863 /*
       
   864  * vdcGetNumberOfAnnexNScalabilityLayers
       
   865  *
       
   866  * Parameters:
       
   867  *    hInstance                  I: handle of instance data
       
   868  *
       
   869  * Function:
       
   870  *    Returns the number of Nokia-proprietary Annex N temporal scalability
       
   871  *    layers.
       
   872  *
       
   873  * Returns:
       
   874  *    See above.
       
   875  */
       
   876 
       
   877 int vdcGetNumberOfAnnexNScalabilityLayers(
       
   878    vdcHInstance_t hInstance)
       
   879 /* {{-output"vdcGetNumberOfAnnexNScalabilityLayers.txt"}} */
       
   880 {
       
   881    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
   882 
       
   883    vdcAssert(instance);
       
   884 
       
   885    return instance->numAnnexNScalabilityLayers;
       
   886 }
       
   887 
       
   888 
       
   889 /* {{-output"vdcGetNumberOfOutputFrames.txt"}} */
       
   890 /*
       
   891  * vdcGetNumberOfOutputFrames
       
   892  *    
       
   893  *
       
   894  * Parameters:
       
   895  *    hInstance                  handle of instance data
       
   896  *
       
   897  * Function:
       
   898  *    This function returns the number of output frames which were produced
       
   899  *    during the latest vdcDecodeFrame. 
       
   900  *
       
   901  * Returns:
       
   902  *    0 if vdcDecodeFrame failed to produce any output frames
       
   903  *    1 for I and P frames
       
   904  *
       
   905  */
       
   906 
       
   907 int vdcGetNumberOfOutputFrames(vdcHInstance_t hInstance)
       
   908 /* {{-output"vdcGetNumberOfOutputFrames.txt"}} */
       
   909 {
       
   910    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
   911 
       
   912    vdcAssert(instance);
       
   913 
       
   914    return ((instance->currFrame) ? 1 : 0);
       
   915 }
       
   916 
       
   917 
       
   918 /* {{-output"vdcGetTR.txt"}} */
       
   919 /*
       
   920  * vdcGetTR
       
   921  *    
       
   922  *
       
   923  * Parameters:
       
   924  *    inpBuffer                  buffer containing the frame data,
       
   925  *                               must start with a PSC
       
   926  *    tr                         temporal reference
       
   927  *
       
   928  * Function:
       
   929  *    Gets the temporal reference field from the input buffer.
       
   930  *    Notice that the validity of the bitstream is not checked.
       
   931  *    This function does not support enhanced temporal reference
       
   932  *    (ETR) defined in section 5.1.8 of the H.263 recommendation.
       
   933  *
       
   934  * Returns:
       
   935  *    Nothing
       
   936  *
       
   937  *    
       
   938  */
       
   939 
       
   940 void vdcGetTR(void *inpBuffer, u_int8 *tr)
       
   941 /* {{-output"vdcGetTR.txt"}} */
       
   942 {
       
   943    const u_char 
       
   944       *tmpBuffer = (u_char *) inpBuffer;
       
   945 
       
   946    *tr = (u_int8) (((tmpBuffer[2] & 2) << 6) | ((tmpBuffer[3] & 252) >> 2));
       
   947 }
       
   948 
       
   949 
       
   950 /* {{-output"vdcIsEOSReached.txt"}} */
       
   951 /*
       
   952  * vdcIsEOSReached
       
   953  *    
       
   954  *
       
   955  * Parameters:
       
   956  *    hInstance                  handle of instance data
       
   957  *
       
   958  * Function:
       
   959  *    This function returns 1 if the EOS code has been reached during
       
   960  *    the decoding. Otherwise, it returns 0.
       
   961  *
       
   962  * Returns:
       
   963  *    See above.
       
   964  *
       
   965  */
       
   966 
       
   967 int vdcIsEOSReached(vdcHInstance_t hInstance)
       
   968 /* {{-output"vdcIsEOSReached.txt"}} */
       
   969 {
       
   970    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
   971 
       
   972    vdcAssert(instance);
       
   973 
       
   974    return instance->fEOS;
       
   975 }
       
   976 
       
   977 
       
   978 /* {{-output"vdcIsINTRA.txt"}} */
       
   979 /*
       
   980  * vdcIsINTRA
       
   981  *    
       
   982  *
       
   983  * Parameters:
       
   984  *    hInstance                  handle of instance data
       
   985  *    frameStart                 pointer to memory chunk containing a frame
       
   986  *    frameLength                number of bytes in frame
       
   987  *
       
   988  * Function:
       
   989  *    This function returns 1 if the passed frame is an INTRA frame.
       
   990  *    Otherwise the function returns 0.
       
   991  *
       
   992  * Returns:
       
   993  *    See above.
       
   994  *
       
   995  *    
       
   996  */
       
   997 
       
   998 int vdcIsINTRA(
       
   999    vdcHInstance_t hInstance,
       
  1000    void *frameStart,
       
  1001    unsigned frameLength)
       
  1002 /* {{-output"vdcIsINTRA.txt"}} */
       
  1003 {
       
  1004    bibBuffer_t *tmpBitBuffer;
       
  1005    int fINTRA = 0, bitErrorIndication, syncCode, vdxStatus;
       
  1006    int16 error = 0;
       
  1007    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
  1008    vdxGetPictureHeaderInputParam_t vdxIn;
       
  1009    vdxPictureHeader_t vdxOut;
       
  1010 
       
  1011    vdcAssert(instance);
       
  1012 
       
  1013    tmpBitBuffer = bibCreate(frameStart, frameLength, &error);
       
  1014    if (!tmpBitBuffer || error)
       
  1015       return 0;
       
  1016 
       
  1017    syncCode = sncCheckSync(tmpBitBuffer, &(vdxIn.numStuffBits), &error);
       
  1018 
       
  1019    if (syncCode == SNC_PSC && error == 0) {
       
  1020 
       
  1021       /* Note: Needs to be changed when support for custom PCF or scalability mode
       
  1022          is added */
       
  1023       vdxIn.fCustomPCF = 0; 
       
  1024       vdxIn.fScalabilityMode = 0;
       
  1025       vdxIn.fRPS = instance->fRPS;
       
  1026       vdxIn.flushBits = bibFlushBits;
       
  1027       vdxIn.getBits = bibGetBits;
       
  1028       vdxIn.showBits = bibShowBits;
       
  1029 
       
  1030       vdxStatus = vdxGetPictureHeader(tmpBitBuffer, &vdxIn, &vdxOut, 
       
  1031          &bitErrorIndication);
       
  1032 
       
  1033       if (vdxStatus >= 0 && bitErrorIndication == 0)
       
  1034          fINTRA = (vdxOut.pictureType == VDX_PIC_TYPE_I);
       
  1035    }
       
  1036 
       
  1037    bibDelete(tmpBitBuffer, &error);
       
  1038 
       
  1039    return fINTRA;
       
  1040 }
       
  1041 
       
  1042 
       
  1043 /* {{-output"vdcIsINTRAGot.txt"}} */
       
  1044 /*
       
  1045  * vdcIsINTRAGot
       
  1046  *    
       
  1047  *
       
  1048  * Parameters:
       
  1049  *    hInstance                  handle of instance data
       
  1050  *
       
  1051  * Function:
       
  1052  *    This function returns 1 if the an INTRA frame has been decoded
       
  1053  *    during the lifetime of the instance. Otherwise, it returns 0.
       
  1054  *
       
  1055  * Returns:
       
  1056  *    See above.
       
  1057  *
       
  1058  *    
       
  1059  */
       
  1060 
       
  1061 int vdcIsINTRAGot(vdcHInstance_t hInstance)
       
  1062 /* {{-output"vdcIsEOSReached.txt"}} */
       
  1063 {
       
  1064    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
  1065 
       
  1066    vdcAssert(instance);
       
  1067 
       
  1068    return instance->fIntraGot;
       
  1069 }
       
  1070 
       
  1071 
       
  1072 /* {{-output"vdcLoad.txt"}} */
       
  1073 /*
       
  1074  * vdcLoad
       
  1075  *    
       
  1076  *
       
  1077  * Parameters:
       
  1078  *    None.
       
  1079  *
       
  1080  * Function:
       
  1081  *    This function initializes the Video Decoder Core module meaning
       
  1082  *    all the data common to all Video Decoder Core instances.
       
  1083  *    vdcLoad has to be called before any other function of this module
       
  1084  *    is used.
       
  1085  *
       
  1086  * Returns:
       
  1087  *    >= 0  if succeeded
       
  1088  *    < 0   if failed
       
  1089  *
       
  1090  *    
       
  1091  */
       
  1092 
       
  1093 int vdcLoad(void)
       
  1094 /* {{-output"vdcLoad.txt"}} */
       
  1095 {
       
  1096    if (dblLoad() < 0)
       
  1097       return VDC_ERR;
       
  1098 
       
  1099    return VDC_OK;
       
  1100 }
       
  1101 
       
  1102 
       
  1103 /* {{-output"vdcOpen.txt"}} */
       
  1104 /*
       
  1105  * vdcOpen
       
  1106  *    
       
  1107  *
       
  1108  * Parameters:
       
  1109  *    imageStore                 pointer to image store instance
       
  1110  *    numReferenceFrames         1 if the Reference Picture Selection (RPS)
       
  1111  *                               mode (Annex N) should not be used,
       
  1112  *                               >1 tells how many reference images
       
  1113  *                               are stored in the RPS mode
       
  1114  *    fudInstance                pointer to Fast Update module instance
       
  1115  *    hParent                    handle of Video Decoder Engine instance
       
  1116  *                               that created this VDC instance
       
  1117  *
       
  1118  * Function:
       
  1119  *    This function creates and initializes a new Video Decoder Core instance.
       
  1120  *
       
  1121  * Returns:
       
  1122  *    a handle to the created instance,
       
  1123  *    or NULL if the function fails
       
  1124  *
       
  1125  *    
       
  1126  */
       
  1127 
       
  1128 vdcHInstance_t vdcOpen(
       
  1129    vdeIms_t *imageStore, 
       
  1130    int numReferenceFrames,
       
  1131    void *hParent)
       
  1132 {
       
  1133    vdcInstance_t *instance;
       
  1134 
       
  1135    vdcAssert(numReferenceFrames >= 1);
       
  1136 
       
  1137    instance = (vdcInstance_t *) vdcMalloc(sizeof(vdcInstance_t));
       
  1138    if (!instance)
       
  1139       return NULL;
       
  1140    memset(instance, 0, sizeof(vdcInstance_t));
       
  1141 
       
  1142    instance->prevPicHeader = (vdxPictureHeader_t *)vdcMalloc( sizeof( vdxPictureHeader_t ));
       
  1143    if ( instance->prevPicHeader == NULL ) {
       
  1144       deb("vdcOpen, MALLOC for prevPicHeader failed.\n");
       
  1145       goto errPHOpen;
       
  1146    }
       
  1147    instance->fPrevPicHeaderReliable = 1;
       
  1148 
       
  1149    instance->imageStore = imageStore;
       
  1150 
       
  1151    instance->numAnnexNScalabilityLayers = -1; /* Indicates no decoded frames */
       
  1152 
       
  1153    instance->fGFIDShouldChange = 0;
       
  1154    instance->gfid = -1;
       
  1155 
       
  1156    instance->nOfDecodedFrames = 0;
       
  1157 
       
  1158    instance->hParent = hParent;
       
  1159    instance->snapshotStatus = -1;
       
  1160 
       
  1161    return (vdcHInstance_t) instance;
       
  1162 
       
  1163    /* Error cases: release everything in reverse order */
       
  1164    errPHOpen:
       
  1165 
       
  1166    vdcDealloc(instance);
       
  1167    return NULL;
       
  1168 }
       
  1169 /* {{-output"vdcOpen.txt"}} */
       
  1170 
       
  1171 
       
  1172 /* {{-output"vdcRestartVideo.txt"}} */
       
  1173 /*
       
  1174  * vdcRestartVideo
       
  1175  *    
       
  1176  *
       
  1177  * Parameters:
       
  1178  *    hInstance                  handle of instance data
       
  1179  *
       
  1180  * Function:
       
  1181  *    Resets the instance data but does not deallocate the allocated buffers.
       
  1182  *    After this function vdcDecodeFrame can be called as if no data for this
       
  1183  *    instance has been decoded.
       
  1184  *
       
  1185  * Note:
       
  1186  *    This function is obsolete and not used anymore. If it is needed again,
       
  1187  *    it should be re-implemented.
       
  1188  *
       
  1189  * Returns:
       
  1190  *    Nothing
       
  1191  *
       
  1192  *    
       
  1193  */
       
  1194 
       
  1195 void vdcRestartVideo(vdcHInstance_t hInstance)
       
  1196 /* {{-output"vdcRestartVideo.txt"}} */
       
  1197 {
       
  1198    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
  1199 
       
  1200    if (instance)
       
  1201       memset(instance, 0, sizeof(vdcInstance_t));
       
  1202 }
       
  1203 
       
  1204 
       
  1205 
       
  1206 
       
  1207 
       
  1208 /*
       
  1209  * Local functions
       
  1210  */
       
  1211 
       
  1212 /*
       
  1213  * vdcFillCommonPartsOfImb
       
  1214  *    
       
  1215  *
       
  1216  * Parameters:
       
  1217  *    instance                   instance data
       
  1218  *    numOfCodedMBs              number of coded macroblocks
       
  1219  *    imb                        pointer to image buffer to fill
       
  1220  *
       
  1221  * Function:
       
  1222  *    This function fills the passed image buffer according to the latest
       
  1223  *    decoding results. Only those parts of the image buffer are filled
       
  1224  *    which can be composed with the presence of another image buffer,
       
  1225  *    e.g. the P image buffer corresponding to the B image buffer.
       
  1226  *
       
  1227  * Returns:
       
  1228  *    Nothing
       
  1229  *
       
  1230  *    
       
  1231  */
       
  1232 
       
  1233 static void vdcFillCommonPartsOfImb(
       
  1234    vdcInstance_t *instance, 
       
  1235    int numOfCodedMBs,
       
  1236    vdeImb_t *imb)
       
  1237 {
       
  1238    vdcAssert(imb);
       
  1239    vdcAssert(instance);
       
  1240 
       
  1241    imb->drawItem->param.dwFlags = 0;
       
  1242    imb->drawItem->param.lTime = instance->frameNum;
       
  1243 
       
  1244    /* Note: for now, convert whole frame */
       
  1245    imb->drawItem->extParam.flags = 0;
       
  1246    /* Else one could convert just coded MBs as follows: */
       
  1247       /* imb->drawItem->extParam.flags = (fBPart) ? 0 : REN_EXTDRAW_NEW_SOURCE; */
       
  1248 
       
  1249    imb->drawItem->extParam.rate = 30000;
       
  1250    imb->drawItem->extParam.scale = 1001;
       
  1251    imb->drawItem->extParam.numOfCodedMBs = numOfCodedMBs;
       
  1252 
       
  1253    /* imb->drawItem->retFrame and imb->drawItem->retFrameParam are set by
       
  1254       the caller */
       
  1255 
       
  1256    imb->fReferenced = 1;
       
  1257    imb->tr = instance->pictureParam.tr;
       
  1258 }
       
  1259 
       
  1260 
       
  1261 /*
       
  1262  * vdcFillImageBuffers
       
  1263  *    
       
  1264  *
       
  1265  * Parameters:
       
  1266  *    instance                   instance data
       
  1267  *    numOfCodedMBs              number of coded macroblocks
       
  1268  *    imbP                       pointer to image buffer of P or I frame
       
  1269  *
       
  1270  * Function:
       
  1271  *    This function fills the passed image buffers according to the latest
       
  1272  *    decoding results.
       
  1273  *
       
  1274  * Returns:
       
  1275  *    >= 0                       if the function was successful
       
  1276  *    < 0                        if an error occured
       
  1277  *
       
  1278  *    
       
  1279  */
       
  1280 
       
  1281 /* Codec and renderer dependent */
       
  1282 int vdcFillImageBuffers(
       
  1283    vdcInstance_t *instance, 
       
  1284    int numOfCodedMBs,
       
  1285    vdeImb_t *imbP)
       
  1286 {
       
  1287    /* Table to convert from lumiance quantization parameter to chrominance
       
  1288       quantization parameter if Modified Quantization (Annex T) is in use. */
       
  1289    static const int yToUVQuantizer[32] = 
       
  1290       {0,1,2,3,4,5,6,6,7,8,9,9,10,10,11,11,12,
       
  1291        12,12,13,13,13,14,14,14,14,14,15,15,15,
       
  1292        15,15};
       
  1293 
       
  1294    int
       
  1295       firstQPIndex,        /* the index of the first non-zero quantizer */
       
  1296 
       
  1297       *yQuantParams = imbP->yQuantParams,
       
  1298                            /* array of Y quantizers in scan-order */
       
  1299 
       
  1300       *uvQuantParams = imbP->uvQuantParams,
       
  1301                            /* array of UV quantizers in scan-order */
       
  1302 
       
  1303       numMBsInPicture,     /* number of macroblocks in the image */
       
  1304 
       
  1305       i;                   /* loop variable */
       
  1306 
       
  1307    vdcAssert(imbP);
       
  1308    vdcAssert(instance);
       
  1309 
       
  1310    /*
       
  1311     * Fill basic stuff
       
  1312     */
       
  1313 
       
  1314    vdcFillCommonPartsOfImb(instance, numOfCodedMBs, imbP);
       
  1315 
       
  1316    /*
       
  1317     * Calculate quantizer arrays for loop/post-filtering
       
  1318     */
       
  1319 
       
  1320    numMBsInPicture = instance->pictureParam.lumMemWidth * 
       
  1321       instance->pictureParam.lumMemHeight / 256;
       
  1322 
       
  1323    /* Get the index of the first non-zero quantizer in scan-order */
       
  1324    for (firstQPIndex = 0; firstQPIndex < numMBsInPicture; firstQPIndex++) {
       
  1325       if (yQuantParams[firstQPIndex] > 0)
       
  1326          break;
       
  1327    }
       
  1328 
       
  1329    /* Assert that at least one macroblock is decoded successfully */
       
  1330    vdcAssert(firstQPIndex < numMBsInPicture);
       
  1331 
       
  1332    /* Replace the first zero quantizers with the first non-zero quantizer
       
  1333       (in scan-order) */
       
  1334    for (i = 0; i < firstQPIndex; i++)
       
  1335       yQuantParams[i] = yQuantParams[firstQPIndex];
       
  1336 
       
  1337    /* Replace all other zero quantizers with the predecessor (in scan-order) */
       
  1338    for (i = firstQPIndex; i < numMBsInPicture; i++) {
       
  1339       if (yQuantParams[i] == 0)
       
  1340          yQuantParams[i] = yQuantParams[i - 1];
       
  1341    }
       
  1342 
       
  1343    /* If Modified Quantization is in use */
       
  1344    if (instance->pictureParam.fMQ) {
       
  1345       /* Convert Y quantizers to UV quantizers */
       
  1346       for (i = 0; i < numMBsInPicture; i++)
       
  1347          uvQuantParams[i] = yToUVQuantizer[yQuantParams[i]];
       
  1348    }
       
  1349    else
       
  1350       /* Copy Y quantizers to UV quantizers */
       
  1351       memcpy(uvQuantParams, yQuantParams, numMBsInPicture * sizeof(int));
       
  1352 
       
  1353 
       
  1354    return VDC_OK;
       
  1355 }
       
  1356 
       
  1357 // End of File