videoeditorengine/h263decoder/src/vdcmvc.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 7 4c409de21d23
--- a/videoeditorengine/h263decoder/src/vdcmvc.cpp	Fri Jan 29 14:08:33 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1701 +0,0 @@
-/*
-* 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:  
-* Motion vector calculations and storage.
-*
-*/
-
-
-
-
-#include "h263dConfig.h"
-
-#include "vdcmvc.h"
-
-#include "core.h"
-#include "errcodes.h"
-#include "debug.h"
-
-
-/* 
- * Defines 
- */
-
-#define NEIGHBOUR_SIZE 2      /* The size for neighbour array */
-#define MVD_NOT_CODED -32767  /* Macroblock is not coded in mvcTable_t */
-#define MVD_INTRA -32765      /* Marks intra macroblock in mvcTable_t */
-
-#define MVD_UMIN_MPEG4 -10240
-
-#define MVD_MIN -160          /* The minimum for mvd. */
-#define MVD_MAX 155           /* The maximum for mvd. */
-#define MVD_UMIN_V1 -315      /* The minimum for MV in unrestricted mode (v1) */
-#define MVD_UMAX_V1 315       /* The maximum for MV in unrestricted mode (v1) */
-#define MVD_UMIN_V2 -32000    /* The minimum for MV in unrestricted mode (v2)
-                                 Note: this value is used to check the validity
-                                 of MVs. If there is no MV for a MB 
-                                 MVD_NOT_CODED or MVD_INTRA are used, and
-                                 therefore any value bigger than those
-                                 suits for this definition. In H.263 v2 
-                                 unlimited submode, MVs can have any length
-                                 within a picture (plus 15-pixel border),
-                                 and therefore this definition is set to small
-                                 enough value. */
-#define MVD_155 155           /* MV for 15.5 */
-#define MVD_160 160           /* MV for 16 */
-#define MVD_320 320           /* MV for 32 */
-/* It is assumed that motion vector values are signed and in order
-   (for example MV for 15.5 < MV for 16).
-   No other assumptions are made. */
-
-
-/* 
- * Macros 
- */
-
-/* mvValid checks if the specified item is a valid motion vector */
-/* Note: MVD_NOT_CODED and MVD_INTRA are very small negative numbers.
-         Thus, we can use the minimum MV for H.263 Annex D unlimited
-         submode to check the validity of a passed item. Actually,
-         we could use any value larger than MVD_NOT_CODED and MVD_INTRA
-         and smaller than or equal to the minimum MV. */
-#define mvValid(d1item, d1y, d1time) \
-   (d1item.mvx >= MVD_UMIN_V2 \
-      && d1item.y == (d1y) && d1item.time == (d1time))
-
-
-#define mvValidMPEG(d1item, d1y, d1time) \
-   (d1item.mvx >= MVD_UMIN_MPEG4 \
-      && d1item.y == (d1y) && d1item.time == (d1time))
-
-/* mvLegal cheks if the specified item has been updated to either contain
-   a motion vector or not coded / intra information */
-#define mvLegal(d5item, d5y, d5time) \
-   (d5item.y == (d5y) && d5item.time == (d5time))
-
-/* mvStore puts given arguments into the motion vector array
-   Used from: mvcCalcMV */
-#define mvStore(d2row, d2x, d2y, d2mvx, d2mvy, d2time, d2type) \
-   d2row[d2x].mvx = d2mvx; d2row[d2x].mvy = d2mvy; \
-   d2row[d2x].y = d2y; d2row[d2x].time = d2time; d2row[d2x].fourMVs = 1; \
-   d2row[d2x].type = d2type
-
-/* mvStoreMB puts given arguments into the motion vector array for the
-   whole macroblock
-   Used from: mvcCalcMV, mvcMarkMBIntra, mvcMarkMBNotCoded */
-#define mvStoreMB(d4row1, d4row2, d4x, d4y, d4mvx, d4mvy, d4time, d4type) \
-   d4row1[d4x].mvx = d4row1[d4x + 1].mvx = \
-      d4row2[d4x].mvx = d4row2[d4x + 1].mvx = d4mvx; \
-   d4row1[d4x].mvy = d4row1[d4x + 1].mvy = \
-      d4row2[d4x].mvy = d4row2[d4x + 1].mvy = d4mvy; \
-   d4row1[d4x].y = d4row1[d4x + 1].y = d4y; \
-   d4row2[d4x].y = d4row2[d4x + 1].y = d4y + 1; \
-   d4row1[d4x].time = d4row1[d4x + 1].time = \
-      d4row2[d4x].time = d4row2[d4x + 1].time = time; \
-   d4row1[d4x].fourMVs = d4row1[d4x + 1].fourMVs = \
-      d4row2[d4x].fourMVs = d4row2[d4x + 1].fourMVs = 0; \
-   d4row1[d4x].type = d4row1[d4x + 1].type = \
-      d4row2[d4x].type = d4row2[d4x + 1].type = (d4type)
-
-/* updateRowPointers checks if currX, currY or currTime have changed
-   and updates them. It also updates mvRow0, mvRow1 and mvRow2.
-   Used from: mvcCalcMV, mvcMarkMBIntra, mvcMarkMBNotCoded */
-#define updateRowPointers(d3x, d3y, d3time) \
-   if (d3x != mvcData->currX) \
-      mvcData->currX = d3x; \
-   if (d3y != mvcData->currY) { \
-      int \
-         mvRowIndex, \
-         currMaxX = mvcData->currMaxX; \
-      mvRowItem_t *mvRow = mvcData->mvRow; \
-      mvcData->currY = d3y; \
-      mvcData->mvRowIndex = mvRowIndex = (mvcData->mvRowIndex + 2) % 3; \
-      mvcData->mvRow0 = &mvRow[(currMaxX + 1) * 2 * mvRowIndex]; \
-      mvcData->mvRow1 = &mvRow[(currMaxX + 1) * 2 * ((mvRowIndex + 1) % 3)]; \
-      mvcData->mvRow2 = &mvRow[(currMaxX + 1) * 2 * ((mvRowIndex + 2) % 3)]; \
-   } \
-   if (d3time != mvcData->currTime) \
-      mvcData->currTime = d3time 
-
-/* mvcInvMVD takes the other one of the possible MVD values defined in
-   H.263 Recommendation */
-#define mvcInvMVD(invMv) \
-   (invMv < 0) ? \
-      MVD_320 + invMv : \
-      -MVD_320 + invMv
-
-/* sign123(x) returns
-      1 if x < 0,
-      2 if x > 0,
-      3 if x == 0 
-   In other words,
-      bit 0 = 1 if x <= 0, 
-      bit 1 = 1 if x >= 0 */
-#define sign123(x) ((x == 0) ? 3 : (x < 0) ? 1 : 2)
-
-
-/* 
- * Local prototypes
- */
-
-static void mvcGetNeighbourMVs(mvcData_t *mvcData, int x, int y, int time,
-   int *nmvx, int *nmvy, int prevFlag, int16 *error);
-
-__inline static void mvcCheckAndSet( 
-      mvRowItem_t *mvRowPtr, int xind, int yind, int time, int nind, 
-      int *nmvx, int *nmvy, mvRowItem_t *cmvRowPtr, int cxind, int cyind,
-      int16 *error);
-
-__inline static void mvcSetToCurrent( 
-      mvRowItem_t *mvRowPtr, int xind, int yind, int time, int nind,
-      int *nmvx, int *nmvy, int16 *error);
-
-
-/*
- * Global functions
- */
-
-
-/* {{-output"mvcSetBorders.txt"}} */
-/*
- *
- * mvcSetBorders
- *
- * Parameters:
- *    mvcData        mvcData_t structure
- *    x              the x coordinate of the MB (0 .. maxX)
- *    y              the y coordinate of the MB
- *                   (0 .. macroblock rows in frame - 1)
- *    mba            Macroblock address of starting MB of the slice. This 
- *                   value SHOULD be set to -1 if Annex K is not in use.
- *    numMBsInMBLine    Number of MBs in MB line    
- *    rightOfBorder     There is a border on the left of the current MB
- *    downOfBorder      There is a border on top of the current MB
- *
- * Function:
- *    This function calculates the borders of GOBs and Slices..This function 
- *    SHOULD be called before mvcCalcMV.....
- *
- * Returns:
- *    Nothing
- *
- * Error codes:
- *    None
- *
- */
-
-void mvcSetBorders(
-      mvcData_t *mvcData, int x, int y, int mba, int numMBsInMBLine, 
-      int *rightOfBorder, int *downOfBorder 
-)
-{
-   int
-      upRightMBIsStart;
-
-   if (mvcData)   {
-      mvcData->rightOfBorderPrev = mvcData->rightOfBorder;
-      mvcData->downOfBorderPrev = mvcData->downOfBorder;
-   }
-
-   if (mba == -1) {
-      if (x == 0) {
-         *rightOfBorder = 1;
-      }
-      else  {
-         *rightOfBorder = 0;
-      }
-      
-      /* Always downOfBorder is set to 1, since in QCIF and CIF every GOB
-         has only 1 MB line. If larger images are supported, numMBLinesInGOB
-         should be passed here. Also number of starting MB of the GOB may be
-         needed...*/
-      *downOfBorder = 1;
-      upRightMBIsStart = 0;
-   }
-   else  {
-      int
-         xs,   /* x coordinate of start MB */
-         ys;   /* y coordinate of start MB */
-      xs = mba % numMBsInMBLine;
-      ys = mba / numMBsInMBLine;
-
-      /* slice structured mode*/
-      /* Check if there is slice border on top of the  current MB:
-         For that, check either current MB should be on the same MB line 
-         with the starting MB of slice or current MB should not be on the
-         left of the starting MB if the MB is on the second line of the 
-         slice. */
-      
-      if ((y == ys) || ((x < xs) && (ys+1 == y)))  {
-         *downOfBorder = 1;
-      }
-      else  {
-         *downOfBorder = 0;
-      }   
-      /* Check if there is a slice border on the left of the current MB.*/
-      if (((x == xs) && (y == ys)) || (x == 0))  {
-         *rightOfBorder = 1;
-      }
-      else  {
-         *rightOfBorder = 0;
-      }
-
-      /* Test the situation of MV2 is in another slice but MV3 in in the
-         same slice... i.e:
-         MB1 MB1 MB1 MB2 MB2 .........MB2
-         MB2 MB2 MB2 MB2 MB2..........MB2
-                  *                        
-         The MB marked with * is an exmaple. MB on top of it is in another slice
-         but the MB which MV3 will come from is in the same slice...*/
-      if ((x+1 == xs) && (y-1 == ys))
-         upRightMBIsStart = 1;
-      else
-         upRightMBIsStart = 0;
-   }   
-
-   if (mvcData)   {
-      mvcData->upRightMBIsStart = upRightMBIsStart;
-      mvcData->downOfBorder = *downOfBorder;
-      mvcData->rightOfBorder = *rightOfBorder;
-      mvcData->leftOfBorder = 0;
-   }
-}
-
-/* {{-output"mvcCalcMV.txt"}} */
-/*
- *
- * mvcCalcMV
- *
- * Parameters:
- *       mvcData        mvcData_t structure
- *
- *       mvdx           motion vector data returned by vlcGetMVD
- *       mvdy
- *
- *       *mvx           the resulting motion vector is placed to *mvx and *mvy
- *       *mvy
- *
- *       predictorMode  0, 1, 2 or 3. See H.263 recommendation, Annex F, Figure
- *                      15, where modes are in the following order:
- *                         0  1
- *                         2  3
- *
- *                      Advanced Prediction mode: It is assumed that this
- *                      function is called by setting predictorMode 0, 1, 2
- *                      and 3 in this order for a particular macroblock.
- *
- *                      Normal: This function should be called by setting
- *                      predictorMode to 0.
- *
- *       fourMVs        if != 0, four motion vectors for current macroblock
- *                      is assumed
- *
- *       unrestrictedMV       if != 0, unrestricted motion vector mode is used
- *
- *       topOfGOB             if != 0, the current MB is assumed to be in the
- *                            first line of the current GOB
- *
- *       nonEmptyGOBHeader    if != 0, the GOB header of the current GOB is
- *                            is assumed to be non-empty, and MV2 and MV3 are
- *                            set to MV1 if they are outside the GOB. If Annex K
- *                            is in use set this value to 1......
- *
- *       x              the x coordinate of the MB (0 .. maxX)
- *       y              the y coordinate of the MB
- *                      (0 .. macroblock rows in frame - 1)
- *
- *       time           a value which is related to the time when the current
- *                      frame must be shown. This value should be unique
- *                      among a relatively small group of consecutive frames.
- *
- *       mbType         must be MVC_MB_INTER or MVC_MB_INTRA. MVC_MB_INTRA 
- *                      should be used only in PB frames mode.
- *
- *       error          error code
- *
- *       fPLUSPTYPE     PLUSTYPE flag
- *
- *       fUMVLimited    Annex D v2 flag
- *                      1  => Limited MVs    (UUI = 1)
- *                      0  => Unlimited MVs  (UUI = 01)
- *
- * Function:
- *       This function counts the motion vector value for given macroblock.
- *       See H.263 Recommendation 6.1.1 Differential Motion Vectors and
- *       Annex F. Advanced Prediction Mode.
- *
- * Returns:
- *       Changes *mvx, *mvy and possibly *error.
- *
- * Error codes:
- *       ERR_MVC_MVDX_ILLEGAL    mvdx illegal
- *       ERR_MVC_MVDY_ILLEGAL    mvdy illegal
- *       ERR_MVC_MVX_ILLEGAL     mvx is NULL
- *       ERR_MVC_MVY_ILLEGAL     mvy is NULL
- *       ERR_MVC_MODE_ILLEGAL    predictorMode illegal
- *       ERR_MVC_X_ILLEGAL       x < 0 or x > maxX
- *       ERR_MVC_Y_ILLEGAL       y < 0
- *       ERR_MVC_TIME_ILLEGAL    time < 0
- *       ERR_MVC_MVPTR           result is not legal
- *
- */
-
-void mvcCalcMV(mvcData_t *mvcData, int mvdx, int mvdy,
-   int *mvx, int *mvy, u_char predictorMode, u_char fourMVs,
-   u_char unrestrictedMV,  u_char nonEmptyGOBHeader, int x, 
-   int y, int time, int mbType, int16 *error, int fPLUSPTYPE, 
-   int fUMVLimited)
-/* {{-output"mvcCalcMV.txt"}} */
-{
-
-   int 
-      i, j,    /* loop variables */
-      mvcx[3], /* Candidates: mv[0] = MV1, mv[1] = MV2, mv[2] = MV3 */
-      mvcy[3],
-      *mv,     /* mvcx or mvcy */
-      *mvptr,  /* == mvx or mvy */
-      mvd,     /* mvdx or mvdy */
-      xx2,     /* x * 2 */
-      yx2,     /* y * 2 */
-      xmv1,    /* index for MV1 */
-      xmv2,    /* index for MV2 */
-      xmv3,    /* index for MV3 */
-      ymv1,
-      ymv2,
-      ymv3,
-      mvRangeLow,    /* Lower boundary for MV Range  
-                        Look H.263+ Rec. Table D.1, D.2 */
-      mvRangeHigh,   /* Higher boundary for MV Range  
-                        Look H.263+ Rec. Table D.1, D.2 */
-      picDim,        /* Temporary variable for luminance width or height */
-      mbCorner,      /* Temporary variable for MB's topleft corner's 
-                        coordinate (x or y)*/
-      mvRes;         /* MB's rightmost or bottommost pixel plus MV
-                        for checking restriction D.1.1 */
-   mvRowItem_t
-      *currMvRow,
-      *prevMvRow,
-      *mvRow0,
-      *mvRow1,
-      *mvRow2;
-
-   /* Check parameters */
-    if ((!fPLUSPTYPE) || (!unrestrictedMV))
-   {
-      if (mvdx < MVD_MIN || mvdx > MVD_MAX) {
-         *error = ERR_MVC_MVDX_ILLEGAL;
-         return;
-      }
-
-      if (mvdy < MVD_MIN || mvdy > MVD_MAX) {
-         *error = ERR_MVC_MVDY_ILLEGAL;
-         return;
-      }
-   }
-
-   if (!mvx) {
-      *error = ERR_MVC_MVX_ILLEGAL;
-      return;
-   }
-
-   if (!mvy) {
-      *error = ERR_MVC_MVY_ILLEGAL;
-      return;
-   }
-
-   if ((fourMVs && predictorMode > 3) ||
-      (!fourMVs && predictorMode > 0)) {
-      *error = ERR_MVC_MODE_ILLEGAL;
-      return;
-   }
-
-   if (x < 0 || x > mvcData->currMaxX) {
-      *error = ERR_MVC_X_ILLEGAL;
-      return;
-   }
-
-   if (y < 0) {
-      *error = ERR_MVC_Y_ILLEGAL;
-      return;
-   }
-
-   if (time < 0) {
-      *error = ERR_MVC_TIME_ILLEGAL;
-      return;
-   }
-
-   updateRowPointers(x, y, time);
-   mvRow0 = mvcData->mvRow0;
-   mvRow1 = mvcData->mvRow1;
-   mvRow2 = mvcData->mvRow2;
-
-   /* Seek candidate predictors */
-
-   xx2 = x << 1; /* xx2 = x * 2 */
-   yx2 = y << 1;
-
-   xmv1 = xx2 - 1 + (predictorMode & 1);
-   xmv2 = xx2 + (predictorMode == 1);
-   xmv3 = xx2 + 2 - (predictorMode > 1);
-   ymv1 = yx2 + (predictorMode > 1);
-   ymv2 = ymv3 = yx2 - 1 + (predictorMode > 1);
-
-   if (predictorMode <= 1) {
-      currMvRow = mvRow1;
-      prevMvRow = mvRow0;
-   }
-   else {
-      currMvRow = mvRow2;
-      prevMvRow = mvRow1;
-   }
-
-   if ( (predictorMode & 1) || /* right column of the MB */
-      ( !mvcData->rightOfBorder && mvValid(currMvRow[xmv1], ymv1, time) ) ) {
-      mvcx[0] = currMvRow[xmv1].mvx;
-      mvcy[0] = currMvRow[xmv1].mvy;
-   }
-   else
-      /* if (x == 0 || motion vector for previous MB does not exist ||
-             the previous MB belongs to a different slice) */
-      mvcx[0] = mvcy[0] = 0;
-
-   if ((y == 0 || (mvcData->downOfBorder && nonEmptyGOBHeader)) && predictorMode <= 1) {
-      /* mv2 and mv3 are outside the picture or GOB
-         (if non-empty GOB header) or outside the slice*/
-      mvcx[1] = mvcx[0];
-      mvcy[1] = mvcy[0];
-      /* Check if the MB ont the previous line and on the next column
-         in in the same slice (means start MBof the slice).. */
-      if (!mvcData->upRightMBIsStart)   {
-         mvcx[2] = mvcx[0];
-         mvcy[2] = mvcy[0];
-      }
-      if (x == mvcData->currMaxX)
-         mvcx[2] = mvcy[2] = 0;
-   }
-   else {
-      if (mvValid(prevMvRow[xmv2], ymv2, time)) {
-         mvcx[1] = prevMvRow[xmv2].mvx;
-         mvcy[1] = prevMvRow[xmv2].mvy;
-      }
-      else 
-         mvcx[1] = mvcy[1] = 0;
-
-      if (mvValid(prevMvRow[xmv3], ymv3, time)) {
-         mvcx[2] = prevMvRow[xmv3].mvx;
-         mvcy[2] = prevMvRow[xmv3].mvy;
-      }
-      else
-         mvcx[2] = mvcy[2] = 0;
-   }
-
-    for (j = 0, mv = mvcx, mvd = mvdx, mvptr = mvx,
-         picDim = mvcData->currLumWidth, mbCorner = x,
-         mvRangeLow = mvcData->mvRangeLowX,
-         mvRangeHigh = mvcData->mvRangeHighX;
-         j < 2;
-         j++, mv = mvcy, mvd = mvdy, mvptr = mvy, 
-         picDim = mvcData->currLumHeight, mbCorner = y,
-         mvRangeLow = mvcData->mvRangeLowY,
-         mvRangeHigh = mvcData->mvRangeHighY) {
-
-      int choice1, min, predictor;
-
-      /* Find the median of the candidates */
-
-      min = mv[0];
-      predictor = 32767;
-
-      for (i = 1; i < 3; i++) {
-         if (mv[i] <= min) {
-            predictor = min;
-            min = mv[i];
-            continue;
-         }
-         if (mv[i] < predictor)
-            predictor = mv[i];
-      }
-
-      /* Count the new motion vector value */
-
-      if (!unrestrictedMV) {
-         /* Default prediction mode.
-            Count the legal [-16..15.5] motion vector */
-
-         choice1 = predictor + mvd;
-
-         *mvptr = (MVD_MIN <= choice1 && choice1 <= MVD_MAX) ?
-            choice1 :
-            /*(mvd == 0) ?
-               predictor :*/ /* index 32, should never happen?! */
-               (mvd < 0) ?
-                  MVD_320 + choice1 : /* index 0..31: 32 + mvd + predictor */
-                  -MVD_320 + choice1; /* index 33..63: -32 + mvd + predictor */
-
-         /* Check that the result is [-16..15.5] */
-         if (*mvptr < MVD_MIN || *mvptr > MVD_MAX) {
-            *error = ERR_MVC_MVPTR;
-            return;
-         }
-      }
-
-      else if ((-MVD_155 <= predictor && predictor <= MVD_160) && (!fPLUSPTYPE))
-         /* Unrestricted motion vector mode && -15.5 <= predictor <= 16.
-            mvd is always valid. */
-         *mvptr = predictor + mvd;
-
-       else if (!fPLUSPTYPE)
-       {
-         /* Unrestricted motion vector mode && predictor not in [-15.5, 16]
-            Result in [-31.5, 31.5] and has the same sign as predictor */
-         choice1 = predictor + mvd;
-         *mvptr = (MVD_UMIN_V1 <= choice1 && choice1 <= MVD_UMAX_V1 &&
-            (sign123(choice1) & sign123(predictor))) ?
-            choice1 :
-            /*(mvd == 0) ?
-               predictor :*/ /* index 32, should never happen!? */
-               (mvd < 0) ?
-                  MVD_320 + choice1 : /* index 0..31: 32 + mvd + predictor */
-                  -MVD_320 + choice1; /* index 33..63: -32 + mvd + predictor */
-
-         /* Check that the result is in the appropriate range. */
-         if ((predictor < -MVD_155 && *mvptr > 0) ||
-            (predictor > MVD_160 && *mvptr < 0)) {
-            *error = ERR_MVC_MVPTR;
-            return;
-         }
-
-      }
-       else if (fUMVLimited)  
-      /* fPlusType==1 && UUI == 1*/
-      {
-         *mvptr = predictor + mvd;
-
-         if ( *mvptr > 0 )
-            /* mvRes is the leftmost/topmost pixels coordinate of next
-               macroblock plus 2 times MV */
-              mvRes = (mbCorner+1)*32 + (*mvptr)/5 ;
-           else
-             /* mvRes is the leftmost/topmost pixels coordinate of current
-               macroblock plus 2 times MV,
-            half a pixel corresponds to 1 in integer scale */
-               mvRes = mbCorner*32 + (*mvptr)/5 ;
-
-         if ((mvRes < -30) || (mvRes > picDim * 2 + 30))
-         /* Restriction D.1.1 */
-         {
-            *error = ERR_MVC_MVPTR;
-            deb("Restriction D.1.1\n");
-            return;
-         }
-      
-         if ((*mvptr < mvRangeLow) || (*mvptr > mvRangeHigh))
-         /* Restriction D.2 */
-         {
-            *error = ERR_MVC_MVPTR;
-            deb("Restriction D.2 \n");
-            return;
-         }
-      }
-      else  /* fPlusType==1 && UUI == 01 */
-      {
-         *mvptr = predictor + mvd;
-         if ( *mvptr > 0 )
-               mvRes = (mbCorner+1)*32 + (*mvptr)/5;
-           else
-               mvRes = mbCorner*32 + (*mvptr)/5;
-         if ((mvRes < -30) || (mvRes > picDim * 2 + 30))
-         /* Restriction D.1.1 */
-         {
-            *error = ERR_MVC_MVPTR;
-            deb("Restriction D.1.1\n");
-            return;
-         }
-      }
-   }
-
-   /* Update motion vector buffer arrays */
-   switch (predictorMode) {
-      case 0:
-         if (fourMVs) {
-            mvStore(mvRow1, xx2, yx2, *mvx, *mvy, time, mbType);
-         }
-         else {
-            mvStoreMB(mvRow1, mvRow2, xx2, yx2, *mvx, *mvy, time, mbType);
-         }
-         break;
-      case 1:
-         mvStore(mvRow1, xx2 + 1, yx2, *mvx, *mvy, time, mbType);
-         break;
-      case 2:
-         mvStore(mvRow2, xx2, yx2 + 1, *mvx, *mvy, time, mbType);
-         break;
-      case 3:
-         mvStore(mvRow2, xx2 + 1, yx2 + 1, *mvx, *mvy, time, mbType);
-         break;
-   }
-}
-
-
-/* {{-output"mvcCalcMPEGMV.txt"}} */
-/*
- *
- * mvcCalcMPEGMV
- *
- * Parameters:
- *       mvcData        mvcData_t structure
- *
- *       mvdx           motion vector data returned by vlcGetMVD
- *       mvdy
- *
- *       *mvx           the resulting motion vector is placed to *mvx and *mvy
- *       *mvy
- *
- *       predictorMode  0, 1, 2 or 3. See H.263 recommendation, Annex F, Figure
- *                      15, where modes are in the following order:
- *                         0  1
- *                         2  3
- *
- *                      Advanced Prediction mode: It is assumed that this
- *                      function is called by setting predictorMode 0, 1, 2
- *                      and 3 in this order for a particular macroblock.
- *
- *                      Normal: This function should be called by setting
- *                      predictorMode to 0.
- *
- *       fourMVs        if != 0, four motion vectors for current macroblock
- *                      is assumed
- *
- *       topOfVP        if != 0, the current MB is assumed to be in the
- *                      first line of the current VideoPacket
- *
- *       leftOfVP       if != 0, the current MB is assumed to be the
- *                      first in the VideoPacket
- *
- *       fmv3_out       if != 0, the 3rd MB (top, right) used as MV predictor
- *                      is outside of the current VideoPacket
- *
- *       x              the x coordinate of the MB (0 .. maxX)
- *       y              the y coordinate of the MB
- *                      (0 .. macroblock rows in frame - 1)
- *
- *       time           a value which is related to the time when the current
- *                      frame must be shown. This value should be unique
- *                      among a relatively small group of consecutive frames.
- *
- *       mbType         must be MVC_MB_INTER or MVC_MB_INTRA. MVC_MB_INTRA 
- *                      should be used only in PB frames mode.
- *
- *       error          error code
- *
- * Function:
- *       This function counts the motion vector value for given macroblock.
- *       See H.263 Recommendation 6.1.1 Differential Motion Vectors and
- *       Annex F. Advanced Prediction Mode.
- *
- * Returns:
- *       Changes *mvx, *mvy and possibly *error.
- *
- * Error codes:
- *       The following codes are assertion-like checks:
- *       ERR_MVC_MVDX_ILLEGAL    mvdx illegal
- *       ERR_MVC_MVDY_ILLEGAL    mvdy illegal
- *       ERR_MVC_MVX_ILLEGAL     mvx is NULL
- *       ERR_MVC_MVY_ILLEGAL     mvy is NULL
- *       ERR_MVC_MODE_ILLEGAL    predictorMode illegal
- *       ERR_MVC_X_ILLEGAL       x < 0 or x > maxX
- *       ERR_MVC_Y_ILLEGAL       y < 0
- *       ERR_MVC_TIME_ILLEGAL    time < 0
- *
- *       The following code may also be caused by a bit error:
- *       ERR_MVC_MVPTR           result is not legal
- *
- */
-
-void mvcCalcMPEGMV(mvcData_t *mvcData,
-   int mvdx, int mvdy, int *mvx, int *mvy,
-   u_char predictorMode, u_char fourMVs,
-   u_char topOfVP, u_char leftOfVP, u_char fmv3_out,
-   int x, int y, int time, int mbType, int16 *error)
-/* {{-output"mvccalc.txt"}} */
-{
-   int 
-      i, j,    /* loop variables */
-      mvcx[3], /* Candidates: mv[0] = MV1, mv[1] = MV2, mv[2] = MV3 */
-      mvcy[3],
-      mvc1_out = 0, mvc2_out = 0, mvc3_out = 0,
-      *mv,     /* mvcx or mvcy */
-      *mvptr,  /* == mvx or mvy */
-      mvd,     /* mvdx or mvdy */
-      xx2,     /* x * 2 */
-      yx2,     /* y * 2 */
-      xmv1,    /* index for MV1 */
-      xmv2,    /* index for MV2 */
-      xmv3,    /* index for MV3 */
-      ymv1,
-      ymv2,
-      ymv3;
-   mvRowItem_t
-      *currMvRow,
-      *prevMvRow,
-      *mvRow0,
-      *mvRow1,
-      *mvRow2;
-
-
-   if (!mvx) {
-      *error = ERR_MVC_MVX_ILLEGAL;
-      return;
-   }
-
-   if (!mvy) {
-      *error = ERR_MVC_MVY_ILLEGAL;
-      return;
-   }
-
-   if ((fourMVs && predictorMode > 3) ||
-      (!fourMVs && predictorMode > 0)) {
-      *error = ERR_MVC_MODE_ILLEGAL;
-      return;
-   }
-
-   if (x < 0 || x > mvcData->currMaxX) {
-      *error = ERR_MVC_X_ILLEGAL;
-      return;
-   }
-
-   if (y < 0) {
-      *error = ERR_MVC_Y_ILLEGAL;
-      return;
-   }
-
-   if (time < 0) {
-      *error = ERR_MVC_TIME_ILLEGAL;
-      return;
-   }
-
-   updateRowPointers(x, y, time);
-   mvRow0 = mvcData->mvRow0;
-   mvRow1 = mvcData->mvRow1;
-   mvRow2 = mvcData->mvRow2;
-
-   /* Seek candidate predictors */
-
-   xx2 = x << 1; /* xx2 = x * 2 */
-   yx2 = y << 1;
-
-   xmv1 = xx2 - 1 + (predictorMode & 1);
-   xmv2 = xx2 + (predictorMode == 1);
-   xmv3 = xx2 + 2 - (predictorMode > 1);
-   ymv1 = yx2 + (predictorMode > 1);
-   ymv2 = ymv3 = yx2 - 1 + (predictorMode > 1);
-
-   if (predictorMode <= 1) {
-      currMvRow = mvRow1;
-      prevMvRow = mvRow0;
-   }
-   else {
-      currMvRow = mvRow2;
-      prevMvRow = mvRow1;
-   }
-
-   if ((x == 0 || leftOfVP) && !(predictorMode & 1)) {
-      /* mv1 is outside the VP or VOP */
-      mvcx[0] = mvcy[0] = 0;
-      mvc1_out = 1;
-   }
-   else {
-      if (mvValidMPEG(currMvRow[xmv1], ymv1, time)) {
-          mvcx[0] = currMvRow[xmv1].mvx;
-          mvcy[0] = currMvRow[xmv1].mvy;
-      }
-      else mvcx[0] = mvcy[0] = 0;
-   }
-
-   if ((y == 0 || topOfVP) && predictorMode <= 1) {
-      /* mv2 is outside the VP or VOP */
-      mvcx[1] = mvcy[1] = 0;
-      mvc2_out = 1;
-   }
-   else {
-      if (mvValidMPEG(prevMvRow[xmv2], ymv2, time)) {
-         mvcx[1] = prevMvRow[xmv2].mvx;
-         mvcy[1] = prevMvRow[xmv2].mvy;
-      }
-      else mvcx[1] = mvcy[1] = 0;
-   }
-
-   if ((y == 0 || fmv3_out || x == mvcData->currMaxX) && predictorMode <= 1) {
-      /* mv3 is outside the VP or VOP */
-      mvcx[2] = mvcy[2] = 0;
-      mvc3_out = 1;
-   }
-   else {
-      if (mvValidMPEG(prevMvRow[xmv3], ymv3, time)) {
-         mvcx[2] = prevMvRow[xmv3].mvx;
-         mvcy[2] = prevMvRow[xmv3].mvy;
-      }
-      else
-         mvcx[2] = mvcy[2] = 0;
-   }
-
-   for (j = 0, mv = mvcx, mvd = mvdx, mvptr = mvx;
-      j < 2;
-      j++, mv = mvcy, mvd = mvdy, mvptr = mvy) {
-
-      int min, predictor;
-
-      switch (mvc1_out + mvc2_out + mvc3_out)
-      {
-         case 3:
-             predictor = 0;
-             break;
-         case 2:
-             predictor = mv[0] + mv[1] + mv[2];
-             break;
-         case 1:
-         case 0:
-             /* Find the median of the candidates */
-             min = mv[0];
-             predictor = 32767;
-
-             for (i = 1; i < 3; i++) {
-                 if (mv[i] <= min) {
-                     predictor = min;
-                     min = mv[i];
-                     continue;
-                 }
-                 if (mv[i] < predictor)
-                     predictor = mv[i];
-             }
-             break;
-         default:
-            /* Should never happen */
-            vdcAssert(0);
-            predictor = 0;
-            break;
-      }
-
-      /* Count the new motion vector value */
-      *mvptr = predictor + mvd;
-
-      if (*mvptr < -(mvcData->range))
-        *mvptr += 2*(mvcData->range);
-      else if (*mvptr > (mvcData->range)-5)
-        *mvptr -= 2*(mvcData->range);
-   }
-
-   /* Update motion vector buffer arrays */
-   switch (predictorMode) {
-      case 0:
-         if (fourMVs) {
-            mvStore(mvRow1, xx2, yx2, *mvx, *mvy, time, mbType);
-         }
-         else {
-            mvStoreMB(mvRow1, mvRow2, xx2, yx2, *mvx, *mvy, time, mbType);
-         }
-         break;
-      case 1:
-         mvStore(mvRow1, xx2 + 1, yx2, *mvx, *mvy, time, mbType);
-         break;
-      case 2:
-         mvStore(mvRow2, xx2, yx2 + 1, *mvx, *mvy, time, mbType);
-         break;
-      case 3:
-         mvStore(mvRow2, xx2 + 1, yx2 + 1, *mvx, *mvy, time, mbType);
-         break;
-   }
-}
-
-/* {{-output"mvcFree.txt"}} */
-/*
- *
- * mvcFree
- *
- * Parameters:
- *    mvcData        mvcData_t structure
- *
- * Function:
- *    This function frees the dynamic memory allocated by mvcStart.
- *    mvcFree should be called at least when exiting the main program.
- *    Alternatively it can be called whenever the playing a video has
- *    ended.
- *
- * Returns:
- *    Nothing
- *
- * Error codes:
- *    None
- *
- *    
- *    
- *    
- */
-
-void mvcFree(mvcData_t *mvcData)
-/* {{-output"mvcFree.txt"}} */
-{
-   if (mvcData) {
-      if (mvcData->mvRow) free(mvcData->mvRow);
-      mvcData->currMaxX = -1;
-   }
-}
-
-
-/* {{-output"mvcGetCurrentMVs.txt"}} */
-/*
- *
- * mvcGetCurrentMVs
- *
- * Parameters:
- *       mvcData  mvcData_t structure
- *       mvx
- *       mvy
- *       error    error code
- *
- * Function:
- *       These functions return the motion vectors of the current 
- *       blocks.
- *
- * Returns:
- *       Changes mvx, mvy and possibly error.
- *
- * Error codes:
- *
- *    ERR_MVC_CURR_NOT_VALID        if the motion vectors for the current
- *                                  macroblock do not exist
- *
- *    ERR_MVC_CURR_NOT_CODED        if the current macroblock was not coded
- *
- *    ERR_MVC_CURR_INTRA            if the current macroblock was coded in
- *                                  INTRA mode
- *
- */
-void mvcGetCurrentMVs(mvcData_t *mvcData, int *mvx, int *mvy,
-   int16 *error)
-{
-   int
-      xx2 = mvcData->currX << 1,
-      yx2 = mvcData->currY << 1;
-   mvRowItem_t
-      *mvRow1 = mvcData->mvRow1,
-      *mvRow2 = mvcData->mvRow2;
-   if (mvValid(mvRow1[xx2], yx2, mvcData->currTime) &&
-         mvRow1[xx2].type == MVC_MB_INTER) {
-      mvx[0] = mvRow1[xx2].mvx;
-      mvx[1] = mvRow1[xx2 + 1].mvx;
-      mvx[2] = mvRow2[xx2].mvx;
-      mvx[3] = mvRow2[xx2 + 1].mvx;
-      mvy[0] = mvRow1[xx2].mvy;
-      mvy[1] = mvRow1[xx2 + 1].mvy;
-      mvy[2] = mvRow2[xx2].mvy;
-      mvy[3] = mvRow2[xx2 + 1].mvy;
-   }
-   else  {
-      mvx[0] = mvx[1] = mvx[2] = mvx[3] =
-      mvy[0] = mvy[1] = mvy[2] = mvy[3] = 0;
-      if mvLegal(mvRow1[xx2], yx2, mvcData->currTime) {
-         if (mvRow1[xx2].type == MVC_MB_NOT_CODED) {
-            /*deb("mvcGetCurrentMVs: ERROR - macroblock not coded.\n");*/
-            *error = ERR_MVC_CURR_NOT_CODED;
-         }
-         else if (mvRow1[xx2].type == MVC_MB_INTRA) {
-            /*deb("mvcGetCurrentMVs: ERROR - INTRA macroblock.\n");*/
-            *error = ERR_MVC_CURR_INTRA;
-         }
-         else {
-            /*deb("mvcGetCurrentMVs: ERROR - macroblock not valid.\n");*/
-            *error = ERR_MVC_CURR_NOT_VALID;
-         }
-      }
-      else {
-         /*deb("mvcGetCurrentMVs: ERROR - macroblock not valid.\n");*/
-         *error = ERR_MVC_CURR_NOT_VALID;
-      }
-   }
-}
-
-/* {{-output"mvcGetNeighbourMVs.txt"}} */
-/*
- *
- * mvcGetCurrNeighbourMVs
- * mvcGetPrevNeighbourMVs
- *
- * Parameters:
- *       mvcData  mvcData_t structure
- *
- *       nmvx     pointer to motion vector x component array
- *       nmvy     pointer to motion vector y component array
- *                The size of the array must be 6. The indexing of the
- *                neighboring motion vectors goes like this:
- *                (X = the motion vector which is investigated, i.e.
- *                the last one decoded (mvcGetCurrNeighbourMVs) or
- *                the one before the last one (mvcGetPrevNeighbourMVs))
- *                     2 3
- *                   0 X X 4
- *                   1 X X 5
- *                It is suggested that the following defines are used
- *                instead of values:
- *                   MVC_XM1_UP (0)
- *                   MVC_XM1_DOWN (1)
- *                   MVC_YM1_LEFT (2)
- *                   MVC_YM1_RIGHT (3)
- *                   MVC_XP1_UP (4)
- *                   MVC_XP1_DOWN (5)
- *                (M stand for minus and P for plus)
- *
- *       pmvx and pmvy are for mvcGetPrevNeighbourMVs only:
- *       pmvx     pointer to the motion vector x component array of the
- *                previous macroblock
- *       pmvy     pointer to the motion vector y component array of the
- *                previous macroblock
- *                The size of the array must be 4. The indexing is similar
- *                to normal block indexing inside a macroblock:
- *                     0 1
- *                     2 3
- *
- *       error    error code
- *
- * Function:
- *       These functions return the motion vectors of the neighboring
- *       blocks (on the left side, above or on the right side) of the
- *       macroblock which is investigated, i.e.
- *          - the last one decoded (mvcGetCurrNeighbourMVs) or
- *          - the one before the last one (mvcGetPrevNeighbourMVs))
- *
- *       The H.263 standard for Overlapped motion compensation for luminance
- *       (Annex F.3) is followed, that is:
- *       If one of the surrounding macroblocks was not coded, the
- *       corresponding remote motion vector is set to zero. If one of the
- *       surrounding (macro)blocks was coded in INTRA mode, the corresponding
- *       remote motion vector is replaced by the motion vector for the
- *       current block expect when in PB-frames mode. In this case (INTRA
- *       block in PB-frame mode), the INTRA block's motion vector is used.
- *       If the current block is at the border of the picture and therefore
- *       a surrounding block is not present, the corresponding remote motion
- *       vector is replaced by the current motion vector.
- *
- *       mvcGetPrevNeighbourMVs also returns the motion vector for the
- *       previous macroblock.
- *
- * Returns:
- *       Changes nmvx, nmvy, pmvx, pmvy and possibly error.
- *
- * Error codes:
- *    ERR_MVC_NO_PREV_MB            if the current MB has x coordinate 0 and
- *                                  mvcGetPrevNeighbourMVs is called
- *
- *    ERR_MVC_NEIGHBOUR_NOT_VALID   if one of the neighboring MVs is not
- *                                  valid, i.e. it has not been updated
- *                                  for this frame. The MV in nmvx and nmvy
- *                                  is set to zero.
- *
- *    for mvcGetPrevNeighbourMVs only:
- *    ERR_MVC_PREV_NOT_VALID        if the motion vectors for the previous
- *                                  macroblock do not exist
- *
- *    ERR_MVC_PREV_NOT_CODED        if the previous macroblock was not coded
- *
- *    ERR_MVC_PREV_INTRA            if the previous macroblock was coded in
- *                                  INTRA mode
- *
- *    
- *    
- *    
- *    
- *    
- *    
- */
-
-void mvcGetCurrNeighbourMVs(mvcData_t *mvcData, int *nmvx, int *nmvy,
-   int16 *error)
-/* {{-output"mvcGetNeighbourMVs.txt"}} */
-{
-   mvRowItem_t
-      *mvRow1 = mvcData->mvRow1;
-   int xx2 = mvcData->currX << 1;
-
-   mvcGetNeighbourMVs(mvcData, mvcData->currX, mvcData->currY,
-      mvcData->currTime, nmvx, nmvy, 0, error);
-   if (*error)   {
-      if mvLegal(mvRow1[xx2], mvcData->currY << 1, mvcData->currTime) {
-         if (mvRow1[xx2].type == MVC_MB_NOT_CODED) {
-            /*deb("mvcGetPrevNeighbourMVs: ERROR - macroblock not coded.\n");*/
-            *error = ERR_MVC_CURR_NOT_CODED;
-         }
-         else if (mvRow1[xx2].type == MVC_MB_INTRA) {
-            /*deb("mvcGetPrevNeighbourMVs: ERROR - INTRA macroblock.\n");*/
-            *error = ERR_MVC_CURR_INTRA;
-         }
-         else {
-            /*deb("mvcGetPrevNeighbourMVs: ERROR - macroblock not valid.\n");*/
-            *error = ERR_MVC_CURR_NOT_VALID;
-         }
-      }
-      else {
-         /*deb("mvcGetPrevNeighbourMVs: ERROR - macroblock not valid.\n");*/
-         *error = ERR_MVC_CURR_NOT_VALID;
-      }
-   }
-}
-
-/* {{-output"mvcGetPrevNeighbourMVs.txt"}} */
-void mvcGetPrevNeighbourMVs(mvcData_t *mvcData, int *nmvx, int *nmvy,
-   int *pmvx, int *pmvy, u_char *fourMVs, int16 *error)
-/* {{-output"mvcGetPrevNeighbourMVs.txt"}} */
-{
-   int
-      currX = mvcData->currX,
-      currY = mvcData->currY;
-   mvRowItem_t
-      *mvRow1 = mvcData->mvRow1,
-      *mvRow2 = mvcData->mvRow2;
-
-   if (currX > 0) {
-      int xx2 = (currX - 1) << 1;
-      mvcGetNeighbourMVs(mvcData, currX - 1, currY,
-         mvcData->currTime, nmvx, nmvy, 1, error);
-      if (mvValid(mvRow1[xx2], currY << 1, mvcData->currTime) &&
-         mvRow1[xx2].type == MVC_MB_INTER) {
-         pmvx[0] = mvRow1[xx2].mvx;
-         pmvx[1] = mvRow1[xx2 + 1].mvx;
-         pmvx[2] = mvRow2[xx2].mvx;
-         pmvx[3] = mvRow2[xx2 + 1].mvx;
-         pmvy[0] = mvRow1[xx2].mvy;
-         pmvy[1] = mvRow1[xx2 + 1].mvy;
-         pmvy[2] = mvRow2[xx2].mvy;
-         pmvy[3] = mvRow2[xx2 + 1].mvy;
-         *fourMVs = mvRow1[xx2].fourMVs;
-      }
-      else {
-         pmvx[0] = pmvx[1] = pmvx[2] = pmvx[3] =
-         pmvy[0] = pmvy[1] = pmvy[2] = pmvy[3] = 0;
-         *fourMVs = 0;
-         if mvLegal(mvRow1[xx2], currY << 1, mvcData->currTime) {
-            if (mvRow1[xx2].type == MVC_MB_NOT_CODED) {
-               /*deb("mvcGetPrevNeighbourMVs: ERROR - macroblock not coded.\n");*/
-               *error = ERR_MVC_PREV_NOT_CODED;
-            }
-            else if (mvRow1[xx2].type == MVC_MB_INTRA) {
-               /*deb("mvcGetPrevNeighbourMVs: ERROR - INTRA macroblock.\n");*/
-               *error = ERR_MVC_PREV_INTRA;
-            }
-            else {
-               /*deb("mvcGetPrevNeighbourMVs: ERROR - macroblock not valid.\n");*/
-               *error = ERR_MVC_PREV_NOT_VALID;
-            }
-         }
-         else {
-            /*deb("mvcGetPrevNeighbourMVs: ERROR - macroblock not valid.\n");*/
-            *error = ERR_MVC_PREV_NOT_VALID;
-         }
-      }
-   }
-   else {
-      /*deb("mvcGetPrevNeighbourMVs: ERROR - no previous macroblock.\n");*/
-      *error = ERR_MVC_NO_PREV_MB;
-   }
-}
-
-
-/* {{-output"mvcGetPrevMVFsAndMVBs.txt"}} */
-/*
- *
- * mvcGetPrevMVFsAndMVBs
- *
- * Parameters:
- *    mvcData           mvcData_t structure
- *
- *    mvfx              the resulting forward motion vector
- *    mvfy
- *
- *    mvbx              the resulting backward motion vector
- *    mvby
- *
- *    fourMVs           1 if there is four motion vectors per macroblock
- *                      0 otherwise
- *
- * Function:
- *    This function gets the forward and backward motion vectors for the
- *    previous B macroblock.
- *
- * Returns:
- *    Changes *mvfx, *mvfy, *mvbx, *mvby and *fourMVs.
- *
- * Error codes:
- *    ERR_MVC_NO_PREV_MB            if the current MB has x coordinate 0 and
- *                                  mvcGetPrevNeighbourMVs is called
- *
- *    ERR_MVC_PREV_NOT_VALID        if the motion vectors for the previous
- *                                  macroblock do not exist
- *
- *    
- */
-
-void mvcGetPrevMVFsAndMVBs(mvcData_t *mvcData, int *mvfx, int *mvfy,
-   int *mvbx, int *mvby, u_char *fourMVs, int16 *error)
-/* {{-output"mvcGetPrevMVFsAndMVBs.txt"}} */
-{
-   mvBFBufItem_t
-      *mvFBuf = mvcData->mvFBufArray[mvcData->mvBFBufIndex ^ 1],
-      *mvBBuf = mvcData->mvBBufArray[mvcData->mvBFBufIndex ^ 1];
-   int i;
-
-   if (mvcData->currX > 0) {
-      if (mvBBuf[0].x == mvcData->currX - 1 &&
-         mvValid(mvBBuf[0], mvcData->currY, mvcData->currTime)) {
-         *fourMVs = mvBBuf[0].fourMVs;
-         for (i = 0; i < 4; i++) {
-            mvfx[i] = mvFBuf[i].mvx;
-            mvfy[i] = mvFBuf[i].mvy;
-            mvbx[i] = mvBBuf[i].mvx;
-            mvby[i] = mvBBuf[i].mvy;
-         }
-      }
-      else {
-         /*deb("mvcGetPrevMVFsAndMVBs: ERROR - PREV_NOT_VALID.\n");*/
-         *error = ERR_MVC_PREV_NOT_VALID;
-      }
-   }
-   else {
-      /*deb("mvcGetPrevMVFsAndMVBs: ERROR - NO_PREV_MB.\n");*/
-      *error = ERR_MVC_NO_PREV_MB;
-   }
-}
-
-
-/* {{-output"mvcMarkMB.txt"}} */
-/*
- *
- * mvcMarkMBIntra
- * mvcMarkMBNotCoded
- *
- * Parameters:
- *    mvcData        mvcData_t structure
- *    x              the x coordinate of the MB (0 .. maxX)
- *    y              the y coordinate of the MB
- *                   (0 .. macroblock rows in frame - 1)
- *
- *    time           a value which is related to the time when the current
- *                   frame must be shown. This value should be unique
- *                   among a relatively small group of consecutive frames.
- *
- * Function:
- *    These functions are used to mark that the macroblock is either
- *    intra coded or not coded at all. The information is used when
- *    deciding the neighboring motion vectors of a macroblock in
- *    mvcGetPrevNeighbourMVs and mvcGetCurrNeighbourMVs.
- *    Note that mvcMarkMBIntra should not be called in case of
- *    INTRA block in PB-frame mode. Instead mvcCalcMV should be used.
- *
- * Returns:
- *    Nothing
- *
- * Error codes:
- *    None
- *
- *    
- *    
- */
-
-void mvcMarkMBIntra(mvcData_t *mvcData, int x, int y, int time)
-/* {{-output"mvcMarkMB.txt"}} */
-{
-   int
-      xx2 = x << 1,
-      yx2 = y << 1;
-   mvRowItem_t
-      *mvRow1,
-      *mvRow2;
-
-   updateRowPointers(x, y, time);
-   mvRow1 = mvcData->mvRow1;
-   mvRow2 = mvcData->mvRow2;
-   mvStoreMB(mvRow1, mvRow2, xx2, yx2, MVD_INTRA, MVD_INTRA, time, MVC_MB_INTRA);
-}
-
-/* {{-output"mvcMarkMBNotCoded.txt"}} */
-void mvcMarkMBNotCoded(mvcData_t *mvcData, int x, int y, int time)
-/* {{-output"mvcMarkMBNotCoded.txt"}} */
-{
-   int
-      xx2 = x << 1,
-      yx2 = y << 1;
-   mvRowItem_t
-      *mvRow1,
-      *mvRow2;
-
-   updateRowPointers(x, y, time);
-   mvRow1 = mvcData->mvRow1;
-   mvRow2 = mvcData->mvRow2;
-   mvStoreMB(mvRow1, mvRow2, xx2, yx2, MVD_NOT_CODED,
-      MVD_NOT_CODED, time, MVC_MB_NOT_CODED);
-}
-
-
-/* {{-output"mvcStart.txt"}} */
-/*
- *
- * mvcStart
- *
- * Parameters:
- *       mvcData        mvcData_t structure
- *
- *       maxX           the largest x coordinate possible for a macroblock
- *                      If maxX if different from maxX when the function was
- *                      last called, a new dynamic memory allocation is made.
- *
- *       lumWidth       Luminance width
- *
- *       lumHeight      Luminance height
- *
- *       error          error code
- *
- * Function:
- *       This function initialises motion vector buffers. It also allocates
- *       buffer memory if needed.
- *       One should call mvcStart in the beginning of each video sequence.
- *
- * Returns:
- *       Nothing
- *
- * Error codes:
- *       ERR_MVC_ALLOC1          dynamic allocation error
- *       ERR_MVC_MAX_X_ILLEGAL   maxX <= 0
- *
- *      
- *      
- *  
- */
-
-void mvcStart(mvcData_t *mvcData, int maxX, int lumWidth, int lumHeight, int16 *error)
-/* {{-output"mvcStart.txt"}} */
-{
-   int
-      i, j, /* loop variables */
-      rowSize; /* the number of items in prevMV?Row */
-
-   if (maxX < 0) {
-      *error = ERR_MVC_MAX_X_ILLEGAL;
-      return;
-   }
-
-   rowSize = (maxX + 1) << 1;
-
-   if (mvcData->currMaxX != maxX || mvcData->mvRow == NULL) {
-      /* frame size changed */
-
-      if (mvcData->mvRow) free(mvcData->mvRow);
-
-      mvcData->mvRow = (mvRowItem_t *) vdcMalloc(
-         rowSize * 3 * sizeof(mvRowItem_t));
-      if (mvcData->mvRow == NULL) {
-         deb("mvcStart: ERROR - memory allocation failed.\n");
-         *error = ERR_MVC_ALLOC1;
-         return;
-      }
-
-      mvcData->currMaxX = maxX;
-   }
-   
-   /* Horizontal motion vector range when PLUSTYPE present and UUI = 1
-      See Table D.1/H.263 */
-   if (mvcData->currLumHeight != lumHeight)
-   {
-      mvcData->currLumHeight = lumHeight;
-      if ((lumHeight>=4)&&(lumHeight<=288))
-      {
-         mvcData->mvRangeLowY = -320;
-         mvcData->mvRangeHighY = 315;
-      }
-      else if ((lumHeight>=292)&&(lumHeight<=576))
-      {
-         mvcData->mvRangeLowY = -640;
-         mvcData->mvRangeHighY = 635;
-      }
-      else if ((lumHeight>=580)&&(lumHeight<=1152))
-      {
-         mvcData->mvRangeLowY = -1280;
-         mvcData->mvRangeHighY = 1275;
-      }
-   }
-
-   /* Vertical motion vector range when PLUSTYPE present and UUI = 1
-      See Table D.2/H.263 */
-   if (mvcData->currLumWidth != lumWidth)
-   {
-      mvcData->currLumWidth = lumWidth;
-      if ((lumWidth>=4)&&(lumWidth<=352))
-      {
-         mvcData->mvRangeLowX = -320;
-         mvcData->mvRangeHighX = 315;
-      }
-      else if ((lumWidth>=356)&&(lumWidth<=704))
-      {
-         mvcData->mvRangeLowX = -640;
-         mvcData->mvRangeHighX = 635;
-      }
-      else if ((lumWidth>=708)&&(lumWidth<=1408))
-      {
-         mvcData->mvRangeLowX = -1280;
-         mvcData->mvRangeHighX = 1275;
-      }
-      else if ((lumWidth>=1412)&&(lumWidth<=2048))
-      {
-         mvcData->mvRangeLowX = -2560;
-         mvcData->mvRangeHighX = 2555;
-      }
-   }
-   /* Set time to be impossible */
-   for (i = 0; i < 3 * rowSize; i++) {
-      mvcData->mvRow[i].time = -2;
-   }
-
-   for (j = 0; j < 2; j++) {
-      for (i = 0; i < 4; i++) {
-         mvcData->mvFBufArray[j][i].time = -2;
-         mvcData->mvBBufArray[j][i].time = -2;
-      }
-   }
-
-   mvcData->currX = -1;
-   mvcData->currY = -1;
-   mvcData->currTime = -2;
-   mvcData->mvRowIndex = 0;
-   mvcData->mvBFBufIndex = 0;
-   mvcData->prevPredMode = 3;
-}
-
-
-/* Local functions */
-
-
-
-/*
- *
- * mvcGetNeighbourMVs
- *
- * Parameters:
- *       mvcData  mvcData_t structure
- *       x
- *       y        macroblock coordinates
- *       time     time reference
- *       nmvx     pointer to motion vector x component array
- *       nmvy     pointer to motion vector y component array
- *                See mvcGetCurrNeighbourMVs/mvcGetPrevNeighbourMVs for
- *                description.
- *       prevFlag If this flag is set, the previous border values should
- *                be used.
- *       error    error code
- *
- * Function:
- *       This function return the motion vectors of the neighboring
- *       blocks (on the left side, above or on the right side) of the
- *       macroblock which is investigated. mvcGetNeighbourMVs is used
- *       by mvcGetCurrNeighbourMVs and mvcGetPrevNeighbourMVs.
- *       See also the functional description for these functions.
- *
- * Returns:
- *       Changes nmvx and nmvy and possibly error.
- *
- * Error codes:
- *    ERR_MVC_NEIGHBOUR_NOT_VALID   if one of the neighboring MVs is not
- *                                  valid, i.e. it has not been updated
- *                                  for this frame. The MV in nmvx and nmvy
- *                                  is set to zero.
- *
- *    
- */
-
-static void mvcGetNeighbourMVs(mvcData_t *mvcData, int x, int y, int time,
-   int *nmvx, int *nmvy, int prevFlag, int16 *error)
-{
-   int
-      xx2 = x << 1,
-      yx2 = y << 1,
-      xtmp,
-      ytmp,
-      rightOfBorder,
-      downOfBorder,
-      leftOfBorder;
-   mvRowItem_t
-      *mvRow0 = mvcData->mvRow0,
-      *mvRow1 = mvcData->mvRow1,
-      *mvRow2 = mvcData->mvRow2;
-
-   if (prevFlag)  {
-      rightOfBorder = mvcData->rightOfBorderPrev;
-      downOfBorder = (mvcData->fSS)?mvcData->downOfBorderPrev:(y==0);
-      leftOfBorder = 0;
-   }
-   else  {
-      rightOfBorder = mvcData->rightOfBorder;
-      downOfBorder = (mvcData->fSS)?mvcData->downOfBorder:(y==0);
-      leftOfBorder = (mvcData->fSS)?(x == mvcData->currMaxX)||(mvcData->leftOfBorder):(x == mvcData->currMaxX);
-   }
-   //if (x > 0) {
-   if (!rightOfBorder)  {
-      xtmp = xx2 - 1;
-      mvcCheckAndSet(mvRow1, xtmp, yx2, time, MVC_XM1_UP, nmvx, nmvy, 
-         mvRow1, xx2, yx2, error);
-      mvcCheckAndSet(mvRow2, xtmp, yx2 + 1, time, MVC_XM1_DOWN, nmvx, nmvy, 
-         mvRow2, xx2, yx2 + 1, error);
-   }
-   else {
-      mvcSetToCurrent(mvRow1, xx2, yx2, time, MVC_XM1_UP, nmvx, nmvy, 
-         error);
-      mvcSetToCurrent(mvRow2, xx2, yx2 + 1, time, MVC_XM1_DOWN, nmvx, nmvy, 
-         error);
-   }
-
-   //if (y > 0) {
-   if (!downOfBorder)   {
-      ytmp = yx2 - 1;
-      mvcCheckAndSet(mvRow0, xx2, ytmp, time, MVC_YM1_LEFT, nmvx, nmvy, 
-         mvRow1, xx2, yx2, error);
-      mvcCheckAndSet(mvRow0, xx2 + 1, ytmp, time, MVC_YM1_RIGHT, nmvx, nmvy,
-         mvRow1, xx2 + 1, yx2, error);
-   }
-   else {
-      mvcSetToCurrent(mvRow1, xx2, yx2, time, MVC_YM1_LEFT, nmvx, nmvy, 
-         error);
-      mvcSetToCurrent(mvRow1, xx2 + 1, yx2, time, MVC_YM1_RIGHT, nmvx, nmvy, 
-         error);
-   }
-
-   //if (x < mvcData->currMaxX) {
-   if (!leftOfBorder) {
-      xtmp = xx2 + 2;
-      mvcCheckAndSet(mvRow1, xtmp, yx2, time, MVC_XP1_UP, nmvx, nmvy, 
-         mvRow1, xtmp - 1, yx2, error);
-      mvcCheckAndSet(mvRow2, xtmp, yx2 + 1, time, MVC_XP1_DOWN, nmvx, nmvy,
-         mvRow2, xtmp -1, yx2 + 1, error);
-   }
-   else {
-      xtmp = xx2 + 1;
-      mvcSetToCurrent(mvRow1, xtmp, yx2, time, MVC_XP1_UP, nmvx, nmvy, 
-         error);
-      mvcSetToCurrent(mvRow2, xtmp, yx2 + 1, time, MVC_XP1_DOWN, nmvx, nmvy, 
-         error);
-   }
-}
-
-
-
-/*
- * mvcCheckAndSet
- *
- * Parameters:
- *    mvRowPtr    Source row item pointer
- *    xind        x index of the source block
- *    yind        y index of the source block
- *    timeref     time reference
- *    nind        index to motion vector arrays ( x and y)
- *    nmvx        pointer to motion vector x component array
- *    nmvy        pointer to motion vector y component array
- *    cmvRowPtr   Target row item pointer
- *    cxind       x index of the target block
- *    cyind       y index of the target block
- *    error       error code
- *
- * Function:
- *       Sets the correct value for neighboring motion vector
- *       used from: mvcGetNeighbourMVs 
- *
- * Returns:
- *       Nothing
- *
- * Error codes:
- *
- */
-
-__inline static void mvcCheckAndSet( 
-      mvRowItem_t *mvRowPtr, int xind, int yind, int timeref, int nind, 
-      int *nmvx, int *nmvy, mvRowItem_t *cmvRowPtr, int cxind, int cyind,
-      int16 *error)
-{
-
-   if (mvLegal(mvRowPtr[xind], yind, timeref))  {
-      if (mvRowPtr[xind].mvx >= MVD_UMIN_V2) {
-         nmvx[nind] = mvRowPtr[xind].mvx; 
-         nmvy[nind] = mvRowPtr[xind].mvy; 
-      } 
-      else if (mvRowPtr[xind].mvx == MVD_INTRA) { 
-         if (mvLegal(cmvRowPtr[cxind], cyind, timeref)) { 
-            if (mvValid(cmvRowPtr[cxind], cyind, timeref)) { 
-               nmvx[nind] = cmvRowPtr[cxind].mvx; 
-               nmvy[nind] = cmvRowPtr[cxind].mvy; 
-            } 
-            else /* Not coded macroblock */ 
-               nmvx[nind] = nmvy[nind] = 0; 
-         } 
-         else { 
-            deb("mvcCheckAndSet: ERROR - neighbour not valid.\n"); 
-            *error = ERR_MVC_NEIGHBOUR_NOT_VALID; 
-            nmvx[nind] = nmvy[nind] = 0; 
-         } 
-      } 
-      else { /* MVD_NOT_CODED */ 
-         nmvx[nind] = nmvy[nind] = 0; 
-      } 
-   } 
-   else { 
-      deb("mvcCheckAndSet: ERROR - neighbour not valid.\n"); 
-      *error = ERR_MVC_NEIGHBOUR_NOT_VALID; 
-      nmvx[nind] = nmvy[nind] = 0; 
-   }
-}
-
-/*
- * mvcSetToCurrent
- *
- * Parameters:
- *    mvRowPtr    Current row item pointer
- *    xind        x index of the block
- *    yind        y index of the block
- *    timeref     time reference
- *    nind        index to motion vector arrays ( x and y)
- *    nmvx        pointer to motion vector x component array
- *    nmvy        pointer to motion vector y component array
- *    error       error code
- *
- * Function:
- *       Sets the correct value for neighboring motion vector using current
- *       motion vector, used in cases of border used from: mvcGetNeighbourMVs
- *
- * Returns:
- *       Nothing
- *
- * Error codes:
- *
- * History
- */
-
-__inline static void mvcSetToCurrent( 
-      mvRowItem_t *mvRowPtr, int xind, int yind, int timeref, int nind,
-      int *nmvx, int *nmvy, int16 *error)
-{
-   if (mvValid(mvRowPtr[xind], yind, timeref)) { 
-      nmvx[nind] = mvRowPtr[xind].mvx; 
-      nmvy[nind] = mvRowPtr[xind].mvy; 
-   } 
-   else { 
-      deb("mvcSetToCurrent: ERROR - neighbour not valid.\n"); 
-      *error = ERR_MVC_NEIGHBOUR_NOT_VALID; 
-      nmvx[nind] = nmvy[nind] = 0; 
-   }
-}
-
-// End of File