فهرست منبع

LibVideo: Allow bit stream reads to throw errors

Errors are propagated to the user of the decoder so that they can be
aware of specific places where a read failed.
Zaggy1024 2 سال پیش
والد
کامیت
b37ea6b414

+ 4 - 2
Userland/Applications/VideoPlayer/main.cpp

@@ -42,10 +42,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
 
 
             auto const& frame = block.frame(0);
             auto const& frame = block.frame(0);
             dbgln("Reading frame 0 from block @ {}", block.timestamp());
             dbgln("Reading frame 0 from block @ {}", block.timestamp());
-            bool failed = !vp9_decoder.decode_frame(frame);
+            auto result = vp9_decoder.decode_frame(frame);
             vp9_decoder.dump_frame_info();
             vp9_decoder.dump_frame_info();
-            if (failed)
+            if (result.is_error()) {
+                outln("Error: {}", result.error().string_literal());
                 return 1;
                 return 1;
+            }
         }
         }
     }
     }
 
 

+ 33 - 24
Userland/Libraries/LibVideo/VP9/BitStream.cpp

@@ -1,24 +1,29 @@
 /*
 /*
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
 
 
+#include <AK/Error.h>
+
 #include "BitStream.h"
 #include "BitStream.h"
 
 
 namespace Video::VP9 {
 namespace Video::VP9 {
 
 
-u8 BitStream::read_byte()
+ErrorOr<u8> BitStream::read_byte()
 {
 {
+    if (m_bytes_remaining < 1)
+        return Error::from_string_literal("read_byte: Out of data.");
     VERIFY(m_bytes_remaining >= 1);
     VERIFY(m_bytes_remaining >= 1);
     m_bytes_remaining--;
     m_bytes_remaining--;
     return *(m_data_ptr++);
     return *(m_data_ptr++);
 }
 }
 
 
-bool BitStream::read_bit()
+ErrorOr<bool> BitStream::read_bit()
 {
 {
     if (!m_current_byte.has_value()) {
     if (!m_current_byte.has_value()) {
-        m_current_byte = read_byte();
+        m_current_byte = TRY(read_byte());
         m_current_bit_position = 7;
         m_current_bit_position = 7;
     }
     }
 
 
@@ -28,47 +33,49 @@ bool BitStream::read_bit()
     return bit_value;
     return bit_value;
 }
 }
 
 
-u8 BitStream::read_f(size_t n)
+ErrorOr<u8> BitStream::read_f(size_t n)
 {
 {
     u8 result = 0;
     u8 result = 0;
     for (size_t i = 0; i < n; i++) {
     for (size_t i = 0; i < n; i++) {
-        result = (2 * result) + read_bit();
+        result = (2 * result) + TRY(read_bit());
     }
     }
     return result;
     return result;
 }
 }
 
 
-u8 BitStream::read_f8()
+ErrorOr<u8> BitStream::read_f8()
 {
 {
     if (!m_current_byte.has_value())
     if (!m_current_byte.has_value())
         return read_byte();
         return read_byte();
 
 
     auto high_bits = m_current_byte.value() & ((1u << m_current_bit_position) - 1);
     auto high_bits = m_current_byte.value() & ((1u << m_current_bit_position) - 1);
     u8 remaining_bits = 7 - m_current_bit_position;
     u8 remaining_bits = 7 - m_current_bit_position;
-    m_current_byte = read_byte();
+    m_current_byte = TRY(read_byte());
     m_current_bit_position = 7;
     m_current_bit_position = 7;
     auto low_bits = (m_current_byte.value() >> (8u - remaining_bits)) & ((1u << remaining_bits) - 1);
     auto low_bits = (m_current_byte.value() >> (8u - remaining_bits)) & ((1u << remaining_bits) - 1);
     m_current_bit_position -= remaining_bits;
     m_current_bit_position -= remaining_bits;
     return (high_bits << remaining_bits) | low_bits;
     return (high_bits << remaining_bits) | low_bits;
 }
 }
 
 
-u16 BitStream::read_f16()
+ErrorOr<u16> BitStream::read_f16()
 {
 {
-    return (read_f8() << 8u) | read_f8();
+    return (TRY(read_f8()) << 8u) | TRY(read_f8());
 }
 }
 
 
 /* 9.2.1 */
 /* 9.2.1 */
