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