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