diff --git a/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.cpp b/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.cpp index 5ecac9229f..d0b8888072 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.cpp @@ -26,21 +26,25 @@ ErrorOr BooleanDecoder::initialize(ReadonlyBytes data) // NOTE: As noted below in fill_reservoir(), we read in multi-byte-sized chunks, // so here we will deviate from the standard to count in bytes rather than bits. - auto decoder = BooleanDecoder { data.data(), data.size() }; - TRY(decoder.fill_reservoir()); - return decoder; + return BooleanDecoder { data.data(), data.size() }; } // Instead of filling the value field one bit at a time as the spec suggests, we store the // data to be read in a reservoir of greater than one byte. This allows us to read out data // for the entire reservoir at once, avoiding a lot of branch misses in read_bool(). -ErrorOr BooleanDecoder::fill_reservoir() +void BooleanDecoder::fill_reservoir() { if (m_value_bits_left > 8) - return {}; + return; - if (m_bytes_left == 0) - return Error::from_string_literal("Range decoder is out of data"); + // Defer errors until the decode is finalized, so the work to check for errors and return them only has + // to be done once. Not refilling the reservoir here will only result in reading out all zeroes until + // the range decode is finished. + if (m_bytes_left == 0) { + dbgln_if(VPX_DEBUG, "BooleanDecoder has read past the end of the coded range"); + m_overread = true; + return; + } // Read the data into the most significant bits of a variable. auto read_size = min(reserve_bytes, m_bytes_left); @@ -56,11 +60,10 @@ ErrorOr BooleanDecoder::fill_reservoir() read_value >>= m_value_bits_left; m_value |= read_value; m_value_bits_left += read_size * 8; - return {}; } // 9.2.2 Boolean decoding process -ErrorOr BooleanDecoder::read_bool(u8 probability) +bool BooleanDecoder::read_bool(u8 probability) { auto split = 1u + (((m_range - 1u) * probability) >> 8u); // The actual value being read resides in the most significant 8 bits @@ -82,23 +85,26 @@ ErrorOr BooleanDecoder::read_bool(u8 probability) m_value <<= bits_to_shift_into_range; m_value_bits_left -= bits_to_shift_into_range; - TRY(fill_reservoir()); + fill_reservoir(); return return_bool; } // 9.2.4 Parsing process for read_literal -ErrorOr BooleanDecoder::read_literal(u8 bits) +u8 BooleanDecoder::read_literal(u8 bits) { u8 return_value = 0; for (size_t i = 0; i < bits; i++) { - return_value = (2 * return_value) + TRY(read_bool(128)); + return_value = (2 * return_value) + read_bool(128); } return return_value; } ErrorOr BooleanDecoder::finish_decode() { + if (m_overread) + return Error::from_string_literal("Range decoder was read past the end of its data"); + #if VPX_DEBUG // 9.2.3 Exit process for Boolean decoder // diff --git a/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.h b/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.h index 3e64a8c91d..0a51a44e0f 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.h +++ b/Userland/Libraries/LibGfx/ImageFormats/BooleanDecoder.h @@ -20,8 +20,8 @@ public: static ErrorOr initialize(ReadonlyBytes data); /* (9.2) */ - ErrorOr read_bool(u8 probability); - ErrorOr read_literal(u8 bits); + bool read_bool(u8 probability); + u8 read_literal(u8 bits); ErrorOr finish_decode(); @@ -37,12 +37,14 @@ private: , m_value(static_cast(*data) << reserve_bits) , m_value_bits_left(8) { + fill_reservoir(); } - ErrorOr fill_reservoir(); + void fill_reservoir(); u8 const* m_data; size_t m_bytes_left { 0 }; + bool m_overread { false }; // This value will never exceed 255. If this is a u8, the compiler will generate a truncation in read_bool(). u32 m_range { 0 }; ValueType m_value { 0 }; diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoaderLossy.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPLoaderLossy.cpp index 52fa91d180..60c77debbd 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoaderLossy.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoaderLossy.cpp @@ -107,11 +107,11 @@ ErrorOr decode_webp_chunk_VP8_header(ReadonlyBytes vp8_data) namespace { // Reads n bits followed by a sign bit (0: positive, 1: negative). -ErrorOr read_signed_literal(BooleanDecoder& decoder, u8 n) +i8 read_signed_literal(BooleanDecoder& decoder, u8 n) { VERIFY(n <= 7); - i8 i = TRY(decoder.read_literal(n)); - if (TRY(decoder.read_literal(1))) + i8 i = decoder.read_literal(n); + if (decoder.read_literal(1)) i = -i; return i; } @@ -139,7 +139,7 @@ struct Segmentation { u8 macroblock_segment_tree_probabilities[3] = { 255, 255, 255 }; }; -ErrorOr decode_VP8_frame_header_segmentation(BooleanDecoder&); +Segmentation decode_VP8_frame_header_segmentation(BooleanDecoder&); // Also https://datatracker.ietf.org/doc/html/rfc6386#section-9.6 "Dequantization Indices" struct QuantizationIndices { @@ -152,14 +152,14 @@ struct QuantizationIndices { i8 uv_dc_delta { 0 }; i8 uv_ac_delta { 0 }; }; -ErrorOr decode_VP8_frame_header_quantization_indices(BooleanDecoder&); +QuantizationIndices decode_VP8_frame_header_quantization_indices(BooleanDecoder&); struct LoopFilterAdjustment { bool enable_loop_filter_adjustment { false }; i8 ref_frame_delta[4] {}; i8 mb_mode_delta[4] {}; }; -ErrorOr decode_VP8_frame_header_loop_filter_adjustment(BooleanDecoder&); +LoopFilterAdjustment decode_VP8_frame_header_loop_filter_adjustment(BooleanDecoder&); using CoefficientProbabilities = Prob[4][8][3][num_dct_tokens - 1]; ErrorOr decode_VP8_frame_header_coefficient_probabilities(BooleanDecoder&, CoefficientProbabilities); @@ -210,42 +210,42 @@ ErrorOr decode_VP8_frame_header(BooleanDecoder& decoder) FrameHeader header; // In the VP8 spec, this is in an `if (key_frames)`, but webp files only have key frames. - header.color_space = ColorSpaceAndPixelType { TRY(L(1)) }; - header.clamping_type = ClampingSpecification { TRY(L(1)) }; + header.color_space = ColorSpaceAndPixelType { L(1) }; + header.clamping_type = ClampingSpecification { L(1) }; dbgln_if(WEBP_DEBUG, "color_space {} clamping_type {}", (int)header.color_space, (int)header.clamping_type); // https://datatracker.ietf.org/doc/html/rfc6386#section-9.3 "Segment-Based Adjustments" - header.is_segmentation_enabled = TRY(L(1)); + header.is_segmentation_enabled = L(1); dbgln_if(WEBP_DEBUG, "segmentation_enabled {}", header.is_segmentation_enabled); if (header.is_segmentation_enabled) - header.segmentation = TRY(decode_VP8_frame_header_segmentation(decoder)); + header.segmentation = decode_VP8_frame_header_segmentation(decoder); - header.filter_type = FilterType { TRY(L(1)) }; - header.loop_filter_level = TRY(L(6)); - header.sharpness_level = TRY(L(3)); + header.filter_type = FilterType { L(1) }; + header.loop_filter_level = L(6); + header.sharpness_level = L(3); dbgln_if(WEBP_DEBUG, "filter_type {} loop_filter_level {} sharpness_level {}", (int)header.filter_type, header.loop_filter_level, header.sharpness_level); - header.loop_filter_adjustment = TRY(decode_VP8_frame_header_loop_filter_adjustment(decoder)); + header.loop_filter_adjustment = decode_VP8_frame_header_loop_filter_adjustment(decoder); - u8 log2_nbr_of_dct_partitions = TRY(L(2)); + u8 log2_nbr_of_dct_partitions = L(2); dbgln_if(WEBP_DEBUG, "log2_nbr_of_dct_partitions {}", log2_nbr_of_dct_partitions); header.number_of_dct_partitions = 1 << log2_nbr_of_dct_partitions; - header.quantization_indices = TRY(decode_VP8_frame_header_quantization_indices(decoder)); + header.quantization_indices = decode_VP8_frame_header_quantization_indices(decoder); // In the VP8 spec, this is in an `if (key_frames)` followed by a lengthy `else`, but webp files only have key frames. - u8 refresh_entropy_probs = TRY(L(1)); // Has no effect in webp files. + u8 refresh_entropy_probs = L(1); // Has no effect in webp files. dbgln_if(WEBP_DEBUG, "refresh_entropy_probs {}", refresh_entropy_probs); memcpy(header.coefficient_probabilities, DEFAULT_COEFFICIENT_PROBABILITIES, sizeof(header.coefficient_probabilities)); TRY(decode_VP8_frame_header_coefficient_probabilities(decoder, header.coefficient_probabilities)); // https://datatracker.ietf.org/doc/html/rfc6386#section-9.11 "Remaining Frame Header Data (Key Frame)" - header.enable_skipping_of_macroblocks_containing_only_zero_coefficients = TRY(L(1)); + header.enable_skipping_of_macroblocks_containing_only_zero_coefficients = L(1); dbgln_if(WEBP_DEBUG, "mb_no_skip_coeff {}", header.enable_skipping_of_macroblocks_containing_only_zero_coefficients); if (header.enable_skipping_of_macroblocks_containing_only_zero_coefficients) { - header.probability_skip_false = TRY(L(8)); + header.probability_skip_false = L(8); dbgln_if(WEBP_DEBUG, "prob_skip_false {}", header.probability_skip_false); } @@ -254,35 +254,35 @@ ErrorOr decode_VP8_frame_header(BooleanDecoder& decoder) return header; } -ErrorOr decode_VP8_frame_header_segmentation(BooleanDecoder& decoder) +Segmentation decode_VP8_frame_header_segmentation(BooleanDecoder& decoder) { // Corresponds to "update_segmentation()" in section 19.2 of the spec. Segmentation segmentation; - segmentation.update_macroblock_segmentation_map = TRY(L(1)); - u8 update_segment_feature_data = TRY(L(1)); + segmentation.update_macroblock_segmentation_map = L(1); + u8 update_segment_feature_data = L(1); dbgln_if(WEBP_DEBUG, "update_mb_segmentation_map {} update_segment_feature_data {}", segmentation.update_macroblock_segmentation_map, update_segment_feature_data); if (update_segment_feature_data) { - segmentation.segment_feature_mode = static_cast(TRY(L(1))); + segmentation.segment_feature_mode = static_cast(L(1)); dbgln_if(WEBP_DEBUG, "segment_feature_mode {}", (int)segmentation.segment_feature_mode); for (int i = 0; i < 4; ++i) { - u8 quantizer_update = TRY(L(1)); + u8 quantizer_update = L(1); dbgln_if(WEBP_DEBUG, "quantizer_update {}", quantizer_update); if (quantizer_update) { - i8 quantizer_update_value = TRY(L_signed(7)); + i8 quantizer_update_value = L_signed(7); dbgln_if(WEBP_DEBUG, "quantizer_update_value {}", quantizer_update_value); segmentation.quantizer_update_value[i] = quantizer_update_value; } } for (int i = 0; i < 4; ++i) { - u8 loop_filter_update = TRY(L(1)); + u8 loop_filter_update = L(1); dbgln_if(WEBP_DEBUG, "loop_filter_update {}", loop_filter_update); if (loop_filter_update) { - i8 loop_filter_update_value = TRY(L_signed(6)); + i8 loop_filter_update_value = L_signed(6); dbgln_if(WEBP_DEBUG, "loop_filter_update_value {}", loop_filter_update_value); segmentation.loop_filter_update_value[i] = loop_filter_update_value; } @@ -292,10 +292,10 @@ ErrorOr decode_VP8_frame_header_segmentation(BooleanDecoder& decod if (segmentation.update_macroblock_segmentation_map) { // This reads mb_segment_tree_probs for https://datatracker.ietf.org/doc/html/rfc6386#section-10. for (int i = 0; i < 3; ++i) { - u8 segment_prob_update = TRY(L(1)); + u8 segment_prob_update = L(1); dbgln_if(WEBP_DEBUG, "segment_prob_update {}", segment_prob_update); if (segment_prob_update) { - u8 segment_prob = TRY(L(8)); + u8 segment_prob = L(8); dbgln_if(WEBP_DEBUG, "segment_prob {}", segment_prob); segmentation.macroblock_segment_tree_probabilities[i] = segment_prob; } @@ -305,7 +305,7 @@ ErrorOr decode_VP8_frame_header_segmentation(BooleanDecoder& decod return segmentation; } -ErrorOr decode_VP8_frame_header_quantization_indices(BooleanDecoder& decoder) +QuantizationIndices decode_VP8_frame_header_quantization_indices(BooleanDecoder& decoder) { // Corresponds to "quant_indices()" in section 19.2 of the spec. QuantizationIndices quantization_indices; @@ -314,52 +314,51 @@ ErrorOr decode_VP8_frame_header_quantization_indices(Boolea // Y-plane AC coefficients, called yac_qi. It is always coded and acts // as a baseline for the other 5 quantization indices, each of which is // represented by a delta from this baseline index." - quantization_indices.y_ac = TRY(L(7)); + quantization_indices.y_ac = L(7); dbgln_if(WEBP_DEBUG, "y_ac_qi {}", quantization_indices.y_ac); - auto read_delta = [&decoder](StringView name, i8* destination) -> ErrorOr { - u8 is_present = TRY(L(1)); + auto read_delta = [&decoder](StringView name, i8* destination) -> void { + u8 is_present = L(1); dbgln_if(WEBP_DEBUG, "{}_present {}", name, is_present); if (is_present) { - i8 delta = TRY(L_signed(4)); + i8 delta = L_signed(4); dbgln_if(WEBP_DEBUG, "{} {}", name, delta); *destination = delta; } - return {}; }; - TRY(read_delta("y_dc_delta"sv, &quantization_indices.y_dc_delta)); - TRY(read_delta("y2_dc_delta"sv, &quantization_indices.y2_dc_delta)); - TRY(read_delta("y2_ac_delta"sv, &quantization_indices.y2_ac_delta)); - TRY(read_delta("uv_dc_delta"sv, &quantization_indices.uv_dc_delta)); - TRY(read_delta("uv_ac_delta"sv, &quantization_indices.uv_ac_delta)); + read_delta("y_dc_delta"sv, &quantization_indices.y_dc_delta); + read_delta("y2_dc_delta"sv, &quantization_indices.y2_dc_delta); + read_delta("y2_ac_delta"sv, &quantization_indices.y2_ac_delta); + read_delta("uv_dc_delta"sv, &quantization_indices.uv_dc_delta); + read_delta("uv_ac_delta"sv, &quantization_indices.uv_ac_delta); return quantization_indices; } -ErrorOr decode_VP8_frame_header_loop_filter_adjustment(BooleanDecoder& decoder) +LoopFilterAdjustment decode_VP8_frame_header_loop_filter_adjustment(BooleanDecoder& decoder) { // Corresponds to "mb_lf_adjustments()" in section 19.2 of the spec. LoopFilterAdjustment adjustment; - adjustment.enable_loop_filter_adjustment = TRY(L(1)); + adjustment.enable_loop_filter_adjustment = L(1); if (adjustment.enable_loop_filter_adjustment) { - u8 mode_ref_lf_delta_update = TRY(L(1)); + u8 mode_ref_lf_delta_update = L(1); dbgln_if(WEBP_DEBUG, "mode_ref_lf_delta_update {}", mode_ref_lf_delta_update); if (mode_ref_lf_delta_update) { for (int i = 0; i < 4; ++i) { - u8 ref_frame_delta_update_flag = TRY(L(1)); + u8 ref_frame_delta_update_flag = L(1); dbgln_if(WEBP_DEBUG, "ref_frame_delta_update_flag {}", ref_frame_delta_update_flag); if (ref_frame_delta_update_flag) { - i8 delta = TRY(L_signed(6)); + i8 delta = L_signed(6); dbgln_if(WEBP_DEBUG, "delta {}", delta); adjustment.ref_frame_delta[i] = delta; } } for (int i = 0; i < 4; ++i) { - u8 mb_mode_delta_update_flag = TRY(L(1)); + u8 mb_mode_delta_update_flag = L(1); dbgln_if(WEBP_DEBUG, "mb_mode_delta_update_flag {}", mb_mode_delta_update_flag); if (mb_mode_delta_update_flag) { - i8 delta = TRY(L_signed(6)); + i8 delta = L_signed(6); dbgln_if(WEBP_DEBUG, "delta {}", delta); adjustment.mb_mode_delta[i] = delta; } @@ -379,8 +378,8 @@ ErrorOr decode_VP8_frame_header_coefficient_probabilities(BooleanDecoder& for (int l = 0; l < 11; l++) { // token_prob_update() says L(1) and L(8), but it's actually B(p) and L(8). // https://datatracker.ietf.org/doc/html/rfc6386#section-13.4 "Token Probability Updates" describes it correctly. - if (TRY(B(COEFFICIENT_UPDATE_PROBABILITIES[i][j][k][l]))) - coefficient_probabilities[i][j][k][l] = TRY(L(8)); + if (B(COEFFICIENT_UPDATE_PROBABILITIES[i][j][k][l])) + coefficient_probabilities[i][j][k][l] = L(8); } } } @@ -390,11 +389,11 @@ ErrorOr decode_VP8_frame_header_coefficient_probabilities(BooleanDecoder& } // https://datatracker.ietf.org/doc/html/rfc6386#section-8.1 "Tree Coding Implementation" -ErrorOr tree_decode(BooleanDecoder& decoder, ReadonlySpan tree, ReadonlyBytes probabilities, TreeIndex initial_i = 0) +u8 tree_decode(BooleanDecoder& decoder, ReadonlySpan tree, ReadonlyBytes probabilities, TreeIndex initial_i = 0) { TreeIndex i = initial_i; while (true) { - u8 b = TRY(B(probabilities[i >> 1])); + u8 b = B(probabilities[i >> 1]); i = tree[i + b]; if (i <= 0) return -i; @@ -454,12 +453,12 @@ ErrorOr> decode_VP8_macroblock_metadata(BooleanDecode MacroblockMetadata metadata; if (header.segmentation.update_macroblock_segmentation_map) - metadata.segment_id = TRY(tree_decode(decoder, MACROBLOCK_SEGMENT_TREE, header.segmentation.macroblock_segment_tree_probabilities)); + metadata.segment_id = tree_decode(decoder, MACROBLOCK_SEGMENT_TREE, header.segmentation.macroblock_segment_tree_probabilities); if (header.enable_skipping_of_macroblocks_containing_only_zero_coefficients) - metadata.skip_coefficients = TRY(B(header.probability_skip_false)); + metadata.skip_coefficients = B(header.probability_skip_false); - int intra_y_mode = TRY(tree_decode(decoder, KEYFRAME_YMODE_TREE, KEYFRAME_YMODE_PROBABILITIES)); + int intra_y_mode = tree_decode(decoder, KEYFRAME_YMODE_TREE, KEYFRAME_YMODE_PROBABILITIES); metadata.intra_y_mode = (IntraMacroblockMode)intra_y_mode; // "If the Ymode is B_PRED, it is followed by a (tree-coded) mode for each of the 16 Y subblocks." @@ -472,7 +471,7 @@ ErrorOr> decode_VP8_macroblock_metadata(BooleanDecode int A = above[mb_x * 4 + x]; int L = left[y]; - auto intra_b_mode = static_cast(TRY(tree_decode(decoder, BLOCK_MODE_TREE, KEYFRAME_BLOCK_MODE_PROBABILITIES[A][L]))); + auto intra_b_mode = static_cast(tree_decode(decoder, BLOCK_MODE_TREE, KEYFRAME_BLOCK_MODE_PROBABILITIES[A][L])); metadata.intra_b_modes[y * 4 + x] = intra_b_mode; above[mb_x * 4 + x] = intra_b_mode; @@ -489,7 +488,7 @@ ErrorOr> decode_VP8_macroblock_metadata(BooleanDecode } } - metadata.uv_mode = (IntraMacroblockMode)TRY(tree_decode(decoder, UV_MODE_TREE, KEYFRAME_UV_MODE_PROBABILITIES)); + metadata.uv_mode = (IntraMacroblockMode)tree_decode(decoder, UV_MODE_TREE, KEYFRAME_UV_MODE_PROBABILITIES); TRY(macroblock_metadata.try_append(metadata)); } @@ -557,7 +556,7 @@ int plane_index(CoefficientBlockIndex index, bool have_y2) return 3; } -ErrorOr coefficient_value_for_token(BooleanDecoder& decoder, u8 token) +i16 coefficient_value_for_token(BooleanDecoder& decoder, u8 token) { // Implements the second half of https://datatracker.ietf.org/doc/html/rfc6386#section-13.2 "Coding of Individual Coefficient Values" i16 v = static_cast(token); // For DCT_0 to DCT4 @@ -578,13 +577,13 @@ ErrorOr coefficient_value_for_token(BooleanDecoder& decoder, u8 token) // This loop corresponds to `DCTextra` in the spec in section 13.2. for (int i = 0; i < bits[token - dct_cat1]; ++i) - v = (v << 1) | TRY(decoder.read_bool(Pcats[token - dct_cat1][i])); + v = (v << 1) | decoder.read_bool(Pcats[token - dct_cat1][i]); v += starts[token - dct_cat1]; } if (v) { - if (TRY(decoder.read_bool(128))) + if (decoder.read_bool(128)) v = -v; } @@ -720,7 +719,7 @@ struct CoefficientReadingContext { using Coefficients = i16[16]; // Returns if any non-zero coefficients were read. -ErrorOr read_coefficent_block(BooleanDecoder& decoder, Coefficients out_coefficients, CoefficientBlockIndex block_index, CoefficientReadingContext& coefficient_reading_context, int mb_x, bool have_y2, int segment_id, FrameHeader const& header) +bool read_coefficent_block(BooleanDecoder& decoder, Coefficients out_coefficients, CoefficientBlockIndex block_index, CoefficientReadingContext& coefficient_reading_context, int mb_x, bool have_y2, int segment_id, FrameHeader const& header) { // Corresponds to `residual_block()` in https://datatracker.ietf.org/doc/html/rfc6386#section-19.3, // but also does dequantization of the stored values. @@ -788,11 +787,11 @@ ErrorOr read_coefficent_block(BooleanDecoder& decoder, Coefficients out_co // However, if the preceding coefficient is a DCT_0, decoding will skip // the first branch, since it is not possible for dct_eob to follow a // DCT_0." - u8 token = TRY(tree_decode(decoder, COEFFICIENT_TREE, header.coefficient_probabilities[plane][band][tricky], last_decoded_value == DCT_0 ? 2 : 0)); + u8 token = tree_decode(decoder, COEFFICIENT_TREE, header.coefficient_probabilities[plane][band][tricky], last_decoded_value == DCT_0 ? 2 : 0); if (token == dct_eob) break; - i16 v = TRY(coefficient_value_for_token(decoder, token)); + i16 v = coefficient_value_for_token(decoder, token); if (v) { // Subblock has non-0 coefficients. Store that, so that `tricky` on the next subblock is initialized correctly. @@ -817,7 +816,7 @@ struct MacroblockCoefficients { Coefficients v_coeffs[4] {}; }; -ErrorOr read_macroblock_coefficients(BooleanDecoder& decoder, FrameHeader const& header, CoefficientReadingContext& coefficient_reading_context, MacroblockMetadata const& metadata, int mb_x) +MacroblockCoefficients read_macroblock_coefficients(BooleanDecoder& decoder, FrameHeader const& header, CoefficientReadingContext& coefficient_reading_context, MacroblockMetadata const& metadata, int mb_x) { // Corresponds to `residual_data()` in https://datatracker.ietf.org/doc/html/rfc6386#section-19.3, // but also does the inverse walsh-hadamard transform if a Y2 block is present. @@ -865,7 +864,7 @@ ErrorOr read_macroblock_coefficients(BooleanDecoder& dec to_read = coefficients.v_coeffs[i - 21]; else // Y to_read = coefficients.y_coeffs[i - 1]; - subblock_has_nonzero_coefficients = TRY(read_coefficent_block(decoder, to_read, block_index, coefficient_reading_context, mb_x, have_y2, metadata.segment_id, header)); + subblock_has_nonzero_coefficients = read_coefficent_block(decoder, to_read, block_index, coefficient_reading_context, mb_x, have_y2, metadata.segment_id, header); } coefficient_reading_context.update(block_index, mb_x, subblock_has_nonzero_coefficients); @@ -1181,7 +1180,7 @@ ErrorOr decode_VP8_image_data(Gfx::Bitmap& bitmap, FrameHeader const& head for (int mb_x = 0; mb_x < macroblock_width; ++mb_x, ++macroblock_index) { auto const& metadata = macroblock_metadata[macroblock_index]; - auto coefficients = TRY(read_macroblock_coefficients(decoder, header, coefficient_reading_context, metadata, mb_x)); + auto coefficients = read_macroblock_coefficients(decoder, header, coefficient_reading_context, metadata, mb_x); u8 y_data[16 * 16] {}; if (metadata.intra_y_mode == B_PRED) diff --git a/Userland/Libraries/LibVideo/VP9/Context.h b/Userland/Libraries/LibVideo/VP9/Context.h index fedd96b769..890a5654ce 100644 --- a/Userland/Libraries/LibVideo/VP9/Context.h +++ b/Userland/Libraries/LibVideo/VP9/Context.h @@ -65,7 +65,7 @@ public: // 9.2.1: The Boolean decoding process specified in section 9.2.2 is invoked to read a marker syntax element from the // bitstream. It is a requirement of bitstream conformance that the value read is equal to 0. auto decoder = DECODER_TRY(DecoderErrorCategory::Corrupted, BooleanDecoder::initialize(compressed_header_data)); - if (DECODER_TRY(DecoderErrorCategory::Corrupted, decoder.read_bool(128))) + if (decoder.read_bool(128)) return DecoderError::corrupted("Range decoder marker was non-zero"sv); DECODER_TRY(DecoderErrorCategory::Corrupted, bit_stream.discard(size)); diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp index ff02c7f1a9..5a4ab74b8f 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.cpp +++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp @@ -595,79 +595,78 @@ DecoderErrorOr Parser::compressed_header(FrameContext& frame_context) { auto decoder = TRY(frame_context.create_range_decoder(frame_context.header_size_in_bytes)); - frame_context.transform_mode = TRY(read_tx_mode(decoder, frame_context)); + frame_context.transform_mode = read_tx_mode(decoder, frame_context); if (frame_context.transform_mode == TransformMode::Select) - TRY(tx_mode_probs(decoder)); - TRY(read_coef_probs(decoder, frame_context.transform_mode)); - TRY(read_skip_prob(decoder)); + tx_mode_probs(decoder); + read_coef_probs(decoder, frame_context.transform_mode); + read_skip_prob(decoder); if (frame_context.is_inter_predicted()) { - TRY(read_inter_mode_probs(decoder)); + read_inter_mode_probs(decoder); if (frame_context.interpolation_filter == Switchable) - TRY(read_interp_filter_probs(decoder)); - TRY(read_is_inter_probs(decoder)); - TRY(frame_reference_mode(frame_context, decoder)); - TRY(frame_reference_mode_probs(decoder, frame_context)); - TRY(read_y_mode_probs(decoder)); - TRY(read_partition_probs(decoder)); - TRY(mv_probs(decoder, frame_context)); + read_interp_filter_probs(decoder); + read_is_inter_probs(decoder); + frame_reference_mode(frame_context, decoder); + frame_reference_mode_probs(decoder, frame_context); + read_y_mode_probs(decoder); + read_partition_probs(decoder); + mv_probs(decoder, frame_context); } TRY_READ(decoder.finish_decode()); return {}; } -DecoderErrorOr Parser::read_tx_mode(BooleanDecoder& decoder, FrameContext const& frame_context) +TransformMode Parser::read_tx_mode(BooleanDecoder& decoder, FrameContext const& frame_context) { if (frame_context.lossless) { return TransformMode::Only_4x4; } - auto tx_mode = TRY_READ(decoder.read_literal(2)); + auto tx_mode = decoder.read_literal(2); if (tx_mode == to_underlying(TransformMode::Allow_32x32)) - tx_mode += TRY_READ(decoder.read_literal(1)); + tx_mode += decoder.read_literal(1); return static_cast(tx_mode); } -DecoderErrorOr Parser::tx_mode_probs(BooleanDecoder& decoder) +void Parser::tx_mode_probs(BooleanDecoder& decoder) { auto& tx_probs = m_probability_tables->tx_probs(); for (auto i = 0; i < TX_SIZE_CONTEXTS; i++) { for (auto j = 0; j < TX_SIZES - 3; j++) - tx_probs[Transform_8x8][i][j] = TRY(diff_update_prob(decoder, tx_probs[Transform_8x8][i][j])); + tx_probs[Transform_8x8][i][j] = diff_update_prob(decoder, tx_probs[Transform_8x8][i][j]); } for (auto i = 0; i < TX_SIZE_CONTEXTS; i++) { for (auto j = 0; j < TX_SIZES - 2; j++) - tx_probs[Transform_16x16][i][j] = TRY(diff_update_prob(decoder, tx_probs[Transform_16x16][i][j])); + tx_probs[Transform_16x16][i][j] = diff_update_prob(decoder, tx_probs[Transform_16x16][i][j]); } for (auto i = 0; i < TX_SIZE_CONTEXTS; i++) { for (auto j = 0; j < TX_SIZES - 1; j++) - tx_probs[Transform_32x32][i][j] = TRY(diff_update_prob(decoder, tx_probs[Transform_32x32][i][j])); + tx_probs[Transform_32x32][i][j] = diff_update_prob(decoder, tx_probs[Transform_32x32][i][j]); } - return {}; } -DecoderErrorOr Parser::diff_update_prob(BooleanDecoder& decoder, u8 prob) +u8 Parser::diff_update_prob(BooleanDecoder& decoder, u8 prob) { - auto update_prob = TRY_READ(decoder.read_bool(252)); + auto update_prob = decoder.read_bool(252); if (update_prob) { - auto delta_prob = TRY(decode_term_subexp(decoder)); + auto delta_prob = decode_term_subexp(decoder); prob = inv_remap_prob(delta_prob, prob); } return prob; } -DecoderErrorOr Parser::decode_term_subexp(BooleanDecoder& decoder) +u8 Parser::decode_term_subexp(BooleanDecoder& decoder) { - if (TRY_READ(decoder.read_literal(1)) == 0) - return TRY_READ(decoder.read_literal(4)); - if (TRY_READ(decoder.read_literal(1)) == 0) - return TRY_READ(decoder.read_literal(4)) + 16; - if (TRY_READ(decoder.read_literal(1)) == 0) - return TRY_READ(decoder.read_literal(5)) + 32; + if (decoder.read_literal(1) == 0) + return decoder.read_literal(4); + if (decoder.read_literal(1) == 0) + return decoder.read_literal(4) + 16; + if (decoder.read_literal(1) == 0) + return decoder.read_literal(5) + 32; - auto v = TRY_READ(decoder.read_literal(7)); + auto v = decoder.read_literal(7); if (v < 65) return v + 64; - return (v << 1u) - 1 + TRY_READ(decoder.read_literal(1)); + return (v << 1u) - 1 + decoder.read_literal(1); } u8 Parser::inv_remap_prob(u8 delta_prob, u8 prob) @@ -688,11 +687,11 @@ u8 Parser::inv_recenter_nonneg(u8 v, u8 m) return m + (v >> 1u); } -DecoderErrorOr Parser::read_coef_probs(BooleanDecoder& decoder, TransformMode transform_mode) +void Parser::read_coef_probs(BooleanDecoder& decoder, TransformMode transform_mode) { auto max_tx_size = tx_mode_to_biggest_tx_size[to_underlying(transform_mode)]; for (u8 transform_size = 0; transform_size <= max_tx_size; transform_size++) { - auto update_probs = TRY_READ(decoder.read_literal(1)); + auto update_probs = decoder.read_literal(1); if (update_probs == 1) { for (auto i = 0; i < 2; i++) { for (auto j = 0; j < 2; j++) { @@ -701,7 +700,7 @@ DecoderErrorOr Parser::read_coef_probs(BooleanDecoder& decoder, TransformM for (auto l = 0; l < max_l; l++) { for (auto m = 0; m < 3; m++) { auto& prob = m_probability_tables->coef_probs()[transform_size][i][j][k][l][m]; - prob = TRY(diff_update_prob(decoder, prob)); + prob = diff_update_prob(decoder, prob); } } } @@ -709,39 +708,34 @@ DecoderErrorOr Parser::read_coef_probs(BooleanDecoder& decoder, TransformM } } } - return {}; } -DecoderErrorOr Parser::read_skip_prob(BooleanDecoder& decoder) +void Parser::read_skip_prob(BooleanDecoder& decoder) { for (auto i = 0; i < SKIP_CONTEXTS; i++) - m_probability_tables->skip_prob()[i] = TRY(diff_update_prob(decoder, m_probability_tables->skip_prob()[i])); - return {}; + m_probability_tables->skip_prob()[i] = diff_update_prob(decoder, m_probability_tables->skip_prob()[i]); } -DecoderErrorOr Parser::read_inter_mode_probs(BooleanDecoder& decoder) +void Parser::read_inter_mode_probs(BooleanDecoder& decoder) { for (auto i = 0; i < INTER_MODE_CONTEXTS; i++) { for (auto j = 0; j < INTER_MODES - 1; j++) - m_probability_tables->inter_mode_probs()[i][j] = TRY(diff_update_prob(decoder, m_probability_tables->inter_mode_probs()[i][j])); + m_probability_tables->inter_mode_probs()[i][j] = diff_update_prob(decoder, m_probability_tables->inter_mode_probs()[i][j]); } - return {}; } -DecoderErrorOr Parser::read_interp_filter_probs(BooleanDecoder& decoder) +void Parser::read_interp_filter_probs(BooleanDecoder& decoder) { for (auto i = 0; i < INTERP_FILTER_CONTEXTS; i++) { for (auto j = 0; j < SWITCHABLE_FILTERS - 1; j++) - m_probability_tables->interp_filter_probs()[i][j] = TRY(diff_update_prob(decoder, m_probability_tables->interp_filter_probs()[i][j])); + m_probability_tables->interp_filter_probs()[i][j] = diff_update_prob(decoder, m_probability_tables->interp_filter_probs()[i][j]); } - return {}; } -DecoderErrorOr Parser::read_is_inter_probs(BooleanDecoder& decoder) +void Parser::read_is_inter_probs(BooleanDecoder& decoder) { for (auto i = 0; i < IS_INTER_CONTEXTS; i++) - m_probability_tables->is_inter_prob()[i] = TRY(diff_update_prob(decoder, m_probability_tables->is_inter_prob()[i])); - return {}; + m_probability_tables->is_inter_prob()[i] = diff_update_prob(decoder, m_probability_tables->is_inter_prob()[i]); } static void setup_compound_reference_mode(FrameContext& frame_context) @@ -762,7 +756,7 @@ static void setup_compound_reference_mode(FrameContext& frame_context) frame_context.variable_reference_types = variable_references; } -DecoderErrorOr Parser::frame_reference_mode(FrameContext& frame_context, BooleanDecoder& decoder) +void Parser::frame_reference_mode(FrameContext& frame_context, BooleanDecoder& decoder) { auto compound_reference_allowed = false; for (size_t i = 2; i <= REFS_PER_FRAME; i++) { @@ -771,11 +765,11 @@ DecoderErrorOr Parser::frame_reference_mode(FrameContext& frame_context, B } ReferenceMode reference_mode; if (compound_reference_allowed) { - auto non_single_reference = TRY_READ(decoder.read_literal(1)); + auto non_single_reference = decoder.read_literal(1); if (non_single_reference == 0) { reference_mode = SingleReference; } else { - auto reference_select = TRY_READ(decoder.read_literal(1)); + auto reference_select = decoder.read_literal(1); if (reference_select == 0) reference_mode = CompoundReference; else @@ -787,74 +781,70 @@ DecoderErrorOr Parser::frame_reference_mode(FrameContext& frame_context, B frame_context.reference_mode = reference_mode; if (reference_mode != SingleReference) setup_compound_reference_mode(frame_context); - return {}; } -DecoderErrorOr Parser::frame_reference_mode_probs(BooleanDecoder& decoder, FrameContext const& frame_context) +void Parser::frame_reference_mode_probs(BooleanDecoder& decoder, FrameContext const& frame_context) { if (frame_context.reference_mode == ReferenceModeSelect) { for (auto i = 0; i < COMP_MODE_CONTEXTS; i++) { auto& comp_mode_prob = m_probability_tables->comp_mode_prob(); - comp_mode_prob[i] = TRY(diff_update_prob(decoder, comp_mode_prob[i])); + comp_mode_prob[i] = diff_update_prob(decoder, comp_mode_prob[i]); } } if (frame_context.reference_mode != CompoundReference) { for (auto i = 0; i < REF_CONTEXTS; i++) { auto& single_ref_prob = m_probability_tables->single_ref_prob(); - single_ref_prob[i][0] = TRY(diff_update_prob(decoder, single_ref_prob[i][0])); - single_ref_prob[i][1] = TRY(diff_update_prob(decoder, single_ref_prob[i][1])); + single_ref_prob[i][0] = diff_update_prob(decoder, single_ref_prob[i][0]); + single_ref_prob[i][1] = diff_update_prob(decoder, single_ref_prob[i][1]); } } if (frame_context.reference_mode != SingleReference) { for (auto i = 0; i < REF_CONTEXTS; i++) { auto& comp_ref_prob = m_probability_tables->comp_ref_prob(); - comp_ref_prob[i] = TRY(diff_update_prob(decoder, comp_ref_prob[i])); + comp_ref_prob[i] = diff_update_prob(decoder, comp_ref_prob[i]); } } - return {}; } -DecoderErrorOr Parser::read_y_mode_probs(BooleanDecoder& decoder) +void Parser::read_y_mode_probs(BooleanDecoder& decoder) { for (auto i = 0; i < BLOCK_SIZE_GROUPS; i++) { for (auto j = 0; j < INTRA_MODES - 1; j++) { auto& y_mode_probs = m_probability_tables->y_mode_probs(); - y_mode_probs[i][j] = TRY(diff_update_prob(decoder, y_mode_probs[i][j])); + y_mode_probs[i][j] = diff_update_prob(decoder, y_mode_probs[i][j]); } } - return {}; } -DecoderErrorOr Parser::read_partition_probs(BooleanDecoder& decoder) +void Parser::read_partition_probs(BooleanDecoder& decoder) { for (auto i = 0; i < PARTITION_CONTEXTS; i++) { for (auto j = 0; j < PARTITION_TYPES - 1; j++) { auto& partition_probs = m_probability_tables->partition_probs(); - partition_probs[i][j] = TRY(diff_update_prob(decoder, partition_probs[i][j])); + partition_probs[i][j] = diff_update_prob(decoder, partition_probs[i][j]); } } - return {}; } -DecoderErrorOr Parser::mv_probs(BooleanDecoder& decoder, FrameContext const& frame_context) +void Parser::mv_probs(BooleanDecoder& decoder, FrameContext const& frame_context) { for (auto j = 0; j < MV_JOINTS - 1; j++) { auto& mv_joint_probs = m_probability_tables->mv_joint_probs(); - mv_joint_probs[j] = TRY(update_mv_prob(decoder, mv_joint_probs[j])); + mv_joint_probs[j] = update_mv_prob(decoder, mv_joint_probs[j]); } for (auto i = 0; i < 2; i++) { auto& mv_sign_prob = m_probability_tables->mv_sign_prob(); - mv_sign_prob[i] = TRY(update_mv_prob(decoder, mv_sign_prob[i])); + mv_sign_prob[i] = update_mv_prob(decoder, mv_sign_prob[i]); for (auto j = 0; j < MV_CLASSES - 1; j++) { auto& mv_class_probs = m_probability_tables->mv_class_probs(); - mv_class_probs[i][j] = TRY(update_mv_prob(decoder, mv_class_probs[i][j])); + mv_class_probs[i][j] = update_mv_prob(decoder, mv_class_probs[i][j]); } auto& mv_class0_bit_prob = m_probability_tables->mv_class0_bit_prob(); - mv_class0_bit_prob[i] = TRY(update_mv_prob(decoder, mv_class0_bit_prob[i])); + mv_class0_bit_prob[i] = update_mv_prob(decoder, mv_class0_bit_prob[i]); for (auto j = 0; j < MV_OFFSET_BITS; j++) { auto& mv_bits_prob = m_probability_tables->mv_bits_prob(); - mv_bits_prob[i][j] = TRY(update_mv_prob(decoder, mv_bits_prob[i][j])); + mv_bits_prob[i][j] = update_mv_prob(decoder, mv_bits_prob[i][j]); } } @@ -862,12 +852,12 @@ DecoderErrorOr Parser::mv_probs(BooleanDecoder& decoder, FrameContext cons for (auto j = 0; j < CLASS0_SIZE; j++) { for (auto k = 0; k < MV_FR_SIZE - 1; k++) { auto& mv_class0_fr_probs = m_probability_tables->mv_class0_fr_probs(); - mv_class0_fr_probs[i][j][k] = TRY(update_mv_prob(decoder, mv_class0_fr_probs[i][j][k])); + mv_class0_fr_probs[i][j][k] = update_mv_prob(decoder, mv_class0_fr_probs[i][j][k]); } } for (auto k = 0; k < MV_FR_SIZE - 1; k++) { auto& mv_fr_probs = m_probability_tables->mv_fr_probs(); - mv_fr_probs[i][k] = TRY(update_mv_prob(decoder, mv_fr_probs[i][k])); + mv_fr_probs[i][k] = update_mv_prob(decoder, mv_fr_probs[i][k]); } } @@ -875,18 +865,16 @@ DecoderErrorOr Parser::mv_probs(BooleanDecoder& decoder, FrameContext cons for (auto i = 0; i < 2; i++) { auto& mv_class0_hp_prob = m_probability_tables->mv_class0_hp_prob(); auto& mv_hp_prob = m_probability_tables->mv_hp_prob(); - mv_class0_hp_prob[i] = TRY(update_mv_prob(decoder, mv_class0_hp_prob[i])); - mv_hp_prob[i] = TRY(update_mv_prob(decoder, mv_hp_prob[i])); + mv_class0_hp_prob[i] = update_mv_prob(decoder, mv_class0_hp_prob[i]); + mv_hp_prob[i] = update_mv_prob(decoder, mv_hp_prob[i]); } } - - return {}; } -DecoderErrorOr Parser::update_mv_prob(BooleanDecoder& decoder, u8 prob) +u8 Parser::update_mv_prob(BooleanDecoder& decoder, u8 prob) { - if (TRY_READ(decoder.read_bool(252))) { - return (TRY_READ(decoder.read_literal(7)) << 1u) | 1u; + if (decoder.read_bool(252)) { + return (decoder.read_literal(7) << 1u) | 1u; } return prob; } @@ -1024,7 +1012,7 @@ DecoderErrorOr Parser::decode_partition(TileContext& tile_context, u32 row bool has_cols = (column + half_block_8x8) < tile_context.frame_context.columns(); u32 row_in_tile = row - tile_context.rows_start; u32 column_in_tile = column - tile_context.columns_start; - auto partition = TRY_READ(TreeParser::parse_partition(tile_context.decoder, *m_probability_tables, *tile_context.counter, has_rows, has_cols, subsize, num_8x8, tile_context.above_partition_context, tile_context.left_partition_context.span(), row_in_tile, column_in_tile, !tile_context.frame_context.is_inter_predicted())); + auto partition = TreeParser::parse_partition(tile_context.decoder, *m_probability_tables, *tile_context.counter, has_rows, has_cols, subsize, num_8x8, tile_context.above_partition_context, tile_context.left_partition_context.span(), row_in_tile, column_in_tile, !tile_context.frame_context.is_inter_predicted()); auto child_subsize = subsize_lookup[partition][subsize]; if (child_subsize < Block_8x8 || partition == PartitionNone) { @@ -1066,7 +1054,7 @@ DecoderErrorOr Parser::decode_block(TileContext& tile_context, u32 row, u3 auto left_context = column > tile_context.columns_start ? tile_context.frame_block_contexts().at(row, column - 1) : FrameBlockContext(); auto block_context = BlockContext::create(tile_context, row, column, subsize); - TRY(mode_info(block_context, above_context, left_context)); + mode_info(block_context, above_context, left_context); auto had_residual_tokens = TRY(residual(block_context, above_context.is_available, left_context.is_available)); if (block_context.is_inter_predicted() && subsize >= Block_8x8 && !had_residual_tokens) block_context.should_skip_residuals = true; @@ -1081,33 +1069,32 @@ DecoderErrorOr Parser::decode_block(TileContext& tile_context, u32 row, u3 return {}; } -DecoderErrorOr Parser::mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) +void Parser::mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { if (block_context.frame_context.is_inter_predicted()) - TRY(inter_frame_mode_info(block_context, above_context, left_context)); + inter_frame_mode_info(block_context, above_context, left_context); else - TRY(intra_frame_mode_info(block_context, above_context, left_context)); - return {}; + intra_frame_mode_info(block_context, above_context, left_context); } -DecoderErrorOr Parser::intra_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) +void Parser::intra_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { block_context.reference_frame_types = { ReferenceFrameType::None, ReferenceFrameType::None }; VERIFY(!block_context.is_inter_predicted()); - TRY(set_intra_segment_id(block_context)); - block_context.should_skip_residuals = TRY(read_should_skip_residuals(block_context, above_context, left_context)); - block_context.transform_size = TRY(read_tx_size(block_context, above_context, left_context, true)); + set_intra_segment_id(block_context); + block_context.should_skip_residuals = read_should_skip_residuals(block_context, above_context, left_context); + block_context.transform_size = read_tx_size(block_context, above_context, left_context, true); // FIXME: This if statement is also present in parse_default_intra_mode. The selection of parameters for // the probability table lookup should be inlined here. if (block_context.size >= Block_8x8) { - auto mode = TRY_READ(TreeParser::parse_default_intra_mode(block_context.decoder, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, 0, 0)); + auto mode = TreeParser::parse_default_intra_mode(block_context.decoder, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, 0, 0); for (auto& block_sub_mode : block_context.sub_block_prediction_modes) block_sub_mode = mode; } else { auto size_in_sub_blocks = block_context.get_size_in_sub_blocks(); for (auto idy = 0; idy < 2; idy += size_in_sub_blocks.height()) { for (auto idx = 0; idx < 2; idx += size_in_sub_blocks.width()) { - auto sub_mode = TRY_READ(TreeParser::parse_default_intra_mode(block_context.decoder, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, idx, idy)); + auto sub_mode = TreeParser::parse_default_intra_mode(block_context.decoder, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, idx, idy); for (auto y = 0; y < size_in_sub_blocks.height(); y++) { for (auto x = 0; x < size_in_sub_blocks.width(); x++) { @@ -1118,71 +1105,68 @@ DecoderErrorOr Parser::intra_frame_mode_info(BlockContext& block_context, } } } - block_context.uv_prediction_mode = TRY_READ(TreeParser::parse_default_uv_mode(block_context.decoder, *m_probability_tables, block_context.y_prediction_mode())); - return {}; + block_context.uv_prediction_mode = TreeParser::parse_default_uv_mode(block_context.decoder, *m_probability_tables, block_context.y_prediction_mode()); } -DecoderErrorOr Parser::set_intra_segment_id(BlockContext& block_context) +void Parser::set_intra_segment_id(BlockContext& block_context) { if (block_context.frame_context.segmentation_enabled && block_context.frame_context.use_full_segment_id_tree) - block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities)); + block_context.segment_id = TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities); else block_context.segment_id = 0; - return {}; } -DecoderErrorOr Parser::read_should_skip_residuals(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) +bool Parser::read_should_skip_residuals(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { if (block_context.get_segment_feature(SegmentFeature::SkipResidualsOverride).enabled) return true; - return TRY_READ(TreeParser::parse_skip(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context)); + return TreeParser::parse_skip(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context); } -DecoderErrorOr Parser::read_tx_size(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select) +TransformSize Parser::read_tx_size(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select) { auto max_tx_size = max_txsize_lookup[block_context.size]; if (allow_select && block_context.frame_context.transform_mode == TransformMode::Select && block_context.size >= Block_8x8) - return (TRY_READ(TreeParser::parse_tx_size(block_context.decoder, *m_probability_tables, block_context.counter, max_tx_size, above_context, left_context))); + return (TreeParser::parse_tx_size(block_context.decoder, *m_probability_tables, block_context.counter, max_tx_size, above_context, left_context)); return min(max_tx_size, tx_mode_to_biggest_tx_size[to_underlying(block_context.frame_context.transform_mode)]); } -DecoderErrorOr Parser::inter_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) +void Parser::inter_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { - TRY(set_inter_segment_id(block_context)); - block_context.should_skip_residuals = TRY(read_should_skip_residuals(block_context, above_context, left_context)); - auto is_inter = TRY(read_is_inter(block_context, above_context, left_context)); - block_context.transform_size = TRY(read_tx_size(block_context, above_context, left_context, !block_context.should_skip_residuals || !is_inter)); + set_inter_segment_id(block_context); + block_context.should_skip_residuals = read_should_skip_residuals(block_context, above_context, left_context); + auto is_inter = read_is_inter(block_context, above_context, left_context); + block_context.transform_size = read_tx_size(block_context, above_context, left_context, !block_context.should_skip_residuals || !is_inter); if (is_inter) { - TRY(inter_block_mode_info(block_context, above_context, left_context)); + inter_block_mode_info(block_context, above_context, left_context); } else { - TRY(intra_block_mode_info(block_context)); + intra_block_mode_info(block_context); } - return {}; } -DecoderErrorOr Parser::set_inter_segment_id(BlockContext& block_context) +void Parser::set_inter_segment_id(BlockContext& block_context) { if (!block_context.frame_context.segmentation_enabled) { block_context.segment_id = 0; - return {}; + return; } auto predicted_segment_id = get_segment_id(block_context); if (!block_context.frame_context.use_full_segment_id_tree) { block_context.segment_id = predicted_segment_id; - return {}; + return; } if (!block_context.frame_context.use_predicted_segment_id_tree) { - block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities)); - return {}; + block_context.segment_id = TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities); + return; } auto above_segmentation_id = block_context.tile_context.above_segmentation_ids[block_context.row - block_context.tile_context.rows_start]; auto left_segmentation_id = block_context.tile_context.left_segmentation_ids[block_context.column - block_context.tile_context.columns_start]; - auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(block_context.decoder, block_context.frame_context.predicted_segment_id_tree_probabilities, above_segmentation_id, left_segmentation_id)); + auto seg_id_predicted = TreeParser::parse_segment_id_predicted(block_context.decoder, block_context.frame_context.predicted_segment_id_tree_probabilities, above_segmentation_id, left_segmentation_id); if (seg_id_predicted) block_context.segment_id = predicted_segment_id; else - block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities)); + block_context.segment_id = TreeParser::parse_segment_id(block_context.decoder, block_context.frame_context.full_segment_id_tree_probabilities); // (7.4.1) AboveSegPredContext[ i ] only needs to be set to 0 for i = 0..MiCols-1. // This is taken care of by the slicing in BlockContext. @@ -1190,7 +1174,6 @@ DecoderErrorOr Parser::set_inter_segment_id(BlockContext& block_context) // (7.4.1) LeftSegPredContext[ i ] only needs to be set to 0 for i = 0..MiRows-1. // This is taken care of by the slicing in BlockContext. block_context.left_segmentation_ids.fill(seg_id_predicted); - return {}; } u8 Parser::get_segment_id(BlockContext const& block_context) @@ -1208,28 +1191,28 @@ u8 Parser::get_segment_id(BlockContext const& block_context) return segment; } -DecoderErrorOr Parser::read_is_inter(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) +bool Parser::read_is_inter(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { auto reference_frame_override_feature = block_context.get_segment_feature(SegmentFeature::ReferenceFrameOverride); if (reference_frame_override_feature.enabled) return reference_frame_override_feature.value != ReferenceFrameType::None; - return TRY_READ(TreeParser::parse_block_is_inter_predicted(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context)); + return TreeParser::parse_block_is_inter_predicted(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context); } -DecoderErrorOr Parser::intra_block_mode_info(BlockContext& block_context) +void Parser::intra_block_mode_info(BlockContext& block_context) { block_context.reference_frame_types = { ReferenceFrameType::None, ReferenceFrameType::None }; VERIFY(!block_context.is_inter_predicted()); auto& sub_modes = block_context.sub_block_prediction_modes; if (block_context.size >= Block_8x8) { - auto mode = TRY_READ(TreeParser::parse_intra_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.size)); + auto mode = TreeParser::parse_intra_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.size); for (auto& block_sub_mode : sub_modes) block_sub_mode = mode; } else { auto size_in_sub_blocks = block_context.get_size_in_sub_blocks(); for (auto idy = 0; idy < 2; idy += size_in_sub_blocks.height()) { for (auto idx = 0; idx < 2; idx += size_in_sub_blocks.width()) { - auto sub_intra_mode = TRY_READ(TreeParser::parse_sub_intra_mode(block_context.decoder, *m_probability_tables, block_context.counter)); + auto sub_intra_mode = TreeParser::parse_sub_intra_mode(block_context.decoder, *m_probability_tables, block_context.counter); for (auto y = 0; y < size_in_sub_blocks.height(); y++) { for (auto x = 0; x < size_in_sub_blocks.width(); x++) sub_modes[(idy + y) * 2 + idx + x] = sub_intra_mode; @@ -1237,15 +1220,14 @@ DecoderErrorOr Parser::intra_block_mode_info(BlockContext& block_context) } } } - block_context.uv_prediction_mode = TRY_READ(TreeParser::parse_uv_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.y_prediction_mode())); - return {}; + block_context.uv_prediction_mode = TreeParser::parse_uv_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.y_prediction_mode()); } static void select_best_reference_motion_vectors(BlockContext& block_context, MotionVectorPair reference_motion_vectors, BlockMotionVectorCandidates& candidates, ReferenceIndex); -DecoderErrorOr Parser::inter_block_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) +void Parser::inter_block_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { - TRY(read_ref_frames(block_context, above_context, left_context)); + read_ref_frames(block_context, above_context, left_context); VERIFY(block_context.is_inter_predicted()); BlockMotionVectorCandidates motion_vector_candidates; @@ -1259,23 +1241,23 @@ DecoderErrorOr Parser::inter_block_mode_info(BlockContext& block_context, if (block_context.get_segment_feature(SegmentFeature::SkipResidualsOverride).enabled) { block_context.y_prediction_mode() = PredictionMode::ZeroMv; } else if (block_context.size >= Block_8x8) { - block_context.y_prediction_mode() = TRY_READ(TreeParser::parse_inter_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.mode_context[block_context.reference_frame_types.primary])); + block_context.y_prediction_mode() = TreeParser::parse_inter_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.mode_context[block_context.reference_frame_types.primary]); } if (block_context.frame_context.interpolation_filter == Switchable) - block_context.interpolation_filter = TRY_READ(TreeParser::parse_interpolation_filter(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context)); + block_context.interpolation_filter = TreeParser::parse_interpolation_filter(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context); else block_context.interpolation_filter = block_context.frame_context.interpolation_filter; if (block_context.size < Block_8x8) { auto size_in_sub_blocks = block_context.get_size_in_sub_blocks(); for (auto idy = 0; idy < 2; idy += size_in_sub_blocks.height()) { for (auto idx = 0; idx < 2; idx += size_in_sub_blocks.width()) { - block_context.y_prediction_mode() = TRY_READ(TreeParser::parse_inter_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.mode_context[block_context.reference_frame_types.primary])); + block_context.y_prediction_mode() = TreeParser::parse_inter_mode(block_context.decoder, *m_probability_tables, block_context.counter, block_context.mode_context[block_context.reference_frame_types.primary]); if (block_context.y_prediction_mode() == PredictionMode::NearestMv || block_context.y_prediction_mode() == PredictionMode::NearMv) { select_best_sub_block_reference_motion_vectors(block_context, motion_vector_candidates, idy * 2 + idx, ReferenceIndex::Primary); if (block_context.is_compound()) select_best_sub_block_reference_motion_vectors(block_context, motion_vector_candidates, idy * 2 + idx, ReferenceIndex::Secondary); } - auto new_motion_vector_pair = TRY(get_motion_vector(block_context, motion_vector_candidates)); + auto new_motion_vector_pair = get_motion_vector(block_context, motion_vector_candidates); for (auto y = 0; y < size_in_sub_blocks.height(); y++) { for (auto x = 0; x < size_in_sub_blocks.width(); x++) { auto sub_block_index = (idy + y) * 2 + idx + x; @@ -1284,26 +1266,25 @@ DecoderErrorOr Parser::inter_block_mode_info(BlockContext& block_context, } } } - return {}; + return; } - auto new_motion_vector_pair = TRY(get_motion_vector(block_context, motion_vector_candidates)); + auto new_motion_vector_pair = get_motion_vector(block_context, motion_vector_candidates); for (auto block = 0; block < 4; block++) block_context.sub_block_motion_vectors[block] = new_motion_vector_pair; - return {}; } -DecoderErrorOr Parser::read_ref_frames(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) +void Parser::read_ref_frames(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context) { auto reference_frame_override_feature = block_context.get_segment_feature(SegmentFeature::ReferenceFrameOverride); if (reference_frame_override_feature.enabled) { block_context.reference_frame_types = { static_cast(reference_frame_override_feature.value), ReferenceFrameType::None }; - return {}; + return; } ReferenceMode compound_mode = block_context.frame_context.reference_mode; auto fixed_reference = block_context.frame_context.fixed_reference_type; if (compound_mode == ReferenceModeSelect) - compound_mode = TRY_READ(TreeParser::parse_comp_mode(block_context.decoder, *m_probability_tables, block_context.counter, fixed_reference, above_context, left_context)); + compound_mode = TreeParser::parse_comp_mode(block_context.decoder, *m_probability_tables, block_context.counter, fixed_reference, above_context, left_context); if (compound_mode == CompoundReference) { auto variable_references = block_context.frame_context.variable_reference_types; @@ -1312,32 +1293,31 @@ DecoderErrorOr Parser::read_ref_frames(BlockContext& block_context, FrameB if (block_context.frame_context.reference_frame_sign_biases[fixed_reference]) swap(fixed_reference_index, variable_reference_index); - auto variable_reference_selection = TRY_READ(TreeParser::parse_comp_ref(block_context.decoder, *m_probability_tables, block_context.counter, fixed_reference, variable_references, variable_reference_index, above_context, left_context)); + auto variable_reference_selection = TreeParser::parse_comp_ref(block_context.decoder, *m_probability_tables, block_context.counter, fixed_reference, variable_references, variable_reference_index, above_context, left_context); block_context.reference_frame_types[fixed_reference_index] = fixed_reference; block_context.reference_frame_types[variable_reference_index] = variable_references[variable_reference_selection]; - return {}; + return; } // FIXME: Maybe consolidate this into a tree. Context is different between part 1 and 2 but still, it would look nice here. ReferenceFrameType primary_type = ReferenceFrameType::LastFrame; - auto single_ref_p1 = TRY_READ(TreeParser::parse_single_ref_part_1(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context)); + auto single_ref_p1 = TreeParser::parse_single_ref_part_1(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context); if (single_ref_p1) { - auto single_ref_p2 = TRY_READ(TreeParser::parse_single_ref_part_2(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context)); + auto single_ref_p2 = TreeParser::parse_single_ref_part_2(block_context.decoder, *m_probability_tables, block_context.counter, above_context, left_context); primary_type = single_ref_p2 ? ReferenceFrameType::AltRefFrame : ReferenceFrameType::GoldenFrame; } block_context.reference_frame_types = { primary_type, ReferenceFrameType::None }; - return {}; } // assign_mv( isCompound ) in the spec. -DecoderErrorOr Parser::get_motion_vector(BlockContext const& block_context, BlockMotionVectorCandidates const& candidates) +MotionVectorPair Parser::get_motion_vector(BlockContext const& block_context, BlockMotionVectorCandidates const& candidates) { MotionVectorPair result; - auto read_one = [&](ReferenceIndex index) -> DecoderErrorOr { + auto read_one = [&](ReferenceIndex index) -> void { switch (block_context.y_prediction_mode()) { case PredictionMode::NewMv: - result[index] = TRY(read_motion_vector(block_context, candidates, index)); + result[index] = read_motion_vector(block_context, candidates, index); break; case PredictionMode::NearestMv: result[index] = candidates[index].nearest_vector; @@ -1349,11 +1329,11 @@ DecoderErrorOr Parser::get_motion_vector(BlockContext const& b result[index] = {}; break; } - return {}; + return; }; - TRY(read_one(ReferenceIndex::Primary)); + read_one(ReferenceIndex::Primary); if (block_context.is_compound()) - TRY(read_one(ReferenceIndex::Secondary)); + read_one(ReferenceIndex::Secondary); return result; } @@ -1364,39 +1344,39 @@ static bool should_use_high_precision_motion_vector(MotionVector const& delta_ve } // read_mv( ref ) in the spec. -DecoderErrorOr Parser::read_motion_vector(BlockContext const& block_context, BlockMotionVectorCandidates const& candidates, ReferenceIndex reference_index) +MotionVector Parser::read_motion_vector(BlockContext const& block_context, BlockMotionVectorCandidates const& candidates, ReferenceIndex reference_index) { auto use_high_precision = block_context.frame_context.high_precision_motion_vectors_allowed && should_use_high_precision_motion_vector(candidates[reference_index].best_vector); MotionVector delta_vector; - auto joint = TRY_READ(TreeParser::parse_motion_vector_joint(block_context.decoder, *m_probability_tables, block_context.counter)); + auto joint = TreeParser::parse_motion_vector_joint(block_context.decoder, *m_probability_tables, block_context.counter); if ((joint & MotionVectorNonZeroRow) != 0) - delta_vector.set_row(TRY(read_single_motion_vector_component(block_context.decoder, block_context.counter, 0, use_high_precision))); + delta_vector.set_row(read_single_motion_vector_component(block_context.decoder, block_context.counter, 0, use_high_precision)); if ((joint & MotionVectorNonZeroColumn) != 0) - delta_vector.set_column(TRY(read_single_motion_vector_component(block_context.decoder, block_context.counter, 1, use_high_precision))); + delta_vector.set_column(read_single_motion_vector_component(block_context.decoder, block_context.counter, 1, use_high_precision)); return candidates[reference_index].best_vector + delta_vector; } // read_mv_component( comp ) in the spec. -DecoderErrorOr Parser::read_single_motion_vector_component(BooleanDecoder& decoder, SyntaxElementCounter& counter, u8 component, bool use_high_precision) +i32 Parser::read_single_motion_vector_component(BooleanDecoder& decoder, SyntaxElementCounter& counter, u8 component, bool use_high_precision) { - auto mv_sign = TRY_READ(TreeParser::parse_motion_vector_sign(decoder, *m_probability_tables, counter, component)); - auto mv_class = TRY_READ(TreeParser::parse_motion_vector_class(decoder, *m_probability_tables, counter, component)); + auto mv_sign = TreeParser::parse_motion_vector_sign(decoder, *m_probability_tables, counter, component); + auto mv_class = TreeParser::parse_motion_vector_class(decoder, *m_probability_tables, counter, component); u32 magnitude; if (mv_class == MvClass0) { - auto mv_class0_bit = TRY_READ(TreeParser::parse_motion_vector_class0_bit(decoder, *m_probability_tables, counter, component)); - auto mv_class0_fr = TRY_READ(TreeParser::parse_motion_vector_class0_fr(decoder, *m_probability_tables, counter, component, mv_class0_bit)); - auto mv_class0_hp = TRY_READ(TreeParser::parse_motion_vector_class0_hp(decoder, *m_probability_tables, counter, component, use_high_precision)); + auto mv_class0_bit = TreeParser::parse_motion_vector_class0_bit(decoder, *m_probability_tables, counter, component); + auto mv_class0_fr = TreeParser::parse_motion_vector_class0_fr(decoder, *m_probability_tables, counter, component, mv_class0_bit); + auto mv_class0_hp = TreeParser::parse_motion_vector_class0_hp(decoder, *m_probability_tables, counter, component, use_high_precision); magnitude = ((mv_class0_bit << 3) | (mv_class0_fr << 1) | mv_class0_hp) + 1; } else { u32 bits = 0; for (u8 i = 0; i < mv_class; i++) { - auto mv_bit = TRY_READ(TreeParser::parse_motion_vector_bit(decoder, *m_probability_tables, counter, component, i)); + auto mv_bit = TreeParser::parse_motion_vector_bit(decoder, *m_probability_tables, counter, component, i); bits |= mv_bit << i; } magnitude = CLASS0_SIZE << (mv_class + 2); - auto mv_fr = TRY_READ(TreeParser::parse_motion_vector_fr(decoder, *m_probability_tables, counter, component)); - auto mv_hp = TRY_READ(TreeParser::parse_motion_vector_hp(decoder, *m_probability_tables, counter, component, use_high_precision)); + auto mv_fr = TreeParser::parse_motion_vector_fr(decoder, *m_probability_tables, counter, component); + auto mv_hp = TreeParser::parse_motion_vector_hp(decoder, *m_probability_tables, counter, component, use_high_precision); magnitude += ((bits << 3) | (mv_fr << 1) | mv_hp) + 1; } return (mv_sign ? -1 : 1) * static_cast(magnitude); @@ -1462,7 +1442,7 @@ DecoderErrorOr Parser::residual(BlockContext& block_context, bool has_bloc TRY(m_decoder.predict_intra(plane, block_context, transform_x_in_px, transform_y_in_px, has_block_left || x > 0, has_block_above || y > 0, (x + transform_size_in_sub_blocks) < block_size_in_sub_blocks.width(), transform_size, sub_block_index)); if (!block_context.should_skip_residuals) { auto transform_set = select_transform_type(block_context, plane, transform_size, sub_block_index); - sub_block_had_non_zero_tokens = TRY(tokens(block_context, plane, x, y, transform_size, transform_set, token_cache)); + sub_block_had_non_zero_tokens = tokens(block_context, plane, x, y, transform_size, transform_set, token_cache); block_had_non_zero_tokens = block_had_non_zero_tokens || sub_block_had_non_zero_tokens; TRY(m_decoder.reconstruct(plane, block_context, transform_x_in_px, transform_y_in_px, transform_size, transform_set)); } @@ -1514,7 +1494,7 @@ static u16 const* get_scan(TransformSize transform_size, TransformSet transform_ return default_scan_32x32; } -DecoderErrorOr Parser::tokens(BlockContext& block_context, size_t plane, u32 sub_block_column, u32 sub_block_row, TransformSize transform_size, TransformSet transform_set, Array token_cache) +bool Parser::tokens(BlockContext& block_context, size_t plane, u32 sub_block_column, u32 sub_block_row, TransformSize transform_size, TransformSet transform_set, Array token_cache) { block_context.residual_tokens.fill(0); @@ -1532,10 +1512,10 @@ DecoderErrorOr Parser::tokens(BlockContext& block_context, size_t plane, u else tokens_context = TreeParser::get_context_for_other_tokens(token_cache, transform_size, transform_set, plane, token_position, block_context.is_inter_predicted(), band); - if (check_for_more_coefficients && !TRY_READ(TreeParser::parse_more_coefficients(block_context.decoder, *m_probability_tables, block_context.counter, tokens_context))) + if (check_for_more_coefficients && !TreeParser::parse_more_coefficients(block_context.decoder, *m_probability_tables, block_context.counter, tokens_context)) break; - auto token = TRY_READ(TreeParser::parse_token(block_context.decoder, *m_probability_tables, block_context.counter, tokens_context)); + auto token = TreeParser::parse_token(block_context.decoder, *m_probability_tables, block_context.counter, tokens_context); token_cache[token_position] = energy_class[token]; i32 coef; @@ -1543,7 +1523,7 @@ DecoderErrorOr Parser::tokens(BlockContext& block_context, size_t plane, u coef = 0; check_for_more_coefficients = false; } else { - coef = TRY(read_coef(block_context.decoder, block_context.frame_context.color_config.bit_depth, token)); + coef = read_coef(block_context.decoder, block_context.frame_context.color_config.bit_depth, token); check_for_more_coefficients = true; } block_context.residual_tokens[token_position] = coef; @@ -1552,22 +1532,22 @@ DecoderErrorOr Parser::tokens(BlockContext& block_context, size_t plane, u return coef_index > 0; } -DecoderErrorOr Parser::read_coef(BooleanDecoder& decoder, u8 bit_depth, Token token) +i32 Parser::read_coef(BooleanDecoder& decoder, u8 bit_depth, Token token) { auto cat = extra_bits[token][0]; auto num_extra = extra_bits[token][1]; i32 coef = extra_bits[token][2]; if (token == DctValCat6) { for (size_t e = 0; e < (u8)(bit_depth - 8); e++) { - auto high_bit = TRY_READ(decoder.read_bool(255)); + auto high_bit = decoder.read_bool(255); coef += high_bit << (5 + bit_depth - e); } } for (size_t e = 0; e < num_extra; e++) { - auto coef_bit = TRY_READ(decoder.read_bool(cat_probs[cat][e])); + auto coef_bit = decoder.read_bool(cat_probs[cat][e]); coef += coef_bit << (num_extra - 1 - e); } - bool sign_bit = TRY_READ(decoder.read_literal(1)); + bool sign_bit = decoder.read_literal(1); coef = sign_bit ? -coef : coef; return coef; } diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h index 85b99e9075..c97a842b9b 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.h +++ b/Userland/Libraries/LibVideo/VP9/Parser.h @@ -71,23 +71,23 @@ private: /* (6.3) Compressed Header Syntax */ DecoderErrorOr compressed_header(FrameContext&); - DecoderErrorOr read_tx_mode(BooleanDecoder&, FrameContext const&); - DecoderErrorOr tx_mode_probs(BooleanDecoder&); - DecoderErrorOr diff_update_prob(BooleanDecoder&, u8 prob); - DecoderErrorOr decode_term_subexp(BooleanDecoder&); + TransformMode read_tx_mode(BooleanDecoder&, FrameContext const&); + void tx_mode_probs(BooleanDecoder&); + u8 diff_update_prob(BooleanDecoder&, u8 prob); + u8 decode_term_subexp(BooleanDecoder&); u8 inv_remap_prob(u8 delta_prob, u8 prob); u8 inv_recenter_nonneg(u8 v, u8 m); - DecoderErrorOr read_coef_probs(BooleanDecoder&, TransformMode); - DecoderErrorOr read_skip_prob(BooleanDecoder&); - DecoderErrorOr read_inter_mode_probs(BooleanDecoder&); - DecoderErrorOr read_interp_filter_probs(BooleanDecoder&); - DecoderErrorOr read_is_inter_probs(BooleanDecoder&); - DecoderErrorOr frame_reference_mode(FrameContext&, BooleanDecoder&); - DecoderErrorOr frame_reference_mode_probs(BooleanDecoder&, FrameContext const&); - DecoderErrorOr read_y_mode_probs(BooleanDecoder&); - DecoderErrorOr read_partition_probs(BooleanDecoder&); - DecoderErrorOr mv_probs(BooleanDecoder&, FrameContext const&); - DecoderErrorOr update_mv_prob(BooleanDecoder&, u8 prob); + void read_coef_probs(BooleanDecoder&, TransformMode); + void read_skip_prob(BooleanDecoder&); + void read_inter_mode_probs(BooleanDecoder&); + void read_interp_filter_probs(BooleanDecoder&); + void read_is_inter_probs(BooleanDecoder&); + void frame_reference_mode(FrameContext&, BooleanDecoder&); + void frame_reference_mode_probs(BooleanDecoder&, FrameContext const&); + void read_y_mode_probs(BooleanDecoder&); + void read_partition_probs(BooleanDecoder&); + void mv_probs(BooleanDecoder&, FrameContext const&); + u8 update_mv_prob(BooleanDecoder&, u8 prob); /* (6.4) Decode Tiles Syntax */ DecoderErrorOr decode_tiles(FrameContext&); @@ -95,24 +95,24 @@ private: void clear_left_context(TileContext&); DecoderErrorOr decode_partition(TileContext&, u32 row, u32 column, BlockSubsize subsize); DecoderErrorOr decode_block(TileContext&, u32 row, u32 column, BlockSubsize subsize); - DecoderErrorOr mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - DecoderErrorOr intra_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - DecoderErrorOr set_intra_segment_id(BlockContext&); - DecoderErrorOr read_should_skip_residuals(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - DecoderErrorOr read_tx_size(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select); - DecoderErrorOr inter_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - DecoderErrorOr set_inter_segment_id(BlockContext&); + void mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); + void intra_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); + void set_intra_segment_id(BlockContext&); + bool read_should_skip_residuals(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); + TransformSize read_tx_size(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select); + void inter_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); + void set_inter_segment_id(BlockContext&); u8 get_segment_id(BlockContext const&); - DecoderErrorOr read_is_inter(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - DecoderErrorOr intra_block_mode_info(BlockContext&); - DecoderErrorOr inter_block_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - DecoderErrorOr read_ref_frames(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); - DecoderErrorOr get_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&); - DecoderErrorOr read_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&, ReferenceIndex); - DecoderErrorOr read_single_motion_vector_component(BooleanDecoder&, SyntaxElementCounter&, u8 component, bool use_high_precision); + bool read_is_inter(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); + void intra_block_mode_info(BlockContext&); + void inter_block_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); + void read_ref_frames(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); + MotionVectorPair get_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&); + MotionVector read_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&, ReferenceIndex); + i32 read_single_motion_vector_component(BooleanDecoder&, SyntaxElementCounter&, u8 component, bool use_high_precision); DecoderErrorOr residual(BlockContext&, bool has_block_above, bool has_block_left); - DecoderErrorOr tokens(BlockContext&, size_t plane, u32 x, u32 y, TransformSize, TransformSet, Array token_cache); - DecoderErrorOr read_coef(BooleanDecoder&, u8 bit_depth, Token token); + bool tokens(BlockContext&, size_t plane, u32 x, u32 y, TransformSize, TransformSet, Array token_cache); + i32 read_coef(BooleanDecoder&, u8 bit_depth, Token token); /* (6.5) Motion Vector Prediction */ MotionVectorPair find_reference_motion_vectors(BlockContext&, ReferenceFrameType, i32 block); diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp index 2e62e27468..80a168d31d 100644 --- a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp +++ b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp @@ -51,7 +51,7 @@ private: }; template -inline ErrorOr parse_tree(BooleanDecoder& decoder, TreeSelection tree_selection, Function const& probability_getter) +inline OutputType parse_tree(BooleanDecoder& decoder, TreeSelection tree_selection, Function const& probability_getter) { // 9.3.3: The tree decoding function. if (tree_selection.is_single_value()) @@ -61,13 +61,13 @@ inline ErrorOr parse_tree(BooleanDecoder& decoder, TreeSelection tre int n = 0; do { u8 node = n >> 1; - n = tree[n + TRY(decoder.read_bool(probability_getter(node)))]; + n = tree[n + decoder.read_bool(probability_getter(node))]; } while (n > 0); return static_cast(-n); } -ErrorOr TreeParser::parse_partition(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, PartitionContextView above_partition_context, PartitionContextView left_partition_context, u32 row, u32 column, bool frame_is_intra) +Partition TreeParser::parse_partition(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, PartitionContextView above_partition_context, PartitionContextView left_partition_context, u32 row, u32 column, bool frame_is_intra) { // Tree array TreeSelection tree = { PartitionSplit }; @@ -100,12 +100,12 @@ ErrorOr TreeParser::parse_partition(BooleanDecoder& decoder, Probabil return probabilities[2]; }; - auto value = TRY(parse_tree(decoder, tree, probability_getter)); + auto value = parse_tree(decoder, tree, probability_getter); counter.m_counts_partition[context][value]++; return value; } -ErrorOr TreeParser::parse_default_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, BlockSubsize mi_size, FrameBlockContext above, FrameBlockContext left, Array const& block_sub_modes, u8 index_x, u8 index_y) +PredictionMode TreeParser::parse_default_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, BlockSubsize mi_size, FrameBlockContext above, FrameBlockContext left, Array const& block_sub_modes, u8 index_x, u8 index_y) { // FIXME: This should use a struct for the above and left contexts. @@ -130,12 +130,12 @@ ErrorOr TreeParser::parse_default_intra_mode(BooleanDecoder& dec } u8 const* probabilities = probability_table.kf_y_mode_probs()[to_underlying(above_mode)][to_underlying(left_mode)]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); // Default intra mode is not counted. return value; } -ErrorOr TreeParser::parse_default_uv_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, PredictionMode y_mode) +PredictionMode TreeParser::parse_default_uv_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, PredictionMode y_mode) { // Tree TreeSelection tree = { intra_mode_tree }; @@ -143,12 +143,12 @@ ErrorOr TreeParser::parse_default_uv_mode(BooleanDecoder& decode // Probabilities u8 const* probabilities = probability_table.kf_uv_mode_prob()[to_underlying(y_mode)]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); // Default UV mode is not counted. return value; } -ErrorOr TreeParser::parse_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, BlockSubsize mi_size) +PredictionMode TreeParser::parse_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, BlockSubsize mi_size) { // Tree TreeSelection tree = { intra_mode_tree }; @@ -157,12 +157,12 @@ ErrorOr TreeParser::parse_intra_mode(BooleanDecoder& decoder, Pr auto context = size_group_lookup[mi_size]; u8 const* probabilities = probability_table.y_mode_probs()[context]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); counter.m_counts_intra_mode[context][to_underlying(value)]++; return value; } -ErrorOr TreeParser::parse_sub_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter) +PredictionMode TreeParser::parse_sub_intra_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter) { // Tree TreeSelection tree = { intra_mode_tree }; @@ -170,12 +170,12 @@ ErrorOr TreeParser::parse_sub_intra_mode(BooleanDecoder& decoder // Probabilities u8 const* probabilities = probability_table.y_mode_probs()[0]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); counter.m_counts_intra_mode[0][to_underlying(value)]++; return value; } -ErrorOr TreeParser::parse_uv_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, PredictionMode y_mode) +PredictionMode TreeParser::parse_uv_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, PredictionMode y_mode) { // Tree TreeSelection tree = { intra_mode_tree }; @@ -183,27 +183,27 @@ ErrorOr TreeParser::parse_uv_mode(BooleanDecoder& decoder, Proba // Probabilities u8 const* probabilities = probability_table.uv_mode_probs()[to_underlying(y_mode)]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); counter.m_counts_uv_mode[to_underlying(y_mode)][to_underlying(value)]++; return value; } -ErrorOr TreeParser::parse_segment_id(BooleanDecoder& decoder, Array const& probabilities) +u8 TreeParser::parse_segment_id(BooleanDecoder& decoder, Array const& probabilities) { - auto value = TRY(parse_tree(decoder, { segment_tree }, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, { segment_tree }, [&](u8 node) { return probabilities[node]; }); // Segment ID is not counted. return value; } -ErrorOr TreeParser::parse_segment_id_predicted(BooleanDecoder& decoder, Array const& probabilities, u8 above_seg_pred_context, u8 left_seg_pred_context) +bool TreeParser::parse_segment_id_predicted(BooleanDecoder& decoder, Array const& probabilities, u8 above_seg_pred_context, u8 left_seg_pred_context) { auto context = left_seg_pred_context + above_seg_pred_context; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probabilities[context]; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probabilities[context]; }); // Segment ID prediction is not counted. return value; } -ErrorOr TreeParser::parse_inter_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 mode_context_for_ref_frame_0) +PredictionMode TreeParser::parse_inter_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 mode_context_for_ref_frame_0) { // Tree TreeSelection tree = { inter_mode_tree }; @@ -211,12 +211,12 @@ ErrorOr TreeParser::parse_inter_mode(BooleanDecoder& decoder, Pr // Probabilities u8 const* probabilities = probability_table.inter_mode_probs()[mode_context_for_ref_frame_0]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); counter.m_counts_inter_mode[mode_context_for_ref_frame_0][value]++; return static_cast(value + to_underlying(PredictionMode::NearestMv)); } -ErrorOr TreeParser::parse_interpolation_filter(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) +InterpolationFilter TreeParser::parse_interpolation_filter(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) { // FIXME: Above and left context should be provided by a struct. @@ -236,12 +236,12 @@ ErrorOr TreeParser::parse_interpolation_filter(BooleanDecod context = above_interp; u8 const* probabilities = probability_table.interp_filter_probs()[context]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); counter.m_counts_interp_filter[context][to_underlying(value)]++; return value; } -ErrorOr TreeParser::parse_skip(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) +bool TreeParser::parse_skip(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) { // Probabilities u8 context = 0; @@ -249,12 +249,12 @@ ErrorOr TreeParser::parse_skip(BooleanDecoder& decoder, ProbabilityTables context += static_cast(left.skip_coefficients); u8 probability = probability_table.skip_prob()[context]; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability; }); counter.m_counts_skip[context][value]++; return value; } -ErrorOr TreeParser::parse_tx_size(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TransformSize max_tx_size, FrameBlockContext above, FrameBlockContext left) +TransformSize TreeParser::parse_tx_size(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TransformSize max_tx_size, FrameBlockContext above, FrameBlockContext left) { // FIXME: Above and left contexts should be in structs. @@ -280,12 +280,12 @@ ErrorOr TreeParser::parse_tx_size(BooleanDecoder& decoder, Probab u8 const* probabilities = probability_table.tx_probs()[max_tx_size][context]; - auto value = TRY(parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; })); + auto value = parse_tree(decoder, tree, [&](u8 node) { return probabilities[node]; }); counter.m_counts_tx_size[max_tx_size][context][value]++; return value; } -ErrorOr TreeParser::parse_block_is_inter_predicted(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) +bool TreeParser::parse_block_is_inter_predicted(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) { // FIXME: Above and left contexts should be in structs. @@ -297,12 +297,12 @@ ErrorOr TreeParser::parse_block_is_inter_predicted(BooleanDecoder& decoder context = 2 * static_cast(above.is_available ? above.is_intra_predicted() : left.is_intra_predicted()); u8 probability = probability_table.is_inter_prob()[context]; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability; }); counter.m_counts_is_inter[context][value]++; return value; } -ErrorOr TreeParser::parse_comp_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, ReferenceFrameType comp_fixed_ref, FrameBlockContext above, FrameBlockContext left) +ReferenceMode TreeParser::parse_comp_mode(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, ReferenceFrameType comp_fixed_ref, FrameBlockContext above, FrameBlockContext left) { // FIXME: Above and left contexts should be in structs. @@ -337,12 +337,12 @@ ErrorOr TreeParser::parse_comp_mode(BooleanDecoder& decoder, Prob } u8 probability = probability_table.comp_mode_prob()[context]; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability; }); counter.m_counts_comp_mode[context][value]++; return value; } -ErrorOr TreeParser::parse_comp_ref(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, ReferenceFrameType comp_fixed_ref, ReferenceFramePair comp_var_ref, ReferenceIndex variable_reference_index, FrameBlockContext above, FrameBlockContext left) +ReferenceIndex TreeParser::parse_comp_ref(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, ReferenceFrameType comp_fixed_ref, ReferenceFramePair comp_var_ref, ReferenceIndex variable_reference_index, FrameBlockContext above, FrameBlockContext left) { // FIXME: Above and left contexts should be in structs. @@ -420,12 +420,12 @@ ErrorOr TreeParser::parse_comp_ref(BooleanDecoder& decoder, Prob u8 probability = probability_table.comp_ref_prob()[context]; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability; }); counter.m_counts_comp_ref[context][to_underlying(value)]++; return value; } -ErrorOr TreeParser::parse_single_ref_part_1(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) +bool TreeParser::parse_single_ref_part_1(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) { // FIXME: Above and left contexts should be in structs. @@ -487,12 +487,12 @@ ErrorOr TreeParser::parse_single_ref_part_1(BooleanDecoder& decoder, Proba } u8 probability = probability_table.single_ref_prob()[context][0]; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability; }); counter.m_counts_single_ref[context][0][value]++; return value; } -ErrorOr TreeParser::parse_single_ref_part_2(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) +bool TreeParser::parse_single_ref_part_2(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, FrameBlockContext above, FrameBlockContext left) { // FIXME: Above and left contexts should be in structs. @@ -573,78 +573,78 @@ ErrorOr TreeParser::parse_single_ref_part_2(BooleanDecoder& decoder, Proba } u8 probability = probability_table.single_ref_prob()[context][1]; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability; }); counter.m_counts_single_ref[context][1][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_joint(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter) +MvJoint TreeParser::parse_motion_vector_joint(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter) { - auto value = TRY(parse_tree(decoder, { mv_joint_tree }, [&](u8 node) { return probability_table.mv_joint_probs()[node]; })); + auto value = parse_tree(decoder, { mv_joint_tree }, [&](u8 node) { return probability_table.mv_joint_probs()[node]; }); counter.m_counts_mv_joint[value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_sign(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) +bool TreeParser::parse_motion_vector_sign(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) { - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability_table.mv_sign_prob()[component]; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability_table.mv_sign_prob()[component]; }); counter.m_counts_mv_sign[component][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_class(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) +MvClass TreeParser::parse_motion_vector_class(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) { // Spec doesn't mention node, but the probabilities table has an extra dimension // so we will use node for that. - auto value = TRY(parse_tree(decoder, { mv_class_tree }, [&](u8 node) { return probability_table.mv_class_probs()[component][node]; })); + auto value = parse_tree(decoder, { mv_class_tree }, [&](u8 node) { return probability_table.mv_class_probs()[component][node]; }); counter.m_counts_mv_class[component][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_class0_bit(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) +bool TreeParser::parse_motion_vector_class0_bit(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) { - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability_table.mv_class0_bit_prob()[component]; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability_table.mv_class0_bit_prob()[component]; }); counter.m_counts_mv_class0_bit[component][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_class0_fr(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool class_0_bit) +u8 TreeParser::parse_motion_vector_class0_fr(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool class_0_bit) { - auto value = TRY(parse_tree(decoder, { mv_fr_tree }, [&](u8 node) { return probability_table.mv_class0_fr_probs()[component][class_0_bit][node]; })); + auto value = parse_tree(decoder, { mv_fr_tree }, [&](u8 node) { return probability_table.mv_class0_fr_probs()[component][class_0_bit][node]; }); counter.m_counts_mv_class0_fr[component][class_0_bit][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_class0_hp(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool use_hp) +bool TreeParser::parse_motion_vector_class0_hp(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool use_hp) { TreeSelection tree { 1 }; if (use_hp) tree = { binary_tree }; - auto value = TRY(parse_tree(decoder, tree, [&](u8) { return probability_table.mv_class0_hp_prob()[component]; })); + auto value = parse_tree(decoder, tree, [&](u8) { return probability_table.mv_class0_hp_prob()[component]; }); counter.m_counts_mv_class0_hp[component][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_bit(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, u8 bit_index) +bool TreeParser::parse_motion_vector_bit(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, u8 bit_index) { - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability_table.mv_bits_prob()[component][bit_index]; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability_table.mv_bits_prob()[component][bit_index]; }); counter.m_counts_mv_bits[component][bit_index][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_fr(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) +u8 TreeParser::parse_motion_vector_fr(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component) { - auto value = TRY(parse_tree(decoder, { mv_fr_tree }, [&](u8 node) { return probability_table.mv_fr_probs()[component][node]; })); + auto value = parse_tree(decoder, { mv_fr_tree }, [&](u8 node) { return probability_table.mv_fr_probs()[component][node]; }); counter.m_counts_mv_fr[component][value]++; return value; } -ErrorOr TreeParser::parse_motion_vector_hp(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool use_hp) +bool TreeParser::parse_motion_vector_hp(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, u8 component, bool use_hp) { TreeSelection tree { 1 }; if (use_hp) tree = { binary_tree }; - auto value = TRY(parse_tree(decoder, tree, [&](u8) { return probability_table.mv_hp_prob()[component]; })); + auto value = parse_tree(decoder, tree, [&](u8) { return probability_table.mv_hp_prob()[component]; }); counter.m_counts_mv_hp[component][value]++; return value; } @@ -704,15 +704,15 @@ TokensContext TreeParser::get_context_for_other_tokens(Array token_cac return TokensContext { transform_size, plane > 0, is_inter, band, context }; } -ErrorOr TreeParser::parse_more_coefficients(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TokensContext const& context) +bool TreeParser::parse_more_coefficients(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TokensContext const& context) { auto probability = probability_table.coef_probs()[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][0]; - auto value = TRY(parse_tree(decoder, { binary_tree }, [&](u8) { return probability; })); + auto value = parse_tree(decoder, { binary_tree }, [&](u8) { return probability; }); counter.m_counts_more_coefs[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][value]++; return value; } -ErrorOr TreeParser::parse_token(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TokensContext const& context) +Token TreeParser::parse_token(BooleanDecoder& decoder, ProbabilityTables const& probability_table, SyntaxElementCounter& counter, TokensContext const& context) { Function probability_getter = [&](u8 node) -> u8 { auto prob = probability_table.coef_probs()[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][min(2, 1 + node)]; @@ -725,7 +725,7 @@ ErrorOr TreeParser::parse_token(BooleanDecoder& decoder, ProbabilityTable return (pareto_table[x][node - 2] + pareto_table[x + 1][node - 2]) >> 1; }; - auto value = TRY(parse_tree(decoder, { token_tree }, probability_getter)); + auto value = parse_tree(decoder, { token_tree }, probability_getter); counter.m_counts_token[context.m_tx_size][context.m_is_uv_plane][context.m_is_inter][context.m_band][context.m_context_index][min(2, value)]++; return value; } diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.h b/Userland/Libraries/LibVideo/VP9/TreeParser.h index 8b0c684ae7..f35aa5056a 100644 --- a/Userland/Libraries/LibVideo/VP9/TreeParser.h +++ b/Userland/Libraries/LibVideo/VP9/TreeParser.h @@ -30,38 +30,38 @@ struct TokensContext { class TreeParser { public: - static ErrorOr parse_partition(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, PartitionContextView above_partition_context, PartitionContextView left_partition_context, u32 row, u32 column, bool frame_is_intra); - static ErrorOr parse_default_intra_mode(BooleanDecoder&, ProbabilityTables const&, BlockSubsize mi_size, FrameBlockContext above, FrameBlockContext left, Array const& block_sub_modes, u8 index_x, u8 index_y); - static ErrorOr parse_default_uv_mode(BooleanDecoder&, ProbabilityTables const&, PredictionMode y_mode); - static ErrorOr parse_intra_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, BlockSubsize mi_size); - static ErrorOr parse_sub_intra_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&); - static ErrorOr parse_uv_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, PredictionMode y_mode); - static ErrorOr parse_segment_id(BooleanDecoder&, Array const& probabilities); - static ErrorOr parse_segment_id_predicted(BooleanDecoder&, Array const& probabilities, u8 above_seg_pred_context, u8 left_seg_pred_context); - static ErrorOr parse_inter_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 mode_context_for_ref_frame_0); - static ErrorOr parse_interpolation_filter(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_skip(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_tx_size(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, TransformSize max_tx_size, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_block_is_inter_predicted(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_comp_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, ReferenceFrameType comp_fixed_ref, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_comp_ref(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, ReferenceFrameType comp_fixed_ref, ReferenceFramePair comp_var_ref, ReferenceIndex variable_reference_index, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_single_ref_part_1(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_single_ref_part_2(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); + static Partition parse_partition(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, bool has_rows, bool has_columns, BlockSubsize block_subsize, u8 num_8x8, PartitionContextView above_partition_context, PartitionContextView left_partition_context, u32 row, u32 column, bool frame_is_intra); + static PredictionMode parse_default_intra_mode(BooleanDecoder&, ProbabilityTables const&, BlockSubsize mi_size, FrameBlockContext above, FrameBlockContext left, Array const& block_sub_modes, u8 index_x, u8 index_y); + static PredictionMode parse_default_uv_mode(BooleanDecoder&, ProbabilityTables const&, PredictionMode y_mode); + static PredictionMode parse_intra_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, BlockSubsize mi_size); + static PredictionMode parse_sub_intra_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&); + static PredictionMode parse_uv_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, PredictionMode y_mode); + static u8 parse_segment_id(BooleanDecoder&, Array const& probabilities); + static bool parse_segment_id_predicted(BooleanDecoder&, Array const& probabilities, u8 above_seg_pred_context, u8 left_seg_pred_context); + static PredictionMode parse_inter_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 mode_context_for_ref_frame_0); + static InterpolationFilter parse_interpolation_filter(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); + static bool parse_skip(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); + static TransformSize parse_tx_size(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, TransformSize max_tx_size, FrameBlockContext above, FrameBlockContext left); + static bool parse_block_is_inter_predicted(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); + static ReferenceMode parse_comp_mode(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, ReferenceFrameType comp_fixed_ref, FrameBlockContext above, FrameBlockContext left); + static ReferenceIndex parse_comp_ref(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, ReferenceFrameType comp_fixed_ref, ReferenceFramePair comp_var_ref, ReferenceIndex variable_reference_index, FrameBlockContext above, FrameBlockContext left); + static bool parse_single_ref_part_1(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); + static bool parse_single_ref_part_2(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, FrameBlockContext above, FrameBlockContext left); - static ErrorOr parse_motion_vector_joint(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&); - static ErrorOr parse_motion_vector_sign(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); - static ErrorOr parse_motion_vector_class(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); - static ErrorOr parse_motion_vector_class0_bit(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); - static ErrorOr parse_motion_vector_class0_fr(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, bool class_0_bit); - static ErrorOr parse_motion_vector_class0_hp(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, bool use_hp); - static ErrorOr parse_motion_vector_bit(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, u8 bit_index); - static ErrorOr parse_motion_vector_fr(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); - static ErrorOr parse_motion_vector_hp(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, bool use_hp); + static MvJoint parse_motion_vector_joint(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&); + static bool parse_motion_vector_sign(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); + static MvClass parse_motion_vector_class(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); + static bool parse_motion_vector_class0_bit(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); + static u8 parse_motion_vector_class0_fr(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, bool class_0_bit); + static bool parse_motion_vector_class0_hp(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, bool use_hp); + static bool parse_motion_vector_bit(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, u8 bit_index); + static u8 parse_motion_vector_fr(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component); + static bool parse_motion_vector_hp(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, u8 component, bool use_hp); static TokensContext get_context_for_first_token(NonZeroTokensView above_non_zero_tokens, NonZeroTokensView left_non_zero_tokens, TransformSize transform_size, u8 plane, u32 sub_block_column, u32 sub_block_row, bool is_inter, u8 band); static TokensContext get_context_for_other_tokens(Array token_cache, TransformSize transform_size, TransformSet transform_set, u8 plane, u16 token_position, bool is_inter, u8 band); - static ErrorOr parse_more_coefficients(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context); - static ErrorOr parse_token(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context); + static bool parse_more_coefficients(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context); + static Token parse_token(BooleanDecoder&, ProbabilityTables const&, SyntaxElementCounter&, TokensContext const& context); }; struct PartitionTreeContext {