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