-bool BitStream::init_bool(size_t bytes)
+ErrorOr<void> BitStream::init_bool(size_t bytes)
 {
 {
-    if (bytes < 1)
-        return false;
-    m_bool_value = read_f8();
+    if (bytes == 0)
+        return Error::from_string_literal("Range coder size cannot be zero.");
+    m_bool_value = TRY(read_f8());
     m_bool_range = 255;
     m_bool_range = 255;
     m_bool_max_bits = (8 * bytes) - 8;
     m_bool_max_bits = (8 * bytes) - 8;
-    return !read_bool(128);
+    if (TRY(read_bool(128)))
+        return Error::from_string_literal("Range coder's first bool was non-zero.");
+    return {};
 }
 }
 
 
 /* 9.2.2 */
 /* 9.2.2 */
-bool BitStream::read_bool(u8 probability)
+ErrorOr<bool> BitStream::read_bool(u8 probability)
 {
 {
     auto split = 1u + (((m_bool_range - 1u) * probability) >> 8u);
     auto split = 1u + (((m_bool_range - 1u) * probability) >> 8u);
     bool return_bool;
     bool return_bool;
@@ -85,7 +92,7 @@ bool BitStream::read_bool(u8 probability)
     while (m_bool_range < 128) {
     while (m_bool_range < 128) {
         bool new_bit;
         bool new_bit;
         if (m_bool_max_bits) {
         if (m_bool_max_bits) {
-            new_bit = read_bit();
+            new_bit = TRY(read_bit());
             m_bool_max_bits--;
             m_bool_max_bits--;
         } else {
         } else {
             new_bit = false;
             new_bit = false;
@@ -98,29 +105,31 @@ bool BitStream::read_bool(u8 probability)
 }
 }
 
 
 /* 9.2.3 */
 /* 9.2.3 */
-bool BitStream::exit_bool()
+ErrorOr<void> BitStream::exit_bool()
 {
 {
     // FIXME: I'm not sure if this call to min is spec compliant, or if there is an issue elsewhere earlier in the parser.
     // FIXME: I'm not sure if this call to min is spec compliant, or if there is an issue elsewhere earlier in the parser.
-    auto padding_element = read_f(min(m_bool_max_bits, (u64)bits_remaining()));
+    auto padding_element = TRY(read_f(min(m_bool_max_bits, (u64)bits_remaining())));
 
 
     // FIXME: It is a requirement of bitstream conformance that enough padding bits are inserted to ensure that the final coded byte of a frame is not equal to a superframe marker.
     // FIXME: It is a requirement of bitstream conformance that enough padding bits are inserted to ensure that the final coded byte of a frame is not equal to a superframe marker.
     //  A byte b is equal to a superframe marker if and only if (b & 0xe0)is equal to 0xc0, i.e. if the most significant 3 bits are equal to 0b110.
     //  A byte b is equal to a superframe marker if and only if (b & 0xe0)is equal to 0xc0, i.e. if the most significant 3 bits are equal to 0b110.
-    return padding_element == 0;
+    if (padding_element != 0)
+        return Error::from_string_literal("Range coder padding was non-zero.");
+    return {};
 }
 }
 
 
-u8 BitStream::read_literal(size_t n)
+ErrorOr<u8> BitStream::read_literal(size_t n)
 {
 {
     u8 return_value = 0;
     u8 return_value = 0;
     for (size_t i = 0; i < n; i++) {
     for (size_t i = 0; i < n; i++) {
-        return_value = (2 * return_value) + read_bool(128);
+        return_value = (2 * return_value) + TRY(read_bool(128));
     }
     }
     return return_value;
     return return_value;
 }
 }
 
 
-i8 BitStream::read_s(size_t n)
+ErrorOr<i8> BitStream::read_s(size_t n)
 {
 {
-    auto value = read_f(n);
-    auto sign = read_bit();
+    auto value = TRY(read_f(n));
+    auto sign = TRY(read_bit());
     return sign ? -value : value;
     return sign ? -value : value;
 }
 }
 
 

+ 11 - 10
Userland/Libraries/LibVideo/VP9/BitStream.h

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -19,22 +20,22 @@ public:
     {
     {
     }
     }
 
 
-    u8 read_byte();
-    bool read_bit();
+    ErrorOr<u8> read_byte();
+    ErrorOr<bool> read_bit();
 
 
     /* (9.1) */
     /* (9.1) */
-    u8 read_f(size_t n);
-    u8 read_f8();
-    u16 read_f16();
+    ErrorOr<u8> read_f(size_t n);
+    ErrorOr<u8> read_f8();
+    ErrorOr<u16> read_f16();
 
 
     /* (9.2) */
     /* (9.2) */
-    bool init_bool(size_t bytes);
-    bool read_bool(u8 probability);
-    bool exit_bool();
-    u8 read_literal(size_t n);
+    ErrorOr<void> init_bool(size_t bytes);
+    ErrorOr<bool> read_bool(u8 probability);
+    ErrorOr<void> exit_bool();
+    ErrorOr<u8> read_literal(size_t n);
 
 
     /* (4.9.2) */
     /* (4.9.2) */
-    i8 read_s(size_t n);
+    ErrorOr<i8> read_s(size_t n);
 
 
     u64 get_position();
     u64 get_position();
     size_t bytes_remaining();
     size_t bytes_remaining();

+ 18 - 16
Userland/Libraries/LibVideo/VP9/Decoder.cpp

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -14,15 +15,16 @@ Decoder::Decoder()
 {
 {
 }
 }
 
 
-bool Decoder::decode_frame(ByteBuffer const& frame_data)
+ErrorOr<void> Decoder::decode_frame(ByteBuffer const& frame_data)
 {
 {
-    SAFE_CALL(m_parser->parse_frame(frame_data));
+    TRY(m_parser->parse_frame(frame_data));
     // TODO:
     // TODO:
     //  - #2
     //  - #2
     //  - #3
     //  - #3
     //  - #4
     //  - #4
-    SAFE_CALL(update_reference_frames());
-    return true;
+    TRY(update_reference_frames());
+
+    return {};
 }
 }
 
 
 void Decoder::dump_frame_info()
 void Decoder::dump_frame_info()
@@ -49,7 +51,7 @@ u8 Decoder::merge_probs(int const* tree, int index, u8* probs, u8* counts, u8 co
     return left_count + right_count;
     return left_count + right_count;
 }
 }
 
 
-bool Decoder::adapt_coef_probs()
+ErrorOr<void> Decoder::adapt_coef_probs()
 {
 {
     u8 update_factor;
     u8 update_factor;
     if (m_parser->m_frame_is_intra || m_parser->m_last_frame_type != KeyFrame)
     if (m_parser->m_frame_is_intra || m_parser->m_last_frame_type != KeyFrame)
@@ -76,7 +78,7 @@ bool Decoder::adapt_coef_probs()
         }
         }
     }
     }
 
 
-    return true;
+    return {};
 }
 }
 
 
 #define ADAPT_PROB_TABLE(name, size)                                     \
 #define ADAPT_PROB_TABLE(name, size)                                     \
