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