summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2011-05-31 18:53:46 -0700
committerJames Dong <jdong@google.com>2011-06-02 12:32:46 -0700
commit0c1bc742181ded4930842b46e9507372f0b1b963 (patch)
treec952bfcb03ff7cce5e0f91ad7d25c67a2fdd39cb /media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
parent92a746c3b18d035189f596ce32847bf26247aaca (diff)
downloadframeworks_av-0c1bc742181ded4930842b46e9507372f0b1b963.zip
frameworks_av-0c1bc742181ded4930842b46e9507372f0b1b963.tar.gz
frameworks_av-0c1bc742181ded4930842b46e9507372f0b1b963.tar.bz2
Initial-checkin for ON2 Software AVC/H264 decoder
o when neon is present, the performance gain of On2 AVC software decoder over PV software decoder is more than 30%. o In addition, it fixes some known PV software decoder issues like missing output frames o allow both pv and on2 software avc to be available for easy comparision o change output frames from 8 to 16 Change-Id: I567ad1842025ead7092f0c47e3513d6d9ca232dd
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c')
-rw-r--r--media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c567
1 files changed, 567 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
new file mode 100644
index 0000000..2bb4c4d
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ H264SwDecInit
+ H264SwDecGetInfo
+ H264SwDecRelease
+ H264SwDecDecode
+ H264SwDecGetAPIVersion
+ H264SwDecNextPicture
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+#include <stdlib.h>
+#include "basetype.h"
+#include "h264bsd_container.h"
+#include "H264SwDecApi.h"
+#include "h264bsd_decoder.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ Version Information
+------------------------------------------------------------------------------*/
+
+#define H264SWDEC_MAJOR_VERSION 2
+#define H264SWDEC_MINOR_VERSION 3
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+H264DEC_TRACE Trace H264 Decoder API function calls.
+H264DEC_EVALUATION Compile evaluation version, restricts number of frames
+ that can be decoded
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+#ifdef H264DEC_TRACE
+#include <stdio.h>
+#define DEC_API_TRC(str) H264SwDecTrace(str)
+#else
+#define DEC_API_TRC(str)
+#endif
+
+#ifdef H264DEC_EVALUATION
+#define H264DEC_EVALUATION_LIMIT 500
+#endif
+
+void H264SwDecTrace(char *string) {
+}
+
+void* H264SwDecMalloc(u32 size) {
+ return malloc(size);
+}
+
+void H264SwDecFree(void *ptr) {
+ free(ptr);
+}
+
+void H264SwDecMemcpy(void *dest, void *src, u32 count) {
+ memcpy(dest, src, count);
+}
+
+void H264SwDecMemset(void *ptr, i32 value, u32 count) {
+ memset(ptr, value, count);
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecInit()
+
+ Functional description:
+ Initialize decoder software. Function reserves memory for the
+ decoder instance and calls h264bsdInit to initialize the
+ instance data.
+
+ Inputs:
+ noOutputReordering flag to indicate decoder that it doesn't have
+ to try to provide output pictures in display
+ order, saves memory
+
+ Outputs:
+ decInst pointer to initialized instance is stored here
+
+ Returns:
+ H264SWDEC_OK successfully initialized the instance
+ H264SWDEC_INITFAIL initialization failed
+ H264SWDEC_PARAM_ERR invalid parameters
+ H264SWDEC_MEM_FAIL memory allocation failed
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecInit(H264SwDecInst *decInst, u32 noOutputReordering)
+{
+ u32 rv = 0;
+
+ decContainer_t *pDecCont;
+
+ DEC_API_TRC("H264SwDecInit#");
+
+ /* check that right shift on negative numbers is performed signed */
+ /*lint -save -e* following check causes multiple lint messages */
+ if ( ((-1)>>1) != (-1) )
+ {
+ DEC_API_TRC("H264SwDecInit# ERROR: Right shift is not signed");
+ return(H264SWDEC_INITFAIL);
+ }
+ /*lint -restore */
+
+ if (decInst == NULL)
+ {
+ DEC_API_TRC("H264SwDecInit# ERROR: decInst == NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t));
+
+ if (pDecCont == NULL)
+ {
+ DEC_API_TRC("H264SwDecInit# ERROR: Memory allocation failed");
+ return(H264SWDEC_MEMFAIL);
+ }
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecInit# decInst %p noOutputReordering %d",
+ (void*)decInst, noOutputReordering);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ rv = h264bsdInit(&pDecCont->storage, noOutputReordering);
+ if (rv != HANTRO_OK)
+ {
+ H264SwDecRelease(pDecCont);
+ return(H264SWDEC_MEMFAIL);
+ }
+
+ pDecCont->decStat = INITIALIZED;
+ pDecCont->picNumber = 0;
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecInit# OK: return %p", (void*)pDecCont);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ *decInst = (decContainer_t *)pDecCont;
+
+ return(H264SWDEC_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecGetInfo()
+
+ Functional description:
+ This function provides read access to decoder information. This
+ function should not be called before H264SwDecDecode function has
+ indicated that headers are ready.
+
+ Inputs:
+ decInst decoder instance
+
+ Outputs:
+ pDecInfo pointer to info struct where data is written
+
+ Returns:
+ H264SWDEC_OK success
+ H264SWDEC_PARAM_ERR invalid parameters
+ H264SWDEC_HDRS_NOT_RDY information not available yet
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecGetInfo(H264SwDecInst decInst, H264SwDecInfo *pDecInfo)
+{
+
+ storage_t *pStorage;
+
+ DEC_API_TRC("H264SwDecGetInfo#");
+
+ if (decInst == NULL || pDecInfo == NULL)
+ {
+ DEC_API_TRC("H264SwDecGetInfo# ERROR: decInst or pDecInfo is NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pStorage = &(((decContainer_t *)decInst)->storage);
+
+ if (pStorage->activeSps == NULL || pStorage->activePps == NULL)
+ {
+ DEC_API_TRC("H264SwDecGetInfo# ERROR: Headers not decoded yet");
+ return(H264SWDEC_HDRS_NOT_RDY);
+ }
+
+#ifdef H264DEC_TRACE
+ sprintf(((decContainer_t*)decInst)->str,
+ "H264SwDecGetInfo# decInst %p pDecInfo %p", decInst, (void*)pDecInfo);
+ DEC_API_TRC(((decContainer_t*)decInst)->str);
+#endif
+
+ /* h264bsdPicWidth and -Height return dimensions in macroblock units,
+ * picWidth and -Height in pixels */
+ pDecInfo->picWidth = h264bsdPicWidth(pStorage) << 4;
+ pDecInfo->picHeight = h264bsdPicHeight(pStorage) << 4;
+ pDecInfo->videoRange = h264bsdVideoRange(pStorage);
+ pDecInfo->matrixCoefficients = h264bsdMatrixCoefficients(pStorage);
+
+ h264bsdCroppingParams(pStorage,
+ &pDecInfo->croppingFlag,
+ &pDecInfo->cropParams.cropLeftOffset,
+ &pDecInfo->cropParams.cropOutWidth,
+ &pDecInfo->cropParams.cropTopOffset,
+ &pDecInfo->cropParams.cropOutHeight);
+
+ /* sample aspect ratio */
+ h264bsdSampleAspectRatio(pStorage,
+ &pDecInfo->parWidth,
+ &pDecInfo->parHeight);
+
+ /* profile */
+ pDecInfo->profile = h264bsdProfile(pStorage);
+
+ DEC_API_TRC("H264SwDecGetInfo# OK");
+
+ return(H264SWDEC_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecRelease()
+
+ Functional description:
+ Release the decoder instance. Function calls h264bsdShutDown to
+ release instance data and frees the memory allocated for the
+ instance.
+
+ Inputs:
+ decInst Decoder instance
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void H264SwDecRelease(H264SwDecInst decInst)
+{
+
+ decContainer_t *pDecCont;
+
+ DEC_API_TRC("H264SwDecRelease#");
+
+ if (decInst == NULL)
+ {
+ DEC_API_TRC("H264SwDecRelease# ERROR: decInst == NULL");
+ return;
+ }
+
+ pDecCont = (decContainer_t*)decInst;
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecRelease# decInst %p",decInst);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ h264bsdShutdown(&pDecCont->storage);
+
+ H264SwDecFree(pDecCont);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecDecode
+
+ Functional description:
+ Decode stream data. Calls h264bsdDecode to do the actual decoding.
+
+ Input:
+ decInst decoder instance
+ pInput pointer to input struct
+
+ Outputs:
+ pOutput pointer to output struct
+
+ Returns:
+ H264SWDEC_NOT_INITIALIZED decoder instance not initialized yet
+ H264SWDEC_PARAM_ERR invalid parameters
+
+ H264SWDEC_STRM_PROCESSED stream buffer decoded
+ H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY headers decoded,
+ stream buffer not finished
+ H264SWDEC_PIC_RDY decoding of a picture finished
+ H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY decoding of a picture finished,
+ stream buffer not finished
+ H264SWDEC_STRM_ERR serious error in decoding, no
+ valid parameter sets available
+ to decode picture data
+ H264SWDEC_EVALUATION_LIMIT_EXCEEDED this can only occur when
+ evaluation version is used,
+ max number of frames reached
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecDecode(H264SwDecInst decInst, H264SwDecInput *pInput,
+ H264SwDecOutput *pOutput)
+{
+
+ decContainer_t *pDecCont;
+ u32 strmLen;
+ u32 numReadBytes;
+ u8 *tmpStream;
+ u32 decResult = 0;
+ H264SwDecRet returnValue = H264SWDEC_STRM_PROCESSED;
+
+ DEC_API_TRC("H264SwDecDecode#");
+
+ /* Check that function input parameters are valid */
+ if (pInput == NULL || pOutput == NULL)
+ {
+ DEC_API_TRC("H264SwDecDecode# ERROR: pInput or pOutput is NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ if ((pInput->pStream == NULL) || (pInput->dataLen == 0))
+ {
+ DEC_API_TRC("H264SwDecDecode# ERROR: Invalid input parameters");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pDecCont = (decContainer_t *)decInst;
+
+ /* Check if decoder is in an incorrect mode */
+ if (decInst == NULL || pDecCont->decStat == UNINITIALIZED)
+ {
+ DEC_API_TRC("H264SwDecDecode# ERROR: Decoder not initialized");
+ return(H264SWDEC_NOT_INITIALIZED);
+ }
+
+#ifdef H264DEC_EVALUATION
+ if (pDecCont->picNumber >= H264DEC_EVALUATION_LIMIT)
+ return(H264SWDEC_EVALUATION_LIMIT_EXCEEDED);
+#endif
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecDecode# decInst %p pInput %p pOutput %p",
+ decInst, (void*)pInput, (void*)pOutput);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ pOutput->pStrmCurrPos = NULL;
+
+ numReadBytes = 0;
+ strmLen = pInput->dataLen;
+ tmpStream = pInput->pStream;
+ pDecCont->storage.intraConcealmentFlag = pInput->intraConcealmentMethod;
+
+ do
+ {
+ /* Return HDRS_RDY after DPB flush caused by new SPS */
+ if (pDecCont->decStat == NEW_HEADERS)
+ {
+ decResult = H264BSD_HDRS_RDY;
+ pDecCont->decStat = INITIALIZED;
+ }
+ else /* Continue decoding normally */
+ {
+ decResult = h264bsdDecode(&pDecCont->storage, tmpStream, strmLen,
+ pInput->picId, &numReadBytes);
+ }
+ tmpStream += numReadBytes;
+ /* check if too many bytes are read from stream */
+ if ( (i32)(strmLen - numReadBytes) >= 0 )
+ strmLen -= numReadBytes;
+ else
+ strmLen = 0;
+
+ pOutput->pStrmCurrPos = tmpStream;
+
+ switch (decResult)
+ {
+ case H264BSD_HDRS_RDY:
+
+ if(pDecCont->storage.dpb->flushed &&
+ pDecCont->storage.dpb->numOut !=
+ pDecCont->storage.dpb->outIndex)
+ {
+ /* output first all DPB stored pictures
+ * DPB flush caused by new SPS */
+ pDecCont->storage.dpb->flushed = 0;
+ pDecCont->decStat = NEW_HEADERS;
+ returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY;
+ strmLen = 0;
+ }
+ else
+ {
+ returnValue = H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY;
+ strmLen = 0;
+ }
+ break;
+
+ case H264BSD_PIC_RDY:
+ pDecCont->picNumber++;
+
+ if (strmLen == 0)
+ returnValue = H264SWDEC_PIC_RDY;
+ else
+ returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY;
+
+ strmLen = 0;
+ break;
+
+ case H264BSD_PARAM_SET_ERROR:
+ if ( !h264bsdCheckValidParamSets(&pDecCont->storage) &&
+ strmLen == 0 )
+ {
+ returnValue = H264SWDEC_STRM_ERR;
+ }
+ break;
+ case H264BSD_MEMALLOC_ERROR:
+ {
+ returnValue = H264SWDEC_MEMFAIL;
+ strmLen = 0;
+ }
+ break;
+ default:
+ break;
+ }
+
+ } while (strmLen);
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecDecode# OK: DecResult %d",
+ returnValue);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ return(returnValue);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecGetAPIVersion
+
+ Functional description:
+ Return version information of the API
+
+ Inputs:
+ none
+
+ Outputs:
+ none
+
+ Returns:
+ API version
+
+------------------------------------------------------------------------------*/
+
+H264SwDecApiVersion H264SwDecGetAPIVersion()
+{
+ H264SwDecApiVersion ver;
+
+ ver.major = H264SWDEC_MAJOR_VERSION;
+ ver.minor = H264SWDEC_MINOR_VERSION;
+
+ return(ver);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: H264SwDecNextPicture
+
+ Functional description:
+ Get next picture in display order if any available.
+
+ Input:
+ decInst decoder instance.
+ flushBuffer force output of all buffered pictures
+
+ Output:
+ pOutput pointer to output structure
+
+ Returns:
+ H264SWDEC_OK no pictures available for display
+ H264SWDEC_PIC_RDY picture available for display
+ H264SWDEC_PARAM_ERR invalid parameters
+
+------------------------------------------------------------------------------*/
+
+H264SwDecRet H264SwDecNextPicture(H264SwDecInst decInst,
+ H264SwDecPicture *pOutput, u32 flushBuffer)
+{
+
+ decContainer_t *pDecCont;
+ u32 numErrMbs, isIdrPic, picId;
+ u32 *pOutPic;
+
+ DEC_API_TRC("H264SwDecNextPicture#");
+
+ if (decInst == NULL || pOutput == NULL)
+ {
+ DEC_API_TRC("H264SwDecNextPicture# ERROR: decInst or pOutput is NULL");
+ return(H264SWDEC_PARAM_ERR);
+ }
+
+ pDecCont = (decContainer_t*)decInst;
+
+#ifdef H264DEC_TRACE
+ sprintf(pDecCont->str, "H264SwDecNextPicture# decInst %p pOutput %p %s %d",
+ decInst, (void*)pOutput, "flushBuffer", flushBuffer);
+ DEC_API_TRC(pDecCont->str);
+#endif
+
+ if (flushBuffer)
+ h264bsdFlushBuffer(&pDecCont->storage);
+
+ pOutPic = (u32*)h264bsdNextOutputPicture(&pDecCont->storage, &picId,
+ &isIdrPic, &numErrMbs);
+
+ if (pOutPic == NULL)
+ {
+ DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_OK");
+ return(H264SWDEC_OK);
+ }
+ else
+ {
+ pOutput->pOutputPicture = pOutPic;
+ pOutput->picId = picId;
+ pOutput->isIdrPicture = isIdrPic;
+ pOutput->nbrOfErrMBs = numErrMbs;
+ DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_PIC_RDY");
+ return(H264SWDEC_PIC_RDY);
+ }
+
+}
+
+