videoeditorengine/h263decoder/src/MPEG4Transcoder.cpp
changeset 0 951a5db380a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/h263decoder/src/MPEG4Transcoder.cpp	Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,4335 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:  
+* Implementation for MPEG4(H263) video transcoder. Operations may include:
+* 1. Bitstream Copying 
+* 2. BlackAndWhite Effect
+* 3. MPEG4 to VDT_RESYN (Simple profile)
+* 4. H.263 -> MPEG4 (Open Loop structure, no MV refinement)
+* 5. MPEG4 -> H263, partial implemented 
+*
+* We call functions 2~5 as transcoding functions since they involve MB level data processing
+*    
+* Note:
+* When RVLC is used and errors occur during  forward decoding, 
+* We don't do backward transcoding, the rest of the data is discarded, 
+*
+*/
+
+
+
+/* 
+* Includes
+*/
+#include "MPEG4Transcoder.h"
+#include "debug.h"
+
+/* Print macro */
+#ifdef _DEBUG
+#include <e32svr.h>
+#define PRINT(x) RDebug::Print x
+#else
+#define PRINT(x)
+#endif
+
+/* 
+* Defines and Typedefs
+*/
+typedef unsigned int         uint32;
+
+#define EInternalAssertionFailure 1000
+#define VDT_NO_DATA(a, b, c, d) ((a) == (c) && (b) == (d))
+
+const int KDataNotValid = -1; 
+const int KMpeg4VopTimeIncrementResolutionLength = 16; 
+const int KOutputMpeg4TimeIncResolution = 30000;
+const int KShortHeaderMpeg4VosSize = 14; 
+const int KH263ToMpeg4VosSize = 28; 
+
+
+
+/*Bit stream formating*/
+#define WRITE32(op, x) sPutBits((op), 16, ((uint32)(x)) >> 16);       \
+sPutBits((op), 16, (x) & 0x0000ffff)
+
+/* 
+* Constants 
+*/
+#ifdef _DEBUG
+const TUint KInitialBufferSize = 200000; /* MPEG4 Simple Visual Profile (Levels 0,1,2,3) initial frame data buffer size vga support */
+#endif
+                                                                                /* 
+                                                                                * Function Declarations 
+*/
+
+//Static Functions 
+
+static void sStuffBitsH263(bibBuffer_t *outBuffer);
+static TVedVideoBitstreamMode sGetMPEG4Mode(int error_resilience_disable, int dp, int rvlc);
+static int sFindCBP(int *mbdata, int fUseIntraDCVLC);
+
+
+
+void vdtPutInterMBCMT(bibBuffer_t *outBuffer, int coeffStart, int *coeff, int *numTextureBits, int svh);
+void vdtPutIntraMBCMT(bibBuffer_t *outBuffer, int *coeff, int *numTextureBits, int index,  int skipDC, int skipAC);
+void vbmEncodeMVDifferential(int32 mvdx, int32 mvdy, int32 fCode, bibBuffer_t *outBuffer);
+void vbmGetH263IMCBPC(int lDQuant, int vopCodingType, int colorEffect, int cbpy, int& mcbpcVal, int& len);
+void vbmGetH263PMCBPC(int lDQuant, int colorEffect, int cbpy, int& mcbpcVal, int& len);
+tBool vbmMVOutsideBound(tMBPosition *mbPos, tMotionVector* bestMV, tBool halfPixel);
+void vbmMvPrediction(tMBInfo *mbi, int32 mBCnt, tMotionVector *predMV,  int32 mbinWidth);
+void vbmPutInterMB(tMBPosition* mbPos, bibBuffer_t *outBuf, dmdPParam_t *paramMB, tMotionVector *initPred, 
+                                     int32 noOfPredictors, u_int32 vopWidth, u_int32 vopHeight, int32 searchRange, 
+                                     int32 mbNo, int32* numTextureBits, int16 colorEffect, tMBInfo *mbsinfo);
+
+void sPutBits (bibBuffer_t *buf, int numBits, unsigned int value);  //forward decl
+
+/* 
+* Function Definitions 
+*/
+
+/*
+* sStuffBitsH263
+*
+* Parameters: 
+*    outBuffer    output buffer
+*
+* Function:
+*    This function stuffs bits for H.263 format
+* Returns:
+*    None
+* Error codes:
+*    None.
+*
+*/
+static void sStuffBitsH263(bibBuffer_t *outBuffer)
+{
+    const int stuffingBits[8][2] = { {1,0}, {2,0}, {3,0}, {4,0}, {5,0}, {6,0}, {7,0}, {0,0} };
+    
+    VDTASSERT(outBuffer->baseAddr);
+    
+    /* find the number of stuffing bits to insert in the output buffer */
+    int bi = outBuffer->bitIndex;
+    int newNumBits = stuffingBits[bi][0]; 
+    int newValue = stuffingBits[bi][1]; 
+    sPutBits(outBuffer, newNumBits, newValue);
+        
+    return;
+}
+
+
+
+/*
+* sGetMPEG4Mode
+*
+* Parameters: 
+*    
+*
+* Function:
+*    This function gets the mode of the MPEG-4 bitstream
+* Returns:
+*    Nothing
+* Error codes:
+*    None.
+*
+*/
+static TVedVideoBitstreamMode sGetMPEG4Mode(int error_resilience_disable, int dp, int rvlc)
+{
+    TVedVideoBitstreamMode mode = EVedVideoBitstreamModeUnknown;
+    int combination = ((!error_resilience_disable) << 2) | (dp << 1) | rvlc;
+    switch (combination)
+    {
+        case 0:
+            mode = EVedVideoBitstreamModeMPEG4Regular;
+            break;
+        case 2:
+            mode = EVedVideoBitstreamModeMPEG4DP;
+            break;
+        case 3:
+            mode = EVedVideoBitstreamModeMPEG4DP_RVLC;
+            break;
+        case 4:
+            mode = EVedVideoBitstreamModeMPEG4Resyn;
+            break;
+        case 6:
+            mode = EVedVideoBitstreamModeMPEG4Resyn_DP;
+            break;
+        case 7:
+            mode = EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC;
+            break;
+        default:
+            mode = EVedVideoBitstreamModeUnknown;
+    }
+    
+    return mode;
+}
+
+
+/* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
+/*
+* sFindCBP
+*
+* Parameters: 
+*    mbdata          Contains the actual MB data to be quantized
+*    fUseIntraDCVLC  ON for INTRA, OFF for INTER
+*
+* Function:
+*    This function finds the coded bit pattern of the MB 
+* Returns:
+*    Coded Block Pattern.
+* Error codes:
+*    None.
+*
+*/
+static int sFindCBP(int *mbdata, int fUseIntraDCVLC)
+{
+    int coeffCnt;
+    int *block;
+    int blkCnt;
+    int cbpFlag = 0;
+    int codedBlockPattern = 0;
+
+    for (blkCnt = 0; blkCnt < 6; blkCnt++)
+    {   
+        cbpFlag = 0;
+        codedBlockPattern <<= 1;
+        block = &mbdata[blkCnt * BLOCK_COEFF_SIZE];
+        for (coeffCnt = fUseIntraDCVLC; coeffCnt < BLOCK_COEFF_SIZE;
+             coeffCnt++)
+             {
+                 if (block[coeffCnt])
+                 {
+                     cbpFlag = 1;
+                     codedBlockPattern |= cbpFlag;
+                     break;
+                 }
+             }
+    }
+    
+    return codedBlockPattern;
+}   
+
+
+
+
+
+
+/* {{-output"sPutBits.txt"}} */
+/*
+* sPutBits
+*
+* Parameters:
+*          outBuf           output buffer
+*           numBits         number of bits to output
+*           value           new value
+*
+* Function:
+*    This function puts some bits to the output buffer
+* Returns:
+*    Nothing.
+* Error codes:
+*    None.
+*
+*/
+void sPutBits (bibBuffer_t *buf, int numBits, unsigned int value)
+{
+    
+    bibEditParams_t edParam;
+    
+    edParam.curNumBits = edParam.newNumBits = numBits;
+    edParam.StartByteIndex = edParam.StartBitIndex = 0; /* used for source buffer only  */
+    edParam.newValue = value;                           /* use value 128, encoded as codeword "1111 1111" = 255 */
+    
+    CopyBufferEdit((bibBuffer_t*)NULL, buf, &edParam, 0); 
+}
+
+
+
+/*
+* GetTimeIncPosition
+*    
+*
+* Parameters:
+*    hInstance                  instance handle
+*
+* Function:
+*    Calculates the time increment position for the current VOP.
+*
+* Returns:
+*    VDX error codes
+*    
+*/
+
+int GetTimeIncPosition(
+   bibBuffer_t *inBuffer,
+   const vdxGetVopHeaderInputParam_t *inpParam,
+   vdxVopHeader_t *header,
+   int * ModuloByteIndex,
+   int * ModuloBitIndex,
+   int * ByteIndex,
+   int * BitIndex,
+   int *bitErrorIndication)
+/* {{-output"vdxGetVopHeader.txt"}} */
+{
+  /* Get VOP header */
+    int ret = vdxGetVopHeader(inBuffer, inpParam, header, 
+        ModuloByteIndex, ModuloBitIndex, ByteIndex, BitIndex,
+        bitErrorIndication);
+    
+    return ret;
+    
+}
+
+
+
+/*
+* CopyEditVop
+*    
+*
+* Parameters:
+*    hInstance                  instance handle
+*
+* Function:
+*    This function copies the VOP header with edited time stamps of the VOP.
+*
+* Returns:
+*    TX error codes
+*/
+
+int CopyEditVop(vdeHInstance_t hInstance, int aNrOfBytesToSkip, bibBuffer_t * inBuffer, 
+                 vdeDecodeParamters_t *aDecoderInfo)
+{
+    PRINT((_L("CopyEditVop() begin")));
+    int StartByteIndex = 0;
+    int StartBitIndex = 7;
+    int16 error;
+    int sncCode;
+    int timeIncByteIndex, timeIncBitIndex;
+    int moduloBaseByteIndex, moduloBaseBitIndex;
+    int vopheaderBitLeft;
+    int numBitChange = 0;
+    int increaseBytes = 0;
+    int stuffingLength = 0;
+
+    tMPEG4TimeParameter * timeStamp = aDecoderInfo->aMPEG4TimeStamp;
+    MPEG4TimeParameter CurNewTimeCode;
+
+    int outTirDecreased = 0;
+    int outputTimeResolution = *aDecoderInfo->aMPEG4TargetTimeResolution;
+    int numOutputTrBits;
+    for (numOutputTrBits = 1; ((outputTimeResolution-1) >> numOutputTrBits) != 0; numOutputTrBits++)
+        {
+        }
+
+    int num_bits;
+    vdxGetVopHeaderInputParam_t inpParam;
+    vdxVopHeader_t vopheader;
+    int bitErrorIndication;
+    vdeInstance_t * vdeTemp = (vdeInstance_t *)hInstance;
+    bibBuffer_t *outBuffer = vdeTemp->outBuffer;
+    bibBufferEdit_t * bufEdit = vdeTemp->bufEdit;
+    
+    int FrameSizeInByte = outBuffer->numBytesRead;
+    bibRewindBits(bibNumberOfFlushedBits(inBuffer),inBuffer,&error);
+    bibRewindBits(bibNumberOfFlushedBits(outBuffer),outBuffer,&error);
+    if ( aNrOfBytesToSkip > 0 )
+        {
+        // VOS header is already in the beginning of the output buffer
+        bibForwardBits(aNrOfBytesToSkip<<3, outBuffer);
+        // need to also skip the VOS header from input
+        }
+    bufEdit->copyMode = CopyWhole; /* CopyWhole - default */
+
+    /* record position */
+    StartByteIndex = inBuffer->numBytesRead;
+    StartBitIndex = inBuffer->bitIndex;
+
+    /* get time increment resolution */
+    vdcInstance_t * vdcTemp = (vdcInstance_t *)(vdeTemp->vdcHInstance);
+    int currentTimeIncResolution = vdcTemp->pictureParam.time_increment_resolution > 0? vdcTemp->pictureParam.time_increment_resolution : outputTimeResolution;
+    inpParam.time_increment_resolution = currentTimeIncResolution;
+
+    /* find the next vop start code */
+    do 
+    {
+        sncCode = sncSeekMPEGStartCode(inBuffer, vdcTemp->pictureParam.fcode_forward, vdcTemp->pictureParam.error_res_disable, 0, &error);
+        bibForwardBits(32,inBuffer); // one start code is found, move on  
+        if(inBuffer->bitsLeft <= 0) 
+        {
+            return TX_ERR;  // did not find any sync code --- vop is corrupted
+        }
+    }
+    while (sncCode != SNC_VOP);
+    bibRewindBits(32,inBuffer, &error);  // go back 
+
+    // if we have VOS header in the input, we are now just after it. If aNrOfBytesToSkip > 0, we should not copy it
+    // however, aNrOfBytesToSkip refers to output buffer, so we should not use it when skipping the input
+    if ( aNrOfBytesToSkip > 0 )
+        {
+        StartByteIndex = inBuffer->numBytesRead;
+        StartBitIndex = inBuffer->bitIndex;
+        }
+
+    /* read vop header */
+    GetTimeIncPosition(inBuffer, &inpParam, &vopheader, 
+        &moduloBaseByteIndex, &moduloBaseBitIndex, &timeIncByteIndex, 
+        &timeIncBitIndex, &bitErrorIndication);
+
+    /* record the header end; */
+    vopheaderBitLeft = inBuffer->bitsLeft;
+
+    /* copy-edit the part from the begin to the end of modulo base */
+    CurNewTimeCode = *timeStamp;
+
+    if (CurNewTimeCode.modulo_time_base != vopheader.time_base_incr)
+    {
+        if (!bufEdit->editParams)
+        {
+            bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+            if(!bufEdit->editParams)
+            {
+                //Memory not available 
+                return TX_ERR; //indicating error;
+            }
+            else
+            {
+                bufEdit->numChanges = 1;
+            }
+        }
+        bufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
+        bufEdit->editParams->curNumBits = vopheader.time_base_incr + 1;
+        bufEdit->editParams->newNumBits = CurNewTimeCode.modulo_time_base + 1;
+        bufEdit->editParams->newValue = ((1 << CurNewTimeCode.modulo_time_base) - 1) << 1;
+        bufEdit->editParams->StartByteIndex = moduloBaseByteIndex;
+        bufEdit->editParams->StartBitIndex = moduloBaseBitIndex;
+        numBitChange += bufEdit->editParams->newNumBits - bufEdit->editParams->curNumBits;
+    }
+    else
+    {
+        bufEdit->copyMode = CopyWhole; /* CopyWithEdit */
+    }
+    /* set the end of copy point */
+    bibRewindBits((inBuffer->numBytesRead<<3)+7-inBuffer->bitIndex,inBuffer,&error);
+    bibForwardBits((moduloBaseByteIndex<<3)+7-moduloBaseBitIndex+vopheader.time_base_incr+2, inBuffer);
+      
+    /* copy data */
+    CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
+    StartByteIndex=inBuffer->getIndex;
+    StartBitIndex=inBuffer->bitIndex;
+    bufEdit->copyMode = CopyWhole; /* CopyWhole */
+
+    /* copy and edit until the end of Vop header */
+    if (currentTimeIncResolution != outputTimeResolution /* && volheader.time_increment_resolution != 30 */
+        || vopheader.time_inc != CurNewTimeCode.time_inc)
+    {
+        for (num_bits = 1; ((currentTimeIncResolution-1) >> num_bits) != 0; num_bits++) 
+            {
+            }
+        /* prepare editing position */
+        if (!bufEdit->editParams)
+        {
+            bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+            if(!bufEdit->editParams)
+            {
+                //Memory not available 
+                return TX_ERR; //indicating error no memory;
+            }
+            else
+            {
+                bufEdit->numChanges = 1;
+            }
+            
+        }
+        bufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
+        bufEdit->editParams->StartByteIndex = timeIncByteIndex;
+        bufEdit->editParams->StartBitIndex = timeIncBitIndex;
+        bufEdit->editParams->curNumBits = num_bits;
+        bufEdit->editParams->newNumBits = numOutputTrBits;
+        bufEdit->editParams->newValue = vopheader.time_inc;
+
+        /* update time increment */
+        if (vopheader.time_inc != CurNewTimeCode.time_inc)
+        {
+            /*bufEdit->editParams->newValue = (int)(vopheader.time_inc * (float)outputTimeResolution /
+            (float)currentTimeIncResolution + 0.5); //CurNewTimeCode.time_inc;
+            */
+            bufEdit->editParams->newValue = CurNewTimeCode.time_inc;
+        }
+        numBitChange += bufEdit->editParams->newNumBits - bufEdit->editParams->curNumBits;
+    }
+
+    /* set the copy end point to the end of vop header */
+    bibForwardBits(inBuffer->bitsLeft - vopheaderBitLeft, inBuffer);
+
+    /* copy data */
+    CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
+    StartByteIndex=inBuffer->getIndex;
+    StartBitIndex=inBuffer->bitIndex;
+    
+    if ( vdcTemp->pictureParam.error_res_disable && (inBuffer->bitsLeft > 40) )   // 40 as below to avoid negative values below
+        {
+        // there are no VP headers => no need to search for VP start codes => can jump to the end.
+        // 40 = 5 bytes; in the end there is a start code that has 4 bytes
+        bibForwardBits( inBuffer->bitsLeft-40 ,inBuffer);
+        }
+
+    PRINT((_L("CopyEditVop() seek sync")));
+    /* find the next resync marker */
+    sncCode = sncSeekMPEGStartCode(inBuffer, vopheader.fcode_forward, vdcTemp->pictureParam.error_res_disable, 0, &error);
+    if ( sncCode == SNC_NO_SYNC )
+        {
+        PRINT((_L("CopyEditVop() sync NOT found, interrupt the copying and return")));
+        return TX_ERR;
+        }
+    PRINT((_L("CopyEditVop() sync found")));
+
+    /* record next resync position */
+    int resyncBitsLeft = inBuffer->bitsLeft;
+        
+    /* rewind stuffing bits */
+    sncRewindStuffing(inBuffer, &error);        
+    
+    if (!bufEdit->editParams)
+    {
+        bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+        if(!bufEdit->editParams)
+        {
+            //Memory not available 
+            return TX_ERR; //indicating error no memory;
+        }
+        else
+        {
+            bufEdit->numChanges = 1;
+        }
+    }
+
+    /* record position */
+    bufEdit->editParams->StartByteIndex = inBuffer->getIndex;
+    bufEdit->editParams->StartBitIndex = inBuffer->bitIndex;
+
+    /* calculate new stuffing bits */
+    bufEdit->editParams->curNumBits = inBuffer->bitsLeft - resyncBitsLeft;
+    /* calculate number of bits/bytes changed */
+    if (numBitChange<0)
+    {
+        outTirDecreased = 1;
+        numBitChange = -numBitChange;
+    }
+    int numByteChange = numBitChange >> 3;
+
+    if (outTirDecreased)
+    {
+        increaseBytes -= numByteChange;
+        stuffingLength = bufEdit->editParams->curNumBits + (numBitChange - (numByteChange << 3));
+        if (stuffingLength > 8)
+        {
+            stuffingLength -= 8;
+            increaseBytes --;
+        }
+    }
+    else
+    {
+        increaseBytes += numByteChange;
+        stuffingLength = bufEdit->editParams->curNumBits - (numBitChange - (numByteChange << 3));
+        if (stuffingLength <= 0)
+        {
+            stuffingLength += 8;
+            increaseBytes ++;
+        }
+    }
+        
+    /* adjust the output buffer size */
+    if (increaseBytes != 0)
+    {
+        outBuffer->size += increaseBytes;
+        if (increaseBytes>=0)
+        {
+            outBuffer->bitsLeft += (increaseBytes << 3);
+        }
+        else
+        {
+            outBuffer->bitsLeft -= ((-increaseBytes) << 3);
+        }
+    }
+
+    /* update edit statistics */
+    bufEdit->editParams->newNumBits = stuffingLength;
+    bufEdit->editParams->newValue = stuffingLength>0?(1<<(stuffingLength-1))-1:0;
+    if (stuffingLength != bufEdit->editParams->curNumBits)
+    {
+        bufEdit->copyMode = CopyWithEdit;
+    }
+
+    bibForwardBits(bufEdit->editParams->curNumBits, inBuffer);
+    /* copy data */
+    CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
+    /* record position */
+    StartByteIndex = inBuffer->getIndex;
+    StartBitIndex = inBuffer->bitIndex;
+        
+    do
+    {
+        /* if it is the start of a video packet, copy it with edit */
+        if (sncCode == SNC_VIDPACK )
+        {
+            /* copy video packet with edit */
+            int retVal = CopyEditVideoPacket(inBuffer, outBuffer, bufEdit, vdcTemp, aDecoderInfo, &vopheader, 
+                &sncCode, &StartByteIndex, &StartBitIndex);
+            if(retVal<0)
+            {
+                //error inside function return error
+                return TX_ERR;
+            }
+        }
+        else if (sncCode == SNC_EOB || sncCode == SNC_EOS || sncCode == SNC_GOV)
+        {
+            // since it is EOB, so end of sequence has occurred, so no more data, so exit       
+            break;
+        }
+    } 
+    while(sncCode != SNC_VOP);
+
+    /* copy the rest of bits */
+    if ((int)inBuffer->numBytesRead < FrameSizeInByte)
+    {
+        bufEdit->copyMode = CopyWhole;
+        bibForwardBits((FrameSizeInByte-StartByteIndex)<<3, inBuffer);
+        CopyStream(inBuffer,outBuffer,bufEdit,StartByteIndex,StartBitIndex);
+    }
+
+    PRINT((_L("CopyEditVop() end")));
+    return TX_OK;
+    }
+
+
+/*
+* CopyEditVideoPacket
+*    
+*
+* Parameters:
+*
+* Function:
+*    This function copies the video packet with edited time stamps, if HEC is enabled
+*
+* Returns:
+*    TX error codes
+*/
+
+int CopyEditVideoPacket(bibBuffer_t* aInBuffer, 
+                        bibBuffer_t* aOutBuffer, 
+                        bibBufferEdit_t* aBufEdit, 
+                        vdcInstance_t * aVdcTemp,
+                        vdeDecodeParamters_t* aDecoderInfo, 
+                        vdxVopHeader_t* aVopheader, 
+                        int* aSncCode, 
+                        int* aStartByteIndex, 
+                        int* aStartBitIndex)
+{
+    int16 error = 0;
+    int value = 0;
+    int bitsGot = 0;
+    int num_bits = 0;
+    int *bitErrorIndication = 0;
+    int numOutputTrBits = 0;
+    int resyncMarkerLength = 0;
+    int numMBs = 0;
+    int mbNumberLength = 0;
+    int startByteIndex = *aStartByteIndex;
+    int startBitIndex  = *aStartBitIndex;
+    int currentTimeIncResolution = 0;
+    int outputTimeResolution = 0;
+    MPEG4TimeParameter curNewTimeCode;
+    MPEG4TimeParameter* timeStamp = aDecoderInfo->aMPEG4TimeStamp;
+
+    int numBitChange = 0;
+    int increaseBytes = 0;
+    int stuffingLength = 0;
+    int outTirDecreased = 0;
+
+    currentTimeIncResolution = aVdcTemp->pictureParam.time_increment_resolution > 0? aVdcTemp->pictureParam.time_increment_resolution : 30000;
+    outputTimeResolution = *aDecoderInfo->aMPEG4TargetTimeResolution;
+    for (numOutputTrBits=1; ((outputTimeResolution-1)>>numOutputTrBits)!=0; numOutputTrBits++)
+        {
+        }
+    /* evaluate resync marker length */
+    resyncMarkerLength = (aVopheader->coding_type == 0 ? 17 : 16+aVopheader->fcode_forward);
+    /* evaluate MB number length */
+    numMBs = ((aVdcTemp->pictureParam.lumWidth+15)>>4) * ((aVdcTemp->pictureParam.lumHeight+15)>>4);
+    for (mbNumberLength = 1; ((numMBs-1) >> mbNumberLength) != 0; mbNumberLength++)
+        {
+        }
+
+    value = bibGetBits(resyncMarkerLength, aInBuffer, &bitsGot, bitErrorIndication, &error);    // resync marker
+    value = bibGetBits(mbNumberLength, aInBuffer, &bitsGot, bitErrorIndication, &error);    // mb number
+    value = bibGetBits(5, aInBuffer, &bitsGot, bitErrorIndication, &error); // quant scale
+    value = bibGetBits(1, aInBuffer, &bitsGot, bitErrorIndication, &error); // header extension code
+    
+    /* if HEC enabled, copy edit time increment fields in the video packet */
+    if (value == 1) 
+    {
+        /* copy-edit the part from the begin to the end of modulo base */
+        curNewTimeCode = *timeStamp;
+        
+        if (curNewTimeCode.modulo_time_base != aVopheader->time_base_incr)
+        {
+            if (!aBufEdit->editParams)
+            {
+                aBufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+                if(!aBufEdit->editParams)
+                {
+                    //Memory not available 
+                    return TX_ERR; //indicating error no memory;
+                }
+                else
+                {
+                    aBufEdit->numChanges = 1;
+                }
+            }
+            aBufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
+            aBufEdit->editParams->curNumBits = aVopheader->time_base_incr + 1;
+            aBufEdit->editParams->newNumBits = curNewTimeCode.modulo_time_base + 1;
+            aBufEdit->editParams->newValue = ((1 << curNewTimeCode.modulo_time_base) - 1) << 1;
+            aBufEdit->editParams->StartByteIndex = aInBuffer->getIndex;
+            aBufEdit->editParams->StartBitIndex = aInBuffer->bitIndex;
+            numBitChange += aBufEdit->editParams->newNumBits - aBufEdit->editParams->curNumBits;
+        } 
+        else
+        {
+            aBufEdit->copyMode = CopyWhole; /* CopyWithEdit */
+        }
+        /* set the end of copy point */
+        bibForwardBits(aVopheader->time_base_incr+2, aInBuffer); // includes one bit for Marker
+        
+        /* copy data */
+        CopyStream(aInBuffer,aOutBuffer,aBufEdit,startByteIndex,startBitIndex);
+        startByteIndex = aInBuffer->getIndex;
+        startBitIndex  = aInBuffer->bitIndex;
+        aBufEdit->copyMode = CopyWhole; /* CopyWhole */
+        
+        /* copy and edit 'time increment' field */
+        if (currentTimeIncResolution != outputTimeResolution /* && volheader.time_increment_resolution != 30 */
+            || aVopheader->time_inc != curNewTimeCode.time_inc)
+        {
+            for (num_bits = 1; ((currentTimeIncResolution-1) >> num_bits) != 0; num_bits++)
+                {
+                }
+            
+            /* prepare editing position */
+            if (!aBufEdit->editParams)
+            {
+                aBufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+                if(!aBufEdit->editParams)
+                {
+                    //Memory not available 
+                    return TX_ERR; //indicating error no memory;
+                }
+                else
+                {
+                    aBufEdit->numChanges = 1;
+                } 
+            } 
+            aBufEdit->copyMode = CopyWithEdit; /* CopyWithEdit */
+            aBufEdit->editParams->StartByteIndex = aInBuffer->getIndex;
+            aBufEdit->editParams->StartBitIndex = aInBuffer->bitIndex;
+            aBufEdit->editParams->curNumBits = num_bits;
+            aBufEdit->editParams->newNumBits = numOutputTrBits;
+            aBufEdit->editParams->newValue = aDecoderInfo->aMPEG4TimeStamp->time_inc;
+    
+            /* move to end position of 'time increment' field */
+            bibForwardBits(num_bits, aInBuffer);    // move to end of 'time increment' field
+            /* update time increment */
+            if (aVopheader->time_inc != curNewTimeCode.time_inc)
+            {
+                aBufEdit->editParams->newValue = curNewTimeCode.time_inc;
+            }
+            numBitChange += aBufEdit->editParams->newNumBits - aBufEdit->editParams->curNumBits;
+        } 
+       
+        /* copy time increment field with edit */
+        CopyStream(aInBuffer,aOutBuffer,aBufEdit,startByteIndex,startBitIndex);
+        startByteIndex=aInBuffer->getIndex;
+        startBitIndex=aInBuffer->bitIndex;
+        
+    }
+
+    /* copy rest of video packet */
+    
+    /* find the next resync marker */
+    *aSncCode = sncSeekMPEGStartCode(aInBuffer, aVopheader->fcode_forward, 0 /* VPs used*/, 0, &error);
+
+    /* record next resync position */
+    int resyncBitsLeft = aInBuffer->bitsLeft;
+        
+    /* rewind stuffing bits */
+    sncRewindStuffing(aInBuffer, &error);       
+        
+    if (!aBufEdit->editParams)
+    {
+        aBufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+        if(!aBufEdit->editParams)
+        { 
+            //Memory not available 
+            return TX_ERR; //indicating error no memory;
+        }
+        else
+        {
+            aBufEdit->numChanges = 1;
+        }
+    }
+
+    /* record position */
+    aBufEdit->editParams->StartByteIndex = aInBuffer->getIndex;
+    aBufEdit->editParams->StartBitIndex = aInBuffer->bitIndex;
+        
+    /* calculate new stuffing bits */
+    aBufEdit->editParams->curNumBits = aInBuffer->bitsLeft - resyncBitsLeft;
+
+    /* calculate number of bits/bytes changed */
+    if (numBitChange<0)
+    {
+        outTirDecreased = 1;
+        numBitChange = -numBitChange;
+    }
+    int numByteChange = numBitChange >> 3;
+        
+    /* evaluate change in buffer size */
+    if (outTirDecreased)
+    {
+        increaseBytes -= numByteChange;
+        stuffingLength = aBufEdit->editParams->curNumBits + (numBitChange - (numByteChange << 3));
+        if (stuffingLength > 8)
+        {
+            stuffingLength -= 8;
+            increaseBytes --;
+        }
+    }
+    else
+    {
+        increaseBytes += numByteChange;
+        stuffingLength = aBufEdit->editParams->curNumBits - (numBitChange - (numByteChange << 3));
+        if (stuffingLength <= 0)
+        {
+            stuffingLength += 8;
+            increaseBytes ++;
+        }
+    }
+        
+    /* adjust the output buffer size */
+    if (increaseBytes != 0)
+    {
+        aOutBuffer->size += increaseBytes;
+        if (increaseBytes>=0)
+        {
+            aOutBuffer->bitsLeft += (increaseBytes << 3);
+        }
+        else
+        {
+            aOutBuffer->bitsLeft -= ((-increaseBytes) << 3);
+        }
+    }
+    /* update edit statistics */
+    aBufEdit->editParams->newNumBits = stuffingLength;
+    aBufEdit->editParams->newValue = stuffingLength>0?(1<<(stuffingLength-1))-1:0;
+    if (stuffingLength != aBufEdit->editParams->curNumBits)
+    {
+        aBufEdit->copyMode = CopyWithEdit; // copy with edit
+    }
+    else 
+    {
+        aBufEdit->copyMode = CopyWhole; // copy whole 
+    }
+        
+    bibForwardBits(aBufEdit->editParams->curNumBits, aInBuffer);
+    /* copy video packet with stuffing bits edited */
+    CopyStream(aInBuffer, aOutBuffer, aBufEdit, startByteIndex, startBitIndex);
+    /* record position */
+    startByteIndex = aInBuffer->getIndex;
+    startBitIndex  = aInBuffer->bitIndex;
+        
+    /* update position for return */
+    *aStartByteIndex = startByteIndex;
+    *aStartBitIndex  = startBitIndex;
+
+    return TX_OK;
+}
+
+
+/*
+* sPutBits
+*
+* Parameters:
+*      outBuf           output buffer
+*           numBits         number of bits to output
+*           value           new value
+*
+* Function:
+*    Wrapper to sPutBits
+* Returns:
+*    None.
+* Error codes:
+*    None.
+*
+*/
+void vdtPutBits (void *buf,  int numBits, unsigned int value)
+{
+    /* must be in this type! "void" is used here only because of the interface with vlb.cpp */
+    sPutBits ((bibBuffer_t *)(buf),  numBits, value);
+}
+
+
+
+/* {{-output"vdtCopyBuffer.txt"}} */
+/*
+* vdtCopyBuffer
+*
+* Parameters:
+*
+* Function:
+*    This function copies some data from source buffer to destination buffer
+* Returns:
+*    None.
+* Error codes:
+*    None.
+*
+*/
+void vdtCopyBuffer(bibBuffer_t *SrcBuffer,bibBuffer_t *DestBuffer,
+                                     int ByteStart,int BitStart, int ByteEnd, int BitEnd)
+{
+    int startByteIndex = SrcBuffer->getIndex;
+    int startBitIndex  = SrcBuffer->bitIndex;
+    int bitsLeft = SrcBuffer->bitsLeft;
+    int numBytesRead = SrcBuffer->numBytesRead;
+    
+    CopyBuffer(SrcBuffer,DestBuffer, ByteStart, BitStart, ByteEnd, BitEnd);
+    
+    /* recover the postion */
+    SrcBuffer->getIndex = startByteIndex ;
+    SrcBuffer->bitIndex = startBitIndex;
+    SrcBuffer->bitsLeft = bitsLeft;
+    SrcBuffer->numBytesRead = numBytesRead;
+}
+
+
+
+
+/* {{-output"vdtStuffBitsMPEG4.txt"}} */
+/*
+* vdtStuffBitsMPEG4
+*
+* Parameters:
+*          outBuf           output buffer
+*
+* Function:
+*    This function puts some stuffing bits to the output buffer
+*   bits need to be stuffed in the output buffer at the end of vp in all cases (bw or not)
+* Returns:
+*    None.
+* Error codes:
+*    None.
+*
+*/
+void vdtStuffBitsMPEG4(bibBuffer_t *outBuffer)
+{
+    const int stuffingBits[8][2] = { {1,0}, {2,1}, {3,3}, {4,7}, {5,15}, {6,31}, {7,63}, {8,127} };
+  VDTASSERT(outBuffer->baseAddr);
+    
+    /* find the number of stuffing bits to insert in the output buffer */
+    int bi = outBuffer->bitIndex;
+    int newNumBits = stuffingBits[bi][0]; 
+    int newValue = stuffingBits[bi][1]; 
+    sPutBits(outBuffer, newNumBits, newValue);
+        
+    return;
+}
+
+
+/*************************************************************/
+
+
+/* {{-output"sResetH263IntraDcUV.txt"}} */
+/*
+* sResetH263IntraDcUV
+*
+* Parameters: output buffer
+*             uValue
+*             vValue
+*
+* Function:
+*    This function reset the chrominace INTRADC when black and white color effect is applied 
+* Returns:
+*    none
+* Error codes:
+*    None.
+*
+*/
+inline void sResetH263IntraDcUV(bibBuffer_t *DestBuffer, TInt uValue, TInt vValue)
+{
+    /* For the Color Effects Fill the U and V buffers with the 
+    corresponding color values */
+   
+    sPutBits(DestBuffer, 8, uValue);
+    sPutBits(DestBuffer, 8, vValue);
+}
+
+
+/* {{-output"vdtGetPMBBlackAndWhiteMCBPC.txt"}} */
+/*
+* vdtGetPMBBlackAndWhiteMCBPC
+*
+* Parameters: 
+*
+* Function:
+*    This function compute the new mcbpc for black and white effect *
+* Returns:
+*    the length of the input mcbpc.
+* Error codes:
+*    None.
+*
+*/
+int vdtGetPMBBlackAndWhiteMCBPC(int& new_len, int& new_val, int mcbpc)
+{
+    int cur_index, new_index, cur_len;
+        
+    const tVLCTable sCBPCPType[21] = 
+    {
+    {1, 1}, {3, 4}, {2, 4}, {5, 6},
+    {3, 3}, {7, 7}, {6, 7}, {5, 9}, 
+    {2, 3}, {5, 7}, {4, 7}, {5, 8},
+    {3, 5}, {4, 8}, {3, 8}, {3, 7},
+    {4, 6}, {4, 9}, {3, 9}, {2, 9}, 
+    {1, 9}
+    };
+    
+     /* evaluate MCBPC parameters */
+    int cur_cbpc = mcbpc & 3;       
+    int new_cbpc = 0;       // cpbc=0 indicates chroma is 0
+    int mbType; 
+    
+    mbType = mcbpc / 4;
+    /* evaluate indices in table */
+    cur_index = mbType * 4 + cur_cbpc;  
+    new_index = mbType * 4 + new_cbpc;  
+    
+    /* retrieve values */
+    cur_len = sCBPCPType[cur_index].length;
+    new_len = sCBPCPType[new_index].length;
+    new_val = sCBPCPType[new_index].code;
+    
+    return cur_len;
+}
+
+
+/* {{-output"vdtGetIMBBlackAndWhiteMCBPC.txt"}} */
+/*
+* vdtGetIMBBlackAndWhiteMCBPC
+*
+* Parameters: None
+*
+* Function:
+*    This function compute the new mcbpc for black and white effect
+* Returns:
+*    the length of the input mcbpc.
+* Error codes:
+*    None.
+*
+*/
+int vdtGetIMBBlackAndWhiteMCBPC(int& new_len, int& new_val, int mcbpc)
+{
+    int cur_index, new_index, cur_len;
+    
+    const tVLCTable sCBPCIType[9] = 
+    {
+    {1, 1}, {1, 3}, {2, 3}, {3, 3}, {1, 4},
+    {1, 6}, {2, 6}, {3, 6}, {1, 9}
+    };
+    
+    /* evaluate MCBPC parameters */
+    int cur_cbpc = mcbpc & 3;       
+    int new_cbpc = 0;       // cpbc=0 indicates chroma is 0
+    int mbType = (mcbpc <4)?3:4;
+    
+    /* evaluate indices in table */
+    cur_index = (mbType == 3 ? 0 : 4) + cur_cbpc;   
+    new_index = (mbType == 3 ? 0 : 4) + new_cbpc;   
+    
+    /* retrieve values */
+    cur_len = sCBPCIType[cur_index].length;
+    new_len = sCBPCIType[new_index].length;
+    new_val = sCBPCIType[new_index].code;
+    
+    return cur_len;
+}
+
+
+
+
+
+/* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
+/*
+* vdtGetVideoBitstreamInfo
+*
+* Parameters: 
+*
+* Function:
+*    This function provides the bitstream info to the processor *
+* Returns:
+*    VDE error codes
+* Error codes:
+*    None.
+*
+*/
+int vdtGetVideoBitstreamInfo(bibBuffer_t *inBuffer, vdeDecodeParamters_t *aInfoOut, int *aByteIndex, int *aBitIndex)
+{
+    int numBitsGot,
+    bitErrorIndication = 0;
+    int16 error = 0;
+    u_int32 bits;
+    int timeResolution = 0;
+    TVedVideoBitstreamMode streamMode = EVedVideoBitstreamModeUnknown;
+    vdxVolHeader_t volHeader;  
+    volHeader.user_data = NULL;
+    
+    bits = bibShowBits(32, inBuffer, &numBitsGot, &bitErrorIndication, &error);
+    if (error)
+    {
+        streamMode = EVedVideoBitstreamModeUnknown;
+        goto exitFunction;
+    }
+    /* If PSC */
+    if ((bits >> 10) == 32) {
+        streamMode = EVedVideoBitstreamModeH263;
+    } 
+
+    /* Else check for Visual Sequence, Visual Object or Video Object start code */
+    else if ((bits == MP4_VOS_START_CODE) || 
+        (bits == MP4_VO_START_CODE) ||
+        ((bits >> MP4_VID_ID_CODE_LENGTH) == MP4_VID_START_CODE) ||
+        ((bits >> MP4_VOL_ID_CODE_LENGTH) == MP4_VOL_START_CODE)) 
+    {
+        
+        /* read the Stream headers from the bitstream */
+        if ((vdxGetVolHeader(inBuffer, &volHeader, &bitErrorIndication, 1, aByteIndex, aBitIndex, NULL) != 0) ||
+            (bitErrorIndication != 0)) 
+        {
+            goto exitFunction;
+        }   
+
+        timeResolution = volHeader.time_increment_resolution;
+        streamMode = sGetMPEG4Mode(volHeader.error_res_disable, volHeader.data_partitioned, volHeader.reversible_vlc);
+        bits = bibShowBits(22, inBuffer, &numBitsGot, &bitErrorIndication, &error);
+        if (error)
+            goto exitFunction;
+        
+      /* Check if H.263 PSC follows the VOL header, in which case this is 
+        MPEG-4 with short header and is decoded as H.263 */
+        if ( bits == 32 ) 
+        {
+            streamMode = EVedVideoBitstreamModeMPEG4ShortHeader;
+        }
+    }
+
+    /* Else no H.263 and no MPEG-4 start code detected  */
+    else {
+        streamMode = EVedVideoBitstreamModeUnknown;
+    }
+    
+exitFunction:
+    /* copy the got user data to the core data structure */
+    if (volHeader.user_data != NULL) 
+    {
+        free(volHeader.user_data);
+    }
+    
+    bibRewindBits( bibNumberOfFlushedBits( inBuffer ), inBuffer, &error );
+    aInfoOut->streamMode = streamMode;
+    aInfoOut->iTimeIncrementResolution = timeResolution;
+    return TX_OK;
+}
+
+
+
+
+
+/* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
+/*
+* sQuantizeMB
+*
+* Parameters: 
+*    mbdata          Contains the actual MB data to be quantized
+*    oldQuant: 
+*    newQuant:
+*    intra
+*
+* Function:
+*    This function requantizes the AC/DCT data for one MB, used in MPEG4 -> H263 transcoding 
+* Returns:
+*    Coded Block Pattern.
+* Error codes:
+*    None.
+*
+*/
+static void sQuantizeMB(int *mbdata, int oldQuant, int newQuant, int intra, int colorEffect)
+{
+#define  SIGN(x)          (((x)<0) ? -1:1 )
+    int   coeffCnt;
+    int   *block;
+    int   blkCnt;
+    
+    for (blkCnt = 0; blkCnt < (colorEffect ? 4 : 6); blkCnt++)
+    {   
+        block = &mbdata[blkCnt * BLOCK_COEFF_SIZE];
+        for (coeffCnt = (intra == VDX_MB_INTRA); coeffCnt < BLOCK_COEFF_SIZE;
+             coeffCnt++)
+             {
+                 if (block[coeffCnt])
+                 {
+                     int level = abs(block[coeffCnt]);
+                     int sign = SIGN(block[coeffCnt]);
+                     int rcoeff;
+                     // dequantize 
+                     if ((oldQuant % 2) == 1)
+                         rcoeff = oldQuant * ((level << 1) + 1);
+                     else
+                         rcoeff = oldQuant * ((level << 1) + 1) - 1;
+                     
+                     rcoeff = min (2047, max (-2048, sign * rcoeff));
+                     
+                     // requantize
+                     if (intra == VDX_MB_INTRA)
+                     {
+                         level = (abs (rcoeff)) / (newQuant << 1);
+                     }
+                     else
+                     {
+                         level = (abs (rcoeff) - (newQuant >> 1)) / (newQuant << 1);
+                         /* clipping to [-127,+127] */
+                     }
+                     
+                     /* clipping to [-127,+127] */
+                     block[coeffCnt] = min (127, max (-127, sign * level));
+                 }
+                 else
+                 {
+                     /* Nothing */
+                 }
+             }
+    }
+    return ;
+}   
+
+
+
+
+/* {{-output"vdtGetVideoBitstreamInfo.txt"}} */
+/*
+* vdtChangeVosHeaderRegResyncL
+*
+* Parameters: 
+*
+* Function:
+*    This function finds the error resillence bit and change it if necessary
+*      to make it Regular Resynchronization mode 
+* Returns:
+*    ETrue if buffer changed.
+* Error codes:
+*    None
+*
+*/
+TBool vdtChangeVosHeaderRegResyncL(TPtrC8& aInputBuffer, TUint aBufferSize)
+{
+    int16   errorCode = 0;             /* return code for bib functions */
+    bibBuffer_t *buffer;                   /* input buffer */
+    
+    /* Create bit buffer */
+    buffer = bibCreate((TAny*)aInputBuffer.Ptr(), aBufferSize, &errorCode);
+    if (!buffer || errorCode)
+        return EFalse;
+     
+    int startByte = 0, startBit = 7;
+    vdeDecodeParamters_t decInfo; 
+    vdtGetVideoBitstreamInfo(buffer, &decInfo, &startByte, &startBit);
+     
+    if (decInfo.streamMode == EVedVideoBitstreamModeMPEG4Regular)
+    {
+        char *temp = (char *) (TAny*)aInputBuffer.Ptr();
+        unsigned char patern[8] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
+        temp[startByte] &= patern[startBit]; // change the error resillence bit to 0;
+        
+        /* Delete bit buffer */
+        bibDelete(buffer, &errorCode);
+        return ETrue;
+    }
+    else
+    {
+      /* Delete bit buffer */
+        bibDelete(buffer, &errorCode);
+        return EFalse;
+    }
+}
+
+/*
+* CMPEG4Transcoder
+*
+* Parameters: 
+*
+* Function:
+*    Constructor
+*
+*/
+CMPEG4Transcoder::CMPEG4Transcoder(const vdeInstance_t *aVDEInstance, bibBuffer_t *aInBuffer, bibBuffer_t *aOutBuffer)
+{
+    VDTASSERT(aVDEInstance); 
+    VDTASSERT(aInBuffer);
+    VDTASSERT(aOutBuffer);
+    
+    /* passing the arguments */
+    iVDEInstance = aVDEInstance;
+    iInBuffer  = aInBuffer;
+    iOutBuffer = aOutBuffer;
+    
+    /* Color Toning */
+    iMBType      = NULL;
+    iCurQuant    = 0;
+    iColorEffect = aVDEInstance->iColorEffect;
+    iColorToneU  = aVDEInstance->iColorToneU;
+    iColorToneV  = aVDEInstance->iColorToneV;
+    iRefQuant    = aVDEInstance->iRefQp;
+    iDcScaler    = GetMpeg4DcScalerUV(iRefQuant);
+        
+    iDoModeTranscoding = EFalse;
+    iDoTranscoding = (iColorEffect || iDoModeTranscoding);
+    iTargetFormat = EVedVideoTypeMPEG4SimpleProfile;
+    iStuffingBitsUsed = 0;
+    
+    /* default values */
+    iLastMBNum = -1;
+    iCurMBNum = 0;
+
+    /* initialize here but will be changed later to proper value */
+    iOutputMpeg4TimeIncResolution = KOutputMpeg4TimeIncResolution;  
+
+    iNumMBsInOneVOP = (iVDEInstance->lumHeight * iVDEInstance->lumWidth) >> 8;  // /256
+    iMBsinWidth = iVDEInstance->lumWidth >> 4; 
+    iNumMBsInGOB = iVDEInstance->lumWidth >> 4; 
+    
+
+    iMBList = NULL;
+    iH263DCData = NULL;
+    h263mbi = NULL;
+
+    
+    iH263MBVPNum = NULL;
+    iErrorResilienceStartByteIndex = KDataNotValid;
+    iErrorResilienceStartBitIndex  = KDataNotValid;
+    
+    iVideoPacketNumInMPEG4 = 0; // the video packet number this MB belongs to, NOTE: the first GOB doesn't have a GOB header
+    iCurMBNumInVP = -1;
+    fFirstFrameInH263 = EFalse;
+    
+    return;
+}
+
+/*
+* ~CMPEG4Transcoder
+*
+* Parameters: 
+*
+* Function:
+*    Destructor
+*
+*/
+CMPEG4Transcoder::~CMPEG4Transcoder()
+{
+    if (iCurIMBinstance)
+    {
+        free(iCurIMBinstance);
+    }
+    if (iCurPMBinstance)
+    {
+        free(iCurPMBinstance);
+    }
+    if (bufEdit.editParams)
+    {
+        free(bufEdit.editParams);
+    }
+    
+    // for H263
+    if (iH263MBVPNum)
+    {
+        free(iH263MBVPNum);
+    }
+    
+    // for color toning
+    if (iMBType)
+    {
+        free(iMBType);
+    }
+
+
+    
+    if (iH263DCData)
+    {
+        for (int i = 0; i < iNumMBsInOneVOP; i++)
+        {
+            free(iH263DCData[i]);
+        }
+        free(iH263DCData);
+    }
+
+    if ( ( (iTargetFormat == EVedVideoTypeH263Profile0Level10) || 
+           (iTargetFormat == EVedVideoTypeH263Profile0Level45) ) &&
+           iBitStreamMode != EVedVideoBitstreamModeMPEG4ShortHeader &&
+           iBitStreamMode != EVedVideoBitstreamModeH263 &&
+           h263mbi)
+    {
+        free(h263mbi);
+    }
+    
+    if ( iOutBuffer )
+        {
+        
+        PRINT((_L("CMPEG4Transcoder: finish one frame successfully, buffer size %d"), 
+           iOutBuffer->getIndex));
+        }
+        
+#ifdef _DEBUG
+    if (iOutBuffer->getIndex > KInitialBufferSize)
+    {
+        PRINT((_L("CMPEG4Transcoder: Output buffer size from engine is not big enough! check KInitialBufferSize")));
+        
+    }
+#endif
+    if ( iOutBuffer )
+        {
+        VDTASSERT(iOutBuffer->getIndex < KInitialBufferSize);
+        }
+}
+
+/*
+* H263EscapeCoding
+*
+* Parameters: 
+*
+* Function:
+*    Indicates whether escape vlc coding is used in one block
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::H263EscapeCoding(int aIndex, int fEscapeCodeUsed)
+{
+    iEscapeCodeUsed[aIndex] = fEscapeCodeUsed;
+}
+
+/*
+* SetTranscoding
+*
+* Parameters: 
+*
+* Function:
+*    Indicates whether we need to do MPEG4 bitstream transcoding
+* Returns:
+*    TX error codes
+* Error codes:
+*    None
+*
+*/
+int CMPEG4Transcoder::SetTranscoding(vdeDecodeParamters_t *aDecoderInfo)
+{
+    iColorEffect = aDecoderInfo->aColorEffect;
+    iColorToneU = aDecoderInfo->aColorToneU; 
+    iColorToneV = aDecoderInfo->aColorToneV;
+    iBitStreamMode = (TVedVideoBitstreamMode)aDecoderInfo->streamMode;
+    
+    iTargetFormat = aDecoderInfo->aOutputVideoFormat; 
+    iDoModeTranscoding = aDecoderInfo->fModeChanged ? ETrue: EFalse;
+    iDoTranscoding = (iColorEffect || iDoModeTranscoding);
+
+    /* set to proper value */
+    iOutputMpeg4TimeIncResolution = *(aDecoderInfo->aMPEG4TargetTimeResolution); 
+
+    /* allocate buffer for MPEG4 - > H263 transcoding */
+    /* the following is used if spatial domain processing is not done */
+        
+    if ( ( (iTargetFormat == EVedVideoTypeH263Profile0Level10) ||
+           (iTargetFormat == EVedVideoTypeH263Profile0Level45) ) &&
+           iBitStreamMode != EVedVideoBitstreamModeMPEG4ShortHeader &&
+           iBitStreamMode != EVedVideoBitstreamModeH263)
+    {
+        h263mbi = (tMBInfo*) malloc (sizeof(tMBInfo) * iNumMBsInOneVOP);
+        if (!h263mbi) 
+        {
+            PRINT((_L("CMPEG4Transcoder::SetTranscoding - h263mbi creation failed")));
+            deb("CMPEG4Transcoder::SetTranscoding - h263mbi creation failed\n");
+
+            return TX_ERR;
+        }
+        memset(h263mbi, 0, sizeof(tMBInfo) * iNumMBsInOneVOP);
+    }
+    
+    return TX_OK;
+}
+
+
+
+
+/*
+* BeginOneVideoPacket
+*
+* Parameters: 
+*
+* Function:
+*    Records the position before one Video packet is processed
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::BeginOneVideoPacket(dvpVPInParam_t *aVPin)
+{
+    VDTASSERT(iInBuffer); 
+    VDTASSERT(aVPin);
+    
+    iCurVPIn = aVPin;
+    iVPStartByteIndex = iInBuffer->getIndex;
+    iVPStartBitIndex  = iInBuffer->bitIndex;
+    
+    iCurMBNumInVP = -1;
+
+    iStuffingBitsUsed = 0;
+    
+    iVopCodingType = aVPin->pictParam->pictureType;
+    iBitStreamMode = sGetMPEG4Mode(aVPin->pictParam->error_res_disable,
+        aVPin->pictParam->data_partitioned, aVPin->pictParam->reversible_vlc);
+}
+
+
+/*
+* sConstructH263PicHeader
+*
+* Parameters: 
+*        lBitOut                output buffer
+*        quant                quant value to be put in header
+*           picType             VDX_VOP_TYPE_P or VDX_VOP_TYPE_I
+*           tr                      time increament
+* Function:
+*    Writes the pic header into bit-stream for one MPEG4 frame
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void sConstructH263PicHeader(bibBuffer_t *lBitOut, int picType, int quant, int tr, int aVOPNotCoded, int aFormat)
+
+{
+    if (aVOPNotCoded)
+    {
+        return;
+    }
+    /* ShortVideoStartMarker */
+    sPutBits(lBitOut, 22, SHORT_VIDEO_START_MARKER);
+    /* TemporalReference */
+    sPutBits(lBitOut, 8, (tr & 0x000000ff));
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);
+    /* Zero Bit */
+    sPutBits(lBitOut, 1, 0);
+    /* SplitScreenIndicator = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* DocumentCameraIndicator = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* FullPictureFreezeRelease = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* Source Fromat */
+    sPutBits(lBitOut, 3, aFormat);
+    /* PictureCodingType 0 for intra, 1 for inter */
+    sPutBits(lBitOut, 1, picType == VDX_VOP_TYPE_P);
+    /* UMV= 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* SAC = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* Advanced Prediction = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* PB frame = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* VOPQuant */
+    sPutBits(lBitOut, 5, quant);
+    /* ZeroBIt */
+    sPutBits(lBitOut, 1, 0);
+    /* Pei = 0 */
+    sPutBits(lBitOut, 1, 0);        
+}
+
+
+/*
+* VOPHeaderEnded
+*
+* Parameters: 
+*
+* Function:
+*    Copy the VOP Header to output buffer
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::VOPHeaderEnded(int aStartByteIndex, int aStartBitIndex, 
+    int aQuant, int aPicType, int aFrameNum, int aVOPNotCoded)
+{
+    const int KNumMbInSqcif = 48; 
+    const int KNumMbInQcif = 99; 
+    const int KNumMbInCif = 396; 
+
+    if (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45)
+    {
+        int sourceFormat = 2; // qcif
+        /* note: other formate not supported */
+        if (iNumMBsInOneVOP == KNumMbInSqcif)  /* sqcif */
+        {
+            sourceFormat = 1;  // sqcif
+        }
+        else if (iNumMBsInOneVOP == KNumMbInQcif) /* qcif */
+        {
+            sourceFormat = 2;  // qcif
+        }
+        else if (iNumMBsInOneVOP == KNumMbInCif) /* cif */
+        {
+            sourceFormat = 3;  // cif
+        }
+        sConstructH263PicHeader(iOutBuffer, aPicType, aQuant, 0, aVOPNotCoded, sourceFormat);
+        PRINT((_L("CMPEG4Transcoder: MPEG4 -> H263: picture header generated")));
+    }
+  /* Copy the VOP header */
+  else 
+    {
+        bufEdit.copyMode = CopyWhole; // whole
+        CopyStream(iInBuffer,iOutBuffer,&bufEdit,aStartByteIndex,aStartBitIndex);
+    }
+  iPreQuant = aQuant;
+  iStuffingBitsUsed = 0;
+
+  iCurQuant = aQuant;
+  /* Color Toning */
+  if (!aFrameNum || !iRefQuant)
+  {
+     iRefQuant = iCurQuant;
+     iDcScaler = GetMpeg4DcScalerUV(iRefQuant); 
+  }
+
+}
+
+
+/*
+* VOPEnded
+*
+* Parameters: 
+*
+* Function:
+*    This function is called when one VOP has ended
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::VOPEnded()
+{
+    /* check if MBs are lost */
+    int dataPartitioned = (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC 
+        || iBitStreamMode == EVedVideoBitstreamModeMPEG4DP ||  iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP);
+    
+    if (iLastMBNum != iNumMBsInOneVOP - 1 && !(dataPartitioned && !iDoModeTranscoding))
+    {
+        for (int i = iLastMBNum+1; i < iNumMBsInOneVOP; i++)
+        {
+            /* output  1 bit COD */
+            sPutBits (iOutBuffer, 1, 1);
+        }
+    }
+    
+    iLastMBNum = iNumMBsInOneVOP - 1; 
+    /* bits need to be stuffed in the output buffer at the end VOP */
+    if (!dataPartitioned && iTargetFormat == EVedVideoTypeMPEG4SimpleProfile)
+    {
+        if (!iStuffingBitsUsed)
+        {
+            vdtStuffBitsMPEG4(iOutBuffer);
+        }
+        iStuffingBitsUsed = 1;
+    }
+    else if (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45)
+    {
+        sStuffBitsH263(iOutBuffer);
+    }
+    
+  PRINT((_L("CMPEG4Transcoder: VOPEnded. color effect: %d, format convert %d, do transcoding: %d streammode: %d, outputformat: %d "), 
+       iColorEffect, iDoModeTranscoding, iDoTranscoding, iBitStreamMode, iTargetFormat));
+}
+
+/*
+* AfterOneVideoPacketHeader
+*
+* Parameters: 
+*
+* Function:
+*    This function is called after retreiving the VP
+*    Records the position before the content of the video packet is processed
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::AfterVideoPacketHeader(dvpVPInOutParam_t *aVPInfo)
+{
+    VDTASSERT(aVPInfo); 
+    iCurVPInOut = aVPInfo;
+    
+    iVPHeaderEndByteIndex = iInBuffer->getIndex;
+    iVPHeaderEndBitIndex  = iInBuffer->bitIndex;
+    
+    /* Color Toning */
+    iCurQuant = aVPInfo->quant; 
+    
+    /* Copy the VP header to output stream. Note; the first VP does not have a VP header */
+    if (iTargetFormat == EVedVideoTypeMPEG4SimpleProfile)
+    {
+       bufEdit.copyMode = CopyWhole; /* whole */
+         CopyStream(iInBuffer,iOutBuffer,&bufEdit,iVPStartByteIndex,iVPStartBitIndex);
+    }
+}
+
+
+/*
+* OneVPEnded
+*
+* Parameters: 
+*
+* Function:
+*    This function is called after one VP  contents are retrieved
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::OneVPEnded()
+{
+    if (!iDoTranscoding)
+    {
+        /* no transcoding, copy whole content VP */
+        bufEdit.copyMode = CopyWhole; 
+        CopyStream(iInBuffer,iOutBuffer,&bufEdit,iVPHeaderEndByteIndex,iVPHeaderEndBitIndex);
+        iStuffingBitsUsed = 1;// also stuffing is copied
+    }
+    else
+    {
+        int dataPartitioned = (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC 
+            || iBitStreamMode == EVedVideoBitstreamModeMPEG4DP ||  iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP);
+        int nextExpectedMBNum = iCurVPInOut->currMBNum;
+        
+        if (dataPartitioned && !iDoModeTranscoding)
+        {
+        /* if data is partitioned and we are not doing format transcoding,
+        not coded MBs info is already in data partition 1
+            */
+        }
+        else
+        {
+            /* MBs are lost or not coded,  */
+            for (int i = iLastMBNum+1; i < nextExpectedMBNum; i++)
+            {
+                /* output  1 bit COD */
+                sPutBits (iOutBuffer, 1, 1);
+            }
+        }
+        
+        iLastMBNum = nextExpectedMBNum - 1; 
+        /* bits need to be stuffed in the output buffer at the end of vp in all cases (bw or not) */
+        if (iTargetFormat == EVedVideoTypeMPEG4SimpleProfile) 
+        {
+            if (!iStuffingBitsUsed)
+            {
+                vdtStuffBitsMPEG4(iOutBuffer);
+            }
+            iStuffingBitsUsed = 1;
+        }
+    }
+}
+
+
+
+/*
+* BeginOneMB
+*
+* Parameters: 
+*
+* Function:
+*    Records the position before one MB is processed
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::BeginOneMB(int aMBNum)
+{
+    VDTASSERT(iInBuffer); 
+    
+    iMBStartByteIndex = iInBuffer->getIndex;
+    iMBStartBitIndex  = iInBuffer->bitIndex;
+    iCurMBNum = aMBNum;
+    
+    // Color Toning
+    iCurMBNumInVP++;
+    
+    if ((iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263) && iDoModeTranscoding)
+    {
+       /* H263 -> MPEG4  */
+       VDTASSERT(iH263MBVPNum);
+         iH263MBVPNum[iCurMBNum]= iVideoPacketNumInMPEG4;
+    }
+}
+
+/*
+* BeginOneBlock
+*
+* Parameters: 
+*
+* Function:
+*    Records the position before one block in MB is processed
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::BeginOneBlock(int aBlockIndex)
+{
+    VDTASSERT(aBlockIndex >= 0 && aBlockIndex < 6); 
+    
+    iBlockStartByteIndex[aBlockIndex] = iInBuffer->getIndex;
+    iBlockStartBitIndex[aBlockIndex]  = iInBuffer->bitIndex;
+}
+
+
+/*
+* OneIMBDataStarted
+*
+* Parameters: 
+*
+* Function:
+*    This function is called after the MB header is read; start one IMB, 
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::OneIMBDataStarted(vdxIMBListItem_t *aMBInstance)
+{
+    VDTASSERT(aMBInstance); 
+    VDTASSERT(iCurIMBinstance);
+    iMBCodingType = VDX_MB_INTRA;
+    iVopCodingType = VDX_VOP_TYPE_I;
+    iMBType[iCurMBNum] = iMBCodingType;
+
+    
+    memcpy(iCurIMBinstance, aMBInstance, sizeof(vdxIMBListItem_t)); 
+}
+
+/*
+* OnePMBDataStarted
+*
+* Parameters: 
+*
+* Function:
+*    This function is called after the MB header is read; start one PMB, 
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::OnePMBDataStarted(vdxPMBListItem_t *aMBInstance)
+{
+    VDTASSERT(aMBInstance); 
+    VDTASSERT(iCurPMBinstance);
+    
+    iMBCodingType = aMBInstance->mbClass;
+    iVopCodingType = VDX_VOP_TYPE_P;
+    iMBType[iCurMBNum] = iMBCodingType;
+
+    memcpy(iCurPMBinstance, aMBInstance, sizeof(vdxPMBListItem_t)); 
+}
+
+
+
+/*
+* OneIMBDataStartedDataPartitioned
+*
+* Parameters: 
+*
+* Function:
+*    Add one IMB instance, It is done after parsing Part1 and Part2 before the block data for current MB
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::OneIMBDataStartedDataPartitioned(vdxIMBListItem_t *aMBInstance, dlst_t *aMBList, int aCurrMBNumInVP, int aMBNum)
+{
+    VDTASSERT(aMBInstance); // at this point, the instance should not be null
+    VDTASSERT(aMBList);
+    
+    memcpy(iCurIMBinstance, aMBInstance, sizeof(vdxIMBListItem_t)); 
+    iCurMBNumInVP = aCurrMBNumInVP;
+    iCurMBNum = aMBNum;
+    iMBList = aMBList;
+    iMBCodingType = VDX_MB_INTRA;
+    iVopCodingType = VDX_VOP_TYPE_I;
+    iMBType[iCurMBNum] = iMBCodingType;
+    
+    if (!iCurMBNumInVP && iDoTranscoding) 
+    {
+        if (!iDoModeTranscoding)
+        {
+          /* We are not doing bitstream transcoding,  
+            we have color effect here and need to reconstruct data partitions.
+            */
+            ReconstructIMBPartitions();
+        }
+    }
+}
+
+/*
+* OnePMBDataStartedDataPartitioned
+*
+* Parameters: 
+*
+* Function:
+*    Add one IMB instance, It is done after parsing Part1 and Part2 before the block data for current MB
+*    Note: PMB may be INTRA coded.
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::OnePMBDataStartedDataPartitioned(vdxPMBListItem_t *aMBInstance, dlst_t *aMBList, int aCurrMBNumInVP, int aMBNum)
+{
+    VDTASSERT(aMBInstance); /* at this point, the instance should not be null */
+    VDTASSERT(aMBList);
+    
+    memcpy(iCurPMBinstance, aMBInstance, sizeof(vdxPMBListItem_t)); 
+    iCurMBNumInVP = aCurrMBNumInVP;
+    iCurMBNum = aMBNum;
+    iMBList = aMBList;
+    iMBCodingType = aMBInstance->mbClass;
+    iVopCodingType = VDX_VOP_TYPE_P;
+    iMBType[iCurMBNum] = iMBCodingType;
+    
+    if (!aMBInstance->fCodedMB && iDoModeTranscoding)
+    {
+        /* this MB is not coded and need to be converted to target mode,
+        out put the possible MB stuffing bits and COD
+        */
+        /* MB stuffing bits if they exsit */
+        vdtCopyBuffer(iInBuffer, iOutBuffer,
+            aMBInstance->DataItemStartByteIndex[11], aMBInstance->DataItemStartBitIndex[11],
+            aMBInstance->DataItemEndByteIndex[11], aMBInstance->DataItemEndBitIndex[11]);
+        /* It is a not-coded MB, output  1 bit COD (it always exists in P frame) */
+        sPutBits (iOutBuffer, 1, 1);
+        iLastMBNum = iCurMBNum;
+    }
+    else if (!iCurMBNumInVP && iDoTranscoding) 
+    {
+        if (!iDoModeTranscoding)
+        {
+        /* We are not doing bitstream transcoding, 
+        we have color effect here and need to reconstruct data partitions.
+            */
+            ReconstructPMBPartitions();
+        }
+    }
+}
+
+
+
+/*
+* TranscodingOneMB
+*
+* Parameters: 
+*
+* Function:
+*    Transcoding one MB, which may include dequantization, requantization , and re-encoding
+* Returns:
+*    DMD error codes since called from decmbdct
+*
+*/
+int CMPEG4Transcoder::TranscodingOneMB(dmdPParam_t *aParam = NULL)
+{
+/* Because it has block data, this MB must be a coded MB,
+which means the position indicated by iMBStartByteIndex and iMBStartBitIndex starts with a MCBPC 
+    */
+    VDTASSERT(!(!iCurPMBinstance->fCodedMB && iMBCodingType == VDX_MB_INTER));
+    
+    if (!iDoTranscoding)
+        {
+        iLastMBNum = iCurMBNum; // need to update the variable to avoid marking this as noncoded MB
+        return TX_OK;
+        }
+    
+    int dataPartitioned = (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC 
+        || iBitStreamMode == EVedVideoBitstreamModeMPEG4DP ||  iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP);
+    
+    if (dataPartitioned)
+    {
+        /* since we need to handle MB stuffing bits, which are handle outside the transcoder in other modes,
+        not coded MBs and MB stuffing bits are handled in OnePMBDataStartedDataPartitioned, 
+             ReconstuctI/PMBPartitios or ConstructRegularMPEG4MBData
+        */
+    }
+    else if(iCurMBNum != iLastMBNum + 1 )
+    {
+        /* if previous MBs are lost or not coded, we copy one MB with COD = 1; */
+        for (int i = 0 ; i < iCurMBNum - iLastMBNum - 1; i++)
+        {
+            /* output  1 bit COD */
+            sPutBits (iOutBuffer, 1, 1);
+        }
+    }
+    
+    int newMCBPCLen = 0;
+    int newMCBPC = 0;
+    int oldMCBPCLen = 0;
+    
+    /* determine whether to change mcbpc */
+    if (iColorEffect)
+    {
+        if (iVopCodingType == VDX_VOP_TYPE_P) 
+        {
+            oldMCBPCLen = vdtGetPMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, iCurPMBinstance->mcbpc);
+        }
+        else
+        {
+            oldMCBPCLen = vdtGetIMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, iCurIMBinstance->mcbpc);
+        }
+    }
+    
+
+    
+    if (iDoModeTranscoding && ( (iTargetFormat == EVedVideoTypeH263Profile0Level10) ||
+                                (iTargetFormat == EVedVideoTypeH263Profile0Level45) ) )
+    {
+        if ( ConstructH263MBData(aParam, newMCBPCLen, newMCBPC) != VDC_OK )
+            {
+            return TX_ERR;
+            }
+    }
+    else /* possible H263->MPEG4 transcoding */
+        
+    {
+        /* MPEG4 with VDT_RESYN and VDT_REGULAR, we only do bitstream copying */
+        if ( iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn || iBitStreamMode == EVedVideoBitstreamModeMPEG4Regular ||
+            ((iBitStreamMode ==EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263) && !iDoModeTranscoding) )
+        {
+        /* the MB stuffing is taken card of outside in file viddemux.cpp
+        we only need to output COD, MCBPC
+            */
+            int mcbpcStartByteIndex, mcbpcStartBitIndex;
+            
+            if (iVopCodingType == VDX_VOP_TYPE_I)
+            {
+                mcbpcStartByteIndex = iCurIMBinstance->DataItemStartByteIndex[0];
+                mcbpcStartBitIndex = iCurIMBinstance->DataItemStartBitIndex[0];
+            }
+            else
+            {
+                mcbpcStartByteIndex = iCurPMBinstance->DataItemStartByteIndex[0];
+                mcbpcStartBitIndex = iCurPMBinstance->DataItemStartBitIndex[0];
+                /* It is a coded MB, output  1 bit COD (it always exists in P frame) */
+                sPutBits (iOutBuffer, 1, 0);
+            }
+            
+            if (!iColorEffect)
+            {
+                bufEdit.copyMode = CopyWhole; /* whole */
+                CopyStream(iInBuffer,iOutBuffer,&bufEdit,mcbpcStartByteIndex,mcbpcStartBitIndex);
+            }
+            else
+            {
+                /* modify mcbpc and copy only the Y data */
+                bufEdit.copyMode = CopyWithEdit; // copy with edit
+                bufEdit.editParams[0].StartByteIndex = mcbpcStartByteIndex; 
+                bufEdit.editParams[0].StartBitIndex  = mcbpcStartBitIndex; 
+                bufEdit.editParams[0].curNumBits = oldMCBPCLen; 
+                bufEdit.editParams[0].newNumBits = newMCBPCLen; 
+                bufEdit.editParams[0].newValue = newMCBPC; 
+                CopyStream(iInBuffer,iOutBuffer,&bufEdit,mcbpcStartByteIndex,mcbpcStartBitIndex);
+                
+                /* disgard the UV data */
+                int16 errorCode = 0;
+                int bitsToRewind = ((iInBuffer->getIndex << 3) + 7  - iInBuffer->bitIndex) 
+                                     - ((iBlockStartByteIndex[4] << 3) + 7 - iBlockStartBitIndex[4]);
+                bibRewindBits(bitsToRewind, iOutBuffer, &errorCode );
+                
+                if (iMBCodingType == VDX_MB_INTRA)
+                {
+                    if (iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263)
+                    {
+                        sResetH263IntraDcUV(iOutBuffer, iColorToneU, iColorToneV);                        
+                    }
+                    else
+                    {
+                        ResetMPEG4IntraDcUV();
+                    }
+                }
+            }
+        }
+
+        else if ((iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader || iBitStreamMode == EVedVideoBitstreamModeH263) && iDoModeTranscoding)
+        {
+            H263ToMPEG4MBData(newMCBPCLen, newMCBPC);
+        }
+        
+        else /* data partitioned */
+        {
+            if (iDoModeTranscoding)
+            {
+                /* for data partitioned bitstream, we do the bitstream rearrangement  */
+                ConstructRegularMPEG4MBData(newMCBPCLen, newMCBPC);
+            }
+            else
+            {
+                /* copy the ACs or DCTs */
+                bufEdit.copyMode = CopyWhole; // whole
+                CopyStream(iInBuffer,iOutBuffer,&bufEdit,iBlockStartByteIndex[0],iBlockStartBitIndex[0]);
+                if (iColorEffect)
+                {
+                    /* discard U V data */
+                    int16 errorCode = 0;
+                    int bitsToRewind = ((iInBuffer->getIndex << 3) + 7  - iInBuffer->bitIndex) 
+                                             - ((iBlockStartByteIndex[4] << 3) + 7 - iBlockStartBitIndex[4]);
+                    bibRewindBits(bitsToRewind, iOutBuffer, &errorCode );
+                }
+            }
+        }
+
+    }
+    iLastMBNum = iCurMBNum;
+    return TX_OK;
+}
+
+
+
+
+/*
+* ReconstructIMBPartitions
+*
+* Parameters: 
+*
+* Function:
+*    Recontruct the partitions for color effect when we are not doing format transcoding
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::ReconstructIMBPartitions()
+{
+    vdxIMBListItem_t *MBinstance;
+     int *dataItemStartByteIndex;
+     int *dataItemStartBitIndex;
+     int *dataItemEndByteIndex;
+     int *dataItemEndBitIndex;
+     int newMCBPCLen = 0;
+     int newMCBPC = 0;
+     
+     VDTASSERT(iMBList);
+     
+     for (dlstHead(iMBList, (void **) &MBinstance); 
+     MBinstance != NULL; 
+     dlstNext(iMBList, (void **) &MBinstance))
+      {
+         dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
+         dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
+         dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
+         dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
+         // MB stuffing bits if they exsit
+         vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
+             dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
+         
+         /* MCBPC    */
+         if (iColorEffect)
+         {
+             /* MCBPC Changed. Ignore the old value (not used) */
+             vdtGetIMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, MBinstance->mcbpc);
+             sPutBits(iOutBuffer, newMCBPCLen, newMCBPC);
+         }
+         else
+         {
+             vdtCopyBuffer(iInBuffer, iOutBuffer,
+                 dataItemStartByteIndex[0], dataItemStartBitIndex[0],
+                 dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
+         }
+         
+         /* DQUANT, if it exsits */
+         vdtCopyBuffer(iInBuffer, iOutBuffer,
+                   dataItemStartByteIndex[1], dataItemStartBitIndex[1],
+                     dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
+         
+         /* INTRA DCs */
+         if (!iColorEffect)
+         {
+             vdtCopyBuffer(iInBuffer, iOutBuffer,
+                 dataItemStartByteIndex[4], dataItemStartBitIndex[4],
+                 dataItemEndByteIndex[4], dataItemEndBitIndex[4]);
+         }
+         else
+         {
+             if (!(VDT_NO_DATA(dataItemStartByteIndex[4], dataItemStartBitIndex[4],
+                 dataItemEndByteIndex[4], dataItemEndBitIndex[4])))   
+             {
+                 vdtCopyBuffer(iInBuffer, iOutBuffer,
+                     dataItemStartByteIndex[4], dataItemStartBitIndex[4],
+                     dataItemStartByteIndex[8], dataItemStartBitIndex[8]);
+                 ResetMPEG4IntraDcUV();
+             }
+         }
+     }
+     
+     /* DC marker */
+     sPutBits(iOutBuffer, DC_MARKER_LENGTH, DC_MARKER);
+     
+   for (dlstHead(iMBList, (void **) &MBinstance); 
+     MBinstance != NULL; 
+     dlstNext(iMBList, (void **) &MBinstance))
+      {
+         dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
+         dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
+         dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
+         dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
+         
+         /* ac_pred_flag */
+         vdtCopyBuffer(iInBuffer, iOutBuffer,
+                   dataItemStartByteIndex[3], dataItemStartBitIndex[3],
+                     dataItemEndByteIndex[3], dataItemEndBitIndex[3]);
+         
+         /* CBPY */
+         vdtCopyBuffer(iInBuffer, iOutBuffer,
+                   dataItemStartByteIndex[2], dataItemStartBitIndex[2],
+                     dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
+      }
+     
+      /* make sure the head of the list is reset */
+      dlstHead(iMBList, (void **) &MBinstance);
+}
+
+/*
+* ReconstructPMBPartitions
+*
+* Parameters: 
+*
+* Function:
+*    Recontruct the partitions for color effect when we are not doing format transcoding
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::ReconstructPMBPartitions()
+{
+    vdxPMBListItem_t *MBinstance;
+    int *dataItemStartByteIndex;
+    int *dataItemStartBitIndex;
+    int *dataItemEndByteIndex;
+    int *dataItemEndBitIndex;
+    int newMCBPCLen = 0;
+    int newMCBPC = 0;
+     
+    VDTASSERT(iMBList);
+     
+  for (dlstHead(iMBList, (void **) &MBinstance); 
+    MBinstance != NULL; 
+    dlstNext(iMBList, (void **) &MBinstance))
+    {
+        dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
+        dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
+        dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
+        dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
+        
+        /* MB stuffing bits if they exsit */
+        vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
+            dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
+        
+        if (MBinstance->fCodedMB)
+        {
+            /* output  1 bit COD, coded */
+            sPutBits (iOutBuffer, 1, 0);
+            
+            /* MCBPC     */
+            if (iColorEffect)
+            {
+                /* MCBPC Changed, ignore the return value */
+                vdtGetPMBBlackAndWhiteMCBPC(newMCBPCLen, newMCBPC, MBinstance->mcbpc);
+                sPutBits(iOutBuffer, newMCBPCLen, newMCBPC);
+            }
+            else
+            {
+                vdtCopyBuffer(iInBuffer, iOutBuffer,
+                    dataItemStartByteIndex[0], dataItemStartBitIndex[0],
+                    dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
+            }
+            
+            /* MVs, if they exist */
+            vdtCopyBuffer(iInBuffer, iOutBuffer,
+                dataItemStartByteIndex[10], dataItemStartBitIndex[10],
+                dataItemEndByteIndex[10], dataItemEndBitIndex[10]);
+        }
+        else
+        {
+            /* output  1 bit COD, not coded */
+            sPutBits (iOutBuffer, 1, 1);
+        }
+    }
+     
+    /* MM marker */
+    sPutBits(iOutBuffer, MOTION_MARKER_LENGTH, MOTION_MARKER);
+     
+    for (dlstHead(iMBList, (void **) &MBinstance); 
+    MBinstance != NULL; 
+    dlstNext(iMBList, (void **) &MBinstance))
+    {
+        if (MBinstance->fCodedMB)
+        {
+            dataItemStartByteIndex = MBinstance->DataItemStartByteIndex;
+            dataItemStartBitIndex  = MBinstance->DataItemStartBitIndex;
+            dataItemEndByteIndex   = MBinstance->DataItemEndByteIndex;
+            dataItemEndBitIndex    = MBinstance->DataItemEndBitIndex;
+            
+            /* ac_pred_flag, if it exsits */
+            vdtCopyBuffer(iInBuffer, iOutBuffer,
+                dataItemStartByteIndex[3], dataItemStartBitIndex[3],
+                dataItemEndByteIndex[3], dataItemEndBitIndex[3]);
+            
+            /* CBPY,  */
+            vdtCopyBuffer(iInBuffer, iOutBuffer,
+                dataItemStartByteIndex[2], dataItemStartBitIndex[2],
+                dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
+            /* DQUANT, if it exsits */
+            vdtCopyBuffer(iInBuffer, iOutBuffer,
+                dataItemStartByteIndex[1], dataItemStartBitIndex[1],
+                dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
+            
+            /* INTRA DCs, if they exsit */
+            if (!iColorEffect)
+            {
+                vdtCopyBuffer(iInBuffer, iOutBuffer,
+                    dataItemStartByteIndex[4], dataItemStartBitIndex[4],
+                    dataItemEndByteIndex[4], dataItemEndBitIndex[4]);
+            }
+            else
+            {
+                if (!(VDT_NO_DATA(dataItemStartByteIndex[4], dataItemStartBitIndex[4],
+                    dataItemEndByteIndex[4], dataItemEndBitIndex[4])))   
+                {
+                    vdtCopyBuffer(iInBuffer, iOutBuffer,
+                        dataItemStartByteIndex[4], dataItemStartBitIndex[4],
+                        dataItemStartByteIndex[8], dataItemStartBitIndex[8]);
+                    ResetMPEG4IntraDcUV();
+                }
+            }
+        }
+    }
+     
+    /* make sure the head of the list is reset */
+    dlstHead(iMBList, (void **) &MBinstance);
+}
+
+/*
+* ResetMPEG4IntraDcUV
+*
+* Parameters: 
+*
+* Function:
+*    This function resets the DCc for U V block in INTRA MB.
+*    Inputs are valid only with Color Effect
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::ResetMPEG4IntraDcUV()
+{
+    /* set INTRADC for u,v in the output buffer */
+    TInt sizeU, sizeCodeU, sizeCodeLengthU, valueU, valueCodeU, valueCodeLengthU;
+    TInt sizeV, sizeCodeV, sizeCodeLengthV, valueV, valueCodeV, valueCodeLengthV;
+    TInt curDcScaler, delta; 
+    TReal realDelta, realVal;
+    TInt mbh, mbv, mbd;  // previous MB in the horizontal, vertical and diagonal directions
+    TInt codeMB; 
+    
+    // initialize for codewords
+    sizeU = sizeCodeU = sizeCodeLengthU = valueCodeU = valueCodeLengthU = 0;
+    sizeV = sizeCodeV = sizeCodeLengthV = valueCodeV = valueCodeLengthV = 0;
+
+    // initialize for prediction
+    mbh = mbv = mbd = VDX_MB_INTER;
+    codeMB = 0;
+    
+    // NOTE: VDX_MB_INTER=1, VDX_MB_INTRA=2, NOT-CODED MB has a value of 0
+    if (iVopCodingType == VDX_VOP_TYPE_I)
+    {
+        /* encode intra DC coefficients for INTRA MBs of I-VOP if 
+           either of the following is true:
+            -
+            -
+            else, do not encode intra DC
+           (because rest of MBs have differential intra DC, which is zero)
+        */
+        if (!iCurMBNumInVP || 
+             (!(iCurMBNum%iMBsinWidth) && (iCurMBNumInVP<iMBsinWidth)))
+        {
+            codeMB = 1;
+        }
+    }
+    else if (iVopCodingType == VDX_VOP_TYPE_P)
+    {
+        if (iCurMBNumInVP>iMBsinWidth)
+        { 
+            if (iCurMBNum%iMBsinWidth)
+            {
+                mbh = iMBType[iCurMBNum-1];
+                mbd = iMBType[iCurMBNum-iMBsinWidth-1];
+            }
+            mbv = iMBType[iCurMBNum-iMBsinWidth];
+        }        
+        else if (iCurMBNumInVP==iMBsinWidth)
+        {
+            if (iCurMBNum%iMBsinWidth)
+            {
+                mbh = iMBType[iCurMBNum-1];
+            }
+            mbv = iMBType[iCurMBNum-iMBsinWidth];
+        }
+        else if (iCurMBNumInVP>0)
+        {
+            if (iCurMBNum%iMBsinWidth)
+            {
+                mbh = iMBType[iCurMBNum-1];
+            }
+        }
+      
+        // 
+        if ((mbh<VDX_MB_INTRA && mbv<VDX_MB_INTRA) ||
+            (mbd==VDX_MB_INTRA && ((mbh==VDX_MB_INTRA && mbv<VDX_MB_INTRA) || 
+            (mbh<VDX_MB_INTRA && mbv==VDX_MB_INTRA))))
+        {
+            codeMB = 1;
+        }
+    }
+
+    if (codeMB)  // if IntraDC need to be coded
+    {
+        // color-toned U,V values
+        valueU = iColorToneU;
+        valueV = iColorToneV;
+      
+        // compensate for different QP than original
+        if (iCurQuant != iRefQuant)  
+        {
+            // calculate change in dc value
+            curDcScaler = GetMpeg4DcScalerUV(iCurQuant);
+            realDelta = TReal(iDcScaler-curDcScaler)/TReal(curDcScaler);
+            if (realDelta != 0.0)
+            {
+                // U
+                realVal = realDelta*TReal(valueU);
+                delta = TInt(realVal + ((realVal<0) ? (-0.5) : (0.5)));
+                valueU += delta;
+                // V
+                realVal = realDelta*TReal(valueV);
+                delta = TInt(realVal + ((realVal<0) ? (-0.5) : (0.5)));
+                valueV += delta;
+            }
+        }
+         
+        // get codewords
+        GetMPEG4IntraDcCoeffUV(valueU, sizeU, sizeCodeU, sizeCodeLengthU, 
+        valueCodeU, valueCodeLengthU);
+        GetMPEG4IntraDcCoeffUV(valueV, sizeV, sizeCodeV, sizeCodeLengthV, 
+        valueCodeV, valueCodeLengthV);
+      
+        // code codewords
+        // U
+        sPutBits(iOutBuffer, sizeCodeLengthU, sizeCodeU); // dct_dc_coeff size
+        if (sizeCodeU != 3) // size=0
+        {
+            sPutBits(iOutBuffer, valueCodeLengthU, valueCodeU); // dct_dc_coeff differential
+            if (valueCodeLengthU>8)
+                sPutBits(iOutBuffer, 1, 1); // marker bit
+        }
+      
+        // V
+        sPutBits(iOutBuffer, sizeCodeLengthV, sizeCodeV); // dct_dc_coeff size
+        if (sizeCodeV != 3) // size=0
+        {
+            sPutBits(iOutBuffer, valueCodeLengthV, valueCodeV); // dct_dc_coeff differential
+            if (valueCodeLengthV>8)
+                sPutBits(iOutBuffer, 1, 1); // marker bit
+        }
+    }    
+    else
+    {        
+        sPutBits (iOutBuffer, 2, 3); /* U */
+        sPutBits (iOutBuffer, 2, 3); /* V */
+    }
+}
+
+
+/*
+* GetMPEG4IntraDcCoeffUV
+*
+* Parameters: 
+*     aValue   coefficient value
+*     aDCAC    pointer the reconstructed coefficients
+* Function:
+*    This function fills the reconstructed DCAC values for INTRA block.
+*    Inputs are valid only with Color Effect
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::GetMPEG4IntraDcCoeffUV(TInt aValue, TInt& aSize, 
+  TInt& aSizeCode, TInt& aSizeCodeLength, TInt& aValueCode, TInt& aValueCodeLength)
+{
+    int absVal = (aValue>=0 ? aValue : -aValue);
+    // size of aValueCode
+    for (aSize=0; absVal|0; absVal>>=1, aSize++) ;
+    if (aSize)
+    {
+        // codeword for aSize
+        if (aSize==1)
+        {
+            aSizeCode = 2;
+            aSizeCodeLength = 2;
+        }
+        else
+        {
+            aSizeCode = 1;
+            aSizeCodeLength = aSize;
+        }
+    
+        // codeword for aValue
+        aValueCode = aValue;
+        if (aValue<0)
+            aValueCode += ((1<<aSize)-1);
+        aValueCodeLength = aSize;
+    }
+    else 
+    {
+        // codeword for aSize
+        aSizeCode = 3;        // codeword for size=0
+        aSizeCodeLength = 2;
+        // no codeword for aValue
+        aValueCode = aValueCodeLength = 0;
+    }
+}
+
+
+/*
+* AddOneBlockDCACrecon
+*
+* Parameters: 
+*     aIndex   block index
+*     aDCAC    pointer the reconstructed coefficients
+* Function:
+*    This function fills the reconstructed DCAC values for INTRA block.
+*    Inputs are valid only with Color Effect
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::AddOneBlockDCACrecon(int aIndex, int *aDCAC)
+{
+    VDTASSERT(aIndex >= 0 && aIndex < 6); 
+    
+    if (aDCAC && iDoModeTranscoding && (iTargetFormat == EVedVideoTypeH263Profile0Level10 ||
+                                        iTargetFormat == EVedVideoTypeH263Profile0Level45))
+    {
+      /* we only need the reconstructed DCACs for MPEG4 -> H263 */
+      /* It is a coded block    */
+      memcpy(iDCTBlockData + (aIndex << 6), aDCAC, sizeof(int) * BLOCK_COEFF_SIZE);
+    }
+}
+
+/*
+* ConstructH263MBData
+*
+* Parameters: 
+*     aNewMCBPCLen     new length of mcbpc
+*     aNewMCBPC        new mcbpc
+* Function:
+*    This function creates a new H263 MB
+*    Inputs are valid only with Color Effect
+* Returns:
+*    VDC error codes
+*
+*/
+int CMPEG4Transcoder::ConstructH263MBData(dmdPParam_t *aParam, int /*aNewMCBPCLen*/, int /*aNewMCBPC*/)
+{
+    /* MB data part1: output MCBPC, CBPY, DQuant, MV, intra DC etc */
+    int *dataItemStartByteIndex;
+    int *dataItemStartBitIndex;
+    int *dataItemEndByteIndex;
+    int *dataItemEndBitIndex;
+    int quant, dquant;
+    int codedBlockPattern = 0;
+    
+    const unsigned int sDquant[5] = 
+    {
+        1, 0, (unsigned int)65536, 2, 3
+    };
+    
+  if (iVopCodingType == VDX_VOP_TYPE_P) 
+    {
+        dataItemStartByteIndex = iCurPMBinstance->DataItemStartByteIndex;
+        dataItemStartBitIndex  = iCurPMBinstance->DataItemStartBitIndex;
+        dataItemEndByteIndex   = iCurPMBinstance->DataItemEndByteIndex;
+        dataItemEndBitIndex    = iCurPMBinstance->DataItemEndBitIndex;
+        quant = iCurPMBinstance->quant;
+        dquant = iCurPMBinstance->dquant;
+    }
+    else
+    {
+        dataItemStartByteIndex = iCurIMBinstance->DataItemStartByteIndex;
+        dataItemStartBitIndex  = iCurIMBinstance->DataItemStartBitIndex;
+        dataItemEndByteIndex   = iCurIMBinstance->DataItemEndByteIndex;
+        dataItemEndBitIndex    = iCurIMBinstance->DataItemEndBitIndex;
+        quant = iCurIMBinstance->quant;
+        dquant = iCurIMBinstance->dquant;
+    }
+    
+    if (iPreQuant != quant - dquant)
+    {
+        /* last quant in MPEG4 and H263 is different, dquant and VLCs may not be reused */
+        if (abs(quant - iPreQuant) > 2)
+        {
+            /* VLCs cannot be reused, obtain the new ones */
+            sQuantizeMB(iDCTBlockData, quant, iPreQuant, 
+                iMBCodingType, iColorEffect);
+            quant = iPreQuant;
+            dquant = 0;
+        }
+        else
+        {
+            /* VLCs can be reused, but need to change dquant and MCBPC */
+            dquant = quant - iPreQuant;
+        }
+    }
+    
+    /* MB stuffing bits if they exsit */
+    vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
+        dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
+    
+    if (iMBCodingType == VDX_MB_INTER) 
+    {
+        VDTASSERT(aParam);
+        tMBPosition mbPos;
+        tMotionVector mvTestOutside;
+        mbPos.x = aParam->xPosInMBs * 16; 
+        mbPos.y = aParam->yPosInMBs * 16;
+        mbPos.LeftBound = 0;
+        mbPos.RightBound = iVDEInstance->lumWidth << 1;
+        mbPos.TopBound = 0;
+        mbPos.BottomBound = iVDEInstance->lumHeight << 1;
+        mvTestOutside.mvx = (int16) ((aParam->mvx[0] << 1) / 10);
+        mvTestOutside.mvy = (int16) ((aParam->mvy[0] << 1) / 10);
+        
+        /* Three cases for MVs. 1): 4MVs -> need mapping 2). 1 outside frame MV 3) rounding type = 1 */
+        vdcInstance_t * vdcTemp = (vdcInstance_t *)(iVDEInstance->vdcHInstance);
+        
+        /* Two cases for MVs. 1): 4MVs -> need mapping 2). 1 outside frame MV */
+        if (iCurPMBinstance->numMVs == 4 || (iCurPMBinstance->numMVs == 1 && 
+            vbmMVOutsideBound(&mbPos, &mvTestOutside, 1)) || vdcTemp->pictureParam.rtype)
+        {
+            int32 numTextureBits;
+            int32 searchRange = 16;
+            tMotionVector   *initPred; 
+            (h263mbi+iCurMBNum)->QuantScale = (int16) quant;
+            (h263mbi+iCurMBNum)->dQuant = (int16) dquant;
+            
+            /* note: this buffer is also used in the diamond search and half-pixel search !!!!! 
+               which needs at least 8 points
+            */
+            initPred = (tMotionVector*) malloc(8 * sizeof (tMotionVector));
+            if(!initPred)
+            {
+                //Memory not available 
+                return TX_ERR;
+            }
+
+                        
+            for (int i = 0; i < iCurPMBinstance->numMVs ; i++)
+            {
+                (initPred + i)->mvx = (int16) (aParam->mvx[i] / 10); /* the recorded mv is multipied by 10, */
+                (initPred + i)->mvy = (int16) (aParam->mvy[i] / 10); /* the recorded mv is multipied by 10, */
+            }
+            int32 noOfPredictors = iCurPMBinstance->numMVs;
+            
+            /* perform the 4MVs -> 1MV mapping, and output this MB */
+            vbmPutInterMB(&mbPos,
+                iOutBuffer,aParam,
+                initPred, noOfPredictors,
+                (u_int32) iVDEInstance->lumWidth, (u_int32) iVDEInstance->lumHeight,
+                searchRange, iCurMBNum, &numTextureBits, 
+                (int16)iColorEffect, h263mbi);
+            /*  the MVs buffer is updated inside vbmPutInterMB */
+            
+            if (initPred)
+                free(initPred);
+        }
+        else
+        {
+            /* Here, for Inter MB with One inside Frame MV, we simply reuse the DCTs */
+            VDTASSERT(iCurPMBinstance->numMVs == 1);
+            
+            /* It is a coded MB, output 1 bit COD (it always exists in P frame) */
+            sPutBits (iOutBuffer, 1, 0);
+            int         cbpy;
+            int         mcbpcVal;
+            int         len;
+            
+            codedBlockPattern = sFindCBP(iDCTBlockData, OFF);
+            mcbpcVal = iColorEffect? 0 : (codedBlockPattern & 3);
+            cbpy = ((codedBlockPattern >> 2) & 0xf);
+            vbmGetH263PMCBPC(dquant, iColorEffect, cbpy, mcbpcVal, len);
+            sPutBits(iOutBuffer, len, mcbpcVal); //MCBPC, CBPY
+            
+            /* DQUANT, if it exsits */
+            if (dquant)
+            {
+                sPutBits(iOutBuffer, 2, sDquant[dquant + 2]);
+            }
+            /* recode MVs, one more indice exists in the MV VLC table in MPEG4
+               moreover, vop_fcode can be larger than 1 (although it may rarely happens), 
+                 so it is better to redo the VLC coding
+      */
+            /* the recorded mv is multipied by 10, in pixel unit */
+            int16 mvx = (int16) ((aParam->mvx[0] << 1) / 10); 
+            int16 mvy = (int16) ((aParam->mvy[0] << 1) / 10);
+            
+            tMotionVector   lPredMV[4];
+            tMBInfo *mbi = h263mbi + iCurMBNum;
+            
+            /* get the new predicted MV */
+            vbmMvPrediction(mbi, iCurMBNum, lPredMV, (u_int32)iMBsinWidth);
+            
+            vbmEncodeMVDifferential(mvx - lPredMV[0].mvx, mvy - lPredMV[0].mvy, 1, iOutBuffer);
+            cbpy = 32;
+            /* following is the block level data */
+            for (int i = 0; i < (iColorEffect? 4 : 6); i++)
+            {
+                int fBlockCoded = cbpy & codedBlockPattern;
+                if (fBlockCoded)
+                {
+                    /* here we do the VLC coding again */ 
+                    int numTextureBits = 0;
+                    vdtPutInterMBCMT(iOutBuffer,0, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, ON);
+                }
+                cbpy >>= 1;
+            } 
+            
+            /* update the MVs buffer */
+            (h263mbi + iCurMBNum)->MV[0][0] = (int16) ((aParam->mvx[0] << 1) / 10); /* the recorded mv is multipied by 10 */
+            (h263mbi + iCurMBNum)->MV[0][1] = (int16) ((aParam->mvy[0] << 1) / 10); /* the recorded mv is multipied by 10 */
+            
+        }  /* end of if 4MVs */
+    }
+    else /* INTRA MB */
+    {
+        /* update the MVs buffer */
+        (h263mbi + iCurMBNum)->MV[0][0] = 0;
+        (h263mbi + iCurMBNum)->MV[0][1] = 0;
+        /* MPEG4 and H263 use different methods for INTRA MB, redo the VLC coding */
+        int         cbpy;
+        int         mcbpcVal;
+        int         len;
+        
+        codedBlockPattern = sFindCBP(iDCTBlockData, ON);
+        mcbpcVal = iColorEffect? 0 : (codedBlockPattern & 3);
+        cbpy = ((codedBlockPattern >> 2) & 0xf);
+        vbmGetH263IMCBPC(dquant, (iVopCodingType == VDX_VOP_TYPE_P), iColorEffect, cbpy, mcbpcVal, len);
+        sPutBits(iOutBuffer, len, mcbpcVal); //COD, MCBPC, CBPY
+        
+        /* DQUANT, if it exsits */
+        if (dquant)
+        {
+            sPutBits(iOutBuffer, 2, sDquant[dquant + 2]);
+        }
+        cbpy = 32;
+        
+        /* following is the block level data */
+        for (int i = 0; i < (iColorEffect? 4 : 6); i++)
+        {
+            /* requantize INTRA DC */
+            /* DC Quantization */
+            int coeff = (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0] >> 3;
+            
+            if(coeff < 1) coeff = 1;
+            if(coeff > 254) coeff = 254;
+            if(coeff == 128)
+            {
+                sPutBits(iOutBuffer, 8, 255);
+            }
+            else
+            {
+                sPutBits(iOutBuffer, 8, coeff);
+            }
+            
+            (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0] = coeff;
+            if(cbpy & codedBlockPattern)
+            {
+                int numTextureBits = 0;
+                vdtPutInterMBCMT(iOutBuffer,1, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, ON);
+            }
+            cbpy >>= 1;
+        }
+    }
+    
+  if (iColorEffect && (iMBCodingType == VDX_MB_INTRA))
+    {
+        ResetH263IntraDcUV(iOutBuffer, iColorToneU, iColorToneV);        
+    }
+  iPreQuant = quant;
+  
+  return TX_OK;
+}
+
+/*
+* ConstructRegularMPEG4MBData
+*
+* Parameters: 
+*     aNewMCBPCLen     new length of mcbpc
+*     aNewMCBPC        new mcbpc
+* Function:
+*    This function rearranges the data for bitstream with data partitioning
+*    Only valid in Data Partitioned mode
+*    Inputs are valid only with Color Effect
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::ConstructRegularMPEG4MBData(int aNewMCBPCLen, int aNewMCBPC)
+{
+  /* MB data part1: output MCBPC, CBPY, DQuant, MV, intra DC etc */
+    int *dataItemStartByteIndex;
+    int *dataItemStartBitIndex;
+    int *dataItemEndByteIndex;
+    int *dataItemEndBitIndex;
+    
+    if (iVopCodingType == VDX_VOP_TYPE_P) 
+    {
+        dataItemStartByteIndex = iCurPMBinstance->DataItemStartByteIndex;
+        dataItemStartBitIndex  = iCurPMBinstance->DataItemStartBitIndex;
+        dataItemEndByteIndex   = iCurPMBinstance->DataItemEndByteIndex;
+        dataItemEndBitIndex    = iCurPMBinstance->DataItemEndBitIndex;
+    }
+    else
+    {
+        dataItemStartByteIndex = iCurIMBinstance->DataItemStartByteIndex;
+        dataItemStartBitIndex  = iCurIMBinstance->DataItemStartBitIndex;
+        dataItemEndByteIndex   = iCurIMBinstance->DataItemEndByteIndex;
+        dataItemEndBitIndex    = iCurIMBinstance->DataItemEndBitIndex;
+    }
+    
+    /* MB stuffing bits if they exsit */
+    vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[11], dataItemStartBitIndex[11],
+        dataItemEndByteIndex[11], dataItemEndBitIndex[11]);
+    
+    if (iVopCodingType == VDX_VOP_TYPE_P)
+    {
+        /* It is a coded MB, output  1 bit COD (it always exists in P frame) */
+        sPutBits (iOutBuffer, 1, 0);
+    }
+    
+    /* MCBPC. NOTE: the positions do not include MCBPC stuffing bits !! */
+    if (iColorEffect)
+    {
+        /* MCBPC Changed */
+        sPutBits(iOutBuffer, aNewMCBPCLen, aNewMCBPC);
+    }
+    else
+    {
+        vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[0], dataItemStartBitIndex[0],
+            dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
+    }
+    /* ac_pred_flag, if it exsits */
+    vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[3], dataItemStartBitIndex[3],
+        dataItemEndByteIndex[3], dataItemEndBitIndex[3]);
+    
+    /* CBPY */
+    vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[2], dataItemStartBitIndex[2],
+        dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
+    
+    /* DQUANT, if it exsits */
+    vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[1], dataItemStartBitIndex[1],
+        dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
+    
+    if (iMBCodingType == VDX_MB_INTER) 
+    {
+        /* MVs, if they exsit */
+        vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[10], dataItemStartBitIndex[10],
+            dataItemEndByteIndex[10], dataItemEndBitIndex[10]);
+    }
+    
+    /* following is the block level data */
+    for (int i = 0; i < (iColorEffect? 4 : 6); i++)
+    {
+        /* INTRA DC, if it exsits */
+        vdtCopyBuffer(iInBuffer, iOutBuffer, dataItemStartByteIndex[i + 4], dataItemStartBitIndex[i + 4],
+            dataItemEndByteIndex[i + 4], dataItemEndBitIndex[i + 4]);
+        
+        /* block data part2, AC or DCT coefficients */
+        if (iBitStreamMode == EVedVideoBitstreamModeMPEG4DP_RVLC || iBitStreamMode == EVedVideoBitstreamModeMPEG4Resyn_DP_RVLC)
+        {
+        /* remember for data partitioning, the positions only indicate the  
+        AC or DCTs coefficients
+            */
+            if (VDT_NO_DATA(iBlockStartByteIndex[i], iBlockStartBitIndex[i],
+                iBlockEndByteIndex[i], iBlockEndBitIndex[i]))  
+            {
+                /* no coefficients,skip this block */
+                continue;
+            }
+            else
+            {
+                /* for RVLC coding, we transform the block data back to VLC */
+                int numTextureBits = 0;
+                /* redo the entropy coding, RVLC -> VLC 
+                only for AC (IMB) or DCT (PMB) coefficients
+                */
+                if (iMBCodingType == VDX_MB_INTRA)
+                {
+                    vdtPutIntraMBCMT(iOutBuffer,iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, i, 1, 0);
+                }
+                else
+                {
+                    vdtPutInterMBCMT(iOutBuffer,0, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, OFF);
+                }
+            }
+        }
+        else /* ouput the AC or DCT coefficients */
+        {
+            bufEdit.copyMode = CopyWhole; /* CopyWhole */
+            vdtCopyBuffer(iInBuffer,iOutBuffer,
+                iBlockStartByteIndex[i],iBlockStartBitIndex[i],
+                iBlockEndByteIndex[i],iBlockEndBitIndex[i]);
+        }
+    }
+  if (iColorEffect && (iMBCodingType == VDX_MB_INTRA))
+    {
+        ResetMPEG4IntraDcUV();
+    }
+}
+
+
+
+/*
+* AddOneBlockDataToMB
+*
+* Parameters: 
+*     blockData        block data before VLC coding, in ZigZag order
+* Function:
+*    This function input one block data to current MB
+*    only here the whole MB data is retrieved (COD=0)
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::AddOneBlockDataToMB(int aBlockIndex, int *aBlockData)
+{
+    VDTASSERT(aBlockIndex >= 0 && aBlockIndex < 6); 
+    
+    
+    if (aBlockData && iDoModeTranscoding)
+    {
+      /* iDCTBlockData is only used when we need to convert the bitstream to MPEG4_RESYN
+      It is a coded block   
+        */
+      if (iMBCodingType == VDX_MB_INTRA && (iTargetFormat == EVedVideoTypeH263Profile0Level10 ||
+                                            iTargetFormat == EVedVideoTypeH263Profile0Level45))
+        {
+          /* we only need the reconstructed DCACs, skipped */
+        }
+        else
+        {
+          memcpy(iDCTBlockData + (aBlockIndex << 6), aBlockData, sizeof(int) * BLOCK_COEFF_SIZE);
+        }
+    }
+    else 
+    {
+      memset(iDCTBlockData + (aBlockIndex << 6), 0, sizeof(int) * BLOCK_COEFF_SIZE);
+    }
+    
+
+    
+    iBlockEndByteIndex[aBlockIndex] = iInBuffer->getIndex;
+    iBlockEndBitIndex[aBlockIndex] = iInBuffer->bitIndex;
+}
+
+/*
+* ErrorResilienceInfo
+*
+* Parameters: 
+*     header        VOL Header data
+* Function:
+*    This function records the position of resnc_marker_disable bit
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::ErrorResilienceInfo(vdxVolHeader_t *header, int aByte, int aBit)
+{
+    if (header)
+    {
+                
+        memcpy(&iVOLHeader, header, sizeof(vdxVolHeader_t));  // save the header info
+
+    }
+    else
+    {
+        iErrorResilienceStartByteIndex = aByte;  /* save the bits position */
+        iErrorResilienceStartBitIndex  = aBit;
+    }
+}
+
+
+
+/*
+* MPEG4TimerResolution
+*
+* Parameters: 
+*     
+* Function:
+*    This function records the position of vop_time_increment_resolution bit
+* Returns:
+*    None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::MPEG4TimerResolution(int aStartByteIndex, int aStartBitIndex)
+{
+    iTimeResolutionByteIndex = aStartByteIndex;
+    iTimeResolutionBitIndex  = aStartBitIndex;
+}
+
+
+
+void CMPEG4Transcoder::ConstructVOSHeader(int aMPEG4, vdeDecodeParamters_t *aDecoderInfo)
+{
+  if (!aMPEG4 )
+  {
+    /* for H263 and MPEG4 shortheader, no vos generated */
+    if (iErrorResilienceStartByteIndex == KDataNotValid && 
+      iErrorResilienceStartBitIndex == KDataNotValid)
+    {
+      iBitStreamMode = EVedVideoBitstreamModeH263; // pure H.263
+      aDecoderInfo->vosHeaderSize = aDecoderInfo->fModeChanged? KH263ToMpeg4VosSize : 0; 
+    }
+    else
+    {
+      /* we went into the VOL layer. It is a MPEG4 bitstream with short header */
+      iBitStreamMode = EVedVideoBitstreamModeMPEG4ShortHeader; /* MPEG4 shortheader */
+      iShortHeaderEndByteIndex = iInBuffer->getIndex;
+      iShortHeaderEndBitIndex  = iInBuffer->bitIndex;
+      aDecoderInfo->vosHeaderSize = aDecoderInfo->fModeChanged? KH263ToMpeg4VosSize : KShortHeaderMpeg4VosSize; 
+    }
+    fFirstFrameInH263 = ETrue;
+  }
+  else 
+  {
+    iNumMBsInOneVOP = (iVDEInstance->lumHeight * iVDEInstance->lumWidth) / 256;
+    
+    /* even iBitStreamMode is given outside, we renew it here anyway */
+    iBitStreamMode = sGetMPEG4Mode(iVOLHeader.error_res_disable,
+      iVOLHeader.data_partitioned, iVOLHeader.reversible_vlc);
+    
+    if (iTargetFormat != EVedVideoTypeH263Profile0Level10 &&
+      iTargetFormat != EVedVideoTypeH263Profile0Level45) /* EVedVideoTypeMPEG4SimpleProfile or None */
+    {
+      /* copy from the begining of the input buffer */
+      vdtCopyBuffer(iInBuffer,iOutBuffer,0,7, iTimeResolutionByteIndex, iTimeResolutionBitIndex); 
+      /* it is 16 bits */
+      sPutBits (iOutBuffer, KMpeg4VopTimeIncrementResolutionLength, *aDecoderInfo->aMPEG4TargetTimeResolution); 
+      
+      int startByteIndex, startBitIndex;
+      startByteIndex = iTimeResolutionByteIndex + 2;
+      startBitIndex  = iTimeResolutionBitIndex;
+      
+      sPutBits(iOutBuffer, 1, MARKER_BIT);
+      /* close fixed_vop_rate */
+      sPutBits (iOutBuffer, 1, 0); /* it is 1 bit */
+      
+      int num_bits = 0;
+      vdcInstance_t * vdcTemp = (vdcInstance_t *)(iVDEInstance->vdcHInstance);
+      if (vdcTemp->pictureParam.fixed_vop_rate)
+      {
+        for (num_bits = 1; ((vdcTemp->pictureParam.time_increment_resolution-1) >> num_bits) != 0; num_bits++)
+            {
+            }
+      }
+      num_bits += 2;
+      
+      /* following is to skip the fixed_vop_rate */
+      int bitsRemain, bitShift = 0;
+      int bitsToMove = 0 ;
+      /* complete the byte */
+      if (startBitIndex != 7)
+      {
+        bitShift = startBitIndex + 1;
+        bitsToMove = (num_bits < bitShift) ? num_bits : bitShift; 
+        /* update statistics to take care of bit addition or byte completion  */
+        if (num_bits < bitShift)
+        {
+          /* bits skipped but byte not completed */
+          startBitIndex -= bitsToMove;
+        }
+        else
+        {
+          /* byte completed */
+          startByteIndex ++;
+          startBitIndex = 7;
+        }
+      }
+      /* full bytes to skip */
+      startByteIndex += ((num_bits - bitsToMove) >> 3);
+      bitsRemain = (num_bits - bitsToMove) % 8;
+      
+      /* the remaining bits */
+      startBitIndex = ( bitsRemain != 0) ? 7 - bitsRemain : startBitIndex;
+
+      
+      /* check if we have user data in the end of VOL; it cannot be copied as such but needs to be byte aligned */
+      /* first need to rewind the input buffer to be able to seek in it */
+      int16 error = 0;
+      int curByteIndex = iInBuffer->getIndex;
+      int curBitIndex = iInBuffer->bitIndex;
+      int bits = ((curByteIndex - iTimeResolutionByteIndex)<<3) + (7-curBitIndex);
+      bibRewindBits(bits, iInBuffer, &error);
+      int sncCode = sncSeekMPEGStartCode(iInBuffer, 
+          vdcTemp->pictureParam.fcode_forward, 1 /* don't check VOPs */, 1 /* check for user data*/, &error);
+        
+      /* record next resync position */
+      int resyncByteIndex = iInBuffer->getIndex;
+        
+      int stuffBits = 0;
+      int userDataExists = 0;
+      if ( sncCode == SNC_USERDATA )
+      {
+        /* copy only until this sync code, and copy the rest separately in the end. */
+        userDataExists = 1;
+      }
+      else
+      {
+        /* No UD */
+        /* restore the original pointers in iInBuffer */
+        iInBuffer->getIndex = curByteIndex;
+        iInBuffer->bitIndex = curBitIndex;
+      }
+      
+      if (iDoModeTranscoding || aDecoderInfo->fHaveDifferentModes)
+      {
+        /* close the error resilience tools, change the bitstream to regular MPEG4 with resyn marker */
+        int numBits = iVOLHeader.data_partitioned ? 3 : 2;
+        
+        bufEdit.copyMode = CopyWithEdit; 
+        bufEdit.editParams[0].StartByteIndex = iErrorResilienceStartByteIndex; 
+        bufEdit.editParams[0].StartBitIndex = iErrorResilienceStartBitIndex; 
+        bufEdit.editParams[0].curNumBits = numBits; 
+        bufEdit.editParams[0].newNumBits = 2;  
+        bufEdit.editParams[0].newValue = 0;  /* new codeword: resyn, no dp, no rvlc */
+        CopyStream(iInBuffer,iOutBuffer,&bufEdit, startByteIndex,startBitIndex); /* copy from vop_time_increment_resolution */
+
+        /* rewind stuffing bits */
+        int16 error;
+        sncRewindStuffing(iOutBuffer, &error);        
+
+        // stuff bits in outbuffer for next start code   
+        vdtStuffBitsMPEG4(iOutBuffer);
+      }
+      else
+      {
+      
+        /* rewind stuffing bits */
+        sncRewindStuffing(iInBuffer, &error);        
+        
+        /* record the number of bits rewinded - can be from 0 to 8 */
+        /* note that iInBuffer must be byte aligned before rewinding */
+        if (iInBuffer->bitIndex == 7) // full byte rewind
+        { 
+          stuffBits = ( (int)(iInBuffer->getIndex) < resyncByteIndex) ? 8 : 0;
+        }
+        else 
+        {
+          stuffBits = iInBuffer->bitIndex + 1;
+        }
+          
+        /* copy the rest of VOS until the first VOP (or UD) */
+        bufEdit.copyMode = CopyWhole; 
+        vdtCopyBuffer(iInBuffer,iOutBuffer, startByteIndex,startBitIndex,
+          resyncByteIndex, iInBuffer->bitIndex); 
+        
+        // stuff bits in outbuffer for next start code   
+        vdtStuffBitsMPEG4(iOutBuffer);
+        
+        // move inbuffer pointer back to original value
+        bibForwardBits(stuffBits, iInBuffer);
+      }
+      
+      
+      if ( userDataExists )
+      {
+        /* seek for VOP start code */
+        int sncCode = sncSeekMPEGStartCode(iInBuffer, 
+          vdcTemp->pictureParam.fcode_forward, vdcTemp->pictureParam.error_res_disable, 0, &error);
+        
+        /* rewind stuffing bits */
+        sncRewindStuffing(iInBuffer, &error);        
+        
+        // record the number of bits rewinded - can be from 0 to 8
+        // note that iInBuffer must be byte aligned before rewinding
+        if (iInBuffer->bitIndex == 7) // full byte rewind
+        { 
+          stuffBits = ( (int)(iInBuffer->getIndex) < resyncByteIndex) ? 8 : 0;
+        }
+        else 
+        {
+          stuffBits = iInBuffer->bitIndex + 1;
+        }
+        
+        bufEdit.copyMode = CopyWhole; 
+        vdtCopyBuffer(iInBuffer,iOutBuffer, resyncByteIndex, 7,
+          iInBuffer->getIndex, iInBuffer->bitIndex); 
+        
+        // stuff bits in outbuffer for next start code   
+        vdtStuffBitsMPEG4(iOutBuffer);
+        
+        // move inbuffer pointer back to original value
+        bibForwardBits(stuffBits, iInBuffer);
+        
+        
+        
+      }
+      
+      aDecoderInfo->vosHeaderSize = iOutBuffer->getIndex;
+    }
+        
+    PRINT((_L("CMPEG4Transcoder: ConstructVOSHeader. resyn: %d, data partitioned: %d, rvlc: %d, resolution: %d"),
+      iVOLHeader.error_res_disable, iVOLHeader.data_partitioned, iVOLHeader.reversible_vlc,
+      aDecoderInfo->iTimeIncrementResolution));
+  }
+  PRINT((_L("CMPEG4Transcoder:  streammode: %d, outputformat: %d, vos size : %d"), 
+    iBitStreamMode, iTargetFormat, aDecoderInfo->vosHeaderSize));
+}
+
+
+
+
+/****************************************************************
+*                                                               *
+*    Functions for H.263, or H.263 -> MPEG4 (only baseline H.263) *
+*                                                               *
+*****************************************************************/
+
+
+/* Luminance block dc-scaler value corresponding to QP values of 0-31 */
+const u_int8 sLumDCScalerTbl[32] = 
+{   
+       0,  8,  8,  8,  8, 10, 12, 14, 
+    16, 17, 18, 19, 20, 21, 22, 23, 
+    24, 25, 26, 27, 28, 29, 30, 31, 
+    32, 34, 36, 38, 40, 42, 44, 46 
+};
+
+/* Chrominance block dc-scaler value corresponding to QP values of 0-31 */
+const u_int8 sChrDCScalerTbl[32] = 
+{   
+       0,  8,  8,  8,  8,  9,  9, 10, 
+    10, 11, 11, 12, 12, 13, 13, 14, 
+    14, 15, 15, 16, 16, 17, 17, 18, 
+    18, 19, 20, 21, 22, 23, 24, 25 
+};
+
+/*
+* sGetMPEG4INTRADCValue
+*
+* Parameters: 
+*     intraDC      reconstructed intra DC from H263
+*     QP           quantion factor
+*     blockNum     block number (0 to 5)
+*     currMBNum    current MB number
+*     mbinWidth    number of MBs in picure width
+*     dcData       matrix to store the INTRA DC values
+*     mbVPNumber   matrix recording the video packet number for each MB
+*     
+* Function:
+*    This function gets the new intra DC for MPEG4
+* Returns:
+*     INTRA DC to put into MPEG4 bitstream
+* Error codes:
+*    None
+*
+*/
+int sGetMPEG4INTRADCValue(int intraDC, int blockNum, int currMBNum,
+                                                    int32 QP, int32 mbinWidth, int **dcData, int *mbVPNumber)
+{
+    int tempDCScaler;
+    int blockA = 0, blockB = 0, blockC = 0;
+    int gradHor, gradVer, predDC;
+    
+    VDTASSERT(currMBNum >= 0);
+    VDTASSERT(QP <= 31);
+    
+  /* Prediction blocks A (left), B (above-left), and C (above) */
+    switch (blockNum)
+    {
+        case 0:
+        case 4:
+        case 5:
+      /* Y0, U, and V blocks */
+            if (((currMBNum % mbinWidth) == 0) || /* Left edge */
+                (mbVPNumber[currMBNum - 1] != mbVPNumber[currMBNum]))
+            {
+                blockA = 1024; /* fixed value for H263 */
+            }
+            else
+            {
+                blockA = dcData[currMBNum - 1][blockNum > 3? blockNum : 1];
+            }
+            
+            if (((currMBNum / mbinWidth) == 0) || /* Top Edge */
+                ((currMBNum % mbinWidth) == 0) || /* Left Edge */
+                (mbVPNumber[currMBNum - mbinWidth - 1] != mbVPNumber[currMBNum]))
+            {
+                blockB = 1024;
+            }
+            else
+            {
+                blockB = dcData[currMBNum - mbinWidth - 1][blockNum > 3? blockNum : 3];
+            }
+            
+            if (((currMBNum / mbinWidth) == 0) || /* Top Edge */
+                (mbVPNumber[currMBNum - mbinWidth] != mbVPNumber[currMBNum]))
+            {
+                blockC = 1024;
+            }
+            else
+            {
+                blockC = dcData[currMBNum - mbinWidth][blockNum > 3? blockNum : 2];
+            }
+            break;
+            
+        case 1:
+            /* Y1 block */
+            blockA = dcData[currMBNum][0];
+            
+            if (((currMBNum / mbinWidth) == 0) || /* Top Edge */
+                (mbVPNumber[currMBNum - mbinWidth] != mbVPNumber[currMBNum]))
+            {
+                blockB = 1024;
+                blockC = 1024;
+            }
+            else
+            {
+                blockB = dcData[currMBNum - mbinWidth][2];
+                blockC = dcData[currMBNum - mbinWidth][3];
+            }
+            break;
+            
+        case 2:
+            /* Y2 block */
+            
+            if (((currMBNum % mbinWidth) == 0) || /* Left Edge */
+                (mbVPNumber[currMBNum - 1] != mbVPNumber[currMBNum]))
+            {
+                blockA = 1024;
+                blockB = 1024;
+            }
+            else
+            {
+                blockA = dcData[currMBNum  - 1][3];
+                blockB = dcData[currMBNum  - 1][1];
+            }
+            
+            blockC = dcData[currMBNum][0];
+            break;
+            
+        case 3:
+            /* Y3 block */
+            
+            blockA = dcData[currMBNum][2];
+            blockB = dcData[currMBNum][0];
+            blockC = dcData[currMBNum][1];
+            break;
+
+        default:
+            break;
+    }
+    
+    gradHor = blockB - blockC;
+    gradVer = blockA - blockB;
+    
+    if ((abs(gradVer)) < (abs(gradHor))) 
+    {
+        /* Vertical prediction (from C) */
+        predDC = blockC;
+    }
+    else 
+    {
+        /* Horizontal prediction (from A) */
+        predDC = blockA;
+    }
+    
+  /* DC quantization */
+  if (blockNum < 4) /* Luminance Block */
+  {
+        intraDC += (sLumDCScalerTbl[QP] >> 1);
+        intraDC /= sLumDCScalerTbl[QP];
+        
+        /* update the DC data matrix
+        note: for INTER MB, the entry is already preset to 1024!!
+        */
+        dcData[currMBNum][blockNum] = intraDC * sLumDCScalerTbl[QP];
+  }
+  else            /* Chrominance block */
+  {
+        intraDC += (sChrDCScalerTbl[QP] >> 1);
+        intraDC /= sChrDCScalerTbl[QP];
+        /* update the DC data matrix
+        note: for INTER MB, the entry is already preset to 1024!!
+        */
+        dcData[currMBNum][blockNum] = intraDC * sChrDCScalerTbl[QP];
+  }
+    /* DC prediction */
+  tempDCScaler = (blockNum<4)? sLumDCScalerTbl[QP] : sChrDCScalerTbl[QP];
+    
+  return (intraDC - ((predDC + tempDCScaler/2) / tempDCScaler));
+}
+
+/*
+* sPutVOLHeader
+*
+* Parameters: 
+*     bitOut       pointer to the output buffer
+*     aWidth       picture width
+*     aHeight      picture height
+*     aTimerResolution timer resolution for MPEG4
+*     
+* Function:
+*    This function writes the VOL header into bit-stream
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+inline void sPutVOLHeader(bibBuffer_t* bitOut, int aWidth, int aHeight, int aTimerResolution)
+{
+    bibBuffer_t     *lBitOut;
+    uint32          vop_time_increment_resolution;
+    
+    lBitOut = bitOut;
+    WRITE32(lBitOut, (uint32)VIDEO_OBJECT_LAYER_START_CODE);
+    /* RandomAccessibleVol == 1 means all VOP's can be decoded independently */
+    sPutBits(lBitOut, 1, 0);
+    /* VideoObjectTypeIndication = SIMPLE OBJECT */
+    sPutBits(lBitOut, 8, SIMPLE_OBJECT);
+    /* IsObjectLayerIdentifier */
+    sPutBits(lBitOut, 1, 0);
+    /* AspectRatioInfo */
+    sPutBits(lBitOut, 4, ASPECT_RATIO_INFO);
+    /* vol_control_parameters = 1 */
+    sPutBits(lBitOut, 1, 1);
+    /* Chroma Format */
+    sPutBits(lBitOut, 2, CHROMA_FORMAT);
+    /* LowDelay = 1; */
+    sPutBits(lBitOut, 1, 1);
+    /* vbvParameters = 0; */
+    sPutBits(lBitOut, 1, 0);
+    /* VideoObjectLayerShape == RECTANGULAR */
+    sPutBits(lBitOut, 2, RECTANGULAR);
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);
+    /* VopTimeIncrementResolution */
+    vop_time_increment_resolution = aTimerResolution;
+    sPutBits(lBitOut, 16, vop_time_increment_resolution);
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);    
+    /* FixedVOPRate = 0, not fixed */
+    sPutBits(lBitOut, 1, 0);    
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);
+    /* VideoObjectLayerWidth */
+    sPutBits(lBitOut, 13, aWidth);
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);
+    /* VideoObjectLayerHeight */
+    sPutBits(lBitOut, 13, aHeight);
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);
+    /* Interlaced = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* ObmcDisable= 1 */
+    sPutBits(lBitOut, 1, 1);
+    /* SpriteEnable = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* Not8Bit = 0 */
+    sPutBits(lBitOut, 1, 0);
+    /* QuantType = H263 (0) */
+    sPutBits(lBitOut, 1, H263);
+    /* Complexity Estimation Disable = 1 */
+    sPutBits(lBitOut, 1, 1);
+    /* ResyncMarkerDisable */
+    sPutBits(lBitOut, 1, 0); /* H263 is converted to resyn_marker MPEG4 in video editor */
+    /* DataPartioned */
+    sPutBits(lBitOut, 1, 0); /* always 0 for H263 */
+    /* Reversible VLC  closed */
+    /* Scalability = 0 */
+    sPutBits(lBitOut, 1, 0);
+    vdtStuffBitsMPEG4(lBitOut);
+    
+    return;
+}
+
+
+/*
+* sPutGOVHeader
+*
+* Parameters: 
+*     bitOut       pointer to the output buffer
+*     aModuloTimeBase  time base for MPEG4
+*     
+* Function:
+*    This function writes the group of VOP(GOV) header into bit-stream
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+inline void sPutGOVHeader(bibBuffer_t *bitOut, int aModuloTimeBase)
+{
+    int32 time_code_hours;
+    int32 time_code_minutes;
+    int32 time_code_seconds;
+    
+    WRITE32(bitOut, (uint32)GROUP_OF_VOP_START_CODE);
+    time_code_seconds = aModuloTimeBase;
+    time_code_minutes = time_code_seconds / 60;
+    time_code_hours   = time_code_minutes / 60;    
+    time_code_minutes = time_code_minutes - (time_code_hours * 60);
+    time_code_seconds = time_code_seconds - (time_code_minutes * 60)
+        - (time_code_hours * 3600);
+    
+    sPutBits(bitOut, 5, time_code_hours);
+    sPutBits(bitOut, 6, time_code_minutes);
+    sPutBits(bitOut, 1, MARKER_BIT);
+    sPutBits(bitOut, 6, time_code_seconds);
+    
+    /* ClosedGov */
+    sPutBits(bitOut, 1, 0);
+    /* Broken Link */
+    sPutBits(bitOut, 1, 0);
+    
+    /* Stuff bits */
+    vdtStuffBitsMPEG4(bitOut);
+    
+    return;
+}
+
+/*
+* sConstructMPEG4VOSHeaderForH263
+*
+* Parameters: 
+*     bitOut       pointer to the output buffer
+*     aWidth       picture width
+*     aHeight      picture height
+*     
+* Function:
+*    This function writes the MPEG4 VOS header into bit-stream
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+void sConstructMPEG4VOSHeaderForH263(bibBuffer_t *bitOut, int aWidth, int aHeight, int aOutputMpeg4TimeRes)
+{
+    /* visual object sequence header */
+    WRITE32(bitOut, (uint32)VISUAL_OBJECT_SEQUENCE_START_CODE);
+    
+    /* This is for testing for level 0,3 */
+    uint32 level = 8;   /* level 0 for QCIF or less */
+    if(aWidth > 176 || aHeight > 144)   /* level 2 for greater than QCIF */
+        level = 2;
+    sPutBits(bitOut, 8, level); /* simple profile, level 0 for H263 */
+    
+    /* visual object header begins */
+    WRITE32(bitOut, (uint32)VISUAL_OBJECT_START_CODE);
+    /* IsVisualObjectIdentifier = 0 */
+    sPutBits(bitOut, 1, 0);
+    /* VisualObjectType = VIDEO_OBJECT */
+    sPutBits(bitOut, 4, VISUAL_OBJECT);
+    /* VideoSignalType = 0 */
+    sPutBits(bitOut, 1, 0);
+    
+    vdtStuffBitsMPEG4(bitOut);
+    WRITE32(bitOut, (uint32)VIDEO_OBJECT_START_CODE);
+    
+    /* Writes the VOL header into bit-stream , for baseline H263 TR is marked with 29.97fps. ->? */
+    sPutVOLHeader(bitOut, aWidth, aHeight, aOutputMpeg4TimeRes);
+    
+    /* Writes GOV , time base is 0 */
+    sPutGOVHeader(bitOut, 0);
+    
+    return;
+}
+
+
+/*
+* sPutVideoPacketHeader
+*
+* Parameters: 
+*     lBitOut      output buffer
+*     mbNo         Macroblock number
+*     quantiserScale quant value to be put in header
+*     aMBsInVOP    # of MBs in one VOP
+*     
+* Function:
+*    This function writes the video packet header information into bit-stream
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+inline void sPutVideoPacketHeader(bibBuffer_t *lBitOut, int32 mbNo, 
+                                                                    int16 quantiserScale,
+                                                                    int aMBsInVOP)
+{
+    int32   lResyncMarkerLength = 17;
+    int32   lMBNoResolution;
+    
+    /* ResyncMarker */
+    int fCode = 1; /*always 1 for H263 */
+    lResyncMarkerLength = 16 + fCode; 
+    sPutBits(lBitOut, lResyncMarkerLength, 1);
+    
+    --aMBsInVOP;
+    lMBNoResolution = 1;
+    while( (aMBsInVOP =
+        aMBsInVOP >> 1) > 0 )
+    {
+        lMBNoResolution++;
+    }
+    sPutBits(lBitOut, lMBNoResolution, mbNo);
+    
+    /* QuantScale */ 
+    sPutBits(lBitOut, 5, quantiserScale);
+    /* HEC */
+    sPutBits(lBitOut, 1, 0); /* always 0 for H263 */
+    
+    return;
+}
+
+/*
+* sConstructVOPHeaderForH263
+*
+* Parameters: 
+*     lBitOut      output buffer
+*     prevQuant    quant value to be put in header
+*     aVOPType     picture coding type
+*     aVOPTimeIncrement  time increament
+*     
+* Function:
+*    This function writes the VOP header into bit-stream for one H263 frame
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+
+void sConstructVOPHeaderForH263(bibBuffer_t *lBitOut, int prevQuant, int aVOPType, int aVOPTimeIncrement,int aOutputMpeg4TimeRes)
+{
+    WRITE32(lBitOut, (uint32)VOP_START_CODE);
+    /* VOPType, 0 for Intra and 1 for inter */
+    sPutBits(lBitOut, 2, aVOPType);
+    
+    /* H263 TR is marked with 29.97fps */
+    /* Modulo Time Base */
+    int outputTimerResolution = aOutputMpeg4TimeRes;
+    while ((unsigned)aVOPTimeIncrement >= (unsigned) outputTimerResolution)
+    {
+        sPutBits(lBitOut, 1, 1);
+        aVOPTimeIncrement -= outputTimerResolution; 
+    }
+    sPutBits(lBitOut, 1, 0);
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);   
+    /* VopTimeIncrement */
+    int numOutputTrBits;
+    for (numOutputTrBits = 1; ((outputTimerResolution-1) >> numOutputTrBits) != 0; numOutputTrBits++)
+        {
+        }
+    int VOPIncrementResolutionLength = numOutputTrBits;
+    sPutBits(lBitOut, VOPIncrementResolutionLength, aVOPTimeIncrement);
+    /* Marker Bit */
+    sPutBits(lBitOut, 1, MARKER_BIT);
+    /* VOPCoded */
+    sPutBits(lBitOut, 1, 1); /* always 1 for H263 */
+    /* VOPRoundingType */
+    if(aVOPType == P_VOP)
+    {
+        sPutBits(lBitOut, 1, 0); /* always 0 for H263 */
+    }
+    /* IntraDCVLCThreshold */
+    sPutBits(lBitOut, 3, 0); /* always 0 for H263 */
+    /* VOPQuant */
+    sPutBits(lBitOut, 5, prevQuant);
+    /* VOPFcodeForwad */
+    if(aVOPType == P_VOP)
+    {
+        sPutBits(lBitOut, 3, 1); /* always 1 for H263 */
+    }
+    
+    return;
+}
+
+
+
+/*
+* H263PictureHeaderEndedL
+*
+* Parameters: 
+*     
+* Function:
+*    This function is called after one H263 picture header is parsed
+*    Note: the input header is only valid inside this function
+* Returns:
+*    VDC error codes
+* Error codes:
+*    None
+*
+*/
+int CMPEG4Transcoder::H263PictureHeaderEnded(dphOutParam_t *aH263PicHeader, dphInOutParam_t *aInfo)
+{
+    VDTASSERT(aH263PicHeader);  
+    
+    // asad
+    if (!aInfo->vdcInstance->frameNum || !iRefQuant)
+    {
+        iRefQuant = aH263PicHeader->pquant;
+        iDcScaler = GetMpeg4DcScalerUV(iRefQuant); 
+    }
+    
+    if (!iDoModeTranscoding )
+    {
+        
+       /* Copy the header to output stream */
+       bufEdit.copyMode = CopyWhole; /* CopyWhole */
+         
+         if ( (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45) && 
+               fFirstFrameInH263 && iBitStreamMode == EVedVideoBitstreamModeMPEG4ShortHeader)
+         {
+             /* we don't need the VOS header, remove it */
+             PRINT((_L("CMPEG4Transcoder: MPEG4 shortheader VOS removed")));
+             
+             CopyStream(iInBuffer,iOutBuffer,&bufEdit,iShortHeaderEndByteIndex,iShortHeaderEndBitIndex);
+             fFirstFrameInH263 = EFalse;
+         }
+         else
+         {
+           /* copy from the begining of the input buffer, 
+              including the VOS header for MPEG4 shortheader if its mode is not being changed
+             */
+             CopyStream(iInBuffer,iOutBuffer,&bufEdit,0,7);
+         }
+    }
+    
+
+    
+    else
+    {
+        /* H263 Picture Header -> MPEG4 VOP Header mapping
+           information about this frame
+        */
+        iMBsinWidth = aInfo->vdcInstance->pictureParam.lumWidth >> 4;
+        
+        iNumMBsInOneVOP = (aInfo->vdcInstance->pictureParam.lumWidth >> 4) *
+            (aInfo->vdcInstance->pictureParam.lumHeight >> 4);
+        
+        iNumMBsInGOB = aInfo->vdcInstance->pictureParam.numMBsInGOB;
+        
+        /* create the intraDC matrix for DC prediction */
+        VDTASSERT(!iH263DCData);
+        VDTASSERT(!iH263MBVPNum);
+        
+        iH263DCData = (int **)malloc(iNumMBsInOneVOP * sizeof(int));
+        if (!iH263DCData) 
+        {
+            deb("CMPEG4Transcoder::ERROR - iH263DCData creation failed\n");
+            return TX_ERR;
+        }
+        
+        for (int i = 0; i < iNumMBsInOneVOP; i++)
+        {
+            iH263DCData[i] = (int *) malloc(6 * sizeof(int)); /* six blocks in one MB */
+            VDTASSERT(iH263DCData[i]);
+            if (!iH263DCData[i]) 
+            {
+                deb("CMPEG4Transcoder::ERROR - iH263DCData[i] creation failed\n");
+
+                for(int k=0; k<i; k++)
+                {
+                    free (iH263DCData[k]); 
+                }
+                if (iH263DCData) 
+                {
+                    free(iH263DCData);
+                }
+
+                return TX_ERR;
+            }
+
+            
+            /* initialize each entry to 1024 for DC prediction */
+            for (int j = 0; j < 6; j++)
+            {
+                iH263DCData[i][j] = 1024;
+            }
+        }
+        
+        iH263MBVPNum = (int *) malloc(iNumMBsInOneVOP * sizeof(int));
+        if (!iH263MBVPNum) 
+        {
+            deb("CMPEG4Transcoder::ERROR - iH263MBVPNum creation failed\n");
+            return TX_ERR;
+        }
+        
+        memset(iH263MBVPNum, 0, iNumMBsInOneVOP * sizeof(int));
+        int pictureType = aInfo->vdcInstance->pictureParam.pictureType == VDX_PIC_TYPE_I? I_VOP : P_VOP;
+        
+        if (fFirstFrameInH263)
+        {
+            /* first frame, construct the VOS header */
+            sConstructMPEG4VOSHeaderForH263(iOutBuffer,
+                aInfo->vdcInstance->pictureParam.lumWidth,
+                aInfo->vdcInstance->pictureParam.lumHeight, 
+                iOutputMpeg4TimeIncResolution);
+            fFirstFrameInH263 = EFalse;
+            
+            PRINT((_L("CMPEG4Transcoder: H263 -> MPEG VOS generated")));
+        }
+        sConstructVOPHeaderForH263(iOutBuffer, aH263PicHeader->pquant, pictureType, aH263PicHeader->trp == -1 ? 0 : aH263PicHeader->trp,iOutputMpeg4TimeIncResolution);
+
+        
+    PRINT((_L("CMPEG4Transcoder: H263 -> MPEG4: transcoding one picture")));
+    }
+    
+    
+    PRINT((_L("CMPEG4Transcoder: H263PictureHeaderEndedL. color effect: %d, format convert %d, do transcoding: %d streammode: %d, outputformat: %d "), 
+       iColorEffect, iDoModeTranscoding, iDoTranscoding,
+         iBitStreamMode, iTargetFormat));
+    
+    return TX_OK;
+}
+
+/*
+* H263GOBSliceHeaderEnded
+*
+* Parameters: 
+*     
+* Function:
+*    This function is called after one H263 GOB or Slice header is parsed
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::H263GOBSliceHeaderEnded(vdxGOBHeader_t *aH263GOBHeader, vdxSliceHeader_t */*aH263SliceHeader*/)
+{
+    iGOBSliceHeaderEndByteIndex = iInBuffer->getIndex;
+    iGOBSliceHeaderEndBitIndex  = iInBuffer->bitIndex;  
+    
+    if (aH263GOBHeader)
+    {
+        /* not the first GOB (no header), we have stuffing bits ahead
+        since we only store the position of GBSC not including 
+        the stuffing bits, we may need to insert the stuffing bits here
+        if we have color effect, we have done the stuffing at the end of last GOB
+        see functin: H263OneGOBSliceWithHeaderEnded
+        */
+        sStuffBitsH263(iOutBuffer); 
+    }
+    
+    if (!iDoModeTranscoding)
+    {
+       /* Copy the header to output stream */
+       bufEdit.copyMode = CopyWhole; // whole
+         CopyStream(iInBuffer,iOutBuffer,&bufEdit,iGOBSliceStartByteIndex,iGOBSliceStartBitIndex);
+         
+    }
+
+    else
+    {
+        /* H263 GOB (Slice) Header -> MPEG4 VP Header mapping */
+        if (!VDT_NO_DATA((int)iInBuffer->getIndex, iInBuffer->bitIndex, iGOBSliceStartByteIndex, iGOBSliceStartBitIndex) &&
+            aH263GOBHeader)
+        {
+            /* sPutVideoPacketHeader */
+            sPutVideoPacketHeader(iOutBuffer, aH263GOBHeader->gn * iNumMBsInGOB, (short)aH263GOBHeader->gquant, iNumMBsInOneVOP);
+        }
+    }
+        
+    // one slice ended, new video packet starting
+    iCurMBNumInVP = -1;
+    
+}
+
+
+/*
+* H263GOBSliceHeaderBegin
+*
+* Parameters: 
+*     
+* Function:
+*    This function is called before one H263 GOB or Slice header is parsed
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::H263GOBSliceHeaderBegin()
+{
+    /* position not include the stuffing bits ahead of the GBSC ! */
+    iGOBSliceStartByteIndex = iInBuffer->getIndex;
+    iGOBSliceStartBitIndex  = iInBuffer->bitIndex;
+    iStuffingBitsUsed = 0;
+}
+
+
+/*
+* H263GOBSliceHeaderBegin
+*
+* Parameters: 
+*     
+* Function:
+*    This function is called after one H263 GOB or Slice ends
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::H263OneGOBSliceEnded(int nextExpectedMBNum)
+{
+    if (iDoTranscoding)
+    {
+        /* MBs are lost or not coded, for H263 and H263->MPEG4 both */
+        for (int i = iLastMBNum+1; i < nextExpectedMBNum; i++)
+        {
+            /* output  1 bit COD */
+            sPutBits (iOutBuffer, 1, 1);
+        }
+        iLastMBNum = nextExpectedMBNum - 1; 
+    }
+}
+
+
+/*
+* H263OneGOBSliceWithHeaderEnded
+*
+* Parameters: 
+*     
+* Function:
+*    This function is called after GOB (Slice) that has GOB header (except the first GOB) ends
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::H263OneGOBSliceWithHeaderEnded()
+{
+    if (!iDoTranscoding)
+    {
+       bufEdit.copyMode = CopyWhole; /* CopyWhole */
+         CopyStream(iInBuffer,iOutBuffer,&bufEdit,
+             iGOBSliceHeaderEndByteIndex,iGOBSliceHeaderEndBitIndex);
+    }
+    else
+    {
+
+        if (iDoModeTranscoding)
+        {
+            /* for H263 to MPEG4, it implies that one video packet is finished */
+            vdtStuffBitsMPEG4(iOutBuffer);
+        }
+        else
+
+        {
+            /* stuffing occurs outside at the end of one GOB/slice withe header or end of frame, check in file core.cpp */
+            sStuffBitsH263(iOutBuffer); 
+        }
+        iVideoPacketNumInMPEG4 ++;
+    }
+
+    // one slice ended, new video packet starting
+    iCurMBNumInVP = -1; // 0
+
+}
+
+
+
+/*
+* H263ToMPEG4MBData
+*
+* Parameters: 
+*     
+* Function:
+*    This function transcodes one H263 MB to one MPEG4 MB
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::H263ToMPEG4MBData(int aNewMCBPCLen, int aNewMCBPC)
+{
+    /* MB data part1: output MCBPC, CBPY, DQuant, MV, intra DC etc */
+    int *dataItemStartByteIndex;
+    int *dataItemStartBitIndex;
+    int *dataItemEndByteIndex;
+    int *dataItemEndBitIndex;
+    int quant, cbpy, cbpc;
+    
+    if (iVopCodingType == VDX_VOP_TYPE_P) 
+    {
+        dataItemStartByteIndex = iCurPMBinstance->DataItemStartByteIndex;
+        dataItemStartBitIndex  = iCurPMBinstance->DataItemStartBitIndex;
+        dataItemEndByteIndex   = iCurPMBinstance->DataItemEndByteIndex;
+        dataItemEndBitIndex    = iCurPMBinstance->DataItemEndBitIndex;
+        quant = iCurPMBinstance->quant;
+        cbpy  = iCurPMBinstance->cbpy;
+        cbpc  = iCurPMBinstance->cbpc;
+    }
+    else
+    {
+        dataItemStartByteIndex = iCurIMBinstance->DataItemStartByteIndex;
+        dataItemStartBitIndex  = iCurIMBinstance->DataItemStartBitIndex;
+        dataItemEndByteIndex   = iCurIMBinstance->DataItemEndByteIndex;
+        dataItemEndBitIndex    = iCurIMBinstance->DataItemEndBitIndex;
+        quant = iCurIMBinstance->quant;
+        cbpy  = iCurIMBinstance->cbpy;
+        cbpc  = iCurIMBinstance->cbpc;
+    }
+    
+    /* COD and MCBPC, (for I frame, it is MCBPC, for P frame it is COD and MCBPC) */
+    if (iVopCodingType == VDX_VOP_TYPE_P)
+    {
+        /* It is a coded MB, output  1 bit COD (it always exists in P frame) */
+        sPutBits (iOutBuffer, 1, 0);
+    }
+    
+    if (iColorEffect)
+    {
+        /* MCBPC Changed */
+        sPutBits(iOutBuffer, aNewMCBPCLen, aNewMCBPC);
+    }
+    else
+    {
+        /* remember the positions do not include the possible stuffing MCBPC bits */
+        vdtCopyBuffer(iInBuffer, iOutBuffer,
+            dataItemStartByteIndex[0], dataItemStartBitIndex[0],
+            dataItemEndByteIndex[0], dataItemEndBitIndex[0]);
+    }
+    
+    /* ac_pred_flag  */
+    if (iMBCodingType == VDX_MB_INTRA) 
+    {
+        sPutBits(iOutBuffer, 1, 0);// it is closed for H263 INTRA MB
+    }
+    
+    /* CBPY */
+    vdtCopyBuffer(iInBuffer, iOutBuffer,
+        dataItemStartByteIndex[2], dataItemStartBitIndex[2],
+        dataItemEndByteIndex[2], dataItemEndBitIndex[2]);
+    
+    /* DQUANT, if it exsits */
+    vdtCopyBuffer(iInBuffer, iOutBuffer,
+        dataItemStartByteIndex[1], dataItemStartBitIndex[1],
+        dataItemEndByteIndex[1], dataItemEndBitIndex[1]);
+    
+    if (iMBCodingType == VDX_MB_INTER) 
+    {
+        /* MVs, if they exsit */
+        vdtCopyBuffer(iInBuffer, iOutBuffer,
+            dataItemStartByteIndex[10], dataItemStartBitIndex[10],
+            dataItemEndByteIndex[10], dataItemEndBitIndex[10]);
+    }
+    
+    /* following is the block level data */
+    for (int i = 0; i < (iColorEffect? 4 : 6); i++)
+    {
+        if (iMBCodingType == VDX_MB_INTRA) 
+        {
+            int fBlockCoded = 0;
+            if (i < 4)
+            {
+                fBlockCoded = vdxIsYCoded(cbpy, i + 1);
+            }
+            else if (i == 4)
+            {
+                fBlockCoded = vdxIsUCoded(cbpc);
+            }
+            else 
+            {
+                fBlockCoded = vdxIsVCoded(cbpc);
+            }
+            
+            /* Difference between H263 and MPEG4 :
+               0. DC quantization is different, DC need to be dequantized and requantized
+                  Note:  for ACs, here we only support H263 quantization in MPEG4, we can copy them
+                        1. DC prediction is used in MPEG4
+                        2. They use different VLC table for INTRA AC coefficient
+            */
+            /* reconstuct INTRA DC */
+            int intraDC = (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0]; /* it is already dequantized in funcion vdxGetIntraDCTBlock */
+            
+            /* INTRA quantization and prediction */
+            (iDCTBlockData + i * BLOCK_COEFF_SIZE)[0] = sGetMPEG4INTRADCValue(intraDC,
+                i, iCurMBNum, quant, iMBsinWidth,iH263DCData, iH263MBVPNum);
+            
+            /* recoding the INTRA block */
+            int numTextureBits = 0;
+            
+            vdtPutIntraMBCMT(iOutBuffer,iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, i, 0, 1); /* DC coding */
+            
+            if (fBlockCoded)
+            {
+                vdtPutIntraMBCMT(iOutBuffer,iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, i, 1, 0); /*encode ACs */
+            }
+            
+        }
+        
+        else if (!(VDT_NO_DATA(iBlockStartByteIndex[i], iBlockStartBitIndex[i],
+            iBlockEndByteIndex[i], iBlockEndBitIndex[i])))
+        {
+            
+        /* 4. same VLC table for DCTs in H263 and MPEG4, but with different Escape Coding type. 
+        see 7.4.1.3. in MPEG4 draft
+            */
+            if (iEscapeCodeUsed[i])
+            {
+                int numTextureBits = 0;
+                vdtPutInterMBCMT(iOutBuffer,0, iDCTBlockData + i * BLOCK_COEFF_SIZE, &numTextureBits, OFF);
+            }
+            else
+            {
+                bufEdit.copyMode = CopyWhole; /* CopyWhole */
+                vdtCopyBuffer(iInBuffer,iOutBuffer,
+                    iBlockStartByteIndex[i],iBlockStartBitIndex[i],
+                    iBlockEndByteIndex[i],iBlockEndBitIndex[i]);
+            }
+        }
+    }
+    
+  if (iColorEffect && (iMBCodingType == VDX_MB_INTRA))
+    {
+        ResetMPEG4IntraDcUV();
+    }
+}
+
+
+
+/*
+* NeedDecodedYUVFrame
+*
+* Parameters: 
+*     
+* Function:
+*    This function indicates if whether we need the decoded frame 
+* Returns:
+*     ETrue if we need the decoded frame
+* Error codes:
+*    None
+*
+*/
+int CMPEG4Transcoder::NeedDecodedYUVFrame()
+{
+    if ( (iTargetFormat == EVedVideoTypeH263Profile0Level10 || iTargetFormat == EVedVideoTypeH263Profile0Level45) &&
+        iBitStreamMode !=EVedVideoBitstreamModeMPEG4ShortHeader && iBitStreamMode != EVedVideoBitstreamModeH263)
+        return ETrue;
+    else
+        return EFalse;
+}
+
+/*
+* NewL
+*
+* Parameters: 
+*     
+* Function:
+*    Symbian two-phased constructor 
+* Returns:
+*     pointer to constructed object, or NULL
+* Error codes:
+*    None
+*
+*/
+CMPEG4Transcoder* CMPEG4Transcoder::NewL(const vdeInstance_t *aVDEInstance, bibBuffer_t *aInBuffer, bibBuffer_t *aOutBuffer)
+{
+    CMPEG4Transcoder *self = new (ELeave) CMPEG4Transcoder(aVDEInstance, aInBuffer, aOutBuffer);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    
+    return self;
+}
+
+
+/*
+* ConstructL
+*
+* Parameters: 
+*     
+* Function:
+*    Symbian 2nd phase constructor (can leave)
+* Returns:
+*     None
+* Error codes:
+*    None
+*
+*/
+void CMPEG4Transcoder::ConstructL()
+{
+    
+    /* Create one IMB Instance  */
+    iCurIMBinstance = (vdxIMBListItem_t *) malloc(sizeof(vdxIMBListItem_t));
+    if (!iCurIMBinstance) 
+    {
+        deb("CMPEG4Transcoder::ERROR - iCurIMBinstance creation failed\n");
+        User::Leave(KErrNoMemory);
+       
+    }
+    memset(iCurIMBinstance, 0, sizeof(vdxIMBListItem_t));
+    
+    /* Create one PMBInstance */
+    iCurPMBinstance = (vdxPMBListItem_t *) malloc(sizeof(vdxPMBListItem_t));
+    if (!iCurPMBinstance) 
+    {
+        deb("CMPEG4Transcoder::ERROR - iCurPMBinstance creation failed\n");
+        User::Leave(KErrNoMemory);
+       
+    }
+    memset(iCurPMBinstance, 0, sizeof(vdxPMBListItem_t));
+    
+    /* initialize the edit buffer */
+    bufEdit.editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
+    VDTASSERT(bufEdit.editParams);
+    if (!bufEdit.editParams) 
+    {
+        deb("CMPEG4Transcoder::ERROR - bufEdit.editParams creation failed\n");
+        User::Leave(KErrNoMemory);
+       
+    }else{
+        bufEdit.numChanges = 1;
+    }
+    
+    if (!iMBType)
+    {
+        iMBType = (u_char *) malloc(iNumMBsInOneVOP * sizeof(u_char));
+        if (!iMBType) 
+        {
+            deb("CMPEG4Transcoder::ERROR - iMBType creation failed\n");
+            User::Leave(KErrNoMemory);
+        }
+        memset(iMBType, VDX_MB_INTER, iNumMBsInOneVOP * sizeof(u_char));
+    }    
+    
+}
+
+
+/*
+* GetMpeg4DcScaler
+*
+* Parameters: 
+*     
+*  aQP            Quantization parameter
+*
+* Function:
+*    Evaluates Chrominance DC Scaler from QP for MPEG4
+* Returns:
+*    int DC scaler value
+* Error codes:
+*    None
+*
+*/
+int CMPEG4Transcoder::GetMpeg4DcScalerUV(int aQP)
+{
+    if (aQP>=1 && aQP<=4)
+        return (8);
+    else if (aQP>=5 && aQP<=24)
+        return ((aQP+13)/2);
+    else if (aQP>=25 && aQP<=31)
+        return (aQP-6);
+    else 
+        return (0);  // error 
+}
+
+
+void CMPEG4Transcoder::AfterMBLayer(int aUpdatedQp)
+{
+  iCurQuant = aUpdatedQp;
+}
+
+
+
+
+/* End of File */