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