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