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