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