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