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