/H264Dec/source/h264bsd_slice_data.c
C | 354 lines | 162 code | 52 blank | 140 comment | 30 complexity | 3dafa2e8dd475a053752471afe408199 MD5 | raw file
Possible License(s): BSD-3-Clause
- /*
- * 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);
- }