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