浏览代码

LibVideo/VP9: Pass the sub-block transform type around as a parameter

The sub-block transform types set and then used in a very small scope,
so now it is just stored in a variable and passed to the two functions
that need it, Parser::tokens() and Decoder::reconstruct().
Zaggy1024 2 年之前
父节点
当前提交
b6f41fe7d9

+ 5 - 5
Userland/Libraries/LibVideo/VP9/Decoder.cpp

@@ -1066,7 +1066,7 @@ u16 Decoder::get_ac_quantizer(BlockContext const& block_context, u8 plane)
     return ac_q(block_context.frame_context.color_config.bit_depth, static_cast<u8>(get_base_quantizer_index(block_context) + offset));
     return ac_q(block_context.frame_context.color_config.bit_depth, static_cast<u8>(get_base_quantizer_index(block_context) + offset));
 }
 }
 
 
-DecoderErrorOr<void> Decoder::reconstruct(u8 plane, BlockContext const& block_context, u32 transform_block_x, u32 transform_block_y, TXSize transform_block_size)
+DecoderErrorOr<void> Decoder::reconstruct(u8 plane, BlockContext const& block_context, u32 transform_block_x, u32 transform_block_y, TXSize transform_block_size, u8 transform_type)
 {
 {
     // 8.6.2 Reconstruct process
     // 8.6.2 Reconstruct process
 
 
@@ -1100,7 +1100,7 @@ DecoderErrorOr<void> Decoder::reconstruct(u8 plane, BlockContext const& block_co
 
 
     // 3. Invoke the 2D inverse transform block process defined in section 8.7.2 with the variable n as input.
     // 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.
     //    The inverse transform outputs are stored back to the Dequant buffer.
-    TRY(inverse_transform_2d(block_context, dequantized, log2_of_block_size));
+    TRY(inverse_transform_2d(block_context, dequantized, log2_of_block_size, transform_type));
 
 
     // 4. CurrFrame[ plane ][ y + i ][ x + j ] is set equal to Clip1( CurrFrame[ plane ][ y + i ][ x + j ] + Dequant[ i ][ j ] )
     // 4. CurrFrame[ plane ][ y + i ][ x + j ] is set equal to Clip1( CurrFrame[ plane ][ y + i ][ x + j ] + Dequant[ i ][ j ] )
     //    for i = 0..(n0-1) and j = 0..(n0-1).
     //    for i = 0..(n0-1) and j = 0..(n0-1).
@@ -1653,7 +1653,7 @@ inline DecoderErrorOr<void> Decoder::inverse_asymmetric_discrete_sine_transform(
     return inverse_asymmetric_discrete_sine_transform_16(bit_depth, data);
     return inverse_asymmetric_discrete_sine_transform_16(bit_depth, data);
 }
 }
 
 
-DecoderErrorOr<void> Decoder::inverse_transform_2d(BlockContext const& block_context, Span<Intermediate> dequantized, u8 log2_of_block_size)
+DecoderErrorOr<void> Decoder::inverse_transform_2d(BlockContext const& block_context, Span<Intermediate> dequantized, u8 log2_of_block_size, u8 transform_type)
 {
 {
     // This process performs a 2D inverse transform for an array of size 2^n by 2^n stored in the 2D array Dequant.
     // This process performs a 2D inverse transform for an array of size 2^n by 2^n stored in the 2D array Dequant.
     // The input to this process is a variable n (log2_of_block_size) that specifies the base 2 logarithm of the width of the transform.
     // The input to this process is a variable n (log2_of_block_size) that specifies the base 2 logarithm of the width of the transform.
@@ -1676,7 +1676,7 @@ DecoderErrorOr<void> Decoder::inverse_transform_2d(BlockContext const& block_con
             TRY(inverse_walsh_hadamard_transform(row, log2_of_block_size, 2));
             TRY(inverse_walsh_hadamard_transform(row, log2_of_block_size, 2));
             continue;
             continue;
         }
         }
-        switch (m_parser->m_tx_type) {
+        switch (transform_type) {
         case DCT_DCT:
         case DCT_DCT:
         case ADST_DCT:
         case ADST_DCT:
             // Otherwise, if TxType is equal to DCT_DCT or TxType is equal to ADST_DCT, apply an inverse DCT as
             // Otherwise, if TxType is equal to DCT_DCT or TxType is equal to ADST_DCT, apply an inverse DCT as
@@ -1716,7 +1716,7 @@ DecoderErrorOr<void> Decoder::inverse_transform_2d(BlockContext const& block_con
             TRY(inverse_walsh_hadamard_transform(column, log2_of_block_size, 2));
             TRY(inverse_walsh_hadamard_transform(column, log2_of_block_size, 2));
             continue;
             continue;
         }
         }
-        switch (m_parser->m_tx_type) {
+        switch (transform_type) {
         case DCT_DCT:
         case DCT_DCT:
         case DCT_ADST:
         case DCT_ADST:
             // Otherwise, if TxType is equal to DCT_DCT or TxType is equal to DCT_ADST, apply an inverse DCT as
             // Otherwise, if TxType is equal to DCT_DCT or TxType is equal to DCT_ADST, apply an inverse DCT as

+ 2 - 2
Userland/Libraries/LibVideo/VP9/Decoder.h

@@ -81,10 +81,10 @@ private:
     static u16 get_ac_quantizer(BlockContext const&, u8 plane);
     static u16 get_ac_quantizer(BlockContext const&, u8 plane);
 
 
     // (8.6.2) Reconstruct process
     // (8.6.2) Reconstruct process
-    DecoderErrorOr<void> reconstruct(u8 plane, BlockContext const&, u32 transform_block_x, u32 transform_block_y, TXSize transform_block_size);
+    DecoderErrorOr<void> reconstruct(u8 plane, BlockContext const&, u32 transform_block_x, u32 transform_block_y, TXSize transform_block_size, u8 transform_type);
 
 
     // (8.7) Inverse transform process
     // (8.7) Inverse transform process
-    DecoderErrorOr<void> inverse_transform_2d(BlockContext const&, Span<Intermediate> dequantized, u8 log2_of_block_size);
+    DecoderErrorOr<void> inverse_transform_2d(BlockContext const&, Span<Intermediate> dequantized, u8 log2_of_block_size, u8 transform_type);
 
 
     // (8.7.1) 1D Transforms
     // (8.7.1) 1D Transforms
     // (8.7.1.1) Butterfly functions
     // (8.7.1.1) Butterfly functions

+ 46 - 41
Userland/Libraries/LibVideo/VP9/Parser.cpp

@@ -1344,6 +1344,20 @@ static TXSize get_uv_tx_size(bool subsampling_x, bool subsampling_y, TXSize tx_s
     return min(tx_size, max_txsize_lookup[get_plane_block_size(subsampling_x, subsampling_y, size, 1)]);
     return min(tx_size, max_txsize_lookup[get_plane_block_size(subsampling_x, subsampling_y, size, 1)]);
 }
 }
 
 
+static u8 select_transform_type(BlockContext const& block_context, u8 plane, TXSize tx_size, u32 block_index)
+{
+    if (plane > 0 || tx_size == TX_32x32)
+        return DCT_DCT;
+    if (tx_size == TX_4x4) {
+        if (block_context.frame_context.is_lossless() || block_context.is_inter_predicted())
+            return DCT_DCT;
+
+        return mode_to_txfm_map[to_underlying(block_context.size < Block_8x8 ? block_context.sub_block_prediction_modes[block_index] : block_context.y_prediction_mode())];
+    }
+
+    return mode_to_txfm_map[to_underlying(block_context.y_prediction_mode())];
+}
+
 DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_block_above, bool has_block_left)
 DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_block_above, bool has_block_left)
 {
 {
     bool had_residual_tokens = false;
     bool had_residual_tokens = false;
@@ -1381,9 +1395,10 @@ DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_bloc
                     if (!block_context.is_inter_predicted())
                     if (!block_context.is_inter_predicted())
                         TRY(m_decoder.predict_intra(plane, block_context, start_x, start_y, has_block_left || x > 0, has_block_above || y > 0, (x + step) < num_4x4_w, tx_size, block_index));
                         TRY(m_decoder.predict_intra(plane, block_context, start_x, start_y, has_block_left || x > 0, has_block_above || y > 0, (x + step) < num_4x4_w, tx_size, block_index));
                     if (!block_context.should_skip_residuals) {
                     if (!block_context.should_skip_residuals) {
-                        non_zero = TRY(tokens(block_context, plane, start_x, start_y, tx_size, block_index));
+                        auto transform_type = select_transform_type(block_context, plane, tx_size, block_index);
+                        non_zero = TRY(tokens(block_context, plane, start_x, start_y, tx_size, transform_type));
                         had_residual_tokens = had_residual_tokens || non_zero;
                         had_residual_tokens = had_residual_tokens || non_zero;
-                        TRY(m_decoder.reconstruct(plane, block_context, start_x, start_y, tx_size));
+                        TRY(m_decoder.reconstruct(plane, block_context, start_x, start_y, tx_size, transform_type));
                     }
                     }
                 }
                 }
 
 
@@ -1406,16 +1421,42 @@ DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_bloc
     return had_residual_tokens;
     return had_residual_tokens;
 }
 }
 
 
-DecoderErrorOr<bool> Parser::tokens(BlockContext& block_context, size_t plane, u32 start_x, u32 start_y, TXSize tx_size, u32 block_index)
+static u32 const* get_scan(TXSize tx_size, u8 transform_type)
+{
+    if (tx_size == TX_4x4) {
+        if (transform_type == ADST_DCT)
+            return row_scan_4x4;
+        if (transform_type == DCT_ADST)
+            return col_scan_4x4;
+        return default_scan_4x4;
+    }
+    if (tx_size == TX_8x8) {
+        if (transform_type == ADST_DCT)
+            return row_scan_8x8;
+        if (transform_type == DCT_ADST)
+            return col_scan_8x8;
+        return default_scan_8x8;
+    }
+    if (tx_size == TX_16x16) {
+        if (transform_type == ADST_DCT)
+            return row_scan_16x16;
+        if (transform_type == DCT_ADST)
+            return col_scan_16x16;
+        return default_scan_16x16;
+    }
+    return default_scan_32x32;
+}
+
+DecoderErrorOr<bool> Parser::tokens(BlockContext& block_context, size_t plane, u32 start_x, u32 start_y, TXSize tx_size, u8 transform_type)
 {
 {
     u32 segment_eob = 16 << (tx_size << 1);
     u32 segment_eob = 16 << (tx_size << 1);
-    auto const* scan = get_scan(block_context, plane, tx_size, block_index);
+    auto const* scan = get_scan(tx_size, transform_type);
     auto check_eob = true;
     auto check_eob = true;
     u32 c = 0;
     u32 c = 0;
     for (; c < segment_eob; c++) {
     for (; c < segment_eob; c++) {
         auto pos = scan[c];
         auto pos = scan[c];
         auto band = (tx_size == TX_4x4) ? coefband_4x4[c] : coefband_8x8plus[c];
         auto band = (tx_size == TX_4x4) ? coefband_4x4[c] : coefband_8x8plus[c];
-        auto tokens_context = TreeParser::get_tokens_context(block_context.frame_context.color_config.subsampling_x, block_context.frame_context.color_config.subsampling_y, block_context.frame_context.rows(), block_context.frame_context.columns(), m_above_nonzero_context, m_left_nonzero_context, m_token_cache, tx_size, m_tx_type, plane, start_x, start_y, pos, block_context.is_inter_predicted(), band, c);
+        auto tokens_context = TreeParser::get_tokens_context(block_context.frame_context.color_config.subsampling_x, block_context.frame_context.color_config.subsampling_y, block_context.frame_context.rows(), block_context.frame_context.columns(), m_above_nonzero_context, m_left_nonzero_context, m_token_cache, tx_size, transform_type, plane, start_x, start_y, pos, block_context.is_inter_predicted(), band, c);
         if (check_eob) {
         if (check_eob) {
             auto more_coefs = TRY_READ(TreeParser::parse_more_coefficients(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, tokens_context));
             auto more_coefs = TRY_READ(TreeParser::parse_more_coefficients(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, tokens_context));
             if (!more_coefs)
             if (!more_coefs)
@@ -1438,42 +1479,6 @@ DecoderErrorOr<bool> Parser::tokens(BlockContext& block_context, size_t plane, u
     return c > 0;
     return c > 0;
 }
 }
 
 
-u32 const* Parser::get_scan(BlockContext const& block_context, size_t plane, TXSize tx_size, u32 block_index)
-{
-    if (plane > 0 || tx_size == TX_32x32) {
-        m_tx_type = DCT_DCT;
-    } else if (tx_size == TX_4x4) {
-        if (block_context.frame_context.is_lossless() || block_context.is_inter_predicted())
-            m_tx_type = DCT_DCT;
-        else
-            m_tx_type = mode_to_txfm_map[to_underlying(block_context.size < Block_8x8 ? block_context.sub_block_prediction_modes[block_index] : block_context.y_prediction_mode())];
-    } else {
-        m_tx_type = mode_to_txfm_map[to_underlying(block_context.y_prediction_mode())];
-    }
-    if (tx_size == TX_4x4) {
-        if (m_tx_type == ADST_DCT)
-            return row_scan_4x4;
-        if (m_tx_type == DCT_ADST)
-            return col_scan_4x4;
-        return default_scan_4x4;
-    }
-    if (tx_size == TX_8x8) {
-        if (m_tx_type == ADST_DCT)
-            return row_scan_8x8;
-        if (m_tx_type == DCT_ADST)
-            return col_scan_8x8;
-        return default_scan_8x8;
-    }
-    if (tx_size == TX_16x16) {
-        if (m_tx_type == ADST_DCT)
-            return row_scan_16x16;
-        if (m_tx_type == DCT_ADST)
-            return col_scan_16x16;
-        return default_scan_16x16;
-    }
-    return default_scan_32x32;
-}
-
 DecoderErrorOr<i32> Parser::read_coef(u8 bit_depth, Token token)
 DecoderErrorOr<i32> Parser::read_coef(u8 bit_depth, Token token)
 {
 {
     auto cat = extra_bits[token][0];
     auto cat = extra_bits[token][0];

+ 1 - 3
Userland/Libraries/LibVideo/VP9/Parser.h

@@ -117,8 +117,7 @@ private:
     DecoderErrorOr<MotionVector> read_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&, ReferenceIndex);
     DecoderErrorOr<MotionVector> read_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&, ReferenceIndex);
     DecoderErrorOr<i32> read_single_motion_vector_component(u8 component);
     DecoderErrorOr<i32> read_single_motion_vector_component(u8 component);
     DecoderErrorOr<bool> residual(BlockContext&, bool has_block_above, bool has_block_left);
     DecoderErrorOr<bool> residual(BlockContext&, bool has_block_above, bool has_block_left);
-    DecoderErrorOr<bool> tokens(BlockContext&, size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
-    u32 const* get_scan(BlockContext const&, size_t plane, TXSize tx_size, u32 block_index);
+    DecoderErrorOr<bool> tokens(BlockContext&, size_t plane, u32 x, u32 y, TXSize tx_size, u8 transform_type);
     DecoderErrorOr<i32> read_coef(u8 bit_depth, Token token);
     DecoderErrorOr<i32> read_coef(u8 bit_depth, Token token);
 
 
     /* (6.5) Motion Vector Prediction */
     /* (6.5) Motion Vector Prediction */
@@ -158,7 +157,6 @@ private:
 
 
     Vector<u16> m_frame_store[NUM_REF_FRAMES][3];
     Vector<u16> m_frame_store[NUM_REF_FRAMES][3];
 
 
-    u8 m_tx_type { 0 };
     u8 m_token_cache[1024];
     u8 m_token_cache[1024];
     i32 m_tokens[1024];
     i32 m_tokens[1024];
     bool m_use_hp { false };
     bool m_use_hp { false };