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