diff --git a/Userland/Libraries/LibVideo/VP9/Context.h b/Userland/Libraries/LibVideo/VP9/Context.h index b37560229f..ae468c9529 100644 --- a/Userland/Libraries/LibVideo/VP9/Context.h +++ b/Userland/Libraries/LibVideo/VP9/Context.h @@ -237,17 +237,26 @@ struct PersistentBlockContext { u8 segment_id { 0 }; }; +enum class FrameShowMode { + CreateAndShowNewFrame, + ShowExistingFrame, + DoNotShowFrame, +}; + struct FrameContext { public: u8 profile { 0 }; - bool shows_existing_frame() const { return m_show_existing_frame; } - u8 existing_frame_index() const { return m_existing_frame_index; } + bool shows_a_frame() const { return m_frame_show_mode != FrameShowMode::DoNotShowFrame; } + bool shows_a_new_frame() const { return m_frame_show_mode == FrameShowMode::CreateAndShowNewFrame; } + bool shows_existing_frame() const { return m_frame_show_mode == FrameShowMode::ShowExistingFrame; } + void set_frame_hidden() { m_frame_show_mode = FrameShowMode::DoNotShowFrame; } void set_existing_frame_to_show(u8 index) { - m_show_existing_frame = true; + m_frame_show_mode = FrameShowMode::ShowExistingFrame; m_existing_frame_index = index; } + u8 existing_frame_index() const { return m_existing_frame_index; } Gfx::Size size() const { return m_size; } ErrorOr set_size(Gfx::Size size) @@ -273,7 +282,7 @@ public: private: friend struct TileContext; - bool m_show_existing_frame { false }; + FrameShowMode m_frame_show_mode { FrameShowMode::CreateAndShowNewFrame }; u8 m_existing_frame_index { 0 }; Gfx::Size m_size { 0, 0 }; diff --git a/Userland/Libraries/LibVideo/VP9/Decoder.cpp b/Userland/Libraries/LibVideo/VP9/Decoder.cpp index e03800866d..a585e2779d 100644 --- a/Userland/Libraries/LibVideo/VP9/Decoder.cpp +++ b/Userland/Libraries/LibVideo/VP9/Decoder.cpp @@ -69,7 +69,7 @@ DecoderErrorOr Decoder::decode_frame(ReadonlyBytes frame_data) // This is handled by update_reference_frames. // 4. The output process as specified in section 8.9 is invoked. - if (m_parser->m_show_frame) + if (frame_context.shows_a_frame()) TRY(create_video_frame(frame_context)); // 5. The reference frame update process as specified in section 8.10 is invoked. @@ -79,6 +79,12 @@ DecoderErrorOr Decoder::decode_frame(ReadonlyBytes frame_data) DecoderErrorOr Decoder::create_video_frame(FrameContext const& frame_context) { + // (8.9) Output process + + // FIXME: If show_existing_frame is set, output from FrameStore[frame_to_show_map_index] here instead. + + // FIXME: The math isn't entirely accurate to spec. output_uv_size is probably incorrect for certain + // sizes, as the spec seems to prefer that the halved sizes be ceiled. u32 decoded_y_width = frame_context.columns() * 8; Gfx::Size output_y_size = frame_context.size(); auto decoded_uv_width = decoded_y_width >> m_parser->m_subsampling_x; diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp index 89cb7ef8ef..a8a574ed7c 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.cpp +++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp @@ -104,7 +104,7 @@ DecoderErrorOr Parser::parse_frame(ReadonlyBytes frame_data) TRY(refresh_probs()); m_previous_frame_size = frame_context.size(); - m_previous_show_frame = m_show_frame; + m_previous_show_frame = frame_context.shows_a_frame(); return frame_context; } @@ -171,7 +171,8 @@ DecoderErrorOr Parser::uncompressed_header() m_last_frame_type = m_frame_type; m_frame_type = TRY(read_frame_type()); - m_show_frame = TRY_READ(m_bit_stream->read_bit()); + if (!TRY_READ(m_bit_stream->read_bit())) + frame_context.set_frame_hidden(); m_error_resilient_mode = TRY_READ(m_bit_stream->read_bit()); Gfx::Size frame_size; @@ -185,7 +186,7 @@ DecoderErrorOr Parser::uncompressed_header() m_refresh_frame_flags = 0xFF; m_frame_is_intra = true; } else { - m_frame_is_intra = !m_show_frame && TRY_READ(m_bit_stream->read_bit()); + m_frame_is_intra = !frame_context.shows_a_frame() && TRY_READ(m_bit_stream->read_bit()); if (!m_error_resilient_mode) { m_reset_frame_context = TRY_READ(m_bit_stream->read_bits(2)); diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h index d8ff606b05..901cf77f57 100644 --- a/Userland/Libraries/LibVideo/VP9/Parser.h +++ b/Userland/Libraries/LibVideo/VP9/Parser.h @@ -149,7 +149,6 @@ private: bool m_loop_filter_delta_enabled { false }; FrameType m_frame_type { FrameType::KeyFrame }; FrameType m_last_frame_type { FrameType::KeyFrame }; - bool m_show_frame { false }; bool m_error_resilient_mode { false }; bool m_frame_is_intra { false }; u8 m_reset_frame_context { 0 };