/* * Copyright (C) 2009 The Android Open Source Project * Modified for use by h264bsd standalone library * * 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 h264bsdDecodeSliceHeader NumSliceGroupChangeCycleBits RefPicListReordering DecRefPicMarking CheckPpsId CheckFrameNum CheckIdrPicId CheckPicOrderCntLsb CheckDeltaPicOrderCntBottom CheckDeltaPicOrderCnt CheckRedundantPicCnt ------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------ 1. Include headers------------------------------------------------------------------------------*/ #include "h264bsd_slice_header.h"#include "h264bsd_util.h"#include "h264bsd_vlc.h"#include "h264bsd_nal_unit.h"#include "h264bsd_dpb.h" /*------------------------------------------------------------------------------ 2. External compiler flags-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- 3. Module defines------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------ 4. Local function prototypes------------------------------------------------------------------------------*/ static u32 RefPicListReordering(strmData_t *, refPicListReordering_t *, u32, u32); static u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs, u32 sliceGroupChangeRate); static u32 DecRefPicMarking(strmData_t *pStrmData, decRefPicMarking_t *pDecRefPicMarking, nalUnitType_e nalUnitType, u32 numRefFrames); /*------------------------------------------------------------------------------ Function name: h264bsdDecodeSliceHeader Functional description: Decode slice header data from the stream. Inputs: pStrmData pointer to stream data structure pSeqParamSet pointer to active sequence parameter set pPicParamSet pointer to active picture parameter set pNalUnit pointer to current NAL unit structure Outputs: pSliceHeader decoded data is stored here Returns: HANTRO_OK success HANTRO_NOK invalid stream data or end of stream ------------------------------------------------------------------------------*/ u32 h264bsdDecodeSliceHeader(strmData_t *pStrmData, sliceHeader_t *pSliceHeader, seqParamSet_t *pSeqParamSet, picParamSet_t *pPicParamSet, nalUnit_t *pNalUnit){ /* Variables */ u32 tmp, i, value; i32 itmp; u32 picSizeInMbs; /* Code */ ASSERT(pStrmData); ASSERT(pSliceHeader); ASSERT(pSeqParamSet); ASSERT(pPicParamSet); ASSERT( pNalUnit->nalUnitType == NAL_CODED_SLICE || pNalUnit->nalUnitType == NAL_CODED_SLICE_IDR ); memset(pSliceHeader, 0, sizeof(sliceHeader_t)); picSizeInMbs = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs; tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->firstMbInSlice = value; if (value >= picSizeInMbs) { EPRINT("first_mb_in_slice"); return(HANTRO_NOK); } tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->sliceType = value; /* slice type has to be either I or P slice. P slice is not allowed when * current NAL unit is an IDR NAL unit or num_ref_frames is 0 */ if ( !IS_I_SLICE(pSliceHeader->sliceType) && ( !IS_P_SLICE(pSliceHeader->sliceType) || IS_IDR_NAL_UNIT(pNalUnit) || !pSeqParamSet->numRefFrames ) ) { EPRINT("slice_type"); return(HANTRO_NOK); } tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->picParameterSetId = value; if (pSliceHeader->picParameterSetId != pPicParamSet->picParameterSetId) { EPRINT("pic_parameter_set_id"); return(HANTRO_NOK); } /* log2(maxFrameNum) -> num bits to represent frame_num */ i = 0; while (pSeqParamSet->maxFrameNum >> i) i++; i--; tmp = h264bsdGetBits(pStrmData, i); if (tmp == END_OF_STREAM) return(HANTRO_NOK); if (IS_IDR_NAL_UNIT(pNalUnit) && tmp != 0) { EPRINT("frame_num"); return(HANTRO_NOK); } pSliceHeader->frameNum = tmp; if (IS_IDR_NAL_UNIT(pNalUnit)) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->idrPicId = value; if (value > 65535) { EPRINT("idr_pic_id"); return(HANTRO_NOK); } } if (pSeqParamSet->picOrderCntType == 0) { /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */ i = 0; while (pSeqParamSet->maxPicOrderCntLsb >> i) i++; i--; tmp = h264bsdGetBits(pStrmData, i); if (tmp == END_OF_STREAM) return(HANTRO_NOK); pSliceHeader->picOrderCntLsb = tmp; if (pPicParamSet->picOrderPresentFlag) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->deltaPicOrderCntBottom = itmp; } /* check that picOrderCnt for IDR picture will be zero. See * DecodePicOrderCnt function to understand the logic here */ if ( IS_IDR_NAL_UNIT(pNalUnit) && ( (pSliceHeader->picOrderCntLsb > pSeqParamSet->maxPicOrderCntLsb/2) || MIN((i32)pSliceHeader->picOrderCntLsb, (i32)pSliceHeader->picOrderCntLsb + pSliceHeader->deltaPicOrderCntBottom) != 0 ) ) { return(HANTRO_NOK); } } if ( (pSeqParamSet->picOrderCntType == 1) && !pSeqParamSet->deltaPicOrderAlwaysZeroFlag ) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->deltaPicOrderCnt[0] = itmp; if (pPicParamSet->picOrderPresentFlag) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->deltaPicOrderCnt[1] = itmp; } /* check that picOrderCnt for IDR picture will be zero. See * DecodePicOrderCnt function to understand the logic here */ if ( IS_IDR_NAL_UNIT(pNalUnit) && MIN(pSliceHeader->deltaPicOrderCnt[0], pSliceHeader->deltaPicOrderCnt[0] + pSeqParamSet->offsetForTopToBottomField + pSliceHeader->deltaPicOrderCnt[1]) != 0) { return(HANTRO_NOK); } } if (pPicParamSet->redundantPicCntPresentFlag) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->redundantPicCnt = value; if (value > 127) { EPRINT("redundant_pic_cnt"); return(HANTRO_NOK); } } if (IS_P_SLICE(pSliceHeader->sliceType)) { tmp = h264bsdGetBits(pStrmData, 1); if (tmp == END_OF_STREAM) return(HANTRO_NOK); pSliceHeader->numRefIdxActiveOverrideFlag = tmp; if (pSliceHeader->numRefIdxActiveOverrideFlag) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); if (value > 15) { EPRINT("num_ref_idx_l0_active_minus1"); return(HANTRO_NOK); } pSliceHeader->numRefIdxL0Active = value + 1; } /* set numRefIdxL0Active from pic param set */ else { /* if value (minus1) in picture parameter set exceeds 15 it should * have been overridden here */ if (pPicParamSet->numRefIdxL0Active > 16) { EPRINT("num_ref_idx_active_override_flag"); return(HANTRO_NOK); } pSliceHeader->numRefIdxL0Active = pPicParamSet->numRefIdxL0Active; } } if (IS_P_SLICE(pSliceHeader->sliceType)) { tmp = RefPicListReordering(pStrmData, &pSliceHeader->refPicListReordering, pSliceHeader->numRefIdxL0Active, pSeqParamSet->maxFrameNum); if (tmp != HANTRO_OK) return(tmp); } if (pNalUnit->nalRefIdc != 0) { tmp = DecRefPicMarking(pStrmData, &pSliceHeader->decRefPicMarking, pNalUnit->nalUnitType, pSeqParamSet->numRefFrames); if (tmp != HANTRO_OK) return(tmp); } /* decode sliceQpDelta and check that initial QP for the slice will be on * the range [0, 51] */ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->sliceQpDelta = itmp; itmp += (i32)pPicParamSet->picInitQp; if ( (itmp < 0) || (itmp > 51) ) { EPRINT("slice_qp_delta"); return(HANTRO_NOK); } if (pPicParamSet->deblockingFilterControlPresentFlag) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->disableDeblockingFilterIdc = value; if (pSliceHeader->disableDeblockingFilterIdc > 2) { EPRINT("disable_deblocking_filter_idc"); return(HANTRO_NOK); } if (pSliceHeader->disableDeblockingFilterIdc != 1) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); if ( (itmp < -6) || (itmp > 6) ) { EPRINT("slice_alpha_c0_offset_div2"); return(HANTRO_NOK); } pSliceHeader->sliceAlphaC0Offset = itmp * 2; tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); if ( (itmp < -6) || (itmp > 6) ) { EPRINT("slice_beta_offset_div2"); return(HANTRO_NOK); } pSliceHeader->sliceBetaOffset = itmp * 2; } } if ( (pPicParamSet->numSliceGroups > 1) && (pPicParamSet->sliceGroupMapType >= 3) && (pPicParamSet->sliceGroupMapType <= 5) ) { /* set tmp to number of bits used to represent slice_group_change_cycle * in the stream */ tmp = NumSliceGroupChangeCycleBits(picSizeInMbs, pPicParamSet->sliceGroupChangeRate); value = h264bsdGetBits(pStrmData, tmp); if (value == END_OF_STREAM) return(HANTRO_NOK); pSliceHeader->sliceGroupChangeCycle = value; /* corresponds to tmp = Ceil(picSizeInMbs / sliceGroupChangeRate) */ tmp = (picSizeInMbs + pPicParamSet->sliceGroupChangeRate - 1) / pPicParamSet->sliceGroupChangeRate; if (pSliceHeader->sliceGroupChangeCycle > tmp) { EPRINT("slice_group_change_cycle"); return(HANTRO_NOK); } } return(HANTRO_OK); } /*------------------------------------------------------------------------------ Function: NumSliceGroupChangeCycleBits Functional description: Determine number of bits needed to represent slice_group_change_cycle in the stream. The standard states that slice_group_change_cycle is represented by Ceil( Log2( (picSizeInMbs / sliceGroupChangeRate) + 1) ) bits. Division "/" in the equation is non-truncating division. Inputs: picSizeInMbs picture size in macroblocks sliceGroupChangeRate Outputs: none Returns: number of bits needed ------------------------------------------------------------------------------*/ static u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs, u32 sliceGroupChangeRate){ /* Variables */ u32 tmp,numBits,mask; /* Code */ ASSERT(picSizeInMbs); ASSERT(sliceGroupChangeRate); ASSERT(sliceGroupChangeRate <= picSizeInMbs); /* compute (picSizeInMbs / sliceGroupChangeRate + 1), rounded up */ if (picSizeInMbs % sliceGroupChangeRate) tmp = 2 + picSizeInMbs/sliceGroupChangeRate; else tmp = 1 + picSizeInMbs/sliceGroupChangeRate; numBits = 0; mask = ~0U; /* set numBits to position of right-most non-zero bit */ while (tmp & (mask<<++numBits)) ; numBits--; /* add one more bit if value greater than 2^numBits */ if (tmp & ((1<<numBits)-1)) numBits++; return(numBits); } /*------------------------------------------------------------------------------ Function: RefPicListReordering Functional description: Decode reference picture list reordering syntax elements from the stream. Max number of reordering commands is numRefIdxActive. Inputs: pStrmData pointer to stream data structure numRefIdxActive number of active reference indices to be used for current slice maxPicNum maxFrameNum from the active SPS Outputs: pRefPicListReordering decoded data is stored here Returns: HANTRO_OK success HANTRO_NOK invalid stream data ------------------------------------------------------------------------------*/ static u32 RefPicListReordering(strmData_t *pStrmData, refPicListReordering_t *pRefPicListReordering, u32 numRefIdxActive, u32 maxPicNum){ /* Variables */ u32 tmp, value, i; u32 command; /* Code */ ASSERT(pStrmData); ASSERT(pRefPicListReordering); ASSERT(numRefIdxActive); ASSERT(maxPicNum); tmp = h264bsdGetBits(pStrmData, 1); if (tmp == END_OF_STREAM) return(HANTRO_NOK); pRefPicListReordering->refPicListReorderingFlagL0 = tmp; if (pRefPicListReordering->refPicListReorderingFlagL0) { i = 0; do { if (i > numRefIdxActive) { EPRINT("Too many reordering commands");Lines 1–500 of 1512. Load more
/* * Copyright (C) 2009 The Android Open Source Project * Modified for use by h264bsd standalone library * * 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 h264bsdDecodeSliceHeader NumSliceGroupChangeCycleBits RefPicListReordering DecRefPicMarking CheckPpsId CheckFrameNum CheckIdrPicId CheckPicOrderCntLsb CheckDeltaPicOrderCntBottom CheckDeltaPicOrderCnt CheckRedundantPicCnt ------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------ 1. Include headers ------------------------------------------------------------------------------*/ #include "h264bsd_slice_header.h" #include "h264bsd_util.h" #include "h264bsd_vlc.h" #include "h264bsd_nal_unit.h" #include "h264bsd_dpb.h" /*------------------------------------------------------------------------------ 2. External compiler flags -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- 3. Module defines ------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------ 4. Local function prototypes ------------------------------------------------------------------------------*/ static u32 RefPicListReordering(strmData_t *, refPicListReordering_t *, u32, u32); static u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs, u32 sliceGroupChangeRate); static u32 DecRefPicMarking(strmData_t *pStrmData, decRefPicMarking_t *pDecRefPicMarking, nalUnitType_e nalUnitType, u32 numRefFrames); /*------------------------------------------------------------------------------ Function name: h264bsdDecodeSliceHeader Functional description: Decode slice header data from the stream. Inputs: pStrmData pointer to stream data structure pSeqParamSet pointer to active sequence parameter set pPicParamSet pointer to active picture parameter set pNalUnit pointer to current NAL unit structure Outputs: pSliceHeader decoded data is stored here Returns: HANTRO_OK success HANTRO_NOK invalid stream data or end of stream ------------------------------------------------------------------------------*/ u32 h264bsdDecodeSliceHeader(strmData_t *pStrmData, sliceHeader_t *pSliceHeader, seqParamSet_t *pSeqParamSet, picParamSet_t *pPicParamSet, nalUnit_t *pNalUnit) { /* Variables */ u32 tmp, i, value; i32 itmp; u32 picSizeInMbs; /* Code */ ASSERT(pStrmData); ASSERT(pSliceHeader); ASSERT(pSeqParamSet); ASSERT(pPicParamSet); ASSERT( pNalUnit->nalUnitType == NAL_CODED_SLICE || pNalUnit->nalUnitType == NAL_CODED_SLICE_IDR ); memset(pSliceHeader, 0, sizeof(sliceHeader_t)); picSizeInMbs = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs; tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->firstMbInSlice = value; if (value >= picSizeInMbs) { EPRINT("first_mb_in_slice"); return(HANTRO_NOK); } tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->sliceType = value; /* slice type has to be either I or P slice. P slice is not allowed when * current NAL unit is an IDR NAL unit or num_ref_frames is 0 */ if ( !IS_I_SLICE(pSliceHeader->sliceType) && ( !IS_P_SLICE(pSliceHeader->sliceType) || IS_IDR_NAL_UNIT(pNalUnit) || !pSeqParamSet->numRefFrames ) ) { EPRINT("slice_type"); return(HANTRO_NOK); } tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->picParameterSetId = value; if (pSliceHeader->picParameterSetId != pPicParamSet->picParameterSetId) { EPRINT("pic_parameter_set_id"); return(HANTRO_NOK); } /* log2(maxFrameNum) -> num bits to represent frame_num */ i = 0; while (pSeqParamSet->maxFrameNum >> i) i++; i--; tmp = h264bsdGetBits(pStrmData, i); if (tmp == END_OF_STREAM) return(HANTRO_NOK); if (IS_IDR_NAL_UNIT(pNalUnit) && tmp != 0) { EPRINT("frame_num"); return(HANTRO_NOK); } pSliceHeader->frameNum = tmp; if (IS_IDR_NAL_UNIT(pNalUnit)) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->idrPicId = value; if (value > 65535) { EPRINT("idr_pic_id"); return(HANTRO_NOK); } } if (pSeqParamSet->picOrderCntType == 0) { /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */ i = 0; while (pSeqParamSet->maxPicOrderCntLsb >> i) i++; i--; tmp = h264bsdGetBits(pStrmData, i); if (tmp == END_OF_STREAM) return(HANTRO_NOK); pSliceHeader->picOrderCntLsb = tmp; if (pPicParamSet->picOrderPresentFlag) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->deltaPicOrderCntBottom = itmp; } /* check that picOrderCnt for IDR picture will be zero. See * DecodePicOrderCnt function to understand the logic here */ if ( IS_IDR_NAL_UNIT(pNalUnit) && ( (pSliceHeader->picOrderCntLsb > pSeqParamSet->maxPicOrderCntLsb/2) || MIN((i32)pSliceHeader->picOrderCntLsb, (i32)pSliceHeader->picOrderCntLsb + pSliceHeader->deltaPicOrderCntBottom) != 0 ) ) { return(HANTRO_NOK); } } if ( (pSeqParamSet->picOrderCntType == 1) && !pSeqParamSet->deltaPicOrderAlwaysZeroFlag ) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->deltaPicOrderCnt[0] = itmp; if (pPicParamSet->picOrderPresentFlag) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->deltaPicOrderCnt[1] = itmp; } /* check that picOrderCnt for IDR picture will be zero. See * DecodePicOrderCnt function to understand the logic here */ if ( IS_IDR_NAL_UNIT(pNalUnit) && MIN(pSliceHeader->deltaPicOrderCnt[0], pSliceHeader->deltaPicOrderCnt[0] + pSeqParamSet->offsetForTopToBottomField + pSliceHeader->deltaPicOrderCnt[1]) != 0) { return(HANTRO_NOK); } } if (pPicParamSet->redundantPicCntPresentFlag) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->redundantPicCnt = value; if (value > 127) { EPRINT("redundant_pic_cnt"); return(HANTRO_NOK); } } if (IS_P_SLICE(pSliceHeader->sliceType)) { tmp = h264bsdGetBits(pStrmData, 1); if (tmp == END_OF_STREAM) return(HANTRO_NOK); pSliceHeader->numRefIdxActiveOverrideFlag = tmp; if (pSliceHeader->numRefIdxActiveOverrideFlag) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); if (value > 15) { EPRINT("num_ref_idx_l0_active_minus1"); return(HANTRO_NOK); } pSliceHeader->numRefIdxL0Active = value + 1; } /* set numRefIdxL0Active from pic param set */ else { /* if value (minus1) in picture parameter set exceeds 15 it should * have been overridden here */ if (pPicParamSet->numRefIdxL0Active > 16) { EPRINT("num_ref_idx_active_override_flag"); return(HANTRO_NOK); } pSliceHeader->numRefIdxL0Active = pPicParamSet->numRefIdxL0Active; } } if (IS_P_SLICE(pSliceHeader->sliceType)) { tmp = RefPicListReordering(pStrmData, &pSliceHeader->refPicListReordering, pSliceHeader->numRefIdxL0Active, pSeqParamSet->maxFrameNum); if (tmp != HANTRO_OK) return(tmp); } if (pNalUnit->nalRefIdc != 0) { tmp = DecRefPicMarking(pStrmData, &pSliceHeader->decRefPicMarking, pNalUnit->nalUnitType, pSeqParamSet->numRefFrames); if (tmp != HANTRO_OK) return(tmp); } /* decode sliceQpDelta and check that initial QP for the slice will be on * the range [0, 51] */ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->sliceQpDelta = itmp; itmp += (i32)pPicParamSet->picInitQp; if ( (itmp < 0) || (itmp > 51) ) { EPRINT("slice_qp_delta"); return(HANTRO_NOK); } if (pPicParamSet->deblockingFilterControlPresentFlag) { tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value); if (tmp != HANTRO_OK) return(tmp); pSliceHeader->disableDeblockingFilterIdc = value; if (pSliceHeader->disableDeblockingFilterIdc > 2) { EPRINT("disable_deblocking_filter_idc"); return(HANTRO_NOK); } if (pSliceHeader->disableDeblockingFilterIdc != 1) { tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); if ( (itmp < -6) || (itmp > 6) ) { EPRINT("slice_alpha_c0_offset_div2"); return(HANTRO_NOK); } pSliceHeader->sliceAlphaC0Offset = itmp * 2; tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp); if (tmp != HANTRO_OK) return(tmp); if ( (itmp < -6) || (itmp > 6) ) { EPRINT("slice_beta_offset_div2"); return(HANTRO_NOK); } pSliceHeader->sliceBetaOffset = itmp * 2; } } if ( (pPicParamSet->numSliceGroups > 1) && (pPicParamSet->sliceGroupMapType >= 3) && (pPicParamSet->sliceGroupMapType <= 5) ) { /* set tmp to number of bits used to represent slice_group_change_cycle * in the stream */ tmp = NumSliceGroupChangeCycleBits(picSizeInMbs, pPicParamSet->sliceGroupChangeRate); value = h264bsdGetBits(pStrmData, tmp); if (value == END_OF_STREAM) return(HANTRO_NOK); pSliceHeader->sliceGroupChangeCycle = value; /* corresponds to tmp = Ceil(picSizeInMbs / sliceGroupChangeRate) */ tmp = (picSizeInMbs + pPicParamSet->sliceGroupChangeRate - 1) / pPicParamSet->sliceGroupChangeRate; if (pSliceHeader->sliceGroupChangeCycle > tmp) { EPRINT("slice_group_change_cycle"); return(HANTRO_NOK); } } return(HANTRO_OK); } /*------------------------------------------------------------------------------ Function: NumSliceGroupChangeCycleBits Functional description: Determine number of bits needed to represent slice_group_change_cycle in the stream. The standard states that slice_group_change_cycle is represented by Ceil( Log2( (picSizeInMbs / sliceGroupChangeRate) + 1) ) bits. Division "/" in the equation is non-truncating division. Inputs: picSizeInMbs picture size in macroblocks sliceGroupChangeRate Outputs: none Returns: number of bits needed ------------------------------------------------------------------------------*/ static u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs, u32 sliceGroupChangeRate) { /* Variables */ u32 tmp,numBits,mask; /* Code */ ASSERT(picSizeInMbs); ASSERT(sliceGroupChangeRate); ASSERT(sliceGroupChangeRate <= picSizeInMbs); /* compute (picSizeInMbs / sliceGroupChangeRate + 1), rounded up */ if (picSizeInMbs % sliceGroupChangeRate) tmp = 2 + picSizeInMbs/sliceGroupChangeRate; else tmp = 1 + picSizeInMbs/sliceGroupChangeRate; numBits = 0; mask = ~0U; /* set numBits to position of right-most non-zero bit */ while (tmp & (mask<<++numBits)) ; numBits--; /* add one more bit if value greater than 2^numBits */ if (tmp & ((1<<numBits)-1)) numBits++; return(numBits); } /*------------------------------------------------------------------------------ Function: RefPicListReordering Functional description: Decode reference picture list reordering syntax elements from the stream. Max number of reordering commands is numRefIdxActive. Inputs: pStrmData pointer to stream data structure numRefIdxActive number of active reference indices to be used for current slice maxPicNum maxFrameNum from the active SPS Outputs: pRefPicListReordering decoded data is stored here Returns: HANTRO_OK success HANTRO_NOK invalid stream data ------------------------------------------------------------------------------*/ static u32 RefPicListReordering(strmData_t *pStrmData, refPicListReordering_t *pRefPicListReordering, u32 numRefIdxActive, u32 maxPicNum) { /* Variables */ u32 tmp, value, i; u32 command; /* Code */ ASSERT(pStrmData); ASSERT(pRefPicListReordering); ASSERT(numRefIdxActive); ASSERT(maxPicNum); tmp = h264bsdGetBits(pStrmData, 1); if (tmp == END_OF_STREAM) return(HANTRO_NOK); pRefPicListReordering->refPicListReorderingFlagL0 = tmp; if (pRefPicListReordering->refPicListReorderingFlagL0) { i = 0; do { if (i > numRefIdxActive) { EPRINT("Too many reordering commands");