/H264Dec/source/H264SwDecApi.c

http://github.com/mbebenita/Broadway · C · 568 lines · 264 code · 89 blank · 215 comment · 49 complexity · 4afb44911d8c7a04a39e76fe51fed779 MD5 · raw file

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