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