add decoder syntax checks
This commit is contained in:
parent
fe766fec2f
commit
61b64190dd
@ -211,6 +211,95 @@ do {
|
||||
|
||||
return 0;
|
||||
}
|
||||
//define macros to check syntax elements
|
||||
#define WELS_CHECK_SE_BOTH_ERROR(val, lower_bound, upper_bound, syntax_name, ret_code) do {\
|
||||
if ((val < lower_bound) || (val > upper_bound)) {\
|
||||
WelsLog(pCtx, WELS_LOG_ERROR, "invalid syntax " syntax_name " %d\n", val);\
|
||||
return ret_code;\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WELS_CHECK_SE_LOWER_ERROR(val, lower_bound, syntax_name, ret_code) do {\
|
||||
if (val < lower_bound) {\
|
||||
WelsLog(pCtx, WELS_LOG_ERROR, "invalid syntax " syntax_name " %d\n", val);\
|
||||
return ret_code;\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WELS_CHECK_SE_UPPER_ERROR(val, upper_bound, syntax_name, ret_code) do {\
|
||||
if (val > upper_bound) {\
|
||||
WelsLog(pCtx, WELS_LOG_ERROR, "invalid syntax " syntax_name " %d\n", val);\
|
||||
return ret_code;\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WELS_CHECK_SE_BOTH_ERROR_NOLOG(val, lower_bound, upper_bound, syntax_name, ret_code) do {\
|
||||
if ((val < lower_bound) || (val > upper_bound)) {\
|
||||
return ret_code;\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WELS_CHECK_SE_LOWER_ERROR_NOLOG(val, lower_bound, syntax_name, ret_code) do {\
|
||||
if (val < lower_bound) {\
|
||||
return ret_code;\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WELS_CHECK_SE_UPPER_ERROR_NOLOG(val, upper_bound, syntax_name, ret_code) do {\
|
||||
if (val > upper_bound) {\
|
||||
return ret_code;\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
|
||||
#define WELS_CHECK_SE_BOTH_WARNING(val, lower_bound, upper_bound, syntax_name) do {\
|
||||
if ((val < lower_bound) || (val > upper_bound)) {\
|
||||
WelsLog(pCtx, WELS_LOG_WARNING, "invalid syntax " syntax_name " %d\n", val);\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WELS_CHECK_SE_LOWER_WARNING(val, lower_bound, syntax_name) do {\
|
||||
if (val < lower_bound) {\
|
||||
WelsLog(pCtx, WELS_LOG_WARNING, "invalid syntax " syntax_name " %d\n", val);\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define WELS_CHECK_SE_UPPER_WARNING(val, upper_bound, syntax_name) do {\
|
||||
if (val > upper_bound) {\
|
||||
WelsLog(pCtx, WELS_LOG_WARNING, "invalid syntax " syntax_name " %d\n", val);\
|
||||
}\
|
||||
}while(0)
|
||||
// below define syntax element offset
|
||||
// for bit_depth_luma_minus8 and bit_depth_chroma_minus8
|
||||
#define BIT_DEPTH_LUMA_OFFSET 8
|
||||
#define BIT_DEPTH_CHROMA_OFFSET 8
|
||||
// for log2_max_frame_num_minus4
|
||||
#define LOG2_MAX_FRAME_NUM_OFFSET 4
|
||||
// for log2_max_pic_order_cnt_lsb_minus4
|
||||
#define LOG2_MAX_PIC_ORDER_CNT_LSB_OFFSET 4
|
||||
// for pic_width_in_mbs_minus1
|
||||
#define PIC_WIDTH_IN_MBS_OFFSET 1
|
||||
// for pic_height_in_map_units_minus1
|
||||
#define PIC_HEIGHT_IN_MAP_UNITS_OFFSET 1
|
||||
// for bit_depth_aux_minus8
|
||||
#define BIT_DEPTH_AUX_OFFSET 8
|
||||
// for num_slice_groups_minus1
|
||||
#define NUM_SLICE_GROUPS_OFFSET 1
|
||||
// for run_length_minus1
|
||||
#define RUN_LENGTH_OFFSET 1
|
||||
// for slice_group_change_rate_minus1
|
||||
#define SLICE_GROUP_CHANGE_RATE_OFFSET 1
|
||||
// for pic_size_in_map_units_minus1
|
||||
#define PIC_SIZE_IN_MAP_UNITS_OFFSET 1
|
||||
// for num_ref_idx_l0_default_active_minus1 and num_ref_idx_l1_default_active_minus1
|
||||
#define NUM_REF_IDX_L0_DEFAULT_ACTIVE_OFFSET 1
|
||||
#define NUM_REF_IDX_L1_DEFAULT_ACTIVE_OFFSET 1
|
||||
// for pic_init_qp_minus26 and pic_init_qs_minus26
|
||||
#define PIC_INIT_QP_OFFSET 26
|
||||
#define PIC_INIT_QS_OFFSET 26
|
||||
// for num_ref_idx_l0_active_minus1 and num_ref_idx_l1_active_minus1
|
||||
#define NUM_REF_IDX_L0_ACTIVE_OFFSET 1
|
||||
#define NUM_REF_IDX_L1_ACTIVE_OFFSET 1
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
|
@ -99,14 +99,28 @@ ERR_INFO_PPS_ID_OVERFLOW,
|
||||
ERR_INFO_INVALID_PROFILE_IDC,
|
||||
ERR_INFO_UNMATCHED_LEVEL_IDC,
|
||||
ERR_INFO_INVALID_POC_TYPE,
|
||||
ERR_INFO_INVALID_MB_SIZE_INFO,
|
||||
ERR_INFO_REF_COUNT_OVERFLOW,
|
||||
ERR_INFO_CROPPING_NO_SUPPORTED,
|
||||
ERR_INFO_INVALID_SLICEGROUP,
|
||||
ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE,
|
||||
ERR_INFO_INVALID_FRAME_NUM,
|
||||
ERR_INFO_INVALID_IDR_PIC_ID,
|
||||
ERR_INFO_INVALID_REDUNDANT_PIC_CNT,
|
||||
ERR_INFO_INVALID_MAX_NUM_REF_FRAMES,
|
||||
ERR_INFO_INVALID_FIRST_MB_IN_SLICE,
|
||||
ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1,
|
||||
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2,
|
||||
ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2,
|
||||
ERR_INFO_FMO_INIT_FAIL,
|
||||
ERR_INFO_SLICE_TYPE_OVERFLOW,
|
||||
ERR_INFO_INVALID_QP,
|
||||
ERR_INFO_INVALID_PIC_INIT_QS,
|
||||
ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET,
|
||||
ERR_INFO_INVALID_PIC_INIT_QP,
|
||||
ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4,
|
||||
ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4,
|
||||
ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE,
|
||||
ERR_INFO_INVALID_DBLOCKING_IDC,
|
||||
ERR_INFO_INVALID_MB_TYPE,
|
||||
ERR_INFO_INVALID_SUB_MB_TYPE,
|
||||
|
@ -600,6 +600,17 @@ void ParsePrefixNalUnit (PWelsDecoderContext pCtx, PBitStringAux pBs) {
|
||||
}
|
||||
}
|
||||
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MIN -32768
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MAX 32767
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MIN -32768
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MAX 32767
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MIN -32768
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MAX 32767
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MIN -32768
|
||||
#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MAX 32767
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStringAux pBs) {
|
||||
PSpsSvcExt pExt = NULL;
|
||||
@ -633,9 +644,17 @@ int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStrin
|
||||
pExt->uiSeqRefLayerChromaPhaseYPlus1 = BsGetBits (pBs, 2);
|
||||
|
||||
kpPos->iLeftOffset = BsGetSe (pBs);
|
||||
WELS_CHECK_SE_BOTH_WARNING (kpPos->iLeftOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MIN,
|
||||
SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MAX, "seq_scaled_ref_layer_left_offset");
|
||||
kpPos->iTopOffset = BsGetSe (pBs);
|
||||
WELS_CHECK_SE_BOTH_WARNING (kpPos->iTopOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MIN,
|
||||
SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MAX, "seq_scaled_ref_layer_top_offset");
|
||||
kpPos->iRightOffset = BsGetSe (pBs);
|
||||
WELS_CHECK_SE_BOTH_WARNING (kpPos->iRightOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MIN,
|
||||
SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MAX, "seq_scaled_ref_layer_right_offset");
|
||||
kpPos->iBottomOffset = BsGetSe (pBs);
|
||||
WELS_CHECK_SE_BOTH_WARNING (kpPos->iBottomOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MIN,
|
||||
SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MAX, "seq_scaled_ref_layer_bottom_offset");
|
||||
}
|
||||
|
||||
pExt->bSeqTCoeffLevelPredFlag = !!BsGetOneBit (pBs);
|
||||
@ -675,7 +694,7 @@ const SLevelLimits *GetLevelLimits(int32_t iLevelIdx, bool bConstraint3) {
|
||||
case 10:
|
||||
return &g_kSLevelLimits[0];
|
||||
case 11:
|
||||
if(bConstraint3)
|
||||
if (bConstraint3)
|
||||
return &g_kSLevelLimits[1];
|
||||
else
|
||||
return &g_kSLevelLimits[2];
|
||||
@ -712,6 +731,16 @@ const SLevelLimits *GetLevelLimits(int32_t iLevelIdx, bool bConstraint3) {
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX 12
|
||||
#define SPS_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4_MAX 12
|
||||
#define SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX 255
|
||||
#define SPS_MAX_NUM_REF_FRAMES_MAX 16
|
||||
#define PPS_PIC_INIT_QP_QS_MIN 0
|
||||
#define PPS_PIC_INIT_QP_QS_MAX 51
|
||||
#define PPS_CHROMA_QP_INDEX_OFFSET_MIN -12
|
||||
#define PPS_CHROMA_QP_INDEX_OFFSET_MAX 12
|
||||
|
||||
/*!
|
||||
*************************************************************************************
|
||||
* \brief to parse Sequence Parameter Set (SPS)
|
||||
@ -728,7 +757,6 @@ const SLevelLimits *GetLevelLimits(int32_t iLevelIdx, bool bConstraint3) {
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight) {
|
||||
PBitStringAux pBs = pBsAux;
|
||||
PSps pSps = NULL;
|
||||
@ -737,10 +765,10 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
ProfileIdc uiProfileIdc;
|
||||
uint8_t uiLevelIdc;
|
||||
int32_t iSpsId;
|
||||
uint32_t uiTmp;
|
||||
bool bConstraintSetFlags[6] = { false };
|
||||
const bool kbUseSubsetFlag = IS_SUBSET_SPS_NAL (pNalHead->eNalUnitType);
|
||||
|
||||
|
||||
if (kbUseSubsetFlag) { // SubsetSps
|
||||
pCtx->bSubspsExistAheadFlag = true;
|
||||
} else { // Sps
|
||||
@ -799,12 +827,11 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
pCtx->bSpsAvailFlags[iSpsId] = true; // added for EC, 10/28/2009
|
||||
#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
|
||||
}
|
||||
const SLevelLimits *pSLevelLimits = GetLevelLimits(uiLevelIdc, bConstraintSetFlags[3]);
|
||||
const SLevelLimits* pSLevelLimits = GetLevelLimits (uiLevelIdc, bConstraintSetFlags[3]);
|
||||
if (NULL == pSLevelLimits) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): level_idx (%d).\n", uiLevelIdc);
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
|
||||
}
|
||||
else pSps->pSLevelLimits = pSLevelLimits;
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): level_idx (%d).\n", uiLevelIdc);
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
|
||||
} else pSps->pSLevelLimits = pSLevelLimits;
|
||||
// syntax elements in default
|
||||
pSps->uiChromaFormatIdc = 1;
|
||||
pSps->uiBitDepthLuma =
|
||||
@ -845,19 +872,29 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
|
||||
}
|
||||
}
|
||||
|
||||
pSps->uiLog2MaxFrameNum = 4 + BsGetUe (pBs); // log2_max_frame_num_minus4
|
||||
uiTmp = BsGetUe (pBs);
|
||||
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX, "log2_max_frame_num_minus4",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4));
|
||||
pSps->uiLog2MaxFrameNum = LOG2_MAX_FRAME_NUM_OFFSET + uiTmp; // log2_max_frame_num_minus4
|
||||
pSps->uiPocType = BsGetUe (pBs); // pic_order_cnt_type
|
||||
|
||||
if (0 == pSps->uiPocType) {
|
||||
pSps->iLog2MaxPocLsb = 4 + BsGetUe (pBs); // log2_max_pic_order_cnt_lsb_minus4
|
||||
uiTmp = BsGetUe (pBs);
|
||||
// log2_max_pic_order_cnt_lsb_minus4 should be in range 0 to 12, inclusive. (sec. 7.4.3)
|
||||
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4_MAX, "log2_max_pic_order_cnt_lsb_minus4",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4));
|
||||
pSps->iLog2MaxPocLsb = LOG2_MAX_PIC_ORDER_CNT_LSB_OFFSET + uiTmp; // log2_max_pic_order_cnt_lsb_minus4
|
||||
|
||||
} else if (1 == pSps->uiPocType) {
|
||||
int32_t i;
|
||||
pSps->bDeltaPicOrderAlwaysZeroFlag = !!BsGetOneBit (pBs); // bDeltaPicOrderAlwaysZeroFlag
|
||||
pSps->iOffsetForNonRefPic = BsGetSe (pBs); // iOffsetForNonRefPic
|
||||
pSps->iOffsetForTopToBottomField = BsGetSe (pBs); // iOffsetForTopToBottomField
|
||||
pSps->iNumRefFramesInPocCycle = BsGetUe (pBs); // num_ref_frames_in_pic_order_cnt_cycle
|
||||
uiTmp = BsGetUe (pBs);
|
||||
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX,
|
||||
"num_ref_frames_in_pic_order_cnt_cycle", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS,
|
||||
ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE));
|
||||
pSps->iNumRefFramesInPocCycle = uiTmp; // num_ref_frames_in_pic_order_cnt_cycle
|
||||
for (i = 0; i < pSps->iNumRefFramesInPocCycle; i++)
|
||||
pSps->iOffsetForRefFrame[ i ] = BsGetSe (pBs); // iOffsetForRefFrame[ i ]
|
||||
}
|
||||
@ -868,11 +905,39 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
|
||||
pSps->iNumRefFrames = BsGetUe (pBs); // max_num_ref_frames
|
||||
pSps->bGapsInFrameNumValueAllowedFlag = !!BsGetOneBit (pBs); // bGapsInFrameNumValueAllowedFlag
|
||||
pSps->iMbWidth = 1 + BsGetUe (pBs); // pic_width_in_mbs_minus1
|
||||
pSps->iMbHeight = 1 + BsGetUe (pBs); // pic_height_in_map_units_minus1
|
||||
uiTmp = BsGetUe (pBs); // pic_width_in_mbs_minus1
|
||||
if (uiTmp == 0xffffffff) {
|
||||
WelsLog (pCtx, WELS_LOG_ERROR, " pic_width_in_mbs read error!\n");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MB_SIZE_INFO);
|
||||
}
|
||||
pSps->iMbWidth = PIC_WIDTH_IN_MBS_OFFSET + uiTmp;
|
||||
if ((uint64_t) (pSps->iMbWidth * pSps->iMbWidth) > (8 * pSLevelLimits->iMaxFS)) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, " the pic_width_in_mbs exceeds the level limits!\n");
|
||||
}
|
||||
uiTmp = BsGetUe (pBs); // pic_height_in_map_units_minus1
|
||||
if (uiTmp == 0xffffffff) {
|
||||
WelsLog (pCtx, WELS_LOG_ERROR, " pic_height_in_mbs read error!\n");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MB_SIZE_INFO);
|
||||
}
|
||||
pSps->iMbHeight = PIC_HEIGHT_IN_MAP_UNITS_OFFSET + uiTmp;
|
||||
if ((uint64_t) (pSps->iMbHeight * pSps->iMbHeight) > (8 * pSLevelLimits->iMaxFS)) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, " the pic_height_in_mbs exceeds the level limits!\n");
|
||||
}
|
||||
pSps->uiTotalMbCount = pSps->iMbWidth * pSps->iMbHeight;
|
||||
if (pSps->uiTotalMbCount > (uint32_t)pSLevelLimits->iMaxFS) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, " the total count of mb exceeds the level limits!\n");
|
||||
}
|
||||
WELS_CHECK_SE_UPPER_ERROR (pSps->iNumRefFrames, SPS_MAX_NUM_REF_FRAMES_MAX, "max_num_ref_frames",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MAX_NUM_REF_FRAMES));
|
||||
// here we check max_num_ref_frames
|
||||
uint32_t uiMaxDpbMbs = pSLevelLimits->iMaxDPBMbs;
|
||||
uint32_t uiMaxDpbFrames = uiMaxDpbMbs / pSps->uiTotalMbCount;
|
||||
if (uiMaxDpbFrames > SPS_MAX_NUM_REF_FRAMES_MAX)
|
||||
uiMaxDpbFrames = SPS_MAX_NUM_REF_FRAMES_MAX;
|
||||
if ((uint32_t)pSps->iNumRefFrames > uiMaxDpbFrames) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, " max_num_ref_frames exceeds level limits!\n");
|
||||
}
|
||||
pSps->bFrameMbsOnlyFlag = !!BsGetOneBit (pBs); // frame_mbs_only_flag
|
||||
|
||||
if (!pSps->bFrameMbsOnlyFlag) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): frame_mbs_only_flag (%d) not supported.\n", pSps->bFrameMbsOnlyFlag);
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_MBAFF);
|
||||
@ -882,8 +947,14 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
if (pSps->bFrameCroppingFlag) {
|
||||
pSps->sFrameCrop.iLeftOffset = BsGetUe (pBs); // frame_crop_left_offset
|
||||
pSps->sFrameCrop.iRightOffset = BsGetUe (pBs); // frame_crop_right_offset
|
||||
if ((pSps->sFrameCrop.iLeftOffset + pSps->sFrameCrop.iRightOffset) > ((int32_t)pSps->iMbWidth * 16 / 2)) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "frame_crop_left_offset + frame_crop_right_offset exceeds limits!\n");
|
||||
}
|
||||
pSps->sFrameCrop.iTopOffset = BsGetUe (pBs); // frame_crop_top_offset
|
||||
pSps->sFrameCrop.iBottomOffset = BsGetUe (pBs); // frame_crop_bottom_offset
|
||||
if ((pSps->sFrameCrop.iTopOffset + pSps->sFrameCrop.iBottomOffset) > ((int32_t)pSps->iMbHeight * 16 / 2)) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "frame_crop_top_offset + frame_crop_right_offset exceeds limits!\n");
|
||||
}
|
||||
} else {
|
||||
pSps->sFrameCrop.iLeftOffset = 0; // frame_crop_left_offset
|
||||
pSps->sFrameCrop.iRightOffset = 0; // frame_crop_right_offset
|
||||
@ -957,7 +1028,7 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
|
||||
pPps->bEntropyCodingModeFlag = !!BsGetOneBit (pBsAux);
|
||||
pPps->bPicOrderPresentFlag = !!BsGetOneBit (pBsAux);
|
||||
|
||||
pPps->uiNumSliceGroups = 1 + BsGetUe (pBsAux);
|
||||
pPps->uiNumSliceGroups = NUM_SLICE_GROUPS_OFFSET + BsGetUe (pBsAux);
|
||||
|
||||
if (pPps->uiNumSliceGroups > MAX_SLICEGROUP_IDS) {
|
||||
return ERR_INFO_INVALID_SLICEGROUP;
|
||||
@ -974,7 +1045,7 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
|
||||
switch (pPps->uiSliceGroupMapType) {
|
||||
case 0:
|
||||
for (iTmp = 0; iTmp < pPps->uiNumSliceGroups; iTmp++) {
|
||||
pPps->uiRunLength[iTmp] = 1 + BsGetUe (pBsAux);
|
||||
pPps->uiRunLength[iTmp] = RUN_LENGTH_OFFSET + BsGetUe (pBsAux);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -982,8 +1053,8 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
|
||||
}
|
||||
}
|
||||
|
||||
pPps->uiNumRefIdxL0Active = 1 + BsGetUe (pBsAux);
|
||||
pPps->uiNumRefIdxL1Active = 1 + BsGetUe (pBsAux);
|
||||
pPps->uiNumRefIdxL0Active = NUM_REF_IDX_L0_DEFAULT_ACTIVE_OFFSET + BsGetUe (pBsAux);
|
||||
pPps->uiNumRefIdxL1Active = NUM_REF_IDX_L1_DEFAULT_ACTIVE_OFFSET + BsGetUe (pBsAux);
|
||||
|
||||
if (pPps->uiNumRefIdxL0Active > MAX_REF_PIC_COUNT ||
|
||||
pPps->uiNumRefIdxL1Active > MAX_REF_PIC_COUNT) {
|
||||
@ -998,10 +1069,15 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP);
|
||||
}
|
||||
|
||||
pPps->iPicInitQp = 26 + BsGetSe (pBsAux);
|
||||
pPps->iPicInitQs = 26 + BsGetSe (pBsAux);
|
||||
|
||||
pPps->iPicInitQp = PIC_INIT_QP_OFFSET + BsGetSe (pBsAux);
|
||||
WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQp, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qp_minus26 + 26",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_PIC_INIT_QP));
|
||||
pPps->iPicInitQs = PIC_INIT_QS_OFFSET + BsGetSe (pBsAux);
|
||||
WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQs, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qs_minus26 + 26",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_PIC_INIT_QS));
|
||||
pPps->iChromaQpIndexOffset = BsGetSe (pBsAux);
|
||||
WELS_CHECK_SE_BOTH_ERROR (pPps->iChromaQpIndexOffset, PPS_CHROMA_QP_INDEX_OFFSET_MIN, PPS_CHROMA_QP_INDEX_OFFSET_MAX,
|
||||
"chroma_qp_index_offset", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET));
|
||||
pPps->bDeblockingFilterControlPresentFlag = !!BsGetOneBit (pBsAux);
|
||||
pPps->bConstainedIntraPredFlag = !!BsGetOneBit (pBsAux);
|
||||
pPps->bRedundantPicCntPresentFlag = !!BsGetOneBit (pBsAux);
|
||||
|
@ -155,7 +155,7 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
|
||||
int32_t iList = 0;
|
||||
const ESliceType keSt = pSh->eSliceType;
|
||||
PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering;
|
||||
|
||||
PSps pSps = pSh->pSps;
|
||||
if (keSt == I_SLICE || keSt == SI_SLICE)
|
||||
return ERR_NONE;
|
||||
|
||||
@ -166,7 +166,7 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
|
||||
if (pRefPicListReordering->bRefPicListReorderingFlag[iList]) {
|
||||
int32_t iIdx = 0;
|
||||
do {
|
||||
const uint8_t kuiIdc = BsGetUe (pBs);
|
||||
const uint32_t kuiIdc = BsGetUe (pBs);
|
||||
|
||||
//Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)---
|
||||
if ((iIdx >= MAX_REF_PIC_COUNT) || (kuiIdc > 3)) {
|
||||
@ -180,7 +180,12 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);
|
||||
|
||||
if (kuiIdc == 0 || kuiIdc == 1) {
|
||||
pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = BsGetUe (pBs); // uiAbsDiffPicNumMinus1
|
||||
// abs_diff_pic_num_minus1 should be in range 0 to MaxPicNum-1, MaxPicNum is derived as
|
||||
// 2^(4+log2_max_frame_num_minus4)
|
||||
uint32_t uiTmp = BsGetUe (pBs);
|
||||
WELS_CHECK_SE_UPPER_ERROR_NOLOG (uiTmp, (1 << pSps->uiLog2MaxFrameNum), "abs_diff_pic_num_minus1",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING));
|
||||
pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = uiTmp; // uiAbsDiffPicNumMinus1
|
||||
} else if (kuiIdc == 2) {
|
||||
pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum = BsGetUe (pBs);
|
||||
}
|
||||
@ -199,7 +204,7 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
|
||||
int32_t ParseDecRefPicMarking (PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps,
|
||||
const bool kbIdrFlag) {
|
||||
PRefPicMarking const kpRefMarking = &pSh->sRefMarking;
|
||||
|
||||
PRefPic pRefPic = &pCtx->sRefPic;
|
||||
if (kbIdrFlag) {
|
||||
kpRefMarking->bNoOutputOfPriorPicsFlag = !!BsGetOneBit (pBs);
|
||||
kpRefMarking->bLongTermRefFlag = !!BsGetOneBit (pBs);
|
||||
@ -447,6 +452,13 @@ int32_t CheckSpsId (PWelsDecoderContext pCtx, PSubsetSps* ppSubsetSps, PSps* ppS
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define SLICE_HEADER_IDR_PIC_ID_MAX 65535
|
||||
#define SLICE_HEADER_REDUNDANT_PIC_CNT_MAX 127
|
||||
#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN -12
|
||||
#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX 12
|
||||
#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN -12
|
||||
#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX 12
|
||||
/*
|
||||
* decode_slice_header_avc
|
||||
* Parse slice header of bitstream in avc for storing data structure
|
||||
@ -465,6 +477,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
int32_t iRet = ERR_NONE;
|
||||
uint8_t uiSliceType = 0;
|
||||
uint8_t uiQualityId = BASE_QUALITY_ID;
|
||||
uint32_t uiTmp;
|
||||
bool bIdrFlag = false;
|
||||
bool bSgChangeCycleInvolved = false; // involved slice group change cycle ?
|
||||
|
||||
@ -489,6 +502,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
|
||||
kpCurNal->sNalData.sVclNal.bSliceHeaderExtFlag = kbExtensionFlag;
|
||||
|
||||
// first_mb_in_slice
|
||||
pSliceHead->iFirstMbInSlice = BsGetUe (pBs);
|
||||
|
||||
uiSliceType = BsGetUe (pBs);
|
||||
@ -500,7 +514,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
if (uiSliceType > 4)
|
||||
uiSliceType -= 5;
|
||||
|
||||
if((eNalType == NAL_UNIT_CODED_SLICE_IDR) && (uiSliceType != 2)){
|
||||
if ((eNalType == NAL_UNIT_CODED_SLICE_IDR) && (uiSliceType != 2)) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "Invalid slice type(%d) in IDR picture. \n", uiSliceType);
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
|
||||
}
|
||||
@ -566,6 +580,9 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "non existing SPS referenced\n");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);
|
||||
}
|
||||
// check first_mb_in_slice
|
||||
WELS_CHECK_SE_UPPER_ERROR ((uint32_t) (pSliceHead->iFirstMbInSlice), pSps->uiTotalMbCount, "first_mb_in_slice",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FIRST_MB_IN_SLICE));
|
||||
pSliceHead->iFrameNum = BsGetBits (pBs, pSps->uiLog2MaxFrameNum);
|
||||
|
||||
pSliceHead->bFieldPicFlag = false;
|
||||
@ -584,7 +601,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
pSliceHead->iFrameNum);
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FRAME_NUM);
|
||||
}
|
||||
pSliceHead->uiIdrPicId = BsGetUe (pBs); /* uiIdrPicId */
|
||||
uiTmp = BsGetUe (pBs);
|
||||
// standard 7.4.3 idr_pic_id should be in range 0 to 65535, inclusive.
|
||||
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SLICE_HEADER_IDR_PIC_ID_MAX, "idr_pic_id", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
|
||||
ERR_INFO_INVALID_IDR_PIC_ID));
|
||||
pSliceHead->uiIdrPicId = uiTmp; /* uiIdrPicId */
|
||||
#ifdef LONG_TERM_REF
|
||||
pCtx->uiCurIdrPicId = pSliceHead->uiIdrPicId;
|
||||
#endif
|
||||
@ -606,7 +627,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
|
||||
pSliceHead->iRedundantPicCnt = 0;
|
||||
if (pPps->bRedundantPicCntPresentFlag) {
|
||||
pSliceHead->iRedundantPicCnt = BsGetUe (pBs);
|
||||
uiTmp = BsGetUe (pBs);
|
||||
// standard section 7.4.3, redundant_pic_cnt should be in range 0 to 127, inclusive.
|
||||
WELS_CHECK_SE_UPPER_ERROR (uiTmp, SLICE_HEADER_REDUNDANT_PIC_CNT_MAX, "redundant_pic_cnt",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT));
|
||||
pSliceHead->iRedundantPicCnt = uiTmp;
|
||||
}
|
||||
|
||||
//set defaults, might be overriden a few line later
|
||||
@ -695,7 +720,13 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
}
|
||||
if (pSliceHead->uiDisableDeblockingFilterIdc != 1) {
|
||||
pSliceHead->iSliceAlphaC0Offset = BsGetSe (pBs) * 2; // slice_alpha_c0_offset_div2
|
||||
WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceAlphaC0Offset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
|
||||
SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
|
||||
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
|
||||
pSliceHead->iSliceBetaOffset = BsGetSe (pBs) * 2; // iSliceBetaOffset
|
||||
WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceBetaOffset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
|
||||
SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_beta_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
|
||||
ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,7 +762,14 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
}
|
||||
if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc != 1) {
|
||||
pSliceHeadExt->iInterLayerSliceAlphaC0Offset = BsGetSe (pBs) << 1;
|
||||
WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceAlphaC0Offset,
|
||||
SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX,
|
||||
"inter_layer_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
|
||||
ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
|
||||
pSliceHeadExt->iInterLayerSliceBetaOffset = BsGetSe (pBs) << 1;
|
||||
WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceBetaOffset, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN,
|
||||
SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX, "inter_layer_slice_beta_offset_div2 * 2",
|
||||
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -985,6 +985,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
PBitStringAux pBs) {
|
||||
PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
|
||||
PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
|
||||
PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0];
|
||||
int32_t iNumRefFrames = pSliceHeader->pSps->iNumRefFrames;
|
||||
int32_t iRefCount[2];
|
||||
PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
|
||||
@ -992,7 +993,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
int32_t iMotionPredFlag[4];
|
||||
int16_t iMv[2] = {0};
|
||||
|
||||
int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
|
||||
int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
|
||||
iMotionPredFlag[0] = iMotionPredFlag[1] = iMotionPredFlag[2] = iMotionPredFlag[3] =
|
||||
pSlice->sSliceHeaderExt.bDefaultMotionPredFlag;
|
||||
iRefCount[0] = pSliceHeader->uiRefCount[0];
|
||||
@ -1000,13 +1002,15 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
|
||||
switch (pCurDqLayer->pMbType[iMbXy]) {
|
||||
case MB_TYPE_16x16: {
|
||||
int8_t iRefIdx = 0;
|
||||
int32_t iRefIdx = 0;
|
||||
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
|
||||
iMotionPredFlag[0] = BsGetOneBit (pBs);
|
||||
}
|
||||
if (iMotionPredFlag[0] == 0) {
|
||||
iRefIdx = BsGetTe0 (pBs, iRefCount[0]);
|
||||
if (iRefIdx < 0 || iRefIdx >= iNumRefFrames) { //error ref_idx
|
||||
// Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
|
||||
// ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
|
||||
if ((iRefIdx < 0) || (iRefIdx >= iRefCount[0]) || (ppRefPic[iRefIdx] == NULL)) { //error ref_idx
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
} else {
|
||||
@ -1017,7 +1021,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
|
||||
iMv[0] += BsGetSe (pBs);
|
||||
iMv[1] += BsGetSe (pBs);
|
||||
|
||||
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
UpdateP16x16MotionInfo (pCurDqLayer, iRefIdx, iMv);
|
||||
}
|
||||
break;
|
||||
@ -1035,7 +1039,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
|
||||
}
|
||||
iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]);
|
||||
if (iRefIdx[i] < 0 || iRefIdx[i] >= iNumRefFrames) { //error ref_idx
|
||||
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
@ -1044,7 +1048,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
|
||||
iMv[0] += BsGetSe (pBs);
|
||||
iMv[1] += BsGetSe (pBs);
|
||||
|
||||
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
UpdateP16x8MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv);
|
||||
}
|
||||
}
|
||||
@ -1060,7 +1064,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (iMotionPredFlag[i] == 0) {
|
||||
iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]);
|
||||
if (iRefIdx[i] < 0 || iRefIdx[i] >= iNumRefFrames) { //error ref_idx
|
||||
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
} else {
|
||||
@ -1074,14 +1078,14 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
|
||||
iMv[0] += BsGetSe (pBs);
|
||||
iMv[1] += BsGetSe (pBs);
|
||||
|
||||
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
UpdateP8x16MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 2, iRefIdx[i], iMv);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MB_TYPE_8x8:
|
||||
case MB_TYPE_8x8_REF0: {
|
||||
int8_t iRefIdx[4] = {0}, iSubPartCount[4], iPartWidth[4];
|
||||
int32_t iRefIdx[4] = {0}, iSubPartCount[4], iPartWidth[4];
|
||||
uint32_t uiSubMbType;
|
||||
|
||||
if (MB_TYPE_8x8_REF0 == pCurDqLayer->pMbType[iMbXy]) {
|
||||
@ -1116,7 +1120,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
|
||||
if (iMotionPredFlag[i] == 0) {
|
||||
iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]);
|
||||
if (iRefIdx[i] < 0 || iRefIdx[i] >= iNumRefFrames) { //error ref_idx
|
||||
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
|
||||
@ -1149,7 +1153,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
|
||||
iMv[0] += BsGetSe (pBs);
|
||||
iMv[1] += BsGetSe (pBs);
|
||||
|
||||
WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
if (SUB_MB_TYPE_8x8 == uiSubMbType) {
|
||||
ST32 (pCurDqLayer->pMv[0][iMbXy][uiScan4Idx], LD32 (iMv));
|
||||
ST32 (pCurDqLayer->pMv[0][iMbXy][uiScan4Idx + 1], LD32 (iMv));
|
||||
|
Loading…
Reference in New Issue
Block a user