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