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