diff options
author | Zaggy1024 <zaggy1024@gmail.com> | 2023-02-10 11:44:30 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-02-10 23:34:37 +0100 |
commit | 33ff3427eb29a5518968e3c8051808ce5aad3e4d (patch) | |
tree | 5b0d06708fe5e201d25e5d9355c2db7e0fab82dc /Userland/Libraries | |
parent | 7c607462a499de2966ccc6b8eb2fc8f6e7cb6f53 (diff) | |
download | serenity-33ff3427eb29a5518968e3c8051808ce5aad3e4d.zip |
LibVideo/VP9: Drop the decoder intermediate bounds checks
Checking the bounds of the intermediate values was only implemented to
help debug the decoder. However, it is non-fatal to have the values
exceed the spec-defined bounds, and causes a measurable performance
reduction.
Additionally, the checks were implemented as an assertion, which is
easily broken by bad input files.
I see about a 4-5% decrease in decoding times in the `webm_in_vp9` test
in TestVP9Decode.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibVideo/VP9/Decoder.cpp | 115 | ||||
-rw-r--r-- | Userland/Libraries/LibVideo/VP9/Decoder.h | 17 |
2 files changed, 50 insertions, 82 deletions
diff --git a/Userland/Libraries/LibVideo/VP9/Decoder.cpp b/Userland/Libraries/LibVideo/VP9/Decoder.cpp index cf2e887c65..e5c1272ae7 100644 --- a/Userland/Libraries/LibVideo/VP9/Decoder.cpp +++ b/Userland/Libraries/LibVideo/VP9/Decoder.cpp @@ -1099,8 +1099,8 @@ DecoderErrorOr<void> Decoder::reconstruct(u8 plane, BlockContext const& block_co // It is a requirement of bitstream conformance that the values written into the Dequant array in steps 1 and 2 // are representable by a signed integer with 8 + BitDepth bits. - for (auto i = 0u; i < block_size * block_size; i++) - VERIFY(check_intermediate_bounds(block_context.frame_context.color_config.bit_depth, dequantized[i])); + // Note: Since bounds checks just ensure that we will not have resulting values that will overflow, it's non-fatal + // to allow these bounds to be violated. Therefore, we can avoid the performance cost here. // 3. Invoke the 2D inverse transform block process defined in section 8.7.2 with the variable n as input. // The inverse transform outputs are stored back to the Dequant buffer. @@ -1172,20 +1172,8 @@ inline i32 Decoder::round_2(T value, u8 bits) return static_cast<i32>(value); } -inline bool check_bounds(i64 value, u8 bits) -{ - i64 const maximum = (1ll << (bits - 1ll)) - 1ll; - return value >= ~maximum && value <= maximum; -} - -inline bool Decoder::check_intermediate_bounds(u8 bit_depth, Intermediate value) -{ - i32 maximum = (1 << (8 + bit_depth - 1)) - 1; - return value >= ~maximum && value <= maximum; -} - // (8.7.1.1) The function B( a, b, angle, 0 ) performs a butterfly rotation. -inline void Decoder::butterfly_rotation_in_place(u8 bit_depth, Span<Intermediate> data, size_t index_a, size_t index_b, u8 angle, bool flip) +inline void Decoder::butterfly_rotation_in_place(Span<Intermediate> data, size_t index_a, size_t index_b, u8 angle, bool flip) { auto cos = cos64(angle); auto sin = sin64(angle); @@ -1206,12 +1194,12 @@ inline void Decoder::butterfly_rotation_in_place(u8 bit_depth, Span<Intermediate // It is a requirement of bitstream conformance that the values saved into the array T by this function are // representable by a signed integer using 8 + BitDepth bits of precision. - VERIFY(check_intermediate_bounds(bit_depth, data[index_a])); - VERIFY(check_intermediate_bounds(bit_depth, data[index_b])); + // Note: Since bounds checks just ensure that we will not have resulting values that will overflow, it's non-fatal + // to allow these bounds to be violated. Therefore, we can avoid the performance cost here. } // (8.7.1.1) The function H( a, b, 0 ) performs a Hadamard rotation. -inline void Decoder::hadamard_rotation_in_place(u8 bit_depth, Span<Intermediate> data, size_t index_a, size_t index_b, bool flip) +inline void Decoder::hadamard_rotation_in_place(Span<Intermediate> data, size_t index_a, size_t index_b, bool flip) { // The function H( a, b, 1 ) performs a Hadamard rotation with flipped indices and is specified as follows: // 1. The function H( b, a, 0 ) is invoked. @@ -1231,8 +1219,8 @@ inline void Decoder::hadamard_rotation_in_place(u8 bit_depth, Span<Intermediate> // It is a requirement of bitstream conformance that the values saved into the array T by this function are // representable by a signed integer using 8 + BitDepth bits of precision. - VERIFY(check_intermediate_bounds(bit_depth, data[index_a])); - VERIFY(check_intermediate_bounds(bit_depth, data[index_b])); + // Note: Since bounds checks just ensure that we will not have resulting values that will overflow, it's non-fatal + // to allow these bounds to be violated. Therefore, we can avoid the performance cost here. } inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform_array_permutation(Span<Intermediate> data, u8 log2_of_block_size) @@ -1255,7 +1243,7 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform_array_per return {}; } -inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_depth, Span<Intermediate> data, u8 log2_of_block_size) +inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(Span<Intermediate> data, u8 log2_of_block_size) { // 2.1. The variable n0 is set equal to 1<<n. u8 block_size = 1 << log2_of_block_size; @@ -1272,14 +1260,14 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_de // 2.5 If n is equal to 2, invoke B( 0, 1, 16, 1 ), otherwise recursively invoke the inverse DCT defined in this // section with the variable n set equal to n - 1. if (log2_of_block_size == 2) - butterfly_rotation_in_place(bit_depth, data, 0, 1, 16, true); + butterfly_rotation_in_place(data, 0, 1, 16, true); else - TRY(inverse_discrete_cosine_transform(bit_depth, data, log2_of_block_size - 1)); + TRY(inverse_discrete_cosine_transform(data, log2_of_block_size - 1)); // 2.6 Invoke B( n1+i, n0-1-i, 32-brev( 5, n1+i), 0 ) for i = 0..(n2-1). for (auto i = 0u; i < quarter_block_size; i++) { auto index = half_block_size + i; - butterfly_rotation_in_place(bit_depth, data, index, block_size - 1 - i, 32 - brev(5, index), false); + butterfly_rotation_in_place(data, index, block_size - 1 - i, 32 - brev(5, index), false); } // 2.7 If n is greater than or equal to 3: @@ -1288,7 +1276,7 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_de for (auto i = 0u; i < eighth_block_size; i++) { for (auto j = 0u; j < 2; j++) { auto index = half_block_size + (4 * i) + (2 * j); - hadamard_rotation_in_place(bit_depth, data, index, index + 1, j); + hadamard_rotation_in_place(data, index, index + 1, j); } } } @@ -1301,7 +1289,7 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_de auto index_a = block_size - log2_of_block_size + 3 - (quarter_block_size * j) - (4 * i); auto index_b = half_block_size + log2_of_block_size - 4 + (quarter_block_size * j) + (4 * i); auto angle = 28 - (16 * i) + (56 * j); - butterfly_rotation_in_place(bit_depth, data, index_a, index_b, angle, true); + butterfly_rotation_in_place(data, index_a, index_b, angle, true); } } @@ -1310,7 +1298,7 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_de for (auto j = 0u; j < 4; j++) { auto index_a = half_block_size + (eighth_block_size * j) + i; auto index_b = half_block_size + quarter_block_size - 5 + (eighth_block_size * j) - i; - hadamard_rotation_in_place(bit_depth, data, index_a, index_b, (j & 1) != 0); + hadamard_rotation_in_place(data, index_a, index_b, (j & 1) != 0); } } } @@ -1322,7 +1310,7 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_de for (auto j = 0u; j < 2; j++) { auto index_a = block_size - log2_of_block_size + 2 - i - (quarter_block_size * j); auto index_b = half_block_size + log2_of_block_size - 3 + i + (quarter_block_size * j); - butterfly_rotation_in_place(bit_depth, data, index_a, index_b, 24 + (48 * j), true); + butterfly_rotation_in_place(data, index_a, index_b, 24 + (48 * j), true); } } @@ -1331,7 +1319,7 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_de for (auto j = 0u; j < 2; j++) { auto index_a = half_block_size + (quarter_block_size * j) + i; auto index_b = half_block_size + quarter_block_size - 1 + (quarter_block_size * j) - i; - hadamard_rotation_in_place(bit_depth, data, index_a, index_b, (j & 1) != 0); + hadamard_rotation_in_place(data, index_a, index_b, (j & 1) != 0); } } } @@ -1342,13 +1330,13 @@ inline DecoderErrorOr<void> Decoder::inverse_discrete_cosine_transform(u8 bit_de for (auto i = 0u; i < eighth_block_size; i++) { auto index_a = block_size - eighth_block_size - 1 - i; auto index_b = half_block_size + eighth_block_size + i; - butterfly_rotation_in_place(bit_depth, data, index_a, index_b, 16, true); + butterfly_rotation_in_place(data, index_a, index_b, 16, true); } } // 7. Invoke H( i, n0-1-i, 0 ) for i = 0..(n1-1). for (auto i = 0u; i < half_block_size; i++) - hadamard_rotation_in_place(bit_depth, data, i, block_size - 1 - i, false); + hadamard_rotation_in_place(data, i, block_size - 1 - i, false); return {}; } @@ -1402,7 +1390,7 @@ inline void Decoder::inverse_asymmetric_discrete_sine_transform_output_array_per } } -inline void Decoder::inverse_asymmetric_discrete_sine_transform_4(u8 bit_depth, Span<Intermediate> data) +inline void Decoder::inverse_asymmetric_discrete_sine_transform_4(Span<Intermediate> data) { VERIFY(data.size() == 4); const i64 sinpi_1_9 = 5283; @@ -1459,11 +1447,8 @@ inline void Decoder::inverse_asymmetric_discrete_sine_transform_4(u8 bit_depth, // (8.7.1.1) The inverse asymmetric discrete sine transforms also make use of an intermediate array named S. // The values in this array require higher precision to avoid overflow. Using signed integers with 24 + // BitDepth bits of precision is enough to avoid overflow. - const u8 bits = 24 + bit_depth; - VERIFY(check_bounds(data[0], bits)); - VERIFY(check_bounds(data[1], bits)); - VERIFY(check_bounds(data[2], bits)); - VERIFY(check_bounds(data[3], bits)); + // Note: Since bounds checks just ensure that we will not have resulting values that will overflow, it's non-fatal + // to allow these bounds to be violated. Therefore, we can avoid the performance cost here. } // The function SB( a, b, angle, 0 ) performs a butterfly rotation. @@ -1503,12 +1488,14 @@ inline void Decoder::hadamard_rotation(Span<S> source, Span<D> destination, size destination[index_b] = round_2(a - b, 14); } -inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_8(u8 bit_depth, Span<Intermediate> data) +inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_8(Span<Intermediate> data) { VERIFY(data.size() == 8); // This process does an in-place transform of the array T using: // A higher precision array S for intermediate results. + // (8.7.1.1) NOTE - The values in array S require higher precision to avoid overflow. Using signed integers with + // 24 + BitDepth bits of precision is enough to avoid overflow. Array<i64, 8> high_precision_temp; // The following ordered steps apply: @@ -1520,11 +1507,7 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_ // 2. Invoke SB( 2*i, 1+2*i, 30-8*i, 1 ) for i = 0..3. for (auto i = 0u; i < 4; i++) butterfly_rotation(data, high_precision_temp.span(), 2 * i, 1 + (2 * i), 30 - (8 * i), true); - // (8.7.1.1) NOTE - The values in array S require higher precision to avoid overflow. Using signed integers with - // 24 + BitDepth bits of precision is enough to avoid overflow. - const u8 bits = 24 + bit_depth; - for (auto i = 0u; i < 8; i++) - VERIFY(check_bounds(high_precision_temp[i], bits)); + // 3. Invoke SH( i, 4+i ) for i = 0..3. for (auto i = 0u; i < 4; i++) hadamard_rotation(high_precision_temp.span(), data, i, 4 + i); @@ -1532,20 +1515,17 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_ // 4. Invoke SB( 4+3*i, 5+i, 24-16*i, 1 ) for i = 0..1. for (auto i = 0u; i < 2; i++) butterfly_rotation(data, high_precision_temp.span(), 4 + (3 * i), 5 + i, 24 - (16 * i), true); - // Check again that we haven't exceeded the integer bounds. - for (auto i = 0u; i < 8; i++) - VERIFY(check_bounds(high_precision_temp[i], bits)); // 5. Invoke SH( 4+i, 6+i ) for i = 0..1. for (auto i = 0u; i < 2; i++) hadamard_rotation(high_precision_temp.span(), data, 4 + i, 6 + i); // 6. Invoke H( i, 2+i, 0 ) for i = 0..1. for (auto i = 0u; i < 2; i++) - hadamard_rotation_in_place(bit_depth, data, i, 2 + i, false); + hadamard_rotation_in_place(data, i, 2 + i, false); // 7. Invoke B( 2+4*i, 3+4*i, 16, 1 ) for i = 0..1. for (auto i = 0u; i < 2; i++) - butterfly_rotation_in_place(bit_depth, data, 2 + (4 * i), 3 + (4 * i), 16, true); + butterfly_rotation_in_place(data, 2 + (4 * i), 3 + (4 * i), 16, true); // 8. Invoke the ADST output array permutation process specified in section 8.7.1.5 with the input variable n // set equal to 3. @@ -1559,12 +1539,15 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_ return {}; } -inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_16(u8 bit_depth, Span<Intermediate> data) +inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_16(Span<Intermediate> data) { VERIFY(data.size() == 16); // This process does an in-place transform of the array T using: // A higher precision array S for intermediate results. + // (8.7.1.1) The inverse asymmetric discrete sine transforms also make use of an intermediate array named S. + // The values in this array require higher precision to avoid overflow. Using signed integers with 24 + + // BitDepth bits of precision is enough to avoid overflow. Array<i64, 16> high_precision_temp; // The following ordered steps apply: @@ -1576,12 +1559,6 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_ // 2. Invoke SB( 2*i, 1+2*i, 31-4*i, 1 ) for i = 0..7. for (auto i = 0u; i < 8; i++) butterfly_rotation(data, high_precision_temp.span(), 2 * i, 1 + (2 * i), 31 - (4 * i), true); - // (8.7.1.1) The inverse asymmetric discrete sine transforms also make use of an intermediate array named S. - // The values in this array require higher precision to avoid overflow. Using signed integers with 24 + - // BitDepth bits of precision is enough to avoid overflow. - const u8 bits = 24 + bit_depth; - for (auto i = 0u; i < 16; i++) - VERIFY(check_bounds(data[i], bits)); // 3. Invoke SH( i, 8+i ) for i = 0..7. for (auto i = 0u; i < 8; i++) hadamard_rotation(high_precision_temp.span(), data, i, 8 + i); @@ -1589,24 +1566,18 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_ // 4. Invoke SB( 8+2*i, 9+2*i, 28-16*i, 1 ) for i = 0..3. for (auto i = 0u; i < 4; i++) butterfly_rotation(data, high_precision_temp.span(), 8 + (2 * i), 9 + (2 * i), 128 + 28 - (16 * i), true); - // Check again that we haven't exceeded the integer bounds. - for (auto i = 0u; i < 16; i++) - VERIFY(check_bounds(data[i], bits)); // 5. Invoke SH( 8+i, 12+i ) for i = 0..3. for (auto i = 0u; i < 4; i++) hadamard_rotation(high_precision_temp.span(), data, 8 + i, 12 + i); // 6. Invoke H( i, 4+i, 0 ) for i = 0..3. for (auto i = 0u; i < 4; i++) - hadamard_rotation_in_place(bit_depth, data, i, 4 + i, false); + hadamard_rotation_in_place(data, i, 4 + i, false); // 7. Invoke SB( 4+8*i+3*j, 5+8*i+j, 24-16*j, 1 ) for i = 0..1, for j = 0..1. for (auto i = 0u; i < 2; i++) for (auto j = 0u; j < 2; j++) butterfly_rotation(data, high_precision_temp.span(), 4 + (8 * i) + (3 * j), 5 + (8 * i) + j, 24 - (16 * j), true); - // Check again that we haven't exceeded the integer bounds. - for (auto i = 0u; i < 16; i++) - VERIFY(check_bounds(data[i], bits)); // 8. Invoke SH( 4+8*j+i, 6+8*j+i ) for i = 0..1, j = 0..1. for (auto i = 0u; i < 2; i++) for (auto j = 0u; j < 2; j++) @@ -1615,11 +1586,11 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_ // 9. Invoke H( 8*j+i, 2+8*j+i, 0 ) for i = 0..1, for j = 0..1. for (auto i = 0u; i < 2; i++) for (auto j = 0u; j < 2; j++) - hadamard_rotation_in_place(bit_depth, data, (8 * j) + i, 2 + (8 * j) + i, false); + hadamard_rotation_in_place(data, (8 * j) + i, 2 + (8 * j) + i, false); // 10. Invoke B( 2+4*j+8*i, 3+4*j+8*i, 48+64*(i^j), 0 ) for i = 0..1, for j = 0..1. for (auto i = 0u; i < 2; i++) for (auto j = 0u; j < 2; j++) - butterfly_rotation_in_place(bit_depth, data, 2 + (4 * j) + (8 * i), 3 + (4 * j) + (8 * i), 48 + (64 * (i ^ j)), false); + butterfly_rotation_in_place(data, 2 + (4 * j) + (8 * i), 3 + (4 * j) + (8 * i), 48 + (64 * (i ^ j)), false); // 11. Invoke the ADST output array permutation process specified in section 8.7.1.5 with the input variable n // set equal to 4. @@ -1635,7 +1606,7 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform_ return {}; } -inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform(u8 bit_depth, Span<Intermediate> data, u8 log2_of_block_size) +inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform(Span<Intermediate> data, u8 log2_of_block_size) { // 8.7.1.9 Inverse ADST Process @@ -1646,15 +1617,15 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform( // The process to invoke depends on n as follows: if (log2_of_block_size == 2) { // − If n is equal to 2, invoke the Inverse ADST4 process specified in section 8.7.1.6. - inverse_asymmetric_discrete_sine_transform_4(bit_depth, data); + inverse_asymmetric_discrete_sine_transform_4(data); return {}; } if (log2_of_block_size == 3) { // − Otherwise if n is equal to 3, invoke the Inverse ADST8 process specified in section 8.7.1.7. - return inverse_asymmetric_discrete_sine_transform_8(bit_depth, data); + return inverse_asymmetric_discrete_sine_transform_8(data); } // − Otherwise (n is equal to 4), invoke the Inverse ADST16 process specified in section 8.7.1.8. - return inverse_asymmetric_discrete_sine_transform_16(bit_depth, data); + return inverse_asymmetric_discrete_sine_transform_16(data); } DecoderErrorOr<void> Decoder::inverse_transform_2d(BlockContext const& block_context, Span<Intermediate> dequantized, u8 log2_of_block_size, TransformSet transform_set) @@ -1687,12 +1658,12 @@ DecoderErrorOr<void> Decoder::inverse_transform_2d(BlockContext const& block_con // 1. Invoke the inverse DCT permutation process as specified in section 8.7.1.2 with the input variable n. TRY(inverse_discrete_cosine_transform_array_permutation(row, log2_of_block_size)); // 2. Invoke the inverse DCT process as specified in section 8.7.1.3 with the input variable n. - TRY(inverse_discrete_cosine_transform(block_context.frame_context.color_config.bit_depth, row, log2_of_block_size)); + TRY(inverse_discrete_cosine_transform(row, log2_of_block_size)); break; case TransformType::ADST: // 4. Otherwise (TxType is equal to DCT_ADST or TxType is equal to ADST_ADST), invoke the inverse ADST // process as specified in section 8.7.1.9 with input variable n. - TRY(inverse_asymmetric_discrete_sine_transform(block_context.frame_context.color_config.bit_depth, row, log2_of_block_size)); + TRY(inverse_asymmetric_discrete_sine_transform(row, log2_of_block_size)); break; default: return DecoderError::corrupted("Unknown tx_type"sv); @@ -1725,12 +1696,12 @@ DecoderErrorOr<void> Decoder::inverse_transform_2d(BlockContext const& block_con // 1. Invoke the inverse DCT permutation process as specified in section 8.7.1.2 with the input variable n. TRY(inverse_discrete_cosine_transform_array_permutation(column, log2_of_block_size)); // 2. Invoke the inverse DCT process as specified in section 8.7.1.3 with the input variable n. - TRY(inverse_discrete_cosine_transform(block_context.frame_context.color_config.bit_depth, column, log2_of_block_size)); + TRY(inverse_discrete_cosine_transform(column, log2_of_block_size)); break; case TransformType::ADST: // 4. Otherwise (TxType is equal to ADST_DCT or TxType is equal to ADST_ADST), invoke the inverse ADST // process as specified in section 8.7.1.9 with input variable n. - TRY(inverse_asymmetric_discrete_sine_transform(block_context.frame_context.color_config.bit_depth, column, log2_of_block_size)); + TRY(inverse_asymmetric_discrete_sine_transform(column, log2_of_block_size)); break; default: VERIFY_NOT_REACHED(); diff --git a/Userland/Libraries/LibVideo/VP9/Decoder.h b/Userland/Libraries/LibVideo/VP9/Decoder.h index 47be9261ce..7b41e68aed 100644 --- a/Userland/Libraries/LibVideo/VP9/Decoder.h +++ b/Userland/Libraries/LibVideo/VP9/Decoder.h @@ -89,9 +89,9 @@ private: inline i32 cos64(u8 angle); inline i32 sin64(u8 angle); // The function B( a, b, angle, 0 ) performs a butterfly rotation. - inline void butterfly_rotation_in_place(u8 bit_depth, Span<Intermediate> data, size_t index_a, size_t index_b, u8 angle, bool flip); + inline void butterfly_rotation_in_place(Span<Intermediate> data, size_t index_a, size_t index_b, u8 angle, bool flip); // The function H( a, b, 0 ) performs a Hadamard rotation. - inline void hadamard_rotation_in_place(u8 bit_depth, Span<Intermediate> data, size_t index_a, size_t index_b, bool flip); + inline void hadamard_rotation_in_place(Span<Intermediate> data, size_t index_a, size_t index_b, bool flip); // The function SB( a, b, angle, 0 ) performs a butterfly rotation. // Spec defines the source as array T, and the destination array as S. template<typename S, typename D> @@ -104,16 +104,13 @@ private: template<typename T> inline i32 round_2(T value, u8 bits); - // Checks whether the value is representable by a signed integer with (8 + bit_depth) bits. - inline bool check_intermediate_bounds(u8 bit_depth, Intermediate value); - // (8.7.1.10) This process does an in-place Walsh-Hadamard transform of the array T (of length 4). inline DecoderErrorOr<void> inverse_walsh_hadamard_transform(Span<Intermediate> data, u8 log2_of_block_size, u8 shift); // (8.7.1.2) Inverse DCT array permutation process inline DecoderErrorOr<void> inverse_discrete_cosine_transform_array_permutation(Span<Intermediate> data, u8 log2_of_block_size); // (8.7.1.3) Inverse DCT process - inline DecoderErrorOr<void> inverse_discrete_cosine_transform(u8 bit_depth, Span<Intermediate> data, u8 log2_of_block_size); + inline DecoderErrorOr<void> inverse_discrete_cosine_transform(Span<Intermediate> data, u8 log2_of_block_size); // (8.7.1.4) This process performs the in-place permutation of the array T of length 2 n which is required as the first step of // the inverse ADST. @@ -123,15 +120,15 @@ private: inline void inverse_asymmetric_discrete_sine_transform_output_array_permutation(Span<Intermediate> data, u8 log2_of_block_size); // (8.7.1.6) This process does an in-place transform of the array T to perform an inverse ADST. - inline void inverse_asymmetric_discrete_sine_transform_4(u8 bit_depth, Span<Intermediate> data); + inline void inverse_asymmetric_discrete_sine_transform_4(Span<Intermediate> data); // (8.7.1.7) This process does an in-place transform of the array T using a higher precision array S for intermediate // results. - inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform_8(u8 bit_depth, Span<Intermediate> data); + inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform_8(Span<Intermediate> data); // (8.7.1.8) This process does an in-place transform of the array T using a higher precision array S for intermediate // results. - inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform_16(u8 bit_depth, Span<Intermediate> data); + inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform_16(Span<Intermediate> data); // (8.7.1.9) This process performs an in-place inverse ADST process on the array T of size 2 n for 2 ≤ n ≤ 4. - inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform(u8 bit_depth, Span<Intermediate> data, u8 log2_of_block_size); + inline DecoderErrorOr<void> inverse_asymmetric_discrete_sine_transform(Span<Intermediate> data, u8 log2_of_block_size); /* (8.10) Reference Frame Update Process */ DecoderErrorOr<void> update_reference_frames(FrameContext const&); |