videoeditorengine/h263decoder/src/h263dntc.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 7 4c409de21d23
equal deleted inserted replaced
0:951a5db380a0 3:e0b5df5c0969
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * Video decoder control interface.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 /*
       
    23  * Includes
       
    24  */
       
    25 
       
    26 /* Include the definition header for the active build target */
       
    27 #include "h263dConfig.h"
       
    28 /* Include the header for this file */
       
    29 #include "h263dntc.h"
       
    30 /* All other inclusions */
       
    31 #include "biblin.h"
       
    32 #include "h263dapi.h"
       
    33 #include "vde.h"
       
    34 #include "vdemain.h"
       
    35 #include "vdeti.h"
       
    36 #include "biblin.h"
       
    37 /* MVE */
       
    38 //#include "InnerTranscoder.h"
       
    39 #include "core.h"
       
    40 #include "MPEG4Transcoder.h"
       
    41 
       
    42 /* 
       
    43  * Constants 
       
    44  */
       
    45 const TUint KH263StartCodeLength = 3;  // H.263 picture start code length
       
    46 const TUint KMPEG4StartCodeLength = 4; // MPEG4 picture start code length
       
    47 
       
    48 /*
       
    49 * Global functions
       
    50 */
       
    51 
       
    52 /* {{-output"h263dClose.txt"}} */
       
    53 /*
       
    54 * h263dClose
       
    55 *    
       
    56 *
       
    57 * Parameters:
       
    58 *    hInstance                  instance handle
       
    59 *
       
    60 * Function:
       
    61 *    This function closes an H.263 decoder instance.
       
    62 *
       
    63 * Returns:
       
    64 *    Nothing
       
    65 */
       
    66 
       
    67 void H263D_CC h263dClose(h263dHInstance_t hInstance)
       
    68 /* {{-output"h263dClose.txt"}} */
       
    69 {
       
    70     if (hInstance)
       
    71         vdeShutDown(hInstance);
       
    72 }
       
    73 
       
    74 
       
    75 /* {{-output"h263dDecodeFrame.txt"}} */
       
    76 /*
       
    77 * h263dDecodeFrameL
       
    78 *    
       
    79 *
       
    80 * Parameters:
       
    81 *    hInstance                  instance data
       
    82 *    pStreamBuffer              pointer to input data (>= 1 video frames)
       
    83 *    streamBufferSize           size of pStreamBuffer
       
    84 *    fFirstFrame                pointer to flag telling if the very first
       
    85 *                               frame is being decoded
       
    86 *    frameSize                  If non-NULL, frameSize is used to return 
       
    87 *                               the number of bytes that were decoded 
       
    88 *                               to produce the reconstructed output frame.
       
    89 *
       
    90 * Function:
       
    91 *    This function decodes the bitstream until it gets at least one decoded
       
    92 *    frame. It also shows the resulting frames. 
       
    93 *    In addition, the function handles the parameter updating synchronization.
       
    94 *
       
    95 * Returns:
       
    96 *    H263D_OK                   if the function was successful
       
    97 *    H263D_OK_EOS               if the end of stream has been reached
       
    98 *    H263D_ERROR                if a fatal error, from which the decoder
       
    99 *                               cannot be restored, has occured
       
   100 *    H263D_ERROR_HALTED         the instance is halted, it should be closed
       
   101 */
       
   102 
       
   103 int H263D_CC h263dDecodeFrameL(h263dHInstance_t hInstance,
       
   104                                void *pStreamBuffer,
       
   105                                void *pOutStreamBuffer,
       
   106                                unsigned streamBufferSize,
       
   107                                u_char *fFirstFrame,
       
   108                                TInt *frameSize,
       
   109                                TInt *outframeSize, 
       
   110                                vdeDecodeParamters_t *aDecoderInfo
       
   111                                )
       
   112                                                             
       
   113 /* {{-output"h263dDecodeFrame.txt"}} */
       
   114 {
       
   115     TInt colorEffect = aDecoderInfo->aColorEffect;
       
   116     TInt colorToneU  = aDecoderInfo->aColorToneU;
       
   117     TInt colorToneV  = aDecoderInfo->aColorToneV;
       
   118     TInt frameOperation = aDecoderInfo->aFrameOperation;
       
   119     TInt* trP = aDecoderInfo->aTrP;
       
   120     TInt* trD = aDecoderInfo->aTrD; 
       
   121     TInt videoClipNumber = aDecoderInfo->aVideoClipNumber; 
       
   122     TInt smSpeed = aDecoderInfo->aSMSpeed;
       
   123     TInt getDecodedFrame = aDecoderInfo->aGetDecodedFrame; 
       
   124     
       
   125     bibBuffer_t 
       
   126         *buffer = 0;                   /* input buffer */
       
   127     
       
   128     bibBuffer_t 
       
   129         *outbuffer = 0;               /* output buffer */
       
   130 
       
   131     bibBuffer_t 
       
   132         *tmpbuffer = 0;                /* temporary buffer */
       
   133 
       
   134     u_char* tmpbuf=0;
       
   135 
       
   136     bibBufferEdit_t
       
   137         *bufEdit = 0;
       
   138      
       
   139     int StartByteIndex=0;
       
   140     int StartBitIndex=7;
       
   141 
       
   142     int tr = 0;
       
   143     int newtr = 0;
       
   144     int efftr;
       
   145     int numBitsGot;
       
   146     int bitsErrorIndication;
       
   147     int16 bibError;
       
   148     
       
   149     int retValue;                  /* return value for vde functions */
       
   150 
       
   151     int leaveError = 0;
       
   152      
       
   153     int16
       
   154         errorCode = 0;             /* return code for bib functions */
       
   155 
       
   156   /* MVE */
       
   157     int startCodeLen = 0;
       
   158     CMPEG4Transcoder *hTranscoder = NULL;
       
   159 
       
   160     TBool modifyMPEG4Afterwards = EFalse;
       
   161 
       
   162     vdeAssert(hInstance);
       
   163     vdeAssert(pStreamBuffer);
       
   164     vdeAssert(pOutStreamBuffer);
       
   165     vdeAssert(streamBufferSize);
       
   166     vdeAssert(fFirstFrame);
       
   167 
       
   168     vdeInstance_t *vdeinstance = (vdeInstance_t *) hInstance;
       
   169     
       
   170     /* Create bit buffer */
       
   171     buffer = bibCreate(pStreamBuffer, streamBufferSize, &errorCode);
       
   172      if (!buffer || errorCode)
       
   173          return H263D_ERROR;
       
   174      
       
   175      /* MVE */
       
   176 
       
   177      if ((aDecoderInfo->streamMode==EVedVideoBitstreamModeMPEG4ShortHeader) || (aDecoderInfo->streamMode == EVedVideoBitstreamModeH263) )
       
   178          outbuffer = bibCreate(pOutStreamBuffer, streamBufferSize-3, &errorCode);
       
   179      else
       
   180          outbuffer = bibCreate(pOutStreamBuffer, streamBufferSize-4-3, &errorCode);
       
   181 
       
   182      if (!outbuffer || errorCode)
       
   183      {
       
   184          bibDelete(buffer, &errorCode);
       
   185          return H263D_ERROR;
       
   186      }
       
   187      
       
   188      bufEdit = bibBufferEditCreate(&errorCode);
       
   189      if (!bufEdit || errorCode)
       
   190      {
       
   191          bibDelete(outbuffer, &errorCode);
       
   192          bibDelete(buffer, &errorCode);
       
   193          return H263D_ERROR;
       
   194      }   
       
   195      
       
   196      if(frameOperation==4 /*ENoDecodeNoWrite*/)
       
   197      {
       
   198          bufEdit->copyMode = CopyNone;
       
   199      }
       
   200      
       
   201      if(colorEffect==1 || colorEffect==2)
       
   202      {
       
   203          outbuffer->numBytesRead=0;
       
   204          outbuffer->size=0;
       
   205      }
       
   206      
       
   207    /* Associate bit buffer with the VDE instance */
       
   208      retValue = vdeSetInputBuffer(hInstance, buffer);
       
   209      if (retValue < 0)
       
   210          goto freeBufferAndReturn;
       
   211      
       
   212      /* Associate output bit buffer with the VDE instance */
       
   213      retValue = vdeSetOutputBuffer(hInstance, outbuffer);
       
   214      if (retValue < 0)
       
   215          goto freeBufferAndReturn;
       
   216      
       
   217      retValue = vdeSetBufferEdit(hInstance, bufEdit);
       
   218      if (retValue < 0)
       
   219          goto freeBufferAndReturn;
       
   220      
       
   221      retValue = vdeSetVideoEditParams(hInstance, colorEffect,
       
   222        getDecodedFrame, colorToneU, colorToneV);
       
   223      if (retValue < 0)
       
   224          goto freeBufferAndReturn;
       
   225      
       
   226    /* MVE */
       
   227      if (aDecoderInfo->streamMode == EVedVideoBitstreamModeH263 /*H.263*/)
       
   228      {
       
   229          /* read current TR */
       
   230          bibForwardBits(22,buffer); // streamBufferSize is in bytes
       
   231          tr = bibGetBits(8,buffer,&numBitsGot, &bitsErrorIndication, &bibError);    
       
   232          bibRewindBits(30,buffer,&bibError);
       
   233      }
       
   234 
       
   235   /* get first frame's QP */
       
   236   if (!(*fFirstFrame))
       
   237   {
       
   238     vdeinstance->iRefQp = aDecoderInfo->aFirstFrameQp;
       
   239   }
       
   240   vdeinstance->iColorEffect = aDecoderInfo->aColorEffect;
       
   241   vdeinstance->iColorToneU = aDecoderInfo->aColorToneU;
       
   242   vdeinstance->iColorToneV = aDecoderInfo->aColorToneV;
       
   243   
       
   244   /* MVE */
       
   245   /* one frame is ready, initialize the transcoder */
       
   246     TRAP( leaveError, (hTranscoder = CMPEG4Transcoder::NewL(vdeinstance, vdeinstance->inBuffer, vdeinstance->outBuffer)) );
       
   247     if ( leaveError != 0 )
       
   248     {
       
   249         retValue = leaveError;
       
   250         goto freeBufferAndReturn;
       
   251     }
       
   252 
       
   253     if (aDecoderInfo->aGetVideoMode)
       
   254     {
       
   255         /* we are to determine the bitstream mode */
       
   256         aDecoderInfo->aOutputVideoFormat = EVedVideoTypeNoVideo;
       
   257         int dummy1, dummy2; // position of the error resillence bit,not used here
       
   258         vdtGetVideoBitstreamInfo(buffer, aDecoderInfo, &dummy1, &dummy2);
       
   259     }
       
   260 
       
   261     /* set transcoding information */
       
   262     retValue = hTranscoder->SetTranscoding(aDecoderInfo);
       
   263     if ( retValue != TX_OK )
       
   264     {
       
   265         goto freeBufferAndReturn;
       
   266     }
       
   267     
       
   268     /* before the first frame is decoded, determine the stream type */
       
   269     if (*fFirstFrame) {
       
   270         retValue = vdeDetermineStreamType(hInstance, hTranscoder);
       
   271         if (retValue < 0)
       
   272             goto freeBufferAndReturn;
       
   273         
       
   274     /* MVE */
       
   275         /* for the first frame of the bitstream, we may need to construct a new VOS */
       
   276         hTranscoder->ConstructVOSHeader(vdeinstance->fMPEG4, aDecoderInfo);
       
   277         
       
   278         if (vdeinstance->fMPEG4 == 1 )
       
   279         {
       
   280             StartByteIndex = buffer->getIndex;
       
   281             StartBitIndex  = buffer->bitIndex;
       
   282             
       
   283             /* for MPEG4 (not including shortheader) stuffing bits are inserted at the end of the VOS
       
   284             but the index here indicates the position of the stuffing bits
       
   285             */
       
   286             if (StartBitIndex != 7)
       
   287             {
       
   288                 StartByteIndex += 1;
       
   289                 StartBitIndex = 7;
       
   290             }
       
   291             
       
   292             // update the output stream size by removing VOS size
       
   293             streamBufferSize -= StartByteIndex; 
       
   294         }
       
   295         
       
   296         else if (aDecoderInfo->streamMode == EVedVideoBitstreamModeMPEG4ShortHeader)
       
   297         {
       
   298             if (aDecoderInfo->aOutputVideoFormat == EVedVideoTypeH263Profile0Level10 ||
       
   299                 aDecoderInfo->aOutputVideoFormat == EVedVideoTypeH263Profile0Level45)
       
   300             {
       
   301                 // we don't need the VOS header
       
   302                 StartByteIndex = buffer->getIndex;
       
   303                 StartBitIndex  = buffer->bitIndex;
       
   304                 // update the output stream size by removing VOS size
       
   305                 streamBufferSize -= StartByteIndex; 
       
   306             }
       
   307             else if (aDecoderInfo->aOutputVideoFormat == EVedVideoTypeMPEG4SimpleProfile &&
       
   308                 aDecoderInfo->fModeChanged == EFalse)
       
   309             {
       
   310                 // update the output stream size by removing VOS size
       
   311                 // but we need the original MPEG4 shortheader VOS, which is not yet copied to the output buffer
       
   312                 streamBufferSize -= buffer->getIndex;
       
   313                 
       
   314             }
       
   315         }
       
   316         
       
   317     }
       
   318 
       
   319     /* This may produce multiple output frames, and that is why it is commented
       
   320      out. However, it may be useful if the bitstream is corrupted and picture
       
   321      start codes are lost
       
   322      while (buffer->bitsLeft > 8) { */
       
   323      /* Decode frame */
       
   324 
       
   325   /* MVE */
       
   326   /* The buffer size is changed in h263decoder.cpp
       
   327     In the old version, it is fixed to 3, which may be incorrect 
       
   328     */
       
   329     startCodeLen = (aDecoderInfo->streamMode == EVedVideoBitstreamModeH263)? KH263StartCodeLength : KMPEG4StartCodeLength;
       
   330     
       
   331     
       
   332     
       
   333     if ( ((aDecoderInfo->aOutputVideoFormat == EVedVideoTypeMPEG4SimpleProfile) 
       
   334             && !(aDecoderInfo->streamMode == EVedVideoBitstreamModeMPEG4ShortHeader))
       
   335         || ((aDecoderInfo->streamMode == EVedVideoBitstreamModeMPEG4ShortHeader) && aDecoderInfo->fModeChanged) )
       
   336         {
       
   337         modifyMPEG4Afterwards = ETrue;
       
   338         }
       
   339 
       
   340     if (frameOperation==1/*EDecodeAndWrite*/ || frameOperation==2/*EDecodeNoWrite*/)
       
   341         {
       
   342         if ( vdeinstance->fMPEG4 == 1 )
       
   343             {
       
   344             buffer->size -= startCodeLen;
       
   345             buffer->bitsLeft -= ( startCodeLen << 3 );
       
   346             }
       
   347         retValue = vdeDecodeFrame(hInstance, StartByteIndex, StartBitIndex, hTranscoder);
       
   348         if ( retValue < VDE_OK )
       
   349             {
       
   350             // negative means fatal error
       
   351             goto freeBufferAndReturn;
       
   352             }
       
   353          // get first frame QP for possible color toning
       
   354          if (*fFirstFrame)
       
   355          {
       
   356            aDecoderInfo->aFirstFrameQp = hTranscoder->GetRefQP();
       
   357         }
       
   358      }
       
   359      else if (frameOperation==3/*EWriteNoDecode*/) 
       
   360         {
       
   361         /* first reset bit counter to beginning of buffer */
       
   362         /* copy input frame as it is */
       
   363         bibForwardBits((streamBufferSize-startCodeLen)<<3,buffer); // streamBufferSize is in bytes
       
   364          
       
   365         if (aDecoderInfo->streamMode == EVedVideoBitstreamModeMPEG4ShortHeader &&
       
   366             aDecoderInfo->aOutputVideoFormat == EVedVideoTypeMPEG4SimpleProfile &&
       
   367             !(aDecoderInfo->fModeChanged))
       
   368             {
       
   369             bibRewindBits(32,buffer,&bibError);
       
   370             }
       
   371          
       
   372         /* reset buffer edit to CopyWhole mode */
       
   373         bufEdit->copyMode = CopyWhole/*CopyWhole*/;
       
   374          
       
   375         if ( vdeinstance->fMPEG4 == 1 )
       
   376             {
       
   377             if (*fFirstFrame)
       
   378                 {
       
   379                 buffer->getIndex = buffer->size - startCodeLen;
       
   380                 buffer->bitIndex = 7;
       
   381                 buffer->bitsLeft = 24;
       
   382                 buffer->numBytesRead = buffer->size - startCodeLen;
       
   383                 }
       
   384              
       
   385             if ( buffer->numBytesRead > 4 )
       
   386                 {
       
   387                 buffer->numBytesRead -= 4;
       
   388                 buffer->getIndex = buffer->numBytesRead;
       
   389                 }
       
   390             }
       
   391          // Reassign pointers so that outbuffer actually has the pointer to (in)buffer's data, 
       
   392          // if we have MPEG4 output (not short header) and we need to change e.g. timestamps
       
   393          // This eliminates 2 memory copies - otherwise we would copy from buffer to outbuffer to tmpbuffer to outbuffer; 
       
   394          // the content is modified when copying from tmpbuffer to outbuffer. 
       
   395          // tmpbuffer is needed since we can't modify the content directly in the outbuffer.
       
   396          // Now we can copy directly from buffer to outbuffer.
       
   397          // In this branch we don't call vdeDecodeFrame at all, but use either CopyEditVopL for MPEG-4 or
       
   398          // CopyStream for H.263
       
   399          if ( modifyMPEG4Afterwards )
       
   400              {
       
   401              tmpbuffer = buffer;
       
   402              }
       
   403          else
       
   404              {
       
   405              /* copy from buffer to outbuffer. This simulates vdeDecodeFrame with EDecodeAndWrite */
       
   406              CopyStream(buffer,outbuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   407              }
       
   408          retValue=0;
       
   409      }
       
   410      
       
   411      outbuffer->size = outbuffer->getIndex;
       
   412      outbuffer->bitsLeft = 0;
       
   413 
       
   414      if ( !tmpbuffer )
       
   415         {
       
   416          /* if tr values are changes, need another buffer */
       
   417          /* first create temp buffer in memory */
       
   418          tmpbuf = (u_char*) malloc(outbuffer->size + 4);
       
   419          if (tmpbuf == NULL) 
       
   420          {
       
   421              bibDelete(outbuffer, &errorCode);
       
   422              bibDelete(buffer, &errorCode);
       
   423              bibBufEditDelete(bufEdit, &errorCode);
       
   424              return H263D_ERROR;
       
   425          }
       
   426          tmpbuffer = bibCreate((void*)tmpbuf, outbuffer->size + 4, &errorCode);
       
   427          if (!tmpbuffer || errorCode)
       
   428          {
       
   429             free(tmpbuf);
       
   430             bibDelete(outbuffer, &errorCode);
       
   431             bibDelete(buffer, &errorCode);
       
   432             bibBufEditDelete(bufEdit, &errorCode);
       
   433             return H263D_ERROR;
       
   434          }
       
   435         }
       
   436      
       
   437    /* MVE */
       
   438      if (aDecoderInfo->aOutputVideoFormat != EVedVideoTypeNoVideo)
       
   439         {
       
   440 
       
   441         if ( modifyMPEG4Afterwards )
       
   442             {
       
   443             if ( tmpbuffer != buffer )
       
   444                 {
       
   445                 // the bitstream was decoded too, need to copy it temporarily from outbuffer to tmpbuffer since it needs to be modified
       
   446                 bibRewindBits(bibNumberOfFlushedBits(tmpbuffer),tmpbuffer,&bibError);
       
   447                 bibRewindBits(bibNumberOfFlushedBits(outbuffer),outbuffer,&bibError);
       
   448                 bibForwardBits(((outbuffer->size)<<3),outbuffer);
       
   449                 outbuffer->bitsLeft = 0;
       
   450 
       
   451                 StartByteIndex = 0;
       
   452                 StartBitIndex = 7;
       
   453                 
       
   454                 CopyStream(outbuffer,tmpbuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   455                 tmpbuffer->baseAddr[tmpbuffer->getIndex] = 0x0;
       
   456                 tmpbuffer->baseAddr[tmpbuffer->getIndex+1] = 0x0;
       
   457                 tmpbuffer->baseAddr[tmpbuffer->getIndex+2] = 0x01;
       
   458                 tmpbuffer->baseAddr[tmpbuffer->getIndex+3] = 0xb6;
       
   459                 }
       
   460              else
       
   461                 {
       
   462                 // the tmpbuffer was used as a shortcut to the buffer, no need to copy anything here. 
       
   463                 tmpbuffer->bitsLeft = 32;
       
   464                 // the following ones are probably not needed
       
   465                 tmpbuffer->baseAddr[tmpbuffer->getIndex+4] = 0x0;
       
   466                 tmpbuffer->baseAddr[tmpbuffer->getIndex+5] = 0x0;
       
   467                 tmpbuffer->baseAddr[tmpbuffer->getIndex+6] = 0x01;
       
   468                 tmpbuffer->baseAddr[tmpbuffer->getIndex+7] = 0xb6;
       
   469                 }
       
   470                 
       
   471            
       
   472             bibForwardBits(32,tmpbuffer);
       
   473             
       
   474             // Copy bitstream part-by-part, possibly modifying it, from tmp to output. 
       
   475             // StartByteIndex may be > 0 if there is VOS header in tmpbuffer already. It is always byte-aligned so no need to have StartBitIndex
       
   476             TInt skip = 0;
       
   477             if ( StartByteIndex > 0 )
       
   478                 {
       
   479                 // startByteIndex refers to input buffer. 
       
   480                 // The skip however should refer to the output buffer. The output header size is in aDecoderInfo
       
   481                 skip = aDecoderInfo->vosHeaderSize;
       
   482                 }
       
   483             int retVal= CopyEditVop(hInstance, skip, tmpbuffer, aDecoderInfo);
       
   484             if(retVal<0)
       
   485                 {
       
   486                 retValue = retVal;  //will be handled later
       
   487                 }
       
   488             }
       
   489         else
       
   490             {
       
   491             /* copy input frame while changing TR */
       
   492             if((videoClipNumber>0) || (smSpeed!=1000))
       
   493                 {
       
   494                 if ((frameOperation==1) || ((frameOperation==2) && !getDecodedFrame))
       
   495                     {
       
   496                     /* if the output buffer will not be use, leave it as it is! */
       
   497                     }
       
   498                 else
       
   499                     {
       
   500 
       
   501                     /* get new TR */
       
   502                     StartByteIndex = 0;
       
   503                     StartBitIndex = 7;
       
   504                     outbuffer->bitsLeft = 0;
       
   505                     newtr = GetNewTrValue(tr, trP, trD, smSpeed);
       
   506                     /* change TR value in output bitstream */
       
   507                     /* prepare editing position */
       
   508                     if (!bufEdit->editParams)
       
   509                         {
       
   510                         bufEdit->editParams = (bibEditParams_t *) malloc(sizeof(bibEditParams_t));
       
   511                         if (bufEdit->editParams == NULL)
       
   512                             {
       
   513                             retValue = H263D_ERROR;
       
   514                             goto freeBufferAndReturn;
       
   515                             }
       
   516                         
       
   517                         bufEdit->numChanges=1;
       
   518                         bufEdit->copyMode = CopyWithEdit; // CopyWithEdit
       
   519                         }
       
   520                     bufEdit->editParams->curNumBits = bufEdit->editParams->newNumBits = 8; 
       
   521                     bufEdit->editParams->StartByteIndex=2; //2;     // starting position for the TR marker 
       
   522                     bufEdit->editParams->StartBitIndex=1; //1;          // starting position for the TR marker 
       
   523                     bufEdit->editParams->newValue=newtr; 
       
   524                     /* copy the input buffer to the output buffer with TR changes */
       
   525                     CopyStream(outbuffer,tmpbuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   526                     bibRewindBits((streamBufferSize)<<3,buffer,&bibError);
       
   527                     /* copy the changed bitstream from tmpbuffer back to buffer */
       
   528                     bufEdit->copyMode = CopyWhole; // CopyWhole
       
   529                     bibRewindBits(bibNumberOfFlushedBits(outbuffer),outbuffer,&bibError);
       
   530                     CopyStream(tmpbuffer,outbuffer,bufEdit,StartByteIndex,StartBitIndex);
       
   531                     bibRewindBits((streamBufferSize)<<3,buffer,&bibError);
       
   532                     }
       
   533                 }
       
   534             /* update TR values */
       
   535             efftr = (videoClipNumber>0 || smSpeed!=1000) ? newtr : tr; 
       
   536             *trP = efftr;
       
   537             *trD = tr; 
       
   538         }
       
   539     }
       
   540     
       
   541     *fFirstFrame = 0;
       
   542 
       
   543     if (retValue < 0)
       
   544         goto freeBufferAndReturn;   
       
   545         /* See the comment above.
       
   546         else if (retValue == H263D_OK_EOS)
       
   547         break;
       
   548    } */
       
   549 
       
   550     if (frameSize)
       
   551         *frameSize = bibNumberOfFlushedBytes(buffer) + 
       
   552         ((bibNumberOfFlushedBits(buffer) % 8 > 0) ? 1 : 0);
       
   553 
       
   554     *outframeSize = outbuffer->numBytesRead; 
       
   555 
       
   556         
       
   557 freeBufferAndReturn:
       
   558 
       
   559     int bitError = buffer->error;
       
   560 
       
   561     if (hTranscoder)
       
   562     {
       
   563         delete hTranscoder;
       
   564         hTranscoder = NULL;
       
   565     }
       
   566      
       
   567     if ( tmpbuffer == buffer )
       
   568         {
       
   569         // tmpbuffer was a shortcut to inbuffer, set it to NULL to avoid deleting it
       
   570         tmpbuffer = NULL;
       
   571         }
       
   572 
       
   573     int16 deleteError = 0;
       
   574     /* Delete bit buffer */
       
   575     bibDelete(buffer, &errorCode);
       
   576     if ( errorCode )
       
   577         {
       
   578         deleteError = errorCode;
       
   579         }
       
   580     
       
   581     /* Delete output bit buffer */
       
   582     bibDelete(outbuffer, &errorCode);
       
   583     if ( errorCode )
       
   584         {
       
   585         deleteError = errorCode;
       
   586         }
       
   587 
       
   588     /* Delete tmp bit buffer, if it was used */
       
   589     if ( tmpbuffer )
       
   590         {
       
   591         bibDelete(tmpbuffer, &errorCode);
       
   592         if ( errorCode )
       
   593             {
       
   594             deleteError = errorCode;
       
   595             }
       
   596         }
       
   597     if(tmpbuf)
       
   598         free(tmpbuf);
       
   599     
       
   600     /* Delete bufEdit */
       
   601     bibBufEditDelete(bufEdit, &errorCode);
       
   602     if ( errorCode )
       
   603         {
       
   604         deleteError = errorCode;
       
   605         }
       
   606     if (deleteError || errorCode)
       
   607         return H263D_ERROR;
       
   608 
       
   609     if ( bitError )
       
   610         {
       
   611         return H263D_OK_BUT_FRAME_USELESS;
       
   612         }
       
   613 
       
   614     return retValue;
       
   615 }
       
   616 
       
   617 
       
   618 /* {{-output"h263dGetLatestFrame.txt"}} */
       
   619 /*
       
   620 * h263dGetLatestFrame
       
   621 *    
       
   622 *
       
   623 * Parameters:
       
   624 *    hInstance                  instance data
       
   625 *    
       
   626 *    ppy, ppu, ppv              used to return Y, U and V frame pointers
       
   627 *
       
   628 *    pLumWidth, pLumHeight      used to return luminance image width and height
       
   629 *
       
   630 *    pFrameNum                  used to return frame number
       
   631 *
       
   632 * Function:
       
   633 *    This function returns the latest correctly decoded frame
       
   634 *    (and some side-information).
       
   635 *
       
   636 * Returns:
       
   637 *    H263D_OK                   if the function was successful
       
   638 *    H263D_ERROR                if a fatal error, from which the decoder
       
   639 *                               cannot be restored, has occured
       
   640 *    H263D_ERROR_HALTED         the instance is halted, it should be closed
       
   641 */
       
   642 
       
   643 
       
   644 int H263D_CC h263dGetLatestFrame(
       
   645                                                                  h263dHInstance_t hInstance,
       
   646                                                                  u_char **ppy, u_char **ppu, u_char **ppv,
       
   647                                                                  int *pLumWidth, int *pLumHeight,
       
   648                                                                  int *pFrameNum)
       
   649                                                                  /* {{-output"h263dGetLatestFrame.txt"}} */
       
   650 {
       
   651     vdeAssert(hInstance);
       
   652     vdeAssert(ppy);
       
   653     vdeAssert(ppu);
       
   654     vdeAssert(ppv);
       
   655     vdeAssert(pLumWidth);
       
   656     vdeAssert(pLumHeight);
       
   657     vdeAssert(pFrameNum);
       
   658     
       
   659     return vdeGetLatestFrame(hInstance, ppy, ppu, ppv, pLumWidth, pLumHeight,
       
   660         pFrameNum);
       
   661 }
       
   662 
       
   663 
       
   664 
       
   665 /* {{-output"h263dIsIntra.txt"}} */
       
   666 /*
       
   667 * h263dIsIntra
       
   668 *    
       
   669 *
       
   670 * Parameters:
       
   671 *    hInstance                  handle of instance data
       
   672 *    frameStart                 pointer to memory chunk containing a frame
       
   673 *    frameLength                number of bytes in frame
       
   674 *
       
   675 * Function:
       
   676 *    This function returns 1 if the passed frame is an INTRA frame.
       
   677 *    Otherwise the function returns 0.
       
   678 *
       
   679 * Returns:
       
   680 *    See above.
       
   681 */
       
   682 
       
   683 int h263dIsIntra(
       
   684                                  h263dHInstance_t hInstance,
       
   685                                  void *frameStart,
       
   686                                  unsigned frameLength)
       
   687                                  /* {{-output"h263dIsIntra.txt"}} */
       
   688 {
       
   689     vdeAssert(hInstance);
       
   690     vdeAssert(frameStart);
       
   691     vdeAssert(frameLength);
       
   692     
       
   693     return vdeIsINTRA(hInstance, frameStart, frameLength);
       
   694 }
       
   695 
       
   696 /* {{-output"h263dOpen.txt"}} */
       
   697 /*
       
   698 * h263dOpen
       
   699 *    
       
   700 *
       
   701 * Parameters:
       
   702 *    openParam                  initialization parameters
       
   703 *
       
   704 * Function:
       
   705 *    This function creates and initializes a new H.263 decoder instance.
       
   706 *
       
   707 * Returns:
       
   708 *    an instance handle if the function was successful
       
   709 *    NULL if an error occured
       
   710 */
       
   711 
       
   712 h263dHInstance_t H263D_CC h263dOpen(h263dOpen_t *openParam)
       
   713 /* {{-output"h263dOpen.txt"}} */
       
   714 {
       
   715     vdeAssert(openParam);
       
   716     
       
   717     /* No extra space needs to be allocated after the VDE instance data
       
   718     (of type vdeInstance_t) due to the fact that no thread specific
       
   719     data is needed. */
       
   720     openParam->freeSpace = 0;
       
   721     
       
   722     return vdeInit(openParam);
       
   723 }
       
   724 
       
   725 
       
   726 
       
   727 int GetNewTrValue(int aTrCurOrig, int* aTrPrevNew, int* aTrPrevOrig, int aSMSpeed)
       
   728 {
       
   729     int trCurNew=0;
       
   730     int trDiff=0;
       
   731     TReal speedFactor = (TReal)aSMSpeed/1000.0;
       
   732 
       
   733     trDiff = aTrCurOrig - *aTrPrevOrig;
       
   734     if(trDiff==0)  // if corrupt TR values
       
   735         trDiff=1;  
       
   736     else if(trDiff<0)  // jump in TR values (change of clip or end of limit)
       
   737         trDiff = 3;    // arbitrary, for 10 fps default
       
   738     // check for slow motion 
       
   739     vdeAssert(aSMSpeed);
       
   740     if(aSMSpeed!=1000)
       
   741         trDiff = (int)((TReal)trDiff/speedFactor + 0.5);
       
   742     trCurNew = *aTrPrevNew + trDiff; 
       
   743     if(trCurNew>255)
       
   744         trCurNew = trCurNew%256;
       
   745     return trCurNew;
       
   746 }
       
   747 
       
   748 
       
   749 
       
   750 // End of File