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