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