videoeditorengine/h263decoder/src/core_mpeg.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 * MPEG-4 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 "decvp_mpeg.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 /* MVE */
       
    39 #include "MPEG4Transcoder.h"
       
    40 
       
    41 
       
    42 /*
       
    43  * Typedefs and structs
       
    44  */
       
    45 
       
    46 /* This structure is used to indicate the expected decoding position. */
       
    47 typedef enum {
       
    48    EDP_START_OF_FRAME,
       
    49    EDP_START_OF_VIDEO_PACKET,
       
    50    EDP_END_OF_FRAME
       
    51 } vdcExpectedDecodingPosition_t;
       
    52 
       
    53 
       
    54 /*
       
    55  * Local function prototypes
       
    56  */ 
       
    57 
       
    58 extern int vdcFillImageBuffers(
       
    59    vdcInstance_t *instance,
       
    60    int numOfCodedMBs,
       
    61    vdeImb_t *imbP);
       
    62 
       
    63 
       
    64 /*
       
    65  * Global functions
       
    66  */
       
    67 
       
    68 /* {{-output"vdcDecodeMPEGVolHeader.txt"}} */
       
    69 /*
       
    70  * vdcDecodeMPEGVolHeader
       
    71  *    
       
    72  *
       
    73  * Parameters:
       
    74  *    None.
       
    75  *
       
    76  * Function:
       
    77  *    This function reads the VOL Header and updates the instance data
       
    78  *    with the read parameters.
       
    79  *
       
    80  * Returns:
       
    81  *    >= 0  if succeeded
       
    82  *    < 0   if failed
       
    83  *
       
    84  */
       
    85 
       
    86 int vdcDecodeMPEGVolHeader(vdcHInstance_t hInstance, bibBuffer_t *inBuffer, CMPEG4Transcoder *hTranscoder)
       
    87 /* {{-output"vdcDecodeMPEGVolHeader.txt"}} */
       
    88 {
       
    89     dphInOutParam_t pichInOut;
       
    90     int headerSuccess = 0;
       
    91 
       
    92     pichInOut.vdcInstance = (vdcInstance_t *) hInstance;
       
    93     pichInOut.inBuffer = inBuffer;
       
    94 
       
    95     headerSuccess = dphGetMPEGVolHeader(&pichInOut, hTranscoder);
       
    96     if (headerSuccess != 0)
       
    97         return VDC_ERR;
       
    98     else 
       
    99         return VDC_OK;
       
   100 }
       
   101 
       
   102 
       
   103 /* {{-output"vdcDecodeMPEGVop.txt"}} */
       
   104 /*
       
   105  * vdcDecodeMPEGVop
       
   106  *    
       
   107  *
       
   108  * Parameters:
       
   109  *    hInstance                  handle of instance data
       
   110  *
       
   111  *    inBuffer                   pointer to bit buffer, the current position
       
   112  *                               of the buffer must start with a PSC
       
   113  *
       
   114  * Function:
       
   115  *    The vdcDecodeMPEGVop function implements the decoding process of the MPEG-4
       
   116  *    Simple Video Object described in ISO/IEC 14496-2. 
       
   117  *
       
   118  *    The function decodes the next frame in the buffer (inBuffer) meaning that
       
   119  *    the decoding continues until the next VOP start code or EOB is found or
       
   120  *    until the end of the buffer is not reached.
       
   121  *
       
   122  * Returns:
       
   123  *    VDC_OK                     if the function was succesful
       
   124  *    VDC_OK_BUT_BIT_ERROR       if bit errors were detected but
       
   125  *                               decoded frames are provided by concealing
       
   126  *                               the errors
       
   127  *    VDC_OK_BUT_FRAME_USELESS   if severe bit errors were detected
       
   128  *                               (no concealment was possible) or
       
   129  *                               the bitstream ended unexpectedly
       
   130  *    VDC_ERR                    if a processing error occured,
       
   131  *                               the instance should be closed
       
   132  *
       
   133  */
       
   134 int vdcDecodeMPEGVop(vdcHInstance_t hInstance, bibBuffer_t *inBuffer, bibBuffer_t *outBuffer,
       
   135                      bibBufferEdit_t *bufEdit, int aColorEffect, TBool aGetDecodedFrame, 
       
   136                      int aStartByteIndex, int aStartBitIndex,
       
   137                      CMPEG4Transcoder *hTranscoder)
       
   138 /* {{-output"vdcDecodeMPEGVop.txt"}} */
       
   139 {
       
   140    int sncCode;               /* the latest synchronization code, see 
       
   141                                  sncCheckSync for the possible values */
       
   142 
       
   143    int retValue = VDC_OK;     /* return value of this function */
       
   144 
       
   145    int16 error = 0;
       
   146 
       
   147    u_char
       
   148       *currYFrame = NULL,     /* current P frame */
       
   149       *currUFrame = NULL,
       
   150       *currVFrame = NULL,
       
   151       *refYFrame = NULL,      /* reference frame */
       
   152       *refUFrame = NULL,
       
   153       *refVFrame = NULL;
       
   154 
       
   155    u_char *fCodedMBs = NULL;  /* Pointer to table, which indicates coded \
       
   156                                  macroblocks by non-zero value */
       
   157    int numOfCodedMBs = 0;     /* The number of coded macroblocks */
       
   158 
       
   159    int *quantParams = NULL;   /* Pointer to table, in which the quantization
       
   160                                  parameter for each macroblock is stored */
       
   161 
       
   162    int currMBNum = 0;       /* Current macro block */
       
   163 
       
   164    int decStatus = 0;
       
   165    int corruptedVPs = 0;
       
   166    int numberOfVPs = 1;
       
   167    int headerSuccess = 0;
       
   168    u_char fVOPHeaderCorrupted = 0, fVOPHeaderLost = 0;
       
   169 
       
   170    vdcExpectedDecodingPosition_t expectedDecodingPosition;
       
   171                               /* Tells in which part of the bitstream
       
   172                                  the decoding should be */
       
   173 
       
   174    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
   175                               /* instance data */
       
   176       
       
   177    vdcAssert(instance != NULL);
       
   178 
       
   179    /* Initializations */
       
   180 
       
   181    instance->currFrame = NULL;
       
   182    expectedDecodingPosition = EDP_START_OF_FRAME;
       
   183 
       
   184    /* Main loop */
       
   185    for (;;) {
       
   186       int bitErrorIndication = 0;
       
   187 
       
   188       sncCode = sncCheckMpegSync(inBuffer, instance->pictureParam.fcode_forward, &error);
       
   189 
       
   190       /* If sncCheckSync failed */
       
   191       if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
       
   192          deb1p("vdcDecodeMPEGVop: ERROR - sncCheckSync returned %d.\n", error);
       
   193          retValue = VDC_ERR;
       
   194          goto exitFunction;
       
   195       }
       
   196 
       
   197       /* If EOS was got */
       
   198       if (sncCode == SNC_EOB)
       
   199          instance->fEOS = 1;
       
   200 
       
   201       /* If frame ends appropriately */
       
   202       if (expectedDecodingPosition == EDP_END_OF_FRAME &&
       
   203          (sncCode == SNC_VOP || sncCode == SNC_GOV || sncCode == SNC_EOB || 
       
   204           sncCode == SNC_STUFFING || error == ERR_BIB_NOT_ENOUGH_DATA))
       
   205          goto exitFunction;
       
   206 
       
   207       /* Else if frame (or stream) data ends suddenly */
       
   208       else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
       
   209          retValue = VDC_OK_BUT_BIT_ERROR;
       
   210          goto exitFunction;
       
   211       }
       
   212 
       
   213       /* Else if EOS was reached */
       
   214       else if (sncCode == SNC_EOB) {
       
   215          /* The current frame is useless since it ends before it is complete.
       
   216             On the other hand, there is no point in concealing it since
       
   217             it is the last frame of the sequence. */
       
   218          goto exitFunction;
       
   219       }
       
   220 
       
   221       /* Else if frame starts as expected */
       
   222       else if (expectedDecodingPosition == EDP_START_OF_FRAME &&
       
   223          ((sncCode == SNC_GOV) || (sncCode == SNC_VOP) || fVOPHeaderLost)) {
       
   224 
       
   225          dphInParam_t pichIn;
       
   226          dphInOutParam_t pichInOut;
       
   227          dphOutParam_t pichOut;
       
   228 
       
   229          if (sncCode == SNC_GOV) {
       
   230               vdxGovHeader_t govHeader;
       
   231 
       
   232               headerSuccess = vdxGetGovHeader(inBuffer, &govHeader, &bitErrorIndication);
       
   233               if ( headerSuccess < 0) {
       
   234                   retValue = VDC_ERR;
       
   235                   goto exitFunction;
       
   236               } else if (( headerSuccess > 0 ) || 
       
   237                   (govHeader.time_stamp < instance->pictureParam.mod_time_base) || 
       
   238                   (govHeader.time_stamp - instance->pictureParam.mod_time_base > 60)) {
       
   239                   
       
   240                   if(sncCheckMpegVOP(inBuffer, &error) != SNC_PSC) {
       
   241                       retValue = VDC_OK_BUT_FRAME_USELESS;
       
   242                       goto exitFunction;
       
   243                   }
       
   244 
       
   245               } else {
       
   246                   instance->pictureParam.mod_time_base = govHeader.time_stamp;
       
   247 
       
   248                   /* copying the user data */
       
   249                   if (govHeader.user_data != NULL) {
       
   250 
       
   251                       if (!instance->user_data)
       
   252                           instance->user_data = (char *) vdcMalloc(
       
   253                               MAX_USER_DATA_LENGTH);
       
   254 
       
   255                       govHeader.user_data_length = 
       
   256                           ((instance->user_data_length + govHeader.user_data_length) >= MAX_USER_DATA_LENGTH) ?
       
   257                           (MAX_USER_DATA_LENGTH - instance->user_data_length) : govHeader.user_data_length;
       
   258                       memcpy(
       
   259                           instance->user_data + instance->user_data_length, 
       
   260                           govHeader.user_data, 
       
   261                           govHeader.user_data_length);
       
   262                       instance->user_data_length += govHeader.user_data_length;
       
   263 
       
   264                       vdcDealloc(govHeader.user_data);
       
   265                   }
       
   266 
       
   267               }
       
   268          }
       
   269 
       
   270          /* Start VOP decoding */
       
   271          pichIn.fReadBits = (fVOPHeaderLost ? 0 : 1);
       
   272          pichIn.fNeedDecodedFrame = aGetDecodedFrame | hTranscoder->NeedDecodedYUVFrame();
       
   273          pichInOut.vdcInstance = instance;
       
   274          pichInOut.inBuffer = inBuffer;
       
   275 
       
   276          /* Get VOP header */
       
   277          headerSuccess = dphGetMPEGVopHeader(&pichIn, &pichInOut, &pichOut, &bitErrorIndication);
       
   278          
       
   279          deb1p("vdcDecodeMPEGVop: frameNum %d.\n", instance->frameNum);
       
   280          if ( headerSuccess < 0) {
       
   281              retValue = VDC_ERR;
       
   282              goto exitFunction;
       
   283          } else if ( headerSuccess > 0 ) {
       
   284 
       
   285              if (headerSuccess == DPH_OK_BUT_BIT_ERROR) {
       
   286                  /* find the next resync marker, to get the number of MBs in the current VP */
       
   287                  sncCode = sncRewindAndSeekNewMPEGSync(-1, inBuffer, instance->pictureParam.fcode_forward, &error);
       
   288                  if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
       
   289                      retValue = VDC_ERR;
       
   290                      goto exitFunction;
       
   291                  }
       
   292 
       
   293                  if (sncCode == SNC_VIDPACK) {
       
   294                      fVOPHeaderCorrupted = 1;
       
   295                  } else {
       
   296                      retValue = VDC_OK_BUT_FRAME_USELESS;
       
   297                      goto exitFunction;
       
   298                  }
       
   299 
       
   300              } else if (headerSuccess == DPH_OK_BUT_NOT_CODED) {
       
   301                              
       
   302                 /* MVE */
       
   303                 /* copy VOP header to output buffer in case VOP is not coded, including the GOV */
       
   304                 bufEdit->copyMode = CopyWhole; /* copyWhole */
       
   305                 CopyStream(inBuffer,outBuffer,bufEdit, aStartByteIndex, aStartBitIndex);
       
   306                              
       
   307                 /* behaves the same as if the frame was useless, but it's just not coded */
       
   308                 retValue = VDC_OK_BUT_NOT_CODED;
       
   309                 goto exitFunction;
       
   310              }
       
   311          }
       
   312 
       
   313 
       
   314          currYFrame = pichOut.currYFrame;
       
   315          currUFrame = pichOut.currUFrame;
       
   316          currVFrame = pichOut.currVFrame;
       
   317 
       
   318          currMBNum = 0;
       
   319 
       
   320          numOfCodedMBs = 0;
       
   321          fCodedMBs = renDriCodedMBs(instance->currFrame->imb->drawItem);
       
   322          memset(fCodedMBs, 0, renDriNumOfMBs(
       
   323             instance->currFrame->imb->drawItem) * sizeof(u_char));
       
   324 
       
   325          /* Initialize quantization parameter array */
       
   326          quantParams = instance->currFrame->imb->yQuantParams;
       
   327          memset(quantParams, 0, renDriNumOfMBs(
       
   328             instance->currFrame->imb->drawItem) * sizeof(int));
       
   329 
       
   330          /* If this is the first frame and callback function has been set, report frame size */ 
       
   331          if (instance->nOfDecodedFrames == 0 && instance->reportPictureSizeCallback) {
       
   332             h263dReportPictureSizeCallback_t cb = 
       
   333                (h263dReportPictureSizeCallback_t)instance->reportPictureSizeCallback;
       
   334             cb(instance->hParent, instance->pictureParam.lumWidth, instance->pictureParam.lumHeight);
       
   335          }
       
   336 
       
   337          /* Decode the 1st VP segment */
       
   338          {
       
   339             dvpVPInParam_t dvpi;
       
   340             dvpVPInOutParam_t dvpio;
       
   341 
       
   342             dvpi.pictParam = &instance->pictureParam;
       
   343             dvpi.inBuffer = inBuffer;
       
   344             dvpi.outBuffer = outBuffer;
       
   345             dvpi.bufEdit = bufEdit;
       
   346             dvpi.iColorEffect = aColorEffect;
       
   347             dvpi.iGetDecodedFrame = aGetDecodedFrame;
       
   348 
       
   349             if (fVOPHeaderLost) fVOPHeaderCorrupted = 1;
       
   350             dvpi.fVOPHeaderCorrupted = fVOPHeaderCorrupted;
       
   351             
       
   352             dvpio.currMBNum = 0;
       
   353             dvpio.quant = pichOut.pquant;
       
   354             dvpio.fCodedMBs = fCodedMBs;
       
   355             dvpio.numOfCodedMBs = numOfCodedMBs;
       
   356             dvpio.quantParams = quantParams;
       
   357             dvpio.mvcData = &instance->mvcData;
       
   358             dvpio.aicData = &instance->aicData;
       
   359             dvpio.imageStore = instance->imageStore;
       
   360             dvpio.frameNum = instance->frameNum;
       
   361     
       
   362             dvpio.refY = refYFrame;
       
   363             dvpio.refU = refUFrame;
       
   364             dvpio.refV = refVFrame;
       
   365             dvpio.currPY = currYFrame;
       
   366             dvpio.currPU = currUFrame;
       
   367             dvpio.currPV = currVFrame;
       
   368             
       
   369             /* MVE */
       
   370             hTranscoder->VOPHeaderEnded(aStartByteIndex, aStartBitIndex,
       
   371                 pichOut.pquant, instance->pictureParam.pictureType,
       
   372                 instance->frameNum, headerSuccess == DPH_OK_BUT_NOT_CODED);
       
   373             /* VOP header parsing success, begin on VP */
       
   374             hTranscoder->BeginOneVideoPacket(&dvpi);
       
   375             hTranscoder->AfterVideoPacketHeader(&dvpio); // the first VP does not have VPHeader
       
   376 
       
   377             decStatus = dvpGetAndDecodeVideoPacketContents(&dvpi,
       
   378                 instance->pictureParam.pictureType != VDX_PIC_TYPE_I,
       
   379                 &dvpio, hTranscoder);
       
   380 
       
   381             if (decStatus < 0) {
       
   382                 retValue = VDC_ERR;
       
   383                 goto exitFunction;
       
   384             } else if (decStatus > 0 ) {
       
   385                 if (decStatus == DGOB_OK_BUT_FRAME_USELESS) {
       
   386                     retValue = VDC_OK_BUT_FRAME_USELESS;
       
   387                     goto exitFunction;
       
   388                 }
       
   389                 corruptedVPs ++;
       
   390             }
       
   391                         
       
   392             /* MVE */
       
   393             /* the first VP ends */
       
   394             hTranscoder->OneVPEnded();
       
   395 
       
   396             currMBNum = dvpio.currMBNum;
       
   397             numOfCodedMBs = dvpio.numOfCodedMBs;
       
   398             refYFrame = dvpio.refY;
       
   399             refUFrame = dvpio.refU;
       
   400             refVFrame = dvpio.refV;
       
   401             
       
   402 
       
   403             if ((decStatus == DGOB_OK && currMBNum == instance->pictureParam.numMBsInGOB) || 
       
   404                 (decStatus == DGOB_OK_BUT_BIT_ERROR && sncCheckMpegVOP(inBuffer, &error) == SNC_PSC))
       
   405                 expectedDecodingPosition = EDP_END_OF_FRAME;
       
   406             else
       
   407                 expectedDecodingPosition = EDP_START_OF_VIDEO_PACKET;
       
   408          }
       
   409       }
       
   410    
       
   411       /* Else if Video Packet starts as expected */
       
   412       else if (expectedDecodingPosition == EDP_START_OF_VIDEO_PACKET &&
       
   413          sncCode == SNC_VIDPACK) {
       
   414 
       
   415             dvpVPInParam_t dvpi;
       
   416             dvpVPInOutParam_t dvpio;
       
   417 
       
   418             dvpi.pictParam = &instance->pictureParam;
       
   419             dvpi.inBuffer = inBuffer;
       
   420             dvpi.outBuffer = outBuffer;
       
   421             dvpi.bufEdit = bufEdit;
       
   422             dvpi.iColorEffect = aColorEffect;
       
   423             dvpi.iGetDecodedFrame = aGetDecodedFrame;
       
   424             dvpi.fVOPHeaderCorrupted = fVOPHeaderCorrupted;
       
   425             
       
   426             dvpio.currMBNum = currMBNum;
       
   427             dvpio.fCodedMBs = fCodedMBs;
       
   428             dvpio.numOfCodedMBs = numOfCodedMBs;
       
   429             dvpio.quantParams = quantParams;
       
   430             dvpio.mvcData = &instance->mvcData;
       
   431             dvpio.aicData = &instance->aicData;
       
   432             dvpio.imageStore = instance->imageStore;
       
   433 
       
   434             dvpio.refY = refYFrame;
       
   435             dvpio.refU = refUFrame;
       
   436             dvpio.refV = refVFrame;
       
   437             dvpio.currPY = currYFrame;
       
   438             dvpio.currPU = currUFrame;
       
   439             dvpio.currPV = currVFrame;
       
   440             
       
   441             /* MVE */
       
   442             /* VOP header parsing success, begin on VP */
       
   443             hTranscoder->BeginOneVideoPacket(&dvpi);
       
   444 
       
   445             /* if the VOP header data needs to be corrected from the HEC codes set
       
   446             inParam->fVOPHeaderCorrupted and pictParam values will be set + read
       
   447             inOutParam->frameNum into instance->frameNum */
       
   448             decStatus = dvpGetAndDecodeVideoPacketHeader(&dvpi, &dvpio);
       
   449                         
       
   450             /* MVE */
       
   451             /* After parsing the VP header */
       
   452             hTranscoder->AfterVideoPacketHeader(&dvpio);
       
   453                         
       
   454             if (decStatus < 0) {
       
   455                 retValue = VDC_ERR;
       
   456                 goto exitFunction;
       
   457             } else if (decStatus > 0) {
       
   458                 
       
   459                 if (fVOPHeaderCorrupted) {
       
   460                     /* this is also true when the whole packet with the VOP header is lost */
       
   461 
       
   462                     if (dvpio.frameNum <= instance->frameNum) {
       
   463                         /* VOP header could not be recovered from HEC (there was no HEC)
       
   464                            or there was an error in the VP header: in this case should we try to recover 
       
   465                            VOP header from the next VP instead of the exiting here? */
       
   466                         retValue = VDC_OK_BUT_FRAME_USELESS;
       
   467                         goto exitFunction;
       
   468 
       
   469                     } else {
       
   470                         /* VOP header was succesfully recovered from HEC, 
       
   471                            the first VP is treated as corrupted or lost */
       
   472                         instance->frameNum = dvpio.frameNum;
       
   473 
       
   474                     }
       
   475                 } else if (currMBNum < dvpio.currMBNum) {
       
   476                     /* when there was no bit-error in the VP header and the MB counter shows difference 
       
   477                        we know, that a whole VP was lost */
       
   478                     
       
   479                     corruptedVPs++;
       
   480                     numberOfVPs++;
       
   481                     
       
   482 
       
   483                 }
       
   484             }
       
   485             
       
   486             numberOfVPs++;
       
   487 
       
   488             if (!decStatus) {
       
   489 
       
   490            
       
   491                 decStatus = dvpGetAndDecodeVideoPacketContents(&dvpi,0,&dvpio, hTranscoder);
       
   492                 if (decStatus < 0) {
       
   493                     retValue = VDC_ERR;
       
   494                     goto exitFunction;
       
   495                 } else if (decStatus > 0 ) {
       
   496                     if (decStatus == DGOB_OK_BUT_FRAME_USELESS) {
       
   497                         retValue = VDC_OK_BUT_FRAME_USELESS;
       
   498                         goto exitFunction;
       
   499                     }
       
   500                     corruptedVPs++;
       
   501                 }
       
   502                 
       
   503             }
       
   504                         
       
   505             /* MVE */
       
   506             hTranscoder->OneVPEnded();
       
   507 
       
   508             currMBNum = dvpio.currMBNum;
       
   509             numOfCodedMBs = dvpio.numOfCodedMBs;
       
   510                         
       
   511             if ((decStatus == DGOB_OK && currMBNum == instance->pictureParam.numMBsInGOB) || 
       
   512                             (decStatus == DGOB_OK_BUT_BIT_ERROR && sncCheckMpegVOP(inBuffer, &error) == SNC_PSC))
       
   513                 expectedDecodingPosition = EDP_END_OF_FRAME;
       
   514             else {
       
   515                 expectedDecodingPosition = EDP_START_OF_VIDEO_PACKET;
       
   516                 if (fVOPHeaderCorrupted) fVOPHeaderCorrupted=0;
       
   517             }
       
   518       }
       
   519             
       
   520       /* Else decoding is out of sync */
       
   521       else {
       
   522          switch (expectedDecodingPosition) {
       
   523 
       
   524             case EDP_START_OF_FRAME:
       
   525                 if (sncCode == SNC_VIDPACK) {
       
   526                     /* VP start code instead of VOP start code -> 
       
   527                        packet including VOP header is lost */                    
       
   528                     fVOPHeaderLost = 1;
       
   529                     continue;                    
       
   530                 } else {
       
   531                     /* No start code */
       
   532                     retValue = VDC_OK_BUT_FRAME_USELESS;
       
   533                     goto exitFunction;
       
   534                 }
       
   535 
       
   536             case EDP_START_OF_VIDEO_PACKET:
       
   537                /* If the decoding gets out of sync, the next sync code is
       
   538                   seeked in dvpGetAndDecodeVideoPacketContents. Then, if 
       
   539                   the frame ends instead of a new VP header, we are here. */
       
   540 
       
   541                 /* Mark the missing VP corrupted */
       
   542                 {
       
   543                     numberOfVPs++;
       
   544                     corruptedVPs++;
       
   545                     
       
   546                 }
       
   547 
       
   548                 retValue = VDC_OK_BUT_BIT_ERROR;
       
   549                 goto exitFunction;
       
   550 
       
   551             case EDP_END_OF_FRAME:
       
   552                /* Too much data */
       
   553                retValue = VDC_OK_BUT_BIT_ERROR;
       
   554                goto exitFunction;
       
   555          }
       
   556       }
       
   557    }
       
   558 
       
   559 
       
   560      
       
   561 exitFunction:
       
   562      
       
   563     /* MVE */
       
   564     hTranscoder->VOPEnded();
       
   565 
       
   566     if (sncCheckMpegSync(inBuffer, instance->pictureParam.fcode_forward, &error) == SNC_EOB) {
       
   567         instance->fEOS = 1;
       
   568     }
       
   569 
       
   570    /* If frame(s) not useless */
       
   571    if (retValue == VDC_OK || retValue == VDC_OK_BUT_BIT_ERROR) {
       
   572 
       
   573        /* If bit errors */  
       
   574        if (corruptedVPs) {
       
   575            retValue = VDC_OK_BUT_FRAME_USELESS;
       
   576        }
       
   577 
       
   578        if ( retValue != VDC_OK_BUT_FRAME_USELESS ) {
       
   579 
       
   580            if ( instance->nOfDecodedFrames < 0xffffffff )
       
   581               instance->nOfDecodedFrames++;
       
   582            if (vdcFillImageBuffers(instance, numOfCodedMBs, 
       
   583                instance->currFrame->imb) < 0)
       
   584                retValue = VDC_ERR;
       
   585 
       
   586        }
       
   587    }
       
   588 
       
   589    /* If a fatal error occurred */
       
   590    if (retValue < 0) {
       
   591       /* Return frame buffers for decoded output images,
       
   592          as they are useless for the caller and 
       
   593          as the caller cannot get a handle to return them */
       
   594       if (instance->currFrame)
       
   595          vdeImsPutFree(instance->imageStore, instance->currFrame);
       
   596    }
       
   597 
       
   598    return retValue;
       
   599 }
       
   600 
       
   601 
       
   602 /* {{-output"vdcIsMPEGINTRA.txt"}} */
       
   603 /*
       
   604  * vdcIsMPEGINTRA
       
   605  *    
       
   606  *
       
   607  * Parameters:
       
   608  *    hInstance                  handle of instance data
       
   609  *    frameStart                 pointer to memory chunk containing a frame
       
   610  *    frameLength                number of bytes in frame
       
   611  *
       
   612  * Function:
       
   613  *    This function returns 1 if the passed frame is an INTRA frame.
       
   614  *    Otherwise the function returns 0.
       
   615  *
       
   616  * Returns:
       
   617  *    See above.
       
   618  *
       
   619  *        
       
   620  */
       
   621 
       
   622 int vdcIsMPEGINTRA(
       
   623    vdcHInstance_t hInstance,
       
   624    void *frameStart,
       
   625    unsigned frameLength)
       
   626 /* {{-output"vdcIsINTRA.txt"}} */
       
   627 {
       
   628    bibBuffer_t *tmpBitBuffer;
       
   629    int fINTRA = 0, bitErrorIndication, syncCode, vdxStatus;
       
   630    int16 error = 0;
       
   631    vdcInstance_t *instance = (vdcInstance_t *) hInstance;
       
   632    vdxGovHeader_t govHeader;
       
   633 
       
   634    vdcAssert(instance);
       
   635 
       
   636    tmpBitBuffer = bibCreate(frameStart, frameLength, &error);
       
   637    if (!tmpBitBuffer || error)
       
   638       return 0;
       
   639 
       
   640    syncCode = sncCheckMpegSync(tmpBitBuffer, instance->pictureParam.fcode_forward, &error);
       
   641 
       
   642    if ((syncCode == SNC_GOV || syncCode == SNC_VOP) && error == 0) {
       
   643       vdxGetVopHeaderInputParam_t vopIn;
       
   644       vdxVopHeader_t vopOut;
       
   645 
       
   646       if (syncCode == SNC_GOV) {
       
   647          vdxStatus = vdxGetGovHeader(tmpBitBuffer, &govHeader, 
       
   648             &bitErrorIndication);
       
   649 
       
   650          if (vdxStatus < 0 || bitErrorIndication != 0) 
       
   651             return fINTRA;
       
   652       }
       
   653 
       
   654       /* MVE */
       
   655       int dummy1, dummy2, dummy3, dummy4; /* not used for any processing */
       
   656       /* Get VOP header */
       
   657       vopIn.time_increment_resolution = instance->pictureParam.time_increment_resolution;
       
   658       vdxStatus = vdxGetVopHeader(tmpBitBuffer, &vopIn, &vopOut, 
       
   659                 &dummy1, &dummy2, &dummy3, &dummy4,
       
   660                 &bitErrorIndication);
       
   661 
       
   662 
       
   663       if (vdxStatus >= 0 && bitErrorIndication == 0)
       
   664          fINTRA = (vopOut.coding_type == VDX_VOP_TYPE_I);
       
   665    }
       
   666    
       
   667    bibDelete(tmpBitBuffer, &error);
       
   668 
       
   669    return fINTRA;
       
   670 }
       
   671 // End of File