videoeditorengine/h263decoder/src/decvp_mpeg.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 5 4c409de21d23
equal deleted inserted replaced
0:951a5db380a0 3:e0b5df5c0969
     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 * Video packet decoding module (MPEG-4).
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 /*
       
    22  * Includes
       
    23  */
       
    24 #include "h263dConfig.h"
       
    25 #include "decvp_mpeg.h"
       
    26 #include "block.h"
       
    27 #include "debug.h"
       
    28 #include "decmbs.h"
       
    29 #include "stckheap.h"
       
    30 #include "sync.h"
       
    31 #include "viddemux.h"
       
    32 #include "biblin.h"
       
    33 /* MVE */
       
    34 #include "MPEG4Transcoder.h"
       
    35 
       
    36 /*
       
    37  * Global functions
       
    38  */
       
    39 
       
    40 /* {{-output"dvpGetAndDecodeVideoPacketHeader.txt"}} */
       
    41 /*
       
    42  * dvpGetAndDecodeVideoPacketHeader
       
    43  *    
       
    44  *
       
    45  * Parameters:
       
    46  *    inParam                    input parameters
       
    47  *    inOutParam                 input/output parameters, these parameters
       
    48  *                               may be modified in the function
       
    49  *
       
    50  * Function:
       
    51  *    This function gets and decodes a Video Packet header at the 
       
    52  *    current position of the bit buffer. It checks its correctness and 
       
    53  *    if it fits to the sequence of VPs, and does the necessary actions for 
       
    54  *    correction.
       
    55  *
       
    56  * Returns:
       
    57  *    >= 0                       the function was successful
       
    58  *    < 0                        an error occured
       
    59  *
       
    60  */
       
    61 
       
    62 int dvpGetAndDecodeVideoPacketHeader(
       
    63    const dvpVPInParam_t *inParam,
       
    64    dvpVPInOutParam_t *inOutParam)
       
    65 /* {{-output"dvpGetAndDecodeVideoPacketHeader.txt"}} */
       
    66 {
       
    67    int16 error = 0;
       
    68    vdxGetVideoPacketHeaderInputParam_t vdxParam;
       
    69    vdxVideoPacketHeader_t header;
       
    70    bibBuffer_t *inBuffer = inParam->inBuffer;
       
    71    int bitErrorIndication = 0, retVal, fLostSegment = FALSE;
       
    72 
       
    73    /* 
       
    74     * Get VP header 
       
    75     */
       
    76 
       
    77    vdxParam.fcode_forward = inParam->pictParam->fcode_forward;
       
    78    vdxParam.time_increment_resolution = inParam->pictParam->time_increment_resolution;
       
    79    vdxParam.numOfMBs = inParam->pictParam->numMBsInGOB;
       
    80 
       
    81    retVal = vdxGetVideoPacketHeader(inBuffer, &vdxParam, &header, &bitErrorIndication);
       
    82    if (retVal < 0) {
       
    83      return DGOB_ERR;
       
    84    } else if (retVal > 0) {
       
    85       deb("dvpGetAndDecodeVideoPacketHeader: ERROR - vdxGetVideoPacketHeader failed.\n");
       
    86       goto headerFailure;
       
    87    }
       
    88 
       
    89 
       
    90    /*
       
    91     * Check header validity
       
    92     */
       
    93 
       
    94    if (header.currMBNum == 0 || header.currMBNum >= inParam->pictParam->numMBsInGOB) {
       
    95       deb("dvpGetAndDecodeVideoPacketHeader: ERROR - too big currMBNum.\n");
       
    96       goto headerFailure;
       
    97    }
       
    98    
       
    99    /* quant can not be zero */
       
   100    if(header.quant == 0) {
       
   101       goto headerFailure;
       
   102    }
       
   103 
       
   104    if (header.fHEC) {
       
   105 
       
   106       if (header.time_base_incr < 0 || header.time_base_incr > 60) {
       
   107          if (bitErrorIndication) {
       
   108             goto headerFailure;
       
   109          }
       
   110       }
       
   111 
       
   112       /* fcode can have only the valid values 1..7 */
       
   113       if (header.coding_type == VDX_VOP_TYPE_P) 
       
   114          if (header.fcode_forward == 0) {
       
   115             goto headerFailure;
       
   116          }
       
   117 
       
   118       if (!inParam->fVOPHeaderCorrupted) {
       
   119 
       
   120          if ((inParam->pictParam->pictureType != header.coding_type) ||
       
   121             (inParam->pictParam->time_base_incr != header.time_base_incr) ||
       
   122             (inParam->pictParam->time_inc != header.time_inc)) {
       
   123             deb("dvpGetAndDecodeVideoPacketHeader: ERROR - Parameter change VOP<->VP header.\n");
       
   124             goto headerFailure;
       
   125          }
       
   126       }
       
   127    }
       
   128    if (inParam->fVOPHeaderCorrupted) {
       
   129       /* Get the coding type parameter since it is needed in the concealment before the other updates */
       
   130       if (header.fHEC) {
       
   131          inParam->pictParam->pictureType = header.coding_type;
       
   132       }
       
   133    }
       
   134    if (header.currMBNum != inOutParam->currMBNum) {
       
   135       if ( header.currMBNum > inOutParam->currMBNum && bitErrorIndication == 0) {
       
   136 
       
   137          fLostSegment = TRUE;
       
   138          goto headerFailure;
       
   139 
       
   140       } else if (header.currMBNum < inOutParam->currMBNum) {
       
   141          deb("dvpGetAndDecodeVideoPacketHeader: ERROR - MB counting is out of sync.\n");
       
   142          goto headerFailure;
       
   143       }
       
   144    }
       
   145 
       
   146    /*
       
   147     * Update parameters
       
   148     */
       
   149 
       
   150    inOutParam->currMBNum = header.currMBNum;
       
   151    inOutParam->quant = header.quant;
       
   152 
       
   153    if (inParam->fVOPHeaderCorrupted) {
       
   154       if (header.fHEC) {
       
   155          inParam->pictParam->mod_time_base += inParam->pictParam->time_base_incr = header.time_base_incr;
       
   156          
       
   157          inParam->pictParam->time_inc = header.time_inc;
       
   158 
       
   159          inOutParam->frameNum = (int) ((inParam->pictParam->mod_time_base + 
       
   160             ((double) header.time_inc) / ((double) inParam->pictParam->time_increment_resolution)) *
       
   161             30.0 + 0.001);
       
   162 
       
   163          inParam->pictParam->tr = inOutParam->frameNum % 256;
       
   164          inParam->pictParam->pictureType = header.coding_type;
       
   165 
       
   166          inParam->pictParam->intra_dc_vlc_thr = header.intra_dc_vlc_thr;
       
   167 
       
   168          if (header.coding_type == VDX_VOP_TYPE_P)
       
   169              if (inParam->pictParam->fcode_forward != header.fcode_forward) {
       
   170                  /* Initialize once to count parameters for the mvc module */
       
   171                  int r_size, scale_factor;
       
   172                  
       
   173                  inParam->pictParam->fcode_forward = header.fcode_forward;
       
   174 
       
   175                  inOutParam->mvcData->f_code = inParam->pictParam->fcode_forward;
       
   176                  r_size = inParam->pictParam->fcode_forward - 1;
       
   177                  scale_factor = (1 << r_size);
       
   178                  inOutParam->mvcData->range = 160 * scale_factor;
       
   179              }
       
   180       } else {
       
   181          /* seek next PSC, VP start code is not good enough */
       
   182          sncRewindAndSeekNewMPEGSync(-1, inBuffer, 0, &error);
       
   183          return DGOB_OK_BUT_BIT_ERROR;
       
   184       }
       
   185    }
       
   186    
       
   187    if (fLostSegment)
       
   188        return DGOB_OK_BUT_BIT_ERROR;
       
   189    else
       
   190        return DGOB_OK;
       
   191 
       
   192    headerFailure:
       
   193       sncRewindAndSeekNewMPEGSync(-1, inBuffer, inParam->pictParam->fcode_forward, &error);
       
   194      
       
   195      if (error && error != ERR_BIB_NOT_ENOUGH_DATA)
       
   196          return DGOB_ERR;
       
   197       return DGOB_OK_BUT_BIT_ERROR;
       
   198 }
       
   199 
       
   200 
       
   201 /* {{-output"dvpGetAndDecodeVideoPacketContents.txt"}} */
       
   202 /*
       
   203  * dvpGetAndDecodeVideoPacketContents
       
   204  *    
       
   205  *
       
   206  * Parameters:
       
   207  *    inParam                    input parameters
       
   208  *    fGetNewReferenceFrame      non-zero if a new reference frame must be
       
   209  *                               requested from the image store, otherwise 0
       
   210  *    inOutParam                 input/output parameters, these parameters
       
   211  *                               may be modified in the function
       
   212  *
       
   213  * Function:
       
   214  *    This function gets and decodes the contents of a Video Packet
       
   215  *    after the header of the VP (either VP header or picture
       
   216  *    header) is already got and processed. It works MB-by-MB or if VP
       
   217  *    is data partitioned calls the corresponding decoding functions.
       
   218  *    Error concealment for the missing (not decodable) MBs in a P-frame
       
   219  *    is called.
       
   220  *
       
   221  * Returns:
       
   222  *    >= 0                       the function was successful
       
   223  *    < 0                        an error occured
       
   224  *
       
   225  */
       
   226 
       
   227 int dvpGetAndDecodeVideoPacketContents(
       
   228    const dvpVPInParam_t *inParam,
       
   229    int fGetNewReferenceFrame,
       
   230    dvpVPInOutParam_t *inOutParam, CMPEG4Transcoder *hTranscoder)
       
   231 /* {{-output"dvpGetAndDecodeVideoPacketContents.txt"}} */
       
   232 {
       
   233    int16 error = 0;
       
   234    int bitErrorIndication = 0;
       
   235    dmbPFrameMBInParam_t dpmbi;
       
   236    dmbPFrameMBInOutParam_t dpmbio;
       
   237    dmbIFrameMBInParam_t dimbi;
       
   238    dmbIFrameMBInOutParam_t dimbio;
       
   239    int yPosInMBs, xPosInMBs = 0;
       
   240    bibBuffer_t *inBuffer;
       
   241    bibBuffer_t 
       
   242        *outBuffer;        /* Output bit buffer instance */
       
   243    
       
   244    bibBufferEdit_t              
       
   245        *bufEdit; 
       
   246    
       
   247    int colorEffect; 
       
   248    TBool getDecodedFrame;
       
   249 
       
   250 
       
   251    int fSegmentCorrupted = 0;
       
   252 
       
   253    int dmbRetValue;
       
   254    int sncCode = SNC_NO_SYNC;
       
   255    int lastMBNumInVP = 0;
       
   256    int startMB = inOutParam->currMBNum;
       
   257 
       
   258    SOH_DEFINE(blcDiffMB_t, pDiffMB); /* Storage for the previous difference blocks */
       
   259   
       
   260    SOH_ALLOC(blcDiffMB_t, pDiffMB);
       
   261 
       
   262    if (pDiffMB == NULL) {
       
   263       deb("dvpGetAndDecodeVideoPacketContents: SOH_ALLOC failed.\n");
       
   264       goto unexpectedError;
       
   265    }
       
   266 
       
   267    pDiffMB->cbpy = 0;
       
   268 
       
   269    inBuffer = inParam->inBuffer;
       
   270    outBuffer = inParam->outBuffer;
       
   271    bufEdit = inParam->bufEdit;
       
   272    colorEffect = inParam->iColorEffect;
       
   273    getDecodedFrame = inParam->iGetDecodedFrame;
       
   274 
       
   275    /* If the reference frame changed */
       
   276    if (fGetNewReferenceFrame) {
       
   277       vdeIms_t *store = inOutParam->imageStore;
       
   278       vdeImsItem_t *imsItem;
       
   279       vdeImb_t *imb;
       
   280       int width, height;
       
   281 
       
   282      if (vdeImsGetReference(store, VDEIMS_REF_LATEST, 0, &imsItem) < 0) {
       
   283         deb("dvpGetAndDecodeVideoPacketContents: ERROR - vdeImsGetReference "
       
   284            "failed.\n");
       
   285         goto unexpectedError;
       
   286      }
       
   287 
       
   288       /* If no reference frame available */
       
   289       if (!imsItem) {
       
   290          /* Treat the situation like a decoding error.*/
       
   291          deb("dvpGetAndDecodeVideoPacketContents: Warning - no reference frame "
       
   292             "available.\n");
       
   293          goto headerFailure;
       
   294       }
       
   295 
       
   296       if (vdeImsStoreItemToImageBuffer(imsItem, &imb) < 0) {
       
   297          deb("dvpGetAndDecodeVideoPacketContents: ERROR - vdeImsStoreItemToImageBuffer "
       
   298             "failed.\n");
       
   299          goto unexpectedError;
       
   300       }
       
   301 
       
   302       if (vdeImbYUV(imb, &inOutParam->refY, &inOutParam->refU, 
       
   303          &inOutParam->refV, &width, &height) < 0) {
       
   304          deb("dvpGetAndDecodeVideoPacketContents: ERROR - vdeImbYUV "
       
   305             "failed.\n");
       
   306          goto unexpectedError;
       
   307       }
       
   308    }
       
   309 
       
   310    xPosInMBs = (inOutParam->currMBNum % inParam->pictParam->numMBsInMBLine);
       
   311    yPosInMBs = (inOutParam->currMBNum / inParam->pictParam->numMBsInMBLine);
       
   312 
       
   313    /* if VOP header corrupted and first VP -> exit */
       
   314    if(inParam->fVOPHeaderCorrupted && inOutParam->currMBNum==0) {
       
   315       fSegmentCorrupted = 1;
       
   316       goto exitWhenVOPHeaderCorrupted;
       
   317    }
       
   318 
       
   319    /* in case of an I-VOP */
       
   320    if (inParam->pictParam->pictureType == VDX_VOP_TYPE_I) {
       
   321       dimbi.inBuffer = inBuffer;
       
   322       dimbi.outBuffer = outBuffer;
       
   323       dimbi.bufEdit = bufEdit;
       
   324       dimbi.iColorEffect = colorEffect;
       
   325       dimbi.iGetDecodedFrame = getDecodedFrame;
       
   326 
       
   327       dimbi.pictParam = inParam->pictParam;
       
   328 
       
   329       dimbi.xPosInMBs = xPosInMBs;
       
   330       dimbi.yPosInMBs = yPosInMBs;
       
   331 
       
   332       dimbio.currMBNum = inOutParam->currMBNum;
       
   333       dimbio.currMBNumInVP = 0;
       
   334 
       
   335      dimbio.aicData = inOutParam->aicData;
       
   336 
       
   337       dimbio.fCodedMBs = inOutParam->fCodedMBs;
       
   338       dimbio.numOfCodedMBs = inOutParam->numOfCodedMBs;
       
   339       dimbio.quant = inOutParam->quant;
       
   340      
       
   341       /* YUV pointers */
       
   342      {
       
   343       int32 yOffset, uvOffset;
       
   344    
       
   345       yOffset = inParam->pictParam->lumMemWidth * dimbi.yPosInMBs + dimbi.xPosInMBs;
       
   346       uvOffset = (inParam->pictParam->lumMemWidth >> 1) * dimbi.yPosInMBs + dimbi.xPosInMBs;
       
   347 
       
   348       if ( inOutParam->currPY != NULL )
       
   349         {
       
   350           dimbio.yMBInFrame = inOutParam->currPY + (yOffset << 4);
       
   351           dimbio.uBlockInFrame = inOutParam->currPU + (uvOffset << 3);
       
   352           dimbio.vBlockInFrame = inOutParam->currPV + (uvOffset << 3);
       
   353         }
       
   354       else
       
   355         {
       
   356           dimbio.yMBInFrame = NULL;
       
   357           dimbio.uBlockInFrame = NULL;
       
   358           dimbio.vBlockInFrame = NULL;
       
   359         }
       
   360      }
       
   361    }
       
   362    /* in case of a P-VOP */
       
   363    else {
       
   364       dpmbi.inBuffer = inBuffer;
       
   365       dpmbi.outBuffer = outBuffer;
       
   366       dpmbi.bufEdit = bufEdit;
       
   367       dpmbi.iColorEffect = colorEffect;
       
   368       dpmbi.iGetDecodedFrame = getDecodedFrame;
       
   369 
       
   370       dpmbi.pictParam = inParam->pictParam;
       
   371 
       
   372       dpmbi.xPosInMBs = xPosInMBs;
       
   373       dpmbi.yPosInMBs = yPosInMBs;
       
   374 
       
   375       dpmbi.refY = inOutParam->refY;
       
   376       dpmbi.refU = inOutParam->refU;
       
   377       dpmbi.refV = inOutParam->refV;
       
   378       dpmbi.currPY = inOutParam->currPY;
       
   379       dpmbi.currPU = inOutParam->currPU;
       
   380       dpmbi.currPV = inOutParam->currPV;
       
   381 
       
   382       dpmbio.currMBNum = inOutParam->currMBNum;
       
   383       dpmbio.currMBNumInVP = 0;
       
   384 
       
   385       dpmbio.fCodedMBs = inOutParam->fCodedMBs;
       
   386       dpmbio.numOfCodedMBs = inOutParam->numOfCodedMBs;
       
   387       dpmbio.quant = inOutParam->quant;
       
   388 
       
   389      dpmbio.aicData = inOutParam->aicData;
       
   390 
       
   391      dpmbio.mvcData = inOutParam->mvcData;
       
   392       dpmbio.diffMB = pDiffMB;
       
   393 
       
   394       /* YUV pointers */
       
   395      {
       
   396       int32 yOffset, uvOffset;
       
   397    
       
   398       yOffset = inParam->pictParam->lumMemWidth * dpmbi.yPosInMBs + dpmbi.xPosInMBs;
       
   399       uvOffset = (inParam->pictParam->lumMemWidth >> 1) * dpmbi.yPosInMBs + dpmbi.xPosInMBs;
       
   400 
       
   401       if ( inOutParam->currPY != NULL )
       
   402         {
       
   403           dpmbio.yMBInFrame = inOutParam->currPY + (yOffset << 4);
       
   404           dpmbio.uBlockInFrame = inOutParam->currPU + (uvOffset << 3);
       
   405           dpmbio.vBlockInFrame = inOutParam->currPV + (uvOffset << 3);
       
   406         }
       
   407       else
       
   408         {
       
   409           dimbio.yMBInFrame = NULL;
       
   410           dimbio.uBlockInFrame = NULL;
       
   411           dimbio.vBlockInFrame = NULL;
       
   412         }
       
   413      }
       
   414    }
       
   415 
       
   416    /* Decode multiple Macroblocks until a resync_marker is found or error occurs */
       
   417    while (inParam->pictParam->numMBsInGOB != inOutParam->currMBNum && 
       
   418          sncCode != SNC_VIDPACK && sncCode != SNC_VOP) {
       
   419 
       
   420        /* MVE */
       
   421        hTranscoder->BeginOneMB((inParam->pictParam->pictureType == VDX_VOP_TYPE_I) ? dimbio.currMBNum : dpmbio.currMBNum );
       
   422        
       
   423      /* decode an I-frame MB */
       
   424       if (inParam->pictParam->pictureType == VDX_VOP_TYPE_I) {
       
   425          
       
   426          if(inParam->pictParam->data_partitioned) {
       
   427 
       
   428             dmbRetValue = dmbsGetAndDecodeIMBsDataPartitioned(&dimbi, &dimbio,
       
   429                inOutParam->quantParams, hTranscoder);
       
   430 
       
   431             if (dmbRetValue < 0)
       
   432                goto unexpectedError;
       
   433             
       
   434             inOutParam->currMBNum = dimbio.currMBNum;
       
   435 
       
   436             /* Video Packet corrupted */
       
   437             if ( fSegmentCorrupted )
       
   438                break;
       
   439 
       
   440          } else {
       
   441 
       
   442             dmbRetValue = dmbGetAndDecodeIFrameMB(&dimbi, &dimbio, 1, hTranscoder);
       
   443             
       
   444             if (dmbRetValue < 0)
       
   445                goto unexpectedError;
       
   446             else if (dmbRetValue == DMB_BIT_ERR ) {
       
   447                /* Video Packet corrupted */
       
   448                fSegmentCorrupted = 1;
       
   449                break;
       
   450             }
       
   451 
       
   452             /* Store quantizer */
       
   453             inOutParam->quantParams[dimbio.currMBNum] = dimbio.quant;
       
   454 
       
   455             /* increment the frame pointers and MB counters */
       
   456             dimbio.currMBNum++;
       
   457             dimbio.currMBNumInVP++;
       
   458 
       
   459             if ( dimbio.yMBInFrame != NULL )
       
   460             {
       
   461                 dimbio.yMBInFrame += 16;
       
   462                 dimbio.uBlockInFrame += 8;
       
   463                 dimbio.vBlockInFrame += 8;
       
   464             }
       
   465             dimbi.xPosInMBs++;
       
   466 
       
   467             if (dimbi.xPosInMBs == inParam->pictParam->numMBsInMBLine) {
       
   468               if ( dimbio.yMBInFrame != NULL )
       
   469                 {
       
   470                    dimbio.yMBInFrame += 15 * inParam->pictParam->lumMemWidth;
       
   471                    dimbio.uBlockInFrame += 7 * (inParam->pictParam->lumMemWidth >> 1);
       
   472                    dimbio.vBlockInFrame += 7 * (inParam->pictParam->lumMemWidth >> 1);
       
   473                 }
       
   474                dimbi.xPosInMBs = 0;
       
   475                dimbi.yPosInMBs++;
       
   476             }
       
   477 
       
   478             inOutParam->currMBNum = dimbio.currMBNum;
       
   479          }
       
   480 
       
   481          /* decode a P-frame MB */
       
   482      } else {
       
   483 
       
   484          if(inParam->pictParam->data_partitioned) {
       
   485 
       
   486             dmbRetValue = dmbsGetAndDecodePMBsDataPartitioned(&dpmbi, &dpmbio,
       
   487                inOutParam->quantParams, hTranscoder);
       
   488 
       
   489             if (dmbRetValue < 0)
       
   490                goto unexpectedError;
       
   491 
       
   492             inOutParam->currMBNum = dpmbio.currMBNum;
       
   493             lastMBNumInVP = dpmbio.currMBNumInVP;
       
   494 
       
   495             /* Video Packet corrupted */
       
   496             if ( fSegmentCorrupted )
       
   497                break;
       
   498 
       
   499          } else {
       
   500 
       
   501             dmbRetValue = dmbGetAndDecodePFrameMB(&dpmbi, &dpmbio, 1, hTranscoder);
       
   502             
       
   503             if (dmbRetValue < 0)
       
   504                goto unexpectedError;
       
   505             else if (dmbRetValue == DMB_BIT_ERR ) {
       
   506                /* Video Packet corrupted */
       
   507                fSegmentCorrupted = 1;
       
   508                break;
       
   509             }
       
   510             
       
   511             /* Store quantizer */
       
   512             inOutParam->quantParams[dpmbio.currMBNum] = dpmbio.quant;
       
   513 
       
   514             /* increment the frame pointers and MB counters */
       
   515             dpmbio.currMBNum++;
       
   516             dpmbio.currMBNumInVP++;
       
   517 
       
   518             if ( dpmbio.yMBInFrame != NULL )
       
   519               {
       
   520                 dpmbio.yMBInFrame += 16;
       
   521                 dpmbio.uBlockInFrame += 8;
       
   522                 dpmbio.vBlockInFrame += 8;
       
   523               }
       
   524             dpmbi.xPosInMBs++;
       
   525 
       
   526             if (dpmbi.xPosInMBs == inParam->pictParam->numMBsInMBLine) {
       
   527                 if ( dpmbio.yMBInFrame != NULL )
       
   528                   {
       
   529                    dpmbio.yMBInFrame += 15 * inParam->pictParam->lumMemWidth;
       
   530                    dpmbio.uBlockInFrame += 7 * (inParam->pictParam->lumMemWidth >> 1);
       
   531                    dpmbio.vBlockInFrame += 7 * (inParam->pictParam->lumMemWidth >> 1);
       
   532                   }
       
   533                dpmbi.xPosInMBs = 0;
       
   534                dpmbi.yPosInMBs++;
       
   535             }
       
   536 
       
   537             inOutParam->currMBNum = dpmbio.currMBNum;
       
   538          }
       
   539      }
       
   540 
       
   541      /* check for a resync_marker */
       
   542      sncCode = sncCheckMpegSync(inBuffer, inParam->pictParam->fcode_forward, &error);
       
   543      
       
   544      /* If sncCheckMpegSync failed */
       
   545      if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
       
   546          deb1p("dvpGetAndDecodeVideoPacketContents: ERROR - sncCheckSync returned %d.\n", error);
       
   547          goto unexpectedError;
       
   548          
       
   549      } else 
       
   550          /* If buffer ends (in one-frame-per-one-buffer case) */
       
   551          if (sncCode == SNC_EOB ||
       
   552              sncCode == SNC_STUFFING ||
       
   553              error == ERR_BIB_NOT_ENOUGH_DATA) {
       
   554              break; 
       
   555          }
       
   556      
       
   557    }
       
   558 
       
   559 
       
   560 // <--
       
   561 
       
   562    inOutParam->numOfCodedMBs = (inParam->pictParam->pictureType != VDX_VOP_TYPE_I) ? 
       
   563         dpmbio.numOfCodedMBs : dimbio.numOfCodedMBs;
       
   564    
       
   565    if (fSegmentCorrupted) {
       
   566       u_int32 nextVPBitPos;
       
   567 
       
   568       /* find the next resync marker, to get the number of MBs in the current VP */
       
   569       sncCode = sncRewindAndSeekNewMPEGSync(-1, inBuffer, inParam->pictParam->fcode_forward, &error);
       
   570       if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
       
   571          goto unexpectedError;
       
   572       } else if (sncCode == SNC_EOB) {
       
   573          goto exitFunction;
       
   574       }
       
   575 
       
   576       nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   577 
       
   578       /* if the lastMBNumInVP was not yet read */
       
   579       if (inParam->pictParam->pictureType == VDX_VOP_TYPE_I || 
       
   580          !inParam->pictParam->data_partitioned || 
       
   581          lastMBNumInVP == 0) { 
       
   582 
       
   583          /* if VP header is found: read it, and get last MB number in current vop */
       
   584          if (sncCode == SNC_VIDPACK) {
       
   585             vdxVideoPacketHeader_t header;
       
   586             vdxGetVideoPacketHeaderInputParam_t vdxParam;
       
   587             int retValue;
       
   588             
       
   589             vdxParam.fcode_forward = inParam->pictParam->fcode_forward;
       
   590             vdxParam.time_increment_resolution = inParam->pictParam->time_increment_resolution;
       
   591             vdxParam.numOfMBs = inParam->pictParam->numMBsInGOB;
       
   592             
       
   593             retValue = vdxGetVideoPacketHeader(inParam->inBuffer, &vdxParam, &header, &bitErrorIndication);
       
   594             if (retValue < 0) {
       
   595                goto unexpectedError;
       
   596             } else if (retValue == VDX_OK_BUT_BIT_ERROR) {
       
   597                /* If bit error occurred */
       
   598                goto headerFailure;
       
   599             }
       
   600             
       
   601             /* rewind the bits to the beginning of the VP header */
       
   602             bibRewindBits(bibNumberOfFlushedBits(inParam->inBuffer) - nextVPBitPos,
       
   603                inParam->inBuffer, &error);
       
   604             
       
   605             lastMBNumInVP = header.currMBNum;
       
   606             
       
   607          } else {
       
   608             lastMBNumInVP = inParam->pictParam->numMBsInGOB;
       
   609          }
       
   610       }
       
   611 
       
   612       /* if possibly the next VP header is damaged (it gives MB index which is smaller than the start of the current one */
       
   613       if (lastMBNumInVP <= startMB || lastMBNumInVP > inParam->pictParam->numMBsInGOB)
       
   614          goto exitFunction;
       
   615 
       
   616       /* if the MB counting due to error overran the next VP header's value */
       
   617       if (inOutParam->currMBNum > lastMBNumInVP)
       
   618          inOutParam->currMBNum = VDC_MAX(lastMBNumInVP-3,startMB);
       
   619       
       
   620       /* if not all the MBs have been predicted due to error */
       
   621       else if (inOutParam->currMBNum < lastMBNumInVP)
       
   622          inOutParam->currMBNum = VDC_MAX(inOutParam->currMBNum-1,startMB);
       
   623 
       
   624       
       
   625       inOutParam->currMBNum = lastMBNumInVP;
       
   626    }
       
   627 
       
   628    exitFunction:
       
   629 
       
   630 
       
   631    exitWhenVOPHeaderCorrupted:
       
   632 
       
   633    if (!fSegmentCorrupted) {
       
   634       SOH_DEALLOC(pDiffMB);
       
   635       return DGOB_OK;
       
   636    }
       
   637    else {
       
   638       SOH_DEALLOC(pDiffMB);
       
   639       return DGOB_OK_BUT_BIT_ERROR;
       
   640    }
       
   641 
       
   642    headerFailure:
       
   643       SOH_DEALLOC(pDiffMB);
       
   644       sncRewindAndSeekNewMPEGSync(-1, inBuffer, 0, &error);
       
   645       if (error && error != ERR_BIB_NOT_ENOUGH_DATA)
       
   646          return DGOB_ERR;
       
   647       return DGOB_OK_BUT_BIT_ERROR;
       
   648 
       
   649    unexpectedError:
       
   650       SOH_DEALLOC(pDiffMB);
       
   651       return DGOB_ERR;
       
   652 }
       
   653 // End of File