videoeditorengine/h263decoder/src/decmbs_dp_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 * MB decoding in data partitioned mode (MPEG-4).
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 /*
       
    23  * Includes 
       
    24  */
       
    25 #include "h263dConfig.h"
       
    26 #include "decmbs.h"
       
    27 #include "decmbdct.h"
       
    28 #include "viddemux.h"
       
    29 #include "errcodes.h"
       
    30 #include "sync.h"
       
    31 #include "mpegcons.h"
       
    32 #include "debug.h"
       
    33 /* MVE */
       
    34 #include "MPEG4Transcoder.h"
       
    35 
       
    36 /*
       
    37  * Local functions
       
    38  */
       
    39 
       
    40 
       
    41 /*
       
    42  * Global functions
       
    43  */
       
    44 
       
    45 /* {{-output"dmbsGetAndDecodeIMBsDataPartitioned.txt"}} */
       
    46 /*
       
    47  * dmbsGetAndDecodeIMBsDataPartitioned
       
    48  *    
       
    49  *
       
    50  * Parameters:
       
    51  *    inParam                    input parameters
       
    52  *    inOutParam                 input/output parameters, these parameters
       
    53  *                               may be modified in the function
       
    54  *
       
    55  * Function:
       
    56  *    This function gets and decodes the MBs of a data partitioned 
       
    57  *    Video Packet in an Intra Frame.
       
    58  *
       
    59  * Returns:
       
    60  *    >= 0                       the function was successful
       
    61  *    < 0                        an error occured
       
    62  *
       
    63  */
       
    64 
       
    65 int dmbsGetAndDecodeIMBsDataPartitioned(
       
    66    dmbIFrameMBInParam_t *inParam,
       
    67    dmbIFrameMBInOutParam_t *inOutParam,
       
    68    int *quantParams, CMPEG4Transcoder *hTranscoder)
       
    69 /* {{-output"dmbsGetAndDecodeIMBsDataPartitioned.txt"}} */
       
    70 {
       
    71    int retValue = DMBS_OK;
       
    72 
       
    73    int currMBNumInVP, lastMBNum, numMBsInVP, numCorrectMBs;
       
    74    int yWidth = inParam->pictParam->lumMemWidth;
       
    75    int uvWidth = yWidth / 2;
       
    76    int bitErrorIndication = 0, ret = 0, sncCode, bitsGot, bitErrorsInPart1 = 0;
       
    77    u_int32 startVPBitPos = 0, 
       
    78          errorBitPos = 0,
       
    79          backwards_errorBitPos = 0,
       
    80          nextVPBitPos = 0,
       
    81          startBlockDataBitPos = 0,
       
    82          DCMarkerBitPos = 0;
       
    83    u_char fPart1Error=0, fPart2Error=0, fBlockError=0;
       
    84    int16 error = 0;
       
    85 #ifdef DEBUG_OUTPUT
       
    86    FILE *rvlc_stat;
       
    87 #endif
       
    88 
       
    89    dlst_t MBList;
       
    90    vdxIMBListItem_t *MBinstance;
       
    91 
       
    92    vdxGetDataPartitionedIMBLayerInputParam_t vdxDPIn;
       
    93    dmdMPEGIParam_t dmdIn;
       
    94    
       
    95    if (dlstOpen(&MBList) < 0)
       
    96       return DMBS_ERR;
       
    97 
       
    98    /* mark the bit position at the beginning of the VP */
       
    99    startVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   100 
       
   101    /* 
       
   102     * read the first partition: DC coefficients, etc. 
       
   103     */
       
   104 
       
   105    vdxDPIn.intra_dc_vlc_thr = inParam->pictParam->intra_dc_vlc_thr;
       
   106    vdxDPIn.quant = inOutParam->quant;
       
   107 
       
   108    /* MVE */
       
   109    ret = vdxGetDataPartitionedIMBLayer_Part1(inParam->inBuffer, inParam->outBuffer, 
       
   110          inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), 
       
   111          &(inOutParam->StartBitIndex), hTranscoder, &vdxDPIn, &MBList, 
       
   112          &bitErrorIndication);
       
   113 
       
   114    bitErrorsInPart1 = bitErrorIndication;
       
   115    if (ret < 0) {
       
   116        retValue = DMBS_ERR;
       
   117        goto exitFunction;
       
   118    }
       
   119    else if (ret == VDX_OK_BUT_BIT_ERROR) {
       
   120 
       
   121       fPart1Error = 1;
       
   122       bitErrorIndication = 0;
       
   123       deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - DC partition error.\n");
       
   124    } else {
       
   125       DCMarkerBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   126    }
       
   127 
       
   128    /* read the next VP header to determine the number of MBs in this VP */
       
   129    if ( fPart1Error ) {
       
   130        /* Stop decoding this segment */
       
   131       goto exitFunction;
       
   132    }
       
   133    else {
       
   134       sncCode = sncRewindAndSeekNewMPEGSync( 1,
       
   135           inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
       
   136    }
       
   137    if (error) {
       
   138       if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
       
   139       else { 
       
   140           retValue = DMBS_ERR;
       
   141           goto exitFunction;          
       
   142       }
       
   143    }
       
   144    
       
   145    nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   146    
       
   147    if (sncCode == SNC_VIDPACK) {
       
   148       
       
   149       vdxVideoPacketHeader_t header;
       
   150       vdxGetVideoPacketHeaderInputParam_t vdxParam;
       
   151       int retValue;
       
   152       
       
   153       vdxParam.fcode_forward = inParam->pictParam->fcode_forward;
       
   154       vdxParam.time_increment_resolution = inParam->pictParam->time_increment_resolution;
       
   155       vdxParam.numOfMBs = inParam->pictParam->numMBsInGOB;
       
   156       
       
   157       retValue = vdxGetVideoPacketHeader(inParam->inBuffer, &vdxParam, &header, &bitErrorIndication);
       
   158       if (retValue < 0) {
       
   159           retValue = DMBS_ERR;
       
   160           goto exitFunction;      
       
   161       } else if (retValue == VDX_OK_BUT_BIT_ERROR) {
       
   162          /* If bit error occurred */
       
   163          deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - VP Header error.\n");
       
   164          bitErrorIndication = 0;
       
   165          lastMBNum = 0;
       
   166       } else {    
       
   167          lastMBNum = header.currMBNum;
       
   168       }
       
   169    } else {
       
   170       lastMBNum = inParam->pictParam->numMBsInGOB;
       
   171    }
       
   172 
       
   173    /* rewind the bits to the beginning of the current VP data */
       
   174    bibRewindBits(bibNumberOfFlushedBits(inParam->inBuffer) - (fPart1Error ? errorBitPos : DCMarkerBitPos),
       
   175       inParam->inBuffer, &error);
       
   176       
       
   177    if (fPart1Error) {
       
   178       /* Seek the DC_MARKER */
       
   179       if ((sncSeekBitPattern(inParam->inBuffer, MP4_DC_MARKER, MP4_DC_MARKER_LENGTH, &error) != SNC_PATTERN) ||
       
   180          (bibNumberOfFlushedBits(inParam->inBuffer) >= nextVPBitPos)) {
       
   181          
       
   182          /* rewind the bits to the beginning of the current VP data */
       
   183          bibRewindBits( VDC_MIN(bibNumberOfRewBits(inParam->inBuffer), (bibNumberOfFlushedBits(inParam->inBuffer) - startVPBitPos)),
       
   184             inParam->inBuffer, &error);
       
   185 
       
   186          deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Part1Error && No DC marker found.\n");
       
   187          goto exitFunction;
       
   188       }
       
   189    } 
       
   190 
       
   191    if ((lastMBNum <= inOutParam->currMBNum) ||
       
   192       (lastMBNum > inParam->pictParam->numMBsInGOB) ||
       
   193       (sncCode == SNC_EOB)) {
       
   194       numMBsInVP = MBList.numItems;
       
   195       if (fPart1Error) fPart2Error = 1;
       
   196    } else 
       
   197       numMBsInVP = lastMBNum - inOutParam->currMBNum;
       
   198 
       
   199    if (numMBsInVP != MBList.numItems || fPart1Error) {
       
   200       deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - MB list length != num MBs.\n");
       
   201       if ( fPart1Error || bitErrorsInPart1 ) {
       
   202          /* Discard few MBs from the end of the list, 
       
   203             since there are errors somewhere in the bitstream. 
       
   204             If the list is short due to the missing packet, 
       
   205             all the read MBs are likely to be OK and there is no
       
   206             need to discard them */
       
   207          dlstTail(&MBList, (void **) &MBinstance);
       
   208          dlstRemove(&MBList, (void **) &MBinstance);
       
   209          free( MBinstance );
       
   210          if (numMBsInVP > MBList.numItems ) {
       
   211             /* Take still one away */
       
   212             dlstTail(&MBList, (void **) &MBinstance);
       
   213             dlstRemove(&MBList, (void **) &MBinstance);
       
   214             free( MBinstance );
       
   215          }
       
   216       }
       
   217       if (numMBsInVP < MBList.numItems ) {
       
   218          /* Discard all the extra MBs from the end of the list + 2 just to be sure, 
       
   219             since there are errors somewhere in the bitstream */
       
   220          while ( MBList.numItems > VDC_MAX(numMBsInVP-2,0) ) {
       
   221             dlstTail(&MBList, (void **) &MBinstance);
       
   222             dlstRemove(&MBList, (void **) &MBinstance);
       
   223             free( MBinstance );
       
   224          }
       
   225       }
       
   226       fPart1Error = 1;
       
   227       errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   228    }
       
   229 
       
   230    /* Flush the DC_Marker */
       
   231    bibFlushBits(MP4_DC_MARKER_LENGTH, inParam->inBuffer, &bitsGot, &bitErrorIndication, &error);
       
   232    if (error)
       
   233    {
       
   234        retValue = DMBS_ERR;
       
   235        goto exitFunction;        
       
   236    }
       
   237 
       
   238    /*
       
   239     * Read the second partition header: cpby, ac_pred_flag 
       
   240     */
       
   241 
       
   242    ret = vdxGetDataPartitionedIMBLayer_Part2(inParam->inBuffer, inParam->outBuffer, 
       
   243          inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), &(inOutParam->StartBitIndex),
       
   244          &MBList, numMBsInVP, &bitErrorIndication);
       
   245    if (ret < 0) {
       
   246       retValue = DMBS_ERR;
       
   247       goto exitFunction;
       
   248    }
       
   249    else if (ret == VDX_OK_BUT_BIT_ERROR) {
       
   250         fPart2Error = 1;
       
   251         deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Part2Error.\n");
       
   252         /* Stop decoding this segment */
       
   253         goto exitFunction;
       
   254    }
       
   255 
       
   256    /* common input parameters for all blocks */
       
   257    dmdIn.aicData = inOutParam->aicData;
       
   258 
       
   259    /* MVE */
       
   260    dmdIn.inBuffer = inParam->inBuffer;
       
   261    dmdIn.outBuffer = inParam->outBuffer;
       
   262    dmdIn.bufEdit = inParam->bufEdit;
       
   263    dmdIn.iColorEffect = inParam->iColorEffect;
       
   264    dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
       
   265 
       
   266    dmdIn.yWidth = inParam->pictParam->lumMemWidth;
       
   267    dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
       
   268    dmdIn.pictureType = inParam->pictParam->pictureType;
       
   269 
       
   270    /*
       
   271     * Read block data partition in forward direction 
       
   272     */
       
   273 
       
   274    startBlockDataBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   275 
       
   276    /* set block pointers to the beginning of the VP */   
       
   277    dmdIn.yMBInFrame = inOutParam->yMBInFrame;
       
   278    dmdIn.uBlockInFrame = inOutParam->uBlockInFrame;
       
   279    dmdIn.vBlockInFrame = inOutParam->vBlockInFrame;
       
   280 
       
   281    dmdIn.xPosInMBs = inParam->xPosInMBs;
       
   282    dmdIn.yPosInMBs = inParam->yPosInMBs;
       
   283 
       
   284    dmdIn.currMBNum = inOutParam->currMBNum;
       
   285 
       
   286    /* get the first MB of the list */
       
   287    dlstHead(&MBList, (void **) &MBinstance);
       
   288 
       
   289    for (currMBNumInVP = 0; currMBNumInVP < numMBsInVP; currMBNumInVP++) {
       
   290          
       
   291          /* if MBList is shorter then the number of MBs in the VP */
       
   292          if (MBinstance == NULL) {
       
   293              deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - MB list < num MBs.\n");
       
   294              goto exitFunction;
       
   295          }
       
   296          
       
   297          /* header params. If partition 2 or AC partition contains errors, no bits are read any more 
       
   298          from the bitstream, but the blocks are reconstructed based only on DC values */
       
   299          dmdIn.cbpy = (fPart2Error || fBlockError) ? 0 : MBinstance->cbpy;
       
   300          dmdIn.cbpc = (fPart2Error || fBlockError) ? 0 : MBinstance->cbpc;
       
   301          dmdIn.quant = MBinstance->quant;
       
   302          
       
   303          /* AC/DC prediction params */
       
   304          dmdIn.switched = MBinstance->switched;
       
   305          
       
   306          dmdIn.fTopOfVP = (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine);
       
   307          dmdIn.fLeftOfVP = (u_char) (currMBNumInVP == 0);
       
   308          dmdIn.fBBlockOut = (u_char) (currMBNumInVP <= inParam->pictParam->numMBsInMBLine);
       
   309          
       
   310          inOutParam->aicData->ACpred_flag = (u_char) ((fPart2Error || fBlockError) ? 0 : MBinstance->ac_pred_flag);
       
   311          
       
   312          /* error resilience params */
       
   313          dmdIn.data_partitioned = 1;
       
   314          dmdIn.DC = MBinstance->DC;
       
   315          
       
   316          dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;
       
   317          dmdIn.vlc_dec_direction = 0;
       
   318          
       
   319          /* MVE */
       
   320          hTranscoder->OneIMBDataStartedDataPartitioned(MBinstance, &MBList, currMBNumInVP, dmdIn.currMBNum);
       
   321          
       
   322          /* get the next macroblock data */
       
   323          ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
       
   324          
       
   325          if ( ret < 0 ) {
       
   326              retValue = DMBS_ERR;
       
   327              goto exitFunction;         
       
   328          }
       
   329       else if ( ret == DMD_BIT_ERR ) {
       
   330          if (fPart1Error) {
       
   331             deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - IMB Blocks decoding error && Part1Error.\n");
       
   332             goto exitFunction;
       
   333          } else {
       
   334             deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - IMB Blocks decoding error. Using DCs only.\n");
       
   335             fBlockError = 1;
       
   336          }
       
   337       }
       
   338 
       
   339       /* Store quantizer */
       
   340       quantParams[dmdIn.currMBNum] = MBinstance->quant;
       
   341 
       
   342       /* increment the block pointers and counters */
       
   343       dmdIn.currMBNum++;
       
   344       if ( dmdIn.yMBInFrame != NULL )
       
   345         {
       
   346             dmdIn.yMBInFrame += 16;
       
   347             dmdIn.uBlockInFrame += 8;
       
   348             dmdIn.vBlockInFrame += 8;
       
   349         }
       
   350       dmdIn.xPosInMBs++;
       
   351 
       
   352       if (dmdIn.xPosInMBs == inParam->pictParam->numMBsInMBLine) {
       
   353          if ( dmdIn.yMBInFrame )
       
   354             {
       
   355              dmdIn.yMBInFrame += 15 * yWidth;
       
   356              dmdIn.uBlockInFrame += 7 * uvWidth;
       
   357              dmdIn.vBlockInFrame += 7 * uvWidth;
       
   358             }
       
   359          dmdIn.xPosInMBs = 0;
       
   360          dmdIn.yPosInMBs++;
       
   361          if (dmdIn.yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
       
   362             break;
       
   363       }
       
   364       
       
   365       dlstNext(&MBList, (void **) &MBinstance);
       
   366    }
       
   367 
       
   368    if (!fPart1Error && !fPart2Error && !fBlockError) {
       
   369          if (sncCode == SNC_EOB) {
       
   370              inOutParam->currMBNum += numMBsInVP;
       
   371              goto exitFunction;
       
   372          } else {
       
   373              
       
   374              sncCode = sncCheckMpegSync(inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
       
   375              if (sncCode == SNC_NO_SYNC) {
       
   376                  deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - After block data no start code found.\n");
       
   377                  if (lastMBNum != 0) 
       
   378                      fBlockError = 1;
       
   379              }
       
   380          }
       
   381    }
       
   382 
       
   383    /*
       
   384     * In case of error, read block data partition in backward direction 
       
   385     */
       
   386 
       
   387    /* WARNING: backwards decoding of INTRA frame RVLC is disabled by setting the VP size
       
   388       higher then 10. The useful VP sizes used in low bitrates allow max. 8-10 MBs per
       
   389      VP, but in average 3-5 MBs. With this small amount the backwards decoding always
       
   390      causes overlap of the MB counter, and the overlapped MBs must be discarded. So the
       
   391      RVLC doesn't have any use. */
       
   392 
       
   393    if (!fPart2Error && fBlockError && inParam->pictParam->reversible_vlc && (numMBsInVP >= 10)) {
       
   394       numCorrectMBs = currMBNumInVP;
       
   395 
       
   396 #ifdef DEBUG_OUTPUT
       
   397       {
       
   398          int bitPos[6], xpos, ypos, mbnum;
       
   399          
       
   400          rvlc_stat = fopen("rvlc.log", "a+t");
       
   401          
       
   402          fprintf(rvlc_stat, "I-VOP: (frame)(MB_first):%3d  (MB_last):%3d\n", 
       
   403             inOutParam->currMBNum, (inOutParam->currMBNum + numMBsInVP-1));
       
   404          
       
   405          for (xpos = inParam->xPosInMBs, ypos = inParam->yPosInMBs, mbnum = 0; mbnum < numCorrectMBs; mbnum++, xpos++) {
       
   406             
       
   407             if (xpos / inParam->pictParam->numMBsInMBLine)
       
   408                xpos = 0, ypos++;
       
   409 
       
   410             fprintf(rvlc_stat, "fw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
       
   411                inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
       
   412          }
       
   413       }
       
   414 #endif
       
   415 
       
   416          /* find next VP header (end of MB block data of this VP) */
       
   417       sncCode = sncRewindAndSeekNewMPEGSync(errorBitPos-startBlockDataBitPos, inParam->inBuffer,
       
   418          inParam->pictParam->fcode_forward, &error);      
       
   419       if (error) {
       
   420           if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
       
   421           else { 
       
   422               retValue = DMBS_ERR;
       
   423               goto exitFunction;              
       
   424           }
       
   425       }
       
   426 
       
   427       if (sncCode == SNC_EOB) {
       
   428          inOutParam->currMBNum += numMBsInVP;
       
   429          goto exitFunction;
       
   430       }
       
   431 
       
   432       nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   433 
       
   434       backwards_errorBitPos = startBlockDataBitPos;
       
   435 
       
   436       /* rewind the stuffing bits */
       
   437       if (sncCode != SNC_NO_SYNC || !(nextVPBitPos % 8)) {
       
   438          if(sncRewindStuffing(inParam->inBuffer, &error) != SNC_PATTERN) {
       
   439             deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, stuffing not found.\n");
       
   440             inOutParam->currMBNum = dmdIn.currMBNum;
       
   441             goto exitFunction;
       
   442          }
       
   443       }
       
   444 
       
   445       /* set the block pointers and counters to the end of the VP */
       
   446       if ( dmdIn.yMBInFrame != NULL )
       
   447         {
       
   448           dmdIn.yMBInFrame = inOutParam->yMBInFrame + 16 * (numMBsInVP-1);
       
   449           dmdIn.uBlockInFrame = inOutParam->uBlockInFrame + 8 * (numMBsInVP-1);
       
   450           dmdIn.vBlockInFrame = inOutParam->vBlockInFrame + 8 * (numMBsInVP-1);
       
   451         }
       
   452       else
       
   453         {
       
   454             dmdIn.yMBInFrame = dmdIn.uBlockInFrame = dmdIn.vBlockInFrame = NULL;
       
   455         }
       
   456       dmdIn.xPosInMBs = inParam->xPosInMBs + (numMBsInVP-1);
       
   457       dmdIn.yPosInMBs = inParam->yPosInMBs;
       
   458 
       
   459       if (dmdIn.xPosInMBs / inParam->pictParam->numMBsInMBLine) {
       
   460 
       
   461          int numFullLines = dmdIn.xPosInMBs / inParam->pictParam->numMBsInMBLine;
       
   462 
       
   463          if ( dmdIn.yMBInFrame != NULL )
       
   464             {
       
   465                 dmdIn.yMBInFrame += 15 * yWidth * numFullLines;
       
   466                 dmdIn.uBlockInFrame += 7 * uvWidth * numFullLines;
       
   467                 dmdIn.vBlockInFrame += 7 * uvWidth * numFullLines;
       
   468             }
       
   469          dmdIn.xPosInMBs = dmdIn.xPosInMBs % inParam->pictParam->numMBsInMBLine;
       
   470          dmdIn.yPosInMBs+=numFullLines;
       
   471       }
       
   472 
       
   473       dmdIn.currMBNum = inOutParam->currMBNum + (numMBsInVP-1);
       
   474 
       
   475       /* get the last MB of the list */
       
   476       dlstTail(&MBList, (void **) &MBinstance);
       
   477 
       
   478       for (currMBNumInVP = numMBsInVP-1; currMBNumInVP >= 0; currMBNumInVP--) {
       
   479 
       
   480          /* header params */
       
   481          dmdIn.cbpy = MBinstance->cbpy;
       
   482          dmdIn.cbpc = MBinstance->cbpc;
       
   483          dmdIn.quant = MBinstance->quant;
       
   484 
       
   485          /* AC/DC prediction params */
       
   486          dmdIn.switched = MBinstance->switched;
       
   487 
       
   488          dmdIn.fTopOfVP = (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine);
       
   489          dmdIn.fLeftOfVP = (u_char) (currMBNumInVP == 0);
       
   490          dmdIn.fBBlockOut = (u_char) (currMBNumInVP <= inParam->pictParam->numMBsInMBLine);
       
   491 
       
   492          inOutParam->aicData->ACpred_flag = MBinstance->ac_pred_flag;
       
   493 
       
   494          /* error resilience params */
       
   495          dmdIn.data_partitioned = 1;
       
   496          dmdIn.DC = MBinstance->DC;
       
   497 
       
   498          dmdIn.reversible_vlc = 1;
       
   499          dmdIn.vlc_dec_direction = 1;
       
   500                  
       
   501          /* get the next macroblock data */
       
   502          ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
       
   503                  
       
   504          if ( ret < 0 ) {
       
   505              retValue = DMBS_ERR;
       
   506              goto exitFunction;                      
       
   507          }
       
   508          else if ( ret == DMD_BIT_ERR ) {
       
   509             backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   510             deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, IMB Blocks error.\n");
       
   511             break;
       
   512          }
       
   513 
       
   514 
       
   515          if (bibNumberOfFlushedBits(inParam->inBuffer) <= startBlockDataBitPos) {
       
   516             deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, block data start position reached.\n");
       
   517             break;
       
   518          }
       
   519 
       
   520          /* deincrement the block pointers and counters */
       
   521          dmdIn.xPosInMBs--;
       
   522          if (dmdIn.xPosInMBs < 0) {
       
   523             if (dmdIn.yPosInMBs > 0) {
       
   524                if ( dmdIn.yMBInFrame != NULL )
       
   525                 {
       
   526                    dmdIn.yMBInFrame -= 15 * yWidth;
       
   527                    dmdIn.uBlockInFrame -= 7 * uvWidth;
       
   528                    dmdIn.vBlockInFrame -= 7 * uvWidth;
       
   529                 }
       
   530                dmdIn.xPosInMBs = inParam->pictParam->numMBsInMBLine -1;
       
   531                dmdIn.yPosInMBs--;
       
   532             } else {
       
   533                dmdIn.xPosInMBs = 0;
       
   534                backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   535                break;
       
   536             }
       
   537          }
       
   538          if ( dmdIn.yMBInFrame != NULL )
       
   539          {
       
   540              dmdIn.yMBInFrame -= 16;
       
   541              dmdIn.uBlockInFrame -= 8;
       
   542              dmdIn.vBlockInFrame -= 8;
       
   543          }
       
   544 
       
   545          dmdIn.currMBNum--;
       
   546          dlstPrev(&MBList, (void **) &MBinstance);
       
   547       }
       
   548 
       
   549       if (currMBNumInVP < 0) {
       
   550          currMBNumInVP = 0;
       
   551          backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   552          deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, all MBs decoded without detected error.\n");
       
   553       }
       
   554 
       
   555 #ifdef DEBUG_OUTPUT
       
   556       {
       
   557          int bitPos[6], xpos, ypos, mbnum;
       
   558          
       
   559          for (xpos = dmdIn.xPosInMBs, ypos = dmdIn.yPosInMBs, mbnum = currMBNumInVP; mbnum < numMBsInVP; mbnum++, xpos++) {
       
   560             
       
   561             if (xpos / inParam->pictParam->numMBsInMBLine)
       
   562                xpos = 0, ypos++;
       
   563             
       
   564             fprintf(rvlc_stat, "bw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
       
   565                inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
       
   566          }
       
   567 
       
   568          fprintf(rvlc_stat, "(blk_st):%8u (fw_det):%8u (bw_det):%8u (nxt_vp):%8u\n", 
       
   569             startBlockDataBitPos, errorBitPos, backwards_errorBitPos, nextVPBitPos);
       
   570       }
       
   571 #endif
       
   572 
       
   573       /* strategy 1 */
       
   574       if ((backwards_errorBitPos > errorBitPos) && 
       
   575          (currMBNumInVP + 1 > numCorrectMBs)) {
       
   576 #ifdef DEBUG_OUTPUT
       
   577          fprintf(rvlc_stat, "I-VOP: strategy 1!\n\n");
       
   578 #endif
       
   579       
       
   580       }
       
   581       /* strategy 2 */
       
   582       else if ((backwards_errorBitPos > errorBitPos) && 
       
   583             (currMBNumInVP + 1 <= numCorrectMBs)) {
       
   584          numCorrectMBs = VDC_MAX(currMBNumInVP-1,0);
       
   585       }
       
   586       /* strategy 3 */
       
   587       else if ((backwards_errorBitPos <= errorBitPos) && 
       
   588             (currMBNumInVP + 1 > numCorrectMBs)) {
       
   589 #ifdef DEBUG_OUTPUT
       
   590          fprintf(rvlc_stat, "I-VOP: strategy 3!\n\n");
       
   591 #endif
       
   592          
       
   593       }
       
   594       /* strategy 4 */
       
   595       else if ((backwards_errorBitPos <= errorBitPos) && 
       
   596             (currMBNumInVP + 1 <= numCorrectMBs)) {
       
   597          numCorrectMBs = VDC_MAX(currMBNumInVP,0);
       
   598       }
       
   599          
       
   600 #ifdef DEBUG_OUTPUT
       
   601       fclose (rvlc_stat);
       
   602 #endif
       
   603 
       
   604       /* if backward decoding, set the currentMB to the first MB of the next VP */
       
   605       inOutParam->currMBNum += numMBsInVP;
       
   606 
       
   607     } else {   
       
   608       /* if no error or no backward decoding, set the currentMB */
       
   609       inOutParam->currMBNum = dmdIn.currMBNum;
       
   610    }
       
   611 
       
   612 #ifdef DEBUG_OUTPUT
       
   613    if (errorBitPos)
       
   614    deb_core("%08lu: MB#%3d VP Data Starts\n%08lu: DC Marker\n%08lu: DCT data starts\n%08lu: MB#%3d Next VP/VOP Header\n%08lu: Fw Error Detected\n%08lu: Bw Error Detected\n", 
       
   615       startVPBitPos, (inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs),
       
   616       DCMarkerBitPos, startBlockDataBitPos, nextVPBitPos, lastMBNum, 
       
   617       errorBitPos,backwards_errorBitPos);
       
   618 #endif
       
   619 
       
   620 exitFunction:
       
   621 
       
   622    deb1p("dmbsGetAndDecodeIMBsDataPartitioned:Finished.\n",inOutParam->currMBNum);
       
   623    /* Free the MB list */
       
   624    if (MBList.numItems != 0)
       
   625    {     
       
   626       dlstHead(&MBList, (void **) &MBinstance);
       
   627       dlstRemove(&MBList, (void **) &MBinstance);
       
   628       while (MBinstance != NULL) {
       
   629          free(MBinstance);
       
   630          dlstRemove(&MBList, (void **) &MBinstance);
       
   631       }
       
   632       dlstClose(&MBList);
       
   633    }
       
   634 
       
   635    return retValue;   
       
   636 }
       
   637 
       
   638 
       
   639 /* {{-output"dmbsGetAndDecodePMBsDataPartitioned.txt"}} */
       
   640 /*
       
   641  * dmbsGetAndDecodePMBsDataPartitioned
       
   642  *    
       
   643  *
       
   644  * Parameters:
       
   645  *    inParam                    input parameters
       
   646  *    inOutParam                 input/output parameters, these parameters
       
   647  *                               may be modified in the function
       
   648  *
       
   649  * Function:
       
   650  *    This function gets and decodes the MBs of a data partitioned 
       
   651  *    Video Packet in an Inter Frame.
       
   652  *
       
   653  * Returns:
       
   654  *    >= 0                       the function was successful
       
   655  *    < 0                        an error occured
       
   656  *
       
   657  */
       
   658 
       
   659 int dmbsGetAndDecodePMBsDataPartitioned(
       
   660    const dmbPFrameMBInParam_t *inParam,
       
   661    dmbPFrameMBInOutParam_t *inOutParam,
       
   662    int *quantParams, CMPEG4Transcoder *hTranscoder)
       
   663 /* {{-output"dmbsGetAndDecodePMBsDataPartitioned.txt"}} */
       
   664 {
       
   665    int currMBNumInVP, currMBNum, numMBsInVP, lastMBNum, numCorrectMBs, numCorrectBackwardsMBs = 0;
       
   666    int xPosInMBs, yPosInMBs;
       
   667    int yWidth = inParam->pictParam->lumMemWidth;
       
   668    int uvWidth = yWidth / 2;
       
   669    int bitErrorIndication = 0, 
       
   670       ret = 0, sncCode, bitsGot,
       
   671       bitErrorsInPart1 = 0;
       
   672    u_int32 errorBitPos = 0,
       
   673          backwards_errorBitPos = 0,
       
   674          nextVPBitPos = 0,
       
   675          startBlockDataBitPos = 0,
       
   676          motionMarkerBitPos = 0;
       
   677    u_char fPart1Error=0, fPart2Error=0, fBlockError=0;
       
   678    u_char *currYMBInFrame, *currUBlkInFrame, *currVBlkInFrame;
       
   679    u_char fourMVs = 0;
       
   680 #ifdef DEBUG_OUTPUT
       
   681    FILE *rvlc_stat;
       
   682 #endif
       
   683 
       
   684    int16 error = 0;
       
   685 
       
   686    dlst_t MBList;
       
   687    vdxPMBListItem_t *MBinstance;
       
   688 
       
   689    vdxGetDataPartitionedPMBLayerInputParam_t vdxDPIn;
       
   690    
       
   691    if (dlstOpen(&MBList) < 0)
       
   692       return DMBS_ERR;
       
   693 
       
   694    currMBNum = inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs;
       
   695 
       
   696    /* Store initial quantizer */
       
   697    quantParams[currMBNum] = inOutParam->quant;
       
   698 
       
   699    /* 
       
   700     * read the first partition: DC coefficients, etc. 
       
   701     */
       
   702 
       
   703    vdxDPIn.intra_dc_vlc_thr = inParam->pictParam->intra_dc_vlc_thr;
       
   704    vdxDPIn.quant = inOutParam->quant;
       
   705    vdxDPIn.f_code = inParam->pictParam->fcode_forward;
       
   706 
       
   707    ret = vdxGetDataPartitionedPMBLayer_Part1(inParam->inBuffer, inParam->outBuffer, 
       
   708          inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), &(inOutParam->StartBitIndex),
       
   709          &vdxDPIn, &MBList, &bitErrorIndication);
       
   710    bitErrorsInPart1 = bitErrorIndication;
       
   711    if (ret < 0)
       
   712       return DMBS_ERR;
       
   713    else if (ret == VDX_OK_BUT_BIT_ERROR) {
       
   714 
       
   715       /* Must break down decoding, because even if we know the number of MBs 
       
   716          in the 2nd partition, the content (quant, ac_pred_flag) is dependent
       
   717         on "not_coded" and the type of MB (I-vop or P-vop), which information
       
   718         is derived from the 1st !currupted! partition. */
       
   719       
       
   720       deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Part 1 Error.\n");
       
   721       fPart1Error = 1;
       
   722       bitErrorIndication = 0;
       
   723       errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   724    } else {
       
   725       motionMarkerBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   726    }
       
   727 
       
   728    /* read the next VP header to determine the number of MBs in this VP */
       
   729    if ( fPart1Error ) {
       
   730        /* Stop decoding this segment */
       
   731       goto exitFunction;
       
   732    }
       
   733    else {
       
   734       sncCode = sncRewindAndSeekNewMPEGSync( 1,
       
   735           inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
       
   736    }
       
   737    if (error) {
       
   738       if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
       
   739       else 
       
   740           return DMBS_ERR;
       
   741    }
       
   742    
       
   743    nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   744    
       
   745    if (sncCode == SNC_VIDPACK) {
       
   746       
       
   747       vdxVideoPacketHeader_t header;
       
   748       vdxGetVideoPacketHeaderInputParam_t vdxParam;
       
   749       int retValue = 0;
       
   750       
       
   751       vdxParam.fcode_forward = inParam->pictParam->fcode_forward;
       
   752       vdxParam.time_increment_resolution = inParam->pictParam->time_increment_resolution;
       
   753       vdxParam.numOfMBs = inParam->pictParam->numMBsInGOB;
       
   754       
       
   755       retValue = vdxGetVideoPacketHeader(inParam->inBuffer, &vdxParam, &header, &bitErrorIndication);
       
   756       if (retValue < 0) {
       
   757          return DMBS_ERR;
       
   758       } else if (retValue == VDX_OK_BUT_BIT_ERROR) {
       
   759          /* If bit error occurred */
       
   760          deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Reading Next VP Header error.\n");
       
   761          lastMBNum = 0;
       
   762       } else {
       
   763          lastMBNum = header.currMBNum;
       
   764       }
       
   765    } else {
       
   766       lastMBNum = inParam->pictParam->numMBsInGOB;
       
   767    }
       
   768 
       
   769    /* signaling to the caller function, that the Next VP header has been read */
       
   770    inOutParam->currMBNumInVP = lastMBNum;
       
   771       
       
   772    /* rewind the bits before the next resync_marker */
       
   773    bibRewindBits(bibNumberOfFlushedBits(inParam->inBuffer) - (fPart1Error ? nextVPBitPos: motionMarkerBitPos),
       
   774       inParam->inBuffer, &error);
       
   775    
       
   776    if ((bitErrorIndication && !fPart1Error) || 
       
   777       (lastMBNum <= currMBNum || lastMBNum > inParam->pictParam->numMBsInGOB) ||
       
   778       (sncCode == SNC_EOB)) {
       
   779       bitErrorIndication = 0;
       
   780       numMBsInVP = MBList.numItems;
       
   781    } else
       
   782       numMBsInVP = lastMBNum - currMBNum;
       
   783 
       
   784    if (numMBsInVP != MBList.numItems || fPart1Error) {
       
   785       deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - MB list length != num MBs.\n");
       
   786       if ( fPart1Error || bitErrorsInPart1 ) {
       
   787          /* Discard few MBs from the end of the list, 
       
   788             since there are errors somewhere in the bitstream. 
       
   789             If the list is short due to the missing packet, 
       
   790             all the read MBs are likely to be OK and there is no
       
   791             need to discard them */
       
   792          dlstTail(&MBList, (void **) &MBinstance);
       
   793          dlstRemove(&MBList, (void **) &MBinstance);
       
   794          free( MBinstance );
       
   795          if (numMBsInVP > MBList.numItems ) {
       
   796             /* Take still one away */
       
   797             dlstTail(&MBList, (void **) &MBinstance);
       
   798             dlstRemove(&MBList, (void **) &MBinstance);
       
   799             free( MBinstance );
       
   800          }
       
   801       }
       
   802       if (numMBsInVP < MBList.numItems ) {
       
   803          /* Discard all the extra MBs from the end of the list + 2 just to be sure, 
       
   804             since there are errors somewhere in the bitstream */
       
   805          while ( MBList.numItems > VDC_MAX(numMBsInVP-2,0) ) {
       
   806             dlstTail(&MBList, (void **) &MBinstance);
       
   807             dlstRemove(&MBList, (void **) &MBinstance);
       
   808             free( MBinstance );
       
   809          }
       
   810       }
       
   811       fPart1Error = 1;
       
   812       errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   813    }
       
   814 
       
   815    if (currMBNum + numMBsInVP > inParam->pictParam->numMBsInGOB) {
       
   816       deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Determined numMBsInVP overrun numMBsInFrame.\n");
       
   817       fPart1Error = 1;
       
   818       errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
   819       numMBsInVP = inParam->pictParam->numMBsInGOB - currMBNum;
       
   820    }
       
   821 
       
   822    if (!fPart1Error) {
       
   823       
       
   824       /* Flush the Motion_Marker */
       
   825       bibFlushBits(MP4_MOTION_MARKER_COMB_LENGTH, inParam->inBuffer, &bitsGot, &bitErrorIndication, &error);
       
   826       if (error)
       
   827          return DMBS_ERR;
       
   828       
       
   829       /*
       
   830        * Read the second partition header: cpby, ac_pred_flag 
       
   831        */
       
   832 
       
   833       ret = vdxGetDataPartitionedPMBLayer_Part2(inParam->inBuffer, inParam->outBuffer, 
       
   834                 inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), 
       
   835                 &(inOutParam->StartBitIndex), hTranscoder, 
       
   836                 &vdxDPIn, &MBList, &bitErrorIndication);
       
   837       if (ret < 0)
       
   838          return DMBS_ERR;
       
   839       else if (ret == VDX_OK_BUT_BIT_ERROR) {
       
   840          deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Part 2 Error.\n");
       
   841          fPart2Error = 1;
       
   842          /* Stop decoding this segment */
       
   843          goto exitFunction;
       
   844       }
       
   845    }
       
   846 
       
   847    /*
       
   848     * Count the motion vectors and copy the prediction blocks 
       
   849     */
       
   850    
       
   851    xPosInMBs = inParam->xPosInMBs;
       
   852    yPosInMBs = inParam->yPosInMBs;
       
   853    currYMBInFrame = inOutParam->yMBInFrame;
       
   854    currUBlkInFrame = inOutParam->uBlockInFrame;
       
   855    currVBlkInFrame = inOutParam->vBlockInFrame;
       
   856 
       
   857    /* get the first MB of the list */
       
   858    dlstHead(&MBList, (void **) &MBinstance);
       
   859 
       
   860    for (currMBNumInVP = 0; currMBNumInVP < numMBsInVP; currMBNumInVP++) {
       
   861 
       
   862       /* Motion vectors for P-macroblock */
       
   863       int mvx[4];
       
   864       int mvy[4];
       
   865        int mbPos;       /* the position of the current macroblock, 
       
   866                            -1 = the leftmost MB of the image, 
       
   867                            0 = MB is not in the border of the image, 
       
   868                            1 = rightmost MB of the image */
       
   869 
       
   870       blcCopyPredictionMBParam_t blcParam;
       
   871       
       
   872       /* if MBList is shorter then the number of MBs in the VP */
       
   873       if (MBinstance == NULL) {
       
   874          deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - MB list < num MBs.\n");
       
   875          inOutParam->currMBNum = currMBNum;
       
   876          goto exitFunction;
       
   877       }
       
   878 
       
   879       if (!MBinstance->fCodedMB) {
       
   880          
       
   881          inOutParam->fCodedMBs[currMBNum] = 0;
       
   882          /* Motion vectors to 0 */ 
       
   883          mvx[0] = mvx[1] = mvx[2] = mvx[3] = 0;
       
   884          mvy[0] = mvy[1] = mvy[2] = mvy[3] = 0;
       
   885          mvcMarkMBNotCoded(
       
   886             inOutParam->mvcData, 
       
   887             xPosInMBs,
       
   888             yPosInMBs,
       
   889             inParam->pictParam->tr);
       
   890          MBinstance->cbpy = 0;
       
   891          fourMVs = 0;
       
   892 
       
   893       } else {
       
   894 
       
   895          inOutParam->fCodedMBs[currMBNum] = 1;
       
   896          inOutParam->numOfCodedMBs++;
       
   897          
       
   898          if(MBinstance->mbClass == VDX_MB_INTER) {
       
   899             int currMVNum;
       
   900 
       
   901             fourMVs = (u_char) (MBinstance->numMVs == 4);
       
   902          
       
   903             for (currMVNum = 0; currMVNum < MBinstance->numMVs; currMVNum++) {
       
   904 
       
   905                mvcCalcMPEGMV(
       
   906                   inOutParam->mvcData,
       
   907                   MBinstance->mvx[currMVNum], MBinstance->mvy[currMVNum],
       
   908                   &mvx[currMVNum], &mvy[currMVNum],
       
   909                   (u_char) currMVNum, fourMVs,
       
   910                   (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine),
       
   911                   (u_char) (currMBNumInVP == 0), 
       
   912                   (u_char) (currMBNumInVP < (inParam->pictParam->numMBsInMBLine-1)),
       
   913                   xPosInMBs,
       
   914                   yPosInMBs,
       
   915                   inParam->pictParam->tr,
       
   916                   (MBinstance->mbClass == VDX_MB_INTRA) ? MVC_MB_INTRA : MVC_MB_INTER,
       
   917                   &error);   
       
   918 
       
   919                 if (error == ERR_MVC_MVPTR)
       
   920                      return DMB_BIT_ERR;
       
   921                 else if (error)
       
   922                      return DMB_ERR;
       
   923             }
       
   924             
       
   925             if (MBinstance->numMVs == 1) {
       
   926                mvx[1] = mvx[2] = mvx[3] = mvx[0];
       
   927                mvy[1] = mvy[2] = mvy[3] = mvy[0];
       
   928             }
       
   929 
       
   930          } else { /* VDX_MB_INTRA */
       
   931             mvcMarkMBIntra(inOutParam->mvcData, xPosInMBs, yPosInMBs, 
       
   932                inParam->pictParam->tr);
       
   933 
       
   934          }
       
   935       }
       
   936 
       
   937       /* mbPos, needed in blcCopyPredictionMB */
       
   938       if (xPosInMBs == 0)
       
   939          mbPos = -1;
       
   940       else if (xPosInMBs == inParam->pictParam->numMBsInMBLine - 1)
       
   941          mbPos = 1;
       
   942       else
       
   943          mbPos = 0;
       
   944 
       
   945       if (!MBinstance->fCodedMB || MBinstance->mbClass == VDX_MB_INTER) {
       
   946                 blcParam.refY = inParam->refY;
       
   947                 blcParam.refU = inParam->refU;
       
   948                 blcParam.refV = inParam->refV;
       
   949                 blcParam.currYMBInFrame = currYMBInFrame;
       
   950                 blcParam.currUBlkInFrame = currUBlkInFrame;
       
   951                 blcParam.currVBlkInFrame = currVBlkInFrame;
       
   952                 blcParam.uvBlkXCoord = xPosInMBs * 8;
       
   953                 blcParam.uvBlkYCoord = yPosInMBs * 8;
       
   954                 blcParam.uvWidth = uvWidth;
       
   955                 blcParam.uvHeight = inParam->pictParam->lumMemHeight / 2;
       
   956                 blcParam.mvcData = inOutParam->mvcData;
       
   957                 blcParam.mvx = mvx;
       
   958                 blcParam.mvy = mvy;
       
   959                 blcParam.mbPlace = mbPos;
       
   960                 blcParam.fAdvancedPrediction = inParam->pictParam->fAP;
       
   961                 blcParam.fMVsOverPictureBoundaries =
       
   962                     inParam->pictParam->fMVsOverPictureBoundaries;
       
   963                 blcParam.diffMB = inOutParam->diffMB;
       
   964                 blcParam.rcontrol = inParam->pictParam->rtype;
       
   965                 blcParam.fourMVs = fourMVs;
       
   966                 
       
   967                 /* MVE */
       
   968                 if (inParam->iGetDecodedFrame || hTranscoder->NeedDecodedYUVFrame())
       
   969                 {
       
   970                     
       
   971                     /* Do motion compensation */
       
   972                     if (blcCopyPredictionMB(&blcParam) < 0) {
       
   973                         deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Block copying failed, illegal MV.\n");
       
   974                         inOutParam->currMBNum = currMBNum;
       
   975                         goto exitFunction;
       
   976                         /* MV was illegal => caused by bitError */
       
   977                     }
       
   978                 }
       
   979       }
       
   980             
       
   981       currMBNum++;
       
   982 
       
   983       /* increment the block pointers and counters */
       
   984       if ( currYMBInFrame != NULL )
       
   985         {
       
   986           currYMBInFrame += 16;
       
   987           currUBlkInFrame += 8;
       
   988           currVBlkInFrame += 8;
       
   989         }
       
   990       xPosInMBs++;
       
   991 
       
   992       if (xPosInMBs == inParam->pictParam->numMBsInMBLine) {
       
   993           if ( currYMBInFrame != NULL )
       
   994             {
       
   995                 currYMBInFrame += 15 * yWidth;
       
   996                 currUBlkInFrame += 7 * uvWidth;
       
   997                 currVBlkInFrame += 7 * uvWidth;
       
   998             }
       
   999             xPosInMBs = 0;
       
  1000             yPosInMBs++;
       
  1001             if (yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
       
  1002                 break;
       
  1003       }
       
  1004             
       
  1005       /* MVE */
       
  1006       MBinstance->mv_x[0] = mvx[0]; MBinstance->mv_x[1] = mvx[1]; MBinstance->mv_x[2] = mvx[2]; MBinstance->mv_x[3] = mvx[3];
       
  1007       MBinstance->mv_y[0] = mvy[0]; MBinstance->mv_y[1] = mvy[1]; MBinstance->mv_y[2] = mvy[2]; MBinstance->mv_y[3] = mvy[3];
       
  1008             
       
  1009       dlstNext(&MBList, (void **) &MBinstance);
       
  1010    }
       
  1011      
       
  1012    /* if error occured in the first 2 MV&header partitions, then stop decoding */
       
  1013    if (fPart1Error || fPart2Error) {
       
  1014 
       
  1015 #ifdef DEBUG_OUTPUT
       
  1016       deb_core("%08lu: MB#%3d VP Data Starts\n%08lu: Motion Marker\n%08lu: DCT data starts\n%08lu: MB#%3d Next VP/VOP Header\n%08lu: Fw Error Detected\n", 
       
  1017          startVPBitPos, (inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs),
       
  1018          motionMarkerBitPos, startBlockDataBitPos, nextVPBitPos, lastMBNum, 
       
  1019          errorBitPos);
       
  1020 #endif
       
  1021       
       
  1022       inOutParam->currMBNum = currMBNum;
       
  1023       goto exitFunction;
       
  1024    }
       
  1025 
       
  1026    /*
       
  1027     * Read block data partition in forward direction 
       
  1028     */
       
  1029 
       
  1030    xPosInMBs = inParam->xPosInMBs;
       
  1031    yPosInMBs = inParam->yPosInMBs;
       
  1032    currMBNumInVP = 0;
       
  1033    currMBNum = inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs;
       
  1034    currYMBInFrame = inOutParam->yMBInFrame;
       
  1035    currUBlkInFrame = inOutParam->uBlockInFrame;
       
  1036    currVBlkInFrame = inOutParam->vBlockInFrame;
       
  1037 
       
  1038    startBlockDataBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1039 
       
  1040    for (dlstHead(&MBList, (void **) &MBinstance); 
       
  1041      MBinstance != NULL; 
       
  1042      dlstNext(&MBList, (void **) &MBinstance))
       
  1043    {
       
  1044         /* MVE */
       
  1045         hTranscoder->OnePMBDataStartedDataPartitioned(MBinstance, &MBList, currMBNumInVP, currMBNum);
       
  1046          
       
  1047         if (MBinstance->fCodedMB) {
       
  1048              
       
  1049             /* If INTER MB */
       
  1050             if (MBinstance->mbClass == VDX_MB_INTER) {
       
  1051                 dmdPParam_t dmdIn;
       
  1052                      
       
  1053                 dmdIn.inBuffer = inParam->inBuffer;
       
  1054                 dmdIn.outBuffer = inParam->outBuffer;
       
  1055                 dmdIn.bufEdit = inParam->bufEdit;
       
  1056                 dmdIn.iColorEffect = inParam->iColorEffect;
       
  1057                 dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
       
  1058                 dmdIn.cbpy = MBinstance->cbpy;
       
  1059                 dmdIn.cbpc = MBinstance->cbpc;
       
  1060                 dmdIn.quant = MBinstance->quant;
       
  1061                      
       
  1062                 /* MVE */
       
  1063                 dmdIn.refY = inParam->refY;
       
  1064                 dmdIn.refU = inParam->refU;
       
  1065                 dmdIn.refV = inParam->refV;
       
  1066                 dmdIn.mvx  = MBinstance->mv_x;
       
  1067                 dmdIn.mvy  = MBinstance->mv_y;
       
  1068 
       
  1069                 dmdIn.currYMBInFrame = currYMBInFrame;
       
  1070                 dmdIn.currUBlkInFrame = currUBlkInFrame;
       
  1071                 dmdIn.currVBlkInFrame = currVBlkInFrame;
       
  1072                 dmdIn.uvWidth = uvWidth;
       
  1073                 dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;     
       
  1074                 dmdIn.vlc_dec_direction = 0;
       
  1075 
       
  1076                 dmdIn.xPosInMBs = xPosInMBs;
       
  1077                 dmdIn.yPosInMBs = yPosInMBs;
       
  1078                 dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
       
  1079                      
       
  1080                 /* Store quantizer */
       
  1081                 quantParams[currMBNum] = MBinstance->quant;
       
  1082                      
       
  1083                 /* Update the AIC module data, marking the MB as Inter (quant=0) */
       
  1084                 aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
       
  1085                      
       
  1086                 /* Decode prediction error blocks */
       
  1087                 ret = dmdGetAndDecodeMPEGPMBBlocks(&dmdIn, hTranscoder);
       
  1088                      
       
  1089                 if ( ret < 0)
       
  1090                     return DMBS_ERR;
       
  1091                 else if ( ret == DMD_BIT_ERR ) {
       
  1092                     deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - PMB Blocks decoding failed.\n");
       
  1093                     fBlockError = 1;
       
  1094                     errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1095                     break;
       
  1096                 }
       
  1097 
       
  1098             }
       
  1099             /* Else block layer decoding of INTRA macroblock */
       
  1100             else {
       
  1101                 dmdMPEGIParam_t dmdIn;
       
  1102                      
       
  1103                 /* Get block layer parameters and decode them */
       
  1104                 dmdIn.inBuffer = inParam->inBuffer;
       
  1105                 dmdIn.outBuffer = inParam->outBuffer;
       
  1106                 dmdIn.bufEdit = inParam->bufEdit;
       
  1107                 dmdIn.iColorEffect = inParam->iColorEffect;
       
  1108                 dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
       
  1109                      
       
  1110                 dmdIn.cbpy = MBinstance->cbpy;
       
  1111                 dmdIn.cbpc = MBinstance->cbpc;
       
  1112                 dmdIn.quant = MBinstance->quant;
       
  1113                 dmdIn.yWidth = yWidth;
       
  1114                 dmdIn.yMBInFrame = currYMBInFrame;
       
  1115                 dmdIn.uBlockInFrame = currUBlkInFrame;
       
  1116                 dmdIn.vBlockInFrame = currVBlkInFrame;
       
  1117                      
       
  1118                 dmdIn.xPosInMBs = xPosInMBs;
       
  1119                 dmdIn.yPosInMBs = yPosInMBs;
       
  1120                 dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
       
  1121                 dmdIn.numMBLinesInGOB = inParam->pictParam->numMBLinesInGOB;
       
  1122                 dmdIn.pictureType = inParam->pictParam->pictureType;
       
  1123                      
       
  1124                 inOutParam->aicData->ACpred_flag = MBinstance->ac_pred_flag;
       
  1125                 dmdIn.aicData = inOutParam->aicData;
       
  1126                      
       
  1127                 dmdIn.data_partitioned = 1;
       
  1128                 dmdIn.switched = MBinstance->switched;
       
  1129                 dmdIn.DC = MBinstance->DC;
       
  1130                      
       
  1131                 dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;
       
  1132                 dmdIn.vlc_dec_direction = 0;
       
  1133                      
       
  1134                 dmdIn.currMBNum = currMBNum;
       
  1135                      
       
  1136                 dmdIn.fTopOfVP = (u_char) 
       
  1137                         (currMBNumInVP < inParam->pictParam->numMBsInMBLine ||
       
  1138                          !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine));
       
  1139                 dmdIn.fLeftOfVP = (u_char)
       
  1140                         (currMBNumInVP == 0 || 
       
  1141                          xPosInMBs == 0 ||
       
  1142                          !aicIsBlockValid(inOutParam->aicData, currMBNum-1));
       
  1143                 dmdIn.fBBlockOut = (u_char) 
       
  1144                         (currMBNumInVP <= inParam->pictParam->numMBsInMBLine ||
       
  1145                          xPosInMBs == 0 ||
       
  1146                          !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine-1));
       
  1147                      
       
  1148                 ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
       
  1149                      
       
  1150                 if ( ret < 0 )
       
  1151                     return DMBS_ERR;
       
  1152                 else if ( ret == DMD_BIT_ERR ) {
       
  1153                     deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - IMB Blocks decoding failed.\n");
       
  1154                     fBlockError = 1;
       
  1155                     errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1156                     break;
       
  1157                 }
       
  1158             }
       
  1159                  
       
  1160         } else {  /* end of if coded MB */
       
  1161                      
       
  1162             /* Update the AIC module data, marking the MB as Not Coded (quant=0) */
       
  1163             aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
       
  1164         }
       
  1165                  
       
  1166         currMBNumInVP++;
       
  1167         currMBNum++;
       
  1168 
       
  1169         /* increment the block pointers and counters */
       
  1170         if ( currYMBInFrame != NULL )
       
  1171          {
       
  1172             currYMBInFrame += 16;
       
  1173             currUBlkInFrame += 8;
       
  1174             currVBlkInFrame += 8;
       
  1175          }
       
  1176         xPosInMBs++;
       
  1177 
       
  1178         if (xPosInMBs == inParam->pictParam->numMBsInMBLine) {
       
  1179           if ( currYMBInFrame != NULL )
       
  1180             {
       
  1181                 currYMBInFrame += 15 * yWidth;
       
  1182                 currUBlkInFrame += 7 * uvWidth;
       
  1183                 currVBlkInFrame += 7 * uvWidth;
       
  1184             }
       
  1185             xPosInMBs = 0;
       
  1186             yPosInMBs++;
       
  1187             if (yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
       
  1188                  break;
       
  1189         }
       
  1190    } // end of for-loop
       
  1191    
       
  1192    if (!fPart1Error && !fPart2Error && !fBlockError) {
       
  1193       if (sncCode == SNC_EOB) {
       
  1194          inOutParam->currMBNum += numMBsInVP;
       
  1195          goto exitFunction;
       
  1196       } else {
       
  1197          sncCode = sncCheckMpegSync(inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
       
  1198          if (sncCode == SNC_NO_SYNC) {
       
  1199             deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - After block data no start code found.\n");
       
  1200             if (lastMBNum != 0) 
       
  1201                fBlockError = 1;
       
  1202             errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1203          }
       
  1204       }
       
  1205    }
       
  1206 
       
  1207    /*
       
  1208     * In case of error, read block data partition in backward direction 
       
  1209    */
       
  1210 
       
  1211    if (fBlockError && inParam->pictParam->reversible_vlc) {
       
  1212       numCorrectMBs = currMBNumInVP;
       
  1213 
       
  1214 #ifdef DEBUG_OUTPUT
       
  1215       {
       
  1216          int bitPos[6], xpos, ypos, mbnum;
       
  1217          
       
  1218          rvlc_stat = fopen("rvlc.log", "a+t");
       
  1219          
       
  1220          fprintf(rvlc_stat, "P-VOP: (MB_first):%3d  (MB_last):%3d\n", 
       
  1221             inOutParam->currMBNum, (inOutParam->currMBNum + numMBsInVP-1));
       
  1222          
       
  1223          for (xpos = inParam->xPosInMBs, ypos = inParam->yPosInMBs, mbnum = 0; mbnum < numCorrectMBs; mbnum++, xpos++) {
       
  1224             
       
  1225             if (xpos / inParam->pictParam->numMBsInMBLine)
       
  1226                xpos = 0, ypos++;
       
  1227 
       
  1228             fprintf(rvlc_stat, "fw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
       
  1229                inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
       
  1230          }
       
  1231       }
       
  1232 #endif
       
  1233 
       
  1234          /* find next VP header (end of MB block data of this VP) */
       
  1235       sncCode = sncRewindAndSeekNewMPEGSync(errorBitPos-startBlockDataBitPos, inParam->inBuffer,
       
  1236          inParam->pictParam->fcode_forward, &error);      
       
  1237       if (error) {
       
  1238           if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
       
  1239           else 
       
  1240               return DMBS_ERR;
       
  1241       }
       
  1242 
       
  1243       if (sncCode == SNC_EOB) {
       
  1244          inOutParam->currMBNum += numMBsInVP;
       
  1245          goto exitFunction;
       
  1246       }
       
  1247 
       
  1248       nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1249    
       
  1250       backwards_errorBitPos = startBlockDataBitPos;
       
  1251 
       
  1252       /* rewind the stuffing bits */
       
  1253       if (sncCode != SNC_NO_SYNC || !(nextVPBitPos % 8)) {
       
  1254          if(sncRewindStuffing(inParam->inBuffer, &error) != SNC_PATTERN) {
       
  1255             deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, stuffing not found.\n");
       
  1256             goto exitFunction;
       
  1257          }
       
  1258       }
       
  1259 
       
  1260       /* set the block pointers and counters to the end of the VP */
       
  1261       if ( currYMBInFrame != NULL )
       
  1262         {
       
  1263           currYMBInFrame = inOutParam->yMBInFrame + 16 * (numMBsInVP-1);
       
  1264           currUBlkInFrame = inOutParam->uBlockInFrame + 8 * (numMBsInVP-1);
       
  1265           currVBlkInFrame = inOutParam->vBlockInFrame + 8 * (numMBsInVP-1);
       
  1266         }
       
  1267 
       
  1268       xPosInMBs = inParam->xPosInMBs + (numMBsInVP-1);
       
  1269       yPosInMBs = inParam->yPosInMBs;
       
  1270 
       
  1271       if (xPosInMBs / inParam->pictParam->numMBsInMBLine) {
       
  1272 
       
  1273          int numFullLines = xPosInMBs / inParam->pictParam->numMBsInMBLine;
       
  1274 
       
  1275          if ( currYMBInFrame != NULL )
       
  1276             {
       
  1277              currYMBInFrame += 15 * yWidth * numFullLines;
       
  1278              currUBlkInFrame += 7 * uvWidth * numFullLines;
       
  1279              currVBlkInFrame += 7 * uvWidth * numFullLines;
       
  1280             }
       
  1281          xPosInMBs = xPosInMBs % inParam->pictParam->numMBsInMBLine;
       
  1282          yPosInMBs+=numFullLines;
       
  1283       }
       
  1284 
       
  1285       currMBNum = inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine +
       
  1286                inParam->xPosInMBs + (numMBsInVP-1);
       
  1287       currMBNumInVP = numMBsInVP-1;
       
  1288 
       
  1289       for (dlstTail(&MBList, (void **) &MBinstance); 
       
  1290          MBinstance != NULL; 
       
  1291          dlstPrev(&MBList, (void **) &MBinstance))
       
  1292       {
       
  1293          if (MBinstance->fCodedMB) 
       
  1294          {
       
  1295 
       
  1296              /* If INTER MB */
       
  1297              if (MBinstance->mbClass == VDX_MB_INTER) 
       
  1298              {
       
  1299                 dmdPParam_t dmdIn;
       
  1300 
       
  1301                 dmdIn.inBuffer = inParam->inBuffer;
       
  1302                 dmdIn.outBuffer = inParam->outBuffer;
       
  1303                 dmdIn.bufEdit = inParam->bufEdit;
       
  1304                 dmdIn.iColorEffect = inParam->iColorEffect;
       
  1305                 dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
       
  1306                 dmdIn.cbpy = MBinstance->cbpy;
       
  1307                 dmdIn.cbpc = MBinstance->cbpc;
       
  1308                 dmdIn.quant = MBinstance->quant;
       
  1309                             
       
  1310                 /* MVE */
       
  1311                 dmdIn.refY = inParam->refY;
       
  1312                 dmdIn.refU = inParam->refU;
       
  1313                 dmdIn.refV = inParam->refV;
       
  1314                 dmdIn.mvx  = MBinstance->mv_x;
       
  1315                 dmdIn.mvy  = MBinstance->mv_y;
       
  1316                             
       
  1317                 dmdIn.currYMBInFrame = currYMBInFrame;
       
  1318                 dmdIn.currUBlkInFrame = currUBlkInFrame;
       
  1319                 dmdIn.currVBlkInFrame = currVBlkInFrame;
       
  1320                 dmdIn.uvWidth = uvWidth;
       
  1321                 
       
  1322                 dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;     
       
  1323                 dmdIn.vlc_dec_direction = 1;
       
  1324                 
       
  1325                 dmdIn.xPosInMBs = xPosInMBs;
       
  1326                 dmdIn.yPosInMBs = yPosInMBs;
       
  1327                 dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
       
  1328 
       
  1329                 /* Update the AIC module data, marking the MB as Inter (quant=0) */
       
  1330                 aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
       
  1331                 
       
  1332                 /* Decode prediction error blocks */
       
  1333                 ret = dmdGetAndDecodeMPEGPMBBlocks(&dmdIn, hTranscoder);
       
  1334 
       
  1335                 if ( ret < 0)
       
  1336                    return DMBS_ERR;
       
  1337                 else if ( ret == DMD_BIT_ERR ) {
       
  1338                    deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, PMB Blocks decoding failed.\n");
       
  1339                    backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1340                    break;
       
  1341                 }
       
  1342 
       
  1343              }
       
  1344              /* Else block layer decoding of INTRA macroblock */
       
  1345              else 
       
  1346              {
       
  1347                 dmdMPEGIParam_t dmdIn;
       
  1348 
       
  1349                 /* Get block layer parameters and decode them */
       
  1350                 dmdIn.inBuffer = inParam->inBuffer;
       
  1351                 dmdIn.outBuffer = inParam->outBuffer;
       
  1352                 dmdIn.bufEdit = inParam->bufEdit;
       
  1353                 dmdIn.iColorEffect = inParam->iColorEffect;
       
  1354                 dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
       
  1355 
       
  1356                 dmdIn.cbpy = MBinstance->cbpy;
       
  1357                 dmdIn.cbpc = MBinstance->cbpc;
       
  1358                 dmdIn.quant = MBinstance->quant;
       
  1359                 dmdIn.yWidth = yWidth;
       
  1360                 dmdIn.yMBInFrame = currYMBInFrame;
       
  1361                 dmdIn.uBlockInFrame = currUBlkInFrame;
       
  1362                 dmdIn.vBlockInFrame = currVBlkInFrame;
       
  1363 
       
  1364                 dmdIn.xPosInMBs = xPosInMBs;
       
  1365                 dmdIn.yPosInMBs = yPosInMBs;
       
  1366                 dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
       
  1367                 dmdIn.numMBLinesInGOB = inParam->pictParam->numMBLinesInGOB;
       
  1368                 dmdIn.pictureType = inParam->pictParam->pictureType;
       
  1369 
       
  1370                 inOutParam->aicData->ACpred_flag = MBinstance->ac_pred_flag;
       
  1371                 dmdIn.aicData = inOutParam->aicData;
       
  1372 
       
  1373                 dmdIn.data_partitioned = inParam->pictParam->data_partitioned;
       
  1374                 dmdIn.switched = MBinstance->switched;
       
  1375                 dmdIn.DC = MBinstance->DC;
       
  1376 
       
  1377                 dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;
       
  1378                 dmdIn.vlc_dec_direction = 1;
       
  1379 
       
  1380                 dmdIn.currMBNum = currMBNum;
       
  1381 
       
  1382                 dmdIn.fTopOfVP = (u_char) 
       
  1383                    (currMBNumInVP < inParam->pictParam->numMBsInMBLine ||
       
  1384                     !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine));
       
  1385                 dmdIn.fLeftOfVP = (u_char)
       
  1386                    (currMBNumInVP == 0 || 
       
  1387                     xPosInMBs == 0 ||
       
  1388                     !aicIsBlockValid(inOutParam->aicData, currMBNum-1));
       
  1389                 dmdIn.fBBlockOut = (u_char) 
       
  1390                    (currMBNumInVP <= inParam->pictParam->numMBsInMBLine ||
       
  1391                     xPosInMBs == 0 ||
       
  1392                     !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine-1));
       
  1393                 
       
  1394                 ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
       
  1395 
       
  1396                 if ( ret < 0 )
       
  1397                    return DMBS_ERR;
       
  1398                 else if ( ret == DMD_BIT_ERR ) {
       
  1399                    deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, IMB Blocks decoding failed.\n");
       
  1400                    backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1401 
       
  1402                    break;
       
  1403                 }
       
  1404              } // end of else
       
  1405 
       
  1406          } /* end of if coded MB */
       
  1407          else 
       
  1408          {  
       
  1409        
       
  1410             /* Update the AIC module data, marking the MB as Not Coded (quant=0) */
       
  1411             aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
       
  1412          }
       
  1413 
       
  1414          if (bibNumberOfFlushedBits(inParam->inBuffer) <= startBlockDataBitPos) {
       
  1415             deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, block data start position reached.\n");
       
  1416             break;
       
  1417          }
       
  1418 
       
  1419          /* deincrement the block pointers and counters */
       
  1420          xPosInMBs--;
       
  1421          if (xPosInMBs < 0) {
       
  1422             if (yPosInMBs > 0) {
       
  1423               if ( currYMBInFrame != NULL )
       
  1424                 {
       
  1425                    currYMBInFrame -= 15 * yWidth;
       
  1426                    currUBlkInFrame -= 7 * uvWidth;
       
  1427                    currVBlkInFrame -= 7 * uvWidth;
       
  1428                 }
       
  1429                xPosInMBs = inParam->pictParam->numMBsInMBLine -1;
       
  1430                yPosInMBs--;
       
  1431             } else {
       
  1432                xPosInMBs = 0;
       
  1433                backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1434                break;
       
  1435             }
       
  1436          }
       
  1437           if ( currYMBInFrame != NULL )
       
  1438             {
       
  1439              currYMBInFrame -= 16;
       
  1440              currUBlkInFrame -= 8;
       
  1441              currVBlkInFrame -= 8;
       
  1442             }
       
  1443 
       
  1444          currMBNumInVP--;
       
  1445          currMBNum--;
       
  1446       }
       
  1447 
       
  1448       if (currMBNumInVP < 0) {
       
  1449          currMBNumInVP = 0;
       
  1450          backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
       
  1451          deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, all MBs decoded without detected error.\n");
       
  1452       }
       
  1453 
       
  1454 #ifdef DEBUG_OUTPUT
       
  1455       {
       
  1456          int bitPos[6], xpos, ypos, mbnum;
       
  1457 
       
  1458          xPosInMBs++;
       
  1459          if (xPosInMBs >= inParam->pictParam->numMBsInMBLine) {
       
  1460             xPosInMBs = 0;
       
  1461             if (yPosInMBs < (inParam->pictParam->numMBLinesInGOB-1))
       
  1462                yPosInMBs++;
       
  1463          }
       
  1464 
       
  1465          for (xpos = xPosInMBs, ypos = yPosInMBs, mbnum = (currMBNumInVP+1); mbnum < numMBsInVP; mbnum++, xpos++) {
       
  1466             
       
  1467             if (xpos / inParam->pictParam->numMBsInMBLine)
       
  1468                xpos = 0, ypos++;
       
  1469             
       
  1470             fprintf(rvlc_stat, "bw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
       
  1471                inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
       
  1472          }
       
  1473          
       
  1474          fprintf(rvlc_stat, "(blk_st):%8u (fw_det):%8u (bw_det):%8u (nxt_vp):%8u\n", 
       
  1475             startBlockDataBitPos, errorBitPos, backwards_errorBitPos, nextVPBitPos);
       
  1476       }
       
  1477 #endif
       
  1478       
       
  1479       /* 
       
  1480        * Based on the decoder MB counters forwards and backwards, 
       
  1481        * recopy the "to be discarded" blocks 
       
  1482        */
       
  1483 
       
  1484       /* strategy 1 */
       
  1485       if ((backwards_errorBitPos > errorBitPos) && 
       
  1486          (currMBNumInVP + 1 > numCorrectMBs)) {
       
  1487          numCorrectBackwardsMBs = VDC_MIN(currMBNumInVP + 2,numMBsInVP);       
       
  1488          numCorrectMBs = VDC_MAX(numCorrectMBs-2,0);
       
  1489 #ifdef DEBUG_OUTPUT
       
  1490          fprintf(rvlc_stat, "P-VOP strategy 1: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
       
  1491 #endif
       
  1492       }
       
  1493       /* strategy 2 */
       
  1494       else if ((backwards_errorBitPos > errorBitPos) && 
       
  1495              (currMBNumInVP + 1 <= numCorrectMBs)) {
       
  1496          numCorrectBackwardsMBs = VDC_MIN(numCorrectMBs + 1,numMBsInVP);
       
  1497          numCorrectMBs = VDC_MAX(currMBNumInVP-1,0);
       
  1498 #ifdef DEBUG_OUTPUT
       
  1499          fprintf(rvlc_stat, "P-VOP strategy 2: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
       
  1500 #endif
       
  1501       }
       
  1502       /* strategy 3 */
       
  1503       else if ((backwards_errorBitPos <= errorBitPos) && 
       
  1504              (currMBNumInVP + 1 > numCorrectMBs)) {
       
  1505          numCorrectBackwardsMBs = VDC_MIN(currMBNumInVP + 2,numMBsInVP);       
       
  1506          numCorrectMBs = VDC_MAX(numCorrectMBs-2,0);
       
  1507 #ifdef DEBUG_OUTPUT
       
  1508          fprintf(rvlc_stat, "P-VOP strategy 3: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
       
  1509 #endif
       
  1510       }
       
  1511       /* strategy 4 */
       
  1512       else if ((backwards_errorBitPos <= errorBitPos) && 
       
  1513              (currMBNumInVP + 1 <= numCorrectMBs)) {
       
  1514          numCorrectBackwardsMBs = VDC_MIN(numCorrectMBs + 1,numMBsInVP);       
       
  1515          numCorrectMBs = VDC_MAX(currMBNumInVP-1,0);
       
  1516 #ifdef DEBUG_OUTPUT
       
  1517          fprintf(rvlc_stat, "P-VOP strategy 4: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
       
  1518 #endif
       
  1519       }
       
  1520 
       
  1521 #ifdef DEBUG_OUTPUT
       
  1522       fclose (rvlc_stat);
       
  1523 #endif
       
  1524 
       
  1525 
       
  1526       /* set the block pointers and counters to the end of the VP */
       
  1527       if ( currYMBInFrame != NULL )
       
  1528         {
       
  1529           currYMBInFrame = inOutParam->yMBInFrame + 16 * numCorrectMBs;
       
  1530           currUBlkInFrame = inOutParam->uBlockInFrame + 8 * numCorrectMBs;
       
  1531           currVBlkInFrame = inOutParam->vBlockInFrame + 8 * numCorrectMBs;
       
  1532         }
       
  1533       
       
  1534       xPosInMBs = inParam->xPosInMBs + numCorrectMBs;
       
  1535       yPosInMBs = inParam->yPosInMBs;
       
  1536       
       
  1537       if (xPosInMBs / inParam->pictParam->numMBsInMBLine) {
       
  1538          
       
  1539          int numFullLines = xPosInMBs / inParam->pictParam->numMBsInMBLine;
       
  1540          
       
  1541          if ( currYMBInFrame != NULL )
       
  1542             {
       
  1543              currYMBInFrame += 15 * yWidth * numFullLines;
       
  1544              currUBlkInFrame += 7 * uvWidth * numFullLines;
       
  1545              currVBlkInFrame += 7 * uvWidth * numFullLines;
       
  1546             }
       
  1547          xPosInMBs = xPosInMBs % inParam->pictParam->numMBsInMBLine;
       
  1548          yPosInMBs+=numFullLines;
       
  1549       }
       
  1550       
       
  1551       /* get the first MB of the list */
       
  1552       for (currMBNumInVP = 0, dlstHead(&MBList, (void **) &MBinstance); 
       
  1553          currMBNumInVP < numCorrectMBs; currMBNumInVP++) 
       
  1554          dlstNext(&MBList, (void **) &MBinstance);
       
  1555       
       
  1556       for (currMBNumInVP = numCorrectMBs; currMBNumInVP < numCorrectBackwardsMBs; currMBNumInVP++) {
       
  1557          /* The blocks whose DCT are missing, will be reconstructed (possibly again => clear effects of corrupted DCT) here,
       
  1558             using the MVs decoded from 1st partition */         
       
  1559          /* Motion vectors for P-macroblock */
       
  1560          int mvx[4];
       
  1561          int mvy[4];
       
  1562          int mbPos;       /* the position of the current macroblock, 
       
  1563                       -1 = the leftmost MB of the image, 
       
  1564                       0 = MB is not in the border of the image,
       
  1565                       1 = rightmost MB of the image */
       
  1566          
       
  1567          blcCopyPredictionMBParam_t blcParam;
       
  1568          
       
  1569          if (MBinstance == NULL) {
       
  1570             break;
       
  1571          }
       
  1572          
       
  1573          if (!MBinstance->fCodedMB) {           
       
  1574             /* Motion vectors to 0 */ 
       
  1575             mvx[0] = mvx[1] = mvx[2] = mvx[3] = 0;
       
  1576             mvy[0] = mvy[1] = mvy[2] = mvy[3] = 0;
       
  1577             mvcMarkMBNotCoded(
       
  1578                inOutParam->mvcData, 
       
  1579                xPosInMBs,
       
  1580                yPosInMBs,
       
  1581                inParam->pictParam->tr);
       
  1582             MBinstance->cbpy = 0;
       
  1583             fourMVs = 0;
       
  1584             
       
  1585          } else {
       
  1586             
       
  1587             if(MBinstance->mbClass == VDX_MB_INTER) {
       
  1588                int currMVNum;
       
  1589                
       
  1590                fourMVs = (u_char) (MBinstance->numMVs == 4);
       
  1591                
       
  1592                for (currMVNum = 0; currMVNum < MBinstance->numMVs; currMVNum++) {
       
  1593                   
       
  1594                   mvcCalcMPEGMV(
       
  1595                      inOutParam->mvcData,
       
  1596                      MBinstance->mvx[currMVNum], MBinstance->mvy[currMVNum],
       
  1597                      &mvx[currMVNum], &mvy[currMVNum],
       
  1598                      (u_char) currMVNum, fourMVs,
       
  1599                      (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine),
       
  1600                      (u_char) (currMBNumInVP == 0), 
       
  1601                      (u_char) (currMBNumInVP < (inParam->pictParam->numMBsInMBLine-1)),
       
  1602                      xPosInMBs,
       
  1603                      yPosInMBs,
       
  1604                      inParam->pictParam->tr,
       
  1605                      (MBinstance->mbClass == VDX_MB_INTRA) ? MVC_MB_INTRA : MVC_MB_INTER,
       
  1606                      &error);   
       
  1607                   
       
  1608                 if (error == ERR_MVC_MVPTR)
       
  1609                      return DMB_BIT_ERR;
       
  1610                 else if (error)
       
  1611                      return DMB_ERR;
       
  1612                         
       
  1613                   /* if MVs over VOP boundaries are not allowed */
       
  1614                   if ((xPosInMBs == 0 && mvx[currMVNum] < 0) ||
       
  1615                       (xPosInMBs == inParam->pictParam->numMBsInMBLine-1 && mvx[currMVNum] > 0) ||
       
  1616                       (yPosInMBs == 0 && mvy[currMVNum] < 0) ||
       
  1617                       (yPosInMBs == inParam->pictParam->numMBLinesInGOB-1 && mvy[currMVNum] > 0)) {
       
  1618                       mvx[currMVNum] = 0;
       
  1619                       mvy[currMVNum] = 0;
       
  1620                   }
       
  1621                }
       
  1622                
       
  1623                if (MBinstance->numMVs == 1) {
       
  1624                   mvx[1] = mvx[2] = mvx[3] = mvx[0];
       
  1625                   mvy[1] = mvy[2] = mvy[3] = mvy[0];
       
  1626                }
       
  1627                                  
       
  1628             } else { /* VDX_MB_INTRA */
       
  1629 
       
  1630                /*int predBlocks[8] = {0,0,0,0,0,0,0,0};*/
       
  1631 
       
  1632                mvcMarkMBIntra(inOutParam->mvcData, xPosInMBs, yPosInMBs, 
       
  1633                   inParam->pictParam->tr);
       
  1634                     
       
  1635 
       
  1636                     /* Conceal the MB in intra mode (use top and left predictor only)
       
  1637                     if (xPosInMBs > 0) predBlocks[5] = 1;
       
  1638                     if (yPosInMBs > 0) predBlocks[4] = 1;
       
  1639                     epixConcealMB( inParam->currPY, yPosInMBs<<1, xPosInMBs<<1, predBlocks, yWidth, 2 );
       
  1640                     epixConcealMB( inParam->currPU, yPosInMBs, xPosInMBs, predBlocks, uvWidth, 1 );
       
  1641                     epixConcealMB( inParam->currPV, yPosInMBs, xPosInMBs, predBlocks, uvWidth, 1 ); */
       
  1642 
       
  1643                mvcCalcMPEGMV(
       
  1644                   inOutParam->mvcData,
       
  1645                   0, 0,
       
  1646                   &mvx[0], &mvy[0],
       
  1647                   (u_char) 0, 0,
       
  1648                   (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine),
       
  1649                   (u_char) (currMBNumInVP == 0), 
       
  1650                   (u_char) (currMBNumInVP < (inParam->pictParam->numMBsInMBLine-1)),
       
  1651                   xPosInMBs,
       
  1652                   yPosInMBs,
       
  1653                   inParam->pictParam->tr,
       
  1654                   MVC_MB_INTRA,
       
  1655                   &error);   
       
  1656                
       
  1657                 if (error == ERR_MVC_MVPTR)
       
  1658                      return DMB_BIT_ERR;
       
  1659                 else if (error)
       
  1660                      return DMB_ERR;
       
  1661                
       
  1662                /* if MVs over VOP boundaries are not allowed */
       
  1663                if ((xPosInMBs == 0 && mvx[0] < 0) ||
       
  1664                   (xPosInMBs == inParam->pictParam->numMBsInMBLine-1 && mvx[0] > 0) ||
       
  1665                   (yPosInMBs == 0 && mvy[0] < 0) ||
       
  1666                   (yPosInMBs == inParam->pictParam->numMBLinesInGOB-1 && mvy[0] > 0)) {
       
  1667                   mvx[0] = 0;
       
  1668                   mvy[0] = 0;
       
  1669                }
       
  1670 
       
  1671                mvx[1] = mvx[2] = mvx[3] = mvx[0];
       
  1672                mvy[1] = mvy[2] = mvy[3] = mvy[0];        
       
  1673             }
       
  1674          }
       
  1675          
       
  1676          /* mbPos, needed in blcCopyPredictionMB */
       
  1677          if (xPosInMBs == 0)
       
  1678             mbPos = -1;
       
  1679          else if (xPosInMBs == inParam->pictParam->numMBsInMBLine - 1)
       
  1680             mbPos = 1;
       
  1681          else
       
  1682             mbPos = 0;
       
  1683          
       
  1684 /*         if (!MBinstance->fCodedMB || MBinstance->mbClass == VDX_MB_INTER) {*/
       
  1685             blcParam.refY = inParam->refY;
       
  1686             blcParam.refU = inParam->refU;
       
  1687             blcParam.refV = inParam->refV;
       
  1688             blcParam.currYMBInFrame = currYMBInFrame;
       
  1689             blcParam.currUBlkInFrame = currUBlkInFrame;
       
  1690             blcParam.currVBlkInFrame = currVBlkInFrame;
       
  1691             blcParam.uvBlkXCoord = xPosInMBs * 8;
       
  1692             blcParam.uvBlkYCoord = yPosInMBs * 8;
       
  1693             blcParam.uvWidth = uvWidth;
       
  1694             blcParam.uvHeight = inParam->pictParam->lumMemHeight / 2;
       
  1695             blcParam.mvcData = inOutParam->mvcData;
       
  1696             blcParam.mvx = mvx;
       
  1697             blcParam.mvy = mvy;
       
  1698             blcParam.mbPlace = mbPos;
       
  1699             blcParam.fAdvancedPrediction = inParam->pictParam->fAP;
       
  1700             blcParam.fMVsOverPictureBoundaries =
       
  1701                inParam->pictParam->fMVsOverPictureBoundaries;
       
  1702             blcParam.diffMB = inOutParam->diffMB;
       
  1703             blcParam.rcontrol = inParam->pictParam->rtype;
       
  1704             blcParam.fourMVs = fourMVs;
       
  1705             
       
  1706             /* Do motion compensation */
       
  1707             if (blcCopyPredictionMB(&blcParam) < 0) {
       
  1708                goto exitFunction;
       
  1709             }
       
  1710 /*         }*/
       
  1711          
       
  1712          /* increment the block pointers and counters */
       
  1713          if ( currYMBInFrame != NULL )
       
  1714             {
       
  1715              currYMBInFrame += 16;
       
  1716              currUBlkInFrame += 8;
       
  1717              currVBlkInFrame += 8;
       
  1718             }
       
  1719          xPosInMBs++;
       
  1720          
       
  1721          if (xPosInMBs == inParam->pictParam->numMBsInMBLine) {
       
  1722           if ( currYMBInFrame != NULL )
       
  1723             {
       
  1724                 currYMBInFrame += 15 * yWidth;
       
  1725                 currUBlkInFrame += 7 * uvWidth;
       
  1726                 currVBlkInFrame += 7 * uvWidth;
       
  1727             }
       
  1728             xPosInMBs = 0;
       
  1729             yPosInMBs++;
       
  1730             if (yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
       
  1731                break;
       
  1732          }
       
  1733          
       
  1734          dlstNext(&MBList, (void **) &MBinstance);
       
  1735       }
       
  1736     } 
       
  1737 
       
  1738 #ifdef DEBUG_OUTPUT
       
  1739    if (errorBitPos)
       
  1740    deb_core("%08lu: MB#%3d VP Data Starts\n%08lu: Motion Marker\n%08lu: DCT data starts\n%08lu: MB#%3d Next VP/VOP Header\n%08lu: Fw Error Detected\n%08lu: Bw Error Detected\n", 
       
  1741       startVPBitPos, (inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs),
       
  1742       motionMarkerBitPos, startBlockDataBitPos, nextVPBitPos, lastMBNum, 
       
  1743       errorBitPos,backwards_errorBitPos);
       
  1744 #endif
       
  1745 
       
  1746    /* if no error in Part1 and Part2, set the currentMB to the first MB of the next VP */
       
  1747    inOutParam->currMBNum += numMBsInVP;
       
  1748 
       
  1749 exitFunction:
       
  1750 
       
  1751    deb1p("dmbsGetAndDecodePMBsDataPartitioned:Finished.\n",inOutParam->currMBNum);
       
  1752    /* Free the MB list */
       
  1753    if (MBList.numItems != 0)
       
  1754    {     
       
  1755       dlstHead(&MBList, (void **) &MBinstance);
       
  1756       dlstRemove(&MBList, (void **) &MBinstance);
       
  1757       while (MBinstance != NULL) {
       
  1758          free(MBinstance);
       
  1759          dlstRemove(&MBList, (void **) &MBinstance);
       
  1760       }
       
  1761       dlstClose(&MBList);
       
  1762    }
       
  1763 
       
  1764    return DMBS_OK;
       
  1765 }
       
  1766 // End of File