OSDN Git Service

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