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