videoeditorengine/h263decoder/src/bma.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * Implementation for MPEG4(H263) video transcoder. 
       
    17 * Block matching algorithms for MPEG4(H263) video transcoder.
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 
       
    23 #include "biblin.h"
       
    24 #include "common.h"
       
    25 #include "h263dconfig.h"
       
    26 #include "decmbdct.h"
       
    27 #include "vdxint.h"
       
    28 
       
    29 /* 
       
    30  * Constants/definitions 
       
    31  */
       
    32 
       
    33 #define DIAMOND_SEARCH_NUMBER 2
       
    34 
       
    35 
       
    36 const tVLCTable sCBPCIType[9] = 
       
    37 {
       
    38     {0x01,0x01}, {0x01,0x03}, {0x02,0x03}, {0x03,0x03}, 
       
    39         {0x01,0x04}, {0x01,0x06}, {0x02,0x06}, {0x03,0x06}, 
       
    40         {0x01,0x09}
       
    41 };
       
    42 
       
    43 const tVLCTable sCBPCPType[21] = 
       
    44 {
       
    45     {0x01,0x01}, {0x03,0x04}, {0x02,0x04}, {0x05,0x06},
       
    46     {0x03,0x03}, {0x07,0x07}, {0x06,0x07}, {0x05,0x09}, 
       
    47     {0x02,0x03}, {0x05,0x07}, {0x04,0x07}, {0x05,0x08},
       
    48     {0x03,0x05}, {0x04,0x08}, {0x03,0x08}, {0x03,0x07},
       
    49     {0x04,0x06}, {0x04,0x09}, {0x03,0x09}, {0x02,0x09}, 
       
    50     {0x01,0x09}
       
    51 };
       
    52 
       
    53 const tVLCTable sCBPY[16] = 
       
    54 {
       
    55     {0x03,0x04}, {0x05,0x05}, {0x04,0x05}, {0x09,0x04},
       
    56     {0x03,0x05}, {0x07,0x04}, {0x02,0x06}, {0x0b,0x04},
       
    57     {0x02,0x05}, {0x03,0x06}, {0x05,0x04}, {0x0a,0x04},
       
    58     {0x04,0x04}, {0x08,0x04}, {0x06,0x04}, {0x03,0x02}
       
    59 };
       
    60 
       
    61 const unsigned int sDquant[5] = 
       
    62 {
       
    63     0x01, 0x00, (unsigned int)NOT_VALID, 0x02, 0x03
       
    64 };
       
    65 
       
    66 const tVLCTable sMVTab[33] =
       
    67 {
       
    68         {0x01,0x01}, {0x02,0x03}, {0x02,0x04}, {0x02,0x05}, 
       
    69         {0x06,0x07}, {0x0a,0x08}, {0x08,0x08}, {0x06,0x08},
       
    70         {0x16,0x0a}, {0x14,0x0a}, {0x12,0x0a}, {0x22,0x0b},
       
    71         {0x20,0x0b}, {0x1e,0x0b}, {0x1c,0x0b}, {0x1a,0x0b},
       
    72         {0x18,0x0b}, {0x16,0x0b}, {0x14,0x0b}, {0x12,0x0b},
       
    73         {0x10,0x0b}, {0x0e,0x0b}, {0x0c,0x0b}, {0x0a,0x0b},
       
    74         {0x08,0x0b}, {0x0e,0x0c}, {0x0c,0x0c}, {0x0a,0x0c}, 
       
    75         {0x08,0x0c}, {0x06,0x0c}, {0x04,0x0c}, {0x06,0x0d},
       
    76         {0x04,0x0d}
       
    77 }; 
       
    78 
       
    79 const int32  sFixedQuantScale1[32]=
       
    80 {
       
    81       0x0000, 0x7fff, 0x3fff, 0x2aaa, 
       
    82         0x1fff, 0x1999, 0x1555, 0x1249, 
       
    83         0x0fff, 0x0e38, 0x0ccc, 0x0ba2,  
       
    84         0x0aaa, 0x09d8, 0x0924, 0x0888,  
       
    85         0x07ff, 0x0787, 0x071c, 0x06bc,  
       
    86         0x0666, 0x0618, 0x05d1, 0x1590,  
       
    87         0x0555, 0x051e, 0x04ec, 0x04bd,  
       
    88         0x0492, 0x0469, 0x0444, 0x0421  
       
    89 };  
       
    90 
       
    91 const u_int16 sPrePostMult[64] = 
       
    92 { 
       
    93       0x8000, 0xb18a, 0xa73d, 0x9683,  
       
    94         0x8000, 0x9683, 0xa73d, 0xb18a, 
       
    95       0xb18a, 0xf641, 0xe7f7, 0xd0c3,  
       
    96         0xb18a, 0xd0c3, 0xe7f7, 0xf641, 
       
    97       0xa73d, 0xe7f7, 0xda82, 0xc4a7,  
       
    98         0xa73d, 0xc4a7, 0xda82, 0xe7f7, 
       
    99       0x9683, 0xd0c3, 0xc4a7, 0xb0fb,  
       
   100         0x9683, 0xb0fb, 0xc4a7, 0xd0c3, 
       
   101       0x8000, 0xb18a, 0xa73d, 0x9683,  
       
   102         0x8000, 0x9683, 0xa73d, 0xb18a, 
       
   103       0x9683, 0xd0c3, 0xc4a7, 0xb0fb,  
       
   104         0x9683, 0xb0fb, 0xc4a7, 0xd0c3, 
       
   105       0xa73d, 0xe7f7, 0xda82, 0xc4a7,  
       
   106         0xa73d, 0xc4a7, 0xda82, 0xe7f7, 
       
   107       0xb18a, 0xf641, 0xe7f7, 0xd0c3,  
       
   108         0xb18a, 0xd0c3, 0xe7f7, 0xf641
       
   109 };
       
   110 
       
   111 
       
   112 
       
   113 /* 
       
   114  * Function Declarations 
       
   115  */
       
   116 int32 vlbCodeACCoeffsSVHWithZigZag(int32 coeffStart, int16* block, bibBuffer_t * outBuf,
       
   117                                  int32 svh, int32 lastPos);
       
   118 void vlbPutBits(bibBuffer_t *base, int32 numBits, u_int32 value);
       
   119 
       
   120 
       
   121 
       
   122 /* 
       
   123  * Function Definitions 
       
   124  */
       
   125 
       
   126 /* {{-output"vbmGetH263IMCBPC.txt"}} */
       
   127 /*
       
   128 * vbmGetH263IMCBPC
       
   129 *
       
   130 * Parameters:
       
   131 *     vopCodingType            coding type (INTER/INTRA) for the VOP
       
   132 *           dQuant                   quantization parameter
       
   133 *           colorEffect              indicates color effect to be aplpied (e.g., black & white)
       
   134 *           cbpy                       cbpy value for the macro block
       
   135 *           mcbpcVal                   computed mcbpc value for the macro block
       
   136 *           length                   length of the computed mcbpc value codeword
       
   137 *
       
   138 * Function:
       
   139 *     This function evaluates the mcpbc codeword for INTRA macro block
       
   140 *
       
   141 * Returns:
       
   142 *     Nothing.
       
   143 *
       
   144 * Error codes:
       
   145 *     None.
       
   146 *
       
   147 */
       
   148 void vbmGetH263IMCBPC(int dQuant, int vopCodingType, int /*colorEffect*/, 
       
   149                                      int cbpy, int& mcbpcVal, int& length)
       
   150 {
       
   151     int index;
       
   152     int len, mcbpc;
       
   153 
       
   154     if(vopCodingType == 1 /* VDX_VOP_TYPE_P */)
       
   155     {
       
   156         index = (dQuant == 0 ? 12 : 16) + mcbpcVal;
       
   157         len = sCBPCPType[index].length + sCBPY[cbpy].length + 1;
       
   158         mcbpc = (sCBPCPType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code;
       
   159         mcbpcVal = mcbpc;
       
   160         length = len;
       
   161     }
       
   162     else
       
   163     {
       
   164         index = (dQuant == 0 ? 0 : 4) + mcbpcVal;
       
   165         len = sCBPCIType[index].length + sCBPY[cbpy].length ;
       
   166         mcbpc = (sCBPCIType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code;
       
   167         mcbpcVal = mcbpc;
       
   168         length = len;
       
   169     }
       
   170 }
       
   171 
       
   172 
       
   173 
       
   174 /* {{-output"vbmGetH263PMCBPC.txt"}} */
       
   175 /*
       
   176 * vbmGetH263PMCBPC
       
   177 *
       
   178 * Parameters:
       
   179 *           dQuant                   quantization parameter
       
   180 *           colorEffect              indicates color effect to be aplpied (e.g., black & white)
       
   181 *           cbpy                       cbpy value for the macro block
       
   182 *           mcbpcVal                   computed mcbpc value for the macro block
       
   183 *           length                   length of the computed mcbpc value codeword
       
   184 *
       
   185 * Function:
       
   186 *     This function evaluates the mcpbc codeword for INTER macro block
       
   187 *
       
   188 * Returns:
       
   189 *     Nothing.
       
   190 *
       
   191 * Error codes:
       
   192 *     None.
       
   193 *
       
   194 */
       
   195 void vbmGetH263PMCBPC(int dQuant, int /*colorEffect*/, int cbpy, int& mcbpcVal, int& length)
       
   196 {
       
   197     int index;
       
   198     int len, mcbpc;
       
   199     cbpy = (~cbpy) & 0xf;
       
   200     
       
   201     /* only ONE MV in baseline H263 */
       
   202     index = (dQuant == 0 ? 0 : 4) + mcbpcVal;
       
   203     len = sCBPCPType[index].length + sCBPY[cbpy].length;
       
   204     mcbpc = (sCBPCPType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code;
       
   205     mcbpcVal = mcbpc;
       
   206     length = len;
       
   207 }
       
   208 
       
   209 
       
   210 
       
   211 /* {{-output"vbmEncodeMVDifferential.txt"}} */
       
   212 /*
       
   213 * vbmEncodeMVDifferential
       
   214 *
       
   215 * Parameters:
       
   216 *     outBuf                     output buffer
       
   217 *           mvdx                     motion vector difference value in horizontal direction, in half-pixel unit
       
   218 *           mvdy                     motion vector difference value in vertical direction, in half-pixel unit
       
   219 *           fCode                      Fcode value
       
   220 *
       
   221 * Function:
       
   222 *     This function encodes the MV difference after prediction into the bitstream
       
   223 *
       
   224 * Returns:
       
   225 *     Nothing.
       
   226 *
       
   227 * Error codes:
       
   228 *     None.
       
   229 *
       
   230 */
       
   231 void vbmEncodeMVDifferential(int32 mvdx, int32 mvdy, int32 fCode, 
       
   232                            bibBuffer_t * outBuf)
       
   233 {
       
   234     int32   mvd[2];
       
   235     u_int32 i;
       
   236     int32   temp;
       
   237     int32   motioncode;
       
   238     int32   motionresidual;
       
   239     int32   rsize = fCode - 1;
       
   240     u_int32 f     = 1 << rsize;
       
   241     int32   high  = 32 * f - 1;
       
   242     int32   low   = -32 * (int32) f;
       
   243     int32   range = 64 *f;
       
   244     
       
   245     mvd[0] = mvdx;
       
   246     mvd[1] = mvdy;
       
   247     
       
   248     for(i = 0; i < 2; i++)    
       
   249     {
       
   250         if (mvd[i] < low)
       
   251         {
       
   252             mvd[i] += range;
       
   253         }
       
   254         else
       
   255         {
       
   256             if (mvd[i] > high)
       
   257             {
       
   258                 mvd[i] -= range;
       
   259             }
       
   260         }
       
   261         temp = ABS(mvd[i]) -1 + f;
       
   262         motioncode = temp >> rsize;    
       
   263         if(mvd[i] >= 0)
       
   264         {
       
   265             vlbPutBits(outBuf, sMVTab[motioncode].length, sMVTab[motioncode].code);
       
   266         }
       
   267         else
       
   268         {
       
   269             vlbPutBits(outBuf, sMVTab[motioncode].length, (sMVTab[motioncode].code) ^ 1);
       
   270         }        
       
   271         if (rsize != 0 && motioncode != 0)
       
   272         {
       
   273             motionresidual = temp & (f - 1);
       
   274             vlbPutBits(outBuf, rsize, motionresidual);
       
   275         }   
       
   276     }
       
   277     return;
       
   278 }
       
   279 
       
   280 
       
   281 
       
   282 
       
   283 /* {{-output"vbmMedian3.txt"}} */
       
   284 /*
       
   285 * vbmMedian3
       
   286 *
       
   287 * Parameters:
       
   288 *     s1                         pointer to the first vector
       
   289 *     s2                         pointer to the second vector
       
   290 *     s3                         pointer to the third vector
       
   291 *     med                        pointer to store the median vector
       
   292 *
       
   293 * Function:
       
   294 *     This function finds the median of three vectors
       
   295 *
       
   296 * Returns:
       
   297 *     Nothing.
       
   298 *
       
   299 * Error codes:
       
   300 *     None.
       
   301 *
       
   302 */
       
   303 void vbmMedian3(int16 *s1, int16 *s2, int16 *s3, tMotionVector *med)
       
   304 {
       
   305     int32 temp1;
       
   306     int32 temp2;
       
   307     int32 temp3;
       
   308     
       
   309     temp1 = s1[0];
       
   310     temp2 = s2[0];
       
   311     temp3 = s3[0];
       
   312     
       
   313     if (temp1 > temp2)
       
   314     {
       
   315         temp1 += temp2;
       
   316         temp2 = temp1 - temp2;
       
   317         temp1 -= temp2;
       
   318     }
       
   319     if (temp2 > temp3)
       
   320     {
       
   321         temp2 += temp3;
       
   322         temp3 = temp2 - temp3;
       
   323         temp2 -= temp3;
       
   324     }
       
   325     if (temp1 > temp2)
       
   326     {
       
   327         temp1 += temp2;
       
   328         temp2 = temp1 - temp2;
       
   329         temp1 -= temp2;
       
   330     }
       
   331     
       
   332     med->mvx = (int16) temp2;
       
   333     temp1 = s1[1];
       
   334     temp2 = s2[1];
       
   335     temp3 = s3[1];
       
   336     
       
   337     if (temp1 > temp2)
       
   338     {
       
   339         temp1 += temp2;
       
   340         temp2 = temp1 - temp2;
       
   341         temp1 -= temp2;
       
   342     }
       
   343     if (temp2 > temp3)
       
   344     {
       
   345         temp2 += temp3;
       
   346         temp3 = temp2 - temp3;
       
   347         temp2 -= temp3;
       
   348     }
       
   349     if (temp1 > temp2)
       
   350     {
       
   351         temp1 += temp2;
       
   352         temp2 = temp1 - temp2;
       
   353         temp1 -= temp2;
       
   354     }
       
   355     med->mvy = (int16) temp2;
       
   356     
       
   357     return;
       
   358 }
       
   359 
       
   360 
       
   361 
       
   362 /* {{-output"vbmMvPrediction.txt"}} */
       
   363 /*
       
   364 * vbmMvPrediction
       
   365 *
       
   366 * Parameters:
       
   367 *     mbi                  macro block info needed for processing
       
   368 *     predMV               pointer to motion vector predictors
       
   369 *     mbinWidth            number of MBs per row
       
   370 *     mBCnt                    mecro block number
       
   371 *
       
   372 * Function:
       
   373 *     This function performs prediction of MV based on adjacent blocks
       
   374 *
       
   375 * Returns:
       
   376 *     Nothing.
       
   377 *
       
   378 * Error codes:
       
   379 *     None.
       
   380 *
       
   381 */
       
   382 void vbmMvPrediction(tMBInfo *mbi, int32 mBCnt, tMotionVector *predMV, int32 mbinWidth)
       
   383 {
       
   384     int16    p[3][2];
       
   385     int32    zeroFound = 0;
       
   386     int32    zeroPredictors = 0;
       
   387     
       
   388     if (mBCnt % mbinWidth == 0)
       
   389     {
       
   390         p[0][0] = 0;
       
   391         p[0][1] = 0;
       
   392         zeroPredictors++;
       
   393     }
       
   394     else
       
   395     {
       
   396         p[0][0] = (mbi - 1)->MV[0][0];
       
   397         p[0][1] = (mbi - 1)->MV[0][1];
       
   398     }
       
   399     
       
   400     if (mBCnt / mbinWidth == 0) 
       
   401     {
       
   402         p[1][0] = 0;
       
   403         p[1][1] = 0;
       
   404         zeroPredictors++;
       
   405         zeroFound += 1;
       
   406     }
       
   407     else
       
   408     {
       
   409         p[1][0] = (mbi - mbinWidth)->MV[0][0];
       
   410         p[1][1] = (mbi - mbinWidth)->MV[0][1];
       
   411     }
       
   412     
       
   413     if ((mBCnt / mbinWidth == 0) ||
       
   414         ((mBCnt % mbinWidth) == (mbinWidth - 1)))
       
   415     {
       
   416         p[2][0] = 0;
       
   417         p[2][1] = 0;
       
   418         zeroPredictors++;
       
   419         zeroFound += 2;
       
   420     }
       
   421     else
       
   422     {
       
   423         p[2][0] = (mbi - mbinWidth + 1)->MV[0][0];
       
   424         p[2][1] = (mbi - mbinWidth + 1)->MV[0][1];
       
   425     }
       
   426     
       
   427     if (zeroPredictors == 3)
       
   428     {
       
   429         predMV->mvx = 0;
       
   430         predMV->mvy = 0;
       
   431     }
       
   432     else if (zeroPredictors == 2)
       
   433     {
       
   434         predMV->mvx = p[zeroFound^3][0];
       
   435         predMV->mvy = p[zeroFound^3][1];
       
   436     }
       
   437     else
       
   438     {
       
   439         vbmMedian3(p[0], p[1], p[2], predMV);
       
   440     }
       
   441     return;
       
   442 }
       
   443 
       
   444 
       
   445 
       
   446 /* {{-output"vbmMBSAD.txt"}} */
       
   447 /*
       
   448 * vbmMBSAD
       
   449 *
       
   450 * Parameters:
       
   451 *     refFrame             pointer to reference frame
       
   452 *     currMB               pointer to current MB
       
   453 *     mv                   pointer to store the SAD and having motion vector
       
   454 *     mbPos                pointer to macroblock position structure
       
   455 *     vopWidth             width of frame/VOP
       
   456 *     yWidth               width of luminance frame 
       
   457 *
       
   458 * Function:
       
   459 *     This function computes the SAD (Sum of Absolute Difference) 
       
   460 *     for a macroblock for integer motion vector
       
   461 *
       
   462 * Returns:
       
   463 *     Nothing.
       
   464 *
       
   465 * Error codes:
       
   466 *     None.
       
   467 *
       
   468 */
       
   469 void vbmMBSAD(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, u_int32 yWidth,
       
   470                             tMotionVector* mv, const tMBPosition* mbPos)
       
   471 {
       
   472     u_int32     sad = 0;
       
   473     tPixel*     refPos;
       
   474     tPixel*     currPos;
       
   475     int32       row;
       
   476     int32       col;
       
   477     
       
   478     refPos = refFrame + (mbPos->y + mv->mvy) * vopWidth + (mbPos->x + mv->mvx); 
       
   479     currPos = currMB; 
       
   480     
       
   481     for(row = 0; row < MB_SIZE; row++)
       
   482     {
       
   483         col = row & 0x1;
       
   484         for(; col < MB_SIZE; col+= 2)
       
   485         {
       
   486             sad += ABS(*(refPos + col) - *(currPos + col));
       
   487         }
       
   488         refPos += vopWidth;
       
   489         currPos += yWidth;
       
   490     }
       
   491     mv->SAD = (sad << 1);
       
   492     return;
       
   493 }
       
   494 
       
   495 
       
   496 
       
   497 /* {{-output"vbmMVOutsideBound.txt"}} */
       
   498 /*
       
   499 * vbmMVOutsideBound
       
   500 *
       
   501 * Parameters:
       
   502 *     mbPos                pointer to macroblock position structure
       
   503 *     bestMV               pointer to store the best match motion vector
       
   504 *     halfPixel            flag to indicate whether half pel search is needed
       
   505 *
       
   506 * Function:
       
   507 *     This function checks whether the MV is within valid range
       
   508 *
       
   509 * Returns:
       
   510 *     Nothing.
       
   511 *
       
   512 * Error codes:
       
   513 *     None.
       
   514 *
       
   515 */
       
   516 tBool vbmMVOutsideBound(tMBPosition *mbPos, tMotionVector* bestMV, tBool halfPixel)
       
   517 {
       
   518     int32   xLeft;
       
   519     int32   xRight;
       
   520     int32   yTop;
       
   521     int32   yBottom;
       
   522     
       
   523     xLeft = (mbPos->x << halfPixel) + bestMV->mvx;
       
   524     xRight = (mbPos->x << halfPixel) + (MB_SIZE << halfPixel) + bestMV->mvx;
       
   525     yTop = (mbPos->y << halfPixel) + bestMV->mvy;
       
   526     yBottom = (mbPos->y << halfPixel) + (MB_SIZE << halfPixel) + bestMV->mvy;
       
   527     
       
   528     if (halfPixel)
       
   529     {
       
   530         return ((xLeft < mbPos->LeftBound) ||
       
   531             (xRight > mbPos->RightBound) ||
       
   532             (yTop < mbPos->TopBound) ||
       
   533             (yBottom > mbPos->BottomBound) ||
       
   534             ((bestMV->mvx) < -32  || (bestMV->mvx) > 31) ||
       
   535             ((bestMV->mvy) < -32  || (bestMV->mvy) > 31)
       
   536             );
       
   537     }
       
   538     else
       
   539     {
       
   540         return ((xLeft < mbPos->LeftBound) ||
       
   541             (xRight > mbPos->RightBound) ||
       
   542             (yTop < mbPos->TopBound) ||
       
   543             (yBottom > mbPos->BottomBound)||
       
   544             ((bestMV->mvx) < -16  || (bestMV->mvx) > 15) ||
       
   545             ((bestMV->mvy) < -16  || (bestMV->mvy) > 15)
       
   546             );
       
   547     }
       
   548 }
       
   549 
       
   550 
       
   551 
       
   552 /* {{-output"vbmEstimateBestPredictor.txt"}} */
       
   553 /*
       
   554 * vbmEstimateBestPredictor
       
   555 *
       
   556 * Parameters:
       
   557 *     refFrame             pointer to reference frame
       
   558 *     currMB               pointer to current MB
       
   559 *     initPred             pointer to predictor motion vectors, pixel unit
       
   560 *     mbPos                pointer to macroblock position structure
       
   561 *     vopWidth             width of frame/VOP
       
   562 *     yWidth               width of luminance frame 
       
   563 *     bestMV               pointer to store the best match motion vector
       
   564 *     noofPredictors       number of predictors
       
   565 *
       
   566 * Function:
       
   567 *     This function estimates the best predictor among the set
       
   568 *
       
   569 * Returns:
       
   570 *     Nothing.
       
   571 *
       
   572 * Error codes:
       
   573 *     None.
       
   574 *
       
   575 */
       
   576 void vbmEstimateBestPredictor(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, u_int32 yWidth, 
       
   577                               tMotionVector* initPred, tMBPosition* mbPos,
       
   578                               int32 noOfPredictors, tMotionVector* bestMV)
       
   579 {
       
   580     int32 i;
       
   581     bestMV->SAD = 65535;
       
   582     for(i = 0; i < noOfPredictors; i++)
       
   583     {
       
   584         if (vbmMVOutsideBound(mbPos, (initPred + i), 0))
       
   585         {
       
   586             initPred[i].SAD = 65535;
       
   587         }
       
   588         else
       
   589         {
       
   590             vbmMBSAD(refFrame, vopWidth, currMB, yWidth, (initPred + i), mbPos);
       
   591         }
       
   592         if(initPred[i].SAD < bestMV->SAD)
       
   593         {
       
   594             bestMV->SAD = initPred[i].SAD;
       
   595             bestMV->mvx = initPred[i].mvx;
       
   596             bestMV->mvy = initPred[i].mvy;
       
   597         }
       
   598     }
       
   599     
       
   600     return;
       
   601 }       
       
   602 
       
   603 
       
   604 
       
   605 /* {{-output"vbmEstimateBound.txt"}} */
       
   606 /*
       
   607 * vbmEstimateBound
       
   608 *
       
   609 * Parameters:
       
   610 *     mbPos                pointer to macroblock position structure
       
   611 *     vopWidth             width of frame/VOP
       
   612 *     vopHeight            height of frame/VOP
       
   613 *     searchRange          search range
       
   614 *
       
   615 * Function:
       
   616 *     This function evaluates the bounds for a macroblock BM search
       
   617 *
       
   618 * Returns:
       
   619 *     Nothing.
       
   620 *
       
   621 * Error codes:
       
   622 *     None.
       
   623 *
       
   624 */
       
   625 void vbmEstimateBound(tMBPosition *mbPos,u_int32 vopWidth, u_int32 vopHeight, int32 searchRange)
       
   626 {
       
   627     mbPos->LeftBound = mbPos->x - searchRange;
       
   628     mbPos->RightBound = mbPos->x + 16 + searchRange;
       
   629     mbPos->TopBound = mbPos->y - searchRange;
       
   630     mbPos->BottomBound = mbPos->y + 16 + searchRange;
       
   631     
       
   632     if(mbPos->LeftBound < 0)
       
   633     {
       
   634         mbPos->LeftBound = 0;
       
   635     }
       
   636     if(mbPos->RightBound > (int32)vopWidth)
       
   637     {
       
   638         mbPos->RightBound = vopWidth;
       
   639     }
       
   640     if(mbPos->TopBound < 0 )
       
   641     {
       
   642         mbPos->TopBound = 0;
       
   643     }
       
   644     if(mbPos->BottomBound > (int32)vopHeight)
       
   645     {
       
   646         mbPos->BottomBound = vopHeight;
       
   647     }
       
   648     
       
   649     return;
       
   650 }
       
   651 
       
   652 
       
   653 
       
   654 /* {{-output"vbmEstimateBoundHalfPel.txt"}} */
       
   655 /*
       
   656 * vbmEstimateBoundHalfPel
       
   657 *
       
   658 * Parameters:
       
   659 *     mbPos                pointer to macroblock position structure
       
   660 *     vopWidth             width of frame/VOP
       
   661 *     vopHeight            height of frame/VOP
       
   662 *
       
   663 * Function:
       
   664 *     This function evaluates the bounds for a macroblock BM search in half pel accuracy
       
   665 *
       
   666 * Returns:
       
   667 *     Nothing.
       
   668 *
       
   669 * Error codes:
       
   670 *     None.
       
   671 *
       
   672 */
       
   673 void vbmEstimateBoundHalfPel(tMBPosition *mbPos, u_int32 vopWidth, u_int32 vopHeight)
       
   674 {
       
   675     mbPos->LeftBound = 0;
       
   676     mbPos->RightBound = (vopWidth << 1);
       
   677     mbPos->TopBound = 0;
       
   678     mbPos->BottomBound = (vopHeight << 1);
       
   679     return;
       
   680 }
       
   681 
       
   682 
       
   683 
       
   684 /* {{-output"vbmSmallDiamondSearch.txt"}} */
       
   685 /*
       
   686 * vbmSmallDiamondSearch
       
   687 *
       
   688 * Parameters:
       
   689 *     refFrame             pointer to reference frame
       
   690 *     currMB               pointer to current MB
       
   691 *     initPred             pointer to predictor motion vectors, pixel unit
       
   692 *     mbPos                pointer to macroblock position structure
       
   693 *     vopWidth             width of frame/VOP
       
   694 *     yWidth               width of luminance frame 
       
   695 *     bestMV               pointer to store the best match motion vector
       
   696 * Function:
       
   697 *     This function performs motion estimation for a macroblock using small diamond search
       
   698 *
       
   699 * Returns:
       
   700 *     Nothing.
       
   701 *
       
   702 * Error codes:
       
   703 *     None.
       
   704 *
       
   705 */
       
   706 void vbmSmallDiamondSearch(tPixel* refFrame, tPixel* currMB, tMotionVector *initPred, 
       
   707                                                      tMotionVector* bestMV, u_int32 vopWidth, tMBPosition* mbPos, 
       
   708                                                      u_int32 yWidth)
       
   709 {
       
   710     u_int8 locateSDS[5][5] =
       
   711     {
       
   712         {0,0,0,0,0},
       
   713         {0,1,1,0,1},
       
   714         {0,1,1,1,0},
       
   715         {0,0,1,1,1},
       
   716         {0,1,0,1,1}
       
   717     };
       
   718     u_int32  i;
       
   719     int32   stepCount;
       
   720     int32   flag=1;
       
   721     int32   position=0;
       
   722     
       
   723     //form the diamond shap search pattern
       
   724     stepCount = 1;
       
   725     initPred[0].SAD = bestMV->SAD;
       
   726     initPred[1].mvx = (int16)(bestMV->mvx + 1);
       
   727     initPred[1].mvy = bestMV->mvy;
       
   728     initPred[2].mvx = bestMV->mvx;
       
   729     initPred[2].mvy = (int16)(bestMV->mvy - 1);
       
   730     initPred[3].mvx = (int16)(bestMV->mvx - 1);
       
   731     initPred[3].mvy = bestMV->mvy;
       
   732     initPred[4].mvx = bestMV->mvx;
       
   733     initPred[4].mvy = (int16)(bestMV->mvy + 1);
       
   734     
       
   735     for(i = 1; i < 5; i++)
       
   736     {
       
   737         if(vbmMVOutsideBound(mbPos, &initPred[i], 0) )
       
   738         {
       
   739             initPred[i].SAD = 65535;
       
   740         }
       
   741         else
       
   742         {
       
   743             vbmMBSAD(refFrame, vopWidth, currMB, yWidth, (initPred + i), mbPos);
       
   744         }
       
   745         if(initPred[i].SAD < bestMV->SAD)
       
   746         {
       
   747             bestMV->SAD = initPred[i].SAD;
       
   748             bestMV->mvx = initPred[i].mvx;
       
   749             bestMV->mvy = initPred[i].mvy;
       
   750             position = i;
       
   751         }
       
   752     }
       
   753     
       
   754     /* the minimum SAD falls in the center */
       
   755     if(bestMV->SAD == initPred[0].SAD)
       
   756     {
       
   757         return;
       
   758     }
       
   759     
       
   760     while(flag)
       
   761     {
       
   762         stepCount++;
       
   763         initPred[0].SAD = bestMV->SAD;
       
   764         initPred[1].mvx = (int16)(bestMV->mvx + 1);
       
   765         initPred[1].mvy = bestMV->mvy;
       
   766         initPred[2].mvx = bestMV->mvx;
       
   767         initPred[2].mvy = (int16)(bestMV->mvy - 1);
       
   768         initPred[3].mvx = (int16)(bestMV->mvx - 1);
       
   769         initPred[3].mvy = bestMV->mvy;
       
   770         initPred[4].mvx = bestMV->mvx;
       
   771         initPred[4].mvy = (int16)(bestMV->mvy + 1);
       
   772         
       
   773         for(i = 1; i < 5; i++)
       
   774         {
       
   775             if(locateSDS[position][i] != 0)
       
   776             {
       
   777                 if(vbmMVOutsideBound(mbPos, &initPred[i],0))
       
   778                 {
       
   779                     initPred[i].SAD = 65535;
       
   780                 }
       
   781                 else
       
   782                 {
       
   783                     vbmMBSAD(refFrame, vopWidth, currMB, yWidth, (initPred + i), mbPos);
       
   784                     if(initPred[i].SAD < bestMV->SAD)
       
   785                     {
       
   786                         bestMV->mvx = initPred[i].mvx;
       
   787                         bestMV->mvy = initPred[i].mvy;
       
   788                         bestMV->SAD = initPred[i].SAD;
       
   789                         position = i;
       
   790                     }
       
   791                 }
       
   792             }
       
   793         }
       
   794         if(bestMV->SAD == initPred[0].SAD)
       
   795         {
       
   796             break;
       
   797         }
       
   798         if(stepCount > DIAMOND_SEARCH_NUMBER) // we only do 2 diamond search here
       
   799         {
       
   800             break;
       
   801         }
       
   802     }
       
   803     
       
   804     return;
       
   805 }
       
   806 
       
   807 
       
   808                                                      
       
   809 /* {{-output"vbmSADHalfPel.txt"}} */
       
   810 /*
       
   811 * vbmSADHalfPel
       
   812 *
       
   813 * Parameters:
       
   814 *     refFrame             pointer to reference frame
       
   815 *     currMB               pointer to current MB
       
   816 *     mbPos                pointer to macroblock position structure
       
   817 *     vopWidth             width of frame/VOP
       
   818 *     yWidth               width of luminance frame 
       
   819 *     mv                   pointer to motion vector
       
   820 *     roundingControl      rounding control value
       
   821 *     blockSize            block size
       
   822 * Function:
       
   823 *     This function evaluates SAD for a macroblock/block for half pel motion vector
       
   824 *
       
   825 * Returns:
       
   826 *     Nothing.
       
   827 *
       
   828 * Error codes:
       
   829 *     None.
       
   830 *
       
   831 */
       
   832 void vbmSADHalfPel(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, u_int32 yWidth,
       
   833                                      tMotionVector* mv, const tMBPosition* mbPos, tBool roundingControl, 
       
   834                    int32 blockSize)
       
   835 {
       
   836     u_int32      sad = 0;
       
   837     tPixel*     refPos;
       
   838     tPixel*     currPos;
       
   839     int32       row;
       
   840     int32       col;
       
   841     int32       extendedVOPWidth;
       
   842     int32       temp;
       
   843     
       
   844     extendedVOPWidth = vopWidth ;
       
   845     refPos = refFrame + (mbPos->y + (mv->mvy >> 1)) * extendedVOPWidth + 
       
   846         (mbPos->x + (mv->mvx >> 1)); 
       
   847     currPos = currMB; 
       
   848     
       
   849     if(mv->mvy & 1)
       
   850     {
       
   851         if(mv->mvx & 1)
       
   852         {
       
   853             /* Both horizontal and vertical components are having half pel */
       
   854             for(row = 0; row < blockSize; row++)
       
   855             {
       
   856                 col = row & 0x1;
       
   857                 for(; col < blockSize; col += 2)
       
   858                 {
       
   859                     temp = (refPos[col] + refPos[col + 1] + 
       
   860                         refPos[col + extendedVOPWidth] +
       
   861                         refPos[col + extendedVOPWidth + 1] +
       
   862                         2 -roundingControl) >> 2;
       
   863                     sad += ABS(temp - currPos[col]);
       
   864                 }
       
   865                 refPos += extendedVOPWidth;
       
   866                 currPos += yWidth;
       
   867             }
       
   868             mv->SAD = (sad << 1);
       
   869         }
       
   870         else
       
   871         {
       
   872             /* Vertical component is having half pel */
       
   873             for(row = 0; row < blockSize; row++)
       
   874             {
       
   875                 col = row & 0x1;
       
   876                 for(; col < blockSize; col += 2)
       
   877                 {
       
   878                     temp = (refPos[col] + refPos[col + extendedVOPWidth]+
       
   879                         1 -roundingControl) >> 1;
       
   880                     sad += ABS(temp - currPos[col]);
       
   881                 }
       
   882                 refPos += extendedVOPWidth;
       
   883                 currPos += yWidth;
       
   884             }
       
   885             mv->SAD = (sad << 1);
       
   886         }
       
   887     }
       
   888     else
       
   889     {
       
   890         if(mv->mvx & 1)
       
   891         {
       
   892             /* Horizontal component is having half pel */
       
   893             for(row = 0; row < blockSize; row++)
       
   894             {
       
   895                 col = row & 0x1;
       
   896                 for(; col < blockSize; col += 2)
       
   897                 {
       
   898                     temp = (refPos[col] + refPos[col + 1] + 
       
   899                         1 -roundingControl) >> 1;
       
   900                     sad += ABS(temp - currPos[col]);
       
   901                 }
       
   902                 refPos += extendedVOPWidth;
       
   903                 currPos += yWidth;
       
   904             }
       
   905             mv->SAD = (sad << 1);
       
   906         }
       
   907         else
       
   908         {
       
   909             /* Both horizontal and vertical components are integer pel */
       
   910             for(row = 0; row < blockSize; row++)
       
   911             {
       
   912                 col = row & 0x1;
       
   913                 for(; col < blockSize; col += 2)
       
   914                 {
       
   915                     sad += ABS(refPos[col] - currPos[col]);
       
   916                 }
       
   917                 refPos += extendedVOPWidth;
       
   918                 currPos += yWidth;
       
   919             }
       
   920             mv->SAD = (sad << 1);
       
   921         }
       
   922     }
       
   923     
       
   924     return;
       
   925 }
       
   926 
       
   927 
       
   928 
       
   929 
       
   930 /* {{-output"vbmHalfPelSearchMB.txt"}} */
       
   931 /*
       
   932 * vbmHalfPelSearchMB
       
   933 *
       
   934 * Parameters:
       
   935 *     refFrame             pointer to reference frame
       
   936 *     currMB               pointer to current MB
       
   937 *     mbPos                pointer to macroblock position structure
       
   938 *     vopWidth             width of frame/VOP
       
   939 *     yWidth               width of luminance frame 
       
   940 *     initPred             pointer to predictor motion vectors, pixel unit
       
   941 *     bestMV               pointer to store the best match motion vector
       
   942 * Function:
       
   943 *     This function evaluates the half pel motion vector for a 16x16 block using 
       
   944 *     the integer pel motion vector
       
   945 *
       
   946 * Returns:
       
   947 *     Nothing.
       
   948 *
       
   949 * Error codes:
       
   950 *     None.
       
   951 *
       
   952 */
       
   953 void vbmHalfPelSearchMB(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, 
       
   954                                                 u_int32 yWidth, tMotionVector* initPred,
       
   955                                                 tMotionVector* bestMV, tMBPosition* mbPos)
       
   956 {
       
   957     int32 i;
       
   958     int32 position=0;
       
   959     
       
   960     initPred[0].SAD = bestMV->SAD;
       
   961     initPred[1].mvx = (int16)(bestMV->mvx + 1);
       
   962     initPred[1].mvy = bestMV->mvy;
       
   963     initPred[2].mvx = bestMV->mvx;
       
   964     initPred[2].mvy = (int16)(bestMV->mvy - 1);
       
   965     initPred[3].mvx = (int16)(bestMV->mvx - 1);
       
   966     initPred[3].mvy = bestMV->mvy;
       
   967     initPred[4].mvx = bestMV->mvx;
       
   968     initPred[4].mvy = (int16)(bestMV->mvy + 1);
       
   969     
       
   970     for(i = 1; i < 5; i++)
       
   971     {
       
   972         if(vbmMVOutsideBound(mbPos, &initPred[i], 1))
       
   973         {
       
   974             initPred[i].SAD = 65535;
       
   975         }
       
   976         else
       
   977         {
       
   978             vbmSADHalfPel(refFrame, vopWidth, currMB, yWidth, 
       
   979                 (initPred + i), mbPos,(tBool)(0), 16);
       
   980         }
       
   981         
       
   982         if(initPred[i].SAD < bestMV->SAD)
       
   983         {
       
   984             bestMV->mvx = initPred[i].mvx;
       
   985             bestMV->mvy = initPred[i].mvy;
       
   986             bestMV->SAD = initPred[i].SAD;
       
   987             position = i;
       
   988         }
       
   989     }
       
   990     
       
   991     if(1)
       
   992     {
       
   993         if(bestMV->SAD == initPred[0].SAD)
       
   994         {
       
   995             return;
       
   996         }
       
   997         else
       
   998         {
       
   999             switch(position)
       
  1000             {
       
  1001             case 1: case 3:
       
  1002                 initPred[5].mvx = bestMV->mvx;
       
  1003                 initPred[5].mvy = (int16)(bestMV->mvy - 1);
       
  1004                 initPred[6].mvx = bestMV->mvx;
       
  1005                 initPred[6].mvy = (int16)(bestMV->mvy + 1);
       
  1006                 break;
       
  1007                 
       
  1008             case 2: case 4:
       
  1009                 initPred[5].mvx = (int16)(bestMV->mvx - 1);
       
  1010                 initPred[5].mvy = bestMV->mvy;
       
  1011                 initPred[6].mvx = (int16)(bestMV->mvx + 1);
       
  1012                 initPred[6].mvy = bestMV->mvy;
       
  1013                 break;
       
  1014                 
       
  1015             default:
       
  1016                 break;
       
  1017             }
       
  1018             
       
  1019             for(i = 5; i < 7; i++)
       
  1020             {
       
  1021                 
       
  1022                 if(vbmMVOutsideBound(mbPos, &initPred[i],1))
       
  1023                 {
       
  1024                     initPred[i].SAD = 65535;
       
  1025                 }
       
  1026                 else
       
  1027                 {
       
  1028                     vbmSADHalfPel(refFrame, vopWidth, currMB, yWidth,
       
  1029                         (initPred + i), mbPos, (tBool)0, 16);
       
  1030                 }
       
  1031                 if(initPred[i].SAD < bestMV->SAD)
       
  1032                 {
       
  1033                     bestMV->mvx = initPred[i].mvx;
       
  1034                     bestMV->mvy = initPred[i].mvy;
       
  1035                     bestMV->SAD = initPred[i].SAD;
       
  1036                 }
       
  1037             }
       
  1038         }
       
  1039     }
       
  1040     
       
  1041     return;
       
  1042 }
       
  1043 
       
  1044 
       
  1045 
       
  1046 /* {{-output"vbmMEMBSpatioTemporalSearch.txt"}} */
       
  1047 /*
       
  1048 * vbmMEMBSpatioTemporalSearch
       
  1049 *
       
  1050 * Parameters:
       
  1051 *     refFrame             pointer to reference frame
       
  1052 *     currMB               pointer to current MB
       
  1053 *     mbPos                pointer to macroblock position structure
       
  1054 *     vopWidth             width of frame/VOP
       
  1055 *     vopHeight            height of frame/VOP
       
  1056 *     yWidth               width of luminance frame 
       
  1057 *     initPred             pointer to predictor motion vectors, pixel unit
       
  1058 *     bestMV               pointer to store the best match motion vector
       
  1059 *     noOfPredictors       number of MV predictors
       
  1060 *     searchRange          search range
       
  1061 *     minSAD               minimum SAD
       
  1062 * Function:
       
  1063 *     This function performs motion estimation for a macroblock using 
       
  1064 *     spatio-temporal correlation based search
       
  1065 *
       
  1066 * Returns:
       
  1067 *     Nothing.
       
  1068 *
       
  1069 * Error codes:
       
  1070 *     None.
       
  1071 *
       
  1072 */
       
  1073 int32 vbmMEMBSpatioTemporalSearch(tPixel* refFrame, u_int32 vopWidth, u_int32 vopHeight, 
       
  1074                                                                     tPixel* currMB, u_int32 yWidth, tMBPosition* mbPos,
       
  1075                                                                     tMotionVector   *initPred, int32 noOfPredictors,
       
  1076                                                                     tMotionVector* bestMV, int32 searchRange, u_int32 minSAD)
       
  1077 {
       
  1078     /* estimate the bound of MV for current MB */
       
  1079     vbmEstimateBound(mbPos, vopWidth, vopHeight, searchRange);
       
  1080     
       
  1081     /* get the best MV predictor from the candidates set */
       
  1082     vbmEstimateBestPredictor(refFrame, vopWidth, currMB, yWidth, initPred, mbPos, noOfPredictors, bestMV);
       
  1083     
       
  1084     if(bestMV->SAD >= minSAD)
       
  1085     {
       
  1086         /* from the MV predictor, starts the small diamond search    */
       
  1087         vbmSmallDiamondSearch(refFrame, currMB, initPred, bestMV, vopWidth, mbPos, yWidth);
       
  1088     }
       
  1089     
       
  1090     /* adjustment for half-pixel search */
       
  1091     bestMV->mvx <<= 1;
       
  1092     bestMV->mvy <<= 1;
       
  1093     
       
  1094     /* MV bound in half-pixel  */
       
  1095     vbmEstimateBoundHalfPel(mbPos,vopWidth, vopHeight);
       
  1096     
       
  1097     /* starts the half-pixel search around the integer-pixel MV */
       
  1098     vbmHalfPelSearchMB(refFrame, vopWidth, currMB, yWidth, 
       
  1099         initPred, bestMV, mbPos);
       
  1100     
       
  1101     return bestMV->SAD;
       
  1102 }
       
  1103 
       
  1104 
       
  1105 
       
  1106 /* {{-output"vbmRowDCT.txt"}} */
       
  1107 /*
       
  1108 * vbmRowDCT
       
  1109 *
       
  1110 * Parameters:
       
  1111 *     block                array of 64 block coefficients 
       
  1112 * Function:
       
  1113 *     This function performs row DCT of 8x8 block of data elements
       
  1114 *
       
  1115 * Returns:
       
  1116 *     Nothing.
       
  1117 *
       
  1118 * Error codes:
       
  1119 *     None.
       
  1120 *
       
  1121 */
       
  1122 void vbmRowDCT(int16 *block)
       
  1123 {
       
  1124     int32  coeff0, coeff1, coeff2, coeff3;
       
  1125     int32  coeff4, coeff5, coeff6, coeff7;
       
  1126     int32  temp;
       
  1127     u_int16 count;
       
  1128     int32  rowStartIndex;
       
  1129     
       
  1130     for(count = 0; count < BLOCK_SIZE; count++)
       
  1131     {
       
  1132         rowStartIndex = count << LOG_BLOCK_WIDTH;
       
  1133         
       
  1134         /* Stage 1 and up scaling of the input data to improve precision */
       
  1135         coeff0 = (block[rowStartIndex] + block[rowStartIndex + 7]) <<
       
  1136             DCT_KEPT_PRECISION;
       
  1137         coeff7 = (block[rowStartIndex] - block[rowStartIndex + 7]) <<
       
  1138             DCT_KEPT_PRECISION;
       
  1139         
       
  1140         coeff1 = (block[rowStartIndex + 1] + block[rowStartIndex + 6]) <<
       
  1141             DCT_KEPT_PRECISION;
       
  1142         coeff6 = (block[rowStartIndex + 1] - block[rowStartIndex + 6]) <<
       
  1143             DCT_KEPT_PRECISION;
       
  1144         
       
  1145         coeff2 = (block[rowStartIndex + 2] + block[rowStartIndex + 5]) <<
       
  1146             DCT_KEPT_PRECISION;
       
  1147         coeff5 = (block[rowStartIndex + 2] - block[rowStartIndex + 5]) <<
       
  1148             DCT_KEPT_PRECISION;
       
  1149         
       
  1150         coeff3 = (block[rowStartIndex + 3] + block[rowStartIndex + 4]) <<
       
  1151             DCT_KEPT_PRECISION;
       
  1152         coeff4 = (block[rowStartIndex + 3] - block[rowStartIndex + 4]) <<
       
  1153             DCT_KEPT_PRECISION;
       
  1154         
       
  1155         /* Stage 2 */
       
  1156         temp =   coeff0 + coeff3;
       
  1157         coeff3 = coeff0 - coeff3;
       
  1158         coeff0 = temp;
       
  1159         
       
  1160         temp =   coeff1 + coeff2;
       
  1161         coeff2 = coeff1 - coeff2;
       
  1162         coeff1 = temp;
       
  1163         
       
  1164         temp =   ((coeff6 - coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION;
       
  1165         coeff6 = ((coeff6 + coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION;
       
  1166         coeff5 = temp;
       
  1167         
       
  1168         /* Stage 3 */
       
  1169         temp =   coeff0 + coeff1;
       
  1170         coeff1 = coeff0 - coeff1;
       
  1171         coeff0 = temp;
       
  1172         
       
  1173         temp =   ((coeff2 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) + coeff3;
       
  1174         coeff3 = ((coeff3 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) - coeff2;
       
  1175         coeff2 = temp;
       
  1176         
       
  1177         temp =   coeff4 + coeff5;
       
  1178         coeff5 = coeff4 - coeff5;
       
  1179         coeff4 = temp;
       
  1180         
       
  1181         temp =   coeff7 - coeff6;
       
  1182         coeff7 = coeff7 + coeff6;
       
  1183         coeff6 = temp;
       
  1184         
       
  1185         /* Stage 4 */
       
  1186         temp =   ((coeff4 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) + coeff7;
       
  1187         coeff7 = ((coeff7 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) - coeff4;
       
  1188         coeff4 = temp;
       
  1189         
       
  1190         temp =   coeff5 + ((coeff6 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION);
       
  1191         coeff6 = coeff6 - ((coeff5 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION);
       
  1192         coeff5 = temp;
       
  1193         
       
  1194         block[rowStartIndex] =     (int16)coeff0;
       
  1195         block[rowStartIndex + 4] = (int16)coeff1;
       
  1196         block[rowStartIndex + 2] = (int16)coeff2;
       
  1197         block[rowStartIndex + 6] = (int16)coeff3;
       
  1198         block[rowStartIndex + 1] = (int16)coeff4;
       
  1199         block[rowStartIndex + 5] = (int16)coeff5;
       
  1200         block[rowStartIndex + 3] = (int16)coeff6;
       
  1201         block[rowStartIndex + 7] = (int16)coeff7;
       
  1202     }
       
  1203     
       
  1204     return;
       
  1205 }
       
  1206 
       
  1207 
       
  1208 
       
  1209 /* {{-output"vbmDCTQuantInterSVH.txt"}} */
       
  1210 /*
       
  1211 * vbmDCTQuantInterSVH
       
  1212 *
       
  1213 * Parameters:
       
  1214 *     block                array of 64 block coefficients 
       
  1215 *     mbi                  contains info about MB quantization scale and coding type
       
  1216 *     lastPosition         indicates last non zero coefficient
       
  1217 * Function:
       
  1218 *     This function performs DCT of a 8x8 block of data elements and 
       
  1219 *     quantizes the DCT coefficients with short video header flag set
       
  1220 *
       
  1221 * Returns:
       
  1222 *     Nothing.
       
  1223 *
       
  1224 * Error codes:
       
  1225 *     None.
       
  1226 *
       
  1227 */
       
  1228 void vbmDCTQuantInterSVH(int16 *block, tMBInfo *mbi, int32* lastPosition)
       
  1229 {
       
  1230     int32  coeff0, coeff1, coeff2, coeff3;
       
  1231     int32  coeff4, coeff5, coeff6, coeff7;
       
  1232     int32  temp;
       
  1233     u_int16 count;
       
  1234     int32   sign;
       
  1235     
       
  1236     vbmRowDCT(block);
       
  1237     
       
  1238     for(count = 0; count < BLOCK_SIZE; count++)
       
  1239     {
       
  1240         /* Stage 1 */
       
  1241         coeff0 = block[count] + block[count + 56];
       
  1242         coeff7 = block[count] - block[count + 56];
       
  1243         
       
  1244         coeff1 = block[count + 8] + block[count + 48];
       
  1245         coeff6 = block[count + 8] - block[count + 48];
       
  1246         
       
  1247         coeff2 = block[count + 16] + block[count + 40];
       
  1248         coeff5 = block[count + 16] - block[count + 40];
       
  1249         
       
  1250         coeff3 = block[count + 24] + block[count + 32];
       
  1251         coeff4 = block[count + 24] - block[count + 32];
       
  1252         
       
  1253         /* Stage 2 */
       
  1254         temp =   coeff0 + coeff3;
       
  1255         coeff3 = coeff0 - coeff3;
       
  1256         coeff0 = temp;
       
  1257         
       
  1258         temp =   coeff1 + coeff2;
       
  1259         coeff2 = coeff1 - coeff2;
       
  1260         coeff1 = temp;
       
  1261         
       
  1262         temp =   ((coeff6 - coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION;
       
  1263         coeff6 = ((coeff6 + coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION;
       
  1264         coeff5 = temp;
       
  1265         
       
  1266         /* Stage 3 */
       
  1267         temp =   coeff0 + coeff1;
       
  1268         coeff1 = coeff0 - coeff1;
       
  1269         coeff0 = temp;
       
  1270         
       
  1271         temp =   ((coeff2 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) + coeff3;
       
  1272         coeff3 = ((coeff3 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) - coeff2;
       
  1273         coeff2 = temp;
       
  1274         
       
  1275         temp =   coeff4 + coeff5;
       
  1276         coeff5 = coeff4 - coeff5;
       
  1277         coeff4 = temp;
       
  1278         
       
  1279         temp =   coeff7 - coeff6;
       
  1280         coeff7 = coeff7 + coeff6;
       
  1281         coeff6 = temp;
       
  1282         
       
  1283         /* Stage 4 */
       
  1284         temp =   ((coeff4 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) + coeff7;
       
  1285         coeff7 = ((coeff7 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) - coeff4;
       
  1286         coeff4 = temp;
       
  1287         
       
  1288         temp =   coeff5 + ((coeff6 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION);
       
  1289         coeff6 = coeff6 - ((coeff5 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION);
       
  1290         coeff5 = temp;
       
  1291         
       
  1292         block[count] =     (int16) ( (coeff0* sPrePostMult[count] + 
       
  1293             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);
       
  1294         block[count + 32] = (int16) ((coeff1* sPrePostMult[count+32] + 
       
  1295             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);
       
  1296         block[count + 16] = (int16) ((coeff2* sPrePostMult[count+16] + 
       
  1297             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);
       
  1298         block[count + 48] = (int16) ((coeff3* sPrePostMult[count+48] + 
       
  1299             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);
       
  1300         block[count + 8] =  (int16) ((coeff4* sPrePostMult[count+8] + 
       
  1301             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);
       
  1302         block[count + 40] = (int16) ((coeff5* sPrePostMult[count+40] + 
       
  1303             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);
       
  1304         block[count + 24] = (int16) ((coeff6* sPrePostMult[count+24] + 
       
  1305             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);
       
  1306         block[count + 56] = (int16) ((coeff7* sPrePostMult[count+56] + 
       
  1307             DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT);    
       
  1308         
       
  1309         coeff1 = mbi->QuantScale;
       
  1310         temp= count;
       
  1311         while(temp<64)
       
  1312         {
       
  1313             coeff0 = (int32) block[temp];   
       
  1314             if (coeff0 >= 0) {
       
  1315                 sign = 1;
       
  1316             }
       
  1317             else{
       
  1318                 sign = -1;
       
  1319             }
       
  1320             coeff0 = sign * coeff0;
       
  1321             
       
  1322             if (coeff0 < ((coeff1 * 5 ) >> 1))
       
  1323             {
       
  1324                 block[temp] = 0;
       
  1325             } 
       
  1326             else
       
  1327             {
       
  1328                 coeff0 -= (coeff1 >> 1);
       
  1329                 coeff0 += 1;
       
  1330                 coeff0 *= sFixedQuantScale1[coeff1];
       
  1331                 coeff0 >>= FIXED_PT_BITS;
       
  1332                 coeff0 *= sign;
       
  1333                 
       
  1334                 if (coeff0 > MAX_SAT_VAL_SVH)
       
  1335                 {
       
  1336                     coeff0 = MAX_SAT_VAL_SVH;
       
  1337                 }
       
  1338                 else if (coeff0 < MIN_SAT_VAL_SVH)
       
  1339                 {
       
  1340                     coeff0 = MIN_SAT_VAL_SVH;
       
  1341                 }
       
  1342                 
       
  1343                 block[temp] = (int16) coeff0;       
       
  1344                 if( temp > (*lastPosition)) *lastPosition = temp;
       
  1345             }
       
  1346             temp = temp+8;
       
  1347         }
       
  1348     }
       
  1349         
       
  1350     return;
       
  1351 }
       
  1352 
       
  1353 
       
  1354 
       
  1355 /* {{-output"vbmCBPYInter.txt"}} */
       
  1356 /*
       
  1357 * vbmCBPYInter
       
  1358 *
       
  1359 * Parameters:
       
  1360 *     mbi                  contains info about MB quantization scale and coding type
       
  1361 *     lastPosition         indicates last non zero coefficient
       
  1362 * Function:
       
  1363 *     This function evaluates the coded bit pattern of the Inter MB
       
  1364 *
       
  1365 * Returns:
       
  1366 *     Nothing.
       
  1367 *
       
  1368 * Error codes:
       
  1369 *     None.
       
  1370 *
       
  1371 */
       
  1372 void vbmCBPYInter(tMBInfo *mbi, int32* lastPosition)
       
  1373 {
       
  1374     int32 blkCnt;
       
  1375     
       
  1376     mbi->CodedBlockPattern = 0;
       
  1377     for (blkCnt = 0; blkCnt < 6; blkCnt++)
       
  1378     {   
       
  1379         mbi->CodedBlockPattern <<= 1;
       
  1380         
       
  1381         if(lastPosition[blkCnt] != -1)
       
  1382         {
       
  1383             mbi->CodedBlockPattern |= 1;
       
  1384         }
       
  1385     }
       
  1386     
       
  1387     return;
       
  1388 }   
       
  1389 
       
  1390 
       
  1391 
       
  1392 /* {{-output"vbmCBPYInter.txt"}} */
       
  1393 /*
       
  1394 * vbmCBPYInter
       
  1395 *
       
  1396 * Parameters:
       
  1397 *     refFrame             reference frame
       
  1398 *     currBlockPos         current block
       
  1399 *     block                block for storing the difference between predicted and
       
  1400 *                          actual pixel values.
       
  1401 *     mv                   motion vector for the block in half pixel unit
       
  1402 *     x                    x-coordinate for the first pixel of block
       
  1403 *     y                    y-coordinate for the first pixel of block
       
  1404 *     refFrameWidth        width of the reference frame
       
  1405 *     curFrameWidth        width of current Frame
       
  1406 *     extendVopSize        extension of the frame width
       
  1407 * Function:
       
  1408 *     This function finds the predicted block from the reference frame and 
       
  1409 *     copies the predicted frame into the current frame
       
  1410 *
       
  1411 * Returns:
       
  1412 *     Nothing.
       
  1413 *
       
  1414 * Error codes:
       
  1415 *     None.
       
  1416 *
       
  1417 */
       
  1418 int32 vbmPredictBlock(tPixel *refFrame, int32 refFrameWidth, u_int32 extendVopSize,
       
  1419                                             tPixel *currBlockPos, int32 curFrameWidth,
       
  1420                                             int16 *block, tMotionVector *mv, int32 x, int32 y)
       
  1421 {
       
  1422     int32 count1, count2;
       
  1423     u_int8 *tempFrame, *tempFrame1, *tempFrame2;
       
  1424     int32 tempVal, sad;
       
  1425     int32 extframeWidth;
       
  1426     extframeWidth = refFrameWidth + 2 * extendVopSize; /* Because of padding */
       
  1427     
       
  1428                                                                                                          /* 
       
  1429                                                                                                          * Since the frame is appended by 8 rows and 8 colums on all sides
       
  1430                                                                                                          * 0,0 of referenceframe will now be frameStartPoint
       
  1431      */
       
  1432         
       
  1433     tempFrame = refFrame + extframeWidth * extendVopSize + extendVopSize
       
  1434         + ((y + (mv->mvy >> 1)) * extframeWidth) + x + (mv->mvx >> 1);
       
  1435     tempFrame2 = currBlockPos;
       
  1436     
       
  1437     if (mv->mvy & 1) /* Motion vector of y has half pel accuracy */
       
  1438     {
       
  1439         if (mv->mvx & 1) /* MV has half pel value in both coordinates */
       
  1440         {
       
  1441             tempFrame1 = tempFrame + extframeWidth;
       
  1442             sad=0;
       
  1443             for (count1 = 0; count1 < BLOCK_SIZE; count1++)
       
  1444             {
       
  1445                 count2 = 0;
       
  1446                 tempVal = (tempFrame[count2]
       
  1447                     + tempFrame[count2 + 1]
       
  1448                     + tempFrame1[count2]
       
  1449                     + tempFrame1[count2 + 1]+ 2) >> 2;
       
  1450                 
       
  1451                 block[count2] = (int16)(tempFrame2[count2] - tempVal);
       
  1452                 sad+=ABS(block[count2]);
       
  1453                 tempVal = (tempFrame[count2 + 1]
       
  1454                     + tempFrame[count2 + 2]
       
  1455                     + tempFrame1[count2 + 1]
       
  1456                     + tempFrame1[count2 + 2]+ 2) >> 2;
       
  1457                 
       
  1458                 block[count2 + 1] = (int16)(tempFrame2[count2 + 1] - tempVal);
       
  1459                 sad+=ABS(block[count2+1]);
       
  1460                 tempVal = (tempFrame[count2 + 2]
       
  1461                     + tempFrame[count2 + 3]
       
  1462                     + tempFrame1[count2 + 2]
       
  1463                     + tempFrame1[count2 + 3]+ 2) >> 2;
       
  1464                 
       
  1465                 block[count2 + 2] = (int16)(tempFrame2[count2 + 2] - tempVal);
       
  1466                 sad+=ABS(block[count2+2]);
       
  1467                 tempVal = (tempFrame[count2 + 3]
       
  1468                     + tempFrame[count2 + 4]
       
  1469                     + tempFrame1[count2 + 3]
       
  1470                     + tempFrame1[count2 + 4]+ 2) >> 2;
       
  1471                 
       
  1472                 block[count2 + 3] = (int16)(tempFrame2[count2 + 3] - tempVal);
       
  1473                 sad+=ABS(block[count2+3]);
       
  1474                 tempVal = (tempFrame[count2 + 4]
       
  1475                     + tempFrame[count2 + 5]
       
  1476                     + tempFrame1[count2 + 4]
       
  1477                     + tempFrame1[count2 + 5]+ 2) >> 2;
       
  1478                 
       
  1479                 block[count2 + 4] = (int16)(tempFrame2[count2 + 4] - tempVal);
       
  1480                 sad+=ABS(block[count2+4]);
       
  1481                 tempVal = (tempFrame[count2 + 5]
       
  1482                     + tempFrame[count2 + 6]
       
  1483                     + tempFrame1[count2 + 5]
       
  1484                     + tempFrame1[count2 + 6]+ 2) >> 2;
       
  1485                 
       
  1486                 block[count2 + 5] = (int16)(tempFrame2[count2 + 5] - tempVal);
       
  1487                 sad+=ABS(block[count2+5]);
       
  1488                 tempVal = (tempFrame[count2+ 6]
       
  1489                     + tempFrame[count2 + 7]
       
  1490                     + tempFrame1[count2 + 6]
       
  1491                     + tempFrame1[count2 + 7]+ 2) >> 2;
       
  1492                 
       
  1493                 block[count2 + 6] = (int16)(tempFrame2[count2 + 6] - tempVal);
       
  1494                 sad+=ABS(block[count2+6]);
       
  1495                 tempVal = (tempFrame[count2 + 7]
       
  1496                     + tempFrame[count2 + 8]
       
  1497                     + tempFrame1[count2 + 7]
       
  1498                     + tempFrame1[count2 + 8]+ 2) >> 2;
       
  1499                 
       
  1500                 block[count2 + 7] = (int16)(tempFrame2[count2 + 7] - tempVal);
       
  1501                 sad+=ABS(block[count2+7]);
       
  1502                 block += BLOCK_SIZE;
       
  1503                 tempFrame += extframeWidth;
       
  1504                 tempFrame1 += extframeWidth;
       
  1505                 tempFrame2 += curFrameWidth;
       
  1506             }
       
  1507         }
       
  1508         else  /* MV has half pel only in y direction */
       
  1509         {
       
  1510             tempFrame1 = tempFrame + extframeWidth;
       
  1511             sad=0;
       
  1512             for (count1 = 0; count1 < BLOCK_SIZE; count1++)
       
  1513             {
       
  1514                 count2 = 0;
       
  1515                 tempVal = (tempFrame[count2]
       
  1516                     + tempFrame1[count2]+ 1) >> 1;
       
  1517                 
       
  1518                 block[count2] = (int16)(tempFrame2[count2] - tempVal);
       
  1519                 sad+=ABS(block[count2]);
       
  1520                 tempVal = (tempFrame[count2 + 1]
       
  1521                     + tempFrame1[count2 + 1]+ 1) >> 1;
       
  1522                 
       
  1523                 block[count2 + 1] = (int16)(tempFrame2[count2 + 1] - tempVal);
       
  1524                 sad+=ABS(block[count2+1]);
       
  1525                 tempVal = (tempFrame[count2 + 2]
       
  1526                     + tempFrame1[count2 + 2]+ 1) >> 1;
       
  1527                 
       
  1528                 block[count2 + 2] = (int16)(tempFrame2[count2 + 2] - tempVal);
       
  1529                 sad+=ABS(block[count2+2]);
       
  1530                 tempVal = (tempFrame[count2 + 3]+ tempFrame1[count2 + 3]+1) >> 1;
       
  1531                 
       
  1532                 block[count2 + 3] = (int16)(tempFrame2[count2 + 3] - tempVal);
       
  1533                 sad+=ABS(block[count2+3]);
       
  1534                 tempVal = (tempFrame[count2 + 4]
       
  1535                     + tempFrame1[count2 + 4]+ 1) >> 1;
       
  1536                 
       
  1537                 block[count2 + 4] = (int16)(tempFrame2[count2 + 4] - tempVal);
       
  1538                 sad+=ABS(block[count2+4]);
       
  1539                 tempVal = (tempFrame[count2 + 5]
       
  1540                     + tempFrame1[count2 + 5]+ 1) >> 1;
       
  1541                 
       
  1542                 block[count2 + 5] = (int16)(tempFrame2[count2 + 5] - tempVal);
       
  1543                 sad+=ABS(block[count2+5]);
       
  1544                 tempVal = (tempFrame[count2+ 6]
       
  1545                     + tempFrame1[count2 + 6]+ 1) >> 1;
       
  1546                 
       
  1547                 block[count2 + 6] = (int16)(tempFrame2[count2 + 6] - tempVal);
       
  1548                 sad+=ABS(block[count2+6]);
       
  1549                 tempVal = (tempFrame[count2 + 7]
       
  1550                     + tempFrame1[count2 + 7]+ 1) >> 1;
       
  1551                 
       
  1552                 block[count2 + 7] = (int16)(tempFrame2[count2 + 7] - tempVal);
       
  1553                 sad+=ABS(block[count2+7]);
       
  1554                 block += BLOCK_SIZE;
       
  1555                 tempFrame += extframeWidth;
       
  1556                 tempFrame1 += extframeWidth;
       
  1557                 tempFrame2 += curFrameWidth;
       
  1558             }
       
  1559         }
       
  1560     }
       
  1561     else
       
  1562     {
       
  1563         if (mv->mvx & 1) /* MV has half pel only in x direction */
       
  1564         {
       
  1565             sad=0;
       
  1566             for (count1 = 0; count1 < BLOCK_SIZE; count1++)
       
  1567             {
       
  1568                 count2 = 0;
       
  1569                 tempVal = (tempFrame[count2]
       
  1570                     + tempFrame[count2 + 1]+1) >> 1;
       
  1571                 
       
  1572                 block[count2] = (int16)(tempFrame2[count2] - tempVal);
       
  1573                 sad+=ABS(block[count2]);
       
  1574                 tempVal = (tempFrame[count2 + 1]
       
  1575                     + tempFrame[count2 + 2]+ 1) >> 1;
       
  1576                 
       
  1577                 block[count2 + 1] = (int16)(tempFrame2[count2 + 1] - tempVal);
       
  1578                 sad+=ABS(block[count2+1]);
       
  1579                 tempVal = (tempFrame[count2 + 2]
       
  1580                     + tempFrame[count2 + 3]+ 1) >> 1;
       
  1581                 
       
  1582                 block[count2 + 2] = (int16)(tempFrame2[count2 + 2] - tempVal);
       
  1583                 sad+=ABS(block[count2+2]);
       
  1584                 tempVal = (tempFrame[count2 + 3]
       
  1585                     + tempFrame[count2 + 4]+1) >> 1;
       
  1586                 
       
  1587                 block[count2 + 3] = (int16)(tempFrame2[count2 + 3] - tempVal);
       
  1588                 sad+=ABS(block[count2+3]);
       
  1589                 tempVal = (tempFrame[count2 + 4]
       
  1590                     + tempFrame[count2 + 5]+ 1) >> 1;
       
  1591                 
       
  1592                 block[count2 + 4] = (int16)(tempFrame2[count2 + 4] - tempVal);
       
  1593                 sad+=ABS(block[count2+4]);
       
  1594                 tempVal = (tempFrame[count2 + 5]
       
  1595                     + tempFrame[count2 + 6]+ 1) >> 1;
       
  1596                 
       
  1597                 block[count2 + 5] = (int16)(tempFrame2[count2 + 5] - tempVal);
       
  1598                 sad+=ABS(block[count2+5]);
       
  1599                 tempVal = (tempFrame[count2+ 6]
       
  1600                     + tempFrame[count2 + 7]
       
  1601                     + 1) >> 1;
       
  1602                 
       
  1603                 block[count2 + 6] = (int16)(tempFrame2[count2 + 6] - tempVal);
       
  1604                 sad+=ABS(block[count2+6]);
       
  1605                 tempVal = (tempFrame[count2 + 7]
       
  1606                     + tempFrame[count2 + 8]+ 1) >> 1;
       
  1607                 
       
  1608                 block[count2 + 7] = (int16)(tempFrame2[count2 + 7] - tempVal);
       
  1609                 sad+=ABS(block[count2+7]);
       
  1610                 block += BLOCK_SIZE;
       
  1611                 tempFrame += extframeWidth;
       
  1612                 tempFrame2 += curFrameWidth;
       
  1613             }
       
  1614         }
       
  1615         else    /* MV has full pel accuracy in both coordinates */
       
  1616         {
       
  1617             sad=0;
       
  1618             for (count1 = 0; count1 < BLOCK_SIZE; count1++)
       
  1619             {
       
  1620                 for (count2 = 0; count2 < BLOCK_SIZE; count2++)
       
  1621                 {
       
  1622                     block[count2] = (int16)(tempFrame2[count2]- tempFrame[count2]);
       
  1623                     sad+=ABS(block[count2]);
       
  1624                 }
       
  1625                 block += BLOCK_SIZE;
       
  1626                 tempFrame += extframeWidth;
       
  1627                 tempFrame2 += curFrameWidth;
       
  1628             }
       
  1629         }
       
  1630     }
       
  1631     return sad;
       
  1632 }
       
  1633 
       
  1634 
       
  1635 
       
  1636 
       
  1637 /* {{-output"vbmPutInterMBSVH.txt"}} */
       
  1638 /*
       
  1639 * vbmPutInterMBSVH
       
  1640 *
       
  1641 * Parameters:
       
  1642 *     outBuf               pointer to the output bit-stream buffer structure
       
  1643 *     mbData               pointer to the macro block data structure
       
  1644 *     mbi                  pointer to macro block information structure.
       
  1645 *     numTextureBits       pointer to store the number of bits needed to encode macro block
       
  1646 *     predMV               pointer to the predicted motion vector data
       
  1647 *     lastPos              pointer to last non-zero position of each block in the macro block
       
  1648 *     colorEffect          color effect applied
       
  1649 * Function:
       
  1650 *     This function encodes INTER macroblock in SVH mode
       
  1651 *
       
  1652 * Returns:
       
  1653 *     Nothing.
       
  1654 *
       
  1655 * Error codes:
       
  1656 *     None.
       
  1657 *
       
  1658 */
       
  1659 void vbmPutInterMBSVH(tMacroblockData* mbData, tMBInfo* mbi, bibBuffer_t *outBuf, 
       
  1660                                             int32 *numTextureBits, tMotionVector* predMV, int32* lastPos, 
       
  1661                                             int16 colorEffect)
       
  1662 {
       
  1663   int32  dQuant;
       
  1664     int32    mcbpcVal;
       
  1665     int32    index;
       
  1666     int32    cbpy;
       
  1667     int32    textureBits;
       
  1668     int16* coeff;
       
  1669     int32    len;
       
  1670     
       
  1671     vlbPutBits(outBuf, 1, mbi->SkippedMB);
       
  1672     if(mbi->SkippedMB == ON)
       
  1673     {
       
  1674         *numTextureBits = 0;
       
  1675         return;
       
  1676     }
       
  1677     
       
  1678     dQuant = mbi->dQuant;
       
  1679     mcbpcVal = colorEffect? 0 : (mbi->CodedBlockPattern & 3);
       
  1680     cbpy = (~((mbi->CodedBlockPattern >> 2) & 0xf)) & 0xf;
       
  1681     
       
  1682     /* only ONE MV in baseline H263 */
       
  1683     index = (dQuant == 0 ? 0 : 4) + mcbpcVal;
       
  1684     len = sCBPCPType[index].length + sCBPY[cbpy].length;
       
  1685     mcbpcVal = (sCBPCPType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code;
       
  1686     
       
  1687     vlbPutBits(outBuf, len, mcbpcVal);
       
  1688     
       
  1689     if(dQuant != 0)
       
  1690     {
       
  1691         vlbPutBits(outBuf, 2, sDquant[dQuant + 2]);
       
  1692     }
       
  1693     
       
  1694     /* encode motion vectors */
       
  1695     {
       
  1696         vbmEncodeMVDifferential(mbi->MV[0][0] - predMV[0].mvx,
       
  1697             mbi->MV[0][1] - predMV[0].mvy,
       
  1698             1, outBuf);
       
  1699     }
       
  1700     
       
  1701     /* encode texture coefficents */
       
  1702     textureBits = 0;
       
  1703     cbpy = 32;
       
  1704     for (index = 0; index < (colorEffect ? 4 : 6); index++)
       
  1705     {
       
  1706         if(cbpy & mbi->CodedBlockPattern)
       
  1707         {
       
  1708             coeff = mbData->Data + index * 64;
       
  1709             textureBits += vlbCodeACCoeffsSVHWithZigZag(0, coeff, outBuf, ON, lastPos[index]);
       
  1710         }
       
  1711         cbpy >>= 1;
       
  1712     }
       
  1713     *numTextureBits = textureBits;
       
  1714     
       
  1715     return;
       
  1716 }
       
  1717 
       
  1718 /*
       
  1719 *******************************************************************************
       
  1720 Name            : vbmPutInterMB
       
  1721 Description     : INTER macroblock is encoded here.
       
  1722 Parameter       : 
       
  1723     mbData: Pointer to the macro block data structure
       
  1724     mbi:        Pointer to the macro block information structure.
       
  1725     vopData:    Pointer to the VOP data structure.
       
  1726     currFrame:  Pointer to the current frame data
       
  1727     mbNo:       The number macro block being encoded.
       
  1728     numTextureBits:Pointer to store the number of bits taken to encode the macro block.
       
  1729     prevQuant:  Pointer to the quantization sacle.
       
  1730     blockSAD:   Pointer to store the block SAD values.                  
       
  1731     outBuf:     Pointer to the output bit-stream buffer structure
       
  1732     mvi:        Pointer to the MV array
       
  1733 Return Value    : void
       
  1734 *******************************************************************************
       
  1735 */
       
  1736 /* {{-output"vbmPutInterMB.txt"}} */
       
  1737 /*
       
  1738 * vbmPutInterMB
       
  1739 *
       
  1740 * Parameters:
       
  1741 *     outBuf               pointer to the output bit-stream buffer structure
       
  1742 *     mbPos                pointer to macroblock position structure
       
  1743 *     paramMB              pointer to macroblock parameters structure
       
  1744 *     initPred             pointer to predictor motion vectors, pixel unit
       
  1745 *     noOfPredictors       number of MV predictors
       
  1746 *     numTextureBits       pointer to store the number of bits needed to encode macro block
       
  1747 *     colorEffect          color effect applied
       
  1748 *     vopWidth             width of frame/VOP
       
  1749 *     vopHeight            height of frame/VOP
       
  1750 *     mbsinfo              pointer to macro block information structure
       
  1751 *     searchRange          search range
       
  1752 * Function:
       
  1753 *     This function encodes INTER macroblock
       
  1754 *
       
  1755 * Returns:
       
  1756 *     Nothing.
       
  1757 *
       
  1758 * Error codes:
       
  1759 *     None.
       
  1760 *
       
  1761 */
       
  1762 void vbmPutInterMB(tMBPosition* mbPos, bibBuffer_t *outBuf, dmdPParam_t *paramMB,
       
  1763                                      tMotionVector *initPred, int32 noOfPredictors, u_int32 vopWidth, 
       
  1764                                      u_int32 vopHeight,int32 searchRange, int32 mbNo, 
       
  1765                                      int32* numTextureBits, int16 colorEffect, tMBInfo *mbsinfo)
       
  1766 {
       
  1767     int32           blkCnt;
       
  1768     tMotionVector   predMV[4];
       
  1769     int32           lastPosition[6] = {-1,-1,-1,-1,-1,-1};
       
  1770     tPixel *currBlockPos = NULL; 
       
  1771     tMotionVector bestMV; 
       
  1772     tMacroblockData mbData;
       
  1773     tMBInfo *mbi = mbsinfo + mbNo;
       
  1774     mbi->SkippedMB = OFF;
       
  1775     u_int32 yWidth = paramMB->uvWidth * 2;
       
  1776     
       
  1777     bestMV.mvx = 0;
       
  1778     bestMV.mvy = 0;
       
  1779     bestMV.SAD = MB_SIZE * MB_SIZE / 2; // quich search stop threshold
       
  1780     
       
  1781     vbmMEMBSpatioTemporalSearch(paramMB->refY, vopWidth,vopHeight,paramMB->currYMBInFrame, yWidth, 
       
  1782         mbPos, initPred, noOfPredictors, &bestMV,
       
  1783         searchRange, bestMV.SAD);
       
  1784     
       
  1785     /* update MV buffer */
       
  1786     mbi->MV[0][0] = bestMV.mvx;
       
  1787     mbi->MV[0][1] = bestMV.mvy;
       
  1788     mbi->SAD      = bestMV.SAD;
       
  1789     currBlockPos = paramMB->currYMBInFrame;
       
  1790     
       
  1791     for (blkCnt= 0; blkCnt < 4; blkCnt++)
       
  1792     {
       
  1793         int blkPosX, blkPosY;
       
  1794         blkPosX = (blkCnt & 1) ? mbPos->x + 8 : mbPos->x;
       
  1795         blkPosY = (blkCnt & 2) ? mbPos->y + 8 : mbPos->y;
       
  1796         
       
  1797         vbmPredictBlock(paramMB->refY, vopWidth, 0, currBlockPos, yWidth,
       
  1798             &mbData.Data[blkCnt * BLOCK_COEFF_SIZE], 
       
  1799             &bestMV, blkPosX, blkPosY);
       
  1800         vbmDCTQuantInterSVH(&mbData.Data[blkCnt * BLOCK_COEFF_SIZE], 
       
  1801             mbi, &(lastPosition[blkCnt]));
       
  1802         currBlockPos += 8;
       
  1803         if (blkCnt & 1)
       
  1804             currBlockPos += 8 * yWidth - 16;
       
  1805     }
       
  1806     
       
  1807     if (!colorEffect)
       
  1808     {
       
  1809         /* Find the Chrominance Block Motion vectors */
       
  1810         tMotionVector lChrMv;
       
  1811         
       
  1812         lChrMv.mvx = (int16)(bestMV.mvx % 4 == 0 ? bestMV.mvx >> 1 : (bestMV.mvx >> 1) | 1);
       
  1813         lChrMv.mvy = (int16)(bestMV.mvy % 4 == 0 ? bestMV.mvy >> 1 : (bestMV.mvy >> 1) | 1);
       
  1814         blkCnt = 4; /* U */
       
  1815         vbmPredictBlock(paramMB->refU, paramMB->uvWidth, 0, paramMB->currUBlkInFrame, paramMB->uvWidth,
       
  1816             &mbData.Data[blkCnt * BLOCK_COEFF_SIZE], 
       
  1817             &lChrMv, mbPos->x >> 1, mbPos->y >> 1);
       
  1818         vbmDCTQuantInterSVH(&mbData.Data[blkCnt * BLOCK_COEFF_SIZE], 
       
  1819             mbi, &(lastPosition[blkCnt]));
       
  1820         blkCnt = 5; /* V */
       
  1821         vbmPredictBlock(paramMB->refV, paramMB->uvWidth, 0, paramMB->currVBlkInFrame, paramMB->uvWidth,
       
  1822             &mbData.Data[blkCnt * BLOCK_COEFF_SIZE], 
       
  1823             &lChrMv, mbPos->x >> 1, mbPos->y >> 1);
       
  1824         vbmDCTQuantInterSVH(&mbData.Data[blkCnt * BLOCK_COEFF_SIZE], 
       
  1825             mbi, &(lastPosition[blkCnt]));
       
  1826     }
       
  1827     
       
  1828     vbmCBPYInter(mbi, lastPosition);
       
  1829     if((mbi->CodedBlockPattern == 0) &&
       
  1830         (mbi->MV[0][0] == 0) && (mbi->MV[0][1] == 0))
       
  1831     {
       
  1832         mbi->SkippedMB = ON;
       
  1833     }
       
  1834     else //(mbi->SkippedMB == OFF)
       
  1835     {
       
  1836         vbmMvPrediction(mbi, mbNo, predMV, vopWidth / MB_SIZE);
       
  1837     }
       
  1838     vbmPutInterMBSVH(&mbData, mbi, outBuf,
       
  1839         numTextureBits, predMV, lastPosition, colorEffect);
       
  1840     
       
  1841     return;
       
  1842 }
       
  1843 
       
  1844 
       
  1845 /* End of bma.cpp */
       
  1846