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