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