@@ -94,7 +96,7 @@ bool Decoder::adapt_coef_probs()
         }                                                                                                  \
         }                                                                                                  \
     } while (0)
     } while (0)
 
 
-bool Decoder::adapt_non_coef_probs()
+ErrorOr<void> Decoder::adapt_non_coef_probs()
 {
 {
     auto& probs = *m_parser->m_probability_tables;
     auto& probs = *m_parser->m_probability_tables;
     auto& counter = *m_parser->m_syntax_element_counter;
     auto& counter = *m_parser->m_syntax_element_counter;
@@ -137,7 +139,7 @@ bool Decoder::adapt_non_coef_probs()
             probs.mv_hp_prob()[i] = adapt_prob(probs.mv_hp_prob()[i], counter.m_counts_mv_hp[i]);
             probs.mv_hp_prob()[i] = adapt_prob(probs.mv_hp_prob()[i], counter.m_counts_mv_hp[i]);
         }
         }
     }
     }
-    return true;
+    return {};
 }
 }
 
 
 void Decoder::adapt_probs(int const* tree, u8* probs, u8* counts)
 void Decoder::adapt_probs(int const* tree, u8* probs, u8* counts)
@@ -150,25 +152,25 @@ u8 Decoder::adapt_prob(u8 prob, u8 counts[2])
     return merge_prob(prob, counts[0], counts[1], COUNT_SAT, MAX_UPDATE_FACTOR);
     return merge_prob(prob, counts[0], counts[1], COUNT_SAT, MAX_UPDATE_FACTOR);
 }
 }
 
 
