Przeglądaj źródła

LibVideo/VP9: Begin reference frame update process (8.10)

This was required for correctly parsing more than one frame's
height/width data properly. Additionally, start handling failure
a little more gracefully. Since we don't fully parse a tile before
starting to parse the next tile, we will now no longer make it past
the first tile mark, meaning we should not handle that scenario well.
FalseHonesty 4 lat temu
rodzic
commit
cf6b3d0ce9

+ 3 - 1
Userland/Applications/VideoPlayer/main.cpp

@@ -43,8 +43,10 @@ int main(int argc, char** argv)
 
             auto const& frame = block.frame(0);
             dbgln("Reading frame 0 from block @ {}", block.timestamp());
-            vp9_decoder.decode_frame(frame);
+            bool failed = !vp9_decoder.decode_frame(frame);
             vp9_decoder.dump_frame_info();
+            if (failed)
+                return 1;
         }
     }
 

+ 1 - 0
Userland/Libraries/LibVideo/CMakeLists.txt

@@ -10,6 +10,7 @@ set(SOURCES
     VP9/Symbols.h
     VP9/SyntaxElementCounter.cpp
     VP9/TreeParser.cpp
+    VP9/Utilities.h
 )
 
 serenity_lib(LibVideo video)

+ 22 - 1
Userland/Libraries/LibVideo/VP9/Decoder.cpp

@@ -5,6 +5,7 @@
  */
 
 #include "Decoder.h"
+#include "Utilities.h"
 
 namespace Video::VP9 {
 
@@ -15,7 +16,13 @@ Decoder::Decoder()
 
 bool Decoder::decode_frame(ByteBuffer const& frame_data)
 {
-    return m_parser->parse_frame(frame_data);
+    SAFE_CALL(m_parser->parse_frame(frame_data));
+    // TODO:
+    //  - #2
+    //  - #3
+    //  - #4
+    SAFE_CALL(update_reference_frames());
+    return true;
 }
 
 void Decoder::dump_frame_info()
@@ -41,4 +48,18 @@ bool Decoder::reconstruct(size_t, u32, u32, TXSize)
     return true;
 }
 
+bool Decoder::update_reference_frames()
+{
+    for (auto i = 0; i < NUM_REF_FRAMES; i++) {
+        dbgln("updating frame {}? {}", i, (m_parser->m_refresh_frame_flags & (1 << i)) == 1);
+        if ((m_parser->m_refresh_frame_flags & (1 << i)) != 1)
+            continue;
+        m_parser->m_ref_frame_width[i] = m_parser->m_frame_width;
+        m_parser->m_ref_frame_height[i] = m_parser->m_frame_height;
+        // TODO: 1.3-1.7
+    }
+    // TODO: 2.1-2.2
+    return true;
+}
+
 }

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

@@ -27,6 +27,9 @@ private:
     /* (8.6) Reconstruction and Dequantization */
     bool reconstruct(size_t plane, u32 x, u32 y, TXSize size);
 
+    /* (8.10) Reference Frame Update Process */
+    bool update_reference_frames();
+
     NonnullOwnPtr<Parser> m_parser;
 };
 

+ 6 - 8
Userland/Libraries/LibVideo/VP9/Parser.cpp

@@ -6,6 +6,7 @@
 
 #include "Parser.h"
 #include "Decoder.h"
+#include "Utilities.h"
 
 namespace Video::VP9 {
 
@@ -13,10 +14,6 @@ namespace Video::VP9 {
     if (m_bit_stream->read_bit() != 0) \
     return false
 
-#define SAFE_CALL(call)       \
-    if (!(call)) [[unlikely]] \
-    return false
-
 Parser::Parser(Decoder& decoder)
     : m_probability_tables(make<ProbabilityTables>())
     , m_tree_parser(make<TreeParser>(*this))
@@ -220,6 +217,7 @@ bool Parser::frame_size_with_refs()
     for (auto frame_index : m_ref_frame_idx) {
         found_ref = m_bit_stream->read_bit();
         if (found_ref) {
+            dbgln("Reading size from ref frame {}", frame_index);
             m_frame_width = m_ref_frame_width[frame_index];
             m_frame_height = m_ref_frame_height[frame_index];
             break;
@@ -1203,10 +1201,10 @@ bool Parser::append_sub8x8_mvs(u8, u8)
 
 void Parser::dump_info()
 {
-    dbgln("Frame dimensions: {}x{}", m_frame_width, m_frame_height);
-    dbgln("Render dimensions: {}x{}", m_render_width, m_render_height);
-    dbgln("Bit depth: {}", m_bit_depth);
-    dbgln("Interpolation filter: {}", (u8)m_interpolation_filter);
+    outln("Frame dimensions: {}x{}", m_frame_width, m_frame_height);
+    outln("Render dimensions: {}x{}", m_render_width, m_render_height);
+    outln("Bit depth: {}", m_bit_depth);
+    outln("Interpolation filter: {}", (u8)m_interpolation_filter);
 }
 
 }

+ 19 - 0
Userland/Libraries/LibVideo/VP9/Utilities.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+namespace Video::VP9 {
+
+#define SAFE_CALL(call)             \
+    do {                            \
+        if (!(call)) [[unlikely]] { \
+            dbgln("FAILED " #call); \
+            return false;           \
+        }                           \
+    } while (0)
+
+}