Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "mp4dec_lib.h"
     19 #include "vlc_decode.h"
     20 #include "bitstream.h"
     21 
     22 #define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
     23 #include "osclconfig_compiler_warnings.h"
     24 
     25 #ifdef DEC_INTERNAL_MEMORY_OPT
     26 #define QCIF_MBS 99
     27 #define QCIF_BS (4*QCIF_MBS)
     28 #define QCIF_MB_ROWS 11
     29 extern uint8                IMEM_sliceNo[QCIF_MBS];
     30 extern uint8                IMEM_acPredFlag[QCIF_MBS];
     31 extern uint8                IMEM_headerInfo_Mode[QCIF_MBS];
     32 extern uint8                IMEM_headerInfo_CBP[QCIF_MBS];
     33 extern int                  IMEM_headerInfo_QPMB[QCIF_MBS];
     34 extern MacroBlock           IMEM_mblock;
     35 extern MOT                  IMEM_motX[QCIF_BS];
     36 extern MOT                  IMEM_motY[QCIF_BS];
     37 extern BitstreamDecVideo    IMEM_BitstreamDecVideo[4];
     38 extern typeDCStore          IMEM_predDC[QCIF_MBS];
     39 extern typeDCACStore        IMEM_predDCAC_col[QCIF_MB_ROWS+1];
     40 
     41 extern VideoDecData         IMEM_VideoDecData[1];
     42 extern Vop                  IMEM_currVop[1];
     43 extern Vop                  IMEM_prevVop[1];
     44 extern PIXEL                IMEM_currVop_yChan[QCIF_MBS*128*3];
     45 extern PIXEL                IMEM_prevVop_yChan[QCIF_MBS*128*3];
     46 extern uint8                IMEM_pstprcTypCur[6*QCIF_MBS];
     47 extern uint8                IMEM_pstprcTypPrv[6*QCIF_MBS];
     48 
     49 
     50 extern Vop                  IMEM_vopHEADER[2];
     51 extern Vol                  IMEM_VOL[2];
     52 extern Vop                  IMEM_vopHeader[2][1];
     53 extern Vol                  IMEM_vol[2][1];
     54 
     55 #endif
     56 
     57 /* ======================================================================== */
     58 /*  Function : PVInitVideoDecoder()                                         */
     59 /*  Date     : 04/11/2000, 08/29/2000                                       */
     60 /*  Purpose  : Initialization of the MPEG-4 video decoder library.          */
     61 /*             The return type is Bool instead of PV_STATUS because         */
     62 /*             we don't want to expose PV_STATUS to (outside) programmers   */
     63 /*             that use our decoder library SDK.                            */
     64 /*  In/out   :                                                              */
     65 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
     66 /*  Modified :                                                              */
     67 /* ======================================================================== */
     68 OSCL_EXPORT_REF Bool PVInitVideoDecoder(VideoDecControls *decCtrl, uint8 *volbuf[],
     69                                         int32 *volbuf_size, int nLayers, int width, int height, MP4DecodingMode mode)
     70 {
     71     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
     72     Bool status = PV_TRUE;
     73     int idx;
     74     BitstreamDecVideo *stream;
     75 
     76 
     77     oscl_memset(decCtrl, 0, sizeof(VideoDecControls)); /* fix a size bug.   03/28/2001 */
     78     decCtrl->nLayers = nLayers;
     79     for (idx = 0; idx < nLayers; idx++)
     80     {
     81         decCtrl->volbuf[idx] = volbuf[idx];
     82         decCtrl->volbuf_size[idx] = volbuf_size[idx];
     83     }
     84 
     85     /* memory allocation & initialization */
     86 #ifdef DEC_INTERNAL_MEMORY_OPT
     87     video = IMEM_VideoDecData;
     88 #else
     89     video = (VideoDecData *) oscl_malloc(sizeof(VideoDecData));
     90 #endif
     91     if (video != NULL)
     92     {
     93         oscl_memset(video, 0, sizeof(VideoDecData));
     94         video->memoryUsage = sizeof(VideoDecData);
     95         video->numberOfLayers = nLayers;
     96 #ifdef DEC_INTERNAL_MEMORY_OPT
     97         video->vol = (Vol **) IMEM_VOL;
     98 #else
     99         video->vol = (Vol **) oscl_malloc(nLayers * sizeof(Vol *));
    100 #endif
    101         if (video->vol == NULL) status = PV_FALSE;
    102         video->memoryUsage += nLayers * sizeof(Vol *);
    103 
    104 
    105         /* we need to setup this pointer for the application to */
    106         /*    pass it around.                                   */
    107         decCtrl->videoDecoderData = (void *) video;
    108         video->videoDecControls = decCtrl;  /* yes. we have a cyclic */
    109         /* references here :)    */
    110 
    111         /* Allocating Vop space, this has to change when we add */
    112         /*    spatial scalability to the decoder                */
    113 #ifdef DEC_INTERNAL_MEMORY_OPT
    114         video->currVop = IMEM_currVop;
    115         if (video->currVop == NULL) status = PV_FALSE;
    116         else oscl_memset(video->currVop, 0, sizeof(Vop));
    117         video->prevVop = IMEM_prevVop;
    118         if (video->prevVop == NULL) status = PV_FALSE;
    119         else oscl_memset(video->prevVop, 0, sizeof(Vop));
    120         video->memoryUsage += (sizeof(Vop) * 2);
    121         video->vopHeader = (Vop **) IMEM_vopHEADER;
    122 #else
    123 
    124         video->currVop = (Vop *) oscl_malloc(sizeof(Vop));
    125         if (video->currVop == NULL) status = PV_FALSE;
    126         else oscl_memset(video->currVop, 0, sizeof(Vop));
    127         video->prevVop = (Vop *) oscl_malloc(sizeof(Vop));
    128         if (video->prevVop == NULL) status = PV_FALSE;
    129         else oscl_memset(video->prevVop, 0, sizeof(Vop));
    130         video->memoryUsage += (sizeof(Vop) * 2);
    131 
    132         video->vopHeader = (Vop **) oscl_malloc(sizeof(Vop *) * nLayers);
    133 #endif
    134         if (video->vopHeader == NULL) status = PV_FALSE;
    135         else oscl_memset(video->vopHeader, 0, sizeof(Vop *)*nLayers);
    136         video->memoryUsage += (sizeof(Vop *) * nLayers);
    137 
    138         video->initialized = PV_FALSE;
    139         /* Decode the header to get all information to allocate data */
    140         if (status == PV_TRUE)
    141         {
    142             /* initialize decoded frame counter.   04/24/2001 */
    143             video->frame_idx = -1;
    144 
    145 
    146             for (idx = 0; idx < nLayers; idx++)
    147             {
    148 
    149 #ifdef DEC_INTERNAL_MEMORY_OPT
    150                 video->vopHeader[idx] = IMEM_vopHeader[idx];
    151 #else
    152                 video->vopHeader[idx] = (Vop *) oscl_malloc(sizeof(Vop));
    153 #endif
    154                 if (video->vopHeader[idx] == NULL)
    155                 {
    156                     status = PV_FALSE;
    157                     break;
    158                 }
    159                 else
    160                 {
    161                     oscl_memset(video->vopHeader[idx], 0, sizeof(Vop));
    162                     video->vopHeader[idx]->timeStamp = 0;
    163                     video->memoryUsage += (sizeof(Vop));
    164                 }
    165 #ifdef DEC_INTERNAL_MEMORY_OPT
    166                 video->vol[idx] = IMEM_vol[idx];
    167                 video->memoryUsage += sizeof(Vol);
    168                 oscl_memset(video->vol[idx], 0, sizeof(Vol));
    169                 if (video->vol[idx] == NULL) status = PV_FALSE;
    170                 stream = IMEM_BitstreamDecVideo;
    171 #else
    172                 video->vol[idx] = (Vol *) oscl_malloc(sizeof(Vol));
    173                 if (video->vol[idx] == NULL)
    174                 {
    175                     status = PV_FALSE;
    176                     break;
    177                 }
    178                 else
    179                 {
    180                     video->memoryUsage += sizeof(Vol);
    181                     oscl_memset(video->vol[idx], 0, sizeof(Vol));
    182                 }
    183 
    184                 stream = (BitstreamDecVideo *) oscl_malloc(sizeof(BitstreamDecVideo));
    185 #endif
    186                 video->memoryUsage += sizeof(BitstreamDecVideo);
    187                 if (stream == NULL)
    188                 {
    189                     status = PV_FALSE;
    190                     break;
    191                 }
    192                 else
    193                 {
    194                     int32 buffer_size;
    195                     if ((buffer_size = BitstreamOpen(stream, idx)) < 0)
    196                     {
    197                         mp4dec_log("InitVideoDecoder(): Can't allocate bitstream buffer.\n");
    198                         status = PV_FALSE;
    199                         break;
    200                     }
    201                     video->memoryUsage += buffer_size;
    202                     video->vol[idx]->bitstream = stream;
    203                     video->vol[idx]->volID = idx;
    204                     video->vol[idx]->timeInc_offset = 0;  /*  11/12/01 */
    205                     video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader;
    206                     video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader;
    207                     if (mode == MPEG4_MODE)
    208                     {
    209                         /* Set up VOL header bitstream for frame-based decoding.  08/30/2000 */
    210                         BitstreamReset(stream, decCtrl->volbuf[idx], decCtrl->volbuf_size[idx]);
    211 
    212                         switch (DecodeVOLHeader(video, idx))
    213                         {
    214                             case PV_SUCCESS :
    215                                 if (status == PV_TRUE)
    216                                     status = PV_TRUE;   /*  we want to make sure that if first layer is bad, second layer is good return PV_FAIL */
    217                                 else
    218                                     status = PV_FALSE;
    219                                 break;
    220 #ifdef PV_TOLERATE_VOL_ERRORS
    221                             case PV_BAD_VOLHEADER:
    222                                 status = PV_TRUE;
    223                                 break;
    224 #endif
    225                             default :
    226                                 status = PV_FALSE;
    227                                 break;
    228                         }
    229 
    230                     }
    231                     else
    232                     {
    233                         video->shortVideoHeader = PV_TRUE;
    234                     }
    235 
    236                     if (video->shortVideoHeader == PV_TRUE)
    237                     {
    238                         mode = H263_MODE;
    239                         /* Set max width and height.  In H.263 mode, we use    */
    240                         /*  volbuf_size[0] to pass in width and volbuf_size[1] */
    241                         /*  to pass in height.                    04/23/2001 */
    242                         video->prevVop->temporalRef = 0; /*  11/12/01 */
    243                         /* Compute some convenience variables:   04/23/2001 */
    244                         video->vol[idx]->quantType = 0;
    245                         video->vol[idx]->quantPrecision = 5;
    246                         video->vol[idx]->errorResDisable = 1;
    247                         video->vol[idx]->dataPartitioning = 0;
    248                         video->vol[idx]->useReverseVLC = 0;
    249                         video->intra_acdcPredDisable = 1;
    250                         video->vol[idx]->scalability = 0;
    251                         video->size = (int32)width * height;
    252 
    253                         video->displayWidth = video->width = width;
    254                         video->displayHeight = video->height = height;
    255 #ifdef PV_ANNEX_IJKT_SUPPORT
    256                         video->modified_quant = 0;
    257                         video->advanced_INTRA = 0;
    258                         video->deblocking = 0;
    259                         video->slice_structure = 0;
    260 #endif
    261                     }
    262 
    263                 }
    264             }
    265 
    266         }
    267         if (status != PV_FALSE)
    268         {
    269             status = PVAllocVideoData(decCtrl, width, height, nLayers);
    270             video->initialized = PV_TRUE;
    271         }
    272     }
    273     else
    274     {
    275         status = PV_FALSE;
    276     }
    277 
    278     if (status == PV_FALSE) PVCleanUpVideoDecoder(decCtrl);
    279 
    280     return status;
    281 }
    282 
    283 Bool PVAllocVideoData(VideoDecControls *decCtrl, int width, int height, int nLayers)
    284 {
    285     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
    286     Bool status = PV_TRUE;
    287     int nTotalMB;
    288     int nMBPerRow;
    289     int32 size;
    290 
    291     if (video->shortVideoHeader == PV_TRUE)
    292     {
    293         video->displayWidth = video->width = width;
    294         video->displayHeight = video->height = height;
    295 
    296         video->nMBPerRow =
    297             video->nMBinGOB  = video->width / MB_SIZE;
    298         video->nMBPerCol =
    299             video->nGOBinVop = video->height / MB_SIZE;
    300         video->nTotalMB =
    301             video->nMBPerRow * video->nMBPerCol;
    302     }
    303 
    304     size = (int32)sizeof(PIXEL) * video->width * video->height;
    305 #ifdef PV_MEMORY_POOL
    306     decCtrl->size = size;
    307 #else
    308 #ifdef DEC_INTERNAL_MEMORY_OPT
    309     video->currVop->yChan = IMEM_currVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
    310     if (video->currVop->yChan == NULL) status = PV_FALSE;
    311     video->currVop->uChan = video->currVop->yChan + size;
    312     video->currVop->vChan = video->currVop->uChan + (size >> 2);
    313 
    314     video->prevVop->yChan = IMEM_prevVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
    315     if (video->prevVop->yChan == NULL) status = PV_FALSE;
    316     video->prevVop->uChan = video->prevVop->yChan + size;
    317     video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
    318 #else
    319     video->currVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
    320     if (video->currVop->yChan == NULL) status = PV_FALSE;
    321 
    322     video->currVop->uChan = video->currVop->yChan + size;
    323     video->currVop->vChan = video->currVop->uChan + (size >> 2);
    324     video->prevVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
    325     if (video->prevVop->yChan == NULL) status = PV_FALSE;
    326 
    327     video->prevVop->uChan = video->prevVop->yChan + size;
    328     video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
    329 #endif
    330     video->memoryUsage += (size * 3);
    331 #endif   // MEMORY_POOL
    332     /* Note that baseVop, enhcVop is only used to hold enhancement */
    333     /*    layer header information.                  05/04/2000  */
    334     if (nLayers > 1)
    335     {
    336         video->prevEnhcVop = (Vop *) oscl_malloc(sizeof(Vop));
    337         video->memoryUsage += (sizeof(Vop));
    338         if (video->prevEnhcVop == NULL)
    339         {
    340             status = PV_FALSE;
    341         }
    342         else
    343         {
    344             oscl_memset(video->prevEnhcVop, 0, sizeof(Vop));
    345 #ifndef PV_MEMORY_POOL
    346             video->prevEnhcVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
    347             if (video->prevEnhcVop->yChan == NULL) status = PV_FALSE;
    348             video->prevEnhcVop->uChan = video->prevEnhcVop->yChan + size;
    349             video->prevEnhcVop->vChan = video->prevEnhcVop->uChan + (size >> 2);
    350             video->memoryUsage += (3 * size / 2);
    351 #endif
    352         }
    353     }
    354 
    355     /* Allocating space for slices, AC prediction flag, and */
    356     /*    AC/DC prediction storage */
    357     nTotalMB = video->nTotalMB;
    358     nMBPerRow = video->nMBPerRow;
    359 
    360 #ifdef DEC_INTERNAL_MEMORY_OPT
    361     video->sliceNo = (uint8 *)(IMEM_sliceNo);
    362     if (video->sliceNo == NULL) status = PV_FALSE;
    363     video->memoryUsage += nTotalMB;
    364     video->acPredFlag = (uint8 *)(IMEM_acPredFlag);
    365     if (video->acPredFlag == NULL) status = PV_FALSE;
    366     video->memoryUsage += (nTotalMB);
    367     video->predDC = (typeDCStore *)(IMEM_predDC);
    368     if (video->predDC == NULL) status = PV_FALSE;
    369     video->memoryUsage += (nTotalMB * sizeof(typeDCStore));
    370     video->predDCAC_col = (typeDCACStore *)(IMEM_predDCAC_col);
    371     if (video->predDCAC_col == NULL) status = PV_FALSE;
    372     video->memoryUsage += ((nMBPerRow + 1) * sizeof(typeDCACStore));
    373     video->predDCAC_row = video->predDCAC_col + 1;
    374     video->headerInfo.Mode = (uint8 *)(IMEM_headerInfo_Mode);
    375     if (video->headerInfo.Mode == NULL) status = PV_FALSE;
    376     video->memoryUsage += nTotalMB;
    377     video->headerInfo.CBP = (uint8 *)(IMEM_headerInfo_CBP);
    378     if (video->headerInfo.CBP == NULL) status = PV_FALSE;
    379     video->memoryUsage += nTotalMB;
    380     video->QPMB = (int *)(IMEM_headerInfo_QPMB);
    381     if (video->QPMB == NULL) status = PV_FALSE;
    382     video->memoryUsage += (nTotalMB * sizeof(int));
    383     video->mblock = &IMEM_mblock;
    384     if (video->mblock == NULL) status = PV_FALSE;
    385     oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); //  Aug 23,2005
    386 
    387     video->memoryUsage += sizeof(MacroBlock);
    388     video->motX = (MOT *)(IMEM_motX);
    389     if (video->motX == NULL) status = PV_FALSE;
    390     video->motY = (MOT *)(IMEM_motY);
    391     if (video->motY == NULL) status = PV_FALSE;
    392     video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
    393 #else
    394     video->sliceNo = (uint8 *) oscl_malloc(nTotalMB);
    395     if (video->sliceNo == NULL) status = PV_FALSE;
    396     video->memoryUsage += nTotalMB;
    397 
    398     video->acPredFlag = (uint8 *) oscl_malloc(nTotalMB * sizeof(uint8));
    399     if (video->acPredFlag == NULL) status = PV_FALSE;
    400     video->memoryUsage += (nTotalMB);
    401 
    402     video->predDC = (typeDCStore *) oscl_malloc(nTotalMB * sizeof(typeDCStore));
    403     if (video->predDC == NULL) status = PV_FALSE;
    404     video->memoryUsage += (nTotalMB * sizeof(typeDCStore));
    405 
    406     video->predDCAC_col = (typeDCACStore *) oscl_malloc((nMBPerRow + 1) * sizeof(typeDCACStore));
    407     if (video->predDCAC_col == NULL) status = PV_FALSE;
    408     video->memoryUsage += ((nMBPerRow + 1) * sizeof(typeDCACStore));
    409 
    410     /* element zero will be used for storing vertical (col) AC coefficients */
    411     /*  the rest will be used for storing horizontal (row) AC coefficients  */
    412     video->predDCAC_row = video->predDCAC_col + 1;        /*  ACDC */
    413 
    414     /* Allocating HeaderInfo structure & Quantizer array */
    415     video->headerInfo.Mode = (uint8 *) oscl_malloc(nTotalMB);
    416     if (video->headerInfo.Mode == NULL) status = PV_FALSE;
    417     video->memoryUsage += nTotalMB;
    418     video->headerInfo.CBP = (uint8 *) oscl_malloc(nTotalMB);
    419     if (video->headerInfo.CBP == NULL) status = PV_FALSE;
    420     video->memoryUsage += nTotalMB;
    421     video->QPMB = (int16 *) oscl_malloc(nTotalMB * sizeof(int16));
    422     if (video->QPMB == NULL) status = PV_FALSE;
    423     video->memoryUsage += (nTotalMB * sizeof(int));
    424 
    425     /* Allocating macroblock space */
    426     video->mblock = (MacroBlock *) oscl_malloc(sizeof(MacroBlock));
    427     if (video->mblock == NULL)
    428     {
    429         status = PV_FALSE;
    430     }
    431     else
    432     {
    433         oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); //  Aug 23,2005
    434 
    435         video->memoryUsage += sizeof(MacroBlock);
    436     }
    437     /* Allocating motion vector space */
    438     video->motX = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
    439     if (video->motX == NULL) status = PV_FALSE;
    440     video->motY = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
    441     if (video->motY == NULL) status = PV_FALSE;
    442     video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
    443 #endif
    444 
    445 #ifdef PV_POSTPROC_ON
    446     /* Allocating space for post-processing Mode */
    447 #ifdef DEC_INTERNAL_MEMORY_OPT
    448     video->pstprcTypCur = IMEM_pstprcTypCur;
    449     video->memoryUsage += (nTotalMB * 6);
    450     if (video->pstprcTypCur == NULL)
    451     {
    452         status = PV_FALSE;
    453     }
    454     else
    455     {
    456         oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
    457     }
    458 
    459     video->pstprcTypPrv = IMEM_pstprcTypPrv;
    460     video->memoryUsage += (nTotalMB * 6);
    461     if (video->pstprcTypPrv == NULL)
    462     {
    463         status = PV_FALSE;
    464     }
    465     else
    466     {
    467         oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
    468     }
    469 
    470 #else
    471     video->pstprcTypCur = (uint8 *) oscl_malloc(nTotalMB * 6);
    472     video->memoryUsage += (nTotalMB * 6);
    473     if (video->pstprcTypCur == NULL)
    474     {
    475         status = PV_FALSE;
    476     }
    477     else
    478     {
    479         oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
    480     }
    481 
    482     video->pstprcTypPrv = (uint8 *) oscl_malloc(nTotalMB * 6);
    483     video->memoryUsage += (nTotalMB * 6);
    484     if (video->pstprcTypPrv == NULL)
    485     {
    486         status = PV_FALSE;
    487     }
    488     else
    489     {
    490         oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
    491     }
    492 
    493 #endif
    494 
    495 #endif
    496 
    497     /* initialize the decoder library */
    498     video->prevVop->predictionType = I_VOP;
    499     video->prevVop->timeStamp = 0;
    500 #ifndef PV_MEMORY_POOL
    501     oscl_memset(video->prevVop->yChan, 16, sizeof(uint8)*size);     /*  10/31/01 */
    502     oscl_memset(video->prevVop->uChan, 128, sizeof(uint8)*size / 2);
    503 
    504     oscl_memset(video->currVop->yChan, 0, sizeof(uint8)*size*3 / 2);
    505     if (nLayers > 1)
    506     {
    507         oscl_memset(video->prevEnhcVop->yChan, 0, sizeof(uint8)*size*3 / 2);
    508         video->prevEnhcVop->timeStamp = 0;
    509     }
    510     video->concealFrame = video->prevVop->yChan;               /*  07/07/2001 */
    511     decCtrl->outputFrame = video->prevVop->yChan;              /*  06/19/2002 */
    512 #endif
    513 
    514     /* always start from base layer */
    515     video->currLayer = 0;
    516     return status;
    517 }
    518 
    519 /* ======================================================================== */
    520 /*  Function : PVResetVideoDecoder()                                        */
    521 /*  Date     : 01/14/2002                                                   */
    522 /*  Purpose  : Reset video timestamps                                       */
    523 /*  In/out   :                                                              */
    524 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
    525 /*  Modified :                                                              */
    526 /* ======================================================================== */
    527 Bool PVResetVideoDecoder(VideoDecControls *decCtrl)
    528 {
    529     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
    530     int idx;
    531 
    532     for (idx = 0; idx < decCtrl->nLayers; idx++)
    533     {
    534         video->vopHeader[idx]->timeStamp = 0;
    535     }
    536     video->prevVop->timeStamp = 0;
    537     if (decCtrl->nLayers > 1)
    538         video->prevEnhcVop->timeStamp = 0;
    539 
    540     oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); //  Aug 23,2005
    541 
    542     return PV_TRUE;
    543 }
    544 
    545 
    546 /* ======================================================================== */
    547 /*  Function : PVCleanUpVideoDecoder()                                      */
    548 /*  Date     : 04/11/2000, 08/29/2000                                       */
    549 /*  Purpose  : Cleanup of the MPEG-4 video decoder library.                 */
    550 /*  In/out   :                                                              */
    551 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
    552 /*  Modified :                                                              */
    553 /* ======================================================================== */
    554 OSCL_EXPORT_REF Bool PVCleanUpVideoDecoder(VideoDecControls *decCtrl)
    555 {
    556     int idx;
    557     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
    558 #ifdef DEC_INTERNAL_MEMORY_OPT
    559     if (video)
    560     {
    561 #ifdef PV_POSTPROC_ON
    562         video->pstprcTypCur = NULL;
    563         video->pstprcTypPrv = NULL;
    564 #endif
    565 
    566         video->acPredFlag       = NULL;
    567         video->sliceNo          = NULL;
    568         video->motX             = NULL;
    569         video->motY             = NULL;
    570         video->mblock           = NULL;
    571         video->QPMB             = NULL;
    572         video->predDC           = NULL;
    573         video->predDCAC_row     = NULL;
    574         video->predDCAC_col     = NULL;
    575         video->headerInfo.Mode  = NULL;
    576         video->headerInfo.CBP   = NULL;
    577         if (video->numberOfLayers > 1)
    578         {
    579             if (video->prevEnhcVop)
    580             {
    581                 video->prevEnhcVop->uChan = NULL;
    582                 video->prevEnhcVop->vChan = NULL;
    583                 if (video->prevEnhcVop->yChan) oscl_free(video->prevEnhcVop->yChan);
    584                 oscl_free(video->prevEnhcVop);
    585             }
    586         }
    587         if (video->currVop)
    588         {
    589             video->currVop->uChan = NULL;
    590             video->currVop->vChan = NULL;
    591             if (video->currVop->yChan)
    592                 video->currVop->yChan = NULL;
    593             video->currVop = NULL;
    594         }
    595         if (video->prevVop)
    596         {
    597             video->prevVop->uChan = NULL;
    598             video->prevVop->vChan = NULL;
    599             if (video->prevVop->yChan)
    600                 video->prevVop->yChan = NULL;
    601             video->prevVop = NULL;
    602         }
    603 
    604         if (video->vol)
    605         {
    606             for (idx = 0; idx < video->numberOfLayers; idx++)
    607             {
    608                 if (video->vol[idx])
    609                 {
    610                     BitstreamClose(video->vol[idx]->bitstream);
    611                     video->vol[idx]->bitstream = NULL;
    612                     video->vol[idx] = NULL;
    613                 }
    614                 video->vopHeader[idx] = NULL;
    615 
    616             }
    617             video->vol = NULL;
    618             video->vopHeader = NULL;
    619         }
    620 
    621         video = NULL;
    622         decCtrl->videoDecoderData = NULL;
    623     }
    624 
    625 #else
    626 
    627     if (video)
    628     {
    629 #ifdef PV_POSTPROC_ON
    630         if (video->pstprcTypCur) oscl_free(video->pstprcTypCur);
    631         if (video->pstprcTypPrv) oscl_free(video->pstprcTypPrv);
    632 #endif
    633         if (video->predDC) oscl_free(video->predDC);
    634         video->predDCAC_row = NULL;
    635         if (video->predDCAC_col) oscl_free(video->predDCAC_col);
    636         if (video->motX) oscl_free(video->motX);
    637         if (video->motY) oscl_free(video->motY);
    638         if (video->mblock) oscl_free(video->mblock);
    639         if (video->QPMB) oscl_free(video->QPMB);
    640         if (video->headerInfo.Mode) oscl_free(video->headerInfo.Mode);
    641         if (video->headerInfo.CBP) oscl_free(video->headerInfo.CBP);
    642         if (video->sliceNo) oscl_free(video->sliceNo);
    643         if (video->acPredFlag) oscl_free(video->acPredFlag);
    644 
    645         if (video->numberOfLayers > 1)
    646         {
    647             if (video->prevEnhcVop)
    648             {
    649                 video->prevEnhcVop->uChan = NULL;
    650                 video->prevEnhcVop->vChan = NULL;
    651                 if (video->prevEnhcVop->yChan) oscl_free(video->prevEnhcVop->yChan);
    652                 oscl_free(video->prevEnhcVop);
    653             }
    654         }
    655         if (video->currVop)
    656         {
    657 
    658 #ifndef PV_MEMORY_POOL
    659             video->currVop->uChan = NULL;
    660             video->currVop->vChan = NULL;
    661             if (video->currVop->yChan)
    662                 oscl_free(video->currVop->yChan);
    663 #endif
    664             oscl_free(video->currVop);
    665         }
    666         if (video->prevVop)
    667         {
    668 #ifndef PV_MEMORY_POOL
    669             video->prevVop->uChan = NULL;
    670             video->prevVop->vChan = NULL;
    671             if (video->prevVop->yChan)
    672                 oscl_free(video->prevVop->yChan);
    673 #endif
    674             oscl_free(video->prevVop);
    675         }
    676 
    677         if (video->vol)
    678         {
    679             for (idx = 0; idx < video->numberOfLayers; idx++)
    680             {
    681                 if (video->vol[idx])
    682                 {
    683                     if (video->vol[idx]->bitstream)
    684                     {
    685                         BitstreamClose(video->vol[idx]->bitstream);
    686                         oscl_free(video->vol[idx]->bitstream);
    687                     }
    688                     oscl_free(video->vol[idx]);
    689                 }
    690 
    691             }
    692             oscl_free(video->vol);
    693         }
    694 
    695         for (idx = 0; idx < video->numberOfLayers; idx++)
    696         {
    697             if (video->vopHeader[idx]) oscl_free(video->vopHeader[idx]);
    698         }
    699 
    700         if (video->vopHeader) oscl_free(video->vopHeader);
    701 
    702         oscl_free(video);
    703         decCtrl->videoDecoderData = NULL;
    704     }
    705 #endif
    706     return PV_TRUE;
    707 }
    708 /* ======================================================================== */
    709 /*  Function : PVGetVideoDimensions()                                       */
    710 /*  Date     : 040505                                                       */
    711 /*  Purpose  :                                                              */
    712 /*  In/out   :                                                              */
    713 /*  Return   : the display_width and display_height of                      */
    714 /*          the frame in the current layer.                                 */
    715 /*  Note     : This is not a macro or inline function because we do         */
    716 /*              not want to expose our internal data structure.             */
    717 /*  Modified :                                                              */
    718 /* ======================================================================== */
    719 OSCL_EXPORT_REF void PVGetVideoDimensions(VideoDecControls *decCtrl, int32 *display_width, int32 *display_height)
    720 {
    721     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    722     *display_width = video->displayWidth;
    723     *display_height = video->displayHeight;
    724 }
    725 
    726 /* ======================================================================== */
    727 /*  Function : PVGetVideoTimeStamp()                                        */
    728 /*  Date     : 04/27/2000, 08/29/2000                                       */
    729 /*  Purpose  :                                                              */
    730 /*  In/out   :                                                              */
    731 /*  Return   : current time stamp in millisecond.                           */
    732 /*  Note     :                                                              */
    733 /*  Modified :                                                              */
    734 /* ======================================================================== */
    735 uint32 PVGetVideoTimeStamp(VideoDecControls *decCtrl)
    736 {
    737     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    738     return video->currTimestamp;
    739 }
    740 
    741 
    742 /* ======================================================================== */
    743 /*  Function : PVSetPostProcType()                                          */
    744 /*  Date     : 07/07/2000                                                   */
    745 /*  Purpose  :                                                              */
    746 /*  In/out   :                                                              */
    747 /*  Return   : Set post-processing filter type.                             */
    748 /*  Note     :                                                              */
    749 /*  Modified : . 08/29/2000 changes the name for consistency.               */
    750 /* ======================================================================== */
    751 OSCL_EXPORT_REF void PVSetPostProcType(VideoDecControls *decCtrl, int mode)
    752 {
    753     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    754     video->postFilterType = mode;
    755 }
    756 
    757 
    758 /* ======================================================================== */
    759 /*  Function : PVGetDecBitrate()                                            */
    760 /*  Date     : 08/23/2000                                                   */
    761 /*  Purpose  :                                                              */
    762 /*  In/out   :                                                              */
    763 /*  Return   : This function returns the average bits per second.           */
    764 /*  Note     :                                                              */
    765 /*  Modified :                                                              */
    766 /* ======================================================================== */
    767 int PVGetDecBitrate(VideoDecControls *decCtrl)
    768 {
    769     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    770     int     idx;
    771     int32   sum = 0;
    772 
    773     for (idx = 0; idx < BITRATE_AVERAGE_WINDOW; idx++)
    774     {
    775         sum += video->nBitsPerVop[idx];
    776     }
    777     sum = (sum * video->frameRate) / (10 * BITRATE_AVERAGE_WINDOW);
    778     return (int) sum;
    779 }
    780 
    781 
    782 /* ======================================================================== */
    783 /*  Function : PVGetDecFramerate()                                          */
    784 /*  Date     : 08/23/2000                                                   */
    785 /*  Purpose  :                                                              */
    786 /*  In/out   :                                                              */
    787 /*  Return   : This function returns the average frame per 10 second.       */
    788 /*  Note     : The fps can be calculated by PVGetDecFramerate()/10          */
    789 /*  Modified :                                                              */
    790 /* ======================================================================== */
    791 int PVGetDecFramerate(VideoDecControls *decCtrl)
    792 {
    793     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    794 
    795     return video->frameRate;
    796 }
    797 
    798 /* ======================================================================== */
    799 /*  Function : PVGetOutputFrame()                                           */
    800 /*  Date     : 05/07/2001                                                   */
    801 /*  Purpose  :                                                              */
    802 /*  In/out   :                                                              */
    803 /*  Return   : This function returns the pointer to the output frame        */
    804 /*  Note     :                                                              */
    805 /*  Modified :                                                              */
    806 /* ======================================================================== */
    807 uint8 *PVGetDecOutputFrame(VideoDecControls *decCtrl)
    808 {
    809     return decCtrl->outputFrame;
    810 }
    811 
    812 /* ======================================================================== */
    813 /*  Function : PVGetLayerID()                                               */
    814 /*  Date     : 07/09/2001                                                   */
    815 /*  Purpose  :                                                              */
    816 /*  In/out   :                                                              */
    817 /*  Return   : This function returns decoded frame layer id (BASE/ENHANCE)  */
    818 /*  Note     :                                                              */
    819 /*  Modified :                                                              */
    820 /* ======================================================================== */
    821 int PVGetLayerID(VideoDecControls *decCtrl)
    822 {
    823     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    824     return video->currLayer;
    825 }
    826 /* ======================================================================== */
    827 /*  Function : PVGetDecMemoryUsage()                                        */
    828 /*  Date     : 08/23/2000                                                   */
    829 /*  Purpose  :                                                              */
    830 /*  In/out   :                                                              */
    831 /*  Return   : This function returns the amount of memory used.             */
    832 /*  Note     :                                                              */
    833 /*  Modified :                                                              */
    834 /* ======================================================================== */
    835 int32 PVGetDecMemoryUsage(VideoDecControls *decCtrl)
    836 {
    837     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    838     return video->memoryUsage;
    839 }
    840 
    841 
    842 /* ======================================================================== */
    843 /*  Function : PVGetDecBitstreamMode()                                      */
    844 /*  Date     : 08/23/2000                                                   */
    845 /*  Purpose  :                                                              */
    846 /*  In/out   :                                                              */
    847 /*  Return   : This function returns the decoding mode of the baselayer     */
    848 /*              bitstream.                                                  */
    849 /*  Note     :                                                              */
    850 /*  Modified :                                                              */
    851 /* ======================================================================== */
    852 OSCL_EXPORT_REF MP4DecodingMode PVGetDecBitstreamMode(VideoDecControls *decCtrl)
    853 {
    854     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
    855     if (video->shortVideoHeader)
    856     {
    857         return H263_MODE;
    858     }
    859     else
    860     {
    861         return MPEG4_MODE;
    862     }
    863 }
    864 
    865 
    866 /* ======================================================================== */
    867 /*  Function : PVExtractVolHeader()                                         */
    868 /*  Date     : 08/29/2000                                                   */
    869 /*  Purpose  :                                                              */
    870 /*  In/out   :                                                              */
    871 /*  Return   : Extract vol header of the bitstream from buffer[].           */
    872 /*  Note     :                                                              */
    873 /*  Modified :                                                              */
    874 /* ======================================================================== */
    875 Bool PVExtractVolHeader(uint8 *video_buffer, uint8 *vol_header, int32 *vol_header_size)
    876 {
    877     int idx = -1;
    878     uint8 start_code_prefix[] = { 0x00, 0x00, 0x01 };
    879     uint8 h263_prefix[] = { 0x00, 0x00, 0x80 };
    880 
    881     if (oscl_memcmp(h263_prefix, video_buffer, 3) == 0) /* we have short header stream */
    882     {
    883         oscl_memcpy(vol_header, video_buffer, 32);
    884         *vol_header_size = 32;
    885         return TRUE;
    886     }
    887     else
    888     {
    889         if (oscl_memcmp(start_code_prefix, video_buffer, 3) ||
    890                 (video_buffer[3] != 0xb0 && video_buffer[3] >= 0x20)) return FALSE;
    891 
    892         do
    893         {
    894             idx++;
    895             while (oscl_memcmp(start_code_prefix, video_buffer + idx, 3))
    896             {
    897                 idx++;
    898                 if (idx + 3 >= *vol_header_size) goto quit;
    899             }
    900         }
    901         while (video_buffer[idx+3] != 0xb3 && video_buffer[idx+3] != 0xb6);
    902 
    903         oscl_memcpy(vol_header, video_buffer, idx);
    904         *vol_header_size = idx;
    905         return TRUE;
    906     }
    907 
    908 quit:
    909     oscl_memcpy(vol_header, video_buffer, *vol_header_size);
    910     return FALSE;
    911 }
    912 
    913 
    914 /* ======================================================================== */
    915 /*  Function : PVLocateFrameHeader()                                        */
    916 /*  Date     : 04/8/2005                                                    */
    917 /*  Purpose  :                                                              */
    918 /*  In/out   :                                                              */
    919 /*  Return   : Return the offset to the first SC in the buffer              */
    920 /*  Note     :                                                              */
    921 /*  Modified :                                                              */
    922 /* ======================================================================== */
    923 int32 PVLocateFrameHeader(uint8 *ptr, int32 size)
    924 {
    925     int count = 0;
    926     int32 i = size;
    927 
    928     if (size < 1)
    929     {
    930         return 0;
    931     }
    932     while (i--)
    933     {
    934         if ((count > 1) && (*ptr == 0x01))
    935         {
    936             i += 2;
    937             break;
    938         }
    939 
    940         if (*ptr++)
    941             count = 0;
    942         else
    943             count++;
    944     }
    945     return (size - (i + 1));
    946 }
    947 
    948 
    949 /* ======================================================================== */
    950 /*  Function : PVLocateH263FrameHeader()                                    */
    951 /*  Date     : 04/8/2005                                                    */
    952 /*  Purpose  :                                                              */
    953 /*  In/out   :                                                              */
    954 /*  Return   : Return the offset to the first SC in the buffer              */
    955 /*  Note     :                                                              */
    956 /*  Modified :                                                              */
    957 /* ======================================================================== */
    958 int32 PVLocateH263FrameHeader(uint8 *ptr, int32 size)
    959 {
    960     int count = 0;
    961     int32 i = size;
    962 
    963     if (size < 1)
    964     {
    965         return 0;
    966     }
    967 
    968     while (i--)
    969     {
    970         if ((count > 1) && ((*ptr & 0xFC) == 0x80))
    971         {
    972             i += 2;
    973             break;
    974         }
    975 
    976         if (*ptr++)
    977             count = 0;
    978         else
    979             count++;
    980     }
    981     return (size - (i + 1));
    982 }
    983 
    984 
    985 /* ======================================================================== */
    986 /*  Function : PVDecodeVideoFrame()                                         */
    987 /*  Date     : 08/29/2000                                                   */
    988 /*  Purpose  : Decode one video frame and return a YUV-12 image.            */
    989 /*  In/out   :                                                              */
    990 /*  Return   :                                                              */
    991 /*  Note     :                                                              */
    992 /*  Modified : 04/17/2001 removed PV_EOS, PV_END_OF_BUFFER              */
    993 /*           : 08/22/2002 break up into 2 functions PVDecodeVopHeader and */
    994 /*                          PVDecodeVopBody                                 */
    995 /* ======================================================================== */
    996 OSCL_EXPORT_REF Bool PVDecodeVideoFrame(VideoDecControls *decCtrl, uint8 *buffer[],
    997                                         uint32 timestamp[], int32 buffer_size[], uint use_ext_timestamp[], uint8 *currYUV)
    998 {
    999     PV_STATUS status = PV_FAIL;
   1000     VopHeaderInfo header_info;
   1001 
   1002     status = (PV_STATUS)PVDecodeVopHeader(decCtrl, buffer, timestamp, buffer_size, &header_info, use_ext_timestamp, currYUV);
   1003     if (status != PV_TRUE)
   1004         return PV_FALSE;
   1005 
   1006     if (PVDecodeVopBody(decCtrl, buffer_size) != PV_TRUE)
   1007     {
   1008         return PV_FALSE;
   1009     }
   1010 
   1011     return PV_TRUE;
   1012 }
   1013 
   1014 /* ======================================================================== */
   1015 /*  Function : PVDecodeVopHeader()                                          */
   1016 /*  Date     : 08/22/2002                                                   */
   1017 /*  Purpose  : Determine target layer and decode vop header, modified from  */
   1018 /*              original PVDecodeVideoFrame.                                */
   1019 /*  In/out   :                                                              */
   1020 /*  Return   :                                                              */
   1021 /*  Note     :                                                              */
   1022 /*  Modified :                                                              */
   1023 /* ======================================================================== */
   1024 Bool PVDecodeVopHeader(VideoDecControls *decCtrl, uint8 *buffer[],
   1025                        uint32 timestamp[], int32 buffer_size[], VopHeaderInfo *header_info, uint use_ext_timestamp [], uint8 *currYUV)
   1026 {
   1027     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
   1028     Vol *currVol;
   1029     Vop *currVop = video->currVop;
   1030     Vop **vopHeader = video->vopHeader;
   1031     BitstreamDecVideo *stream;
   1032 
   1033     int target_layer;
   1034 
   1035 #ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
   1036     PV_STATUS status = PV_FAIL;
   1037     int idx;
   1038     int32 display_time;
   1039 
   1040     /* decide which frame to decode next */
   1041     if (decCtrl->nLayers > 1)
   1042     {
   1043         display_time = target_layer = -1;
   1044         for (idx = 0; idx < decCtrl->nLayers; idx++)
   1045         {
   1046             /* do we have data for this layer? */
   1047             if (buffer_size[idx] <= 0)
   1048             {
   1049                 timestamp[idx] = -1;
   1050                 continue;
   1051             }
   1052 
   1053             /* did the application provide a timestamp for this vop? */
   1054             if (timestamp[idx] < 0)
   1055             {
   1056                 if (vopHeader[idx]->timeStamp < 0)
   1057                 {
   1058                     /* decode the timestamp in the bitstream */
   1059                     video->currLayer = idx;
   1060                     stream = video->vol[idx]->bitstream;
   1061                     BitstreamReset(stream, buffer[idx], buffer_size[idx]);
   1062 
   1063                     while ((status = DecodeVOPHeader(video, vopHeader[idx], FALSE)) != PV_SUCCESS)
   1064                     {
   1065                         /* Try to find a VOP header in the buffer.   08/30/2000. */
   1066                         if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
   1067                         {
   1068                             /* if we don't have data for enhancement layer, */
   1069                             /*    don't just stop.   09/07/2000.          */
   1070                             buffer_size[idx] = 0;
   1071                             break;
   1072                         }
   1073                     }
   1074                     if (status == PV_SUCCESS)
   1075                     {
   1076                         vopHeader[idx]->timeStamp =
   1077                             timestamp[idx] = CalcVopDisplayTime(video->vol[idx], vopHeader[idx], video->shortVideoHeader);
   1078                         if (idx == 0) vopHeader[idx]->refSelectCode = 1;
   1079                     }
   1080                 }
   1081                 else
   1082                 {
   1083                     /* We've decoded this vop header in the previous run already. */
   1084                     timestamp[idx] = vopHeader[idx]->timeStamp;
   1085                 }
   1086             }
   1087 
   1088             /* Use timestamps to select the next VOP to be decoded */
   1089             if (timestamp[idx] >= 0 && (display_time < 0 || display_time > timestamp[idx]))
   1090             {
   1091                 display_time = timestamp[idx];
   1092                 target_layer = idx;
   1093             }
   1094             else if (display_time == timestamp[idx])
   1095             {
   1096                 /* we have to handle either SNR or spatial scalability here. */
   1097             }
   1098         }
   1099         if (target_layer < 0) return PV_FALSE;
   1100 
   1101         /* set up for decoding the target layer */
   1102         video->currLayer = target_layer;
   1103         currVol = video->vol[target_layer];
   1104         video->bitstream = stream = currVol->bitstream;
   1105 
   1106         /* We need to decode the vop header if external timestamp   */
   1107         /*    is provided.    10/04/2000                            */
   1108         if (vopHeader[target_layer]->timeStamp < 0)
   1109         {
   1110             stream = video->vol[target_layer]->bitstream;
   1111             BitstreamReset(stream, buffer[target_layer], buffer_size[target_layer]);
   1112 
   1113             while (DecodeVOPHeader(video, vopHeader[target_layer], TRUE) != PV_SUCCESS)
   1114             {
   1115                 /* Try to find a VOP header in the buffer.   08/30/2000. */
   1116                 if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
   1117                 {
   1118                     /* if we don't have data for enhancement layer, */
   1119                     /*    don't just stop.   09/07/2000.          */
   1120                     buffer_size[target_layer] = 0;
   1121                     break;
   1122                 }
   1123             }
   1124             video->vol[target_layer]->timeInc_offset = vopHeader[target_layer]->timeInc;
   1125             video->vol[target_layer]->moduloTimeBase = timestamp[target_layer];
   1126             vopHeader[target_layer]->timeStamp = timestamp[target_layer];
   1127             if (target_layer == 0) vopHeader[target_layer]->refSelectCode = 1;
   1128         }
   1129     }
   1130     else /* base layer only decoding */
   1131     {
   1132 #endif
   1133         video->currLayer = target_layer = 0;
   1134         currVol = video->vol[0];
   1135         video->bitstream = stream = currVol->bitstream;
   1136         if (buffer_size[0] <= 0) return PV_FALSE;
   1137         BitstreamReset(stream, buffer[0], buffer_size[0]);
   1138 
   1139         if (video->shortVideoHeader)
   1140         {
   1141             while (DecodeShortHeader(video, vopHeader[0]) != PV_SUCCESS)
   1142             {
   1143                 if (PVSearchNextH263Frame(stream) != PV_SUCCESS)
   1144                 {
   1145                     /* There is no vop header in the buffer,    */
   1146                     /*   clean bitstream buffer.     2/5/2001   */
   1147                     buffer_size[0] = 0;
   1148                     if (video->initialized == PV_FALSE)
   1149                     {
   1150                         video->displayWidth = video->width = 0;
   1151                         video->displayHeight = video->height = 0;
   1152                     }
   1153                     return PV_FALSE;
   1154                 }
   1155             }
   1156 
   1157             if (use_ext_timestamp[0])
   1158             {
   1159                 /* MTB for H263 is absolute TR */
   1160                 /* following line is equivalent to  round((timestamp[0]*30)/1001);   11/13/2001 */
   1161                 video->vol[0]->moduloTimeBase = 30 * ((timestamp[0] + 17) / 1001) + (30 * ((timestamp[0] + 17) % 1001) / 1001);
   1162                 vopHeader[0]->timeStamp = timestamp[0];
   1163             }
   1164             else
   1165                 vopHeader[0]->timeStamp = CalcVopDisplayTime(currVol, vopHeader[0], video->shortVideoHeader);
   1166         }
   1167         else
   1168         {
   1169             while (DecodeVOPHeader(video, vopHeader[0], FALSE) != PV_SUCCESS)
   1170             {
   1171                 /* Try to find a VOP header in the buffer.   08/30/2000. */
   1172                 if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
   1173                 {
   1174                     /* There is no vop header in the buffer,    */
   1175                     /*   clean bitstream buffer.     2/5/2001   */
   1176                     buffer_size[0] = 0;
   1177                     return PV_FALSE;
   1178                 }
   1179             }
   1180 
   1181             if (use_ext_timestamp[0])
   1182             {
   1183                 video->vol[0]->timeInc_offset = vopHeader[0]->timeInc;
   1184                 video->vol[0]->moduloTimeBase = timestamp[0];  /*  11/12/2001 */
   1185                 vopHeader[0]->timeStamp = timestamp[0];
   1186             }
   1187             else
   1188             {
   1189                 vopHeader[0]->timeStamp = CalcVopDisplayTime(currVol, vopHeader[0], video->shortVideoHeader);
   1190             }
   1191         }
   1192 
   1193         /* set up some base-layer only parameters */
   1194         vopHeader[0]->refSelectCode = 1;
   1195 #ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
   1196     }
   1197 #endif
   1198     timestamp[target_layer] = video->currTimestamp = vopHeader[target_layer]->timeStamp;
   1199 #ifdef PV_MEMORY_POOL
   1200     vopHeader[target_layer]->yChan = (PIXEL *)currYUV;
   1201     vopHeader[target_layer]->uChan = (PIXEL *)currYUV + decCtrl->size;
   1202     vopHeader[target_layer]->vChan = (PIXEL *)(vopHeader[target_layer]->uChan) + (decCtrl->size >> 2);
   1203 #else
   1204     vopHeader[target_layer]->yChan = currVop->yChan;
   1205     vopHeader[target_layer]->uChan = currVop->uChan;
   1206     vopHeader[target_layer]->vChan = currVop->vChan;
   1207 #endif
   1208     oscl_memcpy(currVop, vopHeader[target_layer], sizeof(Vop));
   1209 
   1210 #ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
   1211     vopHeader[target_layer]->timeStamp = -1;
   1212 #endif
   1213     /* put header info into the structure */
   1214     header_info->currLayer = target_layer;
   1215     header_info->timestamp = video->currTimestamp;
   1216     header_info->frameType = (MP4FrameType)currVop->predictionType;
   1217     header_info->refSelCode = vopHeader[target_layer]->refSelectCode;
   1218     header_info->quantizer = currVop->quantizer;
   1219     /***************************************/
   1220 
   1221     return PV_TRUE;
   1222 }
   1223 
   1224 
   1225 /* ======================================================================== */
   1226 /*  Function : PVDecodeVopBody()                                            */
   1227 /*  Date     : 08/22/2002                                                   */
   1228 /*  Purpose  : Decode vop body after the header is decoded, modified from   */
   1229 /*              original PVDecodeVideoFrame.                                */
   1230 /*  In/out   :                                                              */
   1231 /*  Return   :                                                              */
   1232 /*  Note     :                                                              */
   1233 /*  Modified :                                                              */
   1234 /* ======================================================================== */
   1235 Bool PVDecodeVopBody(VideoDecControls *decCtrl, int32 buffer_size[])
   1236 {
   1237     PV_STATUS status = PV_FAIL;
   1238     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
   1239     int target_layer = video->currLayer;
   1240     Vol *currVol = video->vol[target_layer];
   1241     Vop *currVop = video->currVop;
   1242     Vop *prevVop = video->prevVop;
   1243     Vop *tempVopPtr;
   1244     int bytes_consumed = 0; /* Record how many bits we used in the buffer.   04/24/2001 */
   1245 
   1246     int idx;
   1247 
   1248     if (currVop->vopCoded == 0)                  /*  07/03/2001 */
   1249     {
   1250         PV_BitstreamByteAlign(currVol->bitstream);
   1251         /* We should always clear up bitstream buffer.   10/10/2000 */
   1252         bytes_consumed = (getPointer(currVol->bitstream) + 7) >> 3;
   1253 
   1254         if (bytes_consumed > currVol->bitstream->data_end_pos)
   1255         {
   1256             bytes_consumed = currVol->bitstream->data_end_pos;
   1257         }
   1258 
   1259         if (bytes_consumed < buffer_size[target_layer])
   1260         {
   1261             /* If we only consume part of the bits in the buffer, take those */
   1262             /*  out.     04/24/2001 */
   1263             /*          oscl_memcpy(buffer[target_layer], buffer[target_layer]+bytes_consumed,
   1264                             (buffer_size[target_layer]-=bytes_consumed)); */
   1265             buffer_size[target_layer] -= bytes_consumed;
   1266         }
   1267         else
   1268         {
   1269             buffer_size[target_layer] = 0;
   1270         }
   1271 #ifdef PV_MEMORY_POOL
   1272 
   1273         if (target_layer)
   1274         {
   1275             if (video->prevEnhcVop->timeStamp > video->prevVop->timeStamp)
   1276             {
   1277                 video->prevVop = video->prevEnhcVop;
   1278             }
   1279         }
   1280 
   1281         oscl_memcpy(currVop->yChan, video->prevVop->yChan, (decCtrl->size*3) / 2);
   1282 
   1283         video->prevVop = prevVop;
   1284 
   1285         video->concealFrame = currVop->yChan;       /*  07/07/2001 */
   1286 
   1287         video->vop_coding_type = currVop->predictionType; /*  07/09/01 */
   1288 
   1289         decCtrl->outputFrame = currVop->yChan;
   1290 
   1291         /* Swap VOP pointers.  No enhc. frame oscl_memcpy() anymore!   04/24/2001 */
   1292         if (target_layer)
   1293         {
   1294             tempVopPtr = video->prevEnhcVop;
   1295             video->prevEnhcVop = video->currVop;
   1296             video->currVop = tempVopPtr;
   1297         }
   1298         else
   1299         {
   1300             tempVopPtr = video->prevVop;
   1301             video->prevVop = video->currVop;
   1302             video->currVop = tempVopPtr;
   1303         }
   1304 #else
   1305         if (target_layer)       /* this is necessary to avoid flashback problems   06/21/2002*/
   1306         {
   1307             video->prevEnhcVop->timeStamp = currVop->timeStamp;
   1308         }
   1309         else
   1310         {
   1311             video->prevVop->timeStamp = currVop->timeStamp;
   1312         }
   1313 #endif
   1314         video->vop_coding_type = currVop->predictionType; /*  07/09/01 */
   1315         /* the following is necessary to avoid displaying an notCoded I-VOP at the beginning of a session
   1316         or after random positioning  07/03/02*/
   1317         if (currVop->predictionType == I_VOP)
   1318         {
   1319             video->vop_coding_type = P_VOP;
   1320         }
   1321 
   1322 
   1323         return PV_TRUE;
   1324     }
   1325     /* ======================================================= */
   1326     /*  Decode vop body (if there is no error in the header!)  */
   1327     /* ======================================================= */
   1328 
   1329     /* first, we need to select a reference frame */
   1330     if (decCtrl->nLayers > 1)
   1331     {
   1332         if (currVop->predictionType == I_VOP)
   1333         {
   1334             /* do nothing here */
   1335         }
   1336         else if (currVop->predictionType == P_VOP)
   1337         {
   1338             switch (currVop->refSelectCode)
   1339             {
   1340                 case 0 : /* most recently decoded enhancement vop */
   1341                     /* Setup video->prevVop before we call PV_DecodeVop().   04/24/2001 */
   1342                     if (video->prevEnhcVop->timeStamp >= video->prevVop->timeStamp)
   1343                         video->prevVop = video->prevEnhcVop;
   1344                     break;
   1345 
   1346                 case 1 : /* most recently displayed base-layer vop */
   1347                     if (target_layer)
   1348                     {
   1349                         if (video->prevEnhcVop->timeStamp > video->prevVop->timeStamp)
   1350                             video->prevVop = video->prevEnhcVop;
   1351                     }
   1352                     break;
   1353 
   1354                 case 2 : /* next base-layer vop in display order */
   1355                     break;
   1356 
   1357                 case 3 : /* temporally coincident base-layer vop (no MV's) */
   1358                     break;
   1359             }
   1360         }
   1361         else /* we have a B-Vop */
   1362         {
   1363             mp4dec_log("DecodeVideoFrame(): B-VOP not supported.\n");
   1364         }
   1365     }
   1366 
   1367     /* This is for the calculation of the frame rate and bitrate. */
   1368     idx = ++video->frame_idx % BITRATE_AVERAGE_WINDOW;
   1369 
   1370     /* Calculate bitrate for this layer.   08/23/2000 */
   1371     status = PV_DecodeVop(video);
   1372     video->nBitsPerVop[idx] = getPointer(currVol->bitstream);
   1373     video->prevTimestamp[idx] = currVop->timeStamp;
   1374 
   1375     /* restore video->prevVop after PV_DecodeVop().   04/24/2001 */
   1376 //  if (currVop->refSelectCode == 0) video->prevVop = prevVop;
   1377     video->prevVop = prevVop;
   1378 
   1379     /* Estimate the frame rate.   08/23/2000 */
   1380     video->duration = video->prevTimestamp[idx];
   1381     video->duration -= video->prevTimestamp[(++idx)%BITRATE_AVERAGE_WINDOW];
   1382     if (video->duration > 0)
   1383     { /* Only update framerate when the timestamp is right */
   1384         video->frameRate = (int)(FRAMERATE_SCALE) / video->duration;
   1385     }
   1386 
   1387     /* We should always clear up bitstream buffer.   10/10/2000 */
   1388     bytes_consumed = (getPointer(currVol->bitstream) + 7) >> 3; /*  11/4/03 */
   1389 
   1390     if (bytes_consumed > currVol->bitstream->data_end_pos)
   1391     {
   1392         bytes_consumed = currVol->bitstream->data_end_pos;
   1393     }
   1394 
   1395     if (bytes_consumed < buffer_size[target_layer])
   1396     {
   1397         /* If we only consume part of the bits in the buffer, take those */
   1398         /*  out.     04/24/2001 */
   1399         /*      oscl_memcpy(buffer[target_layer], buffer[target_layer]+bytes_consumed,
   1400                     (buffer_size[target_layer]-=bytes_consumed)); */
   1401         buffer_size[target_layer] -= bytes_consumed;
   1402     }
   1403     else
   1404     {
   1405         buffer_size[target_layer] = 0;
   1406     }
   1407     switch (status)
   1408     {
   1409         case PV_FAIL :
   1410             return PV_FALSE;        /* this will take care of concealment if we lose whole frame  */
   1411 
   1412         case PV_END_OF_VOP :
   1413             /* we may want to differenciate PV_END_OF_VOP and PV_SUCCESS */
   1414             /*    in the future.     05/10/2000                      */
   1415 
   1416         case PV_SUCCESS :
   1417             /* Nohting is wrong :). */
   1418 
   1419 
   1420             video->concealFrame = video->currVop->yChan;       /*  07/07/2001 */
   1421 
   1422             video->vop_coding_type = video->currVop->predictionType; /*  07/09/01 */
   1423 
   1424             decCtrl->outputFrame = video->currVop->yChan;
   1425 
   1426             /* Swap VOP pointers.  No enhc. frame oscl_memcpy() anymore!   04/24/2001 */
   1427             if (target_layer)
   1428             {
   1429                 tempVopPtr = video->prevEnhcVop;
   1430                 video->prevEnhcVop = video->currVop;
   1431                 video->currVop = tempVopPtr;
   1432             }
   1433             else
   1434             {
   1435                 tempVopPtr = video->prevVop;
   1436                 video->prevVop = video->currVop;
   1437                 video->currVop = tempVopPtr;
   1438             }
   1439             break;
   1440 
   1441         default :
   1442             /* This will never happen */
   1443             break;
   1444     }
   1445 
   1446     return PV_TRUE;
   1447 }
   1448 
   1449 #ifdef PV_MEMORY_POOL
   1450 OSCL_EXPORT_REF void PVSetReferenceYUV(VideoDecControls *decCtrl, uint8 *YUV)
   1451 {
   1452     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
   1453     video->prevVop->yChan = (PIXEL *)YUV;
   1454     video->prevVop->uChan = (PIXEL *)YUV + video->size;
   1455     video->prevVop->vChan = (PIXEL *)video->prevVop->uChan + (decCtrl->size >> 2);
   1456     oscl_memset(video->prevVop->yChan, 16, sizeof(uint8)*decCtrl->size);     /*  10/31/01 */
   1457     oscl_memset(video->prevVop->uChan, 128, sizeof(uint8)*decCtrl->size / 2);
   1458     video->concealFrame = video->prevVop->yChan;               /*  07/07/2001 */
   1459     decCtrl->outputFrame = video->prevVop->yChan;              /*  06/19/2002 */
   1460 }
   1461 #endif
   1462 
   1463 
   1464 /* ======================================================================== */
   1465 /*  Function : VideoDecoderErrorDetected()                                  */
   1466 /*  Date     : 06/20/2000                                                   */
   1467 /*  Purpose  :                                                              */
   1468 /*  In/out   :                                                              */
   1469 /*  Return   : This function will be called everytime an error int the      */
   1470 /*              bitstream is detected.                                      */
   1471 /*  Note     :                                                              */
   1472 /*  Modified :                                                              */
   1473 /* ======================================================================== */
   1474 uint VideoDecoderErrorDetected(VideoDecData * video)
   1475 {
   1476     OSCL_UNUSED_ARG(video);
   1477     /* This is only used for trapping bitstream error for debuging */
   1478     return 0;
   1479 }
   1480 
   1481 #ifdef ENABLE_LOG
   1482 #include <stdio.h>
   1483 #include <stdarg.h>
   1484 /* ======================================================================== */
   1485 /*  Function : m4vdec_dprintf()                                             */
   1486 /*  Date     : 08/15/2000                                                   */
   1487 /*  Purpose  : This is a function that logs messages in the mpeg4 video     */
   1488 /*             decoder.  We can call the standard PacketVideo PVMessage     */
   1489 /*             from inside this function if necessary.                      */
   1490 /*  In/out   :                                                              */
   1491 /*  Return   :                                                              */
   1492 /*  Note     : To turn on the logging, LOG_MP4DEC_MESSAGE must be defined   */
   1493 /*              when compiling this file (only this file).                  */
   1494 /*  Modified :                                                              */
   1495 /* ======================================================================== */
   1496 void m4vdec_dprintf(char *format, ...)
   1497 {
   1498     FILE *log_fp;
   1499     va_list args;
   1500     va_start(args, format);
   1501 
   1502     /* open the log file */
   1503     log_fp = fopen("\\mp4dec_log.txt", "a+");
   1504     if (log_fp == NULL) return;
   1505     /* output the message */
   1506     vfprintf(log_fp, format, args);
   1507     fclose(log_fp);
   1508 
   1509     va_end(args);
   1510 }
   1511 #endif
   1512 
   1513 
   1514 /* ======================================================================== */
   1515 /*  Function : IsIntraFrame()                                               */
   1516 /*  Date     : 05/29/2000                                                   */
   1517 /*  Purpose  :                                                              */
   1518 /*  In/out   :                                                              */
   1519 /*  Return   : The most recently decoded frame is an Intra frame.           */
   1520 /*  Note     :                                                              */
   1521 /*  Modified :                                                              */
   1522 /* ======================================================================== */
   1523 Bool IsIntraFrame(VideoDecControls *decCtrl)
   1524 {
   1525     VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
   1526     return (video->vop_coding_type == I_VOP);
   1527 }
   1528 
   1529 /* ======================================================================== */
   1530 /*  Function : PVDecPostProcess()                                           */
   1531 /*  Date     : 01/09/2002                                                   */
   1532 /*  Purpose  : PostProcess one video frame and return a YUV-12 image.       */
   1533 /*  In/out   :                                                              */
   1534 /*  Return   :                                                              */
   1535 /*  Note     :                                                              */
   1536 /*  Modified :                                                              */
   1537 /* ======================================================================== */
   1538 void PVDecPostProcess(VideoDecControls *decCtrl, uint8 *outputYUV)
   1539 {
   1540     uint8 *outputBuffer;
   1541 #ifdef PV_POSTPROC_ON
   1542     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
   1543     int32 tmpvar;
   1544     if (outputYUV)
   1545     {
   1546         outputBuffer = outputYUV;
   1547     }
   1548     else
   1549     {
   1550         if (video->postFilterType)
   1551         {
   1552             outputBuffer = video->currVop->yChan;
   1553         }
   1554         else
   1555         {
   1556             outputBuffer = decCtrl->outputFrame;
   1557         }
   1558     }
   1559 
   1560     if (video->postFilterType)
   1561     {
   1562         /* Post-processing,  */
   1563         PostFilter(video, video->postFilterType, outputBuffer);
   1564     }
   1565     else
   1566     {
   1567         if (outputYUV)
   1568         {
   1569             /* Copy decoded frame to the output buffer. */
   1570             tmpvar = (int32)video->width * video->height;
   1571             oscl_memcpy(outputBuffer, decCtrl->outputFrame, tmpvar*3 / 2);           /*  3/3/01 */
   1572         }
   1573     }
   1574 #else
   1575     OSCL_UNUSED_ARG(outputYUV);
   1576     outputBuffer = decCtrl->outputFrame;
   1577 #endif
   1578     decCtrl->outputFrame = outputBuffer;
   1579     return;
   1580 }
   1581 
   1582 
   1583 /* ======================================================================== */
   1584 /*  Function : PVDecSetReference(VideoDecControls *decCtrl, uint8 *refYUV,  */
   1585 /*                              int32 timestamp)                            */
   1586 /*  Date     : 07/22/2003                                                   */
   1587 /*  Purpose  : Get YUV reference frame from external source.                */
   1588 /*  In/out   : YUV 4-2-0 frame containing new reference frame in the same   */
   1589 /*   : dimension as original, i.e., doesn't have to be multiple of 16 !!!.  */
   1590 /*  Return   :                                                              */
   1591 /*  Note     :                                                              */
   1592 /*  Modified :                                                              */
   1593 /* ======================================================================== */
   1594 Bool PVDecSetReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp)
   1595 {
   1596     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
   1597     Vop *prevVop = video->prevVop;
   1598     int width = video->width;
   1599     uint8 *dstPtr, *orgPtr, *dstPtr2, *orgPtr2;
   1600     int32 size = (int32)width * video->height;
   1601 
   1602 
   1603     /* set new parameters */
   1604     prevVop->timeStamp = timestamp;
   1605     prevVop->predictionType = I_VOP;
   1606 
   1607     dstPtr = prevVop->yChan;
   1608     orgPtr = refYUV;
   1609     oscl_memcpy(dstPtr, orgPtr, size);
   1610     dstPtr = prevVop->uChan;
   1611     dstPtr2 = prevVop->vChan;
   1612     orgPtr = refYUV + size;
   1613     orgPtr2 = orgPtr + (size >> 2);
   1614     oscl_memcpy(dstPtr, orgPtr, (size >> 2));
   1615     oscl_memcpy(dstPtr2, orgPtr2, (size >> 2));
   1616 
   1617     video->concealFrame = video->prevVop->yChan;
   1618     video->vop_coding_type = I_VOP;
   1619     decCtrl->outputFrame = video->prevVop->yChan;
   1620 
   1621     return PV_TRUE;
   1622 }
   1623 
   1624 /* ======================================================================== */
   1625 /*  Function : PVDecSetEnhReference(VideoDecControls *decCtrl, uint8 *refYUV,   */
   1626 /*                              int32 timestamp)                            */
   1627 /*  Date     : 07/23/2003                                                   */
   1628 /*  Purpose  : Get YUV enhance reference frame from external source.        */
   1629 /*  In/out   : YUV 4-2-0 frame containing new reference frame in the same   */
   1630 /*   : dimension as original, i.e., doesn't have to be multiple of 16 !!!.  */
   1631 /*  Return   :                                                              */
   1632 /*  Note     :                                                              */
   1633 /*  Modified :                                                              */
   1634 /* ======================================================================== */
   1635 Bool PVDecSetEnhReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp)
   1636 {
   1637     VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
   1638     Vop *prevEnhcVop = video->prevEnhcVop;
   1639     uint8 *dstPtr, *orgPtr, *dstPtr2, *orgPtr2;
   1640     int32 size = (int32) video->width * video->height;
   1641 
   1642     if (video->numberOfLayers <= 1)
   1643         return PV_FALSE;
   1644 
   1645 
   1646     /* set new parameters */
   1647     prevEnhcVop->timeStamp = timestamp;
   1648     prevEnhcVop->predictionType = I_VOP;
   1649 
   1650     dstPtr = prevEnhcVop->yChan;
   1651     orgPtr = refYUV;
   1652     oscl_memcpy(dstPtr, orgPtr, size);
   1653     dstPtr = prevEnhcVop->uChan;
   1654     dstPtr2 = prevEnhcVop->vChan;
   1655     orgPtr = refYUV + size;
   1656     orgPtr2 = orgPtr + (size >> 2);
   1657     oscl_memcpy(dstPtr, orgPtr, (size >> 2));
   1658     oscl_memcpy(dstPtr2, orgPtr2, (size >> 2));
   1659     video->concealFrame = video->prevEnhcVop->yChan;
   1660     video->vop_coding_type = I_VOP;
   1661     decCtrl->outputFrame = video->prevEnhcVop->yChan;
   1662 
   1663     return PV_TRUE;
   1664 }
   1665 
   1666 
   1667 /* ======================================================================== */
   1668 /*  Function : PVGetVolInfo()                                               */
   1669 /*  Date     : 08/06/2003                                                   */
   1670 /*  Purpose  : Get the vol info(only base-layer).                           */
   1671 /*  In/out   :                                                              */
   1672 /*  Return   :                                                              */
   1673 /*  Note     :                                                              */
   1674 /*  Modified : 06/24/2004                                                   */
   1675 /* ======================================================================== */
   1676 Bool PVGetVolInfo(VideoDecControls *decCtrl, VolInfo *pVolInfo)
   1677 {
   1678     Vol *currVol;
   1679 
   1680     if (pVolInfo == NULL || decCtrl == NULL || decCtrl->videoDecoderData == NULL ||
   1681             ((VideoDecData *)decCtrl->videoDecoderData)->vol[0] == NULL) return PV_FALSE;
   1682 
   1683     currVol = ((VideoDecData *)(decCtrl->videoDecoderData))->vol[0];
   1684 
   1685     // get the VOL info
   1686     pVolInfo->shortVideoHeader = (int32)((VideoDecData *)(decCtrl->videoDecoderData))->shortVideoHeader;
   1687     pVolInfo->dataPartitioning = (int32)currVol->dataPartitioning;
   1688     pVolInfo->errorResDisable  = (int32)currVol->errorResDisable;
   1689     pVolInfo->useReverseVLC    = (int32)currVol->useReverseVLC;
   1690     pVolInfo->scalability      = (int32)currVol->scalability;
   1691     pVolInfo->nbitsTimeIncRes  = (int32)currVol->nbitsTimeIncRes;
   1692     pVolInfo->profile_level_id = (int32)currVol->profile_level_id;
   1693 
   1694     return PV_TRUE;
   1695 }
   1696 
   1697 
   1698 
   1699