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