1 /* 2 * Copyright (C) 2009 The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /*------------------------------------------------------------------------------ 18 19 Table of contents 20 21 1. Include headers 22 2. External compiler flags 23 3. Module defines 24 4. Local function prototypes 25 5. Functions 26 H264SwDecInit 27 H264SwDecGetInfo 28 H264SwDecRelease 29 H264SwDecDecode 30 H264SwDecGetAPIVersion 31 H264SwDecNextPicture 32 33 ------------------------------------------------------------------------------*/ 34 35 /*------------------------------------------------------------------------------ 36 1. Include headers 37 ------------------------------------------------------------------------------*/ 38 #include <stdlib.h> 39 #include "basetype.h" 40 #include "h264bsd_container.h" 41 #include "H264SwDecApi.h" 42 #include "h264bsd_decoder.h" 43 #include "h264bsd_util.h" 44 45 #define UNUSED(x) (void)(x) 46 47 /*------------------------------------------------------------------------------ 48 Version Information 49 ------------------------------------------------------------------------------*/ 50 51 #define H264SWDEC_MAJOR_VERSION 2 52 #define H264SWDEC_MINOR_VERSION 3 53 54 /*------------------------------------------------------------------------------ 55 2. External compiler flags 56 -------------------------------------------------------------------------------- 57 58 H264DEC_TRACE Trace H264 Decoder API function calls. 59 H264DEC_EVALUATION Compile evaluation version, restricts number of frames 60 that can be decoded 61 62 -------------------------------------------------------------------------------- 63 3. Module defines 64 ------------------------------------------------------------------------------*/ 65 66 #ifdef H264DEC_TRACE 67 #include <stdio.h> 68 #define DEC_API_TRC(str) H264SwDecTrace(str) 69 #else 70 #define DEC_API_TRC(str) 71 #endif 72 73 #ifdef H264DEC_EVALUATION 74 #define H264DEC_EVALUATION_LIMIT 500 75 #endif 76 77 void H264SwDecTrace(char *string) { 78 UNUSED(string); 79 } 80 81 void* H264SwDecMalloc(u32 size) { 82 return malloc(size); 83 } 84 85 void H264SwDecFree(void *ptr) { 86 free(ptr); 87 } 88 89 void H264SwDecMemcpy(void *dest, void *src, u32 count) { 90 memcpy(dest, src, count); 91 } 92 93 void H264SwDecMemset(void *ptr, i32 value, u32 count) { 94 memset(ptr, value, count); 95 } 96 97 98 /*------------------------------------------------------------------------------ 99 100 Function: H264SwDecInit() 101 102 Functional description: 103 Initialize decoder software. Function reserves memory for the 104 decoder instance and calls h264bsdInit to initialize the 105 instance data. 106 107 Inputs: 108 noOutputReordering flag to indicate decoder that it doesn't have 109 to try to provide output pictures in display 110 order, saves memory 111 112 Outputs: 113 decInst pointer to initialized instance is stored here 114 115 Returns: 116 H264SWDEC_OK successfully initialized the instance 117 H264SWDEC_INITFAIL initialization failed 118 H264SWDEC_PARAM_ERR invalid parameters 119 H264SWDEC_MEM_FAIL memory allocation failed 120 121 ------------------------------------------------------------------------------*/ 122 123 H264SwDecRet H264SwDecInit(H264SwDecInst *decInst, u32 noOutputReordering) 124 { 125 u32 rv = 0; 126 127 decContainer_t *pDecCont; 128 129 DEC_API_TRC("H264SwDecInit#"); 130 131 /* check that right shift on negative numbers is performed signed */ 132 /*lint -save -e* following check causes multiple lint messages */ 133 if ( ((-1)>>1) != (-1) ) 134 { 135 DEC_API_TRC("H264SwDecInit# ERROR: Right shift is not signed"); 136 return(H264SWDEC_INITFAIL); 137 } 138 /*lint -restore */ 139 140 if (decInst == NULL) 141 { 142 DEC_API_TRC("H264SwDecInit# ERROR: decInst == NULL"); 143 return(H264SWDEC_PARAM_ERR); 144 } 145 146 pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t)); 147 148 if (pDecCont == NULL) 149 { 150 DEC_API_TRC("H264SwDecInit# ERROR: Memory allocation failed"); 151 return(H264SWDEC_MEMFAIL); 152 } 153 154 #ifdef H264DEC_TRACE 155 sprintf(pDecCont->str, "H264SwDecInit# decInst %p noOutputReordering %d", 156 (void*)decInst, noOutputReordering); 157 DEC_API_TRC(pDecCont->str); 158 #endif 159 160 rv = h264bsdInit(&pDecCont->storage, noOutputReordering); 161 if (rv != HANTRO_OK) 162 { 163 H264SwDecRelease(pDecCont); 164 return(H264SWDEC_MEMFAIL); 165 } 166 167 pDecCont->decStat = INITIALIZED; 168 pDecCont->picNumber = 0; 169 170 #ifdef H264DEC_TRACE 171 sprintf(pDecCont->str, "H264SwDecInit# OK: return %p", (void*)pDecCont); 172 DEC_API_TRC(pDecCont->str); 173 #endif 174 175 *decInst = (decContainer_t *)pDecCont; 176 177 return(H264SWDEC_OK); 178 179 } 180 181 /*------------------------------------------------------------------------------ 182 183 Function: H264SwDecGetInfo() 184 185 Functional description: 186 This function provides read access to decoder information. This 187 function should not be called before H264SwDecDecode function has 188 indicated that headers are ready. 189 190 Inputs: 191 decInst decoder instance 192 193 Outputs: 194 pDecInfo pointer to info struct where data is written 195 196 Returns: 197 H264SWDEC_OK success 198 H264SWDEC_PARAM_ERR invalid parameters 199 H264SWDEC_HDRS_NOT_RDY information not available yet 200 201 ------------------------------------------------------------------------------*/ 202 203 H264SwDecRet H264SwDecGetInfo(H264SwDecInst decInst, H264SwDecInfo *pDecInfo) 204 { 205 206 storage_t *pStorage; 207 208 DEC_API_TRC("H264SwDecGetInfo#"); 209 210 if (decInst == NULL || pDecInfo == NULL) 211 { 212 DEC_API_TRC("H264SwDecGetInfo# ERROR: decInst or pDecInfo is NULL"); 213 return(H264SWDEC_PARAM_ERR); 214 } 215 216 pStorage = &(((decContainer_t *)decInst)->storage); 217 218 if (pStorage->activeSps == NULL || pStorage->activePps == NULL) 219 { 220 DEC_API_TRC("H264SwDecGetInfo# ERROR: Headers not decoded yet"); 221 return(H264SWDEC_HDRS_NOT_RDY); 222 } 223 224 #ifdef H264DEC_TRACE 225 sprintf(((decContainer_t*)decInst)->str, 226 "H264SwDecGetInfo# decInst %p pDecInfo %p", decInst, (void*)pDecInfo); 227 DEC_API_TRC(((decContainer_t*)decInst)->str); 228 #endif 229 230 /* h264bsdPicWidth and -Height return dimensions in macroblock units, 231 * picWidth and -Height in pixels */ 232 pDecInfo->picWidth = h264bsdPicWidth(pStorage) << 4; 233 pDecInfo->picHeight = h264bsdPicHeight(pStorage) << 4; 234 pDecInfo->videoRange = h264bsdVideoRange(pStorage); 235 pDecInfo->matrixCoefficients = h264bsdMatrixCoefficients(pStorage); 236 237 h264bsdCroppingParams(pStorage, 238 &pDecInfo->croppingFlag, 239 &pDecInfo->cropParams.cropLeftOffset, 240 &pDecInfo->cropParams.cropOutWidth, 241 &pDecInfo->cropParams.cropTopOffset, 242 &pDecInfo->cropParams.cropOutHeight); 243 244 /* sample aspect ratio */ 245 h264bsdSampleAspectRatio(pStorage, 246 &pDecInfo->parWidth, 247 &pDecInfo->parHeight); 248 249 /* profile */ 250 pDecInfo->profile = h264bsdProfile(pStorage); 251 252 DEC_API_TRC("H264SwDecGetInfo# OK"); 253 254 return(H264SWDEC_OK); 255 256 } 257 258 /*------------------------------------------------------------------------------ 259 260 Function: H264SwDecRelease() 261 262 Functional description: 263 Release the decoder instance. Function calls h264bsdShutDown to 264 release instance data and frees the memory allocated for the 265 instance. 266 267 Inputs: 268 decInst Decoder instance 269 270 Outputs: 271 none 272 273 Returns: 274 none 275 276 ------------------------------------------------------------------------------*/ 277 278 void H264SwDecRelease(H264SwDecInst decInst) 279 { 280 281 decContainer_t *pDecCont; 282 283 DEC_API_TRC("H264SwDecRelease#"); 284 285 if (decInst == NULL) 286 { 287 DEC_API_TRC("H264SwDecRelease# ERROR: decInst == NULL"); 288 return; 289 } 290 291 pDecCont = (decContainer_t*)decInst; 292 293 #ifdef H264DEC_TRACE 294 sprintf(pDecCont->str, "H264SwDecRelease# decInst %p",decInst); 295 DEC_API_TRC(pDecCont->str); 296 #endif 297 298 h264bsdShutdown(&pDecCont->storage); 299 300 H264SwDecFree(pDecCont); 301 302 } 303 304 /*------------------------------------------------------------------------------ 305 306 Function: H264SwDecDecode 307 308 Functional description: 309 Decode stream data. Calls h264bsdDecode to do the actual decoding. 310 311 Input: 312 decInst decoder instance 313 pInput pointer to input struct 314 315 Outputs: 316 pOutput pointer to output struct 317 318 Returns: 319 H264SWDEC_NOT_INITIALIZED decoder instance not initialized yet 320 H264SWDEC_PARAM_ERR invalid parameters 321 322 H264SWDEC_STRM_PROCESSED stream buffer decoded 323 H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY headers decoded, 324 stream buffer not finished 325 H264SWDEC_PIC_RDY decoding of a picture finished 326 H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY decoding of a picture finished, 327 stream buffer not finished 328 H264SWDEC_STRM_ERR serious error in decoding, no 329 valid parameter sets available 330 to decode picture data 331 H264SWDEC_EVALUATION_LIMIT_EXCEEDED this can only occur when 332 evaluation version is used, 333 max number of frames reached 334 335 ------------------------------------------------------------------------------*/ 336 337 H264SwDecRet H264SwDecDecode(H264SwDecInst decInst, H264SwDecInput *pInput, 338 H264SwDecOutput *pOutput) 339 { 340 341 decContainer_t *pDecCont; 342 u32 strmLen; 343 u32 numReadBytes; 344 u8 *tmpStream; 345 u32 decResult = 0; 346 H264SwDecRet returnValue = H264SWDEC_STRM_PROCESSED; 347 348 DEC_API_TRC("H264SwDecDecode#"); 349 350 /* Check that function input parameters are valid */ 351 if (pInput == NULL || pOutput == NULL) 352 { 353 DEC_API_TRC("H264SwDecDecode# ERROR: pInput or pOutput is NULL"); 354 return(H264SWDEC_PARAM_ERR); 355 } 356 357 if ((pInput->pStream == NULL) || (pInput->dataLen == 0)) 358 { 359 DEC_API_TRC("H264SwDecDecode# ERROR: Invalid input parameters"); 360 return(H264SWDEC_PARAM_ERR); 361 } 362 363 pDecCont = (decContainer_t *)decInst; 364 365 /* Check if decoder is in an incorrect mode */ 366 if (decInst == NULL || pDecCont->decStat == UNINITIALIZED) 367 { 368 DEC_API_TRC("H264SwDecDecode# ERROR: Decoder not initialized"); 369 return(H264SWDEC_NOT_INITIALIZED); 370 } 371 372 #ifdef H264DEC_EVALUATION 373 if (pDecCont->picNumber >= H264DEC_EVALUATION_LIMIT) 374 return(H264SWDEC_EVALUATION_LIMIT_EXCEEDED); 375 #endif 376 377 #ifdef H264DEC_TRACE 378 sprintf(pDecCont->str, "H264SwDecDecode# decInst %p pInput %p pOutput %p", 379 decInst, (void*)pInput, (void*)pOutput); 380 DEC_API_TRC(pDecCont->str); 381 #endif 382 383 pOutput->pStrmCurrPos = NULL; 384 385 numReadBytes = 0; 386 strmLen = pInput->dataLen; 387 tmpStream = pInput->pStream; 388 pDecCont->storage.intraConcealmentFlag = pInput->intraConcealmentMethod; 389 390 do 391 { 392 /* Return HDRS_RDY after DPB flush caused by new SPS */ 393 if (pDecCont->decStat == NEW_HEADERS) 394 { 395 decResult = H264BSD_HDRS_RDY; 396 pDecCont->decStat = INITIALIZED; 397 } 398 else /* Continue decoding normally */ 399 { 400 decResult = h264bsdDecode(&pDecCont->storage, tmpStream, strmLen, 401 pInput->picId, &numReadBytes); 402 } 403 tmpStream += numReadBytes; 404 /* check if too many bytes are read from stream */ 405 if ( (i32)(strmLen - numReadBytes) >= 0 ) 406 strmLen -= numReadBytes; 407 else 408 strmLen = 0; 409 410 pOutput->pStrmCurrPos = tmpStream; 411 412 switch (decResult) 413 { 414 case H264BSD_HDRS_RDY: 415 416 if(pDecCont->storage.dpb->flushed && 417 pDecCont->storage.dpb->numOut != 418 pDecCont->storage.dpb->outIndex) 419 { 420 /* output first all DPB stored pictures 421 * DPB flush caused by new SPS */ 422 pDecCont->storage.dpb->flushed = 0; 423 pDecCont->decStat = NEW_HEADERS; 424 returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY; 425 strmLen = 0; 426 } 427 else 428 { 429 returnValue = H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY; 430 strmLen = 0; 431 } 432 break; 433 434 case H264BSD_PIC_RDY: 435 pDecCont->picNumber++; 436 437 if (strmLen == 0) 438 returnValue = H264SWDEC_PIC_RDY; 439 else 440 returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY; 441 442 strmLen = 0; 443 break; 444 445 case H264BSD_PARAM_SET_ERROR: 446 if ( !h264bsdCheckValidParamSets(&pDecCont->storage) && 447 strmLen == 0 ) 448 { 449 returnValue = H264SWDEC_STRM_ERR; 450 } 451 break; 452 case H264BSD_MEMALLOC_ERROR: 453 { 454 returnValue = H264SWDEC_MEMFAIL; 455 strmLen = 0; 456 } 457 break; 458 default: 459 break; 460 } 461 462 } while (strmLen); 463 464 #ifdef H264DEC_TRACE 465 sprintf(pDecCont->str, "H264SwDecDecode# OK: DecResult %d", 466 returnValue); 467 DEC_API_TRC(pDecCont->str); 468 #endif 469 470 return(returnValue); 471 472 } 473 474 /*------------------------------------------------------------------------------ 475 476 Function: H264SwDecGetAPIVersion 477 478 Functional description: 479 Return version information of the API 480 481 Inputs: 482 none 483 484 Outputs: 485 none 486 487 Returns: 488 API version 489 490 ------------------------------------------------------------------------------*/ 491 492 H264SwDecApiVersion H264SwDecGetAPIVersion() 493 { 494 H264SwDecApiVersion ver; 495 496 ver.major = H264SWDEC_MAJOR_VERSION; 497 ver.minor = H264SWDEC_MINOR_VERSION; 498 499 return(ver); 500 } 501 502 /*------------------------------------------------------------------------------ 503 504 Function: H264SwDecNextPicture 505 506 Functional description: 507 Get next picture in display order if any available. 508 509 Input: 510 decInst decoder instance. 511 flushBuffer force output of all buffered pictures 512 513 Output: 514 pOutput pointer to output structure 515 516 Returns: 517 H264SWDEC_OK no pictures available for display 518 H264SWDEC_PIC_RDY picture available for display 519 H264SWDEC_PARAM_ERR invalid parameters 520 521 ------------------------------------------------------------------------------*/ 522 523 H264SwDecRet H264SwDecNextPicture(H264SwDecInst decInst, 524 H264SwDecPicture *pOutput, u32 flushBuffer) 525 { 526 527 decContainer_t *pDecCont; 528 u32 numErrMbs, isIdrPic, picId; 529 u32 *pOutPic; 530 531 DEC_API_TRC("H264SwDecNextPicture#"); 532 533 if (decInst == NULL || pOutput == NULL) 534 { 535 DEC_API_TRC("H264SwDecNextPicture# ERROR: decInst or pOutput is NULL"); 536 return(H264SWDEC_PARAM_ERR); 537 } 538 539 pDecCont = (decContainer_t*)decInst; 540 541 #ifdef H264DEC_TRACE 542 sprintf(pDecCont->str, "H264SwDecNextPicture# decInst %p pOutput %p %s %d", 543 decInst, (void*)pOutput, "flushBuffer", flushBuffer); 544 DEC_API_TRC(pDecCont->str); 545 #endif 546 547 if (flushBuffer) 548 h264bsdFlushBuffer(&pDecCont->storage); 549 550 pOutPic = (u32*)h264bsdNextOutputPicture(&pDecCont->storage, &picId, 551 &isIdrPic, &numErrMbs); 552 553 if (pOutPic == NULL) 554 { 555 DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_OK"); 556 return(H264SWDEC_OK); 557 } 558 else 559 { 560 pOutput->pOutputPicture = pOutPic; 561 pOutput->picId = picId; 562 pOutput->isIdrPicture = isIdrPic; 563 pOutput->nbrOfErrMBs = numErrMbs; 564 DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_PIC_RDY"); 565 return(H264SWDEC_PIC_RDY); 566 } 567 568 } 569 570 571