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