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