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