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