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