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