-bool Decoder::predict_intra(size_t, u32, u32, bool, bool, bool, TXSize, u32)
+ErrorOr<void> Decoder::predict_intra(size_t, u32, u32, bool, bool, bool, TXSize, u32)
 {
 {
     // TODO: Implement
     // TODO: Implement
-    return true;
+    return Error::from_string_literal("predict_intra not implemented");
 }
 }
 
 
-bool Decoder::predict_inter(size_t, u32, u32, u32, u32, u32)
+ErrorOr<void> Decoder::predict_inter(size_t, u32, u32, u32, u32, u32)
 {
 {
     // TODO: Implement
     // TODO: Implement
-    return true;
+    return Error::from_string_literal("predict_inter not implemented");
 }
 }
 
 
-bool Decoder::reconstruct(size_t, u32, u32, TXSize)
+ErrorOr<void> Decoder::reconstruct(size_t, u32, u32, TXSize)
 {
 {
     // TODO: Implement
     // TODO: Implement
-    return true;
+    return Error::from_string_literal("reconstruct not implemented");
 }
 }
 
 
-bool Decoder::update_reference_frames()
+ErrorOr<void> Decoder::update_reference_frames()
 {
 {
     for (auto i = 0; i < NUM_REF_FRAMES; i++) {
     for (auto i = 0; i < NUM_REF_FRAMES; i++) {
         dbgln("updating frame {}? {}", i, (m_parser->m_refresh_frame_flags & (1 << i)) == 1);
         dbgln("updating frame {}? {}", i, (m_parser->m_refresh_frame_flags & (1 << i)) == 1);
@@ -179,7 +181,7 @@ bool Decoder::update_reference_frames()
         // TODO: 1.3-1.7
         // TODO: 1.3-1.7
     }
     }
     // TODO: 2.1-2.2
     // TODO: 2.1-2.2
-    return true;
+    return {};
 }
 }
 
 
 }
 }

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

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -8,6 +9,7 @@
 
 
 #include "Parser.h"
 #include "Parser.h"
 #include <AK/ByteBuffer.h>
 #include <AK/ByteBuffer.h>
