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