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