Browse Source

LibVideo/VP9: Implement intra_frame_mode_info procedure (6.4.6)

FalseHonesty 4 years ago
parent
commit
e687f05b42

+ 34 - 3
Userland/Libraries/LibVideo/VP9/Decoder.cpp

@@ -824,7 +824,33 @@ bool Decoder::intra_frame_mode_info()
     SAFE_CALL(intra_segment_id());
     SAFE_CALL(intra_segment_id());
     SAFE_CALL(read_skip());
     SAFE_CALL(read_skip());
     SAFE_CALL(read_tx_size(true));
     SAFE_CALL(read_tx_size(true));
-    // FIXME: Finish implementing
+    m_ref_frame[0] = IntraFrame;
+    m_ref_frame[1] = None;
+    m_is_inter = false;
+    if (m_mi_size >= Block_8x8) {
+        m_default_intra_mode = static_cast<IntraMode>(m_tree_parser->parse_tree(SyntaxElementType::DefaultIntraMode));
+        m_y_mode = m_default_intra_mode;
+        for (auto b = 0; b < 4; b++)
+            m_sub_modes[b] = m_y_mode;
+    } else {
+        m_num_4x4_w = num_4x4_blocks_wide_lookup[m_mi_size];
+        m_num_4x4_h = num_4x4_blocks_high_lookup[m_mi_size];
+        for (auto idy = 0; idy < 2; idy += m_num_4x4_h) {
+            for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
+                m_default_intra_mode = static_cast<IntraMode>(m_tree_parser->parse_tree(SyntaxElementType::DefaultIntraMode));
+                for (auto y = 0; y < m_num_4x4_h; y++) {
+                    for (auto x = 0; x < m_num_4x4_w; x++) {
+                        auto index = (idy + y) * 2 + idx + x;
+                        if (index > 3)
+                            dbgln("Trying to access index {} on m_sub_modes", index);
+                        m_sub_modes[index] = m_default_intra_mode;
+                    }
+                }
+            }
+        }
+        m_y_mode = m_default_intra_mode;
+    }
+    m_uv_mode = m_tree_parser->parse_tree(SyntaxElementType::DefaultUVMode);
     return true;
     return true;
 }
 }
 
 
@@ -855,13 +881,18 @@ bool Decoder::seg_feature_active(u8 feature)
 
 
 bool Decoder::read_tx_size(bool allow_select)
 bool Decoder::read_tx_size(bool allow_select)
 {
 {
-    // FIXME: Implement
-    (void)allow_select;
+    m_max_tx_size = max_txsize_lookup[m_mi_size];
+    if (allow_select && m_tx_mode == TXModeSelect && m_mi_size >= Block_8x8) {
+        m_tx_size = static_cast<TXSize>(m_tree_parser->parse_tree(SyntaxElementType::TXSize));
+    } else {
+        m_tx_size = min(m_max_tx_size, tx_mode_to_biggest_tx_size[m_tx_mode]);
+    }
     return true;
     return true;
 }
 }
 
 
 bool Decoder::inter_frame_mode_info()
 bool Decoder::inter_frame_mode_info()
 {
 {
+    // FIXME: Implement
     return true;
     return true;
 }
 }
 
 

+ 9 - 0
Userland/Libraries/LibVideo/VP9/Decoder.h

@@ -167,6 +167,15 @@ private:
     u8 m_block_subsize { 0 };
     u8 m_block_subsize { 0 };
     u32 m_row { 0 };
     u32 m_row { 0 };
     u32 m_col { 0 };
     u32 m_col { 0 };
+    TXSize m_tx_size { TX_4x4 };
+    ReferenceFrame m_ref_frame[2];
+    bool m_is_inter { false };
+    IntraMode m_default_intra_mode { DcPred };
+    u8 m_y_mode { 0 };
+    u8 m_sub_modes[4]; // FIXME: What size is this supposed to be?
+    u8 m_num_4x4_w { 0 };
+    u8 m_num_4x4_h { 0 };
+    u8 m_uv_mode { 0 }; // FIXME: Is u8 the right size?
 
 
     bool m_use_hp { false };
     bool m_use_hp { false };
 
 

+ 2 - 0
Userland/Libraries/LibVideo/VP9/Enums.h

@@ -41,6 +41,8 @@ enum InterpolationFilter {
 };
 };
 
 
 enum ReferenceFrame {
 enum ReferenceFrame {
+    // 0 is both INTRA_FRAME and NONE because the value's meaning changes depending on which index they're in on the ref_frame array
+    None = 0,
     IntraFrame = 0,
     IntraFrame = 0,
     LastFrame = 1,
     LastFrame = 1,
     GoldenFrame = 2,
     GoldenFrame = 2,

+ 16 - 0
Userland/Libraries/LibVideo/VP9/LookupTables.h

@@ -184,4 +184,20 @@ static constexpr u8 mi_height_log2_lookup[BLOCK_SIZES] = { 0, 0, 0, 0, 1, 0, 1,
 static constexpr u8 num_8x8_blocks_high_lookup[BLOCK_SIZES] = { 1, 1, 1, 1, 2, 1, 2, 4, 2, 4, 8, 4, 8 };
 static constexpr u8 num_8x8_blocks_high_lookup[BLOCK_SIZES] = { 1, 1, 1, 1, 2, 1, 2, 4, 2, 4, 8, 4, 8 };
 static constexpr u8 size_group_lookup[BLOCK_SIZES] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3 };
 static constexpr u8 size_group_lookup[BLOCK_SIZES] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3 };
 
 
+static constexpr TXSize max_txsize_lookup[BLOCK_SIZES] = {
+    TX_4x4,
+    TX_4x4,
+    TX_4x4,
+    TX_8x8,
+    TX_8x8,
+    TX_8x8,
+    TX_16x16,
+    TX_16x16,
+    TX_16x16,
+    TX_32x32,
+    TX_32x32,
+    TX_32x32,
+    TX_32x32,
+};
+
 }
 }