videoeditorengine/h263decoder/src/decmbs_dp_mpeg.cpp
changeset 0 951a5db380a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/h263decoder/src/decmbs_dp_mpeg.cpp	Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,1766 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:  
+* MB decoding in data partitioned mode (MPEG-4).
+*
+*/
+
+
+
+/*
+ * Includes 
+ */
+#include "h263dConfig.h"
+#include "decmbs.h"
+#include "decmbdct.h"
+#include "viddemux.h"
+#include "errcodes.h"
+#include "sync.h"
+#include "mpegcons.h"
+#include "debug.h"
+/* MVE */
+#include "MPEG4Transcoder.h"
+
+/*
+ * Local functions
+ */
+
+
+/*
+ * Global functions
+ */
+
+/* {{-output"dmbsGetAndDecodeIMBsDataPartitioned.txt"}} */
+/*
+ * dmbsGetAndDecodeIMBsDataPartitioned
+ *    
+ *
+ * Parameters:
+ *    inParam                    input parameters
+ *    inOutParam                 input/output parameters, these parameters
+ *                               may be modified in the function
+ *
+ * Function:
+ *    This function gets and decodes the MBs of a data partitioned 
+ *    Video Packet in an Intra Frame.
+ *
+ * Returns:
+ *    >= 0                       the function was successful
+ *    < 0                        an error occured
+ *
+ */
+
+int dmbsGetAndDecodeIMBsDataPartitioned(
+   dmbIFrameMBInParam_t *inParam,
+   dmbIFrameMBInOutParam_t *inOutParam,
+   int *quantParams, CMPEG4Transcoder *hTranscoder)
+/* {{-output"dmbsGetAndDecodeIMBsDataPartitioned.txt"}} */
+{
+   int retValue = DMBS_OK;
+
+   int currMBNumInVP, lastMBNum, numMBsInVP, numCorrectMBs;
+   int yWidth = inParam->pictParam->lumMemWidth;
+   int uvWidth = yWidth / 2;
+   int bitErrorIndication = 0, ret = 0, sncCode, bitsGot, bitErrorsInPart1 = 0;
+   u_int32 startVPBitPos = 0, 
+         errorBitPos = 0,
+         backwards_errorBitPos = 0,
+         nextVPBitPos = 0,
+         startBlockDataBitPos = 0,
+         DCMarkerBitPos = 0;
+   u_char fPart1Error=0, fPart2Error=0, fBlockError=0;
+   int16 error = 0;
+#ifdef DEBUG_OUTPUT
+   FILE *rvlc_stat;
+#endif
+
+   dlst_t MBList;
+   vdxIMBListItem_t *MBinstance;
+
+   vdxGetDataPartitionedIMBLayerInputParam_t vdxDPIn;
+   dmdMPEGIParam_t dmdIn;
+   
+   if (dlstOpen(&MBList) < 0)
+      return DMBS_ERR;
+
+   /* mark the bit position at the beginning of the VP */
+   startVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+
+   /* 
+    * read the first partition: DC coefficients, etc. 
+    */
+
+   vdxDPIn.intra_dc_vlc_thr = inParam->pictParam->intra_dc_vlc_thr;
+   vdxDPIn.quant = inOutParam->quant;
+
+   /* MVE */
+   ret = vdxGetDataPartitionedIMBLayer_Part1(inParam->inBuffer, inParam->outBuffer, 
+         inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), 
+         &(inOutParam->StartBitIndex), hTranscoder, &vdxDPIn, &MBList, 
+         &bitErrorIndication);
+
+   bitErrorsInPart1 = bitErrorIndication;
+   if (ret < 0) {
+       retValue = DMBS_ERR;
+       goto exitFunction;
+   }
+   else if (ret == VDX_OK_BUT_BIT_ERROR) {
+
+      fPart1Error = 1;
+      bitErrorIndication = 0;
+      deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - DC partition error.\n");
+   } else {
+      DCMarkerBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   }
+
+   /* read the next VP header to determine the number of MBs in this VP */
+   if ( fPart1Error ) {
+       /* Stop decoding this segment */
+      goto exitFunction;
+   }
+   else {
+      sncCode = sncRewindAndSeekNewMPEGSync( 1,
+          inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
+   }
+   if (error) {
+      if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
+      else { 
+          retValue = DMBS_ERR;
+          goto exitFunction;          
+      }
+   }
+   
+   nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   
+   if (sncCode == SNC_VIDPACK) {
+      
+      vdxVideoPacketHeader_t header;
+      vdxGetVideoPacketHeaderInputParam_t vdxParam;
+      int retValue;
+      
+      vdxParam.fcode_forward = inParam->pictParam->fcode_forward;
+      vdxParam.time_increment_resolution = inParam->pictParam->time_increment_resolution;
+      vdxParam.numOfMBs = inParam->pictParam->numMBsInGOB;
+      
+      retValue = vdxGetVideoPacketHeader(inParam->inBuffer, &vdxParam, &header, &bitErrorIndication);
+      if (retValue < 0) {
+          retValue = DMBS_ERR;
+          goto exitFunction;      
+      } else if (retValue == VDX_OK_BUT_BIT_ERROR) {
+         /* If bit error occurred */
+         deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - VP Header error.\n");
+         bitErrorIndication = 0;
+         lastMBNum = 0;
+      } else {    
+         lastMBNum = header.currMBNum;
+      }
+   } else {
+      lastMBNum = inParam->pictParam->numMBsInGOB;
+   }
+
+   /* rewind the bits to the beginning of the current VP data */
+   bibRewindBits(bibNumberOfFlushedBits(inParam->inBuffer) - (fPart1Error ? errorBitPos : DCMarkerBitPos),
+      inParam->inBuffer, &error);
+      
+   if (fPart1Error) {
+      /* Seek the DC_MARKER */
+      if ((sncSeekBitPattern(inParam->inBuffer, MP4_DC_MARKER, MP4_DC_MARKER_LENGTH, &error) != SNC_PATTERN) ||
+         (bibNumberOfFlushedBits(inParam->inBuffer) >= nextVPBitPos)) {
+         
+         /* rewind the bits to the beginning of the current VP data */
+         bibRewindBits( VDC_MIN(bibNumberOfRewBits(inParam->inBuffer), (bibNumberOfFlushedBits(inParam->inBuffer) - startVPBitPos)),
+            inParam->inBuffer, &error);
+
+         deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Part1Error && No DC marker found.\n");
+         goto exitFunction;
+      }
+   } 
+
+   if ((lastMBNum <= inOutParam->currMBNum) ||
+      (lastMBNum > inParam->pictParam->numMBsInGOB) ||
+      (sncCode == SNC_EOB)) {
+      numMBsInVP = MBList.numItems;
+      if (fPart1Error) fPart2Error = 1;
+   } else 
+      numMBsInVP = lastMBNum - inOutParam->currMBNum;
+
+   if (numMBsInVP != MBList.numItems || fPart1Error) {
+      deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - MB list length != num MBs.\n");
+      if ( fPart1Error || bitErrorsInPart1 ) {
+         /* Discard few MBs from the end of the list, 
+            since there are errors somewhere in the bitstream. 
+            If the list is short due to the missing packet, 
+            all the read MBs are likely to be OK and there is no
+            need to discard them */
+         dlstTail(&MBList, (void **) &MBinstance);
+         dlstRemove(&MBList, (void **) &MBinstance);
+         free( MBinstance );
+         if (numMBsInVP > MBList.numItems ) {
+            /* Take still one away */
+            dlstTail(&MBList, (void **) &MBinstance);
+            dlstRemove(&MBList, (void **) &MBinstance);
+            free( MBinstance );
+         }
+      }
+      if (numMBsInVP < MBList.numItems ) {
+         /* Discard all the extra MBs from the end of the list + 2 just to be sure, 
+            since there are errors somewhere in the bitstream */
+         while ( MBList.numItems > VDC_MAX(numMBsInVP-2,0) ) {
+            dlstTail(&MBList, (void **) &MBinstance);
+            dlstRemove(&MBList, (void **) &MBinstance);
+            free( MBinstance );
+         }
+      }
+      fPart1Error = 1;
+      errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   }
+
+   /* Flush the DC_Marker */
+   bibFlushBits(MP4_DC_MARKER_LENGTH, inParam->inBuffer, &bitsGot, &bitErrorIndication, &error);
+   if (error)
+   {
+       retValue = DMBS_ERR;
+       goto exitFunction;        
+   }
+
+   /*
+    * Read the second partition header: cpby, ac_pred_flag 
+    */
+
+   ret = vdxGetDataPartitionedIMBLayer_Part2(inParam->inBuffer, inParam->outBuffer, 
+         inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), &(inOutParam->StartBitIndex),
+         &MBList, numMBsInVP, &bitErrorIndication);
+   if (ret < 0) {
+      retValue = DMBS_ERR;
+      goto exitFunction;
+   }
+   else if (ret == VDX_OK_BUT_BIT_ERROR) {
+        fPart2Error = 1;
+        deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Part2Error.\n");
+        /* Stop decoding this segment */
+        goto exitFunction;
+   }
+
+   /* common input parameters for all blocks */
+   dmdIn.aicData = inOutParam->aicData;
+
+   /* MVE */
+   dmdIn.inBuffer = inParam->inBuffer;
+   dmdIn.outBuffer = inParam->outBuffer;
+   dmdIn.bufEdit = inParam->bufEdit;
+   dmdIn.iColorEffect = inParam->iColorEffect;
+   dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
+
+   dmdIn.yWidth = inParam->pictParam->lumMemWidth;
+   dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
+   dmdIn.pictureType = inParam->pictParam->pictureType;
+
+   /*
+    * Read block data partition in forward direction 
+    */
+
+   startBlockDataBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+
+   /* set block pointers to the beginning of the VP */   
+   dmdIn.yMBInFrame = inOutParam->yMBInFrame;
+   dmdIn.uBlockInFrame = inOutParam->uBlockInFrame;
+   dmdIn.vBlockInFrame = inOutParam->vBlockInFrame;
+
+   dmdIn.xPosInMBs = inParam->xPosInMBs;
+   dmdIn.yPosInMBs = inParam->yPosInMBs;
+
+   dmdIn.currMBNum = inOutParam->currMBNum;
+
+   /* get the first MB of the list */
+   dlstHead(&MBList, (void **) &MBinstance);
+
+   for (currMBNumInVP = 0; currMBNumInVP < numMBsInVP; currMBNumInVP++) {
+         
+         /* if MBList is shorter then the number of MBs in the VP */
+         if (MBinstance == NULL) {
+             deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - MB list < num MBs.\n");
+             goto exitFunction;
+         }
+         
+         /* header params. If partition 2 or AC partition contains errors, no bits are read any more 
+         from the bitstream, but the blocks are reconstructed based only on DC values */
+         dmdIn.cbpy = (fPart2Error || fBlockError) ? 0 : MBinstance->cbpy;
+         dmdIn.cbpc = (fPart2Error || fBlockError) ? 0 : MBinstance->cbpc;
+         dmdIn.quant = MBinstance->quant;
+         
+         /* AC/DC prediction params */
+         dmdIn.switched = MBinstance->switched;
+         
+         dmdIn.fTopOfVP = (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine);
+         dmdIn.fLeftOfVP = (u_char) (currMBNumInVP == 0);
+         dmdIn.fBBlockOut = (u_char) (currMBNumInVP <= inParam->pictParam->numMBsInMBLine);
+         
+         inOutParam->aicData->ACpred_flag = (u_char) ((fPart2Error || fBlockError) ? 0 : MBinstance->ac_pred_flag);
+         
+         /* error resilience params */
+         dmdIn.data_partitioned = 1;
+         dmdIn.DC = MBinstance->DC;
+         
+         dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;
+         dmdIn.vlc_dec_direction = 0;
+         
+         /* MVE */
+         hTranscoder->OneIMBDataStartedDataPartitioned(MBinstance, &MBList, currMBNumInVP, dmdIn.currMBNum);
+         
+         /* get the next macroblock data */
+         ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
+         
+         if ( ret < 0 ) {
+             retValue = DMBS_ERR;
+             goto exitFunction;         
+         }
+      else if ( ret == DMD_BIT_ERR ) {
+         if (fPart1Error) {
+            deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - IMB Blocks decoding error && Part1Error.\n");
+            goto exitFunction;
+         } else {
+            deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - IMB Blocks decoding error. Using DCs only.\n");
+            fBlockError = 1;
+         }
+      }
+
+      /* Store quantizer */
+      quantParams[dmdIn.currMBNum] = MBinstance->quant;
+
+      /* increment the block pointers and counters */
+      dmdIn.currMBNum++;
+      if ( dmdIn.yMBInFrame != NULL )
+        {
+            dmdIn.yMBInFrame += 16;
+            dmdIn.uBlockInFrame += 8;
+            dmdIn.vBlockInFrame += 8;
+        }
+      dmdIn.xPosInMBs++;
+
+      if (dmdIn.xPosInMBs == inParam->pictParam->numMBsInMBLine) {
+         if ( dmdIn.yMBInFrame )
+            {
+             dmdIn.yMBInFrame += 15 * yWidth;
+             dmdIn.uBlockInFrame += 7 * uvWidth;
+             dmdIn.vBlockInFrame += 7 * uvWidth;
+            }
+         dmdIn.xPosInMBs = 0;
+         dmdIn.yPosInMBs++;
+         if (dmdIn.yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
+            break;
+      }
+      
+      dlstNext(&MBList, (void **) &MBinstance);
+   }
+
+   if (!fPart1Error && !fPart2Error && !fBlockError) {
+         if (sncCode == SNC_EOB) {
+             inOutParam->currMBNum += numMBsInVP;
+             goto exitFunction;
+         } else {
+             
+             sncCode = sncCheckMpegSync(inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
+             if (sncCode == SNC_NO_SYNC) {
+                 deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - After block data no start code found.\n");
+                 if (lastMBNum != 0) 
+                     fBlockError = 1;
+             }
+         }
+   }
+
+   /*
+    * In case of error, read block data partition in backward direction 
+    */
+
+   /* WARNING: backwards decoding of INTRA frame RVLC is disabled by setting the VP size
+      higher then 10. The useful VP sizes used in low bitrates allow max. 8-10 MBs per
+     VP, but in average 3-5 MBs. With this small amount the backwards decoding always
+     causes overlap of the MB counter, and the overlapped MBs must be discarded. So the
+     RVLC doesn't have any use. */
+
+   if (!fPart2Error && fBlockError && inParam->pictParam->reversible_vlc && (numMBsInVP >= 10)) {
+      numCorrectMBs = currMBNumInVP;
+
+#ifdef DEBUG_OUTPUT
+      {
+         int bitPos[6], xpos, ypos, mbnum;
+         
+         rvlc_stat = fopen("rvlc.log", "a+t");
+         
+         fprintf(rvlc_stat, "I-VOP: (frame)(MB_first):%3d  (MB_last):%3d\n", 
+            inOutParam->currMBNum, (inOutParam->currMBNum + numMBsInVP-1));
+         
+         for (xpos = inParam->xPosInMBs, ypos = inParam->yPosInMBs, mbnum = 0; mbnum < numCorrectMBs; mbnum++, xpos++) {
+            
+            if (xpos / inParam->pictParam->numMBsInMBLine)
+               xpos = 0, ypos++;
+
+            fprintf(rvlc_stat, "fw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
+               inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
+         }
+      }
+#endif
+
+         /* find next VP header (end of MB block data of this VP) */
+      sncCode = sncRewindAndSeekNewMPEGSync(errorBitPos-startBlockDataBitPos, inParam->inBuffer,
+         inParam->pictParam->fcode_forward, &error);      
+      if (error) {
+          if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
+          else { 
+              retValue = DMBS_ERR;
+              goto exitFunction;              
+          }
+      }
+
+      if (sncCode == SNC_EOB) {
+         inOutParam->currMBNum += numMBsInVP;
+         goto exitFunction;
+      }
+
+      nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+
+      backwards_errorBitPos = startBlockDataBitPos;
+
+      /* rewind the stuffing bits */
+      if (sncCode != SNC_NO_SYNC || !(nextVPBitPos % 8)) {
+         if(sncRewindStuffing(inParam->inBuffer, &error) != SNC_PATTERN) {
+            deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, stuffing not found.\n");
+            inOutParam->currMBNum = dmdIn.currMBNum;
+            goto exitFunction;
+         }
+      }
+
+      /* set the block pointers and counters to the end of the VP */
+      if ( dmdIn.yMBInFrame != NULL )
+        {
+          dmdIn.yMBInFrame = inOutParam->yMBInFrame + 16 * (numMBsInVP-1);
+          dmdIn.uBlockInFrame = inOutParam->uBlockInFrame + 8 * (numMBsInVP-1);
+          dmdIn.vBlockInFrame = inOutParam->vBlockInFrame + 8 * (numMBsInVP-1);
+        }
+      else
+        {
+            dmdIn.yMBInFrame = dmdIn.uBlockInFrame = dmdIn.vBlockInFrame = NULL;
+        }
+      dmdIn.xPosInMBs = inParam->xPosInMBs + (numMBsInVP-1);
+      dmdIn.yPosInMBs = inParam->yPosInMBs;
+
+      if (dmdIn.xPosInMBs / inParam->pictParam->numMBsInMBLine) {
+
+         int numFullLines = dmdIn.xPosInMBs / inParam->pictParam->numMBsInMBLine;
+
+         if ( dmdIn.yMBInFrame != NULL )
+            {
+                dmdIn.yMBInFrame += 15 * yWidth * numFullLines;
+                dmdIn.uBlockInFrame += 7 * uvWidth * numFullLines;
+                dmdIn.vBlockInFrame += 7 * uvWidth * numFullLines;
+            }
+         dmdIn.xPosInMBs = dmdIn.xPosInMBs % inParam->pictParam->numMBsInMBLine;
+         dmdIn.yPosInMBs+=numFullLines;
+      }
+
+      dmdIn.currMBNum = inOutParam->currMBNum + (numMBsInVP-1);
+
+      /* get the last MB of the list */
+      dlstTail(&MBList, (void **) &MBinstance);
+
+      for (currMBNumInVP = numMBsInVP-1; currMBNumInVP >= 0; currMBNumInVP--) {
+
+         /* header params */
+         dmdIn.cbpy = MBinstance->cbpy;
+         dmdIn.cbpc = MBinstance->cbpc;
+         dmdIn.quant = MBinstance->quant;
+
+         /* AC/DC prediction params */
+         dmdIn.switched = MBinstance->switched;
+
+         dmdIn.fTopOfVP = (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine);
+         dmdIn.fLeftOfVP = (u_char) (currMBNumInVP == 0);
+         dmdIn.fBBlockOut = (u_char) (currMBNumInVP <= inParam->pictParam->numMBsInMBLine);
+
+         inOutParam->aicData->ACpred_flag = MBinstance->ac_pred_flag;
+
+         /* error resilience params */
+         dmdIn.data_partitioned = 1;
+         dmdIn.DC = MBinstance->DC;
+
+         dmdIn.reversible_vlc = 1;
+         dmdIn.vlc_dec_direction = 1;
+                 
+         /* get the next macroblock data */
+         ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
+                 
+         if ( ret < 0 ) {
+             retValue = DMBS_ERR;
+             goto exitFunction;                      
+         }
+         else if ( ret == DMD_BIT_ERR ) {
+            backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+            deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, IMB Blocks error.\n");
+            break;
+         }
+
+
+         if (bibNumberOfFlushedBits(inParam->inBuffer) <= startBlockDataBitPos) {
+            deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, block data start position reached.\n");
+            break;
+         }
+
+         /* deincrement the block pointers and counters */
+         dmdIn.xPosInMBs--;
+         if (dmdIn.xPosInMBs < 0) {
+            if (dmdIn.yPosInMBs > 0) {
+               if ( dmdIn.yMBInFrame != NULL )
+                {
+                   dmdIn.yMBInFrame -= 15 * yWidth;
+                   dmdIn.uBlockInFrame -= 7 * uvWidth;
+                   dmdIn.vBlockInFrame -= 7 * uvWidth;
+                }
+               dmdIn.xPosInMBs = inParam->pictParam->numMBsInMBLine -1;
+               dmdIn.yPosInMBs--;
+            } else {
+               dmdIn.xPosInMBs = 0;
+               backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+               break;
+            }
+         }
+         if ( dmdIn.yMBInFrame != NULL )
+         {
+             dmdIn.yMBInFrame -= 16;
+             dmdIn.uBlockInFrame -= 8;
+             dmdIn.vBlockInFrame -= 8;
+         }
+
+         dmdIn.currMBNum--;
+         dlstPrev(&MBList, (void **) &MBinstance);
+      }
+
+      if (currMBNumInVP < 0) {
+         currMBNumInVP = 0;
+         backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+         deb("dmbsGetAndDecodeIMBsDataPartitioned:ERROR - Backwards decoding, all MBs decoded without detected error.\n");
+      }
+
+#ifdef DEBUG_OUTPUT
+      {
+         int bitPos[6], xpos, ypos, mbnum;
+         
+         for (xpos = dmdIn.xPosInMBs, ypos = dmdIn.yPosInMBs, mbnum = currMBNumInVP; mbnum < numMBsInVP; mbnum++, xpos++) {
+            
+            if (xpos / inParam->pictParam->numMBsInMBLine)
+               xpos = 0, ypos++;
+            
+            fprintf(rvlc_stat, "bw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
+               inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
+         }
+
+         fprintf(rvlc_stat, "(blk_st):%8u (fw_det):%8u (bw_det):%8u (nxt_vp):%8u\n", 
+            startBlockDataBitPos, errorBitPos, backwards_errorBitPos, nextVPBitPos);
+      }
+#endif
+
+      /* strategy 1 */
+      if ((backwards_errorBitPos > errorBitPos) && 
+         (currMBNumInVP + 1 > numCorrectMBs)) {
+#ifdef DEBUG_OUTPUT
+         fprintf(rvlc_stat, "I-VOP: strategy 1!\n\n");
+#endif
+      
+      }
+      /* strategy 2 */
+      else if ((backwards_errorBitPos > errorBitPos) && 
+            (currMBNumInVP + 1 <= numCorrectMBs)) {
+         numCorrectMBs = VDC_MAX(currMBNumInVP-1,0);
+      }
+      /* strategy 3 */
+      else if ((backwards_errorBitPos <= errorBitPos) && 
+            (currMBNumInVP + 1 > numCorrectMBs)) {
+#ifdef DEBUG_OUTPUT
+         fprintf(rvlc_stat, "I-VOP: strategy 3!\n\n");
+#endif
+         
+      }
+      /* strategy 4 */
+      else if ((backwards_errorBitPos <= errorBitPos) && 
+            (currMBNumInVP + 1 <= numCorrectMBs)) {
+         numCorrectMBs = VDC_MAX(currMBNumInVP,0);
+      }
+         
+#ifdef DEBUG_OUTPUT
+      fclose (rvlc_stat);
+#endif
+
+      /* if backward decoding, set the currentMB to the first MB of the next VP */
+      inOutParam->currMBNum += numMBsInVP;
+
+    } else {   
+      /* if no error or no backward decoding, set the currentMB */
+      inOutParam->currMBNum = dmdIn.currMBNum;
+   }
+
+#ifdef DEBUG_OUTPUT
+   if (errorBitPos)
+   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", 
+      startVPBitPos, (inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs),
+      DCMarkerBitPos, startBlockDataBitPos, nextVPBitPos, lastMBNum, 
+      errorBitPos,backwards_errorBitPos);
+#endif
+
+exitFunction:
+
+   deb1p("dmbsGetAndDecodeIMBsDataPartitioned:Finished.\n",inOutParam->currMBNum);
+   /* Free the MB list */
+   if (MBList.numItems != 0)
+   {     
+      dlstHead(&MBList, (void **) &MBinstance);
+      dlstRemove(&MBList, (void **) &MBinstance);
+      while (MBinstance != NULL) {
+         free(MBinstance);
+         dlstRemove(&MBList, (void **) &MBinstance);
+      }
+      dlstClose(&MBList);
+   }
+
+   return retValue;   
+}
+
+
+/* {{-output"dmbsGetAndDecodePMBsDataPartitioned.txt"}} */
+/*
+ * dmbsGetAndDecodePMBsDataPartitioned
+ *    
+ *
+ * Parameters:
+ *    inParam                    input parameters
+ *    inOutParam                 input/output parameters, these parameters
+ *                               may be modified in the function
+ *
+ * Function:
+ *    This function gets and decodes the MBs of a data partitioned 
+ *    Video Packet in an Inter Frame.
+ *
+ * Returns:
+ *    >= 0                       the function was successful
+ *    < 0                        an error occured
+ *
+ */
+
+int dmbsGetAndDecodePMBsDataPartitioned(
+   const dmbPFrameMBInParam_t *inParam,
+   dmbPFrameMBInOutParam_t *inOutParam,
+   int *quantParams, CMPEG4Transcoder *hTranscoder)
+/* {{-output"dmbsGetAndDecodePMBsDataPartitioned.txt"}} */
+{
+   int currMBNumInVP, currMBNum, numMBsInVP, lastMBNum, numCorrectMBs, numCorrectBackwardsMBs = 0;
+   int xPosInMBs, yPosInMBs;
+   int yWidth = inParam->pictParam->lumMemWidth;
+   int uvWidth = yWidth / 2;
+   int bitErrorIndication = 0, 
+      ret = 0, sncCode, bitsGot,
+      bitErrorsInPart1 = 0;
+   u_int32 errorBitPos = 0,
+         backwards_errorBitPos = 0,
+         nextVPBitPos = 0,
+         startBlockDataBitPos = 0,
+         motionMarkerBitPos = 0;
+   u_char fPart1Error=0, fPart2Error=0, fBlockError=0;
+   u_char *currYMBInFrame, *currUBlkInFrame, *currVBlkInFrame;
+   u_char fourMVs = 0;
+#ifdef DEBUG_OUTPUT
+   FILE *rvlc_stat;
+#endif
+
+   int16 error = 0;
+
+   dlst_t MBList;
+   vdxPMBListItem_t *MBinstance;
+
+   vdxGetDataPartitionedPMBLayerInputParam_t vdxDPIn;
+   
+   if (dlstOpen(&MBList) < 0)
+      return DMBS_ERR;
+
+   currMBNum = inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs;
+
+   /* Store initial quantizer */
+   quantParams[currMBNum] = inOutParam->quant;
+
+   /* 
+    * read the first partition: DC coefficients, etc. 
+    */
+
+   vdxDPIn.intra_dc_vlc_thr = inParam->pictParam->intra_dc_vlc_thr;
+   vdxDPIn.quant = inOutParam->quant;
+   vdxDPIn.f_code = inParam->pictParam->fcode_forward;
+
+   ret = vdxGetDataPartitionedPMBLayer_Part1(inParam->inBuffer, inParam->outBuffer, 
+         inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), &(inOutParam->StartBitIndex),
+         &vdxDPIn, &MBList, &bitErrorIndication);
+   bitErrorsInPart1 = bitErrorIndication;
+   if (ret < 0)
+      return DMBS_ERR;
+   else if (ret == VDX_OK_BUT_BIT_ERROR) {
+
+      /* Must break down decoding, because even if we know the number of MBs 
+         in the 2nd partition, the content (quant, ac_pred_flag) is dependent
+        on "not_coded" and the type of MB (I-vop or P-vop), which information
+        is derived from the 1st !currupted! partition. */
+      
+      deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Part 1 Error.\n");
+      fPart1Error = 1;
+      bitErrorIndication = 0;
+      errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   } else {
+      motionMarkerBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   }
+
+   /* read the next VP header to determine the number of MBs in this VP */
+   if ( fPart1Error ) {
+       /* Stop decoding this segment */
+      goto exitFunction;
+   }
+   else {
+      sncCode = sncRewindAndSeekNewMPEGSync( 1,
+          inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
+   }
+   if (error) {
+      if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
+      else 
+          return DMBS_ERR;
+   }
+   
+   nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   
+   if (sncCode == SNC_VIDPACK) {
+      
+      vdxVideoPacketHeader_t header;
+      vdxGetVideoPacketHeaderInputParam_t vdxParam;
+      int retValue = 0;
+      
+      vdxParam.fcode_forward = inParam->pictParam->fcode_forward;
+      vdxParam.time_increment_resolution = inParam->pictParam->time_increment_resolution;
+      vdxParam.numOfMBs = inParam->pictParam->numMBsInGOB;
+      
+      retValue = vdxGetVideoPacketHeader(inParam->inBuffer, &vdxParam, &header, &bitErrorIndication);
+      if (retValue < 0) {
+         return DMBS_ERR;
+      } else if (retValue == VDX_OK_BUT_BIT_ERROR) {
+         /* If bit error occurred */
+         deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Reading Next VP Header error.\n");
+         lastMBNum = 0;
+      } else {
+         lastMBNum = header.currMBNum;
+      }
+   } else {
+      lastMBNum = inParam->pictParam->numMBsInGOB;
+   }
+
+   /* signaling to the caller function, that the Next VP header has been read */
+   inOutParam->currMBNumInVP = lastMBNum;
+      
+   /* rewind the bits before the next resync_marker */
+   bibRewindBits(bibNumberOfFlushedBits(inParam->inBuffer) - (fPart1Error ? nextVPBitPos: motionMarkerBitPos),
+      inParam->inBuffer, &error);
+   
+   if ((bitErrorIndication && !fPart1Error) || 
+      (lastMBNum <= currMBNum || lastMBNum > inParam->pictParam->numMBsInGOB) ||
+      (sncCode == SNC_EOB)) {
+      bitErrorIndication = 0;
+      numMBsInVP = MBList.numItems;
+   } else
+      numMBsInVP = lastMBNum - currMBNum;
+
+   if (numMBsInVP != MBList.numItems || fPart1Error) {
+      deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - MB list length != num MBs.\n");
+      if ( fPart1Error || bitErrorsInPart1 ) {
+         /* Discard few MBs from the end of the list, 
+            since there are errors somewhere in the bitstream. 
+            If the list is short due to the missing packet, 
+            all the read MBs are likely to be OK and there is no
+            need to discard them */
+         dlstTail(&MBList, (void **) &MBinstance);
+         dlstRemove(&MBList, (void **) &MBinstance);
+         free( MBinstance );
+         if (numMBsInVP > MBList.numItems ) {
+            /* Take still one away */
+            dlstTail(&MBList, (void **) &MBinstance);
+            dlstRemove(&MBList, (void **) &MBinstance);
+            free( MBinstance );
+         }
+      }
+      if (numMBsInVP < MBList.numItems ) {
+         /* Discard all the extra MBs from the end of the list + 2 just to be sure, 
+            since there are errors somewhere in the bitstream */
+         while ( MBList.numItems > VDC_MAX(numMBsInVP-2,0) ) {
+            dlstTail(&MBList, (void **) &MBinstance);
+            dlstRemove(&MBList, (void **) &MBinstance);
+            free( MBinstance );
+         }
+      }
+      fPart1Error = 1;
+      errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   }
+
+   if (currMBNum + numMBsInVP > inParam->pictParam->numMBsInGOB) {
+      deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Determined numMBsInVP overrun numMBsInFrame.\n");
+      fPart1Error = 1;
+      errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+      numMBsInVP = inParam->pictParam->numMBsInGOB - currMBNum;
+   }
+
+   if (!fPart1Error) {
+      
+      /* Flush the Motion_Marker */
+      bibFlushBits(MP4_MOTION_MARKER_COMB_LENGTH, inParam->inBuffer, &bitsGot, &bitErrorIndication, &error);
+      if (error)
+         return DMBS_ERR;
+      
+      /*
+       * Read the second partition header: cpby, ac_pred_flag 
+       */
+
+      ret = vdxGetDataPartitionedPMBLayer_Part2(inParam->inBuffer, inParam->outBuffer, 
+                inParam->bufEdit, inParam->iColorEffect, &(inOutParam->StartByteIndex), 
+                &(inOutParam->StartBitIndex), hTranscoder, 
+                &vdxDPIn, &MBList, &bitErrorIndication);
+      if (ret < 0)
+         return DMBS_ERR;
+      else if (ret == VDX_OK_BUT_BIT_ERROR) {
+         deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Part 2 Error.\n");
+         fPart2Error = 1;
+         /* Stop decoding this segment */
+         goto exitFunction;
+      }
+   }
+
+   /*
+    * Count the motion vectors and copy the prediction blocks 
+    */
+   
+   xPosInMBs = inParam->xPosInMBs;
+   yPosInMBs = inParam->yPosInMBs;
+   currYMBInFrame = inOutParam->yMBInFrame;
+   currUBlkInFrame = inOutParam->uBlockInFrame;
+   currVBlkInFrame = inOutParam->vBlockInFrame;
+
+   /* get the first MB of the list */
+   dlstHead(&MBList, (void **) &MBinstance);
+
+   for (currMBNumInVP = 0; currMBNumInVP < numMBsInVP; currMBNumInVP++) {
+
+      /* Motion vectors for P-macroblock */
+      int mvx[4];
+      int mvy[4];
+       int mbPos;       /* the position of the current macroblock, 
+                           -1 = the leftmost MB of the image, 
+                           0 = MB is not in the border of the image, 
+                           1 = rightmost MB of the image */
+
+      blcCopyPredictionMBParam_t blcParam;
+      
+      /* if MBList is shorter then the number of MBs in the VP */
+      if (MBinstance == NULL) {
+         deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - MB list < num MBs.\n");
+         inOutParam->currMBNum = currMBNum;
+         goto exitFunction;
+      }
+
+      if (!MBinstance->fCodedMB) {
+         
+         inOutParam->fCodedMBs[currMBNum] = 0;
+         /* Motion vectors to 0 */ 
+         mvx[0] = mvx[1] = mvx[2] = mvx[3] = 0;
+         mvy[0] = mvy[1] = mvy[2] = mvy[3] = 0;
+         mvcMarkMBNotCoded(
+            inOutParam->mvcData, 
+            xPosInMBs,
+            yPosInMBs,
+            inParam->pictParam->tr);
+         MBinstance->cbpy = 0;
+         fourMVs = 0;
+
+      } else {
+
+         inOutParam->fCodedMBs[currMBNum] = 1;
+         inOutParam->numOfCodedMBs++;
+         
+         if(MBinstance->mbClass == VDX_MB_INTER) {
+            int currMVNum;
+
+            fourMVs = (u_char) (MBinstance->numMVs == 4);
+         
+            for (currMVNum = 0; currMVNum < MBinstance->numMVs; currMVNum++) {
+
+               mvcCalcMPEGMV(
+                  inOutParam->mvcData,
+                  MBinstance->mvx[currMVNum], MBinstance->mvy[currMVNum],
+                  &mvx[currMVNum], &mvy[currMVNum],
+                  (u_char) currMVNum, fourMVs,
+                  (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine),
+                  (u_char) (currMBNumInVP == 0), 
+                  (u_char) (currMBNumInVP < (inParam->pictParam->numMBsInMBLine-1)),
+                  xPosInMBs,
+                  yPosInMBs,
+                  inParam->pictParam->tr,
+                  (MBinstance->mbClass == VDX_MB_INTRA) ? MVC_MB_INTRA : MVC_MB_INTER,
+                  &error);   
+
+                if (error == ERR_MVC_MVPTR)
+                     return DMB_BIT_ERR;
+                else if (error)
+                     return DMB_ERR;
+            }
+            
+            if (MBinstance->numMVs == 1) {
+               mvx[1] = mvx[2] = mvx[3] = mvx[0];
+               mvy[1] = mvy[2] = mvy[3] = mvy[0];
+            }
+
+         } else { /* VDX_MB_INTRA */
+            mvcMarkMBIntra(inOutParam->mvcData, xPosInMBs, yPosInMBs, 
+               inParam->pictParam->tr);
+
+         }
+      }
+
+      /* mbPos, needed in blcCopyPredictionMB */
+      if (xPosInMBs == 0)
+         mbPos = -1;
+      else if (xPosInMBs == inParam->pictParam->numMBsInMBLine - 1)
+         mbPos = 1;
+      else
+         mbPos = 0;
+
+      if (!MBinstance->fCodedMB || MBinstance->mbClass == VDX_MB_INTER) {
+                blcParam.refY = inParam->refY;
+                blcParam.refU = inParam->refU;
+                blcParam.refV = inParam->refV;
+                blcParam.currYMBInFrame = currYMBInFrame;
+                blcParam.currUBlkInFrame = currUBlkInFrame;
+                blcParam.currVBlkInFrame = currVBlkInFrame;
+                blcParam.uvBlkXCoord = xPosInMBs * 8;
+                blcParam.uvBlkYCoord = yPosInMBs * 8;
+                blcParam.uvWidth = uvWidth;
+                blcParam.uvHeight = inParam->pictParam->lumMemHeight / 2;
+                blcParam.mvcData = inOutParam->mvcData;
+                blcParam.mvx = mvx;
+                blcParam.mvy = mvy;
+                blcParam.mbPlace = mbPos;
+                blcParam.fAdvancedPrediction = inParam->pictParam->fAP;
+                blcParam.fMVsOverPictureBoundaries =
+                    inParam->pictParam->fMVsOverPictureBoundaries;
+                blcParam.diffMB = inOutParam->diffMB;
+                blcParam.rcontrol = inParam->pictParam->rtype;
+                blcParam.fourMVs = fourMVs;
+                
+                /* MVE */
+                if (inParam->iGetDecodedFrame || hTranscoder->NeedDecodedYUVFrame())
+                {
+                    
+                    /* Do motion compensation */
+                    if (blcCopyPredictionMB(&blcParam) < 0) {
+                        deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Block copying failed, illegal MV.\n");
+                        inOutParam->currMBNum = currMBNum;
+                        goto exitFunction;
+                        /* MV was illegal => caused by bitError */
+                    }
+                }
+      }
+            
+      currMBNum++;
+
+      /* increment the block pointers and counters */
+      if ( currYMBInFrame != NULL )
+        {
+          currYMBInFrame += 16;
+          currUBlkInFrame += 8;
+          currVBlkInFrame += 8;
+        }
+      xPosInMBs++;
+
+      if (xPosInMBs == inParam->pictParam->numMBsInMBLine) {
+          if ( currYMBInFrame != NULL )
+            {
+                currYMBInFrame += 15 * yWidth;
+                currUBlkInFrame += 7 * uvWidth;
+                currVBlkInFrame += 7 * uvWidth;
+            }
+            xPosInMBs = 0;
+            yPosInMBs++;
+            if (yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
+                break;
+      }
+            
+      /* MVE */
+      MBinstance->mv_x[0] = mvx[0]; MBinstance->mv_x[1] = mvx[1]; MBinstance->mv_x[2] = mvx[2]; MBinstance->mv_x[3] = mvx[3];
+      MBinstance->mv_y[0] = mvy[0]; MBinstance->mv_y[1] = mvy[1]; MBinstance->mv_y[2] = mvy[2]; MBinstance->mv_y[3] = mvy[3];
+            
+      dlstNext(&MBList, (void **) &MBinstance);
+   }
+     
+   /* if error occured in the first 2 MV&header partitions, then stop decoding */
+   if (fPart1Error || fPart2Error) {
+
+#ifdef DEBUG_OUTPUT
+      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", 
+         startVPBitPos, (inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs),
+         motionMarkerBitPos, startBlockDataBitPos, nextVPBitPos, lastMBNum, 
+         errorBitPos);
+#endif
+      
+      inOutParam->currMBNum = currMBNum;
+      goto exitFunction;
+   }
+
+   /*
+    * Read block data partition in forward direction 
+    */
+
+   xPosInMBs = inParam->xPosInMBs;
+   yPosInMBs = inParam->yPosInMBs;
+   currMBNumInVP = 0;
+   currMBNum = inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs;
+   currYMBInFrame = inOutParam->yMBInFrame;
+   currUBlkInFrame = inOutParam->uBlockInFrame;
+   currVBlkInFrame = inOutParam->vBlockInFrame;
+
+   startBlockDataBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+
+   for (dlstHead(&MBList, (void **) &MBinstance); 
+     MBinstance != NULL; 
+     dlstNext(&MBList, (void **) &MBinstance))
+   {
+        /* MVE */
+        hTranscoder->OnePMBDataStartedDataPartitioned(MBinstance, &MBList, currMBNumInVP, currMBNum);
+         
+        if (MBinstance->fCodedMB) {
+             
+            /* If INTER MB */
+            if (MBinstance->mbClass == VDX_MB_INTER) {
+                dmdPParam_t dmdIn;
+                     
+                dmdIn.inBuffer = inParam->inBuffer;
+                dmdIn.outBuffer = inParam->outBuffer;
+                dmdIn.bufEdit = inParam->bufEdit;
+                dmdIn.iColorEffect = inParam->iColorEffect;
+                dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
+                dmdIn.cbpy = MBinstance->cbpy;
+                dmdIn.cbpc = MBinstance->cbpc;
+                dmdIn.quant = MBinstance->quant;
+                     
+                /* MVE */
+                dmdIn.refY = inParam->refY;
+                dmdIn.refU = inParam->refU;
+                dmdIn.refV = inParam->refV;
+                dmdIn.mvx  = MBinstance->mv_x;
+                dmdIn.mvy  = MBinstance->mv_y;
+
+                dmdIn.currYMBInFrame = currYMBInFrame;
+                dmdIn.currUBlkInFrame = currUBlkInFrame;
+                dmdIn.currVBlkInFrame = currVBlkInFrame;
+                dmdIn.uvWidth = uvWidth;
+                dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;     
+                dmdIn.vlc_dec_direction = 0;
+
+                dmdIn.xPosInMBs = xPosInMBs;
+                dmdIn.yPosInMBs = yPosInMBs;
+                dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
+                     
+                /* Store quantizer */
+                quantParams[currMBNum] = MBinstance->quant;
+                     
+                /* Update the AIC module data, marking the MB as Inter (quant=0) */
+                aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
+                     
+                /* Decode prediction error blocks */
+                ret = dmdGetAndDecodeMPEGPMBBlocks(&dmdIn, hTranscoder);
+                     
+                if ( ret < 0)
+                    return DMBS_ERR;
+                else if ( ret == DMD_BIT_ERR ) {
+                    deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - PMB Blocks decoding failed.\n");
+                    fBlockError = 1;
+                    errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+                    break;
+                }
+
+            }
+            /* Else block layer decoding of INTRA macroblock */
+            else {
+                dmdMPEGIParam_t dmdIn;
+                     
+                /* Get block layer parameters and decode them */
+                dmdIn.inBuffer = inParam->inBuffer;
+                dmdIn.outBuffer = inParam->outBuffer;
+                dmdIn.bufEdit = inParam->bufEdit;
+                dmdIn.iColorEffect = inParam->iColorEffect;
+                dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
+                     
+                dmdIn.cbpy = MBinstance->cbpy;
+                dmdIn.cbpc = MBinstance->cbpc;
+                dmdIn.quant = MBinstance->quant;
+                dmdIn.yWidth = yWidth;
+                dmdIn.yMBInFrame = currYMBInFrame;
+                dmdIn.uBlockInFrame = currUBlkInFrame;
+                dmdIn.vBlockInFrame = currVBlkInFrame;
+                     
+                dmdIn.xPosInMBs = xPosInMBs;
+                dmdIn.yPosInMBs = yPosInMBs;
+                dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
+                dmdIn.numMBLinesInGOB = inParam->pictParam->numMBLinesInGOB;
+                dmdIn.pictureType = inParam->pictParam->pictureType;
+                     
+                inOutParam->aicData->ACpred_flag = MBinstance->ac_pred_flag;
+                dmdIn.aicData = inOutParam->aicData;
+                     
+                dmdIn.data_partitioned = 1;
+                dmdIn.switched = MBinstance->switched;
+                dmdIn.DC = MBinstance->DC;
+                     
+                dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;
+                dmdIn.vlc_dec_direction = 0;
+                     
+                dmdIn.currMBNum = currMBNum;
+                     
+                dmdIn.fTopOfVP = (u_char) 
+                        (currMBNumInVP < inParam->pictParam->numMBsInMBLine ||
+                         !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine));
+                dmdIn.fLeftOfVP = (u_char)
+                        (currMBNumInVP == 0 || 
+                         xPosInMBs == 0 ||
+                         !aicIsBlockValid(inOutParam->aicData, currMBNum-1));
+                dmdIn.fBBlockOut = (u_char) 
+                        (currMBNumInVP <= inParam->pictParam->numMBsInMBLine ||
+                         xPosInMBs == 0 ||
+                         !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine-1));
+                     
+                ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
+                     
+                if ( ret < 0 )
+                    return DMBS_ERR;
+                else if ( ret == DMD_BIT_ERR ) {
+                    deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - IMB Blocks decoding failed.\n");
+                    fBlockError = 1;
+                    errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+                    break;
+                }
+            }
+                 
+        } else {  /* end of if coded MB */
+                     
+            /* Update the AIC module data, marking the MB as Not Coded (quant=0) */
+            aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
+        }
+                 
+        currMBNumInVP++;
+        currMBNum++;
+
+        /* increment the block pointers and counters */
+        if ( currYMBInFrame != NULL )
+         {
+            currYMBInFrame += 16;
+            currUBlkInFrame += 8;
+            currVBlkInFrame += 8;
+         }
+        xPosInMBs++;
+
+        if (xPosInMBs == inParam->pictParam->numMBsInMBLine) {
+          if ( currYMBInFrame != NULL )
+            {
+                currYMBInFrame += 15 * yWidth;
+                currUBlkInFrame += 7 * uvWidth;
+                currVBlkInFrame += 7 * uvWidth;
+            }
+            xPosInMBs = 0;
+            yPosInMBs++;
+            if (yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
+                 break;
+        }
+   } // end of for-loop
+   
+   if (!fPart1Error && !fPart2Error && !fBlockError) {
+      if (sncCode == SNC_EOB) {
+         inOutParam->currMBNum += numMBsInVP;
+         goto exitFunction;
+      } else {
+         sncCode = sncCheckMpegSync(inParam->inBuffer, inParam->pictParam->fcode_forward, &error);
+         if (sncCode == SNC_NO_SYNC) {
+            deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - After block data no start code found.\n");
+            if (lastMBNum != 0) 
+               fBlockError = 1;
+            errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+         }
+      }
+   }
+
+   /*
+    * In case of error, read block data partition in backward direction 
+   */
+
+   if (fBlockError && inParam->pictParam->reversible_vlc) {
+      numCorrectMBs = currMBNumInVP;
+
+#ifdef DEBUG_OUTPUT
+      {
+         int bitPos[6], xpos, ypos, mbnum;
+         
+         rvlc_stat = fopen("rvlc.log", "a+t");
+         
+         fprintf(rvlc_stat, "P-VOP: (MB_first):%3d  (MB_last):%3d\n", 
+            inOutParam->currMBNum, (inOutParam->currMBNum + numMBsInVP-1));
+         
+         for (xpos = inParam->xPosInMBs, ypos = inParam->yPosInMBs, mbnum = 0; mbnum < numCorrectMBs; mbnum++, xpos++) {
+            
+            if (xpos / inParam->pictParam->numMBsInMBLine)
+               xpos = 0, ypos++;
+
+            fprintf(rvlc_stat, "fw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
+               inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
+         }
+      }
+#endif
+
+         /* find next VP header (end of MB block data of this VP) */
+      sncCode = sncRewindAndSeekNewMPEGSync(errorBitPos-startBlockDataBitPos, inParam->inBuffer,
+         inParam->pictParam->fcode_forward, &error);      
+      if (error) {
+          if (error == ERR_BIB_NOT_ENOUGH_DATA) error = 0;
+          else 
+              return DMBS_ERR;
+      }
+
+      if (sncCode == SNC_EOB) {
+         inOutParam->currMBNum += numMBsInVP;
+         goto exitFunction;
+      }
+
+      nextVPBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+   
+      backwards_errorBitPos = startBlockDataBitPos;
+
+      /* rewind the stuffing bits */
+      if (sncCode != SNC_NO_SYNC || !(nextVPBitPos % 8)) {
+         if(sncRewindStuffing(inParam->inBuffer, &error) != SNC_PATTERN) {
+            deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, stuffing not found.\n");
+            goto exitFunction;
+         }
+      }
+
+      /* set the block pointers and counters to the end of the VP */
+      if ( currYMBInFrame != NULL )
+        {
+          currYMBInFrame = inOutParam->yMBInFrame + 16 * (numMBsInVP-1);
+          currUBlkInFrame = inOutParam->uBlockInFrame + 8 * (numMBsInVP-1);
+          currVBlkInFrame = inOutParam->vBlockInFrame + 8 * (numMBsInVP-1);
+        }
+
+      xPosInMBs = inParam->xPosInMBs + (numMBsInVP-1);
+      yPosInMBs = inParam->yPosInMBs;
+
+      if (xPosInMBs / inParam->pictParam->numMBsInMBLine) {
+
+         int numFullLines = xPosInMBs / inParam->pictParam->numMBsInMBLine;
+
+         if ( currYMBInFrame != NULL )
+            {
+             currYMBInFrame += 15 * yWidth * numFullLines;
+             currUBlkInFrame += 7 * uvWidth * numFullLines;
+             currVBlkInFrame += 7 * uvWidth * numFullLines;
+            }
+         xPosInMBs = xPosInMBs % inParam->pictParam->numMBsInMBLine;
+         yPosInMBs+=numFullLines;
+      }
+
+      currMBNum = inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine +
+               inParam->xPosInMBs + (numMBsInVP-1);
+      currMBNumInVP = numMBsInVP-1;
+
+      for (dlstTail(&MBList, (void **) &MBinstance); 
+         MBinstance != NULL; 
+         dlstPrev(&MBList, (void **) &MBinstance))
+      {
+         if (MBinstance->fCodedMB) 
+         {
+
+             /* If INTER MB */
+             if (MBinstance->mbClass == VDX_MB_INTER) 
+             {
+                dmdPParam_t dmdIn;
+
+                dmdIn.inBuffer = inParam->inBuffer;
+                dmdIn.outBuffer = inParam->outBuffer;
+                dmdIn.bufEdit = inParam->bufEdit;
+                dmdIn.iColorEffect = inParam->iColorEffect;
+                dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
+                dmdIn.cbpy = MBinstance->cbpy;
+                dmdIn.cbpc = MBinstance->cbpc;
+                dmdIn.quant = MBinstance->quant;
+                            
+                /* MVE */
+                dmdIn.refY = inParam->refY;
+                dmdIn.refU = inParam->refU;
+                dmdIn.refV = inParam->refV;
+                dmdIn.mvx  = MBinstance->mv_x;
+                dmdIn.mvy  = MBinstance->mv_y;
+                            
+                dmdIn.currYMBInFrame = currYMBInFrame;
+                dmdIn.currUBlkInFrame = currUBlkInFrame;
+                dmdIn.currVBlkInFrame = currVBlkInFrame;
+                dmdIn.uvWidth = uvWidth;
+                
+                dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;     
+                dmdIn.vlc_dec_direction = 1;
+                
+                dmdIn.xPosInMBs = xPosInMBs;
+                dmdIn.yPosInMBs = yPosInMBs;
+                dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
+
+                /* Update the AIC module data, marking the MB as Inter (quant=0) */
+                aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
+                
+                /* Decode prediction error blocks */
+                ret = dmdGetAndDecodeMPEGPMBBlocks(&dmdIn, hTranscoder);
+
+                if ( ret < 0)
+                   return DMBS_ERR;
+                else if ( ret == DMD_BIT_ERR ) {
+                   deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, PMB Blocks decoding failed.\n");
+                   backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+                   break;
+                }
+
+             }
+             /* Else block layer decoding of INTRA macroblock */
+             else 
+             {
+                dmdMPEGIParam_t dmdIn;
+
+                /* Get block layer parameters and decode them */
+                dmdIn.inBuffer = inParam->inBuffer;
+                dmdIn.outBuffer = inParam->outBuffer;
+                dmdIn.bufEdit = inParam->bufEdit;
+                dmdIn.iColorEffect = inParam->iColorEffect;
+                dmdIn.iGetDecodedFrame = inParam->iGetDecodedFrame;
+
+                dmdIn.cbpy = MBinstance->cbpy;
+                dmdIn.cbpc = MBinstance->cbpc;
+                dmdIn.quant = MBinstance->quant;
+                dmdIn.yWidth = yWidth;
+                dmdIn.yMBInFrame = currYMBInFrame;
+                dmdIn.uBlockInFrame = currUBlkInFrame;
+                dmdIn.vBlockInFrame = currVBlkInFrame;
+
+                dmdIn.xPosInMBs = xPosInMBs;
+                dmdIn.yPosInMBs = yPosInMBs;
+                dmdIn.numMBsInMBLine = inParam->pictParam->numMBsInMBLine;
+                dmdIn.numMBLinesInGOB = inParam->pictParam->numMBLinesInGOB;
+                dmdIn.pictureType = inParam->pictParam->pictureType;
+
+                inOutParam->aicData->ACpred_flag = MBinstance->ac_pred_flag;
+                dmdIn.aicData = inOutParam->aicData;
+
+                dmdIn.data_partitioned = inParam->pictParam->data_partitioned;
+                dmdIn.switched = MBinstance->switched;
+                dmdIn.DC = MBinstance->DC;
+
+                dmdIn.reversible_vlc = inParam->pictParam->reversible_vlc;
+                dmdIn.vlc_dec_direction = 1;
+
+                dmdIn.currMBNum = currMBNum;
+
+                dmdIn.fTopOfVP = (u_char) 
+                   (currMBNumInVP < inParam->pictParam->numMBsInMBLine ||
+                    !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine));
+                dmdIn.fLeftOfVP = (u_char)
+                   (currMBNumInVP == 0 || 
+                    xPosInMBs == 0 ||
+                    !aicIsBlockValid(inOutParam->aicData, currMBNum-1));
+                dmdIn.fBBlockOut = (u_char) 
+                   (currMBNumInVP <= inParam->pictParam->numMBsInMBLine ||
+                    xPosInMBs == 0 ||
+                    !aicIsBlockValid(inOutParam->aicData, currMBNum-inParam->pictParam->numMBsInMBLine-1));
+                
+                ret = dmdGetAndDecodeMPEGIMBBlocks(&dmdIn, hTranscoder);
+
+                if ( ret < 0 )
+                   return DMBS_ERR;
+                else if ( ret == DMD_BIT_ERR ) {
+                   deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, IMB Blocks decoding failed.\n");
+                   backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+
+                   break;
+                }
+             } // end of else
+
+         } /* end of if coded MB */
+         else 
+         {  
+       
+            /* Update the AIC module data, marking the MB as Not Coded (quant=0) */
+            aicBlockUpdate (inOutParam->aicData, currMBNum, 0, NULL, 0, 0);
+         }
+
+         if (bibNumberOfFlushedBits(inParam->inBuffer) <= startBlockDataBitPos) {
+            deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, block data start position reached.\n");
+            break;
+         }
+
+         /* deincrement the block pointers and counters */
+         xPosInMBs--;
+         if (xPosInMBs < 0) {
+            if (yPosInMBs > 0) {
+              if ( currYMBInFrame != NULL )
+                {
+                   currYMBInFrame -= 15 * yWidth;
+                   currUBlkInFrame -= 7 * uvWidth;
+                   currVBlkInFrame -= 7 * uvWidth;
+                }
+               xPosInMBs = inParam->pictParam->numMBsInMBLine -1;
+               yPosInMBs--;
+            } else {
+               xPosInMBs = 0;
+               backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+               break;
+            }
+         }
+          if ( currYMBInFrame != NULL )
+            {
+             currYMBInFrame -= 16;
+             currUBlkInFrame -= 8;
+             currVBlkInFrame -= 8;
+            }
+
+         currMBNumInVP--;
+         currMBNum--;
+      }
+
+      if (currMBNumInVP < 0) {
+         currMBNumInVP = 0;
+         backwards_errorBitPos = bibNumberOfFlushedBits(inParam->inBuffer);
+         deb("dmbsGetAndDecodePMBsDataPartitioned:ERROR - Backwards decoding, all MBs decoded without detected error.\n");
+      }
+
+#ifdef DEBUG_OUTPUT
+      {
+         int bitPos[6], xpos, ypos, mbnum;
+
+         xPosInMBs++;
+         if (xPosInMBs >= inParam->pictParam->numMBsInMBLine) {
+            xPosInMBs = 0;
+            if (yPosInMBs < (inParam->pictParam->numMBLinesInGOB-1))
+               yPosInMBs++;
+         }
+
+         for (xpos = xPosInMBs, ypos = yPosInMBs, mbnum = (currMBNumInVP+1); mbnum < numMBsInVP; mbnum++, xpos++) {
+            
+            if (xpos / inParam->pictParam->numMBsInMBLine)
+               xpos = 0, ypos++;
+            
+            fprintf(rvlc_stat, "bw: MB#%3d\tY0: %8d | Y1: %8d | Y2: %8d | Y3: %8d | U: %8d | V: %8d\n", 
+               inOutParam->currMBNum+mbnum, bitPos[0], bitPos[1], bitPos[2], bitPos[3], bitPos[4], bitPos[5]); 
+         }
+         
+         fprintf(rvlc_stat, "(blk_st):%8u (fw_det):%8u (bw_det):%8u (nxt_vp):%8u\n", 
+            startBlockDataBitPos, errorBitPos, backwards_errorBitPos, nextVPBitPos);
+      }
+#endif
+      
+      /* 
+       * Based on the decoder MB counters forwards and backwards, 
+       * recopy the "to be discarded" blocks 
+       */
+
+      /* strategy 1 */
+      if ((backwards_errorBitPos > errorBitPos) && 
+         (currMBNumInVP + 1 > numCorrectMBs)) {
+         numCorrectBackwardsMBs = VDC_MIN(currMBNumInVP + 2,numMBsInVP);       
+         numCorrectMBs = VDC_MAX(numCorrectMBs-2,0);
+#ifdef DEBUG_OUTPUT
+         fprintf(rvlc_stat, "P-VOP strategy 1: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
+#endif
+      }
+      /* strategy 2 */
+      else if ((backwards_errorBitPos > errorBitPos) && 
+             (currMBNumInVP + 1 <= numCorrectMBs)) {
+         numCorrectBackwardsMBs = VDC_MIN(numCorrectMBs + 1,numMBsInVP);
+         numCorrectMBs = VDC_MAX(currMBNumInVP-1,0);
+#ifdef DEBUG_OUTPUT
+         fprintf(rvlc_stat, "P-VOP strategy 2: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
+#endif
+      }
+      /* strategy 3 */
+      else if ((backwards_errorBitPos <= errorBitPos) && 
+             (currMBNumInVP + 1 > numCorrectMBs)) {
+         numCorrectBackwardsMBs = VDC_MIN(currMBNumInVP + 2,numMBsInVP);       
+         numCorrectMBs = VDC_MAX(numCorrectMBs-2,0);
+#ifdef DEBUG_OUTPUT
+         fprintf(rvlc_stat, "P-VOP strategy 3: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
+#endif
+      }
+      /* strategy 4 */
+      else if ((backwards_errorBitPos <= errorBitPos) && 
+             (currMBNumInVP + 1 <= numCorrectMBs)) {
+         numCorrectBackwardsMBs = VDC_MIN(numCorrectMBs + 1,numMBsInVP);       
+         numCorrectMBs = VDC_MAX(currMBNumInVP-1,0);
+#ifdef DEBUG_OUTPUT
+         fprintf(rvlc_stat, "P-VOP strategy 4: MBs %3d-%3d concealed\n\n", inOutParam->currMBNum+numCorrectMBs, inOutParam->currMBNum+numCorrectBackwardsMBs-1);
+#endif
+      }
+
+#ifdef DEBUG_OUTPUT
+      fclose (rvlc_stat);
+#endif
+
+
+      /* set the block pointers and counters to the end of the VP */
+      if ( currYMBInFrame != NULL )
+        {
+          currYMBInFrame = inOutParam->yMBInFrame + 16 * numCorrectMBs;
+          currUBlkInFrame = inOutParam->uBlockInFrame + 8 * numCorrectMBs;
+          currVBlkInFrame = inOutParam->vBlockInFrame + 8 * numCorrectMBs;
+        }
+      
+      xPosInMBs = inParam->xPosInMBs + numCorrectMBs;
+      yPosInMBs = inParam->yPosInMBs;
+      
+      if (xPosInMBs / inParam->pictParam->numMBsInMBLine) {
+         
+         int numFullLines = xPosInMBs / inParam->pictParam->numMBsInMBLine;
+         
+         if ( currYMBInFrame != NULL )
+            {
+             currYMBInFrame += 15 * yWidth * numFullLines;
+             currUBlkInFrame += 7 * uvWidth * numFullLines;
+             currVBlkInFrame += 7 * uvWidth * numFullLines;
+            }
+         xPosInMBs = xPosInMBs % inParam->pictParam->numMBsInMBLine;
+         yPosInMBs+=numFullLines;
+      }
+      
+      /* get the first MB of the list */
+      for (currMBNumInVP = 0, dlstHead(&MBList, (void **) &MBinstance); 
+         currMBNumInVP < numCorrectMBs; currMBNumInVP++) 
+         dlstNext(&MBList, (void **) &MBinstance);
+      
+      for (currMBNumInVP = numCorrectMBs; currMBNumInVP < numCorrectBackwardsMBs; currMBNumInVP++) {
+         /* The blocks whose DCT are missing, will be reconstructed (possibly again => clear effects of corrupted DCT) here,
+            using the MVs decoded from 1st partition */         
+         /* Motion vectors for P-macroblock */
+         int mvx[4];
+         int mvy[4];
+         int mbPos;       /* the position of the current macroblock, 
+                      -1 = the leftmost MB of the image, 
+                      0 = MB is not in the border of the image,
+                      1 = rightmost MB of the image */
+         
+         blcCopyPredictionMBParam_t blcParam;
+         
+         if (MBinstance == NULL) {
+            break;
+         }
+         
+         if (!MBinstance->fCodedMB) {           
+            /* Motion vectors to 0 */ 
+            mvx[0] = mvx[1] = mvx[2] = mvx[3] = 0;
+            mvy[0] = mvy[1] = mvy[2] = mvy[3] = 0;
+            mvcMarkMBNotCoded(
+               inOutParam->mvcData, 
+               xPosInMBs,
+               yPosInMBs,
+               inParam->pictParam->tr);
+            MBinstance->cbpy = 0;
+            fourMVs = 0;
+            
+         } else {
+            
+            if(MBinstance->mbClass == VDX_MB_INTER) {
+               int currMVNum;
+               
+               fourMVs = (u_char) (MBinstance->numMVs == 4);
+               
+               for (currMVNum = 0; currMVNum < MBinstance->numMVs; currMVNum++) {
+                  
+                  mvcCalcMPEGMV(
+                     inOutParam->mvcData,
+                     MBinstance->mvx[currMVNum], MBinstance->mvy[currMVNum],
+                     &mvx[currMVNum], &mvy[currMVNum],
+                     (u_char) currMVNum, fourMVs,
+                     (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine),
+                     (u_char) (currMBNumInVP == 0), 
+                     (u_char) (currMBNumInVP < (inParam->pictParam->numMBsInMBLine-1)),
+                     xPosInMBs,
+                     yPosInMBs,
+                     inParam->pictParam->tr,
+                     (MBinstance->mbClass == VDX_MB_INTRA) ? MVC_MB_INTRA : MVC_MB_INTER,
+                     &error);   
+                  
+                if (error == ERR_MVC_MVPTR)
+                     return DMB_BIT_ERR;
+                else if (error)
+                     return DMB_ERR;
+                        
+                  /* if MVs over VOP boundaries are not allowed */
+                  if ((xPosInMBs == 0 && mvx[currMVNum] < 0) ||
+                      (xPosInMBs == inParam->pictParam->numMBsInMBLine-1 && mvx[currMVNum] > 0) ||
+                      (yPosInMBs == 0 && mvy[currMVNum] < 0) ||
+                      (yPosInMBs == inParam->pictParam->numMBLinesInGOB-1 && mvy[currMVNum] > 0)) {
+                      mvx[currMVNum] = 0;
+                      mvy[currMVNum] = 0;
+                  }
+               }
+               
+               if (MBinstance->numMVs == 1) {
+                  mvx[1] = mvx[2] = mvx[3] = mvx[0];
+                  mvy[1] = mvy[2] = mvy[3] = mvy[0];
+               }
+                                 
+            } else { /* VDX_MB_INTRA */
+
+               /*int predBlocks[8] = {0,0,0,0,0,0,0,0};*/
+
+               mvcMarkMBIntra(inOutParam->mvcData, xPosInMBs, yPosInMBs, 
+                  inParam->pictParam->tr);
+                    
+
+                    /* Conceal the MB in intra mode (use top and left predictor only)
+                    if (xPosInMBs > 0) predBlocks[5] = 1;
+                    if (yPosInMBs > 0) predBlocks[4] = 1;
+                    epixConcealMB( inParam->currPY, yPosInMBs<<1, xPosInMBs<<1, predBlocks, yWidth, 2 );
+                    epixConcealMB( inParam->currPU, yPosInMBs, xPosInMBs, predBlocks, uvWidth, 1 );
+                    epixConcealMB( inParam->currPV, yPosInMBs, xPosInMBs, predBlocks, uvWidth, 1 ); */
+
+               mvcCalcMPEGMV(
+                  inOutParam->mvcData,
+                  0, 0,
+                  &mvx[0], &mvy[0],
+                  (u_char) 0, 0,
+                  (u_char) (currMBNumInVP < inParam->pictParam->numMBsInMBLine),
+                  (u_char) (currMBNumInVP == 0), 
+                  (u_char) (currMBNumInVP < (inParam->pictParam->numMBsInMBLine-1)),
+                  xPosInMBs,
+                  yPosInMBs,
+                  inParam->pictParam->tr,
+                  MVC_MB_INTRA,
+                  &error);   
+               
+                if (error == ERR_MVC_MVPTR)
+                     return DMB_BIT_ERR;
+                else if (error)
+                     return DMB_ERR;
+               
+               /* if MVs over VOP boundaries are not allowed */
+               if ((xPosInMBs == 0 && mvx[0] < 0) ||
+                  (xPosInMBs == inParam->pictParam->numMBsInMBLine-1 && mvx[0] > 0) ||
+                  (yPosInMBs == 0 && mvy[0] < 0) ||
+                  (yPosInMBs == inParam->pictParam->numMBLinesInGOB-1 && mvy[0] > 0)) {
+                  mvx[0] = 0;
+                  mvy[0] = 0;
+               }
+
+               mvx[1] = mvx[2] = mvx[3] = mvx[0];
+               mvy[1] = mvy[2] = mvy[3] = mvy[0];        
+            }
+         }
+         
+         /* mbPos, needed in blcCopyPredictionMB */
+         if (xPosInMBs == 0)
+            mbPos = -1;
+         else if (xPosInMBs == inParam->pictParam->numMBsInMBLine - 1)
+            mbPos = 1;
+         else
+            mbPos = 0;
+         
+/*         if (!MBinstance->fCodedMB || MBinstance->mbClass == VDX_MB_INTER) {*/
+            blcParam.refY = inParam->refY;
+            blcParam.refU = inParam->refU;
+            blcParam.refV = inParam->refV;
+            blcParam.currYMBInFrame = currYMBInFrame;
+            blcParam.currUBlkInFrame = currUBlkInFrame;
+            blcParam.currVBlkInFrame = currVBlkInFrame;
+            blcParam.uvBlkXCoord = xPosInMBs * 8;
+            blcParam.uvBlkYCoord = yPosInMBs * 8;
+            blcParam.uvWidth = uvWidth;
+            blcParam.uvHeight = inParam->pictParam->lumMemHeight / 2;
+            blcParam.mvcData = inOutParam->mvcData;
+            blcParam.mvx = mvx;
+            blcParam.mvy = mvy;
+            blcParam.mbPlace = mbPos;
+            blcParam.fAdvancedPrediction = inParam->pictParam->fAP;
+            blcParam.fMVsOverPictureBoundaries =
+               inParam->pictParam->fMVsOverPictureBoundaries;
+            blcParam.diffMB = inOutParam->diffMB;
+            blcParam.rcontrol = inParam->pictParam->rtype;
+            blcParam.fourMVs = fourMVs;
+            
+            /* Do motion compensation */
+            if (blcCopyPredictionMB(&blcParam) < 0) {
+               goto exitFunction;
+            }
+/*         }*/
+         
+         /* increment the block pointers and counters */
+         if ( currYMBInFrame != NULL )
+            {
+             currYMBInFrame += 16;
+             currUBlkInFrame += 8;
+             currVBlkInFrame += 8;
+            }
+         xPosInMBs++;
+         
+         if (xPosInMBs == inParam->pictParam->numMBsInMBLine) {
+          if ( currYMBInFrame != NULL )
+            {
+                currYMBInFrame += 15 * yWidth;
+                currUBlkInFrame += 7 * uvWidth;
+                currVBlkInFrame += 7 * uvWidth;
+            }
+            xPosInMBs = 0;
+            yPosInMBs++;
+            if (yPosInMBs >= inParam->pictParam->numMBLinesInGOB)
+               break;
+         }
+         
+         dlstNext(&MBList, (void **) &MBinstance);
+      }
+    } 
+
+#ifdef DEBUG_OUTPUT
+   if (errorBitPos)
+   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", 
+      startVPBitPos, (inParam->yPosInMBs*inParam->pictParam->numMBsInMBLine + inParam->xPosInMBs),
+      motionMarkerBitPos, startBlockDataBitPos, nextVPBitPos, lastMBNum, 
+      errorBitPos,backwards_errorBitPos);
+#endif
+
+   /* if no error in Part1 and Part2, set the currentMB to the first MB of the next VP */
+   inOutParam->currMBNum += numMBsInVP;
+
+exitFunction:
+
+   deb1p("dmbsGetAndDecodePMBsDataPartitioned:Finished.\n",inOutParam->currMBNum);
+   /* Free the MB list */
+   if (MBList.numItems != 0)
+   {     
+      dlstHead(&MBList, (void **) &MBinstance);
+      dlstRemove(&MBList, (void **) &MBinstance);
+      while (MBinstance != NULL) {
+         free(MBinstance);
+         dlstRemove(&MBList, (void **) &MBinstance);
+      }
+      dlstClose(&MBList);
+   }
+
+   return DMBS_OK;
+}
+// End of File