summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.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/h264bsd_slice_data.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/h264bsd_slice_data.c')
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c354
1 files changed, 354 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c
new file mode 100755
index 0000000..c288d4b
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c
@@ -0,0 +1,354 @@
+/*
+ * 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
+ h264bsdDecodeSliceData
+ SetMbParams
+ h264bsdMarkSliceCorrupted
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_slice_data.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
+ i32 chromaQpIndexOffset);
+
+/*------------------------------------------------------------------------------
+
+ 5.1 Function name: h264bsdDecodeSliceData
+
+ Functional description:
+ Decode one slice. Function decodes stream data, i.e. macroblocks
+ and possible skip_run fields. h264bsdDecodeMacroblock function is
+ called to handle all other macroblock related processing.
+ Macroblock to slice group mapping is considered when next
+ macroblock to process is determined (h264bsdNextMbAddress function)
+ map
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pStorage pointer to storage structure
+ currImage pointer to current processed picture, needed for
+ intra prediction of the macroblocks
+ pSliceHeader pointer to slice header of the current slice
+
+ Outputs:
+ currImage processed macroblocks are written to current image
+ pStorage mbStorage structure of each processed macroblock
+ is updated here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceData(strmData_t *pStrmData, storage_t *pStorage,
+ image_t *currImage, sliceHeader_t *pSliceHeader)
+{
+
+/* Variables */
+
+ u8 mbData[384 + 15 + 32];
+ u8 *data;
+ u32 tmp;
+ u32 skipRun;
+ u32 prevSkipped;
+ u32 currMbAddr;
+ u32 moreMbs;
+ u32 mbCount;
+ i32 qpY;
+ macroblockLayer_t *mbLayer;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSliceHeader);
+ ASSERT(pStorage);
+ ASSERT(pSliceHeader->firstMbInSlice < pStorage->picSizeInMbs);
+
+ /* ensure 16-byte alignment */
+ data = (u8*)ALIGN(mbData, 16);
+
+ mbLayer = pStorage->mbLayer;
+
+ currMbAddr = pSliceHeader->firstMbInSlice;
+ skipRun = 0;
+ prevSkipped = HANTRO_FALSE;
+
+ /* increment slice index, will be one for decoding of the first slice of
+ * the picture */
+ pStorage->slice->sliceId++;
+
+ /* lastMbAddr stores address of the macroblock that was last successfully
+ * decoded, needed for error handling */
+ pStorage->slice->lastMbAddr = 0;
+
+ mbCount = 0;
+ /* initial quantization parameter for the slice is obtained as the sum of
+ * initial QP for the picture and sliceQpDelta for the current slice */
+ qpY = (i32)pStorage->activePps->picInitQp + pSliceHeader->sliceQpDelta;
+ do
+ {
+ /* primary picture and already decoded macroblock -> error */
+ if (!pSliceHeader->redundantPicCnt && pStorage->mb[currMbAddr].decoded)
+ {
+ EPRINT("Primary and already decoded");
+ return(HANTRO_NOK);
+ }
+
+ SetMbParams(pStorage->mb + currMbAddr, pSliceHeader,
+ pStorage->slice->sliceId, pStorage->activePps->chromaQpIndexOffset);
+
+ if (!IS_I_SLICE(pSliceHeader->sliceType))
+ {
+ if (!prevSkipped)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &skipRun);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* skip_run shall be less than or equal to number of
+ * macroblocks left */
+ if (skipRun > (pStorage->picSizeInMbs - currMbAddr))
+ {
+ EPRINT("skip_run");
+ return(HANTRO_NOK);
+ }
+ if (skipRun)
+ {
+ prevSkipped = HANTRO_TRUE;
+ H264SwDecMemset(&mbLayer->mbPred, 0, sizeof(mbPred_t));
+ /* mark current macroblock skipped */
+ mbLayer->mbType = P_Skip;
+ }
+ }
+ }
+
+ if (skipRun)
+ {
+ DEBUG(("Skipping macroblock %d\n", currMbAddr));
+ skipRun--;
+ }
+ else
+ {
+ prevSkipped = HANTRO_FALSE;
+ tmp = h264bsdDecodeMacroblockLayer(pStrmData, mbLayer,
+ pStorage->mb + currMbAddr, pSliceHeader->sliceType,
+ pSliceHeader->numRefIdxL0Active);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("macroblock_layer");
+ return(tmp);
+ }
+ }
+
+ tmp = h264bsdDecodeMacroblock(pStorage->mb + currMbAddr, mbLayer,
+ currImage, pStorage->dpb, &qpY, currMbAddr,
+ pStorage->activePps->constrainedIntraPredFlag, data);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("MACRO_BLOCK");
+ return(tmp);
+ }
+
+ /* increment macroblock count only for macroblocks that were decoded
+ * for the first time (redundant slices) */
+ if (pStorage->mb[currMbAddr].decoded == 1)
+ mbCount++;
+
+ /* keep on processing as long as there is stream data left or
+ * processing of macroblocks to be skipped based on the last skipRun is
+ * not finished */
+ moreMbs = (h264bsdMoreRbspData(pStrmData) || skipRun) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ /* lastMbAddr is only updated for intra slices (all macroblocks of
+ * inter slices will be lost in case of an error) */
+ if (IS_I_SLICE(pSliceHeader->sliceType))
+ pStorage->slice->lastMbAddr = currMbAddr;
+
+ currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
+ pStorage->picSizeInMbs, currMbAddr);
+ /* data left in the buffer but no more macroblocks for current slice
+ * group -> error */
+ if (moreMbs && !currMbAddr)
+ {
+ EPRINT("Next mb address");
+ return(HANTRO_NOK);
+ }
+
+ } while (moreMbs);
+
+ if ((pStorage->slice->numDecodedMbs + mbCount) > pStorage->picSizeInMbs)
+ {
+ EPRINT("Num decoded mbs");
+ return(HANTRO_NOK);
+ }
+
+ pStorage->slice->numDecodedMbs += mbCount;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.2 Function: SetMbParams
+
+ Functional description:
+ Set macroblock parameters that remain constant for this slice
+
+ Inputs:
+ pSlice pointer to current slice header
+ sliceId id of the current slice
+ chromaQpIndexOffset
+
+ Outputs:
+ pMb pointer to macroblock structure which is updated
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
+ i32 chromaQpIndexOffset)
+{
+
+/* Variables */
+ u32 tmp1;
+ i32 tmp2, tmp3;
+
+/* Code */
+
+ tmp1 = pSlice->disableDeblockingFilterIdc;
+ tmp2 = pSlice->sliceAlphaC0Offset;
+ tmp3 = pSlice->sliceBetaOffset;
+ pMb->sliceId = sliceId;
+ pMb->disableDeblockingFilterIdc = tmp1;
+ pMb->filterOffsetA = tmp2;
+ pMb->filterOffsetB = tmp3;
+ pMb->chromaQpIndexOffset = chromaQpIndexOffset;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.3 Function name: h264bsdMarkSliceCorrupted
+
+ Functional description:
+ Mark macroblocks of the slice corrupted. If lastMbAddr in the slice
+ storage is set -> picWidhtInMbs (or at least 10) macroblocks back
+ from the lastMbAddr are marked corrupted. However, if lastMbAddr
+ is not set -> all macroblocks of the slice are marked.
+
+ Inputs:
+ pStorage pointer to storage structure
+ firstMbInSlice address of the first macroblock in the slice, this
+ identifies the slice to be marked corrupted
+
+ Outputs:
+ pStorage mbStorage for the corrupted macroblocks updated
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdMarkSliceCorrupted(storage_t *pStorage, u32 firstMbInSlice)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+ u32 sliceId;
+ u32 currMbAddr;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(firstMbInSlice < pStorage->picSizeInMbs);
+
+ currMbAddr = firstMbInSlice;
+
+ sliceId = pStorage->slice->sliceId;
+
+ /* DecodeSliceData sets lastMbAddr for I slices -> if it was set, go back
+ * MAX(picWidthInMbs, 10) macroblocks and start marking from there */
+ if (pStorage->slice->lastMbAddr)
+ {
+ ASSERT(pStorage->mb[pStorage->slice->lastMbAddr].sliceId == sliceId);
+ i = pStorage->slice->lastMbAddr - 1;
+ tmp = 0;
+ while (i > currMbAddr)
+ {
+ if (pStorage->mb[i].sliceId == sliceId)
+ {
+ tmp++;
+ if (tmp >= MAX(pStorage->activeSps->picWidthInMbs, 10))
+ break;
+ }
+ i--;
+ }
+ currMbAddr = i;
+ }
+
+ do
+ {
+
+ if ( (pStorage->mb[currMbAddr].sliceId == sliceId) &&
+ (pStorage->mb[currMbAddr].decoded) )
+ {
+ pStorage->mb[currMbAddr].decoded--;
+ }
+ else
+ {
+ break;
+ }
+
+ currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
+ pStorage->picSizeInMbs, currMbAddr);
+
+ } while (currMbAddr);
+
+}
+