1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 #include "mp4dec_lib.h"
19 #include "vlc_decode.h"
20 #include "bitstream.h"
22 #define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
24 #ifdef DEC_INTERNAL_MEMORY_OPT
26 #define QCIF_BS (4*QCIF_MBS)
27 #define QCIF_MB_ROWS 11
28 extern uint8 IMEM_sliceNo[QCIF_MBS];
29 extern uint8 IMEM_acPredFlag[QCIF_MBS];
30 extern uint8 IMEM_headerInfo_Mode[QCIF_MBS];
31 extern uint8 IMEM_headerInfo_CBP[QCIF_MBS];
32 extern int IMEM_headerInfo_QPMB[QCIF_MBS];
33 extern MacroBlock IMEM_mblock;
34 extern MOT IMEM_motX[QCIF_BS];
35 extern MOT IMEM_motY[QCIF_BS];
36 extern BitstreamDecVideo IMEM_BitstreamDecVideo[4];
37 extern typeDCStore IMEM_predDC[QCIF_MBS];
38 extern typeDCACStore IMEM_predDCAC_col[QCIF_MB_ROWS+1];
40 extern VideoDecData IMEM_VideoDecData[1];
41 extern Vop IMEM_currVop[1];
42 extern Vop IMEM_prevVop[1];
43 extern PIXEL IMEM_currVop_yChan[QCIF_MBS*128*3];
44 extern PIXEL IMEM_prevVop_yChan[QCIF_MBS*128*3];
45 extern uint8 IMEM_pstprcTypCur[6*QCIF_MBS];
46 extern uint8 IMEM_pstprcTypPrv[6*QCIF_MBS];
49 extern Vop IMEM_vopHEADER[2];
50 extern Vol IMEM_VOL[2];
51 extern Vop IMEM_vopHeader[2][1];
52 extern Vol IMEM_vol[2][1];
56 /* ======================================================================== */
57 /* Function : PVInitVideoDecoder() */
58 /* Date : 04/11/2000, 08/29/2000 */
59 /* Purpose : Initialization of the MPEG-4 video decoder library. */
60 /* The return type is Bool instead of PV_STATUS because */
61 /* we don't want to expose PV_STATUS to (outside) programmers */
62 /* that use our decoder library SDK. */
64 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
66 /* ======================================================================== */
67 OSCL_EXPORT_REF Bool PVInitVideoDecoder(VideoDecControls *decCtrl, uint8 *volbuf[],
68 int32 *volbuf_size, int nLayers, int width, int height, MP4DecodingMode mode)
70 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
71 Bool status = PV_TRUE;
73 BitstreamDecVideo *stream;
76 oscl_memset(decCtrl, 0, sizeof(VideoDecControls)); /* fix a size bug. 03/28/2001 */
77 decCtrl->nLayers = nLayers;
78 for (idx = 0; idx < nLayers; idx++)
80 decCtrl->volbuf[idx] = volbuf[idx];
81 decCtrl->volbuf_size[idx] = volbuf_size[idx];
84 /* memory allocation & initialization */
85 #ifdef DEC_INTERNAL_MEMORY_OPT
86 video = IMEM_VideoDecData;
88 video = (VideoDecData *) oscl_malloc(sizeof(VideoDecData));
92 oscl_memset(video, 0, sizeof(VideoDecData));
93 video->memoryUsage = sizeof(VideoDecData);
94 video->numberOfLayers = nLayers;
95 #ifdef DEC_INTERNAL_MEMORY_OPT
96 video->vol = (Vol **) IMEM_VOL;
98 video->vol = (Vol **) oscl_malloc(nLayers * sizeof(Vol *));
100 if (video->vol == NULL) status = PV_FALSE;
101 video->memoryUsage += nLayers * sizeof(Vol *);
104 /* we need to setup this pointer for the application to */
105 /* pass it around. */
106 decCtrl->videoDecoderData = (void *) video;
107 video->videoDecControls = decCtrl; /* yes. we have a cyclic */
108 /* references here :) */
110 /* Allocating Vop space, this has to change when we add */
111 /* spatial scalability to the decoder */
112 #ifdef DEC_INTERNAL_MEMORY_OPT
113 video->currVop = IMEM_currVop;
114 if (video->currVop == NULL) status = PV_FALSE;
115 else oscl_memset(video->currVop, 0, sizeof(Vop));
116 video->prevVop = IMEM_prevVop;
117 if (video->prevVop == NULL) status = PV_FALSE;
118 else oscl_memset(video->prevVop, 0, sizeof(Vop));
119 video->memoryUsage += (sizeof(Vop) * 2);
120 video->vopHeader = (Vop **) IMEM_vopHEADER;
123 video->currVop = (Vop *) oscl_malloc(sizeof(Vop));
124 if (video->currVop == NULL) status = PV_FALSE;
125 else oscl_memset(video->currVop, 0, sizeof(Vop));
126 video->prevVop = (Vop *) oscl_malloc(sizeof(Vop));
127 if (video->prevVop == NULL) status = PV_FALSE;
128 else oscl_memset(video->prevVop, 0, sizeof(Vop));
129 video->memoryUsage += (sizeof(Vop) * 2);
131 video->vopHeader = (Vop **) oscl_malloc(sizeof(Vop *) * nLayers);
133 if (video->vopHeader == NULL) status = PV_FALSE;
134 else oscl_memset(video->vopHeader, 0, sizeof(Vop *)*nLayers);
135 video->memoryUsage += (sizeof(Vop *) * nLayers);
137 video->initialized = PV_FALSE;
138 /* Decode the header to get all information to allocate data */
139 if (status == PV_TRUE)
141 /* initialize decoded frame counter. 04/24/2001 */
142 video->frame_idx = -1;
145 for (idx = 0; idx < nLayers; idx++)
148 #ifdef DEC_INTERNAL_MEMORY_OPT
149 video->vopHeader[idx] = IMEM_vopHeader[idx];
151 video->vopHeader[idx] = (Vop *) oscl_malloc(sizeof(Vop));
153 if (video->vopHeader[idx] == NULL)
160 oscl_memset(video->vopHeader[idx], 0, sizeof(Vop));
161 video->vopHeader[idx]->timeStamp = 0;
162 video->memoryUsage += (sizeof(Vop));
164 #ifdef DEC_INTERNAL_MEMORY_OPT
165 video->vol[idx] = IMEM_vol[idx];
166 video->memoryUsage += sizeof(Vol);
167 oscl_memset(video->vol[idx], 0, sizeof(Vol));
168 if (video->vol[idx] == NULL) status = PV_FALSE;
169 stream = IMEM_BitstreamDecVideo;
171 video->vol[idx] = (Vol *) oscl_malloc(sizeof(Vol));
172 if (video->vol[idx] == NULL)
179 video->memoryUsage += sizeof(Vol);
180 oscl_memset(video->vol[idx], 0, sizeof(Vol));
183 stream = (BitstreamDecVideo *) oscl_malloc(sizeof(BitstreamDecVideo));
185 video->memoryUsage += sizeof(BitstreamDecVideo);
194 if ((buffer_size = BitstreamOpen(stream, idx)) < 0)
196 mp4dec_log("InitVideoDecoder(): Can't allocate bitstream buffer.\n");
200 video->memoryUsage += buffer_size;
201 video->vol[idx]->bitstream = stream;
202 video->vol[idx]->volID = idx;
203 video->vol[idx]->timeInc_offset = 0; /* 11/12/01 */
204 video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader;
205 video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader;
206 if (mode == MPEG4_MODE)
208 /* Set up VOL header bitstream for frame-based decoding. 08/30/2000 */
209 BitstreamReset(stream, decCtrl->volbuf[idx], decCtrl->volbuf_size[idx]);
211 switch (DecodeVOLHeader(video, idx))
214 if (status == PV_TRUE)
215 status = PV_TRUE; /* we want to make sure that if first layer is bad, second layer is good return PV_FAIL */
219 #ifdef PV_TOLERATE_VOL_ERRORS
220 case PV_BAD_VOLHEADER:
232 video->shortVideoHeader = PV_TRUE;
235 if (video->shortVideoHeader == PV_TRUE)
238 /* Set max width and height. In H.263 mode, we use */
239 /* volbuf_size[0] to pass in width and volbuf_size[1] */
240 /* to pass in height. 04/23/2001 */
241 video->prevVop->temporalRef = 0; /* 11/12/01 */
242 /* Compute some convenience variables: 04/23/2001 */
243 video->vol[idx]->quantType = 0;
244 video->vol[idx]->quantPrecision = 5;
245 video->vol[idx]->errorResDisable = 1;
246 video->vol[idx]->dataPartitioning = 0;
247 video->vol[idx]->useReverseVLC = 0;
248 video->intra_acdcPredDisable = 1;
249 video->vol[idx]->scalability = 0;
250 video->size = (int32)width * height;
252 video->displayWidth = video->width = width;
253 video->displayHeight = video->height = height;
254 #ifdef PV_ANNEX_IJKT_SUPPORT
255 video->modified_quant = 0;
256 video->advanced_INTRA = 0;
257 video->deblocking = 0;
258 video->slice_structure = 0;
266 if (status != PV_FALSE)
268 status = PVAllocVideoData(decCtrl, width, height, nLayers);
269 video->initialized = PV_TRUE;
277 if (status == PV_FALSE) PVCleanUpVideoDecoder(decCtrl);
282 Bool PVAllocVideoData(VideoDecControls *decCtrl, int width, int height, int nLayers)
284 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
285 Bool status = PV_TRUE;
290 if (video->shortVideoHeader == PV_TRUE)
292 video->displayWidth = video->width = width;
293 video->displayHeight = video->height = height;
296 video->nMBinGOB = video->width / MB_SIZE;
298 video->nGOBinVop = video->height / MB_SIZE;
300 video->nMBPerRow * video->nMBPerCol;
303 size = (int32)sizeof(PIXEL) * video->width * video->height;
304 #ifdef PV_MEMORY_POOL
305 decCtrl->size = size;
307 #ifdef DEC_INTERNAL_MEMORY_OPT
308 video->currVop->yChan = IMEM_currVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
309 if (video->currVop->yChan == NULL) status = PV_FALSE;
310 video->currVop->uChan = video->currVop->yChan + size;
311 video->currVop->vChan = video->currVop->uChan + (size >> 2);
313 video->prevVop->yChan = IMEM_prevVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
314 if (video->prevVop->yChan == NULL) status = PV_FALSE;
315 video->prevVop->uChan = video->prevVop->yChan + size;
316 video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
318 video->currVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
319 if (video->currVop->yChan == NULL) status = PV_FALSE;
321 video->currVop->uChan = video->currVop->yChan + size;
322 video->currVop->vChan = video->currVop->uChan + (size >> 2);
323 video->prevVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
324 if (video->prevVop->yChan == NULL) status = PV_FALSE;
326 video->prevVop->uChan = video->prevVop->yChan + size;
327 video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
329 video->memoryUsage += (size * 3);
330 #endif // MEMORY_POOL
331 /* Note that baseVop, enhcVop is only used to hold enhancement */
332 /* layer header information. 05/04/2000 */
335 video->prevEnhcVop = (Vop *) oscl_malloc(sizeof(Vop));
336 video->memoryUsage += (sizeof(Vop));
337 if (video->prevEnhcVop == NULL)
343 oscl_memset(video->prevEnhcVop, 0, sizeof(Vop));
344 #ifndef PV_MEMORY_POOL
345 video->prevEnhcVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
346 if (video->prevEnhcVop->yChan == NULL) status = PV_FALSE;
347 video->prevEnhcVop->uChan = video->prevEnhcVop->yChan + size;
348 video->prevEnhcVop->vChan = video->prevEnhcVop->uChan + (size >> 2);
349 video->memoryUsage += (3 * size / 2);
354 /* Allocating space for slices, AC prediction flag, and */
355 /* AC/DC prediction storage */
356 nTotalMB = video->nTotalMB;
357 nMBPerRow = video->nMBPerRow;
359 #ifdef DEC_INTERNAL_MEMORY_OPT
360 video->sliceNo = (uint8 *)(IMEM_sliceNo);
361 if (video->sliceNo == NULL) status = PV_FALSE;
362 video->memoryUsage += nTotalMB;
363 video->acPredFlag = (uint8 *)(IMEM_acPredFlag);
364 if (video->acPredFlag == NULL) status = PV_FALSE;
365 video->memoryUsage += (nTotalMB);
366 video->predDC = (typeDCStore *)(IMEM_predDC);
367 if (video->predDC == NULL) status = PV_FALSE;
368 video->memoryUsage += (nTotalMB * sizeof(typeDCStore));
369 video->predDCAC_col = (typeDCACStore *)(IMEM_predDCAC_col);
370 if (video->predDCAC_col == NULL) status = PV_FALSE;
371 video->memoryUsage += ((nMBPerRow + 1) * sizeof(typeDCACStore));
372 video->predDCAC_row = video->predDCAC_col + 1;
373 video->headerInfo.Mode = (uint8 *)(IMEM_headerInfo_Mode);
374 if (video->headerInfo.Mode == NULL) status = PV_FALSE;
375 video->memoryUsage += nTotalMB;
376 video->headerInfo.CBP = (uint8 *)(IMEM_headerInfo_CBP);
377 if (video->headerInfo.CBP == NULL) status = PV_FALSE;
378 video->memoryUsage += nTotalMB;
379 video->QPMB = (int *)(IMEM_headerInfo_QPMB);
380 if (video->QPMB == NULL) status = PV_FALSE;
381 video->memoryUsage += (nTotalMB * sizeof(int));
382 video->mblock = &IMEM_mblock;
383 if (video->mblock == NULL) status = PV_FALSE;
384 oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); // Aug 23,2005
386 video->memoryUsage += sizeof(MacroBlock);
387 video->motX = (MOT *)(IMEM_motX);
388 if (video->motX == NULL) status = PV_FALSE;
389 video->motY = (MOT *)(IMEM_motY);
390 if (video->motY == NULL) status = PV_FALSE;
391 video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
393 video->sliceNo = (uint8 *) oscl_malloc(nTotalMB);
394 if (video->sliceNo == NULL) status = PV_FALSE;
395 video->memoryUsage += nTotalMB;
397 video->acPredFlag = (uint8 *) oscl_malloc(nTotalMB * sizeof(uint8));
398 if (video->acPredFlag == NULL) status = PV_FALSE;
399 video->memoryUsage += (nTotalMB);
401 video->predDC = (typeDCStore *) oscl_malloc(nTotalMB * sizeof(typeDCStore));
402 if (video->predDC == NULL) status = PV_FALSE;
403 video->memoryUsage += (nTotalMB * sizeof(typeDCStore));
405 video->predDCAC_col = (typeDCACStore *) oscl_malloc((nMBPerRow + 1) * sizeof(typeDCACStore));
406 if (video->predDCAC_col == NULL) status = PV_FALSE;
407 video->memoryUsage += ((nMBPerRow + 1) * sizeof(typeDCACStore));
409 /* element zero will be used for storing vertical (col) AC coefficients */
410 /* the rest will be used for storing horizontal (row) AC coefficients */
411 video->predDCAC_row = video->predDCAC_col + 1; /* ACDC */
413 /* Allocating HeaderInfo structure & Quantizer array */
414 video->headerInfo.Mode = (uint8 *) oscl_malloc(nTotalMB);
415 if (video->headerInfo.Mode == NULL) status = PV_FALSE;
416 video->memoryUsage += nTotalMB;
417 video->headerInfo.CBP = (uint8 *) oscl_malloc(nTotalMB);
418 if (video->headerInfo.CBP == NULL) status = PV_FALSE;
419 video->memoryUsage += nTotalMB;
420 video->QPMB = (int16 *) oscl_malloc(nTotalMB * sizeof(int16));
421 if (video->QPMB == NULL) status = PV_FALSE;
422 video->memoryUsage += (nTotalMB * sizeof(int));
424 /* Allocating macroblock space */
425 video->mblock = (MacroBlock *) oscl_malloc(sizeof(MacroBlock));
426 if (video->mblock == NULL)
432 oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); // Aug 23,2005
434 video->memoryUsage += sizeof(MacroBlock);
436 /* Allocating motion vector space */
437 video->motX = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
438 if (video->motX == NULL) status = PV_FALSE;
439 video->motY = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
440 if (video->motY == NULL) status = PV_FALSE;
441 video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
444 #ifdef PV_POSTPROC_ON
445 /* Allocating space for post-processing Mode */
446 #ifdef DEC_INTERNAL_MEMORY_OPT
447 video->pstprcTypCur = IMEM_pstprcTypCur;
448 video->memoryUsage += (nTotalMB * 6);
449 if (video->pstprcTypCur == NULL)
455 oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
458 video->pstprcTypPrv = IMEM_pstprcTypPrv;
459 video->memoryUsage += (nTotalMB * 6);
460 if (video->pstprcTypPrv == NULL)
466 oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
470 video->pstprcTypCur = (uint8 *) oscl_malloc(nTotalMB * 6);
471 video->memoryUsage += (nTotalMB * 6);
472 if (video->pstprcTypCur == NULL)
478 oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
481 video->pstprcTypPrv = (uint8 *) oscl_malloc(nTotalMB * 6);
482 video->memoryUsage += (nTotalMB * 6);
483 if (video->pstprcTypPrv == NULL)
489 oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
496 /* initialize the decoder library */
497 video->prevVop->predictionType = I_VOP;
498 video->prevVop->timeStamp = 0;
499 #ifndef PV_MEMORY_POOL
500 oscl_memset(video->prevVop->yChan, 16, sizeof(uint8)*size); /* 10/31/01 */
501 oscl_memset(video->prevVop->uChan, 128, sizeof(uint8)*size / 2);
503 oscl_memset(video->currVop->yChan, 0, sizeof(uint8)*size*3 / 2);
506 oscl_memset(video->prevEnhcVop->yChan, 0, sizeof(uint8)*size*3 / 2);
507 video->prevEnhcVop->timeStamp = 0;
509 video->concealFrame = video->prevVop->yChan; /* 07/07/2001 */
510 decCtrl->outputFrame = video->prevVop->yChan; /* 06/19/2002 */
513 /* always start from base layer */
514 video->currLayer = 0;
518 /* ======================================================================== */
519 /* Function : PVResetVideoDecoder() */
520 /* Date : 01/14/2002 */
521 /* Purpose : Reset video timestamps */
523 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
525 /* ======================================================================== */
526 Bool PVResetVideoDecoder(VideoDecControls *decCtrl)
528 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
531 for (idx = 0; idx < decCtrl->nLayers; idx++)
533 video->vopHeader[idx]->timeStamp = 0;
535 video->prevVop->timeStamp = 0;
536 if (decCtrl->nLayers > 1)
537 video->prevEnhcVop->timeStamp = 0;
539 oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); // Aug 23,2005
545 /* ======================================================================== */
546 /* Function : PVCleanUpVideoDecoder() */
547 /* Date : 04/11/2000, 08/29/2000 */
548 /* Purpose : Cleanup of the MPEG-4 video decoder library. */
550 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
552 /* ======================================================================== */
553 OSCL_EXPORT_REF Bool PVCleanUpVideoDecoder(VideoDecControls *decCtrl)
556 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
557 #ifdef DEC_INTERNAL_MEMORY_OPT
560 #ifdef PV_POSTPROC_ON
561 video->pstprcTypCur = NULL;
562 video->pstprcTypPrv = NULL;
565 video->acPredFlag = NULL;
566 video->sliceNo = NULL;
569 video->mblock = NULL;
571 video->predDC = NULL;
572 video->predDCAC_row = NULL;
573 video->predDCAC_col = NULL;
574 video->headerInfo.Mode = NULL;
575 video->headerInfo.CBP = NULL;
576 if (video->numberOfLayers > 1)
578 if (video->prevEnhcVop)
580 video->prevEnhcVop->uChan = NULL;
581 video->prevEnhcVop->vChan = NULL;
582 if (video->prevEnhcVop->yChan) oscl_free(video->prevEnhcVop->yChan);
583 oscl_free(video->prevEnhcVop);
588 video->currVop->uChan = NULL;
589 video->currVop->vChan = NULL;
590 if (video->currVop->yChan)
591 video->currVop->yChan = NULL;
592 video->currVop = NULL;
596 video->prevVop->uChan = NULL;
597 video->prevVop->vChan = NULL;
598 if (video->prevVop->yChan)
599 video->prevVop->yChan = NULL;
600 video->prevVop = NULL;
605 for (idx = 0; idx < video->numberOfLayers; idx++)
609 BitstreamClose(video->vol[idx]->bitstream);
610 video->vol[idx]->bitstream = NULL;
611 video->vol[idx] = NULL;
613 video->vopHeader[idx] = NULL;
617 video->vopHeader = NULL;
621 decCtrl->videoDecoderData = NULL;
628 #ifdef PV_POSTPROC_ON
629 if (video->pstprcTypCur) oscl_free(video->pstprcTypCur);
630 if (video->pstprcTypPrv) oscl_free(video->pstprcTypPrv);
632 if (video->predDC) oscl_free(video->predDC);
633 video->predDCAC_row = NULL;
634 if (video->predDCAC_col) oscl_free(video->predDCAC_col);
635 if (video->motX) oscl_free(video->motX);
636 if (video->motY) oscl_free(video->motY);
637 if (video->mblock) oscl_free(video->mblock);
638 if (video->QPMB) oscl_free(video->QPMB);
639 if (video->headerInfo.Mode) oscl_free(video->headerInfo.Mode);
640 if (video->headerInfo.CBP) oscl_free(video->headerInfo.CBP);
641 if (video->sliceNo) oscl_free(video->sliceNo);
642 if (video->acPredFlag) oscl_free(video->acPredFlag);
644 if (video->numberOfLayers > 1)
646 if (video->prevEnhcVop)
648 video->prevEnhcVop->uChan = NULL;
649 video->prevEnhcVop->vChan = NULL;
650 if (video->prevEnhcVop->yChan) oscl_free(video->prevEnhcVop->yChan);
651 oscl_free(video->prevEnhcVop);
657 #ifndef PV_MEMORY_POOL
658 video->currVop->uChan = NULL;
659 video->currVop->vChan = NULL;
660 if (video->currVop->yChan)
661 oscl_free(video->currVop->yChan);
663 oscl_free(video->currVop);
667 #ifndef PV_MEMORY_POOL
668 video->prevVop->uChan = NULL;
669 video->prevVop->vChan = NULL;
670 if (video->prevVop->yChan)
671 oscl_free(video->prevVop->yChan);
673 oscl_free(video->prevVop);
678 for (idx = 0; idx < video->numberOfLayers; idx++)
682 if (video->vol[idx]->bitstream)
684 BitstreamClose(video->vol[idx]->bitstream);
685 oscl_free(video->vol[idx]->bitstream);
687 oscl_free(video->vol[idx]);
691 oscl_free(video->vol);
694 for (idx = 0; idx < video->numberOfLayers; idx++)
696 if (video->vopHeader[idx]) oscl_free(video->vopHeader[idx]);
699 if (video->vopHeader) oscl_free(video->vopHeader);
702 decCtrl->videoDecoderData = NULL;
707 /* ======================================================================== */
708 /* Function : PVGetVideoDimensions() */
712 /* Return : the display_width and display_height of */
713 /* the frame in the current layer. */
714 /* Note : This is not a macro or inline function because we do */
715 /* not want to expose our internal data structure. */
717 /* ======================================================================== */
718 OSCL_EXPORT_REF void PVGetVideoDimensions(VideoDecControls *decCtrl, int32 *display_width, int32 *display_height)
720 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
721 *display_width = video->displayWidth;
722 *display_height = video->displayHeight;
725 OSCL_EXPORT_REF void PVGetBufferDimensions(VideoDecControls *decCtrl, int32 *width, int32 *height) {
726 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
727 *width = video->width;
728 *height = video->height;
731 /* ======================================================================== */
732 /* Function : PVGetVideoTimeStamp() */
733 /* Date : 04/27/2000, 08/29/2000 */
736 /* Return : current time stamp in millisecond. */
739 /* ======================================================================== */
740 uint32 PVGetVideoTimeStamp(VideoDecControls *decCtrl)
742 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
743 return video->currTimestamp;
747 /* ======================================================================== */
748 /* Function : PVSetPostProcType() */
749 /* Date : 07/07/2000 */
752 /* Return : Set post-processing filter type. */
754 /* Modified : . 08/29/2000 changes the name for consistency. */
755 /* ======================================================================== */
756 OSCL_EXPORT_REF void PVSetPostProcType(VideoDecControls *decCtrl, int mode)
758 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
759 video->postFilterType = mode;
763 /* ======================================================================== */
764 /* Function : PVGetDecBitrate() */
765 /* Date : 08/23/2000 */
768 /* Return : This function returns the average bits per second. */
771 /* ======================================================================== */
772 int PVGetDecBitrate(VideoDecControls *decCtrl)
774 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
778 for (idx = 0; idx < BITRATE_AVERAGE_WINDOW; idx++)
780 sum += video->nBitsPerVop[idx];
782 sum = (sum * video->frameRate) / (10 * BITRATE_AVERAGE_WINDOW);
787 /* ======================================================================== */
788 /* Function : PVGetDecFramerate() */
789 /* Date : 08/23/2000 */
792 /* Return : This function returns the average frame per 10 second. */
793 /* Note : The fps can be calculated by PVGetDecFramerate()/10 */
795 /* ======================================================================== */
796 int PVGetDecFramerate(VideoDecControls *decCtrl)
798 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
800 return video->frameRate;
803 /* ======================================================================== */
804 /* Function : PVGetOutputFrame() */
805 /* Date : 05/07/2001 */
808 /* Return : This function returns the pointer to the output frame */
811 /* ======================================================================== */
812 uint8 *PVGetDecOutputFrame(VideoDecControls *decCtrl)
814 return decCtrl->outputFrame;
817 /* ======================================================================== */
818 /* Function : PVGetLayerID() */
819 /* Date : 07/09/2001 */
822 /* Return : This function returns decoded frame layer id (BASE/ENHANCE) */
825 /* ======================================================================== */
826 int PVGetLayerID(VideoDecControls *decCtrl)
828 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
829 return video->currLayer;
831 /* ======================================================================== */
832 /* Function : PVGetDecMemoryUsage() */
833 /* Date : 08/23/2000 */
836 /* Return : This function returns the amount of memory used. */
839 /* ======================================================================== */
840 int32 PVGetDecMemoryUsage(VideoDecControls *decCtrl)
842 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
843 return video->memoryUsage;
847 /* ======================================================================== */
848 /* Function : PVGetDecBitstreamMode() */
849 /* Date : 08/23/2000 */
852 /* Return : This function returns the decoding mode of the baselayer */
856 /* ======================================================================== */
857 OSCL_EXPORT_REF MP4DecodingMode PVGetDecBitstreamMode(VideoDecControls *decCtrl)
859 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
860 if (video->shortVideoHeader)
871 /* ======================================================================== */
872 /* Function : PVExtractVolHeader() */
873 /* Date : 08/29/2000 */
876 /* Return : Extract vol header of the bitstream from buffer[]. */
879 /* ======================================================================== */
880 Bool PVExtractVolHeader(uint8 *video_buffer, uint8 *vol_header, int32 *vol_header_size)
883 uint8 start_code_prefix[] = { 0x00, 0x00, 0x01 };
884 uint8 h263_prefix[] = { 0x00, 0x00, 0x80 };
886 if (oscl_memcmp(h263_prefix, video_buffer, 3) == 0) /* we have short header stream */
888 oscl_memcpy(vol_header, video_buffer, 32);
889 *vol_header_size = 32;
894 if (oscl_memcmp(start_code_prefix, video_buffer, 3) ||
895 (video_buffer[3] != 0xb0 && video_buffer[3] >= 0x20)) return FALSE;
900 while (oscl_memcmp(start_code_prefix, video_buffer + idx, 3))
903 if (idx + 3 >= *vol_header_size) goto quit;
906 while (video_buffer[idx+3] != 0xb3 && video_buffer[idx+3] != 0xb6);
908 oscl_memcpy(vol_header, video_buffer, idx);
909 *vol_header_size = idx;
914 oscl_memcpy(vol_header, video_buffer, *vol_header_size);
919 /* ======================================================================== */
920 /* Function : PVLocateFrameHeader() */
921 /* Date : 04/8/2005 */
924 /* Return : Return the offset to the first SC in the buffer */
927 /* ======================================================================== */
928 int32 PVLocateFrameHeader(uint8 *ptr, int32 size)
939 if ((count > 1) && (*ptr == 0x01))
950 return (size - (i + 1));
954 /* ======================================================================== */
955 /* Function : PVLocateH263FrameHeader() */
956 /* Date : 04/8/2005 */
959 /* Return : Return the offset to the first SC in the buffer */
962 /* ======================================================================== */
963 int32 PVLocateH263FrameHeader(uint8 *ptr, int32 size)
975 if ((count > 1) && ((*ptr & 0xFC) == 0x80))
986 return (size - (i + 1));
990 /* ======================================================================== */
991 /* Function : PVDecodeVideoFrame() */
992 /* Date : 08/29/2000 */
993 /* Purpose : Decode one video frame and return a YUV-12 image. */
997 /* Modified : 04/17/2001 removed PV_EOS, PV_END_OF_BUFFER */
998 /* : 08/22/2002 break up into 2 functions PVDecodeVopHeader and */
999 /* PVDecodeVopBody */
1000 /* ======================================================================== */
1001 OSCL_EXPORT_REF Bool PVDecodeVideoFrame(VideoDecControls *decCtrl, uint8 *buffer[],
1002 uint32 timestamp[], int32 buffer_size[], uint use_ext_timestamp[], uint8 *currYUV)
1004 PV_STATUS status = PV_FAIL;
1005 VopHeaderInfo header_info;
1007 status = (PV_STATUS)PVDecodeVopHeader(decCtrl, buffer, timestamp, buffer_size, &header_info, use_ext_timestamp, currYUV);
1008 if (status != PV_TRUE)
1011 if (PVDecodeVopBody(decCtrl, buffer_size) != PV_TRUE)
1019 /* ======================================================================== */
1020 /* Function : PVDecodeVopHeader() */
1021 /* Date : 08/22/2002 */
1022 /* Purpose : Determine target layer and decode vop header, modified from */
1023 /* original PVDecodeVideoFrame. */
1028 /* ======================================================================== */
1029 Bool PVDecodeVopHeader(VideoDecControls *decCtrl, uint8 *buffer[],
1030 uint32 timestamp[], int32 buffer_size[], VopHeaderInfo *header_info, uint use_ext_timestamp [], uint8 *currYUV)
1032 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
1034 Vop *currVop = video->currVop;
1035 Vop **vopHeader = video->vopHeader;
1036 BitstreamDecVideo *stream;
1040 #ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
1041 PV_STATUS status = PV_FAIL;
1045 /* decide which frame to decode next */
1046 if (decCtrl->nLayers > 1)
1048 display_time = target_layer = -1;
1049 for (idx = 0; idx < decCtrl->nLayers; idx++)
1051 /* do we have data for this layer? */
1052 if (buffer_size[idx] <= 0)
1054 timestamp[idx] = -1;
1058 /* did the application provide a timestamp for this vop? */
1059 if (timestamp[idx] < 0)
1061 if (vopHeader[idx]->timeStamp < 0)
1063 /* decode the timestamp in the bitstream */
1064 video->currLayer = idx;
1065 stream = video->vol[idx]->bitstream;
1066 BitstreamReset(stream, buffer[idx], buffer_size[idx]);
1068 while ((status = DecodeVOPHeader(video, vopHeader[idx], FALSE)) != PV_SUCCESS)
1070 /* Try to find a VOP header in the buffer. 08/30/2000. */
1071 if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
1073 /* if we don't have data for enhancement layer, */
1074 /* don't just stop. 09/07/2000. */
1075 buffer_size[idx] = 0;
1079 if (status == PV_SUCCESS)
1081 vopHeader[idx]->timeStamp =
1082 timestamp[idx] = CalcVopDisplayTime(video->vol[idx], vopHeader[idx], video->shortVideoHeader);
1083 if (idx == 0) vopHeader[idx]->refSelectCode = 1;
1088 /* We've decoded this vop header in the previous run already. */
1089 timestamp[idx] = vopHeader[idx]->timeStamp;
1093 /* Use timestamps to select the next VOP to be decoded */
1094 if (timestamp[idx] >= 0 && (display_time < 0 || display_time > timestamp[idx]))
1096 display_time = timestamp[idx];
1099 else if (display_time == timestamp[idx])
1101 /* we have to handle either SNR or spatial scalability here. */
1104 if (target_layer < 0) return PV_FALSE;
1106 /* set up for decoding the target layer */
1107 video->currLayer = target_layer;
1108 currVol = video->vol[target_layer];
1109 video->bitstream = stream = currVol->bitstream;
1111 /* We need to decode the vop header if external timestamp */
1112 /* is provided. 10/04/2000 */
1113 if (vopHeader[target_layer]->timeStamp < 0)
1115 stream = video->vol[target_layer]->bitstream;
1116 BitstreamReset(stream, buffer[target_layer], buffer_size[target_layer]);
1118 while (DecodeVOPHeader(video, vopHeader[target_layer], TRUE) != PV_SUCCESS)
1120 /* Try to find a VOP header in the buffer. 08/30/2000. */
1121 if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
1123 /* if we don't have data for enhancement layer, */
1124 /* don't just stop. 09/07/2000. */
1125 buffer_size[target_layer] = 0;
1129 video->vol[target_layer]->timeInc_offset = vopHeader[target_layer]->timeInc;
1130 video->vol[target_layer]->moduloTimeBase = timestamp[target_layer];
1131 vopHeader[target_layer]->timeStamp = timestamp[target_layer];
1132 if (target_layer == 0) vopHeader[target_layer]->refSelectCode = 1;
1135 else /* base layer only decoding */
1138 video->currLayer = target_layer = 0;
1139 currVol = video->vol[0];
1140 video->bitstream = stream = currVol->bitstream;
1141 if (buffer_size[0] <= 0) return PV_FALSE;
1142 BitstreamReset(stream, buffer[0], buffer_size[0]);
1144 if (video->shortVideoHeader)
1146 while (DecodeShortHeader(video, vopHeader[0]) != PV_SUCCESS)
1148 if (PVSearchNextH263Frame(stream) != PV_SUCCESS)
1150 /* There is no vop header in the buffer, */
1151 /* clean bitstream buffer. 2/5/2001 */
1153 if (video->initialized == PV_FALSE)
1155 video->displayWidth = video->width = 0;
1156 video->displayHeight = video->height = 0;
1162 if (use_ext_timestamp[0])
1164 /* MTB for H263 is absolute TR */
1165 /* following line is equivalent to round((timestamp[0]*30)/1001); 11/13/2001 */
1166 video->vol[0]->moduloTimeBase = 30 * ((timestamp[0] + 17) / 1001) + (30 * ((timestamp[0] + 17) % 1001) / 1001);
1167 vopHeader[0]->timeStamp = timestamp[0];
1170 vopHeader[0]->timeStamp = CalcVopDisplayTime(currVol, vopHeader[0], video->shortVideoHeader);
1174 while (DecodeVOPHeader(video, vopHeader[0], FALSE) != PV_SUCCESS)
1176 /* Try to find a VOP header in the buffer. 08/30/2000. */
1177 if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
1179 /* There is no vop header in the buffer, */
1180 /* clean bitstream buffer. 2/5/2001 */
1186 if (use_ext_timestamp[0])
1188 video->vol[0]->timeInc_offset = vopHeader[0]->timeInc;
1189 video->vol[0]->moduloTimeBase = timestamp[0]; /* 11/12/2001 */
1190 vopHeader[0]->timeStamp = timestamp[0];
1194 vopHeader[0]->timeStamp = CalcVopDisplayTime(currVol, vopHeader[0], video->shortVideoHeader);
1198 /* set up some base-layer only parameters */
1199 vopHeader[0]->refSelectCode = 1;
1200 #ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
1203 timestamp[target_layer] = video->currTimestamp = vopHeader[target_layer]->timeStamp;
1204 #ifdef PV_MEMORY_POOL
1205 vopHeader[target_layer]->yChan = (PIXEL *)currYUV;
1206 vopHeader[target_layer]->uChan = (PIXEL *)currYUV + decCtrl->size;
1207 vopHeader[target_layer]->vChan = (PIXEL *)(vopHeader[target_layer]->uChan) + (decCtrl->size >> 2);
1209 vopHeader[target_layer]->yChan = currVop->yChan;
1210 vopHeader[target_layer]->uChan = currVop->uChan;
1211 vopHeader[target_layer]->vChan = currVop->vChan;
1213 oscl_memcpy(currVop, vopHeader[target_layer], sizeof(Vop));
1215 #ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
1216 vopHeader[target_layer]->timeStamp = -1;
1218 /* put header info into the structure */
1219 header_info->currLayer = target_layer;
1220 header_info->timestamp = video->currTimestamp;
1221 header_info->frameType = (MP4FrameType)currVop->predictionType;
1222 header_info->refSelCode = vopHeader[target_layer]->refSelectCode;
1223 header_info->quantizer = currVop->quantizer;
1224 /***************************************/
1230 /* ======================================================================== */
1231 /* Function : PVDecodeVopBody() */
1232 /* Date : 08/22/2002 */
1233 /* Purpose : Decode vop body after the header is decoded, modified from */
1234 /* original PVDecodeVideoFrame. */
1239 /* ======================================================================== */
1240 Bool PVDecodeVopBody(VideoDecControls *decCtrl, int32 buffer_size[])
1242 PV_STATUS status = PV_FAIL;
1243 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
1244 int target_layer = video->currLayer;
1245 Vol *currVol = video->vol[target_layer];
1246 Vop *currVop = video->currVop;
1247 Vop *prevVop = video->prevVop;
1249 int bytes_consumed = 0; /* Record how many bits we used in the buffer. 04/24/2001 */
1253 if (currVop->vopCoded == 0) /* 07/03/2001 */
1255 PV_BitstreamByteAlign(currVol->bitstream);
1256 /* We should always clear up bitstream buffer. 10/10/2000 */
1257 bytes_consumed = (getPointer(currVol->bitstream) + 7) >> 3;
1259 if (bytes_consumed > currVol->bitstream->data_end_pos)
1261 bytes_consumed = currVol->bitstream->data_end_pos;
1264 if (bytes_consumed < buffer_size[target_layer])
1266 /* If we only consume part of the bits in the buffer, take those */
1267 /* out. 04/24/2001 */
1268 /* oscl_memcpy(buffer[target_layer], buffer[target_layer]+bytes_consumed,
1269 (buffer_size[target_layer]-=bytes_consumed)); */
1270 buffer_size[target_layer] -= bytes_consumed;
1274 buffer_size[target_layer] = 0;
1276 #ifdef PV_MEMORY_POOL
1280 if (video->prevEnhcVop->timeStamp > video->prevVop->timeStamp)
1282 video->prevVop = video->prevEnhcVop;
1286 oscl_memcpy(currVop->yChan, video->prevVop->yChan, (decCtrl->size*3) / 2);
1288 video->prevVop = prevVop;
1290 video->concealFrame = currVop->yChan; /* 07/07/2001 */
1292 video->vop_coding_type = currVop->predictionType; /* 07/09/01 */
1294 decCtrl->outputFrame = currVop->yChan;
1296 /* Swap VOP pointers. No enhc. frame oscl_memcpy() anymore! 04/24/2001 */
1299 tempVopPtr = video->prevEnhcVop;
1300 video->prevEnhcVop = video->currVop;
1301 video->currVop = tempVopPtr;
1305 tempVopPtr = video->prevVop;
1306 video->prevVop = video->currVop;
1307 video->currVop = tempVopPtr;
1310 if (target_layer) /* this is necessary to avoid flashback problems 06/21/2002*/
1312 video->prevEnhcVop->timeStamp = currVop->timeStamp;
1316 video->prevVop->timeStamp = currVop->timeStamp;
1319 video->vop_coding_type = currVop->predictionType; /* 07/09/01 */
1320 /* the following is necessary to avoid displaying an notCoded I-VOP at the beginning of a session
1321 or after random positioning 07/03/02*/
1322 if (currVop->predictionType == I_VOP)
1324 video->vop_coding_type = P_VOP;
1330 /* ======================================================= */
1331 /* Decode vop body (if there is no error in the header!) */
1332 /* ======================================================= */
1334 /* first, we need to select a reference frame */
1335 if (decCtrl->nLayers > 1)
1337 if (currVop->predictionType == I_VOP)
1339 /* do nothing here */
1341 else if (currVop->predictionType == P_VOP)
1343 switch (currVop->refSelectCode)
1345 case 0 : /* most recently decoded enhancement vop */
1346 /* Setup video->prevVop before we call PV_DecodeVop(). 04/24/2001 */
1347 if (video->prevEnhcVop->timeStamp >= video->prevVop->timeStamp)
1348 video->prevVop = video->prevEnhcVop;
1351 case 1 : /* most recently displayed base-layer vop */
1354 if (video->prevEnhcVop->timeStamp > video->prevVop->timeStamp)
1355 video->prevVop = video->prevEnhcVop;
1359 case 2 : /* next base-layer vop in display order */
1362 case 3 : /* temporally coincident base-layer vop (no MV's) */
1366 else /* we have a B-Vop */
1368 mp4dec_log("DecodeVideoFrame(): B-VOP not supported.\n");
1372 /* This is for the calculation of the frame rate and bitrate. */
1373 idx = ++video->frame_idx % BITRATE_AVERAGE_WINDOW;
1375 /* Calculate bitrate for this layer. 08/23/2000 */
1376 status = PV_DecodeVop(video);
1377 video->nBitsPerVop[idx] = getPointer(currVol->bitstream);
1378 video->prevTimestamp[idx] = currVop->timeStamp;
1380 /* restore video->prevVop after PV_DecodeVop(). 04/24/2001 */
1381 // if (currVop->refSelectCode == 0) video->prevVop = prevVop;
1382 video->prevVop = prevVop;
1384 /* Estimate the frame rate. 08/23/2000 */
1385 video->duration = video->prevTimestamp[idx];
1386 video->duration -= video->prevTimestamp[(++idx)%BITRATE_AVERAGE_WINDOW];
1387 if (video->duration > 0)
1388 { /* Only update framerate when the timestamp is right */
1389 video->frameRate = (int)(FRAMERATE_SCALE) / video->duration;
1392 /* We should always clear up bitstream buffer. 10/10/2000 */
1393 bytes_consumed = (getPointer(currVol->bitstream) + 7) >> 3; /* 11/4/03 */
1395 if (bytes_consumed > currVol->bitstream->data_end_pos)
1397 bytes_consumed = currVol->bitstream->data_end_pos;
1400 if (bytes_consumed < buffer_size[target_layer])
1402 /* If we only consume part of the bits in the buffer, take those */
1403 /* out. 04/24/2001 */
1404 /* oscl_memcpy(buffer[target_layer], buffer[target_layer]+bytes_consumed,
1405 (buffer_size[target_layer]-=bytes_consumed)); */
1406 buffer_size[target_layer] -= bytes_consumed;
1410 buffer_size[target_layer] = 0;
1415 return PV_FALSE; /* this will take care of concealment if we lose whole frame */
1417 case PV_END_OF_VOP :
1418 /* we may want to differenciate PV_END_OF_VOP and PV_SUCCESS */
1419 /* in the future. 05/10/2000 */
1422 /* Nohting is wrong :). */
1425 video->concealFrame = video->currVop->yChan; /* 07/07/2001 */
1427 video->vop_coding_type = video->currVop->predictionType; /* 07/09/01 */
1429 decCtrl->outputFrame = video->currVop->yChan;
1431 /* Swap VOP pointers. No enhc. frame oscl_memcpy() anymore! 04/24/2001 */
1434 tempVopPtr = video->prevEnhcVop;
1435 video->prevEnhcVop = video->currVop;
1436 video->currVop = tempVopPtr;
1440 tempVopPtr = video->prevVop;
1441 video->prevVop = video->currVop;
1442 video->currVop = tempVopPtr;
1447 /* This will never happen */
1454 #ifdef PV_MEMORY_POOL
1455 OSCL_EXPORT_REF void PVSetReferenceYUV(VideoDecControls *decCtrl, uint8 *YUV)
1457 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
1458 video->prevVop->yChan = (PIXEL *)YUV;
1459 video->prevVop->uChan = (PIXEL *)YUV + video->size;
1460 video->prevVop->vChan = (PIXEL *)video->prevVop->uChan + (decCtrl->size >> 2);
1461 oscl_memset(video->prevVop->yChan, 16, sizeof(uint8)*decCtrl->size); /* 10/31/01 */
1462 oscl_memset(video->prevVop->uChan, 128, sizeof(uint8)*decCtrl->size / 2);
1463 video->concealFrame = video->prevVop->yChan; /* 07/07/2001 */
1464 decCtrl->outputFrame = video->prevVop->yChan; /* 06/19/2002 */
1469 /* ======================================================================== */
1470 /* Function : VideoDecoderErrorDetected() */
1471 /* Date : 06/20/2000 */
1474 /* Return : This function will be called everytime an error int the */
1475 /* bitstream is detected. */
1478 /* ======================================================================== */
1479 uint VideoDecoderErrorDetected(VideoDecData *)
1481 /* This is only used for trapping bitstream error for debuging */
1488 /* ======================================================================== */
1489 /* Function : m4vdec_dprintf() */
1490 /* Date : 08/15/2000 */
1491 /* Purpose : This is a function that logs messages in the mpeg4 video */
1492 /* decoder. We can call the standard PacketVideo PVMessage */
1493 /* from inside this function if necessary. */
1496 /* Note : To turn on the logging, LOG_MP4DEC_MESSAGE must be defined */
1497 /* when compiling this file (only this file). */
1499 /* ======================================================================== */
1500 void m4vdec_dprintf(char *format, ...)
1504 va_start(args, format);
1506 /* open the log file */
1507 log_fp = fopen("\\mp4dec_log.txt", "a+");
1508 if (log_fp == NULL) return;
1509 /* output the message */
1510 vfprintf(log_fp, format, args);
1518 /* ======================================================================== */
1519 /* Function : IsIntraFrame() */
1520 /* Date : 05/29/2000 */
1523 /* Return : The most recently decoded frame is an Intra frame. */
1526 /* ======================================================================== */
1527 Bool IsIntraFrame(VideoDecControls *decCtrl)
1529 VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
1530 return (video->vop_coding_type == I_VOP);
1533 /* ======================================================================== */
1534 /* Function : PVDecPostProcess() */
1535 /* Date : 01/09/2002 */
1536 /* Purpose : PostProcess one video frame and return a YUV-12 image. */
1541 /* ======================================================================== */
1542 void PVDecPostProcess(VideoDecControls *decCtrl, uint8 *outputYUV)
1544 uint8 *outputBuffer;
1545 #ifdef PV_POSTPROC_ON
1546 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
1550 outputBuffer = outputYUV;
1554 if (video->postFilterType)
1556 outputBuffer = video->currVop->yChan;
1560 outputBuffer = decCtrl->outputFrame;
1564 if (video->postFilterType)
1566 /* Post-processing, */
1567 PostFilter(video, video->postFilterType, outputBuffer);
1573 /* Copy decoded frame to the output buffer. */
1574 tmpvar = (int32)video->width * video->height;
1575 oscl_memcpy(outputBuffer, decCtrl->outputFrame, tmpvar*3 / 2); /* 3/3/01 */
1579 outputBuffer = decCtrl->outputFrame;
1582 decCtrl->outputFrame = outputBuffer;
1587 /* ======================================================================== */
1588 /* Function : PVDecSetReference(VideoDecControls *decCtrl, uint8 *refYUV, */
1589 /* int32 timestamp) */
1590 /* Date : 07/22/2003 */
1591 /* Purpose : Get YUV reference frame from external source. */
1592 /* In/out : YUV 4-2-0 frame containing new reference frame in the same */
1593 /* : dimension as original, i.e., doesn't have to be multiple of 16 !!!. */
1597 /* ======================================================================== */
1598 Bool PVDecSetReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp)
1600 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
1601 Vop *prevVop = video->prevVop;
1602 int width = video->width;
1603 uint8 *dstPtr, *orgPtr, *dstPtr2, *orgPtr2;
1604 int32 size = (int32)width * video->height;
1607 /* set new parameters */
1608 prevVop->timeStamp = timestamp;
1609 prevVop->predictionType = I_VOP;
1611 dstPtr = prevVop->yChan;
1613 oscl_memcpy(dstPtr, orgPtr, size);
1614 dstPtr = prevVop->uChan;
1615 dstPtr2 = prevVop->vChan;
1616 orgPtr = refYUV + size;
1617 orgPtr2 = orgPtr + (size >> 2);
1618 oscl_memcpy(dstPtr, orgPtr, (size >> 2));
1619 oscl_memcpy(dstPtr2, orgPtr2, (size >> 2));
1621 video->concealFrame = video->prevVop->yChan;
1622 video->vop_coding_type = I_VOP;
1623 decCtrl->outputFrame = video->prevVop->yChan;
1628 /* ======================================================================== */
1629 /* Function : PVDecSetEnhReference(VideoDecControls *decCtrl, uint8 *refYUV, */
1630 /* int32 timestamp) */
1631 /* Date : 07/23/2003 */
1632 /* Purpose : Get YUV enhance reference frame from external source. */
1633 /* In/out : YUV 4-2-0 frame containing new reference frame in the same */
1634 /* : dimension as original, i.e., doesn't have to be multiple of 16 !!!. */
1638 /* ======================================================================== */
1639 Bool PVDecSetEnhReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp)
1641 VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
1642 Vop *prevEnhcVop = video->prevEnhcVop;
1643 uint8 *dstPtr, *orgPtr, *dstPtr2, *orgPtr2;
1644 int32 size = (int32) video->width * video->height;
1646 if (video->numberOfLayers <= 1)
1650 /* set new parameters */
1651 prevEnhcVop->timeStamp = timestamp;
1652 prevEnhcVop->predictionType = I_VOP;
1654 dstPtr = prevEnhcVop->yChan;
1656 oscl_memcpy(dstPtr, orgPtr, size);
1657 dstPtr = prevEnhcVop->uChan;
1658 dstPtr2 = prevEnhcVop->vChan;
1659 orgPtr = refYUV + size;
1660 orgPtr2 = orgPtr + (size >> 2);
1661 oscl_memcpy(dstPtr, orgPtr, (size >> 2));
1662 oscl_memcpy(dstPtr2, orgPtr2, (size >> 2));
1663 video->concealFrame = video->prevEnhcVop->yChan;
1664 video->vop_coding_type = I_VOP;
1665 decCtrl->outputFrame = video->prevEnhcVop->yChan;
1671 /* ======================================================================== */
1672 /* Function : PVGetVolInfo() */
1673 /* Date : 08/06/2003 */
1674 /* Purpose : Get the vol info(only base-layer). */
1678 /* Modified : 06/24/2004 */
1679 /* ======================================================================== */
1680 Bool PVGetVolInfo(VideoDecControls *decCtrl, VolInfo *pVolInfo)
1684 if (pVolInfo == NULL || decCtrl == NULL || decCtrl->videoDecoderData == NULL ||
1685 ((VideoDecData *)decCtrl->videoDecoderData)->vol[0] == NULL) return PV_FALSE;
1687 currVol = ((VideoDecData *)(decCtrl->videoDecoderData))->vol[0];
1690 pVolInfo->shortVideoHeader = (int32)((VideoDecData *)(decCtrl->videoDecoderData))->shortVideoHeader;
1691 pVolInfo->dataPartitioning = (int32)currVol->dataPartitioning;
1692 pVolInfo->errorResDisable = (int32)currVol->errorResDisable;
1693 pVolInfo->useReverseVLC = (int32)currVol->useReverseVLC;
1694 pVolInfo->scalability = (int32)currVol->scalability;
1695 pVolInfo->nbitsTimeIncRes = (int32)currVol->nbitsTimeIncRes;
1696 pVolInfo->profile_level_id = (int32)currVol->profile_level_id;