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