+#include <AK/Error.h>
 
 
 namespace Video::VP9 {
 namespace Video::VP9 {
 
 
@@ -16,27 +18,27 @@ class Decoder {
 
 
 public:
 public:
     Decoder();
     Decoder();
-    bool decode_frame(ByteBuffer const&);
+    ErrorOr<void> decode_frame(ByteBuffer const&);
     void dump_frame_info();
     void dump_frame_info();
 
 
 private:
 private:
     /* (8.4) Probability Adaptation Process */
     /* (8.4) Probability Adaptation Process */
     u8 merge_prob(u8 pre_prob, u8 count_0, u8 count_1, u8 count_sat, u8 max_update_factor);
     u8 merge_prob(u8 pre_prob, u8 count_0, u8 count_1, u8 count_sat, u8 max_update_factor);
     u8 merge_probs(int const* tree, int index, u8* probs, u8* counts, u8 count_sat, u8 max_update_factor);
     u8 merge_probs(int const* tree, int index, u8* probs, u8* counts, u8 count_sat, u8 max_update_factor);
-    bool adapt_coef_probs();
-    bool adapt_non_coef_probs();
+    ErrorOr<void> adapt_coef_probs();
+    ErrorOr<void> adapt_non_coef_probs();
     void adapt_probs(int const* tree, u8* probs, u8* counts);
     void adapt_probs(int const* tree, u8* probs, u8* counts);
     u8 adapt_prob(u8 prob, u8 counts[2]);
     u8 adapt_prob(u8 prob, u8 counts[2]);
 
 
     /* (8.5) Prediction Processes */
     /* (8.5) Prediction Processes */
-    bool predict_intra(size_t plane, u32 x, u32 y, bool have_left, bool have_above, bool not_on_right, TXSize tx_size, u32 block_index);
-    bool predict_inter(size_t plane, u32 x, u32 y, u32 w, u32 h, u32 block_index);
+    ErrorOr<void> predict_intra(size_t plane, u32 x, u32 y, bool have_left, bool have_above, bool not_on_right, TXSize tx_size, u32 block_index);
+    ErrorOr<void> predict_inter(size_t plane, u32 x, u32 y, u32 w, u32 h, u32 block_index);
 
 
     /* (8.6) Reconstruction and Dequantization */
     /* (8.6) Reconstruction and Dequantization */
-    bool reconstruct(size_t plane, u32 x, u32 y, TXSize size);
+    ErrorOr<void> reconstruct(size_t plane, u32 x, u32 y, TXSize size);
 
 
     /* (8.10) Reference Frame Update Process */
     /* (8.10) Reference Frame Update Process */
-    bool update_reference_frames();
+    ErrorOr<void> update_reference_frames();
 
 
     NonnullOwnPtr<Parser> m_parser;
     NonnullOwnPtr<Parser> m_parser;
 };
 };

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 263 - 256
Userland/Libraries/LibVideo/VP9/Parser.cpp


+ 65 - 64
Userland/Libraries/LibVideo/VP9/Parser.h

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -26,20 +27,20 @@ class Parser {
 public:
 public:
     explicit Parser(Decoder&);
     explicit Parser(Decoder&);
     ~Parser();
     ~Parser();
-    bool parse_frame(ByteBuffer const&);
+    ErrorOr<void> parse_frame(ByteBuffer const&);
     void dump_info();
     void dump_info();
 
 
 private:
 private:
-    FrameType read_frame_type()
+    ErrorOr<FrameType> read_frame_type()
     {
     {
-        if (m_bit_stream->read_bit())
+        if (TRY(m_bit_stream->read_bit()))
             return NonKeyFrame;
             return NonKeyFrame;
         return KeyFrame;
         return KeyFrame;
     }
     }
 
 
-    ColorRange read_color_range()
+    ErrorOr<ColorRange> read_color_range()
     {
     {
-        if (m_bit_stream->read_bit())
+        if (TRY(m_bit_stream->read_bit()))
             return FullSwing;
             return FullSwing;
         return StudioSwing;
         return StudioSwing;
     }
     }
@@ -52,83 +53,83 @@ private:
 
 
     /* (6.1) Frame Syntax */
     /* (6.1) Frame Syntax */
     bool trailing_bits();
     bool trailing_bits();
-    bool refresh_probs();
+    ErrorOr<void> refresh_probs();
 
 
     /* (6.2) Uncompressed Header Syntax */
     /* (6.2) Uncompressed Header Syntax */
-    bool uncompressed_header();
-    bool frame_sync_code();
-    bool color_config();
-    bool frame_size();
-    bool render_size();
-    bool frame_size_with_refs();
-    bool compute_image_size();
-    bool read_interpolation_filter();
-    bool loop_filter_params();
-    bool quantization_params();
-    i8 read_delta_q();
-    bool segmentation_params();
-    u8 read_prob();
-    bool tile_info();
+    ErrorOr<void> uncompressed_header();
+    ErrorOr<void> frame_sync_code();
+    ErrorOr<void> color_config();
+    ErrorOr<void> frame_size();
+    ErrorOr<void> render_size();
+    ErrorOr<void> frame_size_with_refs();
+    void compute_image_size();
+    ErrorOr<void> read_interpolation_filter();
+    ErrorOr<void> loop_filter_params();
+    ErrorOr<void> quantization_params();
+    ErrorOr<i8> read_delta_q();
+    ErrorOr<void> segmentation_params();
+    ErrorOr<u8> read_prob();
+    ErrorOr<void> tile_info();
     u16 calc_min_log2_tile_cols();
     u16 calc_min_log2_tile_cols();
     u16 calc_max_log2_tile_cols();
     u16 calc_max_log2_tile_cols();
-    bool setup_past_independence();
+    void setup_past_independence();
 
 
     /* (6.3) Compressed Header Syntax */
     /* (6.3) Compressed Header Syntax */
-    bool compressed_header();
-    bool read_tx_mode();
-    bool tx_mode_probs();
-    u8 diff_update_prob(u8 prob);
-    u8 decode_term_subexp();
+    ErrorOr<void> compressed_header();
+    ErrorOr<void> read_tx_mode();
+    ErrorOr<void> tx_mode_probs();
+    ErrorOr<u8> diff_update_prob(u8 prob);
+    ErrorOr<u8> decode_term_subexp();
     u8 inv_remap_prob(u8 delta_prob, u8 prob);
     u8 inv_remap_prob(u8 delta_prob, u8 prob);
     u8 inv_recenter_nonneg(u8 v, u8 m);
     u8 inv_recenter_nonneg(u8 v, u8 m);
-    bool read_coef_probs();
-    bool read_skip_prob();
-    bool read_inter_mode_probs();
-    bool read_interp_filter_probs();
-    bool read_is_inter_probs();
-    bool frame_reference_mode();
-    bool frame_reference_mode_probs();
-    bool read_y_mode_probs();
-    bool read_partition_probs();
-    bool mv_probs();
-    u8 update_mv_prob(u8 prob);
-    bool setup_compound_reference_mode();
+    ErrorOr<void> read_coef_probs();
+    ErrorOr<void> read_skip_prob();
+    ErrorOr<void> read_inter_mode_probs();
+    ErrorOr<void> read_interp_filter_probs();
+    ErrorOr<void> read_is_inter_probs();
+    ErrorOr<void> frame_reference_mode();
+    ErrorOr<void> frame_reference_mode_probs();
+    ErrorOr<void> read_y_mode_probs();
+    ErrorOr<void> read_partition_probs();
+    ErrorOr<void> mv_probs();
+    ErrorOr<u8> update_mv_prob(u8 prob);
+    void setup_compound_reference_mode();
 
 
     /* (6.4) Decode Tiles Syntax */
     /* (6.4) Decode Tiles Syntax */
-    bool decode_tiles();
-    bool clear_above_context();
+    ErrorOr<void> decode_tiles();
+    void clear_above_context();
     u32 get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2);
     u32 get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2);
