add decoder syntax checks
Showing the changes to codec/decoder (5 of 5 files). Show all
Unified · Split
| @@ -211,6 +211,95 @@ do { · 210 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | return 0; |
| 213 | 213 | } |
| 214 | +//define macros to check syntax elements | |
| 215 | +#define WELS_CHECK_SE_BOTH_ERROR(val, lower_bound, upper_bound, syntax_name, ret_code) do {\ | |
| 216 | +if ((val < lower_bound) || (val > upper_bound)) {\ | |
| 217 | + WelsLog(pCtx, WELS_LOG_ERROR, "invalid syntax " syntax_name " %d\n", val);\ | |
| 218 | + return ret_code;\ | |
| 219 | +}\ | |
| 220 | +}while(0) | |
| 221 | + | |
| 222 | +#define WELS_CHECK_SE_LOWER_ERROR(val, lower_bound, syntax_name, ret_code) do {\ | |
| 223 | +if (val < lower_bound) {\ | |
| 224 | + WelsLog(pCtx, WELS_LOG_ERROR, "invalid syntax " syntax_name " %d\n", val);\ | |
| 225 | + return ret_code;\ | |
| 226 | +}\ | |
| 227 | +}while(0) | |
| 228 | + | |
| 229 | +#define WELS_CHECK_SE_UPPER_ERROR(val, upper_bound, syntax_name, ret_code) do {\ | |
| 230 | +if (val > upper_bound) {\ | |
| 231 | + WelsLog(pCtx, WELS_LOG_ERROR, "invalid syntax " syntax_name " %d\n", val);\ | |
| 232 | + return ret_code;\ | |
| 233 | +}\ | |
| 234 | +}while(0) | |
| 235 | + | |
| 236 | +#define WELS_CHECK_SE_BOTH_ERROR_NOLOG(val, lower_bound, upper_bound, syntax_name, ret_code) do {\ | |
| 237 | +if ((val < lower_bound) || (val > upper_bound)) {\ | |
| 238 | + return ret_code;\ | |
| 239 | +}\ | |
| 240 | +}while(0) | |
| 241 | + | |
| 242 | +#define WELS_CHECK_SE_LOWER_ERROR_NOLOG(val, lower_bound, syntax_name, ret_code) do {\ | |
| 243 | +if (val < lower_bound) {\ | |
| 244 | + return ret_code;\ | |
| 245 | +}\ | |
| 246 | +}while(0) | |
| 247 | + | |
| 248 | +#define WELS_CHECK_SE_UPPER_ERROR_NOLOG(val, upper_bound, syntax_name, ret_code) do {\ | |
| 249 | +if (val > upper_bound) {\ | |
| 250 | + return ret_code;\ | |
| 251 | +}\ | |
| 252 | +}while(0) | |
| 253 | + | |
| 254 | + | |
| 255 | +#define WELS_CHECK_SE_BOTH_WARNING(val, lower_bound, upper_bound, syntax_name) do {\ | |
| 256 | +if ((val < lower_bound) || (val > upper_bound)) {\ | |
| 257 | + WelsLog(pCtx, WELS_LOG_WARNING, "invalid syntax " syntax_name " %d\n", val);\ | |
| 258 | +}\ | |
| 259 | +}while(0) | |
| 260 | + | |
| 261 | +#define WELS_CHECK_SE_LOWER_WARNING(val, lower_bound, syntax_name) do {\ | |
| 262 | +if (val < lower_bound) {\ | |
| 263 | + WelsLog(pCtx, WELS_LOG_WARNING, "invalid syntax " syntax_name " %d\n", val);\ | |
| 264 | +}\ | |
| 265 | +}while(0) | |
| 266 | + | |
| 267 | +#define WELS_CHECK_SE_UPPER_WARNING(val, upper_bound, syntax_name) do {\ | |
| 268 | +if (val > upper_bound) {\ | |
| 269 | + WelsLog(pCtx, WELS_LOG_WARNING, "invalid syntax " syntax_name " %d\n", val);\ | |
| 270 | +}\ | |
| 271 | +}while(0) | |
| 272 | +// below define syntax element offset | |
| 273 | +// for bit_depth_luma_minus8 and bit_depth_chroma_minus8 | |
| 274 | +#define BIT_DEPTH_LUMA_OFFSET 8 | |
| 275 | +#define BIT_DEPTH_CHROMA_OFFSET 8 | |
| 276 | +// for log2_max_frame_num_minus4 | |
| 277 | +#define LOG2_MAX_FRAME_NUM_OFFSET 4 | |
| 278 | +// for log2_max_pic_order_cnt_lsb_minus4 | |
| 279 | +#define LOG2_MAX_PIC_ORDER_CNT_LSB_OFFSET 4 | |
| 280 | +// for pic_width_in_mbs_minus1 | |
| 281 | +#define PIC_WIDTH_IN_MBS_OFFSET 1 | |
| 282 | +// for pic_height_in_map_units_minus1 | |
| 283 | +#define PIC_HEIGHT_IN_MAP_UNITS_OFFSET 1 | |
| 284 | +// for bit_depth_aux_minus8 | |
| 285 | +#define BIT_DEPTH_AUX_OFFSET 8 | |
| 286 | +// for num_slice_groups_minus1 | |
| 287 | +#define NUM_SLICE_GROUPS_OFFSET 1 | |
| 288 | +// for run_length_minus1 | |
| 289 | +#define RUN_LENGTH_OFFSET 1 | |
| 290 | +// for slice_group_change_rate_minus1 | |
| 291 | +#define SLICE_GROUP_CHANGE_RATE_OFFSET 1 | |
| 292 | +// for pic_size_in_map_units_minus1 | |
| 293 | +#define PIC_SIZE_IN_MAP_UNITS_OFFSET 1 | |
| 294 | +// for num_ref_idx_l0_default_active_minus1 and num_ref_idx_l1_default_active_minus1 | |
| 295 | +#define NUM_REF_IDX_L0_DEFAULT_ACTIVE_OFFSET 1 | |
| 296 | +#define NUM_REF_IDX_L1_DEFAULT_ACTIVE_OFFSET 1 | |
| 297 | +// for pic_init_qp_minus26 and pic_init_qs_minus26 | |
| 298 | +#define PIC_INIT_QP_OFFSET 26 | |
| 299 | +#define PIC_INIT_QS_OFFSET 26 | |
| 300 | +// for num_ref_idx_l0_active_minus1 and num_ref_idx_l1_active_minus1 | |
| 301 | +#define NUM_REF_IDX_L0_ACTIVE_OFFSET 1 | |
| 302 | +#define NUM_REF_IDX_L1_ACTIVE_OFFSET 1 | |
| 214 | 303 | |
| 215 | 304 | } // namespace WelsDec |
| 216 | 305 | |
| @@ -99,14 +99,28 @@ ERR_INFO_PPS_ID_OVERFLOW, · 98 unmodified lines | ||
| 99 | 99 | ERR_INFO_INVALID_PROFILE_IDC, |
| 100 | 100 | ERR_INFO_UNMATCHED_LEVEL_IDC, |
| 101 | 101 | ERR_INFO_INVALID_POC_TYPE, |
| 102 | +ERR_INFO_INVALID_MB_SIZE_INFO, | |
| 102 | 103 | ERR_INFO_REF_COUNT_OVERFLOW, |
| 103 | 104 | ERR_INFO_CROPPING_NO_SUPPORTED, |
| 104 | 105 | ERR_INFO_INVALID_SLICEGROUP, |
| 105 | 106 | ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE, |
| 106 | 107 | ERR_INFO_INVALID_FRAME_NUM, |
| 108 | +ERR_INFO_INVALID_IDR_PIC_ID, | |
| 109 | +ERR_INFO_INVALID_REDUNDANT_PIC_CNT, | |
| 110 | +ERR_INFO_INVALID_MAX_NUM_REF_FRAMES, | |
| 111 | +ERR_INFO_INVALID_FIRST_MB_IN_SLICE, | |
| 112 | +ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1, | |
| 113 | +ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2, | |
| 114 | +ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2, | |
| 107 | 115 | ERR_INFO_FMO_INIT_FAIL, |
| 108 | 116 | ERR_INFO_SLICE_TYPE_OVERFLOW, |
| 109 | 117 | ERR_INFO_INVALID_QP, |
| 118 | +ERR_INFO_INVALID_PIC_INIT_QS, | |
| 119 | +ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET, | |
| 120 | +ERR_INFO_INVALID_PIC_INIT_QP, | |
| 121 | +ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4, | |
| 122 | +ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4, | |
| 123 | +ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE, | |
| 110 | 124 | ERR_INFO_INVALID_DBLOCKING_IDC, |
| 111 | 125 | ERR_INFO_INVALID_MB_TYPE, |
| 112 | 126 | ERR_INFO_INVALID_SUB_MB_TYPE, |
| @@ -600,6 +600,17 @@ void ParsePrefixNalUnit (PWelsDecoderContext pCtx, PBitStringAux pBs) { · 599 unmodified lines | ||
| 600 | 600 | } |
| 601 | 601 | } |
| 602 | 602 | |
| 603 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MIN -32768 | |
| 604 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MAX 32767 | |
| 605 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MIN -32768 | |
| 606 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MAX 32767 | |
| 607 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MIN -32768 | |
| 608 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MAX 32767 | |
| 609 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MIN -32768 | |
| 610 | +#define SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MAX 32767 | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 603 | 614 | |
| 604 | 615 | int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStringAux pBs) { |
| 605 | 616 | PSpsSvcExt pExt = NULL; |
| @@ -633,9 +644,17 @@ int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStrin · 27 unmodified lines | ||
| 633 | 644 | pExt->uiSeqRefLayerChromaPhaseYPlus1 = BsGetBits (pBs, 2); |
| 634 | 645 | |
| 635 | 646 | kpPos->iLeftOffset = BsGetSe (pBs); |
| 647 | + WELS_CHECK_SE_BOTH_WARNING (kpPos->iLeftOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MIN, | |
| 648 | + SUBSET_SPS_SEQ_SCALED_REF_LAYER_LEFT_OFFSET_MAX, "seq_scaled_ref_layer_left_offset"); | |
| 636 | 649 | kpPos->iTopOffset = BsGetSe (pBs); |
| 650 | + WELS_CHECK_SE_BOTH_WARNING (kpPos->iTopOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MIN, | |
| 651 | + SUBSET_SPS_SEQ_SCALED_REF_LAYER_TOP_OFFSET_MAX, "seq_scaled_ref_layer_top_offset"); | |
| 637 | 652 | kpPos->iRightOffset = BsGetSe (pBs); |
| 653 | + WELS_CHECK_SE_BOTH_WARNING (kpPos->iRightOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MIN, | |
| 654 | + SUBSET_SPS_SEQ_SCALED_REF_LAYER_RIGHT_OFFSET_MAX, "seq_scaled_ref_layer_right_offset"); | |
| 638 | 655 | kpPos->iBottomOffset = BsGetSe (pBs); |
| 656 | + WELS_CHECK_SE_BOTH_WARNING (kpPos->iBottomOffset, SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MIN, | |
| 657 | + SUBSET_SPS_SEQ_SCALED_REF_LAYER_BOTTOM_OFFSET_MAX, "seq_scaled_ref_layer_bottom_offset"); | |
| 639 | 658 | } |
| 640 | 659 | |
| 641 | 660 | pExt->bSeqTCoeffLevelPredFlag = !!BsGetOneBit (pBs); |
| @@ -675,7 +694,7 @@ const SLevelLimits *GetLevelLimits(int32_t iLevelIdx, bool bConstraint3) { · 33 unmodified lines | ||
| 675 | 694 | case 10: |
| 676 | 695 | return &g_kSLevelLimits[0]; |
| 677 | 696 | case 11: |
| 678 | − if(bConstraint3) | |
| 697 | + if (bConstraint3) | |
| 679 | 698 | return &g_kSLevelLimits[1]; |
| 680 | 699 | else |
| 681 | 700 | return &g_kSLevelLimits[2]; |
| @@ -712,6 +731,16 @@ const SLevelLimits *GetLevelLimits(int32_t iLevelIdx, bool bConstraint3) { · 30 unmodified lines | ||
| 712 | 731 | } |
| 713 | 732 | return NULL; |
| 714 | 733 | } |
| 734 | + | |
| 735 | +#define SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX 12 | |
| 736 | +#define SPS_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4_MAX 12 | |
| 737 | +#define SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX 255 | |
| 738 | +#define SPS_MAX_NUM_REF_FRAMES_MAX 16 | |
| 739 | +#define PPS_PIC_INIT_QP_QS_MIN 0 | |
| 740 | +#define PPS_PIC_INIT_QP_QS_MAX 51 | |
| 741 | +#define PPS_CHROMA_QP_INDEX_OFFSET_MIN -12 | |
| 742 | +#define PPS_CHROMA_QP_INDEX_OFFSET_MAX 12 | |
| 743 | + | |
| 715 | 744 | /*! |
| 716 | 745 | ************************************************************************************* |
| 717 | 746 | * \brief to parse Sequence Parameter Set (SPS) |
| @@ -728,7 +757,6 @@ const SLevelLimits *GetLevelLimits(int32_t iLevelIdx, bool bConstraint3) { · 10 unmodified lines | ||
| 728 | 757 | ************************************************************************************* |
| 729 | 758 | */ |
| 730 | 759 | |
| 731 | − | |
| 732 | 760 | int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight) { |
| 733 | 761 | PBitStringAux pBs = pBsAux; |
| 734 | 762 | PSps pSps = NULL; |
| @@ -737,10 +765,10 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW · 2 unmodified lines | ||
| 737 | 765 | ProfileIdc uiProfileIdc; |
| 738 | 766 | uint8_t uiLevelIdc; |
| 739 | 767 | int32_t iSpsId; |
| 768 | + uint32_t uiTmp; | |
| 740 | 769 | bool bConstraintSetFlags[6] = { false }; |
| 741 | 770 | const bool kbUseSubsetFlag = IS_SUBSET_SPS_NAL (pNalHead->eNalUnitType); |
| 742 | 771 | |
| 743 | − | |
| 744 | 772 | if (kbUseSubsetFlag) { // SubsetSps |
| 745 | 773 | pCtx->bSubspsExistAheadFlag = true; |
| 746 | 774 | } else { // Sps |
| @@ -799,12 +827,11 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW · 52 unmodified lines | ||
| 799 | 827 | pCtx->bSpsAvailFlags[iSpsId] = true; // added for EC, 10/28/2009 |
| 800 | 828 | #endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID |
| 801 | 829 | } |
| 802 | − const SLevelLimits *pSLevelLimits = GetLevelLimits(uiLevelIdc, bConstraintSetFlags[3]); | |
| 830 | + const SLevelLimits* pSLevelLimits = GetLevelLimits (uiLevelIdc, bConstraintSetFlags[3]); | |
| 803 | 831 | if (NULL == pSLevelLimits) { |
| 804 | − WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): level_idx (%d).\n", uiLevelIdc); | |
| 805 | − return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE); | |
| 806 | − } | |
| 807 | − else pSps->pSLevelLimits = pSLevelLimits; | |
| 832 | + WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): level_idx (%d).\n", uiLevelIdc); | |
| 833 | + return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE); | |
| 834 | + } else pSps->pSLevelLimits = pSLevelLimits; | |
| 808 | 835 | // syntax elements in default |
| 809 | 836 | pSps->uiChromaFormatIdc = 1; |
| 810 | 837 | pSps->uiBitDepthLuma = |
| @@ -845,19 +872,29 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW · 34 unmodified lines | ||
| 845 | 872 | return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE); |
| 846 | 873 | } |
| 847 | 874 | } |
| 848 | − | |
| 849 | − pSps->uiLog2MaxFrameNum = 4 + BsGetUe (pBs); // log2_max_frame_num_minus4 | |
| 875 | + uiTmp = BsGetUe (pBs); | |
| 876 | + WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX, "log2_max_frame_num_minus4", | |
| 877 | + GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_LOG2_MAX_FRAME_NUM_MINUS4)); | |
| 878 | + pSps->uiLog2MaxFrameNum = LOG2_MAX_FRAME_NUM_OFFSET + uiTmp; // log2_max_frame_num_minus4 | |
| 850 | 879 | pSps->uiPocType = BsGetUe (pBs); // pic_order_cnt_type |
| 851 | 880 | |
| 852 | 881 | if (0 == pSps->uiPocType) { |
| 853 | − pSps->iLog2MaxPocLsb = 4 + BsGetUe (pBs); // log2_max_pic_order_cnt_lsb_minus4 | |
| 882 | + uiTmp = BsGetUe (pBs); | |
| 883 | + // log2_max_pic_order_cnt_lsb_minus4 should be in range 0 to 12, inclusive. (sec. 7.4.3) | |
| 884 | + WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4_MAX, "log2_max_pic_order_cnt_lsb_minus4", | |
| 885 | + GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4)); | |
| 886 | + pSps->iLog2MaxPocLsb = LOG2_MAX_PIC_ORDER_CNT_LSB_OFFSET + uiTmp; // log2_max_pic_order_cnt_lsb_minus4 | |
| 854 | 887 | |
| 855 | 888 | } else if (1 == pSps->uiPocType) { |
| 856 | 889 | int32_t i; |
| 857 | 890 | pSps->bDeltaPicOrderAlwaysZeroFlag = !!BsGetOneBit (pBs); // bDeltaPicOrderAlwaysZeroFlag |
| 858 | 891 | pSps->iOffsetForNonRefPic = BsGetSe (pBs); // iOffsetForNonRefPic |
| 859 | 892 | pSps->iOffsetForTopToBottomField = BsGetSe (pBs); // iOffsetForTopToBottomField |
| 860 | − pSps->iNumRefFramesInPocCycle = BsGetUe (pBs); // num_ref_frames_in_pic_order_cnt_cycle | |
| 893 | + uiTmp = BsGetUe (pBs); | |
| 894 | + WELS_CHECK_SE_UPPER_ERROR (uiTmp, SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX, | |
| 895 | + "num_ref_frames_in_pic_order_cnt_cycle", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, | |
| 896 | + ERR_INFO_INVALID_NUM_REF_FRAME_IN_PIC_ORDER_CNT_CYCLE)); | |
| 897 | + pSps->iNumRefFramesInPocCycle = uiTmp; // num_ref_frames_in_pic_order_cnt_cycle | |
| 861 | 898 | for (i = 0; i < pSps->iNumRefFramesInPocCycle; i++) |
| 862 | 899 | pSps->iOffsetForRefFrame[ i ] = BsGetSe (pBs); // iOffsetForRefFrame[ i ] |
| 863 | 900 | } |
| @@ -868,11 +905,39 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW · 4 unmodified lines | ||
| 868 | 905 | |
| 869 | 906 | pSps->iNumRefFrames = BsGetUe (pBs); // max_num_ref_frames |
| 870 | 907 | pSps->bGapsInFrameNumValueAllowedFlag = !!BsGetOneBit (pBs); // bGapsInFrameNumValueAllowedFlag |
| 871 | − pSps->iMbWidth = 1 + BsGetUe (pBs); // pic_width_in_mbs_minus1 | |
| 872 | − pSps->iMbHeight = 1 + BsGetUe (pBs); // pic_height_in_map_units_minus1 | |
| 908 | + uiTmp = BsGetUe (pBs); // pic_width_in_mbs_minus1 | |
| 909 | + if (uiTmp == 0xffffffff) { | |
| 910 | + WelsLog (pCtx, WELS_LOG_ERROR, " pic_width_in_mbs read error!\n"); | |
| 911 | + return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MB_SIZE_INFO); | |
| 912 | + } | |
| 913 | + pSps->iMbWidth = PIC_WIDTH_IN_MBS_OFFSET + uiTmp; | |
| 914 | + if ((uint64_t) (pSps->iMbWidth * pSps->iMbWidth) > (8 * pSLevelLimits->iMaxFS)) { | |
| 915 | + WelsLog (pCtx, WELS_LOG_WARNING, " the pic_width_in_mbs exceeds the level limits!\n"); | |
| 916 | + } | |
| 917 | + uiTmp = BsGetUe (pBs); // pic_height_in_map_units_minus1 | |
| 918 | + if (uiTmp == 0xffffffff) { | |
| 919 | + WelsLog (pCtx, WELS_LOG_ERROR, " pic_height_in_mbs read error!\n"); | |
| 920 | + return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MB_SIZE_INFO); | |
| 921 | + } | |
| 922 | + pSps->iMbHeight = PIC_HEIGHT_IN_MAP_UNITS_OFFSET + uiTmp; | |
| 923 | + if ((uint64_t) (pSps->iMbHeight * pSps->iMbHeight) > (8 * pSLevelLimits->iMaxFS)) { | |
| 924 | + WelsLog (pCtx, WELS_LOG_WARNING, " the pic_height_in_mbs exceeds the level limits!\n"); | |
| 925 | + } | |
| 873 | 926 | pSps->uiTotalMbCount = pSps->iMbWidth * pSps->iMbHeight; |
| 927 | + if (pSps->uiTotalMbCount > (uint32_t)pSLevelLimits->iMaxFS) { | |
| 928 | + WelsLog (pCtx, WELS_LOG_WARNING, " the total count of mb exceeds the level limits!\n"); | |
| 929 | + } | |
| 930 | + WELS_CHECK_SE_UPPER_ERROR (pSps->iNumRefFrames, SPS_MAX_NUM_REF_FRAMES_MAX, "max_num_ref_frames", | |
| 931 | + GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MAX_NUM_REF_FRAMES)); | |
| 932 | + // here we check max_num_ref_frames | |
| 933 | + uint32_t uiMaxDpbMbs = pSLevelLimits->iMaxDPBMbs; | |
| 934 | + uint32_t uiMaxDpbFrames = uiMaxDpbMbs / pSps->uiTotalMbCount; | |
| 935 | + if (uiMaxDpbFrames > SPS_MAX_NUM_REF_FRAMES_MAX) | |
| 936 | + uiMaxDpbFrames = SPS_MAX_NUM_REF_FRAMES_MAX; | |
| 937 | + if ((uint32_t)pSps->iNumRefFrames > uiMaxDpbFrames) { | |
| 938 | + WelsLog (pCtx, WELS_LOG_WARNING, " max_num_ref_frames exceeds level limits!\n"); | |
| 939 | + } | |
| 874 | 940 | pSps->bFrameMbsOnlyFlag = !!BsGetOneBit (pBs); // frame_mbs_only_flag |
| 875 | − | |
| 876 | 941 | if (!pSps->bFrameMbsOnlyFlag) { |
| 877 | 942 | WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): frame_mbs_only_flag (%d) not supported.\n", pSps->bFrameMbsOnlyFlag); |
| 878 | 943 | 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 · 3 unmodified lines | ||
| 882 | 947 | if (pSps->bFrameCroppingFlag) { |
| 883 | 948 | pSps->sFrameCrop.iLeftOffset = BsGetUe (pBs); // frame_crop_left_offset |
| 884 | 949 | pSps->sFrameCrop.iRightOffset = BsGetUe (pBs); // frame_crop_right_offset |
| 950 | + if ((pSps->sFrameCrop.iLeftOffset + pSps->sFrameCrop.iRightOffset) > ((int32_t)pSps->iMbWidth * 16 / 2)) { | |
| 951 | + WelsLog (pCtx, WELS_LOG_WARNING, "frame_crop_left_offset + frame_crop_right_offset exceeds limits!\n"); | |
| 952 | + } | |
| 885 | 953 | pSps->sFrameCrop.iTopOffset = BsGetUe (pBs); // frame_crop_top_offset |
| 886 | 954 | pSps->sFrameCrop.iBottomOffset = BsGetUe (pBs); // frame_crop_bottom_offset |
| 955 | + if ((pSps->sFrameCrop.iTopOffset + pSps->sFrameCrop.iBottomOffset) > ((int32_t)pSps->iMbHeight * 16 / 2)) { | |
| 956 | + WelsLog (pCtx, WELS_LOG_WARNING, "frame_crop_top_offset + frame_crop_right_offset exceeds limits!\n"); | |
| 957 | + } | |
| 887 | 958 | } else { |
| 888 | 959 | pSps->sFrameCrop.iLeftOffset = 0; // frame_crop_left_offset |
| 889 | 960 | pSps->sFrameCrop.iRightOffset = 0; // frame_crop_right_offset |
| @@ -957,7 +1028,7 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux) · 67 unmodified lines | ||
| 957 | 1028 | pPps->bEntropyCodingModeFlag = !!BsGetOneBit (pBsAux); |
| 958 | 1029 | pPps->bPicOrderPresentFlag = !!BsGetOneBit (pBsAux); |
| 959 | 1030 | |
| 960 | − pPps->uiNumSliceGroups = 1 + BsGetUe (pBsAux); | |
| 1031 | + pPps->uiNumSliceGroups = NUM_SLICE_GROUPS_OFFSET + BsGetUe (pBsAux); | |
| 961 | 1032 | |
| 962 | 1033 | if (pPps->uiNumSliceGroups > MAX_SLICEGROUP_IDS) { |
| 963 | 1034 | return ERR_INFO_INVALID_SLICEGROUP; |
| @@ -974,7 +1045,7 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux) · 10 unmodified lines | ||
| 974 | 1045 | switch (pPps->uiSliceGroupMapType) { |
| 975 | 1046 | case 0: |
| 976 | 1047 | for (iTmp = 0; iTmp < pPps->uiNumSliceGroups; iTmp++) { |
| 977 | − pPps->uiRunLength[iTmp] = 1 + BsGetUe (pBsAux); | |
| 1048 | + pPps->uiRunLength[iTmp] = RUN_LENGTH_OFFSET + BsGetUe (pBsAux); | |
| 978 | 1049 | } |
| 979 | 1050 | break; |
| 980 | 1051 | default: |
| @@ -982,8 +1053,8 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux) · 1 unmodified line | ||
| 982 | 1053 | } |
| 983 | 1054 | } |
| 984 | 1055 | |
| 985 | − pPps->uiNumRefIdxL0Active = 1 + BsGetUe (pBsAux); | |
| 986 | − pPps->uiNumRefIdxL1Active = 1 + BsGetUe (pBsAux); | |
| 1056 | + pPps->uiNumRefIdxL0Active = NUM_REF_IDX_L0_DEFAULT_ACTIVE_OFFSET + BsGetUe (pBsAux); | |
| 1057 | + pPps->uiNumRefIdxL1Active = NUM_REF_IDX_L1_DEFAULT_ACTIVE_OFFSET + BsGetUe (pBsAux); | |
| 987 | 1058 | |
| 988 | 1059 | if (pPps->uiNumRefIdxL0Active > MAX_REF_PIC_COUNT || |
| 989 | 1060 | pPps->uiNumRefIdxL1Active > MAX_REF_PIC_COUNT) { |
| @@ -998,10 +1069,15 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux) · 8 unmodified lines | ||
| 998 | 1069 | return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP); |
| 999 | 1070 | } |
| 1000 | 1071 | |
| 1001 | − pPps->iPicInitQp = 26 + BsGetSe (pBsAux); | |
| 1002 | − pPps->iPicInitQs = 26 + BsGetSe (pBsAux); | |
| 1003 | − | |
| 1072 | + pPps->iPicInitQp = PIC_INIT_QP_OFFSET + BsGetSe (pBsAux); | |
| 1073 | + WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQp, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qp_minus26 + 26", | |
| 1074 | + GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_PIC_INIT_QP)); | |
| 1075 | + pPps->iPicInitQs = PIC_INIT_QS_OFFSET + BsGetSe (pBsAux); | |
| 1076 | + WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQs, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qs_minus26 + 26", | |
| 1077 | + GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_PIC_INIT_QS)); | |
| 1004 | 1078 | pPps->iChromaQpIndexOffset = BsGetSe (pBsAux); |
| 1079 | + WELS_CHECK_SE_BOTH_ERROR (pPps->iChromaQpIndexOffset, PPS_CHROMA_QP_INDEX_OFFSET_MIN, PPS_CHROMA_QP_INDEX_OFFSET_MAX, | |
| 1080 | + "chroma_qp_index_offset", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET)); | |
| 1005 | 1081 | pPps->bDeblockingFilterControlPresentFlag = !!BsGetOneBit (pBsAux); |
| 1006 | 1082 | pPps->bConstainedIntraPredFlag = !!BsGetOneBit (pBsAux); |
| 1007 | 1083 | pPps->bRedundantPicCntPresentFlag = !!BsGetOneBit (pBsAux); |
| @@ -155,7 +155,7 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) { · 154 unmodified lines | ||
| 155 | 155 | int32_t iList = 0; |
| 156 | 156 | const ESliceType keSt = pSh->eSliceType; |
| 157 | 157 | PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering; |
| 158 | − | |
| 158 | + PSps pSps = pSh->pSps; | |
| 159 | 159 | if (keSt == I_SLICE || keSt == SI_SLICE) |
| 160 | 160 | return ERR_NONE; |
| 161 | 161 | |
| @@ -166,7 +166,7 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) { · 4 unmodified lines | ||
| 166 | 166 | if (pRefPicListReordering->bRefPicListReorderingFlag[iList]) { |
| 167 | 167 | int32_t iIdx = 0; |
| 168 | 168 | do { |
| 169 | − const uint8_t kuiIdc = BsGetUe (pBs); | |
| 169 | + const uint32_t kuiIdc = BsGetUe (pBs); | |
| 170 | 170 | |
| 171 | 171 | //Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)--- |
| 172 | 172 | if ((iIdx >= MAX_REF_PIC_COUNT) || (kuiIdc > 3)) { |
| @@ -180,7 +180,12 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) { · 7 unmodified lines | ||
| 180 | 180 | return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING); |
| 181 | 181 | |
| 182 | 182 | if (kuiIdc == 0 || kuiIdc == 1) { |
| 183 | − pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = BsGetUe (pBs); // uiAbsDiffPicNumMinus1 | |
| 183 | + // abs_diff_pic_num_minus1 should be in range 0 to MaxPicNum-1, MaxPicNum is derived as | |
| 184 | + // 2^(4+log2_max_frame_num_minus4) | |
| 185 | + uint32_t uiTmp = BsGetUe (pBs); | |
| 186 | + WELS_CHECK_SE_UPPER_ERROR_NOLOG (uiTmp, (1 << pSps->uiLog2MaxFrameNum), "abs_diff_pic_num_minus1", | |
| 187 | + GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING)); | |
| 188 | + pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = uiTmp; // uiAbsDiffPicNumMinus1 | |
| 184 | 189 | } else if (kuiIdc == 2) { |
| 185 | 190 | pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum = BsGetUe (pBs); |
| 186 | 191 | } |
| @@ -199,7 +204,7 @@ int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) { · 12 unmodified lines | ||
| 199 | 204 | int32_t ParseDecRefPicMarking (PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps, |
| 200 | 205 | const bool kbIdrFlag) { |
| 201 | 206 | PRefPicMarking const kpRefMarking = &pSh->sRefMarking; |
| 202 | − | |
| 207 | + PRefPic pRefPic = &pCtx->sRefPic; | |
| 203 | 208 | if (kbIdrFlag) { |
| 204 | 209 | kpRefMarking->bNoOutputOfPriorPicsFlag = !!BsGetOneBit (pBs); |
| 205 | 210 | kpRefMarking->bLongTermRefFlag = !!BsGetOneBit (pBs); |
| @@ -447,6 +452,13 @@ int32_t CheckSpsId (PWelsDecoderContext pCtx, PSubsetSps* ppSubsetSps, PSps* ppS · 241 unmodified lines | ||
| 447 | 452 | } |
| 448 | 453 | |
| 449 | 454 | #endif |
| 455 | + | |
| 456 | +#define SLICE_HEADER_IDR_PIC_ID_MAX 65535 | |
| 457 | +#define SLICE_HEADER_REDUNDANT_PIC_CNT_MAX 127 | |
| 458 | +#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN -12 | |
| 459 | +#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX 12 | |
| 460 | +#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN -12 | |
| 461 | +#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX 12 | |
| 450 | 462 | /* |
| 451 | 463 | * decode_slice_header_avc |
| 452 | 464 | * Parse slice header of bitstream in avc for storing data structure |
| @@ -465,6 +477,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 12 unmodified lines | ||
| 465 | 477 | int32_t iRet = ERR_NONE; |
| 466 | 478 | uint8_t uiSliceType = 0; |
| 467 | 479 | uint8_t uiQualityId = BASE_QUALITY_ID; |
| 480 | + uint32_t uiTmp; | |
| 468 | 481 | bool bIdrFlag = false; |
| 469 | 482 | bool bSgChangeCycleInvolved = false; // involved slice group change cycle ? |
| 470 | 483 | |
| @@ -489,6 +502,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 18 unmodified lines | ||
| 489 | 502 | |
| 490 | 503 | kpCurNal->sNalData.sVclNal.bSliceHeaderExtFlag = kbExtensionFlag; |
| 491 | 504 | |
| 505 | + // first_mb_in_slice | |
| 492 | 506 | pSliceHead->iFirstMbInSlice = BsGetUe (pBs); |
| 493 | 507 | |
| 494 | 508 | uiSliceType = BsGetUe (pBs); |
| @@ -500,7 +514,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 5 unmodified lines | ||
| 500 | 514 | if (uiSliceType > 4) |
| 501 | 515 | uiSliceType -= 5; |
| 502 | 516 | |
| 503 | − if((eNalType == NAL_UNIT_CODED_SLICE_IDR) && (uiSliceType != 2)){ | |
| 517 | + if ((eNalType == NAL_UNIT_CODED_SLICE_IDR) && (uiSliceType != 2)) { | |
| 504 | 518 | WelsLog (pCtx, WELS_LOG_WARNING, "Invalid slice type(%d) in IDR picture. \n", uiSliceType); |
| 505 | 519 | return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE); |
| 506 | 520 | } |
| @@ -566,6 +580,9 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 59 unmodified lines | ||
| 566 | 580 | WelsLog (pCtx, WELS_LOG_WARNING, "non existing SPS referenced\n"); |
| 567 | 581 | return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS); |
| 568 | 582 | } |
| 583 | + // check first_mb_in_slice | |
| 584 | + WELS_CHECK_SE_UPPER_ERROR ((uint32_t) (pSliceHead->iFirstMbInSlice), pSps->uiTotalMbCount, "first_mb_in_slice", | |
| 585 | + GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FIRST_MB_IN_SLICE)); | |
| 569 | 586 | pSliceHead->iFrameNum = BsGetBits (pBs, pSps->uiLog2MaxFrameNum); |
| 570 | 587 | |
| 571 | 588 | pSliceHead->bFieldPicFlag = false; |
| @@ -584,7 +601,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 12 unmodified lines | ||
| 584 | 601 | pSliceHead->iFrameNum); |
| 585 | 602 | return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FRAME_NUM); |
| 586 | 603 | } |
| 587 | − pSliceHead->uiIdrPicId = BsGetUe (pBs); /* uiIdrPicId */ | |
| 604 | + uiTmp = BsGetUe (pBs); | |
| 605 | + // standard 7.4.3 idr_pic_id should be in range 0 to 65535, inclusive. | |
| 606 | + WELS_CHECK_SE_UPPER_ERROR (uiTmp, SLICE_HEADER_IDR_PIC_ID_MAX, "idr_pic_id", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, | |
| 607 | + ERR_INFO_INVALID_IDR_PIC_ID)); | |
| 608 | + pSliceHead->uiIdrPicId = uiTmp; /* uiIdrPicId */ | |
| 588 | 609 | #ifdef LONG_TERM_REF |
| 589 | 610 | pCtx->uiCurIdrPicId = pSliceHead->uiIdrPicId; |
| 590 | 611 | #endif |
| @@ -606,7 +627,11 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 15 unmodified lines | ||
| 606 | 627 | |
| 607 | 628 | pSliceHead->iRedundantPicCnt = 0; |
| 608 | 629 | if (pPps->bRedundantPicCntPresentFlag) { |
| 609 | − pSliceHead->iRedundantPicCnt = BsGetUe (pBs); | |
| 630 | + uiTmp = BsGetUe (pBs); | |
| 631 | + // standard section 7.4.3, redundant_pic_cnt should be in range 0 to 127, inclusive. | |
| 632 | + WELS_CHECK_SE_UPPER_ERROR (uiTmp, SLICE_HEADER_REDUNDANT_PIC_CNT_MAX, "redundant_pic_cnt", | |
| 633 | + GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT)); | |
| 634 | + pSliceHead->iRedundantPicCnt = uiTmp; | |
| 610 | 635 | } |
| 611 | 636 | |
| 612 | 637 | //set defaults, might be overriden a few line later |
| @@ -695,7 +720,13 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 82 unmodified lines | ||
| 695 | 720 | } |
| 696 | 721 | if (pSliceHead->uiDisableDeblockingFilterIdc != 1) { |
| 697 | 722 | pSliceHead->iSliceAlphaC0Offset = BsGetSe (pBs) * 2; // slice_alpha_c0_offset_div2 |
| 723 | + WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceAlphaC0Offset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN, | |
| 724 | + SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, | |
| 725 | + ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2)); | |
| 698 | 726 | pSliceHead->iSliceBetaOffset = BsGetSe (pBs) * 2; // iSliceBetaOffset |
| 727 | + WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceBetaOffset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN, | |
| 728 | + SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_beta_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, | |
| 729 | + ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2)); | |
| 699 | 730 | } |
| 700 | 731 | } |
| 701 | 732 | |
| @@ -731,7 +762,14 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co · 29 unmodified lines | ||
| 731 | 762 | } |
| 732 | 763 | if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc != 1) { |
| 733 | 764 | pSliceHeadExt->iInterLayerSliceAlphaC0Offset = BsGetSe (pBs) << 1; |
| 765 | + WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceAlphaC0Offset, | |
| 766 | + SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX, | |
| 767 | + "inter_layer_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, | |
| 768 | + ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2)); | |
| 734 | 769 | pSliceHeadExt->iInterLayerSliceBetaOffset = BsGetSe (pBs) << 1; |
| 770 | + WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceBetaOffset, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN, | |
| 771 | + SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX, "inter_layer_slice_beta_offset_div2 * 2", | |
| 772 | + GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2)); | |
| 735 | 773 | } |
| 736 | 774 | } |
| 737 | 775 | |
| @@ -985,6 +985,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 984 unmodified lines | ||
| 985 | 985 | PBitStringAux pBs) { |
| 986 | 986 | PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer; |
| 987 | 987 | PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; |
| 988 | + PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0]; | |
| 988 | 989 | int32_t iNumRefFrames = pSliceHeader->pSps->iNumRefFrames; |
| 989 | 990 | int32_t iRefCount[2]; |
| 990 | 991 | PDqLayer pCurDqLayer = pCtx->pCurDqLayer; |
| @@ -992,7 +993,8 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 1 unmodified line | ||
| 992 | 993 | int32_t iMbXy = pCurDqLayer->iMbXyIndex; |
| 993 | 994 | int32_t iMotionPredFlag[4]; |
| 994 | 995 | int16_t iMv[2] = {0}; |
| 995 | − | |
| 996 | + int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv; | |
| 997 | + int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv; | |
| 996 | 998 | iMotionPredFlag[0] = iMotionPredFlag[1] = iMotionPredFlag[2] = iMotionPredFlag[3] = |
| 997 | 999 | pSlice->sSliceHeaderExt.bDefaultMotionPredFlag; |
| 998 | 1000 | iRefCount[0] = pSliceHeader->uiRefCount[0]; |
| @@ -1000,13 +1002,15 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 1 unmodified line | ||
| 1000 | 1002 | |
| 1001 | 1003 | switch (pCurDqLayer->pMbType[iMbXy]) { |
| 1002 | 1004 | case MB_TYPE_16x16: { |
| 1003 | − int8_t iRefIdx = 0; | |
| 1005 | + int32_t iRefIdx = 0; | |
| 1004 | 1006 | if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) { |
| 1005 | 1007 | iMotionPredFlag[0] = BsGetOneBit (pBs); |
| 1006 | 1008 | } |
| 1007 | 1009 | if (iMotionPredFlag[0] == 0) { |
| 1008 | 1010 | iRefIdx = BsGetTe0 (pBs, iRefCount[0]); |
| 1009 | − if (iRefIdx < 0 || iRefIdx >= iNumRefFrames) { //error ref_idx | |
| 1011 | + // Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive | |
| 1012 | + // ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1. | |
| 1013 | + if ((iRefIdx < 0) || (iRefIdx >= iRefCount[0]) || (ppRefPic[iRefIdx] == NULL)) { //error ref_idx | |
| 1010 | 1014 | return ERR_INFO_INVALID_REF_INDEX; |
| 1011 | 1015 | } |
| 1012 | 1016 | } else { |
| @@ -1017,7 +1021,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 4 unmodified lines | ||
| 1017 | 1021 | |
| 1018 | 1022 | iMv[0] += BsGetSe (pBs); |
| 1019 | 1023 | iMv[1] += BsGetSe (pBs); |
| 1020 | − | |
| 1024 | + WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv"); | |
| 1021 | 1025 | UpdateP16x16MotionInfo (pCurDqLayer, iRefIdx, iMv); |
| 1022 | 1026 | } |
| 1023 | 1027 | break; |
| @@ -1035,7 +1039,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 11 unmodified lines | ||
| 1035 | 1039 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP); |
| 1036 | 1040 | } |
| 1037 | 1041 | iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]); |
| 1038 | − if (iRefIdx[i] < 0 || iRefIdx[i] >= iNumRefFrames) { //error ref_idx | |
| 1042 | + if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx | |
| 1039 | 1043 | return ERR_INFO_INVALID_REF_INDEX; |
| 1040 | 1044 | } |
| 1041 | 1045 | } |
| @@ -1044,7 +1048,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 2 unmodified lines | ||
| 1044 | 1048 | |
| 1045 | 1049 | iMv[0] += BsGetSe (pBs); |
| 1046 | 1050 | iMv[1] += BsGetSe (pBs); |
| 1047 | − | |
| 1051 | + WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv"); | |
| 1048 | 1052 | UpdateP16x8MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv); |
| 1049 | 1053 | } |
| 1050 | 1054 | } |
| @@ -1060,7 +1064,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 9 unmodified lines | ||
| 1060 | 1064 | for (i = 0; i < 2; i++) { |
| 1061 | 1065 | if (iMotionPredFlag[i] == 0) { |
| 1062 | 1066 | iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]); |
| 1063 | − if (iRefIdx[i] < 0 || iRefIdx[i] >= iNumRefFrames) { //error ref_idx | |
| 1067 | + if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx | |
| 1064 | 1068 | return ERR_INFO_INVALID_REF_INDEX; |
| 1065 | 1069 | } |
| 1066 | 1070 | } else { |
| @@ -1074,14 +1078,14 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 7 unmodified lines | ||
| 1074 | 1078 | |
| 1075 | 1079 | iMv[0] += BsGetSe (pBs); |
| 1076 | 1080 | iMv[1] += BsGetSe (pBs); |
| 1077 | − | |
| 1081 | + WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv"); | |
| 1078 | 1082 | UpdateP8x16MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, i << 2, iRefIdx[i], iMv); |
| 1079 | 1083 | } |
| 1080 | 1084 | } |
| 1081 | 1085 | break; |
| 1082 | 1086 | case MB_TYPE_8x8: |
| 1083 | 1087 | case MB_TYPE_8x8_REF0: { |
| 1084 | − int8_t iRefIdx[4] = {0}, iSubPartCount[4], iPartWidth[4]; | |
| 1088 | + int32_t iRefIdx[4] = {0}, iSubPartCount[4], iPartWidth[4]; | |
| 1085 | 1089 | uint32_t uiSubMbType; |
| 1086 | 1090 | |
| 1087 | 1091 | if (MB_TYPE_8x8_REF0 == pCurDqLayer->pMbType[iMbXy]) { |
| @@ -1116,7 +1120,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 28 unmodified lines | ||
| 1116 | 1120 | |
| 1117 | 1121 | if (iMotionPredFlag[i] == 0) { |
| 1118 | 1122 | iRefIdx[i] = BsGetTe0 (pBs, iRefCount[0]); |
| 1119 | − if (iRefIdx[i] < 0 || iRefIdx[i] >= iNumRefFrames) { //error ref_idx | |
| 1123 | + if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx | |
| 1120 | 1124 | return ERR_INFO_INVALID_REF_INDEX; |
| 1121 | 1125 | } |
| 1122 | 1126 | |
| @@ -1149,7 +1153,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M · 26 unmodified lines | ||
| 1149 | 1153 | |
| 1150 | 1154 | iMv[0] += BsGetSe (pBs); |
| 1151 | 1155 | iMv[1] += BsGetSe (pBs); |
| 1152 | − | |
| 1156 | + WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv"); | |
| 1153 | 1157 | if (SUB_MB_TYPE_8x8 == uiSubMbType) { |
| 1154 | 1158 | ST32 (pCurDqLayer->pMv[0][iMbXy][uiScan4Idx], LD32 (iMv)); |
| 1155 | 1159 | ST32 (pCurDqLayer->pMv[0][iMbXy][uiScan4Idx + 1], LD32 (iMv)); |