videoeditorengine/h263decoder/src/MPEG4Transcoder.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 5 4c409de21d23
equal deleted inserted replaced
0:951a5db380a0 3:e0b5df5c0969
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * Implementation for MPEG4(H263) video transcoder. Operations may include:
       
    17 * 1. Bitstream Copying 
       
    18 * 2. BlackAndWhite Effect
       
    19 * 3. MPEG4 to VDT_RESYN (Simple profile)
       
    20 * 4. H.263 -> MPEG4 (Open Loop structure, no MV refinement)
       
    21 * 5. MPEG4 -> H263, partial implemented 
       
    22 *
       
    23 * We call functions 2~5 as transcoding functions since they involve MB level data processing
       
    24 *    
       
    25 * Note:
       
    26 * When RVLC is used and errors occur during  forward decoding, 
       
    27 * We don't do backward transcoding, the rest of the data is discarded, 
       
    28 *
       
    29 */
       
    30 
       
    31 
       
    32 
       
    33 /* 
       
    34 * Includes
       
    35 */
       
    36 #include "MPEG4Transcoder.h"
       
    37 #include "debug.h"
       
    38 
       
    39 /* Print macro */
       
    40 #ifdef _DEBUG
       
    41 #include <e32svr.h>
       
    42 #define PRINT(x) RDebug::Print x
       
    43 #else
       
    44 #define PRINT(x)
       
    45 #endif
       
    46 
       
    47 /* 
       
    48 * Defines and Typedefs
       
    49 */
       
    50 typedef unsigned int         uint32;
       
    51 
       
    52 #define EInternalAssertionFailure 1000
       
    53 #define VDT_NO_DATA(a, b, c, d) ((a) == (c) && (b) == (d))
       
    54 
       
    55 const int KDataNotValid = -1; 
       
    56 const int KMpeg4VopTimeIncrementResolutionLength = 16; 
       
    57 const int KOutputMpeg4TimeIncResolution = 30000;
       
    58 const int KShortHeaderMpeg4VosSize = 14; 
       
    59 const int KH263ToMpeg4VosSize = 28; 
       
    60 
       
    61 
       
    62 
       
    63 /*Bit stream formating*/
       
    64 #define WRITE32(op, x) sPutBits((op), 16, ((uint32)(x)) >> 16);       \
       
    65 sPutBits((op), 16, (x) & 0x0000ffff)
       
    66 
       
    67 /* 
       
    68 * Constants 
       
    69 */
       
    70 #ifdef _DEBUG
       
    71 const TUint KInitialBufferSize = 200000; /* MPEG4 Simple Visual Profile (Levels 0,1,2,3) initial frame data buffer size vga support */
       
    72 #endif
       
    73                                                                                 /* 
       
    74                                                                                 * Function Declarations 
       
    75 */
       
    76 
       
    77 //Static Functions 
       
    78 
       
    79 static void sStuffBitsH263(bibBuffer_t *outBuffer);
       
    80 static TVedVideoBitstreamMode sGetMPEG4Mode(int error_resilience_disable, int dp, int rvlc);
       
    81 static int sFindCBP(int *mbdata, int fUseIntraDCVLC);
       
    82 
       
    83 
       
    84 
       
    85 void vdtPutInterMBCMT(bibBuffer_t *outBuffer, int coeffStart, int *coeff, int *numTextureBits, int svh);
       
    86 void vdtPutIntraMBCMT(bibBuffer_t *outBuffer, int *coeff, int *numTextureBits, int index,  int skipDC, int skipAC);
       
    87 void vbmEncodeMVDifferential(int32 mvdx, int32 mvdy, int32 fCode, bibBuffer_t *outBuffer);
       
    88 void vbmGetH263IMCBPC(int lDQuant, int vopCodingType, int colorEffect, int cbpy, int& mcbpcVal, int& len);
       
    89 void vbmGetH263PMCBPC(int lDQuant, int colorEffect, int cbpy, int& mcbpcVal, int& len);
       
    90 tBool vbmMVOutsideBound(tMBPosition *mbPos, tMotionVector* bestMV, tBool halfPixel);
       
    91 void vbmMvPrediction(tMBInfo *mbi, int32 mBCnt, tMotionVector *predMV,  int32 mbinWidth);
       
    92 void vbmPutInterMB(tMBPosition* mbPos, bibBuffer_t *outBuf, dmdPParam_t *paramMB, tMotionVector *initPred, 
       
    93                                      int32 noOfPredictors, u_int32 vopWidth, u_int32 vopHeight, int32 searchRange, 
       
    94                                      int32 mbNo, int32* numTextureBits, int16 colorEffect, tMBInfo *mbsinfo);
       
    95 
       
    96 void sPutBits (bibBuffer_t *buf, int numBits, unsigned int value);  //forward decl
       
    97 
       
    98 /* 
       
    99 * Function Definitions 
       
   100 */
       
   101 
       
   102 /*
       
   103 * sStuffBitsH263
       
   104 *
       
   105 * Parameters: 
       
   106 *    outBuffer    output buffer
       
   107 *
       
   108 * Function:
       
   109 *    This function stuffs bits for H.263 format
       
   110 * Returns:
       
   111 *    None
       
   112 * Error codes:
       
   113 *    None.
       
   114 *
       
   115 */
       
   116 static void sStuffBitsH263(bibBuffer_t *outBuffer)
       
   117 {
       
   118     const int stuffingBits[8][2] = { {1,0}, {2,0}, {3,0}, {4,0}, {5,0}, {6,0}, {7,0}, {0,0} };
       
   119     
       
   120     VDTASSERT(outBuffer->baseAddr);
       
   121     
       
   122     /* find the number of stuffing bits to insert in the output buffer */
       
   123     int bi = outBuffer->bitIndex;
       
   124     int newNumBits = stuffingBits[bi][0]; 
       
   125     int newValue = stuffingBits[bi][1]; 
       
   126     sPutBits(outBuffer, newNumBits, newValue);
       
   127         
       
   128     return;
       
   129 }
       
   130 
       
   131 
       
   132 
       
   133 /*
       
   134 * sGetMPEG4Mode
       
   135 *
       
   136 * Parameters: 
       
   137 *    
       
   138 *
       
   139 * Function:
       
   140 *    This function gets the mode of the MPEG-4 bitstream
       
   141 * Returns:
       
   142 *    Nothing
       
   143 * Error codes:
       
   144 *    None.
       
   145 *
       
   146 */
       
   147 static TVedVideoBitstreamMode sGetMPEG4Mode(int error_resilience_disable, int dp, int rvlc)
       
   148 {
       
   149     TVedVideoBitstreamMode mode = EVedVideoBitstreamModeUnknown;
       
   150     int combination = ((!error_resilience_disable) << 2) | (dp << 1) | rvlc;
       
   151     switch (combination)
       
   152     {
       
   153         case 0:
       
   154             mode = EVedVideoBitstreamModeMPEG4Regular;
       
   155             break;
       
   156         case 2:
       
   157             mode = EVedVideoBitstreamModeMPEG4DP;
       
   158             break;
       
   159         case 3:
       
   160             mode = EVedVideoBitstreamModeMPEG4DP_RVLC;
       
   161             break;
       
   162         case 4:
       
   163             mode = EVedVideoBitstreamModeMPEG4Resyn;
       
   164             break;
       
   165         case 6:
       
   166             mode = EVedVideoBitstreamModeMPEG4Resyn_DP;
       
   167             break;
       
   168         case 7:
       
   169             mode = EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC;
       
   170             break;
       
   171         default:
       
   172             mode = EVedVideoBitstreamModeUnknown;
       
   173     }
       
   174     
       
   175     return mode;
       
   176 }
       
   177 
       
   178 
       
   179 /* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
       
   180 /*
       
   181 * sFindCBP
       
   182 *
       
   183 * Parameters: 
       
   184 *    mbdata          Contains the actual MB data to be quantized
       
   185 *    fUseIntraDCVLC  ON for INTRA, OFF for INTER
       
   186 *
       
   187 * Function:
       
   188 *    This function finds the coded bit pattern of the MB 
       
   189 * Returns:
       
   190 *    Coded Block Pattern.
       
   191 * Error codes:
       
   192 *    None.
       
   193 *
       
   194 */
       
   195 static int sFindCBP(int *mbdata, int fUseIntraDCVLC)
       
   196 {
       
   197     int coeffCnt;
       
   198     int *block;
       
   199     int blkCnt;
       
   200     int cbpFlag = 0;
       
   201     int codedBlockPattern = 0;
       
   202 
       
   203     for (blkCnt = 0; blkCnt < 6; blkCnt++)
       
   204     {   
       
   205         cbpFlag = 0;
       
   206         codedBlockPattern <<= 1;
       
   207         block = &mbdata[blkCnt * BLOCK_COEFF_SIZE];
       
   208         for (coeffCnt = fUseIntraDCVLC; coeffCnt < BLOCK_COEFF_SIZE;
       
   209              coeffCnt++)
       
   210              {
       
   211                  if (block[coeffCnt])
       
   212                  {
       
   213                      cbpFlag = 1;
       
   214                      codedBlockPattern |= cbpFlag;
       
   215                      break;
       
   216                  }
       
   217              }
       
   218     }
       
   219     
       
   220     return codedBlockPattern;
       
   221 }   
       
   222 
       
   223 
       
   224 
       
   225 
       
   226 
       
   227 
       
   228 /* {{-output"sPutBits.txt"}} */
       
   229 /*
       
   230 * sPutBits
       
   231 *
       
   232 * Parameters:
       
   233 *          outBuf           output buffer
       
   234 *           numBits         number of bits to output
       
   235 *           value           new value
       
   236 *
       
   237 * Function:
       
   238 *    This function puts some bits to the output buffer
       
   239 * Returns:
       
   240 *    Nothing.
       
   241 * Error codes:
       
   242 *    None.
       
   243 *
       
   244 */
       
   245 void sPutBits (bibBuffer_t *buf, int numBits, unsigned int value)
       
   246 {
       
   247     
       
   248     bibEditParams_t edParam;
       
   249     
       
   250     edParam.curNumBits = edParam.newNumBits = numBits;
       
   251     edParam.StartByteIndex = edParam.StartBitIndex = 0; /* used for source buffer only  */
       
   252     edParam.newValue = value;                           /* use value 128, encoded as codeword "1111 1111" = 255 */
       
   253     
       
   254     CopyBufferEdit((bibBuffer_t*)NULL, buf, &edParam, 0); 
       
   255 }
       
   256 
       
   257 
       
   258 
       
   259 /*
       
   260 * GetTimeIncPosition
       
   261 *    
       
   262 *
       
   263 * Parameters:
       
   264 *    hInstance                  instance handle
       
   265 *
       
   266 * Function:
       
   267 *    Calculates the time increment position for the current VOP.
       
   268 *
       
   269 * Returns:
       
   270 *    VDX error codes
       
   271 *    
       
   272 */
       
   273 
       
   274 int GetTimeIncPosition(
       
   275    bibBuffer_t *inBuffer,
       
   276    const vdxGetVopHeaderInputParam_t *inpParam,
       
   277    vdxVopHeader_t *header,
       
   278    int * ModuloByteIndex,
       
   279    int * ModuloBitIndex,
       
   280    int * ByteIndex,
       
   281    int * BitIndex,
       
   282    int *bitErrorIndication)
       
   283 /* {{-output"vdxGetVopHeader.txt"}} */
       
   284 {
       
   285   /* Get VOP header */
       
   286     int ret = vdxGetVopHeader(inBuffer, inpParam, header, 
       
   287         ModuloByteIndex, ModuloBitIndex, ByteIndex, BitIndex,
       
   288         bitErrorIndication);
       
   289     
       
   290     return ret;
       
   291     
       
   292 }
       
   293 
       
   294 
       
   295 
       
   296 /*
       
   297 * CopyEditVop
       
   298 *    
       
   299 *
       
   300 * Parameters:
       
   301 *    hInstance                  instance handle
       
   302 *
       
   303 * Function:
       
   304 *    This function copies the VOP header with edited time stamps of the VOP.
       
   305 *
       
   306 * Returns:
       
   307 *    TX error codes
       
   308 */
       
   309 
       
   310 int CopyEditVop(vdeHInstance_t hInstance, int aNrOfBytesToSkip, bibBuffer_t * inBuffer, 
       
   311                  vdeDecodeParamters_t *aDecoderInfo)
       
   312 {
       
   313     PRINT((_L("CopyEditVop() begin")));
       
   314     int StartByteIndex = 0;
       
   315     int StartBitIndex = 7;
       
   316     int16 error;
       
   317     int sncCode;
       
   318     int timeIncByteIndex, timeIncBitIndex;
       
   319     int moduloBaseByteIndex, moduloBaseBitIndex;
       
   320     int vopheaderBitLeft;
       
   321     int numBitChange = 0;
       
   322     int increaseBytes = 0;
       
   323     int stuffingLength = 0;
       
   324 
       
   325     tMPEG4TimeParameter * timeStamp = aDecoderInfo->aMPEG4TimeStamp;
       
   326     MPEG4TimeParameter CurNewTimeCode;
       
   327 
       
   328     int outTirDecreased = 0;
       
   329     int outputTimeResolution = *aDecoderInfo->aMPEG4TargetTimeResolution;
       
   330     int numOutputTrBits;
       
   331     for (numOutputTrBits = 1; ((outputTimeResolution-1) >> numOutputTrBits) != 0; numOutputTrBits++)
       
   332         {
       
   333         }
       
   334 
       
   335     int num_bits;
       
   336     vdxGetVopHeaderInputParam_t inpParam;
       
   337     vdxVopHeader_t vopheader;
       
   338     int bitErrorIndication;
       
   339     vdeInstance_t * vdeTemp = (vdeInstance_t *)hInstance;
       
   340     bibBuffer_t *outBuffer = vdeTemp->outBuffer;
       
   341     bibBufferEdit_t * bufEdit = vdeTemp->bufEdit;
       
   342     
       
   343     int FrameSizeInByte = outBuffer->numBytesRead;
       
   344     bibRewindBits(bibNumberOfFlushedBits(inBuffer),inBuffer,&error);
       
   345     bibRewindBits(bibNumberOfFlushedBits(outBuffer),outBuffer,&error);
       
   346     if ( aNrOfBytesToSkip > 0 )
       
   347         {
       
   348         // VOS header is already in the beginning of the output buffer
       
   349         bibForwardBits(aNrOfBytesToSkip<<3, outBuffer);
       
   350         // need to also skip the VOS header from input
       
   351         }
       
   352     bufEdit->copyMode = CopyWhole; /* CopyWhole - default */
       
   353 
       
   354     /* record position */
       
   355     StartByteIndex = inBuffer->numBytesRead;
       
   356     StartBitIndex = inBuffer->bitIndex;
       
   357 
       
   358     /* get time increment resolution */
       
   359     vdcInstance_t * vdcTemp = (vdcInstance_t *)(vdeTemp->vdcHInstance);
       
   360     int currentTimeIncResolution = vdcTemp->pictureParam.time_increment_resolution > 0? vdcTemp->pictureParam.time_increment_resolution : outputTimeResolution;
       
   361     inpParam.time_increment_resolution = currentTimeIncResolution;
       
   362 
       
   363     /* find the next vop start code */
       
   364     do 
       
   365     {
       
   366         sncCode = sncSeekMPEGStartCode(inBuffer, vdcTemp->pictureParam.fcode_forward, vdcTemp->pictureParam.error_res_disable, 0, &error);
       
   367         bibForwardBits(32,inBuffer); // one start code is found, move on  
       
   368         if(inBuffer->bitsLeft <= 0) 
       
   369         {
       
   370             return TX_ERR;  // did not find any sync code --- vop is corrupted
       
   371         }
       
   372     }
       
   373     while (sncCode != SNC_VOP);
       
   374     bibRewindBits(32,inBuffer, &error);  // go back 
       
   375 
       
   376     // if we have VOS header in the input, we are now just after it. If aNrOfBytesToSkip > 0, we should not copy it
       
   377     // however, aNrOfBytesToSkip refers to output buffer, so we should not use it when skipping the input
       
   378     if ( aNrOfBytesToSkip > 0 )
       
   379         {
       
   380         StartByteIndex = inBuffer->numBytesRead;
       
   381         StartBitIndex = inBuffer->bitIndex;
       
   382         }
       
   383 
       
   384     /* read vop header */
       
   385     GetTimeIncPosition(inBuffer, &inpParam, &vopheader, 
       
   386         &moduloBaseByteIndex, &moduloBaseBitIndex, &timeIncByteIndex, 
       
   387         &timeIncBitIndex, &bitErrorIndication);
       
   388 
       
   389     /* record the header end; */
       
   390     vopheaderBitLeft = inBuffer->bitsLeft;
       
   391 
       
   392     /* copy-edit the part from the begin to the end of modulo base */
       
   393     CurNewTimeCode = *timeStamp;
       
   394 
       
   395     if (CurNewTimeCode.modulo_time_base != vopheader.time_base_incr)
       
   396     {
       
   397         if (!bufEdit->editParams)
       
   398         {
       
   399             bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
   400             if(!bufEdit->editParams)
       
   401             {
       
   402                 //Memory not available 
       
   403                 return TX_ERR; //indicating error;
       
   404             }
       
   405             else
       
   406             {
       
   407                 bufEdit->numChanges = 1;
       
   408             }
       
   409         }
       
   410         bufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
       
   411         bufEdit->editParams->curNumBits = vopheader.time_base_incr + 1;
       
   412         bufEdit->editParams->newNumBits = CurNewTimeCode.modulo_time_base + 1;
       
   413         bufEdit->editParams->newValue = ((1 << CurNewTimeCode.modulo_time_base) - 1) << 1;
       
   414         bufEdit->editParams->StartByteIndex = moduloBaseByteIndex;
       
   415         bufEdit->editParams->StartBitIndex = moduloBaseBitIndex;
       
   416         numBitChange += bufEdit->editParams->newNumBits - bufEdit->editParams->curNumBits;
       
   417     }
       
   418     else
       
   419     {
       
   420         bufEdit->copyMode = CopyWhole; /* CopyWithEdit */
       
   421     }
       
   422     /* set the end of copy point */
       
   423     bibRewindBits((inBuffer->numBytesRead<<3)+7-inBuffer->bitIndex,inBuffer,&error);
       
   424     bibForwardBits((moduloBaseByteIndex<<3)+7-moduloBaseBitIndex+vopheader.time_base_incr+2, inBuffer);
       
   425       
       
   426     /* copy data */
       
   427     CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   428     StartByteIndex=inBuffer->getIndex;
       
   429     StartBitIndex=inBuffer->bitIndex;
       
   430     bufEdit->copyMode = CopyWhole; /* CopyWhole */
       
   431 
       
   432     /* copy and edit until the end of Vop header */
       
   433     if (currentTimeIncResolution != outputTimeResolution /* && volheader.time_increment_resolution != 30 */
       
   434         || vopheader.time_inc != CurNewTimeCode.time_inc)
       
   435     {
       
   436         for (num_bits = 1; ((currentTimeIncResolution-1) >> num_bits) != 0; num_bits++) 
       
   437             {
       
   438             }
       
   439         /* prepare editing position */
       
   440         if (!bufEdit->editParams)
       
   441         {
       
   442             bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
   443             if(!bufEdit->editParams)
       
   444             {
       
   445                 //Memory not available 
       
   446                 return TX_ERR; //indicating error no memory;
       
   447             }
       
   448             else
       
   449             {
       
   450                 bufEdit->numChanges = 1;
       
   451             }
       
   452             
       
   453         }
       
   454         bufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
       
   455         bufEdit->editParams->StartByteIndex = timeIncByteIndex;
       
   456         bufEdit->editParams->StartBitIndex = timeIncBitIndex;
       
   457         bufEdit->editParams->curNumBits = num_bits;
       
   458         bufEdit->editParams->newNumBits = numOutputTrBits;
       
   459         bufEdit->editParams->newValue = vopheader.time_inc;
       
   460 
       
   461         /* update time increment */
       
   462         if (vopheader.time_inc != CurNewTimeCode.time_inc)
       
   463         {
       
   464             /*bufEdit->editParams->newValue = (int)(vopheader.time_inc * (float)outputTimeResolution /
       
   465             (float)currentTimeIncResolution + 0.5); //CurNewTimeCode.time_inc;
       
   466             */
       
   467             bufEdit->editParams->newValue = CurNewTimeCode.time_inc;
       
   468         }
       
   469         numBitChange += bufEdit->editParams->newNumBits - bufEdit->editParams->curNumBits;
       
   470     }
       
   471 
       
   472     /* set the copy end point to the end of vop header */
       
   473     bibForwardBits(inBuffer->bitsLeft - vopheaderBitLeft, inBuffer);
       
   474 
       
   475     /* copy data */
       
   476     CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   477     StartByteIndex=inBuffer->getIndex;
       
   478     StartBitIndex=inBuffer->bitIndex;
       
   479     
       
   480     if ( vdcTemp->pictureParam.error_res_disable && (inBuffer->bitsLeft > 40) )   // 40 as below to avoid negative values below
       
   481         {
       
   482         // there are no VP headers => no need to search for VP start codes => can jump to the end.
       
   483         // 40 = 5 bytes; in the end there is a start code that has 4 bytes
       
   484         bibForwardBits( inBuffer->bitsLeft-40 ,inBuffer);
       
   485         }
       
   486 
       
   487     PRINT((_L("CopyEditVop() seek sync")));
       
   488     /* find the next resync marker */
       
   489     sncCode = sncSeekMPEGStartCode(inBuffer, vopheader.fcode_forward, vdcTemp->pictureParam.error_res_disable, 0, &error);
       
   490     if ( sncCode == SNC_NO_SYNC )
       
   491         {
       
   492         PRINT((_L("CopyEditVop() sync NOT found, interrupt the copying and return")));
       
   493         return TX_ERR;
       
   494         }
       
   495     PRINT((_L("CopyEditVop() sync found")));
       
   496 
       
   497     /* record next resync position */
       
   498     int resyncBitsLeft = inBuffer->bitsLeft;
       
   499         
       
   500     /* rewind stuffing bits */
       
   501     sncRewindStuffing(inBuffer, &error);        
       
   502     
       
   503     if (!bufEdit->editParams)
       
   504     {
       
   505         bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
   506         if(!bufEdit->editParams)
       
   507         {
       
   508             //Memory not available 
       
   509             return TX_ERR; //indicating error no memory;
       
   510         }
       
   511         else
       
   512         {
       
   513             bufEdit->numChanges = 1;
       
   514         }
       
   515     }
       
   516 
       
   517     /* record position */
       
   518     bufEdit->editParams->StartByteIndex = inBuffer->getIndex;
       
   519     bufEdit->editParams->StartBitIndex = inBuffer->bitIndex;
       
   520 
       
   521     /* calculate new stuffing bits */
       
   522     bufEdit->editParams->curNumBits = inBuffer->bitsLeft - resyncBitsLeft;
       
   523     /* calculate number of bits/bytes changed */
       
   524     if (numBitChange<0)
       
   525     {
       
   526         outTirDecreased = 1;
       
   527         numBitChange = -numBitChange;
       
   528     }
       
   529     int numByteChange = numBitChange >> 3;
       
   530 
       
   531     if (outTirDecreased)
       
   532     {
       
   533         increaseBytes -= numByteChange;
       
   534         stuffingLength = bufEdit->editParams->curNumBits + (numBitChange - (numByteChange << 3));
       
   535         if (stuffingLength > 8)
       
   536         {
       
   537             stuffingLength -= 8;
       
   538             increaseBytes --;
       
   539         }
       
   540     }
       
   541     else
       
   542     {
       
   543         increaseBytes += numByteChange;
       
   544         stuffingLength = bufEdit->editParams->curNumBits - (numBitChange - (numByteChange << 3));
       
   545         if (stuffingLength <= 0)
       
   546         {
       
   547             stuffingLength += 8;
       
   548             increaseBytes ++;
       
   549         }
       
   550     }
       
   551         
       
   552     /* adjust the output buffer size */
       
   553     if (increaseBytes != 0)
       
   554     {
       
   555         outBuffer->size += increaseBytes;
       
   556         if (increaseBytes>=0)
       
   557         {
       
   558             outBuffer->bitsLeft += (increaseBytes << 3);
       
   559         }
       
   560         else
       
   561         {
       
   562             outBuffer->bitsLeft -= ((-increaseBytes) << 3);
       
   563         }
       
   564     }
       
   565 
       
   566     /* update edit statistics */
       
   567     bufEdit->editParams->newNumBits = stuffingLength;
       
   568     bufEdit->editParams->newValue = stuffingLength>0?(1<<(stuffingLength-1))-1:0;
       
   569     if (stuffingLength != bufEdit->editParams->curNumBits)
       
   570     {
       
   571         bufEdit->copyMode = CopyWithEdit;
       
   572     }
       
   573 
       
   574     bibForwardBits(bufEdit->editParams->curNumBits, inBuffer);
       
   575     /* copy data */
       
   576     CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   577     /* record position */
       
   578     StartByteIndex = inBuffer->getIndex;
       
   579     StartBitIndex = inBuffer->bitIndex;
       
   580         
       
   581     do
       
   582     {
       
   583         /* if it is the start of a video packet, copy it with edit */
       
   584         if (sncCode == SNC_VIDPACK )
       
   585         {
       
   586             /* copy video packet with edit */
       
   587             int retVal = CopyEditVideoPacket(inBuffer, outBuffer, bufEdit, vdcTemp, aDecoderInfo, &vopheader, 
       
   588                 &sncCode, &StartByteIndex, &StartBitIndex);
       
   589             if(retVal<0)
       
   590             {
       
   591                 //error inside function return error
       
   592                 return TX_ERR;
       
   593             }
       
   594         }
       
   595         else if (sncCode == SNC_EOB || sncCode == SNC_EOS || sncCode == SNC_GOV)
       
   596         {
       
   597             // since it is EOB, so end of sequence has occurred, so no more data, so exit       
       
   598             break;
       
   599         }
       
   600     } 
       
   601     while(sncCode != SNC_VOP);
       
   602 
       
   603     /* copy the rest of bits */
       
   604     if ((int)inBuffer->numBytesRead < FrameSizeInByte)
       
   605     {
       
   606         bufEdit->copyMode = CopyWhole;
       
   607         bibForwardBits((FrameSizeInByte-StartByteIndex)<<3, inBuffer);
       
   608         CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   609     }
       
   610 
       
   611     PRINT((_L("CopyEditVop() end")));
       
   612     return TX_OK;
       
   613     }
       
   614 
       
   615 
       
   616 /*
       
   617 * CopyEditVideoPacket
       
   618 *    
       
   619 *
       
   620 * Parameters:
       
   621 *
       
   622 * Function:
       
   623 *    This function copies the video packet with edited time stamps, if HEC is enabled
       
   624 *
       
   625 * Returns:
       
   626 *    TX error codes
       
   627 */
       
   628 
       
   629 int CopyEditVideoPacket(bibBuffer_t* aInBuffer, 
       
   630                         bibBuffer_t* aOutBuffer, 
       
   631                         bibBufferEdit_t* aBufEdit, 
       
   632                         vdcInstance_t * aVdcTemp,
       
   633                         vdeDecodeParamters_t* aDecoderInfo, 
       
   634                         vdxVopHeader_t* aVopheader, 
       
   635                         int* aSncCode, 
       
   636                         int* aStartByteIndex, 
       
   637                         int* aStartBitIndex)
       
   638 {
       
   639     int16 error = 0;
       
   640     int value = 0;
       
   641     int bitsGot = 0;
       
   642     int num_bits = 0;
       
   643     int *bitErrorIndication = 0;
       
   644     int numOutputTrBits = 0;
       
   645     int resyncMarkerLength = 0;
       
   646     int numMBs = 0;
       
   647     int mbNumberLength = 0;
       
   648     int startByteIndex = *aStartByteIndex;
       
   649     int startBitIndex  = *aStartBitIndex;
       
   650     int currentTimeIncResolution = 0;
       
   651     int outputTimeResolution = 0;
       
   652     MPEG4TimeParameter curNewTimeCode;
       
   653     MPEG4TimeParameter* timeStamp = aDecoderInfo->aMPEG4TimeStamp;
       
   654 
       
   655     int numBitChange = 0;
       
   656     int increaseBytes = 0;
       
   657     int stuffingLength = 0;
       
   658     int outTirDecreased = 0;
       
   659 
       
   660     currentTimeIncResolution = aVdcTemp->pictureParam.time_increment_resolution > 0? aVdcTemp->pictureParam.time_increment_resolution : 30000;
       
   661     outputTimeResolution = *aDecoderInfo->aMPEG4TargetTimeResolution;
       
   662     for (numOutputTrBits=1; ((outputTimeResolution-1)>>numOutputTrBits)!=0; numOutputTrBits++)
       
   663         {
       
   664         }
       
   665     /* evaluate resync marker length */
       
   666     resyncMarkerLength = (aVopheader->coding_type == 0 ? 17 : 16+aVopheader->fcode_forward);
       
   667     /* evaluate MB number length */
       
   668     numMBs = ((aVdcTemp->pictureParam.lumWidth+15)>>4) * ((aVdcTemp->pictureParam.lumHeight+15)>>4);
       
   669     for (mbNumberLength = 1; ((numMBs-1) >> mbNumberLength) != 0; mbNumberLength++)
       
   670         {
       
   671         }
       
   672 
       
   673     value = bibGetBits(resyncMarkerLength, aInBuffer, &bitsGot, bitErrorIndication, &error);    // resync marker
       
   674     value = bibGetBits(mbNumberLength, aInBuffer, &bitsGot, bitErrorIndication, &error);    // mb number
       
   675     value = bibGetBits(5, aInBuffer, &bitsGot, bitErrorIndication, &error); // quant scale
       
   676     value = bibGetBits(1, aInBuffer, &bitsGot, bitErrorIndication, &error); // header extension code
       
   677     
       
   678     /* if HEC enabled, copy edit time increment fields in the video packet */
       
   679     if (value == 1) 
       
   680     {
       
   681         /* copy-edit the part from the begin to the end of modulo base */
       
   682         curNewTimeCode = *timeStamp;
       
   683         
       
   684         if (curNewTimeCode.modulo_time_base != aVopheader->time_base_incr)
       
   685         {
       
   686             if (!aBufEdit->editParams)
       
   687             {
       
   688                 aBufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
   689                 if(!aBufEdit->editParams)
       
   690                 {
       
   691                     //Memory not available 
       
   692                     return TX_ERR; //indicating error no memory;
       
   693                 }
       
   694                 else
       
   695                 {
       
   696                     aBufEdit->numChanges = 1;
       
   697                 }
       
   698             }
       
   699             aBufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
       
   700             aBufEdit->editParams->curNumBits = aVopheader->time_base_incr + 1;
       
   701             aBufEdit->editParams->newNumBits = curNewTimeCode.modulo_time_base + 1;
       
   702             aBufEdit->editParams->newValue = ((1 << curNewTimeCode.modulo_time_base) - 1) << 1;
       
   703             aBufEdit->editParams->StartByteIndex = aInBuffer->getIndex;
       
   704             aBufEdit->editParams->StartBitIndex = aInBuffer->bitIndex;
       
   705             numBitChange += aBufEdit->editParams->newNumBits - aBufEdit->editParams->curNumBits;
       
   706         } 
       
   707         else
       
   708         {
       
   709             aBufEdit->copyMode = CopyWhole; /* CopyWithEdit */
       
   710         }
       
   711         /* set the end of copy point */
       
   712         bibForwardBits(aVopheader->time_base_incr+2, aInBuffer); // includes one bit for Marker
       
   713         
       
   714         /* copy data */
       
   715         CopyStream(aInBuffer,aOutBuffer,aBufEdit,startByteIndex,startBitIndex);
       
   716         startByteIndex = aInBuffer->getIndex;
       
   717         startBitIndex  = aInBuffer->bitIndex;
       
   718         aBufEdit->copyMode = CopyWhole; /* CopyWhole */
       
   719         
       
   720         /* copy and edit 'time increment' field */
       
   721         if (currentTimeIncResolution != outputTimeResolution /* && volheader.time_increment_resolution != 30 */
       
   722             || aVopheader->time_inc != curNewTimeCode.time_inc)
       
   723         {
       
   724             for (num_bits = 1; ((currentTimeIncResolution-1) >> num_bits) != 0; num_bits++)
       
   725                 {
       
   726                 }
       
   727             
       
   728             /* prepare editing position */
       
   729             if (!aBufEdit->editParams)
       
   730             {
       
   731                 aBufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
   732                 if(!aBufEdit->editParams)
       
   733                 {
       
   734                     //Memory not available 
       
   735                     return TX_ERR; //indicating error no memory;
       
   736                 }
       
   737                 else
       
   738                 {
       
   739                     aBufEdit->numChanges = 1;
       
   740                 } 
       
   741             } 
       
   742             aBufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
       
   743             aBufEdit->editParams->StartByteIndex = aInBuffer->getIndex;
       
   744             aBufEdit->editParams->StartBitIndex = aInBuffer->bitIndex;
       
   745             aBufEdit->editParams->curNumBits = num_bits;
       
   746             aBufEdit->editParams->newNumBits = numOutputTrBits;
       
   747             aBufEdit->editParams->newValue = aDecoderInfo->aMPEG4TimeStamp->time_inc;
       
   748     
       
   749             /* move to end position of 'time increment' field */
       
   750             bibForwardBits(num_bits, aInBuffer);    // move to end of 'time increment' field
       
   751             /* update time increment */
       
   752             if (aVopheader->time_inc != curNewTimeCode.time_inc)
       
   753             {
       
   754                 aBufEdit->editParams->newValue = curNewTimeCode.time_inc;
       
   755             }
       
   756             numBitChange += aBufEdit->editParams->newNumBits - aBufEdit->editParams->curNumBits;
       
   757         } 
       
   758        
       
   759         /* copy time increment field with edit */
       
   760         CopyStream(aInBuffer,aOutBuffer,aBufEdit,startByteIndex,startBitIndex);
       
   761         startByteIndex=aInBuffer->getIndex;
       
   762         startBitIndex=aInBuffer->bitIndex;
       
   763         
       
   764     }
       
   765 
       
   766     /* copy rest of video packet */
       
   767     
       
   768     /* find the next resync marker */
       
   769     *aSncCode = sncSeekMPEGStartCode(aInBuffer, aVopheader->fcode_forward, 0 /* VPs used*/, 0, &error);
       
   770 
       
   771     /* record next resync position */
       
   772     int resyncBitsLeft = aInBuffer->bitsLeft;
       
   773         
       
   774     /* rewind stuffing bits */
       
   775     sncRewindStuffing(aInBuffer, &error);       
       
   776         
       
   777     if (!aBufEdit->editParams)
       
   778     {
       
   779         aBufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
   780         if(!aBufEdit->editParams)
       
   781         { 
       
   782             //Memory not available 
       
   783             return TX_ERR; //indicating error no memory;
       
   784         }
       
   785         else
       
   786         {
       
   787             aBufEdit->numChanges = 1;
       
   788         }
       
   789     }
       
   790 
       
   791     /* record position */
       
   792     aBufEdit->editParams->StartByteIndex = aInBuffer->getIndex;
       
   793     aBufEdit->editParams->StartBitIndex = aInBuffer->bitIndex;
       
   794         
       
   795     /* calculate new stuffing bits */
       
   796     aBufEdit->editParams->curNumBits = aInBuffer->bitsLeft - resyncBitsLeft;
       
   797 
       
   798     /* calculate number of bits/bytes changed */
       
   799     if (numBitChange<0)
       
   800     {
       
   801         outTirDecreased = 1;
       
   802         numBitChange = -numBitChange;
       
   803     }
       
   804     int numByteChange = numBitChange >> 3;
       
   805         
       
   806     /* evaluate change in buffer size */
       
   807     if (outTirDecreased)
       
   808     {
       
   809         increaseBytes -= numByteChange;
       
   810         stuffingLength = aBufEdit->editParams->curNumBits + (numBitChange - (numByteChange << 3));
       
   811         if (stuffingLength > 8)
       
   812         {
       
   813             stuffingLength -= 8;
       
   814             increaseBytes --;
       
   815         }
       
   816     }
       
   817     else
       
   818     {
       
   819         increaseBytes += numByteChange;
       
   820         stuffingLength = aBufEdit->editParams->curNumBits - (numBitChange - (numByteChange << 3));
       
   821         if (stuffingLength <= 0)
       
   822         {
       
   823             stuffingLength += 8;
       
   824             increaseBytes ++;
       
   825         }
       
   826     }
       
   827         
       
   828     /* adjust the output buffer size */
       
   829     if (increaseBytes != 0)
       
   830     {
       
   831         aOutBuffer->size += increaseBytes;
       
   832         if (increaseBytes>=0)
       
   833         {
       
   834             aOutBuffer->bitsLeft += (increaseBytes << 3);
       
   835         }
       
   836         else
       
   837         {
       
   838             aOutBuffer->bitsLeft -= ((-increaseBytes) << 3);
       
   839         }
       
   840     }
       
   841     /* update edit statistics */
       
   842     aBufEdit->editParams->newNumBits = stuffingLength;
       
   843     aBufEdit->editParams->newValue = stuffingLength>0?(1<<(stuffingLength-1))-1:0;
       
   844     if (stuffingLength != aBufEdit->editParams->curNumBits)
       
   845     {
       
   846         aBufEdit->copyMode = CopyWithEdit; // copy with edit
       
   847     }
       
   848     else 
       
   849     {
       
   850         aBufEdit->copyMode = CopyWhole; // copy whole 
       
   851     }
       
   852         
       
   853     bibForwardBits(aBufEdit->editParams->curNumBits, aInBuffer);
       
   854     /* copy video packet with stuffing bits edited */
       
   855     CopyStream(aInBuffer, aOutBuffer, aBufEdit, startByteIndex, startBitIndex);
       
   856     /* record position */
       
   857     startByteIndex = aInBuffer->getIndex;
       
   858     startBitIndex  = aInBuffer->bitIndex;
       
   859         
       
   860     /* update position for return */
       
   861     *aStartByteIndex = startByteIndex;
       
   862     *aStartBitIndex  = startBitIndex;
       
   863 
       
   864     return TX_OK;
       
   865 }
       
   866 
       
   867 
       
   868 /*
       
   869 * sPutBits
       
   870 *
       
   871 * Parameters:
       
   872 *      outBuf           output buffer
       
   873 *           numBits         number of bits to output
       
   874 *           value           new value
       
   875 *
       
   876 * Function:
       
   877 *    Wrapper to sPutBits
       
   878 * Returns:
       
   879 *    None.
       
   880 * Error codes:
       
   881 *    None.
       
   882 *
       
   883 */
       
   884 void vdtPutBits (void *buf,  int numBits, unsigned int value)
       
   885 {
       
   886     /* must be in this type! "void" is used here only because of the interface with vlb.cpp */
       
   887     sPutBits ((bibBuffer_t *)(buf),  numBits, value);
       
   888 }
       
   889 
       
   890 
       
   891 
       
   892 /* {{-output"vdtCopyBuffer.txt"}} */
       
   893 /*
       
   894 * vdtCopyBuffer
       
   895 *
       
   896 * Parameters:
       
   897 *
       
   898 * Function:
       
   899 *    This function copies some data from source buffer to destination buffer
       
   900 * Returns:
       
   901 *    None.
       
   902 * Error codes:
       
   903 *    None.
       
   904 *
       
   905 */
       
   906 void vdtCopyBuffer(bibBuffer_t *SrcBuffer,bibBuffer_t *DestBuffer,
       
   907                                      int ByteStart,int BitStart, int ByteEnd, int BitEnd)
       
   908 {
       
   909     int startByteIndex = SrcBuffer->getIndex;
       
   910     int startBitIndex  = SrcBuffer->bitIndex;
       
   911     int bitsLeft = SrcBuffer->bitsLeft;
       
   912     int numBytesRead = SrcBuffer->numBytesRead;
       
   913     
       
   914     CopyBuffer(SrcBuffer,DestBuffer, ByteStart, BitStart, ByteEnd, BitEnd);
       
   915     
       
   916     /* recover the postion */
       
   917     SrcBuffer->getIndex = startByteIndex ;
       
   918     SrcBuffer->bitIndex = startBitIndex;
       
   919     SrcBuffer->bitsLeft = bitsLeft;
       
   920     SrcBuffer->numBytesRead = numBytesRead;
       
   921 }
       
   922 
       
   923 
       
   924 
       
   925 
       
   926 /* {{-output"vdtStuffBitsMPEG4.txt"}} */
       
   927 /*
       
   928 * vdtStuffBitsMPEG4
       
   929 *
       
   930 * Parameters:
       
   931 *          outBuf           output buffer
       
   932 *
       
   933 * Function:
       
   934 *    This function puts some stuffing bits to the output buffer
       
   935 *   bits need to be stuffed in the output buffer at the end of vp in all cases (bw or not)
       
   936 * Returns:
       
   937 *    None.
       
   938 * Error codes:
       
   939 *    None.
       
   940 *
       
   941 */
       
   942 void vdtStuffBitsMPEG4(bibBuffer_t *outBuffer)
       
   943 {
       
   944     const int stuffingBits[8][2] = { {1,0}, {2,1}, {3,3}, {4,7}, {5,15}, {6,31}, {7,63}, {8,127} };
       
   945   VDTASSERT(outBuffer->baseAddr);
       
   946     
       
   947     /* find the number of stuffing bits to insert in the output buffer */
       
   948     int bi = outBuffer->bitIndex;
       
   949     int newNumBits = stuffingBits[bi][0]; 
       
   950     int newValue = stuffingBits[bi][1]; 
       
   951     sPutBits(outBuffer, newNumBits, newValue);
       
   952         
       
   953     return;
       
   954 }
       
   955 
       
   956 
       
   957 /*************************************************************/
       
   958 
       
   959 
       
   960 /* {{-output"sResetH263IntraDcUV.txt"}} */
       
   961 /*
       
   962 * sResetH263IntraDcUV
       
   963 *
       
   964 * Parameters: output buffer
       
   965 *             uValue
       
   966 *             vValue
       
   967 *
       
   968 * Function:
       
   969 *    This function reset the chrominace INTRADC when black and white color effect is applied 
       
   970 * Returns:
       
   971 *    none
       
   972 * Error codes:
       
   973 *    None.
       
   974 *
       
   975 */
       
   976 inline void sResetH263IntraDcUV(bibBuffer_t *DestBuffer, TInt uValue, TInt vValue)
       
   977 {
       
   978     /* For the Color Effects Fill the U and V buffers with the 
       
   979     corresponding color values */
       
   980    
       
   981     sPutBits(DestBuffer, 8, uValue);
       
   982     sPutBits(DestBuffer, 8, vValue);
       
   983 }
       
   984 
       
   985 
       
   986 /* {{-output"vdtGetPMBBlackAndWhiteMCBPC.txt"}} */
       
   987 /*
       
   988 * vdtGetPMBBlackAndWhiteMCBPC
       
   989 *
       
   990 * Parameters: 
       
   991 *
       
   992 * Function:
       
   993 *    This function compute the new mcbpc for black and white effect *
       
   994 * Returns:
       
   995 *    the length of the input mcbpc.
       
   996 * Error codes:
       
   997 *    None.
       
   998 *
       
   999 */
       
  1000 int vdtGetPMBBlackAndWhiteMCBPC(int& new_len, int& new_val, int mcbpc)
       
  1001 {
       
  1002     int cur_index, new_index, cur_len;
       
  1003         
       
  1004     const tVLCTable sCBPCPType[21] = 
       
  1005     {
       
  1006     {1, 1}, {3, 4}, {2, 4}, {5, 6},
       
  1007     {3, 3}, {7, 7}, {6, 7}, {5, 9}, 
       
  1008     {2, 3}, {5, 7}, {4, 7}, {5, 8},
       
  1009     {3, 5}, {4, 8}, {3, 8}, {3, 7},
       
  1010     {4, 6}, {4, 9}, {3, 9}, {2, 9}, 
       
  1011     {1, 9}
       
  1012     };
       
  1013     
       
  1014      /* evaluate MCBPC parameters */
       
  1015     int cur_cbpc = mcbpc & 3;       
       
  1016     int new_cbpc = 0;       // cpbc=0 indicates chroma is 0
       
  1017     int mbType; 
       
  1018     
       
  1019     mbType = mcbpc / 4;
       
  1020     /* evaluate indices in table */
       
  1021     cur_index = mbType * 4 + cur_cbpc;  
       
  1022     new_index = mbType * 4 + new_cbpc;  
       
  1023     
       
  1024     /* retrieve values */
       
  1025     cur_len = sCBPCPType[cur_index].length;
       
  1026     new_len = sCBPCPType[new_index].length;
       
  1027     new_val = sCBPCPType[new_index].code;
       
  1028     
       
  1029     return cur_len;
       
  1030 }
       
  1031 
       
  1032 
       
  1033 /* {{-output"vdtGetIMBBlackAndWhiteMCBPC.txt"}} */
       
  1034 /*
       
  1035 * vdtGetIMBBlackAndWhiteMCBPC
       
  1036 *
       
  1037 * Parameters: None
       
  1038 *
       
  1039 * Function:
       
  1040 *    This function compute the new mcbpc for black and white effect
       
  1041 * Returns:
       
  1042 *    the length of the input mcbpc.
       
  1043 * Error codes:
       
  1044 *    None.
       
  1045 *
       
  1046 */
       
  1047 int vdtGetIMBBlackAndWhiteMCBPC(int& new_len, int& new_val, int mcbpc)
       
  1048 {
       
  1049     int cur_index, new_index, cur_len;
       
  1050     
       
  1051     const tVLCTable sCBPCIType[9] = 
       
  1052     {
       
  1053     {1, 1}, {1, 3}, {2, 3}, {3, 3}, {1, 4},
       
  1054     {1, 6}, {2, 6}, {3, 6}, {1, 9}
       
  1055     };
       
  1056     
       
  1057     /* evaluate MCBPC parameters */
       
  1058     int cur_cbpc = mcbpc & 3;       
       
  1059     int new_cbpc = 0;       // cpbc=0 indicates chroma is 0
       
  1060     int mbType = (mcbpc <4)?3:4;
       
  1061     
       
  1062     /* evaluate indices in table */
       
  1063     cur_index = (mbType == 3 ? 0 : 4) + cur_cbpc;   
       
  1064     new_index = (mbType == 3 ? 0 : 4) + new_cbpc;   
       
  1065     
       
  1066     /* retrieve values */
       
  1067     cur_len = sCBPCIType[cur_index].length;
       
  1068     new_len = sCBPCIType[new_index].length;
       
  1069     new_val = sCBPCIType[new_index].code;
       
  1070     
       
  1071     return cur_len;
       
  1072 }
       
  1073 
       
  1074 
       
  1075 
       
  1076 
       
  1077 
       
  1078 /* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
       
  1079 /*
       
  1080 * vdtGetVideoBitstreamInfo
       
  1081 *
       
  1082 * Parameters: 
       
  1083 *
       
  1084 * Function:
       
  1085 *    This function provides the bitstream info to the processor *
       
  1086 * Returns:
       
  1087 *    VDE error codes
       
  1088 * Error codes:
       
  1089 *    None.
       
  1090 *
       
  1091 */
       
  1092 int vdtGetVideoBitstreamInfo(bibBuffer_t *inBuffer, vdeDecodeParamters_t *aInfoOut, int *aByteIndex, int *aBitIndex)
       
  1093 {
       
  1094     int numBitsGot,
       
  1095     bitErrorIndication = 0;
       
  1096     int16 error = 0;
       
  1097     u_int32 bits;
       
  1098     int timeResolution = 0;
       
  1099     TVedVideoBitstreamMode streamMode = EVedVideoBitstreamModeUnknown;
       
  1100     vdxVolHeader_t volHeader;  
       
  1101     volHeader.user_data = NULL;
       
  1102     
       
  1103     bits = bibShowBits(32, inBuffer, &numBitsGot, &bitErrorIndication, &error);
       
  1104     if (error)
       
  1105     {
       
  1106         streamMode = EVedVideoBitstreamModeUnknown;
       
  1107         goto exitFunction;
       
  1108     }
       
  1109     /* If PSC */
       
  1110     if ((bits >> 10) == 32) {
       
  1111         streamMode = EVedVideoBitstreamModeH263;
       
  1112     } 
       
  1113 
       
  1114     /* Else check for Visual Sequence, Visual Object or Video Object start code */
       
  1115     else if ((bits == MP4_VOS_START_CODE) || 
       
  1116         (bits == MP4_VO_START_CODE) ||
       
  1117         ((bits >> MP4_VID_ID_CODE_LENGTH) == MP4_VID_START_CODE) ||
       
  1118         ((bits >> MP4_VOL_ID_CODE_LENGTH) == MP4_VOL_START_CODE)) 
       
  1119     {
       
  1120         
       
  1121         /* read the Stream headers from the bitstream */
       
  1122         if ((vdxGetVolHeader(inBuffer, &volHeader, &bitErrorIndication, 1, aByteIndex, aBitIndex, NULL) != 0) ||
       
  1123             (bitErrorIndication != 0)) 
       
  1124         {
       
  1125             goto exitFunction;
       
  1126         }   
       
  1127 
       
  1128         timeResolution = volHeader.time_increment_resolution;
       
  1129         streamMode = sGetMPEG4Mode(volHeader.error_res_disable, volHeader.data_partitioned, volHeader.reversible_vlc);
       
  1130         bits = bibShowBits(22, inBuffer, &numBitsGot, &bitErrorIndication, &error);
       
  1131         if (error)
       
  1132             goto exitFunction;
       
  1133         
       
  1134       /* Check if H.263 PSC follows the VOL header, in which case this is 
       
  1135         MPEG-4 with short header and is decoded as H.263 */
       
  1136         if ( bits == 32 ) 
       
  1137         {
       
  1138             streamMode = EVedVideoBitstreamModeMPEG4ShortHeader;
       
  1139         }
       
  1140     }
       
  1141 
       
  1142     /* Else no H.263 and no MPEG-4 start code detected  */
       
  1143     else {
       
  1144         streamMode = EVedVideoBitstreamModeUnknown;
       
  1145     }
       
  1146     
       
  1147 exitFunction:
       
  1148     /* copy the got user data to the core data structure */
       
  1149     if (volHeader.user_data != NULL) 
       
  1150     {
       
  1151         free(volHeader.user_data);
       
  1152     }
       
  1153     
       
  1154     bibRewindBits( bibNumberOfFlushedBits( inBuffer ), inBuffer, &error );
       
  1155     aInfoOut->streamMode = streamMode;
       
  1156     aInfoOut->iTimeIncrementResolution = timeResolution;
       
  1157     return TX_OK;
       
  1158 }
       
  1159 
       
  1160 
       
  1161 
       
  1162 
       
  1163 
       
  1164 /* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
       
  1165 /*
       
  1166 * sQuantizeMB
       
  1167 *
       
  1168 * Parameters: 
       
  1169 *    mbdata          Contains the actual MB data to be quantized
       
  1170 *    oldQuant: 
       
  1171 *    newQuant:
       
  1172 *    intra
       
  1173 *
       
  1174 * Function:
       
  1175 *    This function requantizes the AC/DCT data for one MB, used in MPEG4 -> H263 transcoding 
       
  1176 * Returns:
       
  1177 *    Coded Block Pattern.
       
  1178 * Error codes:
       
  1179 *    None.
       
  1180 *
       
  1181 */
       
  1182 static void sQuantizeMB(int *mbdata, int oldQuant, int newQuant, int intra, int colorEffect)
       
  1183 {
       
  1184 #define  SIGN(x)          (((x)<0) ? -1:1 )
       
  1185     int   coeffCnt;
       
  1186     int   *block;
       
  1187     int   blkCnt;
       
  1188     
       
  1189     for (blkCnt = 0; blkCnt < (colorEffect ? 4 : 6); blkCnt++)
       
  1190     {   
       
  1191         block = &mbdata[blkCnt * BLOCK_COEFF_SIZE];
       
  1192         for (coeffCnt = (intra == VDX_MB_INTRA); coeffCnt < BLOCK_COEFF_SIZE;
       
  1193              coeffCnt++)
       
  1194              {
       
  1195                  if (block[coeffCnt])
       
  1196                  {
       
  1197                      int level = abs(block[coeffCnt]);
       
  1198                      int sign = SIGN(block[coeffCnt]);
       
  1199                      int rcoeff;
       
  1200                      // dequantize 
       
  1201                      if ((oldQuant % 2) == 1)
       
  1202                          rcoeff = oldQuant * ((level << 1) + 1);
       
  1203                      else
       
  1204                          rcoeff = oldQuant * ((level << 1) + 1) - 1;
       
  1205                      
       
  1206                      rcoeff = min (2047, max (-2048, sign * rcoeff));
       
  1207                      
       
  1208                      // requantize
       
  1209                      if (intra == VDX_MB_INTRA)
       
  1210                      {
       
  1211                          level = (abs (rcoeff)) / (newQuant << 1);
       
  1212                      }
       
  1213                      else
       
  1214                      {
       
  1215                          level = (abs (rcoeff) - (newQuant >> 1)) / (newQuant << 1);
       
  1216                          /* clipping to [-127,+127] */
       
  1217                      }
       
  1218                      
       
  1219                      /* clipping to [-127,+127] */
       
  1220                      block[coeffCnt] = min (127, max (-127, sign * level));
       
  1221                  }
       
  1222                  else
       
  1223                  {
       
  1224                      /* Nothing */
       
  1225                  }
       
  1226              }
       
  1227     }
       
  1228     return ;
       
  1229 }   
       
  1230 
       
  1231 
       
  1232 
       
  1233 
       
  1234 /* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
       
  1235 /*
       
  1236 * vdtChangeVosHeaderRegResyncL
       
  1237 *
       
  1238 * Parameters: 
       
  1239 *
       
  1240 * Function:
       
  1241 *    This function finds the error resillence bit and change it if necessary
       
  1242 *      to make it Regular Resynchronization mode 
       
  1243 * Returns:
       
  1244 *    ETrue if buffer changed.
       
  1245 * Error codes:
       
  1246 *    None
       
  1247 *
       
  1248 */
       
  1249 TBool vdtChangeVosHeaderRegResyncL(TPtrC8& aInputBuffer, TUint aBufferSize)
       
  1250 {
       
  1251     int16   errorCode = 0;             /* return code for bib functions */
       
  1252     bibBuffer_t *buffer;                   /* input buffer */
       
  1253     
       
  1254     /* Create bit buffer */
       
  1255     buffer = bibCreate((TAny*)aInputBuffer.Ptr(), aBufferSize, &errorCode);
       
  1256     if (!buffer || errorCode)
       
  1257         return EFalse;
       
  1258      
       
  1259     int startByte = 0, startBit = 7;
       
  1260     vdeDecodeParamters_t decInfo; 
       
  1261     vdtGetVideoBitstreamInfo(buffer, &decInfo, &startByte, &startBit);
       
  1262      
       
  1263     if (decInfo.streamMode == EVedVideoBitstreamModeMPEG4Regular)
       
  1264     {
       
  1265         char *temp = (char *) (TAny*)aInputBuffer.Ptr();
       
  1266         unsigned char patern[8] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
       
  1267         temp[startByte] &= patern[startBit]; // change the error resillence bit to 0;
       
  1268         
       
  1269         /* Delete bit buffer */
       
  1270         bibDelete(buffer, &errorCode);
       
  1271         return ETrue;
       
  1272     }
       
  1273     else
       
  1274     {
       
  1275       /* Delete bit buffer */
       
  1276         bibDelete(buffer, &errorCode);
       
  1277         return EFalse;
       
  1278     }
       
  1279 }
       
  1280 
       
  1281 /*
       
  1282 * CMPEG4Transcoder
       
  1283 *
       
  1284 * Parameters: 
       
  1285 *
       
  1286 * Function:
       
  1287 *    Constructor
       
  1288 *
       
  1289 */
       
  1290 CMPEG4Transcoder::CMPEG4Transcoder(const vdeInstance_t *aVDEInstance, bibBuffer_t *aInBuffer, bibBuffer_t *aOutBuffer)
       
  1291 {
       
  1292     VDTASSERT(aVDEInstance); 
       
  1293     VDTASSERT(aInBuffer);
       
  1294     VDTASSERT(aOutBuffer);
       
  1295     
       
  1296     /* passing the arguments */
       
  1297     iVDEInstance = aVDEInstance;
       
  1298     iInBuffer  = aInBuffer;
       
  1299     iOutBuffer = aOutBuffer;
       
  1300     
       
  1301     /* Color Toning */
       
  1302     iMBType      = NULL;
       
  1303     iCurQuant    = 0;
       
  1304     iColorEffect = aVDEInstance->iColorEffect;
       
  1305     iColorToneU  = aVDEInstance->iColorToneU;
       
  1306     iColorToneV  = aVDEInstance->iColorToneV;
       
  1307     iRefQuant    = aVDEInstance->iRefQp;
       
  1308     iDcScaler    = GetMpeg4DcScalerUV(iRefQuant);
       
  1309         
       
  1310     iDoModeTranscoding = EFalse;
       
  1311     iDoTranscoding = (iColorEffect || iDoModeTranscoding);
       
  1312     iTargetFormat = EVedVideoTypeMPEG4SimpleProfile;
       
  1313     iStuffingBitsUsed = 0;
       
  1314     
       
  1315     /* default values */
       
  1316     iLastMBNum = -1;
       
  1317     iCurMBNum = 0;
       
  1318 
       
  1319     /* initialize here but will be changed later to proper value */
       
  1320     iOutputMpeg4TimeIncResolution = KOutputMpeg4TimeIncResolution;  
       
  1321 
       
  1322     iNumMBsInOneVOP = (iVDEInstance->lumHeight * iVDEInstance->lumWidth) >> 8;  // /256
       
  1323     iMBsinWidth = iVDEInstance->lumWidth >> 4; 
       
  1324     iNumMBsInGOB = iVDEInstance->lumWidth >> 4; 
       
  1325     
       
  1326 
       
  1327     iMBList = NULL;
       
  1328     iH263DCData = NULL;
       
  1329     h263mbi = NULL;
       
  1330 
       
  1331     
       
  1332     iH263MBVPNum = NULL;
       
  1333     iErrorResilienceStartByteIndex = KDataNotValid;
       
  1334     iErrorResilienceStartBitIndex  = KDataNotValid;
       
  1335     
       
  1336     iVideoPacketNumInMPEG4 = 0; // the video packet number this MB belongs to, NOTE: the first GOB doesn't have a GOB header
       
  1337     iCurMBNumInVP = -1;
       
  1338     fFirstFrameInH263 = EFalse;
       
  1339     
       
  1340     return;
       
  1341 }
       
  1342 
       
  1343 /*
       
  1344 * ~CMPEG4Transcoder
       
  1345 *
       
  1346 * Parameters: 
       
  1347 *
       
  1348 * Function:
       
  1349 *    Destructor
       
  1350 *
       
  1351 */
       
  1352 CMPEG4Transcoder::~CMPEG4Transcoder()
       
  1353 {
       
  1354     if (iCurIMBinstance)
       
  1355     {
       
  1356         free(iCurIMBinstance);
       
  1357     }
       
  1358     if (iCurPMBinstance)
       
  1359     {
       
  1360         free(iCurPMBinstance);
       
  1361     }
       
  1362     if (bufEdit.editParams)
       
  1363     {
       
  1364         free(bufEdit.editParams);
       
  1365     }
       
  1366     
       
  1367     // for H263
       
  1368     if (iH263MBVPNum)
       
  1369     {
       
  1370         free(iH263MBVPNum);
       
  1371     }
       
  1372     
       
  1373     // for color toning
       
  1374     if (iMBType)
       
  1375     {
       
  1376         free(iMBType);
       
  1377     }
       
  1378 
       
  1379 
       
  1380     
       
  1381     if (iH263DCData)
       
  1382     {
       
  1383         for (int i = 0; i < iNumMBsInOneVOP; i++)
       
  1384         {
       
  1385             free(iH263DCData[i]);
       
  1386         }
       
  1387         free(iH263DCData);
       
  1388     }
       
  1389 
       
  1390     if ( ( (iTargetFormat == EVedVideoTypeH263Profile0Level10) || 
       
  1391            (iTargetFormat == EVedVideoTypeH263Profile0Level45) ) &&
       
  1392            iBitStreamMode != EVedVideoBitstreamModeMPEG4ShortHeader &&
       
  1393            iBitStreamMode != EVedVideoBitstreamModeH263 &&
       
  1394            h263mbi)
       
  1395     {
       
  1396         free(h263mbi);
       
  1397     }
       
  1398     
       
  1399     if ( iOutBuffer )
       
  1400         {
       
  1401         
       
  1402         PRINT((_L("CMPEG4Transcoder: finish one frame successfully, buffer size %d"), 
       
  1403            iOutBuffer->getIndex));
       
  1404         }
       
  1405         
       
  1406 #ifdef _DEBUG
       
  1407     if (iOutBuffer->getIndex > KInitialBufferSize)
       
  1408     {
       
  1409         PRINT((_L("CMPEG4Transcoder: Output buffer size from engine is not big enough! check KInitialBufferSize")));
       
  1410         
       
  1411     }
       
  1412 #endif
       
  1413     if ( iOutBuffer )
       
  1414         {
       
  1415         VDTASSERT(iOutBuffer->getIndex < KInitialBufferSize);
       
  1416         }
       
  1417 }
       
  1418 
       
  1419 /*
       
  1420 * H263EscapeCoding
       
  1421 *
       
  1422 * Parameters: 
       
  1423 *
       
  1424 * Function:
       
  1425 *    Indicates whether escape vlc coding is used in one block
       
  1426 * Returns:
       
  1427 *    None
       
  1428 * Error codes:
       
  1429 *    None
       
  1430 *
       
  1431 */
       
  1432 void CMPEG4Transcoder::H263EscapeCoding(int aIndex, int fEscapeCodeUsed)
       
  1433 {
       
  1434     iEscapeCodeUsed[aIndex] = fEscapeCodeUsed;
       
  1435 }
       
  1436 
       
  1437 /*
       
  1438 * SetTranscoding
       
  1439 *
       
  1440 * Parameters: 
       
  1441 *
       
  1442 * Function:
       
  1443 *    Indicates whether we need to do MPEG4 bitstream transcoding
       
  1444 * Returns:
       
  1445 *    TX error codes
       
  1446 * Error codes:
       
  1447 *    None
       
  1448 *
       
  1449 */
       
  1450 int CMPEG4Transcoder::SetTranscoding(vdeDecodeParamters_t *aDecoderInfo)
       
  1451 {
       
  1452     iColorEffect = aDecoderInfo->aColorEffect;
       
  1453     iColorToneU = aDecoderInfo->aColorToneU; 
       
  1454     iColorToneV = aDecoderInfo->aColorToneV;
       
  1455     iBitStreamMode = (TVedVideoBitstreamMode)aDecoderInfo->streamMode;
       
  1456     
       
  1457     iTargetFormat = aDecoderInfo->aOutputVideoFormat; 
       
  1458     iDoModeTranscoding = aDecoderInfo->fModeChanged ? ETrue: EFalse;
       
  1459     iDoTranscoding = (iColorEffect || iDoModeTranscoding);
       
  1460 
       
  1461     /* set to proper value */
       
  1462     iOutputMpeg4TimeIncResolution = *(aDecoderInfo->aMPEG4TargetTimeResolution); 
       
  1463 
       
  1464     /* allocate buffer for MPEG4 - > H263 transcoding */
       
  1465     /* the following is used if spatial domain processing is not done */
       
  1466         
       
  1467     if ( ( (iTargetFormat == EVedVideoTypeH263Profile0Level10) ||
       
  1468            (iTargetFormat == EVedVideoTypeH263Profile0Level45) ) &&
       
  1469            iBitStreamMode != EVedVideoBitstreamModeMPEG4ShortHeader &&
       
  1470            iBitStreamMode != EVedVideoBitstreamModeH263)
       
  1471     {
       
  1472         h263mbi = (tMBInfo*) malloc (sizeof(tMBInfo) * iNumMBsInOneVOP);
       
  1473         if (!h263mbi) 
       
  1474         {
       
  1475             PRINT((_L("CMPEG4Transcoder::SetTranscoding - h263mbi creation failed")));
       
  1476             deb("CMPEG4Transcoder::SetTranscoding - h263mbi creation failed\n");
       
  1477 
       
  1478             return TX_ERR;
       
  1479         }
       
  1480         memset(h263mbi, 0, sizeof(tMBInfo) * iNumMBsInOneVOP);
       
  1481     }
       
  1482     
       
  1483     return TX_OK;
       
  1484 }
       
  1485 
       
  1486 
       
  1487 
       
  1488 
       
  1489 /*
       
  1490 * BeginOneVideoPacket
       
  1491 *
       
  1492 * Parameters: 
       
  1493 *
       
  1494 * Function:
       
  1495 *    Records the position before one Video packet is processed
       
  1496 * Returns:
       
  1497 *    None
       
  1498 * Error codes:
       
  1499 *    None
       
  1500 *
       
  1501 */
       
  1502 void CMPEG4Transcoder::BeginOneVideoPacket(dvpVPInParam_t *aVPin)
       
  1503 {
       
  1504     VDTASSERT(iInBuffer); 
       
  1505     VDTASSERT(aVPin);
       
  1506     
       
  1507     iCurVPIn = aVPin;
       
  1508     iVPStartByteIndex = iInBuffer->getIndex;
       
  1509     iVPStartBitIndex  = iInBuffer->bitIndex;
       
  1510     
       
  1511     iCurMBNumInVP = -1;
       
  1512 
       
  1513     iStuffingBitsUsed = 0;
       
  1514     
       
  1515     iVopCodingType = aVPin->pictParam->pictureType;
       
  1516     iBitStreamMode = sGetMPEG4Mode(aVPin->pictParam->error_res_disable,
       
  1517         aVPin->pictParam->data_partitioned, aVPin->pictParam->reversible_vlc);
       
  1518 }
       
  1519 
       
  1520 
       
  1521 /*
       
  1522 * sConstructH263PicHeader
       
  1523 *
       
  1524 * Parameters: 
       
  1525 *        lBitOut                output buffer
       
  1526 *        quant                quant value to be put in header
       
  1527 *           picType             VDX_VOP_TYPE_P or VDX_VOP_TYPE_I
       
  1528 *           tr                      time increament
       
  1529 * Function:
       
  1530 *    Writes the pic header into bit-stream for one MPEG4 frame
       
  1531 * Returns:
       
  1532 *    None
       
  1533 * Error codes:
       
  1534 *    None
       
  1535 *
       
  1536 */
       
  1537 void sConstructH263PicHeader(bibBuffer_t *lBitOut, int picType, int quant, int tr, int aVOPNotCoded, int aFormat)
       
  1538 
       
  1539 {
       
  1540     if (aVOPNotCoded)
       
  1541     {
       
  1542         return;
       
  1543     }
       
  1544     /* ShortVideoStartMarker */
       
  1545     sPutBits(lBitOut, 22, SHORT_VIDEO_START_MARKER);
       
  1546     /* TemporalReference */
       
  1547     sPutBits(lBitOut, 8, (tr & 0x000000ff));
       
  1548     /* Marker Bit */
       
  1549     sPutBits(lBitOut, 1, MARKER_BIT);
       
  1550     /* Zero Bit */
       
  1551     sPutBits(lBitOut, 1, 0);
       
  1552     /* SplitScreenIndicator = 0 */
       
  1553     sPutBits(lBitOut, 1, 0);
       
  1554     /* DocumentCameraIndicator = 0 */
       
  1555     sPutBits(lBitOut, 1, 0);
       
  1556     /* FullPictureFreezeRelease = 0 */
       
  1557     sPutBits(lBitOut, 1, 0);
       
  1558     /* Source Fromat */
       
  1559     sPutBits(lBitOut, 3, aFormat);
       
  1560     /* PictureCodingType 0 for intra, 1 for inter */
       
  1561     sPutBits(lBitOut, 1, picType == VDX_VOP_TYPE_P);
       
  1562     /* UMV= 0 */
       
  1563     sPutBits(lBitOut, 1, 0);
       
  1564     /* SAC = 0 */
       
  1565     sPutBits(lBitOut, 1, 0);
       
  1566     /* Advanced Prediction = 0 */
       
  1567     sPutBits(lBitOut, 1, 0);
       
  1568     /* PB frame = 0 */
       
  1569     sPutBits(lBitOut, 1, 0);
       
  1570     /* VOPQuant */
       
  1571     sPutBits(lBitOut, 5, quant);
       
  1572     /* ZeroBIt */
       
  1573     sPutBits(lBitOut, 1, 0);
       
  1574     /* Pei = 0 */
       
  1575     sPutBits(lBitOut, 1, 0);        
       
  1576 }
       
  1577 
       
  1578 
       
  1579 /*
       
  1580 * VOPHeaderEnded
       
  1581 *
       
  1582 * Parameters: 
       
  1583 *
       
  1584 * Function:
       
  1585 *    Copy the VOP Header to output buffer
       
  1586 * Returns:
       
  1587 *    None
       
  1588 * Error codes:
       
  1589 *    None
       
  1590 *
       
  1591 */
       
  1592 void CMPEG4Transcoder::VOPHeaderEnded(int aStartByteIndex, int aStartBitIndex, 
       
  1593     int aQuant, int aPicType, int aFrameNum, int aVOPNotCoded)
       
  1594 {
       
  1595     const int KNumMbInSqcif = 48; 
       
  1596     const int KNumMbInQcif = 99; 
       
  1597     const int KNumMbInCif = 396; 
       
  1598 
       
  1599     if (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45)
       
  1600     {
       
  1601         int sourceFormat = 2; // qcif
       
  1602         /* note: other formate not supported */
       
  1603         if (iNumMBsInOneVOP == KNumMbInSqcif)  /* sqcif */
       
  1604         {
       
  1605             sourceFormat = 1;  // sqcif
       
  1606         }
       
  1607         else if (iNumMBsInOneVOP == KNumMbInQcif) /* qcif */
       
  1608         {
       
  1609             sourceFormat = 2;  // qcif
       
  1610         }
       
  1611         else if (iNumMBsInOneVOP == KNumMbInCif) /* cif */
       
  1612         {
       
  1613             sourceFormat = 3;  // cif
       
  1614         }
       
  1615         sConstructH263PicHeader(iOutBuffer, aPicType, aQuant, 0, aVOPNotCoded, sourceFormat);
       
  1616         PRINT((_L("CMPEG4Transcoder: MPEG4 -> H263: picture header generated")));
       
  1617     }
       
  1618   /* Copy the VOP header */
       
  1619   else 
       
  1620     {
       
  1621         bufEdit.copyMode = CopyWhole; // whole
       
  1622         CopyStream(iInBuffer,iOutBuffer,&bufEdit,aStartByteIndex,aStartBitIndex);
       
  1623     }
       
  1624   iPreQuant = aQuant;
       
  1625   iStuffingBitsUsed = 0;
       
  1626 
       
  1627   iCurQuant = aQuant;
       
  1628   /* Color Toning */
       
  1629   if (!aFrameNum || !iRefQuant)
       
  1630   {
       
  1631      iRefQuant = iCurQuant;
       
  1632      iDcScaler = GetMpeg4DcScalerUV(iRefQuant); 
       
  1633   }
       
  1634 
       
  1635 }
       
  1636 
       
  1637 
       
  1638 /*
       
  1639 * VOPEnded
       
  1640 *
       
  1641 * Parameters: 
       
  1642 *
       
  1643 * Function:
       
  1644 *    This function is called when one VOP has ended
       
  1645 * Returns:
       
  1646 *    None
       
  1647 * Error codes:
       
  1648 *    None
       
  1649 *
       
  1650 */
       
  1651 void CMPEG4Transcoder::VOPEnded()
       
  1652 {
       
  1653     /* check if MBs are lost */
       
  1654     int dataPartitioned = (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC 
       
  1655         || iBitStreamMode == EVedVideoBitstreamModeMPEG4DP ||  iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP);
       
  1656     
       
  1657     if (iLastMBNum != iNumMBsInOneVOP - 1 && !(dataPartitioned && !iDoModeTranscoding))
       
  1658     {
       
  1659         for (int i = iLastMBNum+1; i < iNumMBsInOneVOP; i++)
       
  1660         {
       
  1661             /* output  1 bit COD */
       
  1662             sPutBits (iOutBuffer, 1, 1);
       
  1663         }
       
  1664     }
       
  1665     
       
  1666     iLastMBNum = iNumMBsInOneVOP - 1; 
       
  1667     /* bits need to be stuffed in the output buffer at the end VOP */
       
  1668     if (!dataPartitioned && iTargetFormat == EVedVideoTypeMPEG4SimpleProfile)
       
  1669     {
       
  1670         if (!iStuffingBitsUsed)
       
  1671         {
       
  1672             vdtStuffBitsMPEG4(iOutBuffer);
       
  1673         }
       
  1674         iStuffingBitsUsed = 1;
       
  1675     }
       
  1676     else if (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45)
       
  1677     {
       
  1678         sStuffBitsH263(iOutBuffer);
       
  1679     }
       
  1680     
       
  1681   PRINT((_L("CMPEG4Transcoder: VOPEnded. color effect: %d, format convert %d, do transcoding: %d streammode: %d, outputformat: %d "), 
       
  1682        iColorEffect, iDoModeTranscoding, iDoTranscoding, iBitStreamMode, iTargetFormat));
       
  1683 }
       
  1684 
       
  1685 /*
       
  1686 * AfterOneVideoPacketHeader
       
  1687 *
       
  1688 * Parameters: 
       
  1689 *
       
  1690 * Function:
       
  1691 *    This function is called after retreiving the VP
       
  1692 *    Records the position before the content of the video packet is processed
       
  1693 * Returns:
       
  1694 *    None
       
  1695 * Error codes:
       
  1696 *    None
       
  1697 *
       
  1698 */
       
  1699 void CMPEG4Transcoder::AfterVideoPacketHeader(dvpVPInOutParam_t *aVPInfo)
       
  1700 {
       
  1701     VDTASSERT(aVPInfo); 
       
  1702     iCurVPInOut = aVPInfo;
       
  1703     
       
  1704     iVPHeaderEndByteIndex = iInBuffer->getIndex;
       
  1705     iVPHeaderEndBitIndex  = iInBuffer->bitIndex;
       
  1706     
       
  1707     /* Color Toning */
       
  1708     iCurQuant = aVPInfo->quant; 
       
  1709     
       
  1710     /* Copy the VP header to output stream. Note; the first VP does not have a VP header */
       
  1711     if (iTargetFormat == EVedVideoTypeMPEG4SimpleProfile)
       
  1712     {
       
  1713        bufEdit.copyMode = CopyWhole; /* whole */
       
  1714          CopyStream(iInBuffer,iOutBuffer,&bufEdit,iVPStartByteIndex,iVPStartBitIndex);
       
  1715     }
       
  1716 }
       
  1717 
       
  1718 
       
  1719 /*
       
  1720 * OneVPEnded
       
  1721 *
       
  1722 * Parameters: 
       
  1723 *
       
  1724 * Function:
       
  1725 *    This function is called after one VP  contents are retrieved
       
  1726 * Returns:
       
  1727 *    None
       
  1728 * Error codes:
       
  1729 *    None
       
  1730 *
       
  1731 */
       
  1732 void CMPEG4Transcoder::OneVPEnded()
       
  1733 {
       
  1734     if (!iDoTranscoding)
       
  1735     {
       
  1736         /* no transcoding, copy whole content VP */
       
  1737         bufEdit.copyMode = CopyWhole; 
       
  1738         CopyStream(iInBuffer,iOutBuffer,&bufEdit,iVPHeaderEndByteIndex,iVPHeaderEndBitIndex);
       
  1739         iStuffingBitsUsed = 1;// also stuffing is copied
       
  1740     }
       
  1741     else
       
  1742     {
       
  1743         int dataPartitioned = (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC 
       
  1744             || iBitStreamMode == EVedVideoBitstreamModeMPEG4DP ||  iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP);
       
  1745         int nextExpectedMBNum = iCurVPInOut->currMBNum;
       
  1746         
       
  1747         if (dataPartitioned && !iDoModeTranscoding)
       
  1748         {
       
  1749         /* if data is partitioned and we are not doing format transcoding,
       
  1750         not coded MBs info is already in data partition 1
       
  1751             */
       
  1752         }
       
  1753         else
       
  1754         {
       
  1755             /* MBs are lost or not coded,  */
       
  1756             for (int i = iLastMBNum+1; i < nextExpectedMBNum; i++)
       
  1757             {
       
  1758                 /* output  1 bit COD */
       
  1759                 sPutBits (iOutBuffer, 1, 1);
       
  1760             }
       
  1761         }
       
  1762         
       
  1763         iLastMBNum = nextExpectedMBNum - 1; 
       
  1764         /* bits need to be stuffed in the output buffer at the end of vp in all cases (bw or not) */
       
  1765         if (iTargetFormat == EVedVideoTypeMPEG4SimpleProfile) 
       
  1766         {
       
  1767             if (!iStuffingBitsUsed)
       
  1768             {
       
  1769                 vdtStuffBitsMPEG4(iOutBuffer);
       
  1770             }
       
  1771             iStuffingBitsUsed = 1;
       
  1772         }
       
  1773     }
       
  1774 }
       
  1775 
       
  1776 
       
  1777 
       
  1778 /*
       
  1779 * BeginOneMB
       
  1780 *
       
  1781 * Parameters: 
       
  1782 *
       
  1783 * Function:
       
  1784 *    Records the position before one MB is processed
       
  1785 * Returns:
       
  1786 *    None
       
  1787 * Error codes:
       
  1788 *    None
       
  1789 *
       
  1790 */
       
  1791 void CMPEG4Transcoder::BeginOneMB(int aMBNum)
       
  1792 {
       
  1793     VDTASSERT(iInBuffer); 
       
  1794     
       
  1795     iMBStartByteIndex = iInBuffer->getIndex;
       
  1796     iMBStartBitIndex  = iInBuffer->bitIndex;
       
  1797     iCurMBNum = aMBNum;
       
  1798     
       
  1799     // Color Toning
       
  1800     iCurMBNumInVP++;
       
  1801     
       
  1802     if ((iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263) && iDoModeTranscoding)
       
  1803     {
       
  1804        /* H263 -> MPEG4  */
       
  1805        VDTASSERT(iH263MBVPNum);
       
  1806          iH263MBVPNum[iCurMBNum]= iVideoPacketNumInMPEG4;
       
  1807     }
       
  1808 }
       
  1809 
       
  1810 /*
       
  1811 * BeginOneBlock
       
  1812 *
       
  1813 * Parameters: 
       
  1814 *
       
  1815 * Function:
       
  1816 *    Records the position before one block in MB is processed
       
  1817 * Returns:
       
  1818 *    None
       
  1819 * Error codes:
       
  1820 *    None
       
  1821 *
       
  1822 */
       
  1823 void CMPEG4Transcoder::BeginOneBlock(int aBlockIndex)
       
  1824 {
       
  1825     VDTASSERT(aBlockIndex >= 0 && aBlockIndex < 6); 
       
  1826     
       
  1827     iBlockStartByteIndex[aBlockIndex] = iInBuffer->getIndex;
       
  1828     iBlockStartBitIndex[aBlockIndex]  = iInBuffer->bitIndex;
       
  1829 }
       
  1830 
       
  1831 
       
  1832 /*
       
  1833 * OneIMBDataStarted
       
  1834 *
       
  1835 * Parameters: 
       
  1836 *
       
  1837 * Function:
       
  1838 *    This function is called after the MB header is read; start one IMB, 
       
  1839 * Returns:
       
  1840 *    None
       
  1841 * Error codes:
       
  1842 *    None
       
  1843 *
       
  1844 */
       
  1845 void CMPEG4Transcoder::OneIMBDataStarted(vdxIMBListItem_t *aMBInstance)
       
  1846 {
       
  1847     VDTASSERT(aMBInstance); 
       
  1848     VDTASSERT(iCurIMBinstance);
       
  1849     iMBCodingType = VDX_MB_INTRA;
       
  1850     iVopCodingType = VDX_VOP_TYPE_I;
       
  1851     iMBType[iCurMBNum] = iMBCodingType;
       
  1852 
       
  1853     
       
  1854     memcpy(iCurIMBinstance, aMBInstance, sizeof(vdxIMBListItem_t)); 
       
  1855 }
       
  1856 
       
  1857 /*
       
  1858 * OnePMBDataStarted
       
  1859 *
       
  1860 * Parameters: 
       
  1861 *
       
  1862 * Function:
       
  1863 *    This function is called after the MB header is read; start one PMB, 
       
  1864 * Returns:
       
  1865 *    None
       
  1866 * Error codes:
       
  1867 *    None
       
  1868 *
       
  1869 */
       
  1870 void CMPEG4Transcoder::OnePMBDataStarted(vdxPMBListItem_t *aMBInstance)
       
  1871 {
       
  1872     VDTASSERT(aMBInstance); 
       
  1873     VDTASSERT(iCurPMBinstance);
       
  1874     
       
  1875     iMBCodingType = aMBInstance->mbClass;
       
  1876     iVopCodingType = VDX_VOP_TYPE_P;
       
  1877     iMBType[iCurMBNum] = iMBCodingType;
       
  1878 
       
  1879     memcpy(iCurPMBinstance, aMBInstance, sizeof(vdxPMBListItem_t)); 
       
  1880 }
       
  1881 
       
  1882 
       
  1883 
       
  1884 /*
       
  1885 * OneIMBDataStartedDataPartitioned
       
  1886 *
       
  1887 * Parameters: 
       
  1888 *
       
  1889 * Function:
       
  1890 *    Add one IMB instance, It is done after parsing Part1 and Part2 before the block data for current MB
       
  1891 * Returns:
       
  1892 *    None
       
  1893 * Error codes:
       
  1894 *    None
       
  1895 *
       
  1896 */
       
  1897 void CMPEG4Transcoder::OneIMBDataStartedDataPartitioned(vdxIMBListItem_t *aMBInstance, dlst_t *aMBList, int aCurrMBNumInVP, int aMBNum)
       
  1898 {
       
  1899     VDTASSERT(aMBInstance); // at this point, the instance should not be null
       
  1900     VDTASSERT(aMBList);
       
  1901     
       
  1902     memcpy(iCurIMBinstance, aMBInstance, sizeof(vdxIMBListItem_t)); 
       
  1903     iCurMBNumInVP = aCurrMBNumInVP;
       
  1904     iCurMBNum = aMBNum;
       
  1905     iMBList = aMBList;
       
  1906     iMBCodingType = VDX_MB_INTRA;
       
  1907     iVopCodingType = VDX_VOP_TYPE_I;
       
  1908     iMBType[iCurMBNum] = iMBCodingType;
       
  1909     
       
  1910     if (!iCurMBNumInVP && iDoTranscoding) 
       
  1911     {
       
  1912         if (!iDoModeTranscoding)
       
  1913         {
       
  1914           /* We are not doing bitstream transcoding,  
       
  1915             we have color effect here and need to reconstruct data partitions.
       
  1916             */
       
  1917             ReconstructIMBPartitions();
       
  1918         }
       
  1919     }
       
  1920 }
       
  1921 
       
  1922 /*
       
  1923 * OnePMBDataStartedDataPartitioned
       
  1924 *
       
  1925 * Parameters: 
       
  1926 *
       
  1927 * Function:
       
  1928 *    Add one IMB instance, It is done after parsing Part1 and Part2 before the block data for current MB
       
  1929 *    Note: PMB may be INTRA coded.
       
  1930 * Returns:
       
  1931 *    None
       
  1932 * Error codes:
       
  1933 *    None
       
  1934 *
       
  1935 */
       
  1936 void CMPEG4Transcoder::OnePMBDataStartedDataPartitioned(vdxPMBListItem_t *aMBInstance, dlst_t *aMBList, int aCurrMBNumInVP, int aMBNum)
       
  1937 {
       
  1938     VDTASSERT(aMBInstance); /* at this point, the instance should not be null */
       
  1939     VDTASSERT(aMBList);
       
  1940     
       
  1941     memcpy(iCurPMBinstance, aMBInstance, sizeof(vdxPMBListItem_t)); 
       
  1942     iCurMBNumInVP = aCurrMBNumInVP;
       
  1943     iCurMBNum = aMBNum;
       
  1944     iMBList = aMBList;
       
  1945     iMBCodingType = aMBInstance->mbClass;
       
  1946     iVopCodingType = VDX_VOP_TYPE_P;
       
  1947     iMBType[iCurMBNum] = iMBCodingType;
       
  1948     
       
  1949     if (!aMBInstance->fCodedMB && iDoModeTranscoding)
       
  1950     {
       
  1951         /* this MB is not coded and need to be converted to target mode,
       
  1952         out put the possible MB stuffing bits and COD
       
  1953         */
       
  1954         /* MB stuffing bits if they exsit */
       
  1955         vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  1956             aMBInstance->DataItemStartByteIndex[11], aMBInstance->DataItemStartBitIndex[11],
       
  1957             aMBInstance->DataItemEndByteIndex[11], aMBInstance->DataItemEndBitIndex[11]);
       
  1958         /* It is a not-coded MB, output  1 bit COD (it always exists in P frame) */
       
  1959         sPutBits (iOutBuffer, 1, 1);
       
  1960         iLastMBNum = iCurMBNum;
       
  1961     }
       
  1962     else if (!iCurMBNumInVP && iDoTranscoding) 
       
  1963     {
       
  1964         if (!iDoModeTranscoding)
       
  1965         {
       
  1966         /* We are not doing bitstream transcoding, 
       
  1967         we have color effect here and need to reconstruct data partitions.
       
  1968             */
       
  1969             ReconstructPMBPartitions();
       
  1970         }
       
  1971     }
       
  1972 }
       
  1973 
       
  1974 
       
  1975 
       
  1976 /*
       
  1977 * TranscodingOneMB
       
  1978 *
       
  1979 * Parameters: 
       
  1980 *
       
  1981 * Function:
       
  1982 *    Transcoding one MB, which may include dequantization, requantization , and re-encoding
       
  1983 * Returns:
       
  1984 *    DMD error codes since called from decmbdct
       
  1985 *
       
  1986 */
       
  1987 int CMPEG4Transcoder::TranscodingOneMB(dmdPParam_t *aParam = NULL)
       
  1988 {
       
  1989 /* Because it has block data, this MB must be a coded MB,
       
  1990 which means the position indicated by iMBStartByteIndex and iMBStartBitIndex starts with a MCBPC 
       
  1991     */
       
  1992     VDTASSERT(!(!iCurPMBinstance->fCodedMB && iMBCodingType == VDX_MB_INTER));
       
  1993     
       
  1994     if (!iDoTranscoding)
       
  1995         {
       
  1996         iLastMBNum = iCurMBNum; // need to update the variable to avoid marking this as noncoded MB
       
  1997         return TX_OK;
       
  1998         }
       
  1999     
       
  2000     int dataPartitioned = (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC 
       
  2001         || iBitStreamMode == EVedVideoBitstreamModeMPEG4DP ||  iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP);
       
  2002     
       
  2003     if (dataPartitioned)
       
  2004     {
       
  2005         /* since we need to handle MB stuffing bits, which are handle outside the transcoder in other modes,
       
  2006         not coded MBs and MB stuffing bits are handled in OnePMBDataStartedDataPartitioned, 
       
  2007              ReconstuctI/PMBPartitios or ConstructRegularMPEG4MBData
       
  2008         */
       
  2009     }
       
  2010     else if(iCurMBNum != iLastMBNum + 1 )
       
  2011     {
       
  2012         /* if previous MBs are lost or not coded, we copy one MB with COD = 1; */
       
  2013         for (int i = 0 ; i < iCurMBNum - iLastMBNum - 1; i++)
       
  2014         {
       
  2015             /* output  1 bit COD */
       
  2016             sPutBits (iOutBuffer, 1, 1);
       
  2017         }
       
  2018     }
       
  2019     
       
  2020     int newMCBPCLen = 0;
       
  2021     int newMCBPC = 0;
       
  2022     int oldMCBPCLen = 0;
       
  2023     
       
  2024     /* determine whether to change mcbpc */
       
  2025     if (iColorEffect)
       
  2026     {
       
  2027         if (iVopCodingType == VDX_VOP_TYPE_P) 
       
  2028         {
       
  2029             oldMCBPCLen = vdtGetPMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, iCurPMBinstance->mcbpc);
       
  2030         }
       
  2031         else
       
  2032         {
       
  2033             oldMCBPCLen = vdtGetIMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, iCurIMBinstance->mcbpc);
       
  2034         }
       
  2035     }
       
  2036     
       
  2037 
       
  2038     
       
  2039     if (iDoModeTranscoding && ( (iTargetFormat == EVedVideoTypeH263Profile0Level10) ||
       
  2040                                 (iTargetFormat == EVedVideoTypeH263Profile0Level45) ) )
       
  2041     {
       
  2042         if ( ConstructH263MBData(aParam, newMCBPCLen, newMCBPC) != VDC_OK )
       
  2043             {
       
  2044             return TX_ERR;
       
  2045             }
       
  2046     }
       
  2047     else /* possible H263->MPEG4 transcoding */
       
  2048         
       
  2049     {
       
  2050         /* MPEG4 with VDT_RESYN and VDT_REGULAR, we only do bitstream copying */
       
  2051         if ( iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn || iBitStreamMode == EVedVideoBitstreamModeMPEG4Regular ||
       
  2052             ((iBitStreamMode ==EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263) && !iDoModeTranscoding) )
       
  2053         {
       
  2054         /* the MB stuffing is taken card of outside in file viddemux.cpp
       
  2055         we only need to output COD, MCBPC
       
  2056             */
       
  2057             int mcbpcStartByteIndex, mcbpcStartBitIndex;
       
  2058             
       
  2059             if (iVopCodingType == VDX_VOP_TYPE_I)
       
  2060             {
       
  2061                 mcbpcStartByteIndex = iCurIMBinstance->DataItemStartByteIndex[0];
       
  2062                 mcbpcStartBitIndex = iCurIMBinstance->DataItemStartBitIndex[0];
       
  2063             }
       
  2064             else
       
  2065             {
       
  2066                 mcbpcStartByteIndex = iCurPMBinstance->DataItemStartByteIndex[0];
       
  2067                 mcbpcStartBitIndex = iCurPMBinstance->DataItemStartBitIndex[0];
       
  2068                 /* It is a coded MB, output  1 bit COD (it always exists in P frame) */
       
  2069                 sPutBits (iOutBuffer, 1, 0);
       
  2070             }
       
  2071             
       
  2072             if (!iColorEffect)
       
  2073             {
       
  2074                 bufEdit.copyMode = CopyWhole; /* whole */
       
  2075                 CopyStream(iInBuffer,iOutBuffer,&bufEdit,mcbpcStartByteIndex,mcbpcStartBitIndex);
       
  2076             }
       
  2077             else
       
  2078             {
       
  2079                 /* modify mcbpc and copy only the Y data */
       
  2080                 bufEdit.copyMode = CopyWithEdit; // copy with edit
       
  2081                 bufEdit.editParams[0].StartByteIndex = mcbpcStartByteIndex; 
       
  2082                 bufEdit.editParams[0].StartBitIndex  = mcbpcStartBitIndex; 
       
  2083                 bufEdit.editParams[0].curNumBits = oldMCBPCLen; 
       
  2084                 bufEdit.editParams[0].newNumBits = newMCBPCLen; 
       
  2085                 bufEdit.editParams[0].newValue = newMCBPC; 
       
  2086                 CopyStream(iInBuffer,iOutBuffer,&bufEdit,mcbpcStartByteIndex,mcbpcStartBitIndex);
       
  2087                 
       
  2088                 /* disgard the UV data */
       
  2089                 int16 errorCode = 0;
       
  2090                 int bitsToRewind = ((iInBuffer->getIndex << 3) + 7  - iInBuffer->bitIndex) 
       
  2091                                      - ((iBlockStartByteIndex[4] << 3) + 7 - iBlockStartBitIndex[4]);
       
  2092                 bibRewindBits(bitsToRewind, iOutBuffer, &errorCode );
       
  2093                 
       
  2094                 if (iMBCodingType == VDX_MB_INTRA)
       
  2095                 {
       
  2096                     if (iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263)
       
  2097                     {
       
  2098                         sResetH263IntraDcUV(iOutBuffer, iColorToneU, iColorToneV);                        
       
  2099                     }
       
  2100                     else
       
  2101                     {
       
  2102                         ResetMPEG4IntraDcUV();
       
  2103                     }
       
  2104                 }
       
  2105             }
       
  2106         }
       
  2107 
       
  2108         else if ((iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263) && iDoModeTranscoding)
       
  2109         {
       
  2110             H263ToMPEG4MBData(newMCBPCLen, newMCBPC);
       
  2111         }
       
  2112         
       
  2113         else /* data partitioned */
       
  2114         {
       
  2115             if (iDoModeTranscoding)
       
  2116             {
       
  2117                 /* for data partitioned bitstream, we do the bitstream rearrangement  */
       
  2118                 ConstructRegularMPEG4MBData(newMCBPCLen, newMCBPC);
       
  2119             }
       
  2120             else
       
  2121             {
       
  2122                 /* copy the ACs or DCTs */
       
  2123                 bufEdit.copyMode = CopyWhole; // whole
       
  2124                 CopyStream(iInBuffer,iOutBuffer,&bufEdit,iBlockStartByteIndex[0],iBlockStartBitIndex[0]);
       
  2125                 if (iColorEffect)
       
  2126                 {
       
  2127                     /* discard U V data */
       
  2128                     int16 errorCode = 0;
       
  2129                     int bitsToRewind = ((iInBuffer->getIndex << 3) + 7  - iInBuffer->bitIndex) 
       
  2130                                              - ((iBlockStartByteIndex[4] << 3) + 7 - iBlockStartBitIndex[4]);
       
  2131                     bibRewindBits(bitsToRewind, iOutBuffer, &errorCode );
       
  2132                 }
       
  2133             }
       
  2134         }
       
  2135 
       
  2136     }
       
  2137     iLastMBNum = iCurMBNum;
       
  2138     return TX_OK;
       
  2139 }
       
  2140 
       
  2141 
       
  2142 
       
  2143 
       
  2144 /*
       
  2145 * ReconstructIMBPartitions
       
  2146 *
       
  2147 * Parameters: 
       
  2148 *
       
  2149 * Function:
       
  2150 *    Recontruct the partitions for color effect when we are not doing format transcoding
       
  2151 * Returns:
       
  2152 *    None
       
  2153 * Error codes:
       
  2154 *    None
       
  2155 *
       
  2156 */
       
  2157 void CMPEG4Transcoder::ReconstructIMBPartitions()
       
  2158 {
       
  2159     vdxIMBListItem_t *MBinstance;
       
  2160      int *dataItemStartByteIndex;
       
  2161      int *dataItemStartBitIndex;
       
  2162      int *dataItemEndByteIndex;
       
  2163      int *dataItemEndBitIndex;
       
  2164      int newMCBPCLen = 0;
       
  2165      int newMCBPC = 0;
       
  2166      
       
  2167      VDTASSERT(iMBList);
       
  2168      
       
  2169      for (dlstHead(iMBList, (void **) &MBinstance); 
       
  2170      MBinstance != NULL; 
       
  2171      dlstNext(iMBList, (void **) &MBinstance))
       
  2172       {
       
  2173          dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
       
  2174          dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
       
  2175          dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
       
  2176          dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
       
  2177          // MB stuffing bits if they exsit
       
  2178          vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
       
  2179              dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
       
  2180          
       
  2181          /* MCBPC    */
       
  2182          if (iColorEffect)
       
  2183          {
       
  2184              /* MCBPC Changed. Ignore the old value (not used) */
       
  2185              vdtGetIMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, MBinstance->mcbpc);
       
  2186              sPutBits(iOutBuffer, newMCBPCLen, newMCBPC);
       
  2187          }
       
  2188          else
       
  2189          {
       
  2190              vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2191                  dataItemStartByteIndex[0], dataItemStartBitIndex[0],
       
  2192                  dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
       
  2193          }
       
  2194          
       
  2195          /* DQUANT, if it exsits */
       
  2196          vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2197                    dataItemStartByteIndex[1], dataItemStartBitIndex[1],
       
  2198                      dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
       
  2199          
       
  2200          /* INTRA DCs */
       
  2201          if (!iColorEffect)
       
  2202          {
       
  2203              vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2204                  dataItemStartByteIndex[4], dataItemStartBitIndex[4],
       
  2205                  dataItemEndByteIndex[4], dataItemEndBitIndex[4]);
       
  2206          }
       
  2207          else
       
  2208          {
       
  2209              if (!(VDT_NO_DATA(dataItemStartByteIndex[4], dataItemStartBitIndex[4],
       
  2210                  dataItemEndByteIndex[4], dataItemEndBitIndex[4])))   
       
  2211              {
       
  2212                  vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2213                      dataItemStartByteIndex[4], dataItemStartBitIndex[4],
       
  2214                      dataItemStartByteIndex[8], dataItemStartBitIndex[8]);
       
  2215                  ResetMPEG4IntraDcUV();
       
  2216              }
       
  2217          }
       
  2218      }
       
  2219      
       
  2220      /* DC marker */
       
  2221      sPutBits(iOutBuffer, DC_MARKER_LENGTH, DC_MARKER);
       
  2222      
       
  2223    for (dlstHead(iMBList, (void **) &MBinstance); 
       
  2224      MBinstance != NULL; 
       
  2225      dlstNext(iMBList, (void **) &MBinstance))
       
  2226       {
       
  2227          dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
       
  2228          dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
       
  2229          dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
       
  2230          dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
       
  2231          
       
  2232          /* ac_pred_flag */
       
  2233          vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2234                    dataItemStartByteIndex[3], dataItemStartBitIndex[3],
       
  2235                      dataItemEndByteIndex[3], dataItemEndBitIndex[3]);
       
  2236          
       
  2237          /* CBPY */
       
  2238          vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2239                    dataItemStartByteIndex[2], dataItemStartBitIndex[2],
       
  2240                      dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
       
  2241       }
       
  2242      
       
  2243       /* make sure the head of the list is reset */
       
  2244       dlstHead(iMBList, (void **) &MBinstance);
       
  2245 }
       
  2246 
       
  2247 /*
       
  2248 * ReconstructPMBPartitions
       
  2249 *
       
  2250 * Parameters: 
       
  2251 *
       
  2252 * Function:
       
  2253 *    Recontruct the partitions for color effect when we are not doing format transcoding
       
  2254 * Returns:
       
  2255 *    None
       
  2256 * Error codes:
       
  2257 *    None
       
  2258 *
       
  2259 */
       
  2260 void CMPEG4Transcoder::ReconstructPMBPartitions()
       
  2261 {
       
  2262     vdxPMBListItem_t *MBinstance;
       
  2263     int *dataItemStartByteIndex;
       
  2264     int *dataItemStartBitIndex;
       
  2265     int *dataItemEndByteIndex;
       
  2266     int *dataItemEndBitIndex;
       
  2267     int newMCBPCLen = 0;
       
  2268     int newMCBPC = 0;
       
  2269      
       
  2270     VDTASSERT(iMBList);
       
  2271      
       
  2272   for (dlstHead(iMBList, (void **) &MBinstance); 
       
  2273     MBinstance != NULL; 
       
  2274     dlstNext(iMBList, (void **) &MBinstance))
       
  2275     {
       
  2276         dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
       
  2277         dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
       
  2278         dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
       
  2279         dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
       
  2280         
       
  2281         /* MB stuffing bits if they exsit */
       
  2282         vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
       
  2283             dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
       
  2284         
       
  2285         if (MBinstance->fCodedMB)
       
  2286         {
       
  2287             /* output  1 bit COD, coded */
       
  2288             sPutBits (iOutBuffer, 1, 0);
       
  2289             
       
  2290             /* MCBPC     */
       
  2291             if (iColorEffect)
       
  2292             {
       
  2293                 /* MCBPC Changed, ignore the return value */
       
  2294                 vdtGetPMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, MBinstance->mcbpc);
       
  2295                 sPutBits(iOutBuffer, newMCBPCLen, newMCBPC);
       
  2296             }
       
  2297             else
       
  2298             {
       
  2299                 vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2300                     dataItemStartByteIndex[0], dataItemStartBitIndex[0],
       
  2301                     dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
       
  2302             }
       
  2303             
       
  2304             /* MVs, if they exist */
       
  2305             vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2306                 dataItemStartByteIndex[10], dataItemStartBitIndex[10],
       
  2307                 dataItemEndByteIndex[10], dataItemEndBitIndex[10]);
       
  2308         }
       
  2309         else
       
  2310         {
       
  2311             /* output  1 bit COD, not coded */
       
  2312             sPutBits (iOutBuffer, 1, 1);
       
  2313         }
       
  2314     }
       
  2315      
       
  2316     /* MM marker */
       
  2317     sPutBits(iOutBuffer, MOTION_MARKER_LENGTH, MOTION_MARKER);
       
  2318      
       
  2319     for (dlstHead(iMBList, (void **) &MBinstance); 
       
  2320     MBinstance != NULL; 
       
  2321     dlstNext(iMBList, (void **) &MBinstance))
       
  2322     {
       
  2323         if (MBinstance->fCodedMB)
       
  2324         {
       
  2325             dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
       
  2326             dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
       
  2327             dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
       
  2328             dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
       
  2329             
       
  2330             /* ac_pred_flag, if it exsits */
       
  2331             vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2332                 dataItemStartByteIndex[3], dataItemStartBitIndex[3],
       
  2333                 dataItemEndByteIndex[3], dataItemEndBitIndex[3]);
       
  2334             
       
  2335             /* CBPY,  */
       
  2336             vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2337                 dataItemStartByteIndex[2], dataItemStartBitIndex[2],
       
  2338                 dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
       
  2339             /* DQUANT, if it exsits */
       
  2340             vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2341                 dataItemStartByteIndex[1], dataItemStartBitIndex[1],
       
  2342                 dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
       
  2343             
       
  2344             /* INTRA DCs, if they exsit */
       
  2345             if (!iColorEffect)
       
  2346             {
       
  2347                 vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2348                     dataItemStartByteIndex[4], dataItemStartBitIndex[4],
       
  2349                     dataItemEndByteIndex[4], dataItemEndBitIndex[4]);
       
  2350             }
       
  2351             else
       
  2352             {
       
  2353                 if (!(VDT_NO_DATA(dataItemStartByteIndex[4], dataItemStartBitIndex[4],
       
  2354                     dataItemEndByteIndex[4], dataItemEndBitIndex[4])))   
       
  2355                 {
       
  2356                     vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  2357                         dataItemStartByteIndex[4], dataItemStartBitIndex[4],
       
  2358                         dataItemStartByteIndex[8], dataItemStartBitIndex[8]);
       
  2359                     ResetMPEG4IntraDcUV();
       
  2360                 }
       
  2361             }
       
  2362         }
       
  2363     }
       
  2364      
       
  2365     /* make sure the head of the list is reset */
       
  2366     dlstHead(iMBList, (void **) &MBinstance);
       
  2367 }
       
  2368 
       
  2369 /*
       
  2370 * ResetMPEG4IntraDcUV
       
  2371 *
       
  2372 * Parameters: 
       
  2373 *
       
  2374 * Function:
       
  2375 *    This function resets the DCc for U V block in INTRA MB.
       
  2376 *    Inputs are valid only with Color Effect
       
  2377 * Returns:
       
  2378 *    None
       
  2379 * Error codes:
       
  2380 *    None
       
  2381 *
       
  2382 */
       
  2383 void CMPEG4Transcoder::ResetMPEG4IntraDcUV()
       
  2384 {
       
  2385     /* set INTRADC for u,v in the output buffer */
       
  2386     TInt sizeU, sizeCodeU, sizeCodeLengthU, valueU, valueCodeU, valueCodeLengthU;
       
  2387     TInt sizeV, sizeCodeV, sizeCodeLengthV, valueV, valueCodeV, valueCodeLengthV;
       
  2388     TInt curDcScaler, delta; 
       
  2389     TReal realDelta, realVal;
       
  2390     TInt mbh, mbv, mbd;  // previous MB in the horizontal, vertical and diagonal directions
       
  2391     TInt codeMB; 
       
  2392     
       
  2393     // initialize for codewords
       
  2394     sizeU = sizeCodeU = sizeCodeLengthU = valueCodeU = valueCodeLengthU = 0;
       
  2395     sizeV = sizeCodeV = sizeCodeLengthV = valueCodeV = valueCodeLengthV = 0;
       
  2396 
       
  2397     // initialize for prediction
       
  2398     mbh = mbv = mbd = VDX_MB_INTER;
       
  2399     codeMB = 0;
       
  2400     
       
  2401     // NOTE: VDX_MB_INTER=1, VDX_MB_INTRA=2, NOT-CODED MB has a value of 0
       
  2402     if (iVopCodingType == VDX_VOP_TYPE_I)
       
  2403     {
       
  2404         /* encode intra DC coefficients for INTRA MBs of I-VOP if 
       
  2405            either of the following is true:
       
  2406             -
       
  2407             -
       
  2408             else, do not encode intra DC
       
  2409            (because rest of MBs have differential intra DC, which is zero)
       
  2410         */
       
  2411         if (!iCurMBNumInVP || 
       
  2412              (!(iCurMBNum%iMBsinWidth) && (iCurMBNumInVP<iMBsinWidth)))
       
  2413         {
       
  2414             codeMB = 1;
       
  2415         }
       
  2416     }
       
  2417     else if (iVopCodingType == VDX_VOP_TYPE_P)
       
  2418     {
       
  2419         if (iCurMBNumInVP>iMBsinWidth)
       
  2420         { 
       
  2421             if (iCurMBNum%iMBsinWidth)
       
  2422             {
       
  2423                 mbh = iMBType[iCurMBNum-1];
       
  2424                 mbd = iMBType[iCurMBNum-iMBsinWidth-1];
       
  2425             }
       
  2426             mbv = iMBType[iCurMBNum-iMBsinWidth];
       
  2427         }        
       
  2428         else if (iCurMBNumInVP==iMBsinWidth)
       
  2429         {
       
  2430             if (iCurMBNum%iMBsinWidth)
       
  2431             {
       
  2432                 mbh = iMBType[iCurMBNum-1];
       
  2433             }
       
  2434             mbv = iMBType[iCurMBNum-iMBsinWidth];
       
  2435         }
       
  2436         else if (iCurMBNumInVP>0)
       
  2437         {
       
  2438             if (iCurMBNum%iMBsinWidth)
       
  2439             {
       
  2440                 mbh = iMBType[iCurMBNum-1];
       
  2441             }
       
  2442         }
       
  2443       
       
  2444         // 
       
  2445         if ((mbh<VDX_MB_INTRA && mbv<VDX_MB_INTRA) ||
       
  2446             (mbd==VDX_MB_INTRA && ((mbh==VDX_MB_INTRA && mbv<VDX_MB_INTRA) || 
       
  2447             (mbh<VDX_MB_INTRA && mbv==VDX_MB_INTRA))))
       
  2448         {
       
  2449             codeMB = 1;
       
  2450         }
       
  2451     }
       
  2452 
       
  2453     if (codeMB)  // if IntraDC need to be coded
       
  2454     {
       
  2455         // color-toned U,V values
       
  2456         valueU = iColorToneU;
       
  2457         valueV = iColorToneV;
       
  2458       
       
  2459         // compensate for different QP than original
       
  2460         if (iCurQuant != iRefQuant)  
       
  2461         {
       
  2462             // calculate change in dc value
       
  2463             curDcScaler = GetMpeg4DcScalerUV(iCurQuant);
       
  2464             realDelta = TReal(iDcScaler-curDcScaler)/TReal(curDcScaler);
       
  2465             if (realDelta != 0.0)
       
  2466             {
       
  2467                 // U
       
  2468                 realVal = realDelta*TReal(valueU);
       
  2469                 delta = TInt(realVal + ((realVal<0) ? (-0.5) : (0.5)));
       
  2470                 valueU += delta;
       
  2471                 // V
       
  2472                 realVal = realDelta*TReal(valueV);
       
  2473                 delta = TInt(realVal + ((realVal<0) ? (-0.5) : (0.5)));
       
  2474                 valueV += delta;
       
  2475             }
       
  2476         }
       
  2477          
       
  2478         // get codewords
       
  2479         GetMPEG4IntraDcCoeffUV(valueU, sizeU, sizeCodeU, sizeCodeLengthU, 
       
  2480         valueCodeU, valueCodeLengthU);
       
  2481         GetMPEG4IntraDcCoeffUV(valueV, sizeV, sizeCodeV, sizeCodeLengthV, 
       
  2482         valueCodeV, valueCodeLengthV);
       
  2483       
       
  2484         // code codewords
       
  2485         // U
       
  2486         sPutBits(iOutBuffer, sizeCodeLengthU, sizeCodeU); // dct_dc_coeff size
       
  2487         if (sizeCodeU != 3) // size=0
       
  2488         {
       
  2489             sPutBits(iOutBuffer, valueCodeLengthU, valueCodeU); // dct_dc_coeff differential
       
  2490             if (valueCodeLengthU>8)
       
  2491                 sPutBits(iOutBuffer, 1, 1); // marker bit
       
  2492         }
       
  2493       
       
  2494         // V
       
  2495         sPutBits(iOutBuffer, sizeCodeLengthV, sizeCodeV); // dct_dc_coeff size
       
  2496         if (sizeCodeV != 3) // size=0
       
  2497         {
       
  2498             sPutBits(iOutBuffer, valueCodeLengthV, valueCodeV); // dct_dc_coeff differential
       
  2499             if (valueCodeLengthV>8)
       
  2500                 sPutBits(iOutBuffer, 1, 1); // marker bit
       
  2501         }
       
  2502     }    
       
  2503     else
       
  2504     {        
       
  2505         sPutBits (iOutBuffer, 2, 3); /* U */
       
  2506         sPutBits (iOutBuffer, 2, 3); /* V */
       
  2507     }
       
  2508 }
       
  2509 
       
  2510 
       
  2511 /*
       
  2512 * GetMPEG4IntraDcCoeffUV
       
  2513 *
       
  2514 * Parameters: 
       
  2515 *     aValue   coefficient value
       
  2516 *     aDCAC    pointer the reconstructed coefficients
       
  2517 * Function:
       
  2518 *    This function fills the reconstructed DCAC values for INTRA block.
       
  2519 *    Inputs are valid only with Color Effect
       
  2520 * Returns:
       
  2521 *    None
       
  2522 * Error codes:
       
  2523 *    None
       
  2524 *
       
  2525 */
       
  2526 void CMPEG4Transcoder::GetMPEG4IntraDcCoeffUV(TInt aValue, TInt& aSize, 
       
  2527   TInt& aSizeCode, TInt& aSizeCodeLength, TInt& aValueCode, TInt& aValueCodeLength)
       
  2528 {
       
  2529     int absVal = (aValue>=0 ? aValue : -aValue);
       
  2530     // size of aValueCode
       
  2531     for (aSize=0; absVal|0; absVal>>=1, aSize++) ;
       
  2532     if (aSize)
       
  2533     {
       
  2534         // codeword for aSize
       
  2535         if (aSize==1)
       
  2536         {
       
  2537             aSizeCode = 2;
       
  2538             aSizeCodeLength = 2;
       
  2539         }
       
  2540         else
       
  2541         {
       
  2542             aSizeCode = 1;
       
  2543             aSizeCodeLength = aSize;
       
  2544         }
       
  2545     
       
  2546         // codeword for aValue
       
  2547         aValueCode = aValue;
       
  2548         if (aValue<0)
       
  2549             aValueCode += ((1<<aSize)-1);
       
  2550         aValueCodeLength = aSize;
       
  2551     }
       
  2552     else 
       
  2553     {
       
  2554         // codeword for aSize
       
  2555         aSizeCode = 3;        // codeword for size=0
       
  2556         aSizeCodeLength = 2;
       
  2557         // no codeword for aValue
       
  2558         aValueCode = aValueCodeLength = 0;
       
  2559     }
       
  2560 }
       
  2561 
       
  2562 
       
  2563 /*
       
  2564 * AddOneBlockDCACrecon
       
  2565 *
       
  2566 * Parameters: 
       
  2567 *     aIndex   block index
       
  2568 *     aDCAC    pointer the reconstructed coefficients
       
  2569 * Function:
       
  2570 *    This function fills the reconstructed DCAC values for INTRA block.
       
  2571 *    Inputs are valid only with Color Effect
       
  2572 * Returns:
       
  2573 *    None
       
  2574 * Error codes:
       
  2575 *    None
       
  2576 *
       
  2577 */
       
  2578 void CMPEG4Transcoder::AddOneBlockDCACrecon(int aIndex, int *aDCAC)
       
  2579 {
       
  2580     VDTASSERT(aIndex >= 0 && aIndex < 6); 
       
  2581     
       
  2582     if (aDCAC && iDoModeTranscoding && (iTargetFormat == EVedVideoTypeH263Profile0Level10 ||
       
  2583                                         iTargetFormat == EVedVideoTypeH263Profile0Level45))
       
  2584     {
       
  2585       /* we only need the reconstructed DCACs for MPEG4 -> H263 */
       
  2586       /* It is a coded block    */
       
  2587       memcpy(iDCTBlockData + (aIndex << 6), aDCAC, sizeof(int) * BLOCK_COEFF_SIZE);
       
  2588     }
       
  2589 }
       
  2590 
       
  2591 /*
       
  2592 * ConstructH263MBData
       
  2593 *
       
  2594 * Parameters: 
       
  2595 *     aNewMCBPCLen     new length of mcbpc
       
  2596 *     aNewMCBPC        new mcbpc
       
  2597 * Function:
       
  2598 *    This function creates a new H263 MB
       
  2599 *    Inputs are valid only with Color Effect
       
  2600 * Returns:
       
  2601 *    VDC error codes
       
  2602 *
       
  2603 */
       
  2604 int CMPEG4Transcoder::ConstructH263MBData(dmdPParam_t *aParam, int /*aNewMCBPCLen*/, int /*aNewMCBPC*/)
       
  2605 {
       
  2606     /* MB data part1: output MCBPC, CBPY, DQuant, MV, intra DC etc */
       
  2607     int *dataItemStartByteIndex;
       
  2608     int *dataItemStartBitIndex;
       
  2609     int *dataItemEndByteIndex;
       
  2610     int *dataItemEndBitIndex;
       
  2611     int quant, dquant;
       
  2612     int codedBlockPattern = 0;
       
  2613     
       
  2614     const unsigned int sDquant[5] = 
       
  2615     {
       
  2616         1, 0, (unsigned int)65536, 2, 3
       
  2617     };
       
  2618     
       
  2619   if (iVopCodingType == VDX_VOP_TYPE_P) 
       
  2620     {
       
  2621         dataItemStartByteIndex = iCurPMBinstance->DataItemStartByteIndex;
       
  2622         dataItemStartBitIndex  = iCurPMBinstance->DataItemStartBitIndex;
       
  2623         dataItemEndByteIndex   = iCurPMBinstance->DataItemEndByteIndex;
       
  2624         dataItemEndBitIndex    = iCurPMBinstance->DataItemEndBitIndex;
       
  2625         quant = iCurPMBinstance->quant;
       
  2626         dquant = iCurPMBinstance->dquant;
       
  2627     }
       
  2628     else
       
  2629     {
       
  2630         dataItemStartByteIndex = iCurIMBinstance->DataItemStartByteIndex;
       
  2631         dataItemStartBitIndex  = iCurIMBinstance->DataItemStartBitIndex;
       
  2632         dataItemEndByteIndex   = iCurIMBinstance->DataItemEndByteIndex;
       
  2633         dataItemEndBitIndex    = iCurIMBinstance->DataItemEndBitIndex;
       
  2634         quant = iCurIMBinstance->quant;
       
  2635         dquant = iCurIMBinstance->dquant;
       
  2636     }
       
  2637     
       
  2638     if (iPreQuant != quant - dquant)
       
  2639     {
       
  2640         /* last quant in MPEG4 and H263 is different, dquant and VLCs may not be reused */
       
  2641         if (abs(quant - iPreQuant) > 2)
       
  2642         {
       
  2643             /* VLCs cannot be reused, obtain the new ones */
       
  2644             sQuantizeMB(iDCTBlockData, quant, iPreQuant, 
       
  2645                 iMBCodingType, iColorEffect);
       
  2646             quant = iPreQuant;
       
  2647             dquant = 0;
       
  2648         }
       
  2649         else
       
  2650         {
       
  2651             /* VLCs can be reused, but need to change dquant and MCBPC */
       
  2652             dquant = quant - iPreQuant;
       
  2653         }
       
  2654     }
       
  2655     
       
  2656     /* MB stuffing bits if they exsit */
       
  2657     vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
       
  2658         dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
       
  2659     
       
  2660     if (iMBCodingType == VDX_MB_INTER) 
       
  2661     {
       
  2662         VDTASSERT(aParam);
       
  2663         tMBPosition mbPos;
       
  2664         tMotionVector mvTestOutside;
       
  2665         mbPos.x = aParam->xPosInMBs * 16; 
       
  2666         mbPos.y = aParam->yPosInMBs * 16;
       
  2667         mbPos.LeftBound = 0;
       
  2668         mbPos.RightBound = iVDEInstance->lumWidth << 1;
       
  2669         mbPos.TopBound = 0;
       
  2670         mbPos.BottomBound = iVDEInstance->lumHeight << 1;
       
  2671         mvTestOutside.mvx = (int16) ((aParam->mvx[0] << 1) / 10);
       
  2672         mvTestOutside.mvy = (int16) ((aParam->mvy[0] << 1) / 10);
       
  2673         
       
  2674         /* Three cases for MVs. 1): 4MVs -> need mapping 2). 1 outside frame MV 3) rounding type = 1 */
       
  2675         vdcInstance_t * vdcTemp = (vdcInstance_t *)(iVDEInstance->vdcHInstance);
       
  2676         
       
  2677         /* Two cases for MVs. 1): 4MVs -> need mapping 2). 1 outside frame MV */
       
  2678         if (iCurPMBinstance->numMVs == 4 || (iCurPMBinstance->numMVs == 1 && 
       
  2679             vbmMVOutsideBound(&mbPos, &mvTestOutside, 1)) || vdcTemp->pictureParam.rtype)
       
  2680         {
       
  2681             int32 numTextureBits;
       
  2682             int32 searchRange = 16;
       
  2683             tMotionVector   *initPred; 
       
  2684             (h263mbi+iCurMBNum)->QuantScale = (int16) quant;
       
  2685             (h263mbi+iCurMBNum)->dQuant = (int16) dquant;
       
  2686             
       
  2687             /* note: this buffer is also used in the diamond search and half-pixel search !!!!! 
       
  2688                which needs at least 8 points
       
  2689             */
       
  2690             initPred = (tMotionVector*) malloc(8 * sizeof (tMotionVector));
       
  2691             if(!initPred)
       
  2692             {
       
  2693                 //Memory not available 
       
  2694                 return TX_ERR;
       
  2695             }
       
  2696 
       
  2697                         
       
  2698             for (int i = 0; i < iCurPMBinstance->numMVs ; i++)
       
  2699             {
       
  2700                 (initPred + i)->mvx = (int16) (aParam->mvx[i] / 10); /* the recorded mv is multipied by 10, */
       
  2701                 (initPred + i)->mvy = (int16) (aParam->mvy[i] / 10); /* the recorded mv is multipied by 10, */
       
  2702             }
       
  2703             int32 noOfPredictors = iCurPMBinstance->numMVs;
       
  2704             
       
  2705             /* perform the 4MVs -> 1MV mapping, and output this MB */
       
  2706             vbmPutInterMB(&mbPos,
       
  2707                 iOutBuffer,aParam,
       
  2708                 initPred, noOfPredictors,
       
  2709                 (u_int32) iVDEInstance->lumWidth, (u_int32) iVDEInstance->lumHeight,
       
  2710                 searchRange, iCurMBNum, &numTextureBits, 
       
  2711                 (int16)iColorEffect, h263mbi);
       
  2712             /*  the MVs buffer is updated inside vbmPutInterMB */
       
  2713             
       
  2714             if (initPred)
       
  2715                 free(initPred);
       
  2716         }
       
  2717         else
       
  2718         {
       
  2719             /* Here, for Inter MB with One inside Frame MV, we simply reuse the DCTs */
       
  2720             VDTASSERT(iCurPMBinstance->numMVs == 1);
       
  2721             
       
  2722             /* It is a coded MB, output 1 bit COD (it always exists in P frame) */
       
  2723             sPutBits (iOutBuffer, 1, 0);
       
  2724             int         cbpy;
       
  2725             int         mcbpcVal;
       
  2726             int         len;
       
  2727             
       
  2728             codedBlockPattern = sFindCBP(iDCTBlockData, OFF);
       
  2729             mcbpcVal = iColorEffect? 0 : (codedBlockPattern & 3);
       
  2730             cbpy = ((codedBlockPattern >> 2) & 0xf);
       
  2731             vbmGetH263PMCBPC(dquant, iColorEffect, cbpy, mcbpcVal, len);
       
  2732             sPutBits(iOutBuffer, len, mcbpcVal); //MCBPC, CBPY
       
  2733             
       
  2734             /* DQUANT, if it exsits */
       
  2735             if (dquant)
       
  2736             {
       
  2737                 sPutBits(iOutBuffer, 2, sDquant[dquant + 2]);
       
  2738             }
       
  2739             /* recode MVs, one more indice exists in the MV VLC table in MPEG4
       
  2740                moreover, vop_fcode can be larger than 1 (although it may rarely happens), 
       
  2741                  so it is better to redo the VLC coding
       
  2742       */
       
  2743             /* the recorded mv is multipied by 10, in pixel unit */
       
  2744             int16 mvx = (int16) ((aParam->mvx[0] << 1) / 10); 
       
  2745             int16 mvy = (int16) ((aParam->mvy[0] << 1) / 10);
       
  2746             
       
  2747             tMotionVector   lPredMV[4];
       
  2748             tMBInfo *mbi = h263mbi + iCurMBNum;
       
  2749             
       
  2750             /* get the new predicted MV */
       
  2751             vbmMvPrediction(mbi, iCurMBNum, lPredMV, (u_int32)iMBsinWidth);
       
  2752             
       
  2753             vbmEncodeMVDifferential(mvx - lPredMV[0].mvx, mvy - lPredMV[0].mvy, 1, iOutBuffer);
       
  2754             cbpy = 32;
       
  2755             /* following is the block level data */
       
  2756             for (int i = 0; i < (iColorEffect? 4 : 6); i++)
       
  2757             {
       
  2758                 int fBlockCoded = cbpy & codedBlockPattern;
       
  2759                 if (fBlockCoded)
       
  2760                 {
       
  2761                     /* here we do the VLC coding again */ 
       
  2762                     int numTextureBits = 0;
       
  2763                     vdtPutInterMBCMT(iOutBuffer,0, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, ON);
       
  2764                 }
       
  2765                 cbpy >>= 1;
       
  2766             } 
       
  2767             
       
  2768             /* update the MVs buffer */
       
  2769             (h263mbi + iCurMBNum)->MV[0][0] = (int16) ((aParam->mvx[0] << 1) / 10); /* the recorded mv is multipied by 10 */
       
  2770             (h263mbi + iCurMBNum)->MV[0][1] = (int16) ((aParam->mvy[0] << 1) / 10); /* the recorded mv is multipied by 10 */
       
  2771             
       
  2772         }  /* end of if 4MVs */
       
  2773     }
       
  2774     else /* INTRA MB */
       
  2775     {
       
  2776         /* update the MVs buffer */
       
  2777         (h263mbi + iCurMBNum)->MV[0][0] = 0;
       
  2778         (h263mbi + iCurMBNum)->MV[0][1] = 0;
       
  2779         /* MPEG4 and H263 use different methods for INTRA MB, redo the VLC coding */
       
  2780         int         cbpy;
       
  2781         int         mcbpcVal;
       
  2782         int         len;
       
  2783         
       
  2784         codedBlockPattern = sFindCBP(iDCTBlockData, ON);
       
  2785         mcbpcVal = iColorEffect? 0 : (codedBlockPattern & 3);
       
  2786         cbpy = ((codedBlockPattern >> 2) & 0xf);
       
  2787         vbmGetH263IMCBPC(dquant, (iVopCodingType == VDX_VOP_TYPE_P), iColorEffect, cbpy, mcbpcVal, len);
       
  2788         sPutBits(iOutBuffer, len, mcbpcVal); //COD, MCBPC, CBPY
       
  2789         
       
  2790         /* DQUANT, if it exsits */
       
  2791         if (dquant)
       
  2792         {
       
  2793             sPutBits(iOutBuffer, 2, sDquant[dquant + 2]);
       
  2794         }
       
  2795         cbpy = 32;
       
  2796         
       
  2797         /* following is the block level data */
       
  2798         for (int i = 0; i < (iColorEffect? 4 : 6); i++)
       
  2799         {
       
  2800             /* requantize INTRA DC */
       
  2801             /* DC Quantization */
       
  2802             int coeff = (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0] >> 3;
       
  2803             
       
  2804             if(coeff < 1) coeff = 1;
       
  2805             if(coeff > 254) coeff = 254;
       
  2806             if(coeff == 128)
       
  2807             {
       
  2808                 sPutBits(iOutBuffer, 8, 255);
       
  2809             }
       
  2810             else
       
  2811             {
       
  2812                 sPutBits(iOutBuffer, 8, coeff);
       
  2813             }
       
  2814             
       
  2815             (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0] = coeff;
       
  2816             if(cbpy & codedBlockPattern)
       
  2817             {
       
  2818                 int numTextureBits = 0;
       
  2819                 vdtPutInterMBCMT(iOutBuffer,1, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, ON);
       
  2820             }
       
  2821             cbpy >>= 1;
       
  2822         }
       
  2823     }
       
  2824     
       
  2825   if (iColorEffect && (iMBCodingType == VDX_MB_INTRA))
       
  2826     {
       
  2827         ResetH263IntraDcUV(iOutBuffer, iColorToneU, iColorToneV);        
       
  2828     }
       
  2829   iPreQuant = quant;
       
  2830   
       
  2831   return TX_OK;
       
  2832 }
       
  2833 
       
  2834 /*
       
  2835 * ConstructRegularMPEG4MBData
       
  2836 *
       
  2837 * Parameters: 
       
  2838 *     aNewMCBPCLen     new length of mcbpc
       
  2839 *     aNewMCBPC        new mcbpc
       
  2840 * Function:
       
  2841 *    This function rearranges the data for bitstream with data partitioning
       
  2842 *    Only valid in Data Partitioned mode
       
  2843 *    Inputs are valid only with Color Effect
       
  2844 * Returns:
       
  2845 *    None
       
  2846 * Error codes:
       
  2847 *    None
       
  2848 *
       
  2849 */
       
  2850 void CMPEG4Transcoder::ConstructRegularMPEG4MBData(int aNewMCBPCLen, int aNewMCBPC)
       
  2851 {
       
  2852   /* MB data part1: output MCBPC, CBPY, DQuant, MV, intra DC etc */
       
  2853     int *dataItemStartByteIndex;
       
  2854     int *dataItemStartBitIndex;
       
  2855     int *dataItemEndByteIndex;
       
  2856     int *dataItemEndBitIndex;
       
  2857     
       
  2858     if (iVopCodingType == VDX_VOP_TYPE_P) 
       
  2859     {
       
  2860         dataItemStartByteIndex = iCurPMBinstance->DataItemStartByteIndex;
       
  2861         dataItemStartBitIndex  = iCurPMBinstance->DataItemStartBitIndex;
       
  2862         dataItemEndByteIndex   = iCurPMBinstance->DataItemEndByteIndex;
       
  2863         dataItemEndBitIndex    = iCurPMBinstance->DataItemEndBitIndex;
       
  2864     }
       
  2865     else
       
  2866     {
       
  2867         dataItemStartByteIndex = iCurIMBinstance->DataItemStartByteIndex;
       
  2868         dataItemStartBitIndex  = iCurIMBinstance->DataItemStartBitIndex;
       
  2869         dataItemEndByteIndex   = iCurIMBinstance->DataItemEndByteIndex;
       
  2870         dataItemEndBitIndex    = iCurIMBinstance->DataItemEndBitIndex;
       
  2871     }
       
  2872     
       
  2873     /* MB stuffing bits if they exsit */
       
  2874     vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
       
  2875         dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
       
  2876     
       
  2877     if (iVopCodingType == VDX_VOP_TYPE_P)
       
  2878     {
       
  2879         /* It is a coded MB, output  1 bit COD (it always exists in P frame) */
       
  2880         sPutBits (iOutBuffer, 1, 0);
       
  2881     }
       
  2882     
       
  2883     /* MCBPC. NOTE: the positions do not include MCBPC stuffing bits !! */
       
  2884     if (iColorEffect)
       
  2885     {
       
  2886         /* MCBPC Changed */
       
  2887         sPutBits(iOutBuffer, aNewMCBPCLen, aNewMCBPC);
       
  2888     }
       
  2889     else
       
  2890     {
       
  2891         vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[0], dataItemStartBitIndex[0],
       
  2892             dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
       
  2893     }
       
  2894     /* ac_pred_flag, if it exsits */
       
  2895     vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[3], dataItemStartBitIndex[3],
       
  2896         dataItemEndByteIndex[3], dataItemEndBitIndex[3]);
       
  2897     
       
  2898     /* CBPY */
       
  2899     vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[2], dataItemStartBitIndex[2],
       
  2900         dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
       
  2901     
       
  2902     /* DQUANT, if it exsits */
       
  2903     vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[1], dataItemStartBitIndex[1],
       
  2904         dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
       
  2905     
       
  2906     if (iMBCodingType == VDX_MB_INTER) 
       
  2907     {
       
  2908         /* MVs, if they exsit */
       
  2909         vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[10], dataItemStartBitIndex[10],
       
  2910             dataItemEndByteIndex[10], dataItemEndBitIndex[10]);
       
  2911     }
       
  2912     
       
  2913     /* following is the block level data */
       
  2914     for (int i = 0; i < (iColorEffect? 4 : 6); i++)
       
  2915     {
       
  2916         /* INTRA DC, if it exsits */
       
  2917         vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[i + 4], dataItemStartBitIndex[i + 4],
       
  2918             dataItemEndByteIndex[i + 4], dataItemEndBitIndex[i + 4]);
       
  2919         
       
  2920         /* block data part2, AC or DCT coefficients */
       
  2921         if (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC)
       
  2922         {
       
  2923         /* remember for data partitioning, the positions only indicate the  
       
  2924         AC or DCTs coefficients
       
  2925             */
       
  2926             if (VDT_NO_DATA(iBlockStartByteIndex[i], iBlockStartBitIndex[i],
       
  2927                 iBlockEndByteIndex[i], iBlockEndBitIndex[i]))  
       
  2928             {
       
  2929                 /* no coefficients,skip this block */
       
  2930                 continue;
       
  2931             }
       
  2932             else
       
  2933             {
       
  2934                 /* for RVLC coding, we transform the block data back to VLC */
       
  2935                 int numTextureBits = 0;
       
  2936                 /* redo the entropy coding, RVLC -> VLC 
       
  2937                 only for AC (IMB) or DCT (PMB) coefficients
       
  2938                 */
       
  2939                 if (iMBCodingType == VDX_MB_INTRA)
       
  2940                 {
       
  2941                     vdtPutIntraMBCMT(iOutBuffer,iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, i, 1, 0);
       
  2942                 }
       
  2943                 else
       
  2944                 {
       
  2945                     vdtPutInterMBCMT(iOutBuffer,0, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, OFF);
       
  2946                 }
       
  2947             }
       
  2948         }
       
  2949         else /* ouput the AC or DCT coefficients */
       
  2950         {
       
  2951             bufEdit.copyMode = CopyWhole; /* CopyWhole */
       
  2952             vdtCopyBuffer(iInBuffer,iOutBuffer,
       
  2953                 iBlockStartByteIndex[i],iBlockStartBitIndex[i],
       
  2954                 iBlockEndByteIndex[i],iBlockEndBitIndex[i]);
       
  2955         }
       
  2956     }
       
  2957   if (iColorEffect && (iMBCodingType == VDX_MB_INTRA))
       
  2958     {
       
  2959         ResetMPEG4IntraDcUV();
       
  2960     }
       
  2961 }
       
  2962 
       
  2963 
       
  2964 
       
  2965 /*
       
  2966 * AddOneBlockDataToMB
       
  2967 *
       
  2968 * Parameters: 
       
  2969 *     blockData        block data before VLC coding, in ZigZag order
       
  2970 * Function:
       
  2971 *    This function input one block data to current MB
       
  2972 *    only here the whole MB data is retrieved (COD=0)
       
  2973 * Returns:
       
  2974 *    None
       
  2975 * Error codes:
       
  2976 *    None
       
  2977 *
       
  2978 */
       
  2979 void CMPEG4Transcoder::AddOneBlockDataToMB(int aBlockIndex, int *aBlockData)
       
  2980 {
       
  2981     VDTASSERT(aBlockIndex >= 0 && aBlockIndex < 6); 
       
  2982     
       
  2983     
       
  2984     if (aBlockData && iDoModeTranscoding)
       
  2985     {
       
  2986       /* iDCTBlockData is only used when we need to convert the bitstream to MPEG4_RESYN
       
  2987       It is a coded block   
       
  2988         */
       
  2989       if (iMBCodingType == VDX_MB_INTRA && (iTargetFormat == EVedVideoTypeH263Profile0Level10 ||
       
  2990                                             iTargetFormat == EVedVideoTypeH263Profile0Level45))
       
  2991         {
       
  2992           /* we only need the reconstructed DCACs, skipped */
       
  2993         }
       
  2994         else
       
  2995         {
       
  2996           memcpy(iDCTBlockData + (aBlockIndex << 6), aBlockData, sizeof(int) * BLOCK_COEFF_SIZE);
       
  2997         }
       
  2998     }
       
  2999     else 
       
  3000     {
       
  3001       memset(iDCTBlockData + (aBlockIndex << 6), 0, sizeof(int) * BLOCK_COEFF_SIZE);
       
  3002     }
       
  3003     
       
  3004 
       
  3005     
       
  3006     iBlockEndByteIndex[aBlockIndex] = iInBuffer->getIndex;
       
  3007     iBlockEndBitIndex[aBlockIndex] = iInBuffer->bitIndex;
       
  3008 }
       
  3009 
       
  3010 /*
       
  3011 * ErrorResilienceInfo
       
  3012 *
       
  3013 * Parameters: 
       
  3014 *     header        VOL Header data
       
  3015 * Function:
       
  3016 *    This function records the position of resnc_marker_disable bit
       
  3017 * Returns:
       
  3018 *    None
       
  3019 * Error codes:
       
  3020 *    None
       
  3021 *
       
  3022 */
       
  3023 void CMPEG4Transcoder::ErrorResilienceInfo(vdxVolHeader_t *header, int aByte, int aBit)
       
  3024 {
       
  3025     if (header)
       
  3026     {
       
  3027                 
       
  3028         memcpy(&iVOLHeader, header, sizeof(vdxVolHeader_t));  // save the header info
       
  3029 
       
  3030     }
       
  3031     else
       
  3032     {
       
  3033         iErrorResilienceStartByteIndex = aByte;  /* save the bits position */
       
  3034         iErrorResilienceStartBitIndex  = aBit;
       
  3035     }
       
  3036 }
       
  3037 
       
  3038 
       
  3039 
       
  3040 /*
       
  3041 * MPEG4TimerResolution
       
  3042 *
       
  3043 * Parameters: 
       
  3044 *     
       
  3045 * Function:
       
  3046 *    This function records the position of vop_time_increment_resolution bit
       
  3047 * Returns:
       
  3048 *    None
       
  3049 * Error codes:
       
  3050 *    None
       
  3051 *
       
  3052 */
       
  3053 void CMPEG4Transcoder::MPEG4TimerResolution(int aStartByteIndex, int aStartBitIndex)
       
  3054 {
       
  3055     iTimeResolutionByteIndex = aStartByteIndex;
       
  3056     iTimeResolutionBitIndex  = aStartBitIndex;
       
  3057 }
       
  3058 
       
  3059 
       
  3060 
       
  3061 void CMPEG4Transcoder::ConstructVOSHeader(int aMPEG4, vdeDecodeParamters_t *aDecoderInfo)
       
  3062 {
       
  3063   if (!aMPEG4 )
       
  3064   {
       
  3065     /* for H263 and MPEG4 shortheader, no vos generated */
       
  3066     if (iErrorResilienceStartByteIndex == KDataNotValid && 
       
  3067       iErrorResilienceStartBitIndex == KDataNotValid)
       
  3068     {
       
  3069       iBitStreamMode = EVedVideoBitstreamModeH263; // pure H.263
       
  3070       aDecoderInfo->vosHeaderSize = aDecoderInfo->fModeChanged? KH263ToMpeg4VosSize : 0; 
       
  3071     }
       
  3072     else
       
  3073     {
       
  3074       /* we went into the VOL layer. It is a MPEG4 bitstream with short header */
       
  3075       iBitStreamMode = EVedVideoBitstreamModeMPEG4ShortHeader; /* MPEG4 shortheader */
       
  3076       iShortHeaderEndByteIndex = iInBuffer->getIndex;
       
  3077       iShortHeaderEndBitIndex  = iInBuffer->bitIndex;
       
  3078       aDecoderInfo->vosHeaderSize = aDecoderInfo->fModeChanged? KH263ToMpeg4VosSize : KShortHeaderMpeg4VosSize; 
       
  3079     }
       
  3080     fFirstFrameInH263 = ETrue;
       
  3081   }
       
  3082   else 
       
  3083   {
       
  3084     iNumMBsInOneVOP = (iVDEInstance->lumHeight * iVDEInstance->lumWidth) / 256;
       
  3085     
       
  3086     /* even iBitStreamMode is given outside, we renew it here anyway */
       
  3087     iBitStreamMode = sGetMPEG4Mode(iVOLHeader.error_res_disable,
       
  3088       iVOLHeader.data_partitioned, iVOLHeader.reversible_vlc);
       
  3089     
       
  3090     if (iTargetFormat != EVedVideoTypeH263Profile0Level10 &&
       
  3091       iTargetFormat != EVedVideoTypeH263Profile0Level45) /* EVedVideoTypeMPEG4SimpleProfile or None */
       
  3092     {
       
  3093       /* copy from the begining of the input buffer */
       
  3094       vdtCopyBuffer(iInBuffer,iOutBuffer,0,7, iTimeResolutionByteIndex, iTimeResolutionBitIndex); 
       
  3095       /* it is 16 bits */
       
  3096       sPutBits (iOutBuffer, KMpeg4VopTimeIncrementResolutionLength, *aDecoderInfo->aMPEG4TargetTimeResolution); 
       
  3097       
       
  3098       int startByteIndex, startBitIndex;
       
  3099       startByteIndex = iTimeResolutionByteIndex + 2;
       
  3100       startBitIndex  = iTimeResolutionBitIndex;
       
  3101       
       
  3102       sPutBits(iOutBuffer, 1, MARKER_BIT);
       
  3103       /* close fixed_vop_rate */
       
  3104       sPutBits (iOutBuffer, 1, 0); /* it is 1 bit */
       
  3105       
       
  3106       int num_bits = 0;
       
  3107       vdcInstance_t * vdcTemp = (vdcInstance_t *)(iVDEInstance->vdcHInstance);
       
  3108       if (vdcTemp->pictureParam.fixed_vop_rate)
       
  3109       {
       
  3110         for (num_bits = 1; ((vdcTemp->pictureParam.time_increment_resolution-1) >> num_bits) != 0; num_bits++)
       
  3111             {
       
  3112             }
       
  3113       }
       
  3114       num_bits += 2;
       
  3115       
       
  3116       /* following is to skip the fixed_vop_rate */
       
  3117       int bitsRemain, bitShift = 0;
       
  3118       int bitsToMove = 0 ;
       
  3119       /* complete the byte */
       
  3120       if (startBitIndex != 7)
       
  3121       {
       
  3122         bitShift = startBitIndex + 1;
       
  3123         bitsToMove = (num_bits < bitShift) ? num_bits : bitShift; 
       
  3124         /* update statistics to take care of bit addition or byte completion  */
       
  3125         if (num_bits < bitShift)
       
  3126         {
       
  3127           /* bits skipped but byte not completed */
       
  3128           startBitIndex -= bitsToMove;
       
  3129         }
       
  3130         else
       
  3131         {
       
  3132           /* byte completed */
       
  3133           startByteIndex ++;
       
  3134           startBitIndex = 7;
       
  3135         }
       
  3136       }
       
  3137       /* full bytes to skip */
       
  3138       startByteIndex += ((num_bits - bitsToMove) >> 3);
       
  3139       bitsRemain = (num_bits - bitsToMove) % 8;
       
  3140       
       
  3141       /* the remaining bits */
       
  3142       startBitIndex = ( bitsRemain != 0) ? 7 - bitsRemain : startBitIndex;
       
  3143 
       
  3144       
       
  3145       /* check if we have user data in the end of VOL; it cannot be copied as such but needs to be byte aligned */
       
  3146       /* first need to rewind the input buffer to be able to seek in it */
       
  3147       int16 error = 0;
       
  3148       int curByteIndex = iInBuffer->getIndex;
       
  3149       int curBitIndex = iInBuffer->bitIndex;
       
  3150       int bits = ((curByteIndex - iTimeResolutionByteIndex)<<3) + (7-curBitIndex);
       
  3151       bibRewindBits(bits, iInBuffer, &error);
       
  3152       int sncCode = sncSeekMPEGStartCode(iInBuffer, 
       
  3153           vdcTemp->pictureParam.fcode_forward, 1 /* don't check VOPs */, 1 /* check for user data*/, &error);
       
  3154         
       
  3155       /* record next resync position */
       
  3156       int resyncByteIndex = iInBuffer->getIndex;
       
  3157         
       
  3158       int stuffBits = 0;
       
  3159       int userDataExists = 0;
       
  3160       if ( sncCode == SNC_USERDATA )
       
  3161       {
       
  3162         /* copy only until this sync code, and copy the rest separately in the end. */
       
  3163         userDataExists = 1;
       
  3164       }
       
  3165       else
       
  3166       {
       
  3167         /* No UD */
       
  3168         /* restore the original pointers in iInBuffer */
       
  3169         iInBuffer->getIndex = curByteIndex;
       
  3170         iInBuffer->bitIndex = curBitIndex;
       
  3171       }
       
  3172       
       
  3173       if (iDoModeTranscoding || aDecoderInfo->fHaveDifferentModes)
       
  3174       {
       
  3175         /* close the error resilience tools, change the bitstream to regular MPEG4 with resyn marker */
       
  3176         int numBits = iVOLHeader.data_partitioned ? 3 : 2;
       
  3177         
       
  3178         bufEdit.copyMode = CopyWithEdit; 
       
  3179         bufEdit.editParams[0].StartByteIndex = iErrorResilienceStartByteIndex; 
       
  3180         bufEdit.editParams[0].StartBitIndex = iErrorResilienceStartBitIndex; 
       
  3181         bufEdit.editParams[0].curNumBits = numBits; 
       
  3182         bufEdit.editParams[0].newNumBits = 2;  
       
  3183         bufEdit.editParams[0].newValue = 0;  /* new codeword: resyn, no dp, no rvlc */
       
  3184         CopyStream(iInBuffer,iOutBuffer,&bufEdit, startByteIndex,startBitIndex); /* copy from vop_time_increment_resolution */
       
  3185 
       
  3186         /* rewind stuffing bits */
       
  3187         int16 error;
       
  3188         sncRewindStuffing(iOutBuffer, &error);        
       
  3189 
       
  3190         // stuff bits in outbuffer for next start code   
       
  3191         vdtStuffBitsMPEG4(iOutBuffer);
       
  3192       }
       
  3193       else
       
  3194       {
       
  3195       
       
  3196         /* rewind stuffing bits */
       
  3197         sncRewindStuffing(iInBuffer, &error);        
       
  3198         
       
  3199         /* record the number of bits rewinded - can be from 0 to 8 */
       
  3200         /* note that iInBuffer must be byte aligned before rewinding */
       
  3201         if (iInBuffer->bitIndex == 7) // full byte rewind
       
  3202         { 
       
  3203           stuffBits = ( (int)(iInBuffer->getIndex) < resyncByteIndex) ? 8 : 0;
       
  3204         }
       
  3205         else 
       
  3206         {
       
  3207           stuffBits = iInBuffer->bitIndex + 1;
       
  3208         }
       
  3209           
       
  3210         /* copy the rest of VOS until the first VOP (or UD) */
       
  3211         bufEdit.copyMode = CopyWhole; 
       
  3212         vdtCopyBuffer(iInBuffer,iOutBuffer, startByteIndex,startBitIndex,
       
  3213           resyncByteIndex, iInBuffer->bitIndex); 
       
  3214         
       
  3215         // stuff bits in outbuffer for next start code   
       
  3216         vdtStuffBitsMPEG4(iOutBuffer);
       
  3217         
       
  3218         // move inbuffer pointer back to original value
       
  3219         bibForwardBits(stuffBits, iInBuffer);
       
  3220       }
       
  3221       
       
  3222       
       
  3223       if ( userDataExists )
       
  3224       {
       
  3225         /* seek for VOP start code */
       
  3226         int sncCode = sncSeekMPEGStartCode(iInBuffer, 
       
  3227           vdcTemp->pictureParam.fcode_forward, vdcTemp->pictureParam.error_res_disable, 0, &error);
       
  3228         
       
  3229         /* rewind stuffing bits */
       
  3230         sncRewindStuffing(iInBuffer, &error);        
       
  3231         
       
  3232         // record the number of bits rewinded - can be from 0 to 8
       
  3233         // note that iInBuffer must be byte aligned before rewinding
       
  3234         if (iInBuffer->bitIndex == 7) // full byte rewind
       
  3235         { 
       
  3236           stuffBits = ( (int)(iInBuffer->getIndex) < resyncByteIndex) ? 8 : 0;
       
  3237         }
       
  3238         else 
       
  3239         {
       
  3240           stuffBits = iInBuffer->bitIndex + 1;
       
  3241         }
       
  3242         
       
  3243         bufEdit.copyMode = CopyWhole; 
       
  3244         vdtCopyBuffer(iInBuffer,iOutBuffer, resyncByteIndex, 7,
       
  3245           iInBuffer->getIndex, iInBuffer->bitIndex); 
       
  3246         
       
  3247         // stuff bits in outbuffer for next start code   
       
  3248         vdtStuffBitsMPEG4(iOutBuffer);
       
  3249         
       
  3250         // move inbuffer pointer back to original value
       
  3251         bibForwardBits(stuffBits, iInBuffer);
       
  3252         
       
  3253         
       
  3254         
       
  3255       }
       
  3256       
       
  3257       aDecoderInfo->vosHeaderSize = iOutBuffer->getIndex;
       
  3258     }
       
  3259         
       
  3260     PRINT((_L("CMPEG4Transcoder: ConstructVOSHeader. resyn: %d, data partitioned: %d, rvlc: %d, resolution: %d"),
       
  3261       iVOLHeader.error_res_disable, iVOLHeader.data_partitioned, iVOLHeader.reversible_vlc,
       
  3262       aDecoderInfo->iTimeIncrementResolution));
       
  3263   }
       
  3264   PRINT((_L("CMPEG4Transcoder:  streammode: %d, outputformat: %d, vos size : %d"), 
       
  3265     iBitStreamMode, iTargetFormat, aDecoderInfo->vosHeaderSize));
       
  3266 }
       
  3267 
       
  3268 
       
  3269 
       
  3270 
       
  3271 /****************************************************************
       
  3272 *                                                               *
       
  3273 *    Functions for H.263, or H.263 -> MPEG4 (only baseline H.263) *
       
  3274 *                                                               *
       
  3275 *****************************************************************/
       
  3276 
       
  3277 
       
  3278 /* Luminance block dc-scaler value corresponding to QP values of 0-31 */
       
  3279 const u_int8 sLumDCScalerTbl[32] = 
       
  3280 {   
       
  3281        0,  8,  8,  8,  8, 10, 12, 14, 
       
  3282     16, 17, 18, 19, 20, 21, 22, 23, 
       
  3283     24, 25, 26, 27, 28, 29, 30, 31, 
       
  3284     32, 34, 36, 38, 40, 42, 44, 46 
       
  3285 };
       
  3286 
       
  3287 /* Chrominance block dc-scaler value corresponding to QP values of 0-31 */
       
  3288 const u_int8 sChrDCScalerTbl[32] = 
       
  3289 {   
       
  3290        0,  8,  8,  8,  8,  9,  9, 10, 
       
  3291     10, 11, 11, 12, 12, 13, 13, 14, 
       
  3292     14, 15, 15, 16, 16, 17, 17, 18, 
       
  3293     18, 19, 20, 21, 22, 23, 24, 25 
       
  3294 };
       
  3295 
       
  3296 /*
       
  3297 * sGetMPEG4INTRADCValue
       
  3298 *
       
  3299 * Parameters: 
       
  3300 *     intraDC      reconstructed intra DC from H263
       
  3301 *     QP           quantion factor
       
  3302 *     blockNum     block number (0 to 5)
       
  3303 *     currMBNum    current MB number
       
  3304 *     mbinWidth    number of MBs in picure width
       
  3305 *     dcData       matrix to store the INTRA DC values
       
  3306 *     mbVPNumber   matrix recording the video packet number for each MB
       
  3307 *     
       
  3308 * Function:
       
  3309 *    This function gets the new intra DC for MPEG4
       
  3310 * Returns:
       
  3311 *     INTRA DC to put into MPEG4 bitstream
       
  3312 * Error codes:
       
  3313 *    None
       
  3314 *
       
  3315 */
       
  3316 int sGetMPEG4INTRADCValue(int intraDC, int blockNum, int currMBNum,
       
  3317                                                     int32 QP, int32 mbinWidth, int **dcData, int *mbVPNumber)
       
  3318 {
       
  3319     int tempDCScaler;
       
  3320     int blockA = 0, blockB = 0, blockC = 0;
       
  3321     int gradHor, gradVer, predDC;
       
  3322     
       
  3323     VDTASSERT(currMBNum >= 0);
       
  3324     VDTASSERT(QP <= 31);
       
  3325     
       
  3326   /* Prediction blocks A (left), B (above-left), and C (above) */
       
  3327     switch (blockNum)
       
  3328     {
       
  3329         case 0:
       
  3330         case 4:
       
  3331         case 5:
       
  3332       /* Y0, U, and V blocks */
       
  3333             if (((currMBNum % mbinWidth) == 0) || /* Left edge */
       
  3334                 (mbVPNumber[currMBNum - 1] != mbVPNumber[currMBNum]))
       
  3335             {
       
  3336                 blockA = 1024; /* fixed value for H263 */
       
  3337             }
       
  3338             else
       
  3339             {
       
  3340                 blockA = dcData[currMBNum - 1][blockNum > 3? blockNum : 1];
       
  3341             }
       
  3342             
       
  3343             if (((currMBNum / mbinWidth) == 0) || /* Top Edge */
       
  3344                 ((currMBNum % mbinWidth) == 0) || /* Left Edge */
       
  3345                 (mbVPNumber[currMBNum - mbinWidth - 1] != mbVPNumber[currMBNum]))
       
  3346             {
       
  3347                 blockB = 1024;
       
  3348             }
       
  3349             else
       
  3350             {
       
  3351                 blockB = dcData[currMBNum - mbinWidth - 1][blockNum > 3? blockNum : 3];
       
  3352             }
       
  3353             
       
  3354             if (((currMBNum / mbinWidth) == 0) || /* Top Edge */
       
  3355                 (mbVPNumber[currMBNum - mbinWidth] != mbVPNumber[currMBNum]))
       
  3356             {
       
  3357                 blockC = 1024;
       
  3358             }
       
  3359             else
       
  3360             {
       
  3361                 blockC = dcData[currMBNum - mbinWidth][blockNum > 3? blockNum : 2];
       
  3362             }
       
  3363             break;
       
  3364             
       
  3365         case 1:
       
  3366             /* Y1 block */
       
  3367             blockA = dcData[currMBNum][0];
       
  3368             
       
  3369             if (((currMBNum / mbinWidth) == 0) || /* Top Edge */
       
  3370                 (mbVPNumber[currMBNum - mbinWidth] != mbVPNumber[currMBNum]))
       
  3371             {
       
  3372                 blockB = 1024;
       
  3373                 blockC = 1024;
       
  3374             }
       
  3375             else
       
  3376             {
       
  3377                 blockB = dcData[currMBNum - mbinWidth][2];
       
  3378                 blockC = dcData[currMBNum - mbinWidth][3];
       
  3379             }
       
  3380             break;
       
  3381             
       
  3382         case 2:
       
  3383             /* Y2 block */
       
  3384             
       
  3385             if (((currMBNum % mbinWidth) == 0) || /* Left Edge */
       
  3386                 (mbVPNumber[currMBNum - 1] != mbVPNumber[currMBNum]))
       
  3387             {
       
  3388                 blockA = 1024;
       
  3389                 blockB = 1024;
       
  3390             }
       
  3391             else
       
  3392             {
       
  3393                 blockA = dcData[currMBNum  - 1][3];
       
  3394                 blockB = dcData[currMBNum  - 1][1];
       
  3395             }
       
  3396             
       
  3397             blockC = dcData[currMBNum][0];
       
  3398             break;
       
  3399             
       
  3400         case 3:
       
  3401             /* Y3 block */
       
  3402             
       
  3403             blockA = dcData[currMBNum][2];
       
  3404             blockB = dcData[currMBNum][0];
       
  3405             blockC = dcData[currMBNum][1];
       
  3406             break;
       
  3407 
       
  3408         default:
       
  3409             break;
       
  3410     }
       
  3411     
       
  3412     gradHor = blockB - blockC;
       
  3413     gradVer = blockA - blockB;
       
  3414     
       
  3415     if ((abs(gradVer)) < (abs(gradHor))) 
       
  3416     {
       
  3417         /* Vertical prediction (from C) */
       
  3418         predDC = blockC;
       
  3419     }
       
  3420     else 
       
  3421     {
       
  3422         /* Horizontal prediction (from A) */
       
  3423         predDC = blockA;
       
  3424     }
       
  3425     
       
  3426   /* DC quantization */
       
  3427   if (blockNum < 4) /* Luminance Block */
       
  3428   {
       
  3429         intraDC += (sLumDCScalerTbl[QP] >> 1);
       
  3430         intraDC /= sLumDCScalerTbl[QP];
       
  3431         
       
  3432         /* update the DC data matrix
       
  3433         note: for INTER MB, the entry is already preset to 1024!!
       
  3434         */
       
  3435         dcData[currMBNum][blockNum] = intraDC * sLumDCScalerTbl[QP];
       
  3436   }
       
  3437   else            /* Chrominance block */
       
  3438   {
       
  3439         intraDC += (sChrDCScalerTbl[QP] >> 1);
       
  3440         intraDC /= sChrDCScalerTbl[QP];
       
  3441         /* update the DC data matrix
       
  3442         note: for INTER MB, the entry is already preset to 1024!!
       
  3443         */
       
  3444         dcData[currMBNum][blockNum] = intraDC * sChrDCScalerTbl[QP];
       
  3445   }
       
  3446     /* DC prediction */
       
  3447   tempDCScaler = (blockNum<4)? sLumDCScalerTbl[QP] : sChrDCScalerTbl[QP];
       
  3448     
       
  3449   return (intraDC - ((predDC + tempDCScaler/2) / tempDCScaler));
       
  3450 }
       
  3451 
       
  3452 /*
       
  3453 * sPutVOLHeader
       
  3454 *
       
  3455 * Parameters: 
       
  3456 *     bitOut       pointer to the output buffer
       
  3457 *     aWidth       picture width
       
  3458 *     aHeight      picture height
       
  3459 *     aTimerResolution timer resolution for MPEG4
       
  3460 *     
       
  3461 * Function:
       
  3462 *    This function writes the VOL header into bit-stream
       
  3463 * Returns:
       
  3464 *     None
       
  3465 * Error codes:
       
  3466 *    None
       
  3467 *
       
  3468 */
       
  3469 inline void sPutVOLHeader(bibBuffer_t* bitOut, int aWidth, int aHeight, int aTimerResolution)
       
  3470 {
       
  3471     bibBuffer_t     *lBitOut;
       
  3472     uint32          vop_time_increment_resolution;
       
  3473     
       
  3474     lBitOut = bitOut;
       
  3475     WRITE32(lBitOut, (uint32)VIDEO_OBJECT_LAYER_START_CODE);
       
  3476     /* RandomAccessibleVol == 1 means all VOP's can be decoded independently */
       
  3477     sPutBits(lBitOut, 1, 0);
       
  3478     /* VideoObjectTypeIndication = SIMPLE OBJECT */
       
  3479     sPutBits(lBitOut, 8, SIMPLE_OBJECT);
       
  3480     /* IsObjectLayerIdentifier */
       
  3481     sPutBits(lBitOut, 1, 0);
       
  3482     /* AspectRatioInfo */
       
  3483     sPutBits(lBitOut, 4, ASPECT_RATIO_INFO);
       
  3484     /* vol_control_parameters = 1 */
       
  3485     sPutBits(lBitOut, 1, 1);
       
  3486     /* Chroma Format */
       
  3487     sPutBits(lBitOut, 2, CHROMA_FORMAT);
       
  3488     /* LowDelay = 1; */
       
  3489     sPutBits(lBitOut, 1, 1);
       
  3490     /* vbvParameters = 0; */
       
  3491     sPutBits(lBitOut, 1, 0);
       
  3492     /* VideoObjectLayerShape == RECTANGULAR */
       
  3493     sPutBits(lBitOut, 2, RECTANGULAR);
       
  3494     /* Marker Bit */
       
  3495     sPutBits(lBitOut, 1, MARKER_BIT);
       
  3496     /* VopTimeIncrementResolution */
       
  3497     vop_time_increment_resolution = aTimerResolution;
       
  3498     sPutBits(lBitOut, 16, vop_time_increment_resolution);
       
  3499     /* Marker Bit */
       
  3500     sPutBits(lBitOut, 1, MARKER_BIT);    
       
  3501     /* FixedVOPRate = 0, not fixed */
       
  3502     sPutBits(lBitOut, 1, 0);    
       
  3503     /* Marker Bit */
       
  3504     sPutBits(lBitOut, 1, MARKER_BIT);
       
  3505     /* VideoObjectLayerWidth */
       
  3506     sPutBits(lBitOut, 13, aWidth);
       
  3507     /* Marker Bit */
       
  3508     sPutBits(lBitOut, 1, MARKER_BIT);
       
  3509     /* VideoObjectLayerHeight */
       
  3510     sPutBits(lBitOut, 13, aHeight);
       
  3511     /* Marker Bit */
       
  3512     sPutBits(lBitOut, 1, MARKER_BIT);
       
  3513     /* Interlaced = 0 */
       
  3514     sPutBits(lBitOut, 1, 0);
       
  3515     /* ObmcDisable= 1 */
       
  3516     sPutBits(lBitOut, 1, 1);
       
  3517     /* SpriteEnable = 0 */
       
  3518     sPutBits(lBitOut, 1, 0);
       
  3519     /* Not8Bit = 0 */
       
  3520     sPutBits(lBitOut, 1, 0);
       
  3521     /* QuantType = H263 (0) */
       
  3522     sPutBits(lBitOut, 1, H263);
       
  3523     /* Complexity Estimation Disable = 1 */
       
  3524     sPutBits(lBitOut, 1, 1);
       
  3525     /* ResyncMarkerDisable */
       
  3526     sPutBits(lBitOut, 1, 0); /* H263 is converted to resyn_marker MPEG4 in video editor */
       
  3527     /* DataPartioned */
       
  3528     sPutBits(lBitOut, 1, 0); /* always 0 for H263 */
       
  3529     /* Reversible VLC  closed */
       
  3530     /* Scalability = 0 */
       
  3531     sPutBits(lBitOut, 1, 0);
       
  3532     vdtStuffBitsMPEG4(lBitOut);
       
  3533     
       
  3534     return;
       
  3535 }
       
  3536 
       
  3537 
       
  3538 /*
       
  3539 * sPutGOVHeader
       
  3540 *
       
  3541 * Parameters: 
       
  3542 *     bitOut       pointer to the output buffer
       
  3543 *     aModuloTimeBase  time base for MPEG4
       
  3544 *     
       
  3545 * Function:
       
  3546 *    This function writes the group of VOP(GOV) header into bit-stream
       
  3547 * Returns:
       
  3548 *     None
       
  3549 * Error codes:
       
  3550 *    None
       
  3551 *
       
  3552 */
       
  3553 inline void sPutGOVHeader(bibBuffer_t *bitOut, int aModuloTimeBase)
       
  3554 {
       
  3555     int32 time_code_hours;
       
  3556     int32 time_code_minutes;
       
  3557     int32 time_code_seconds;
       
  3558     
       
  3559     WRITE32(bitOut, (uint32)GROUP_OF_VOP_START_CODE);
       
  3560     time_code_seconds = aModuloTimeBase;
       
  3561     time_code_minutes = time_code_seconds / 60;
       
  3562     time_code_hours   = time_code_minutes / 60;    
       
  3563     time_code_minutes = time_code_minutes - (time_code_hours * 60);
       
  3564     time_code_seconds = time_code_seconds - (time_code_minutes * 60)
       
  3565         - (time_code_hours * 3600);
       
  3566     
       
  3567     sPutBits(bitOut, 5, time_code_hours);
       
  3568     sPutBits(bitOut, 6, time_code_minutes);
       
  3569     sPutBits(bitOut, 1, MARKER_BIT);
       
  3570     sPutBits(bitOut, 6, time_code_seconds);
       
  3571     
       
  3572     /* ClosedGov */
       
  3573     sPutBits(bitOut, 1, 0);
       
  3574     /* Broken Link */
       
  3575     sPutBits(bitOut, 1, 0);
       
  3576     
       
  3577     /* Stuff bits */
       
  3578     vdtStuffBitsMPEG4(bitOut);
       
  3579     
       
  3580     return;
       
  3581 }
       
  3582 
       
  3583 /*
       
  3584 * sConstructMPEG4VOSHeaderForH263
       
  3585 *
       
  3586 * Parameters: 
       
  3587 *     bitOut       pointer to the output buffer
       
  3588 *     aWidth       picture width
       
  3589 *     aHeight      picture height
       
  3590 *     
       
  3591 * Function:
       
  3592 *    This function writes the MPEG4 VOS header into bit-stream
       
  3593 * Returns:
       
  3594 *     None
       
  3595 * Error codes:
       
  3596 *    None
       
  3597 *
       
  3598 */
       
  3599 void sConstructMPEG4VOSHeaderForH263(bibBuffer_t *bitOut, int aWidth, int aHeight, int aOutputMpeg4TimeRes)
       
  3600 {
       
  3601     /* visual object sequence header */
       
  3602     WRITE32(bitOut, (uint32)VISUAL_OBJECT_SEQUENCE_START_CODE);
       
  3603     
       
  3604     /* This is for testing for level 0,3 */
       
  3605     uint32 level = 8;   /* level 0 for QCIF or less */
       
  3606     if(aWidth > 176 || aHeight > 144)   /* level 2 for greater than QCIF */
       
  3607         level = 2;
       
  3608     sPutBits(bitOut, 8, level); /* simple profile, level 0 for H263 */
       
  3609     
       
  3610     /* visual object header begins */
       
  3611     WRITE32(bitOut, (uint32)VISUAL_OBJECT_START_CODE);
       
  3612     /* IsVisualObjectIdentifier = 0 */
       
  3613     sPutBits(bitOut, 1, 0);
       
  3614     /* VisualObjectType = VIDEO_OBJECT */
       
  3615     sPutBits(bitOut, 4, VISUAL_OBJECT);
       
  3616     /* VideoSignalType = 0 */
       
  3617     sPutBits(bitOut, 1, 0);
       
  3618     
       
  3619     vdtStuffBitsMPEG4(bitOut);
       
  3620     WRITE32(bitOut, (uint32)VIDEO_OBJECT_START_CODE);
       
  3621     
       
  3622     /* Writes the VOL header into bit-stream , for baseline H263 TR is marked with 29.97fps. ->? */
       
  3623     sPutVOLHeader(bitOut, aWidth, aHeight, aOutputMpeg4TimeRes);
       
  3624     
       
  3625     /* Writes GOV , time base is 0 */
       
  3626     sPutGOVHeader(bitOut, 0);
       
  3627     
       
  3628     return;
       
  3629 }
       
  3630 
       
  3631 
       
  3632 /*
       
  3633 * sPutVideoPacketHeader
       
  3634 *
       
  3635 * Parameters: 
       
  3636 *     lBitOut      output buffer
       
  3637 *     mbNo         Macroblock number
       
  3638 *     quantiserScale quant value to be put in header
       
  3639 *     aMBsInVOP    # of MBs in one VOP
       
  3640 *     
       
  3641 * Function:
       
  3642 *    This function writes the video packet header information into bit-stream
       
  3643 * Returns:
       
  3644 *     None
       
  3645 * Error codes:
       
  3646 *    None
       
  3647 *
       
  3648 */
       
  3649 inline void sPutVideoPacketHeader(bibBuffer_t *lBitOut, int32 mbNo, 
       
  3650                                                                     int16 quantiserScale,
       
  3651                                                                     int aMBsInVOP)
       
  3652 {
       
  3653     int32   lResyncMarkerLength = 17;
       
  3654     int32   lMBNoResolution;
       
  3655     
       
  3656     /* ResyncMarker */
       
  3657     int fCode = 1; /*always 1 for H263 */
       
  3658     lResyncMarkerLength = 16 + fCode; 
       
  3659     sPutBits(lBitOut, lResyncMarkerLength, 1);
       
  3660     
       
  3661     --aMBsInVOP;
       
  3662     lMBNoResolution = 1;
       
  3663     while( (aMBsInVOP =
       
  3664         aMBsInVOP >> 1) > 0 )
       
  3665     {
       
  3666         lMBNoResolution++;
       
  3667     }
       
  3668     sPutBits(lBitOut, lMBNoResolution, mbNo);
       
  3669     
       
  3670     /* QuantScale */ 
       
  3671     sPutBits(lBitOut, 5, quantiserScale);
       
  3672     /* HEC */
       
  3673     sPutBits(lBitOut, 1, 0); /* always 0 for H263 */
       
  3674     
       
  3675     return;
       
  3676 }
       
  3677 
       
  3678 /*
       
  3679 * sConstructVOPHeaderForH263
       
  3680 *
       
  3681 * Parameters: 
       
  3682 *     lBitOut      output buffer
       
  3683 *     prevQuant    quant value to be put in header
       
  3684 *     aVOPType     picture coding type
       
  3685 *     aVOPTimeIncrement  time increament
       
  3686 *     
       
  3687 * Function:
       
  3688 *    This function writes the VOP header into bit-stream for one H263 frame
       
  3689 * Returns:
       
  3690 *     None
       
  3691 * Error codes:
       
  3692 *    None
       
  3693 *
       
  3694 */
       
  3695 
       
  3696 void sConstructVOPHeaderForH263(bibBuffer_t *lBitOut, int prevQuant, int aVOPType, int aVOPTimeIncrement,int aOutputMpeg4TimeRes)
       
  3697 {
       
  3698     WRITE32(lBitOut, (uint32)VOP_START_CODE);
       
  3699     /* VOPType, 0 for Intra and 1 for inter */
       
  3700     sPutBits(lBitOut, 2, aVOPType);
       
  3701     
       
  3702     /* H263 TR is marked with 29.97fps */
       
  3703     /* Modulo Time Base */
       
  3704     int outputTimerResolution = aOutputMpeg4TimeRes;
       
  3705     while ((unsigned)aVOPTimeIncrement >= (unsigned) outputTimerResolution)
       
  3706     {
       
  3707         sPutBits(lBitOut, 1, 1);
       
  3708         aVOPTimeIncrement -= outputTimerResolution; 
       
  3709     }
       
  3710     sPutBits(lBitOut, 1, 0);
       
  3711     /* Marker Bit */
       
  3712     sPutBits(lBitOut, 1, MARKER_BIT);   
       
  3713     /* VopTimeIncrement */
       
  3714     int numOutputTrBits;
       
  3715     for (numOutputTrBits = 1; ((outputTimerResolution-1) >> numOutputTrBits) != 0; numOutputTrBits++)
       
  3716         {
       
  3717         }
       
  3718     int VOPIncrementResolutionLength = numOutputTrBits;
       
  3719     sPutBits(lBitOut, VOPIncrementResolutionLength, aVOPTimeIncrement);
       
  3720     /* Marker Bit */
       
  3721     sPutBits(lBitOut, 1, MARKER_BIT);
       
  3722     /* VOPCoded */
       
  3723     sPutBits(lBitOut, 1, 1); /* always 1 for H263 */
       
  3724     /* VOPRoundingType */
       
  3725     if(aVOPType == P_VOP)
       
  3726     {
       
  3727         sPutBits(lBitOut, 1, 0); /* always 0 for H263 */
       
  3728     }
       
  3729     /* IntraDCVLCThreshold */
       
  3730     sPutBits(lBitOut, 3, 0); /* always 0 for H263 */
       
  3731     /* VOPQuant */
       
  3732     sPutBits(lBitOut, 5, prevQuant);
       
  3733     /* VOPFcodeForwad */
       
  3734     if(aVOPType == P_VOP)
       
  3735     {
       
  3736         sPutBits(lBitOut, 3, 1); /* always 1 for H263 */
       
  3737     }
       
  3738     
       
  3739     return;
       
  3740 }
       
  3741 
       
  3742 
       
  3743 
       
  3744 /*
       
  3745 * H263PictureHeaderEndedL
       
  3746 *
       
  3747 * Parameters: 
       
  3748 *     
       
  3749 * Function:
       
  3750 *    This function is called after one H263 picture header is parsed
       
  3751 *    Note: the input header is only valid inside this function
       
  3752 * Returns:
       
  3753 *    VDC error codes
       
  3754 * Error codes:
       
  3755 *    None
       
  3756 *
       
  3757 */
       
  3758 int CMPEG4Transcoder::H263PictureHeaderEnded(dphOutParam_t *aH263PicHeader, dphInOutParam_t *aInfo)
       
  3759 {
       
  3760     VDTASSERT(aH263PicHeader);  
       
  3761     
       
  3762     // asad
       
  3763     if (!aInfo->vdcInstance->frameNum || !iRefQuant)
       
  3764     {
       
  3765         iRefQuant = aH263PicHeader->pquant;
       
  3766         iDcScaler = GetMpeg4DcScalerUV(iRefQuant); 
       
  3767     }
       
  3768     
       
  3769     if (!iDoModeTranscoding )
       
  3770     {
       
  3771         
       
  3772        /* Copy the header to output stream */
       
  3773        bufEdit.copyMode = CopyWhole; /* CopyWhole */
       
  3774          
       
  3775          if ( (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45) && 
       
  3776                fFirstFrameInH263 && iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader)
       
  3777          {
       
  3778              /* we don't need the VOS header, remove it */
       
  3779              PRINT((_L("CMPEG4Transcoder: MPEG4 shortheader VOS removed")));
       
  3780              
       
  3781              CopyStream(iInBuffer,iOutBuffer,&bufEdit,iShortHeaderEndByteIndex,iShortHeaderEndBitIndex);
       
  3782              fFirstFrameInH263 = EFalse;
       
  3783          }
       
  3784          else
       
  3785          {
       
  3786            /* copy from the begining of the input buffer, 
       
  3787               including the VOS header for MPEG4 shortheader if its mode is not being changed
       
  3788              */
       
  3789              CopyStream(iInBuffer,iOutBuffer,&bufEdit,0,7);
       
  3790          }
       
  3791     }
       
  3792     
       
  3793 
       
  3794     
       
  3795     else
       
  3796     {
       
  3797         /* H263 Picture Header -> MPEG4 VOP Header mapping
       
  3798            information about this frame
       
  3799         */
       
  3800         iMBsinWidth = aInfo->vdcInstance->pictureParam.lumWidth >> 4;
       
  3801         
       
  3802         iNumMBsInOneVOP = (aInfo->vdcInstance->pictureParam.lumWidth >> 4) *
       
  3803             (aInfo->vdcInstance->pictureParam.lumHeight >> 4);
       
  3804         
       
  3805         iNumMBsInGOB = aInfo->vdcInstance->pictureParam.numMBsInGOB;
       
  3806         
       
  3807         /* create the intraDC matrix for DC prediction */
       
  3808         VDTASSERT(!iH263DCData);
       
  3809         VDTASSERT(!iH263MBVPNum);
       
  3810         
       
  3811         iH263DCData = (int **)malloc(iNumMBsInOneVOP * sizeof(int));
       
  3812         if (!iH263DCData) 
       
  3813         {
       
  3814             deb("CMPEG4Transcoder::ERROR - iH263DCData creation failed\n");
       
  3815             return TX_ERR;
       
  3816         }
       
  3817         
       
  3818         for (int i = 0; i < iNumMBsInOneVOP; i++)
       
  3819         {
       
  3820             iH263DCData[i] = (int *) malloc(6 * sizeof(int)); /* six blocks in one MB */
       
  3821             VDTASSERT(iH263DCData[i]);
       
  3822             if (!iH263DCData[i]) 
       
  3823             {
       
  3824                 deb("CMPEG4Transcoder::ERROR - iH263DCData[i] creation failed\n");
       
  3825 
       
  3826                 for(int k=0; k<i; k++)
       
  3827                 {
       
  3828                     free (iH263DCData[k]); 
       
  3829                 }
       
  3830                 if (iH263DCData) 
       
  3831                 {
       
  3832                     free(iH263DCData);
       
  3833                 }
       
  3834 
       
  3835                 return TX_ERR;
       
  3836             }
       
  3837 
       
  3838             
       
  3839             /* initialize each entry to 1024 for DC prediction */
       
  3840             for (int j = 0; j < 6; j++)
       
  3841             {
       
  3842                 iH263DCData[i][j] = 1024;
       
  3843             }
       
  3844         }
       
  3845         
       
  3846         iH263MBVPNum = (int *) malloc(iNumMBsInOneVOP * sizeof(int));
       
  3847         if (!iH263MBVPNum) 
       
  3848         {
       
  3849             deb("CMPEG4Transcoder::ERROR - iH263MBVPNum creation failed\n");
       
  3850             return TX_ERR;
       
  3851         }
       
  3852         
       
  3853         memset(iH263MBVPNum, 0, iNumMBsInOneVOP * sizeof(int));
       
  3854         int pictureType = aInfo->vdcInstance->pictureParam.pictureType == VDX_PIC_TYPE_I? I_VOP : P_VOP;
       
  3855         
       
  3856         if (fFirstFrameInH263)
       
  3857         {
       
  3858             /* first frame, construct the VOS header */
       
  3859             sConstructMPEG4VOSHeaderForH263(iOutBuffer,
       
  3860                 aInfo->vdcInstance->pictureParam.lumWidth,
       
  3861                 aInfo->vdcInstance->pictureParam.lumHeight, 
       
  3862                 iOutputMpeg4TimeIncResolution);
       
  3863             fFirstFrameInH263 = EFalse;
       
  3864             
       
  3865             PRINT((_L("CMPEG4Transcoder: H263 -> MPEG VOS generated")));
       
  3866         }
       
  3867         sConstructVOPHeaderForH263(iOutBuffer, aH263PicHeader->pquant, pictureType, aH263PicHeader->trp == -1 ? 0 : aH263PicHeader->trp,iOutputMpeg4TimeIncResolution);
       
  3868 
       
  3869         
       
  3870     PRINT((_L("CMPEG4Transcoder: H263 -> MPEG4: transcoding one picture")));
       
  3871     }
       
  3872     
       
  3873     
       
  3874     PRINT((_L("CMPEG4Transcoder: H263PictureHeaderEndedL. color effect: %d, format convert %d, do transcoding: %d streammode: %d, outputformat: %d "), 
       
  3875        iColorEffect, iDoModeTranscoding, iDoTranscoding,
       
  3876          iBitStreamMode, iTargetFormat));
       
  3877     
       
  3878     return TX_OK;
       
  3879 }
       
  3880 
       
  3881 /*
       
  3882 * H263GOBSliceHeaderEnded
       
  3883 *
       
  3884 * Parameters: 
       
  3885 *     
       
  3886 * Function:
       
  3887 *    This function is called after one H263 GOB or Slice header is parsed
       
  3888 * Returns:
       
  3889 *     None
       
  3890 * Error codes:
       
  3891 *    None
       
  3892 *
       
  3893 */
       
  3894 void CMPEG4Transcoder::H263GOBSliceHeaderEnded(vdxGOBHeader_t *aH263GOBHeader, vdxSliceHeader_t */*aH263SliceHeader*/)
       
  3895 {
       
  3896     iGOBSliceHeaderEndByteIndex = iInBuffer->getIndex;
       
  3897     iGOBSliceHeaderEndBitIndex  = iInBuffer->bitIndex;  
       
  3898     
       
  3899     if (aH263GOBHeader)
       
  3900     {
       
  3901         /* not the first GOB (no header), we have stuffing bits ahead
       
  3902         since we only store the position of GBSC not including 
       
  3903         the stuffing bits, we may need to insert the stuffing bits here
       
  3904         if we have color effect, we have done the stuffing at the end of last GOB
       
  3905         see functin: H263OneGOBSliceWithHeaderEnded
       
  3906         */
       
  3907         sStuffBitsH263(iOutBuffer); 
       
  3908     }
       
  3909     
       
  3910     if (!iDoModeTranscoding)
       
  3911     {
       
  3912        /* Copy the header to output stream */
       
  3913        bufEdit.copyMode = CopyWhole; // whole
       
  3914          CopyStream(iInBuffer,iOutBuffer,&bufEdit,iGOBSliceStartByteIndex,iGOBSliceStartBitIndex);
       
  3915          
       
  3916     }
       
  3917 
       
  3918     else
       
  3919     {
       
  3920         /* H263 GOB (Slice) Header -> MPEG4 VP Header mapping */
       
  3921         if (!VDT_NO_DATA((int)iInBuffer->getIndex, iInBuffer->bitIndex, iGOBSliceStartByteIndex, iGOBSliceStartBitIndex) &&
       
  3922             aH263GOBHeader)
       
  3923         {
       
  3924             /* sPutVideoPacketHeader */
       
  3925             sPutVideoPacketHeader(iOutBuffer, aH263GOBHeader->gn * iNumMBsInGOB, (short)aH263GOBHeader->gquant, iNumMBsInOneVOP);
       
  3926         }
       
  3927     }
       
  3928         
       
  3929     // one slice ended, new video packet starting
       
  3930     iCurMBNumInVP = -1;
       
  3931     
       
  3932 }
       
  3933 
       
  3934 
       
  3935 /*
       
  3936 * H263GOBSliceHeaderBegin
       
  3937 *
       
  3938 * Parameters: 
       
  3939 *     
       
  3940 * Function:
       
  3941 *    This function is called before one H263 GOB or Slice header is parsed
       
  3942 * Returns:
       
  3943 *     None
       
  3944 * Error codes:
       
  3945 *    None
       
  3946 *
       
  3947 */
       
  3948 void CMPEG4Transcoder::H263GOBSliceHeaderBegin()
       
  3949 {
       
  3950     /* position not include the stuffing bits ahead of the GBSC ! */
       
  3951     iGOBSliceStartByteIndex = iInBuffer->getIndex;
       
  3952     iGOBSliceStartBitIndex  = iInBuffer->bitIndex;
       
  3953     iStuffingBitsUsed = 0;
       
  3954 }
       
  3955 
       
  3956 
       
  3957 /*
       
  3958 * H263GOBSliceHeaderBegin
       
  3959 *
       
  3960 * Parameters: 
       
  3961 *     
       
  3962 * Function:
       
  3963 *    This function is called after one H263 GOB or Slice ends
       
  3964 * Returns:
       
  3965 *     None
       
  3966 * Error codes:
       
  3967 *    None
       
  3968 *
       
  3969 */
       
  3970 void CMPEG4Transcoder::H263OneGOBSliceEnded(int nextExpectedMBNum)
       
  3971 {
       
  3972     if (iDoTranscoding)
       
  3973     {
       
  3974         /* MBs are lost or not coded, for H263 and H263->MPEG4 both */
       
  3975         for (int i = iLastMBNum+1; i < nextExpectedMBNum; i++)
       
  3976         {
       
  3977             /* output  1 bit COD */
       
  3978             sPutBits (iOutBuffer, 1, 1);
       
  3979         }
       
  3980         iLastMBNum = nextExpectedMBNum - 1; 
       
  3981     }
       
  3982 }
       
  3983 
       
  3984 
       
  3985 /*
       
  3986 * H263OneGOBSliceWithHeaderEnded
       
  3987 *
       
  3988 * Parameters: 
       
  3989 *     
       
  3990 * Function:
       
  3991 *    This function is called after GOB (Slice) that has GOB header (except the first GOB) ends
       
  3992 * Returns:
       
  3993 *     None
       
  3994 * Error codes:
       
  3995 *    None
       
  3996 *
       
  3997 */
       
  3998 void CMPEG4Transcoder::H263OneGOBSliceWithHeaderEnded()
       
  3999 {
       
  4000     if (!iDoTranscoding)
       
  4001     {
       
  4002        bufEdit.copyMode = CopyWhole; /* CopyWhole */
       
  4003          CopyStream(iInBuffer,iOutBuffer,&bufEdit,
       
  4004              iGOBSliceHeaderEndByteIndex,iGOBSliceHeaderEndBitIndex);
       
  4005     }
       
  4006     else
       
  4007     {
       
  4008 
       
  4009         if (iDoModeTranscoding)
       
  4010         {
       
  4011             /* for H263 to MPEG4, it implies that one video packet is finished */
       
  4012             vdtStuffBitsMPEG4(iOutBuffer);
       
  4013         }
       
  4014         else
       
  4015 
       
  4016         {
       
  4017             /* stuffing occurs outside at the end of one GOB/slice withe header or end of frame, check in file core.cpp */
       
  4018             sStuffBitsH263(iOutBuffer); 
       
  4019         }
       
  4020         iVideoPacketNumInMPEG4 ++;
       
  4021     }
       
  4022 
       
  4023     // one slice ended, new video packet starting
       
  4024     iCurMBNumInVP = -1; // 0
       
  4025 
       
  4026 }
       
  4027 
       
  4028 
       
  4029 
       
  4030 /*
       
  4031 * H263ToMPEG4MBData
       
  4032 *
       
  4033 * Parameters: 
       
  4034 *     
       
  4035 * Function:
       
  4036 *    This function transcodes one H263 MB to one MPEG4 MB
       
  4037 * Returns:
       
  4038 *     None
       
  4039 * Error codes:
       
  4040 *    None
       
  4041 *
       
  4042 */
       
  4043 void CMPEG4Transcoder::H263ToMPEG4MBData(int aNewMCBPCLen, int aNewMCBPC)
       
  4044 {
       
  4045     /* MB data part1: output MCBPC, CBPY, DQuant, MV, intra DC etc */
       
  4046     int *dataItemStartByteIndex;
       
  4047     int *dataItemStartBitIndex;
       
  4048     int *dataItemEndByteIndex;
       
  4049     int *dataItemEndBitIndex;
       
  4050     int quant, cbpy, cbpc;
       
  4051     
       
  4052     if (iVopCodingType == VDX_VOP_TYPE_P) 
       
  4053     {
       
  4054         dataItemStartByteIndex = iCurPMBinstance->DataItemStartByteIndex;
       
  4055         dataItemStartBitIndex  = iCurPMBinstance->DataItemStartBitIndex;
       
  4056         dataItemEndByteIndex   = iCurPMBinstance->DataItemEndByteIndex;
       
  4057         dataItemEndBitIndex    = iCurPMBinstance->DataItemEndBitIndex;
       
  4058         quant = iCurPMBinstance->quant;
       
  4059         cbpy  = iCurPMBinstance->cbpy;
       
  4060         cbpc  = iCurPMBinstance->cbpc;
       
  4061     }
       
  4062     else
       
  4063     {
       
  4064         dataItemStartByteIndex = iCurIMBinstance->DataItemStartByteIndex;
       
  4065         dataItemStartBitIndex  = iCurIMBinstance->DataItemStartBitIndex;
       
  4066         dataItemEndByteIndex   = iCurIMBinstance->DataItemEndByteIndex;
       
  4067         dataItemEndBitIndex    = iCurIMBinstance->DataItemEndBitIndex;
       
  4068         quant = iCurIMBinstance->quant;
       
  4069         cbpy  = iCurIMBinstance->cbpy;
       
  4070         cbpc  = iCurIMBinstance->cbpc;
       
  4071     }
       
  4072     
       
  4073     /* COD and MCBPC, (for I frame, it is MCBPC, for P frame it is COD and MCBPC) */
       
  4074     if (iVopCodingType == VDX_VOP_TYPE_P)
       
  4075     {
       
  4076         /* It is a coded MB, output  1 bit COD (it always exists in P frame) */
       
  4077         sPutBits (iOutBuffer, 1, 0);
       
  4078     }
       
  4079     
       
  4080     if (iColorEffect)
       
  4081     {
       
  4082         /* MCBPC Changed */
       
  4083         sPutBits(iOutBuffer, aNewMCBPCLen, aNewMCBPC);
       
  4084     }
       
  4085     else
       
  4086     {
       
  4087         /* remember the positions do not include the possible stuffing MCBPC bits */
       
  4088         vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  4089             dataItemStartByteIndex[0], dataItemStartBitIndex[0],
       
  4090             dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
       
  4091     }
       
  4092     
       
  4093     /* ac_pred_flag  */
       
  4094     if (iMBCodingType == VDX_MB_INTRA) 
       
  4095     {
       
  4096         sPutBits(iOutBuffer, 1, 0);// it is closed for H263 INTRA MB
       
  4097     }
       
  4098     
       
  4099     /* CBPY */
       
  4100     vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  4101         dataItemStartByteIndex[2], dataItemStartBitIndex[2],
       
  4102         dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
       
  4103     
       
  4104     /* DQUANT, if it exsits */
       
  4105     vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  4106         dataItemStartByteIndex[1], dataItemStartBitIndex[1],
       
  4107         dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
       
  4108     
       
  4109     if (iMBCodingType == VDX_MB_INTER) 
       
  4110     {
       
  4111         /* MVs, if they exsit */
       
  4112         vdtCopyBuffer(iInBuffer, iOutBuffer,
       
  4113             dataItemStartByteIndex[10], dataItemStartBitIndex[10],
       
  4114             dataItemEndByteIndex[10], dataItemEndBitIndex[10]);
       
  4115     }
       
  4116     
       
  4117     /* following is the block level data */
       
  4118     for (int i = 0; i < (iColorEffect? 4 : 6); i++)
       
  4119     {
       
  4120         if (iMBCodingType == VDX_MB_INTRA) 
       
  4121         {
       
  4122             int fBlockCoded = 0;
       
  4123             if (i < 4)
       
  4124             {
       
  4125                 fBlockCoded = vdxIsYCoded(cbpy, i + 1);
       
  4126             }
       
  4127             else if (i == 4)
       
  4128             {
       
  4129                 fBlockCoded = vdxIsUCoded(cbpc);
       
  4130             }
       
  4131             else 
       
  4132             {
       
  4133                 fBlockCoded = vdxIsVCoded(cbpc);
       
  4134             }
       
  4135             
       
  4136             /* Difference between H263 and MPEG4 :
       
  4137                0. DC quantization is different, DC need to be dequantized and requantized
       
  4138                   Note:  for ACs, here we only support H263 quantization in MPEG4, we can copy them
       
  4139                         1. DC prediction is used in MPEG4
       
  4140                         2. They use different VLC table for INTRA AC coefficient
       
  4141             */
       
  4142             /* reconstuct INTRA DC */
       
  4143             int intraDC = (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0]; /* it is already dequantized in funcion vdxGetIntraDCTBlock */
       
  4144             
       
  4145             /* INTRA quantization and prediction */
       
  4146             (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0] = sGetMPEG4INTRADCValue(intraDC,
       
  4147                 i, iCurMBNum, quant, iMBsinWidth,iH263DCData, iH263MBVPNum);
       
  4148             
       
  4149             /* recoding the INTRA block */
       
  4150             int numTextureBits = 0;
       
  4151             
       
  4152             vdtPutIntraMBCMT(iOutBuffer,iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, i, 0, 1); /* DC coding */
       
  4153             
       
  4154             if (fBlockCoded)
       
  4155             {
       
  4156                 vdtPutIntraMBCMT(iOutBuffer,iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, i, 1, 0); /*encode ACs */
       
  4157             }
       
  4158             
       
  4159         }
       
  4160         
       
  4161         else if (!(VDT_NO_DATA(iBlockStartByteIndex[i], iBlockStartBitIndex[i],
       
  4162             iBlockEndByteIndex[i], iBlockEndBitIndex[i])))
       
  4163         {
       
  4164             
       
  4165         /* 4. same VLC table for DCTs in H263 and MPEG4, but with different Escape Coding type. 
       
  4166         see 7.4.1.3. in MPEG4 draft
       
  4167             */
       
  4168             if (iEscapeCodeUsed[i])
       
  4169             {
       
  4170                 int numTextureBits = 0;
       
  4171                 vdtPutInterMBCMT(iOutBuffer,0, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, OFF);
       
  4172             }
       
  4173             else
       
  4174             {
       
  4175                 bufEdit.copyMode = CopyWhole; /* CopyWhole */
       
  4176                 vdtCopyBuffer(iInBuffer,iOutBuffer,
       
  4177                     iBlockStartByteIndex[i],iBlockStartBitIndex[i],
       
  4178                     iBlockEndByteIndex[i],iBlockEndBitIndex[i]);
       
  4179             }
       
  4180         }
       
  4181     }
       
  4182     
       
  4183   if (iColorEffect && (iMBCodingType == VDX_MB_INTRA))
       
  4184     {
       
  4185         ResetMPEG4IntraDcUV();
       
  4186     }
       
  4187 }
       
  4188 
       
  4189 
       
  4190 
       
  4191 /*
       
  4192 * NeedDecodedYUVFrame
       
  4193 *
       
  4194 * Parameters: 
       
  4195 *     
       
  4196 * Function:
       
  4197 *    This function indicates if whether we need the decoded frame 
       
  4198 * Returns:
       
  4199 *     ETrue if we need the decoded frame
       
  4200 * Error codes:
       
  4201 *    None
       
  4202 *
       
  4203 */
       
  4204 int CMPEG4Transcoder::NeedDecodedYUVFrame()
       
  4205 {
       
  4206     if ( (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45) &&
       
  4207         iBitStreamMode !=EVedVideoBitstreamModeMPEG4ShortHeader && iBitStreamMode != EVedVideoBitstreamModeH263)
       
  4208         return ETrue;
       
  4209     else
       
  4210         return EFalse;
       
  4211 }
       
  4212 
       
  4213 /*
       
  4214 * NewL
       
  4215 *
       
  4216 * Parameters: 
       
  4217 *     
       
  4218 * Function:
       
  4219 *    Symbian two-phased constructor 
       
  4220 * Returns:
       
  4221 *     pointer to constructed object, or NULL
       
  4222 * Error codes:
       
  4223 *    None
       
  4224 *
       
  4225 */
       
  4226 CMPEG4Transcoder* CMPEG4Transcoder::NewL(const vdeInstance_t *aVDEInstance, bibBuffer_t *aInBuffer, bibBuffer_t *aOutBuffer)
       
  4227 {
       
  4228     CMPEG4Transcoder *self = new (ELeave) CMPEG4Transcoder(aVDEInstance, aInBuffer, aOutBuffer);
       
  4229     CleanupStack::PushL(self);
       
  4230     self->ConstructL();
       
  4231     CleanupStack::Pop(self);
       
  4232     
       
  4233     return self;
       
  4234 }
       
  4235 
       
  4236 
       
  4237 /*
       
  4238 * ConstructL
       
  4239 *
       
  4240 * Parameters: 
       
  4241 *     
       
  4242 * Function:
       
  4243 *    Symbian 2nd phase constructor (can leave)
       
  4244 * Returns:
       
  4245 *     None
       
  4246 * Error codes:
       
  4247 *    None
       
  4248 *
       
  4249 */
       
  4250 void CMPEG4Transcoder::ConstructL()
       
  4251 {
       
  4252     
       
  4253     /* Create one IMB Instance  */
       
  4254     iCurIMBinstance = (vdxIMBListItem_t *) malloc(sizeof(vdxIMBListItem_t));
       
  4255     if (!iCurIMBinstance) 
       
  4256     {
       
  4257         deb("CMPEG4Transcoder::ERROR - iCurIMBinstance creation failed\n");
       
  4258         User::Leave(KErrNoMemory);
       
  4259        
       
  4260     }
       
  4261     memset(iCurIMBinstance, 0, sizeof(vdxIMBListItem_t));
       
  4262     
       
  4263     /* Create one PMBInstance */
       
  4264     iCurPMBinstance = (vdxPMBListItem_t *) malloc(sizeof(vdxPMBListItem_t));
       
  4265     if (!iCurPMBinstance) 
       
  4266     {
       
  4267         deb("CMPEG4Transcoder::ERROR - iCurPMBinstance creation failed\n");
       
  4268         User::Leave(KErrNoMemory);
       
  4269        
       
  4270     }
       
  4271     memset(iCurPMBinstance, 0, sizeof(vdxPMBListItem_t));
       
  4272     
       
  4273     /* initialize the edit buffer */
       
  4274     bufEdit.editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
  4275     VDTASSERT(bufEdit.editParams);
       
  4276     if (!bufEdit.editParams) 
       
  4277     {
       
  4278         deb("CMPEG4Transcoder::ERROR - bufEdit.editParams creation failed\n");
       
  4279         User::Leave(KErrNoMemory);
       
  4280        
       
  4281     }else{
       
  4282         bufEdit.numChanges = 1;
       
  4283     }
       
  4284     
       
  4285     if (!iMBType)
       
  4286     {
       
  4287         iMBType = (u_char *) malloc(iNumMBsInOneVOP * sizeof(u_char));
       
  4288         if (!iMBType) 
       
  4289         {
       
  4290             deb("CMPEG4Transcoder::ERROR - iMBType creation failed\n");
       
  4291             User::Leave(KErrNoMemory);
       
  4292         }
       
  4293         memset(iMBType, VDX_MB_INTER, iNumMBsInOneVOP * sizeof(u_char));
       
  4294     }    
       
  4295     
       
  4296 }
       
  4297 
       
  4298 
       
  4299 /*
       
  4300 * GetMpeg4DcScaler
       
  4301 *
       
  4302 * Parameters: 
       
  4303 *     
       
  4304 *  aQP            Quantization parameter
       
  4305 *
       
  4306 * Function:
       
  4307 *    Evaluates Chrominance DC Scaler from QP for MPEG4
       
  4308 * Returns:
       
  4309 *    int DC scaler value
       
  4310 * Error codes:
       
  4311 *    None
       
  4312 *
       
  4313 */
       
  4314 int CMPEG4Transcoder::GetMpeg4DcScalerUV(int aQP)
       
  4315 {
       
  4316     if (aQP>=1 && aQP<=4)
       
  4317         return (8);
       
  4318     else if (aQP>=5 && aQP<=24)
       
  4319         return ((aQP+13)/2);
       
  4320     else if (aQP>=25 && aQP<=31)
       
  4321         return (aQP-6);
       
  4322     else 
       
  4323         return (0);  // error 
       
  4324 }
       
  4325 
       
  4326 
       
  4327 void CMPEG4Transcoder::AfterMBLayer(int aUpdatedQp)
       
  4328 {
       
  4329   iCurQuant = aUpdatedQp;
       
  4330 }
       
  4331 
       
  4332 
       
  4333 
       
  4334 
       
  4335 /* End of File */