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