-    bool decode_tile();
-    bool clear_left_context();
-    bool decode_partition(u32 row, u32 col, u8 block_subsize);
-    bool decode_block(u32 row, u32 col, u8 subsize);
-    bool mode_info();
-    bool intra_frame_mode_info();
-    bool intra_segment_id();
-    bool read_skip();
+    ErrorOr<void> decode_tile();
+    void clear_left_context();
+    ErrorOr<void> decode_partition(u32 row, u32 col, u8 block_subsize);
+    ErrorOr<void> decode_block(u32 row, u32 col, u8 subsize);
+    ErrorOr<void> mode_info();
+    ErrorOr<void> intra_frame_mode_info();
+    ErrorOr<void> intra_segment_id();
+    ErrorOr<void> read_skip();
     bool seg_feature_active(u8 feature);
     bool seg_feature_active(u8 feature);
-    bool read_tx_size(bool allow_select);
-    bool inter_frame_mode_info();
-    bool inter_segment_id();
+    ErrorOr<void> read_tx_size(bool allow_select);
+    ErrorOr<void> inter_frame_mode_info();
+    ErrorOr<void> inter_segment_id();
     u8 get_segment_id();
     u8 get_segment_id();
-    bool read_is_inter();
-    bool intra_block_mode_info();
-    bool inter_block_mode_info();
-    bool read_ref_frames();
-    bool assign_mv(bool is_compound);
-    bool read_mv(u8 ref);
-    i32 read_mv_component(u8 component);
-    bool residual();
+    ErrorOr<void> read_is_inter();
+    ErrorOr<void> intra_block_mode_info();
+    ErrorOr<void> inter_block_mode_info();
+    ErrorOr<void> read_ref_frames();
+    ErrorOr<void> assign_mv(bool is_compound);
+    ErrorOr<void> read_mv(u8 ref);
+    ErrorOr<i32> read_mv_component(u8 component);
+    ErrorOr<void> residual();
     TXSize get_uv_tx_size();
     TXSize get_uv_tx_size();
     BlockSubsize get_plane_block_size(u32 subsize, u8 plane);
     BlockSubsize get_plane_block_size(u32 subsize, u8 plane);
