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