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