-    bool tokens(size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
+    ErrorOr<bool> tokens(size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
     u32 const* get_scan(size_t plane, TXSize tx_size, u32 block_index);
     u32 const* get_scan(size_t plane, TXSize tx_size, u32 block_index);
-    u32 read_coef(Token token);
+    ErrorOr<i32> read_coef(Token token);
 
 
     /* (6.5) Motion Vector Prediction */
     /* (6.5) Motion Vector Prediction */
-    bool find_mv_refs(ReferenceFrame, int block);
-    bool find_best_ref_mvs(int ref_list);
-    bool append_sub8x8_mvs(u8 block, u8 ref_list);
+    ErrorOr<void> find_mv_refs(ReferenceFrame, int block);
+    ErrorOr<void> find_best_ref_mvs(int ref_list);
+    ErrorOr<void> append_sub8x8_mvs(u8 block, u8 ref_list);
     bool use_mv_hp(MV const& delta_mv);
     bool use_mv_hp(MV const& delta_mv);
 
 
     u8 m_profile { 0 };
     u8 m_profile { 0 };

+ 13 - 13
Userland/Libraries/LibVideo/VP9/TreeParser.cpp

@@ -11,7 +11,7 @@
 namespace Video::VP9 {
 namespace Video::VP9 {
 
 
 template<typename T>
 template<typename T>
-T TreeParser::parse_tree(SyntaxElementType type)
+ErrorOr<T> TreeParser::parse_tree(SyntaxElementType type)
 {
 {
     auto tree_selection = select_tree(type);
     auto tree_selection = select_tree(type);
     int value;
     int value;
@@ -21,7 +21,7 @@ T TreeParser::parse_tree(SyntaxElementType type)
         auto tree = tree_selection.get_tree_value();
         auto tree = tree_selection.get_tree_value();
         int n = 0;
         int n = 0;
         do {
         do {
-            n = tree[n + m_decoder.m_bit_stream->read_bool(select_tree_probability(type, n >> 1))];
+            n = tree[n + TRY(m_decoder.m_bit_stream->read_bool(select_tree_probability(type, n >> 1)))];
         } while (n > 0);
         } while (n > 0);
         value = -n;
         value = -n;
     }
     }
@@ -29,17 +29,17 @@ T TreeParser::parse_tree(SyntaxElementType type)
     return static_cast<T>(value);
     return static_cast<T>(value);
 }
 }
 
 
-template int TreeParser::parse_tree(SyntaxElementType);
-template bool TreeParser::parse_tree(SyntaxElementType);
-template u8 TreeParser::parse_tree(SyntaxElementType);
-template u32 TreeParser::parse_tree(SyntaxElementType);
-template IntraMode TreeParser::parse_tree(SyntaxElementType);
-template TXSize TreeParser::parse_tree(SyntaxElementType);
-template InterpolationFilter TreeParser::parse_tree(SyntaxElementType);
-template ReferenceMode TreeParser::parse_tree(SyntaxElementType);
-template Token TreeParser::parse_tree(SyntaxElementType);
-template MvClass TreeParser::parse_tree(SyntaxElementType);
-template MvJoint TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<int> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<bool> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<u8> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<u32> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<IntraMode> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<TXSize> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<InterpolationFilter> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<ReferenceMode> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<Token> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<MvClass> TreeParser::parse_tree(SyntaxElementType);
+template ErrorOr<MvJoint> TreeParser::parse_tree(SyntaxElementType);
 
 
 /*
 /*
  * Select a tree value based on the type of syntax element being parsed, as well as some parser state, as specified in section 9.3.1
  * Select a tree value based on the type of syntax element being parsed, as well as some parser state, as specified in section 9.3.1

+ 1 - 1
Userland/Libraries/LibVideo/VP9/TreeParser.h

@@ -43,7 +43,7 @@ public:
 
 
     /* (9.3.3) */
     /* (9.3.3) */
     template<typename T = int>
     template<typename T = int>
-    T parse_tree(SyntaxElementType type);
+    ErrorOr<T> parse_tree(SyntaxElementType type);
     /* (9.3.1) */
     /* (9.3.1) */
     TreeSelection select_tree(SyntaxElementType type);
     TreeSelection select_tree(SyntaxElementType type);
     /* (9.3.2) */
     /* (9.3.2) */

+ 1 - 8
Userland/Libraries/LibVideo/VP9/Utilities.h

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -10,14 +11,6 @@
 
 
 namespace Video::VP9 {
 namespace Video::VP9 {
 
 
-#define SAFE_CALL(call)             \
-    do {                            \
-        if (!(call)) [[unlikely]] { \
-            dbgln("FAILED " #call); \
-            return false;           \
-        }                           \
-    } while (0)
-
 u8 clip_3(u8 x, u8 y, u8 z);
 u8 clip_3(u8 x, u8 y, u8 z);
 u8 round_2(u8 x, u8 n);
 u8 round_2(u8 x, u8 n);
 
 

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است