mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 14:07:45 +00:00
LibVideo/VP9: Choose whether/how to show new frames using an enum
There are three mutually exclusive frame-showing states: - Show no new frame, only store the frame as a reference. - Show a newly decoded frame. - Show frame from the reference frame store. Since they are mutually exclusive, using an enum rather than two bools makes more sense.
This commit is contained in:
parent
befcd479ae
commit
3259c99cab
4 changed files with 24 additions and 9 deletions
|
@ -237,17 +237,26 @@ struct PersistentBlockContext {
|
||||||
u8 segment_id { 0 };
|
u8 segment_id { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class FrameShowMode {
|
||||||
|
CreateAndShowNewFrame,
|
||||||
|
ShowExistingFrame,
|
||||||
|
DoNotShowFrame,
|
||||||
|
};
|
||||||
|
|
||||||
struct FrameContext {
|
struct FrameContext {
|
||||||
public:
|
public:
|
||||||
u8 profile { 0 };
|
u8 profile { 0 };
|
||||||
|
|
||||||
bool shows_existing_frame() const { return m_show_existing_frame; }
|
bool shows_a_frame() const { return m_frame_show_mode != FrameShowMode::DoNotShowFrame; }
|
||||||
u8 existing_frame_index() const { return m_existing_frame_index; }
|
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)
|
void set_existing_frame_to_show(u8 index)
|
||||||
{
|
{
|
||||||
m_show_existing_frame = true;
|
m_frame_show_mode = FrameShowMode::ShowExistingFrame;
|
||||||
m_existing_frame_index = index;
|
m_existing_frame_index = index;
|
||||||
}
|
}
|
||||||
|
u8 existing_frame_index() const { return m_existing_frame_index; }
|
||||||
|
|
||||||
Gfx::Size<u32> size() const { return m_size; }
|
Gfx::Size<u32> size() const { return m_size; }
|
||||||
ErrorOr<void> set_size(Gfx::Size<u32> size)
|
ErrorOr<void> set_size(Gfx::Size<u32> size)
|
||||||
|
@ -273,7 +282,7 @@ public:
|
||||||
private:
|
private:
|
||||||
friend struct TileContext;
|
friend struct TileContext;
|
||||||
|
|
||||||
bool m_show_existing_frame { false };
|
FrameShowMode m_frame_show_mode { FrameShowMode::CreateAndShowNewFrame };
|
||||||
u8 m_existing_frame_index { 0 };
|
u8 m_existing_frame_index { 0 };
|
||||||
|
|
||||||
Gfx::Size<u32> m_size { 0, 0 };
|
Gfx::Size<u32> m_size { 0, 0 };
|
||||||
|
|
|
@ -69,7 +69,7 @@ DecoderErrorOr<void> Decoder::decode_frame(ReadonlyBytes frame_data)
|
||||||
// This is handled by update_reference_frames.
|
// This is handled by update_reference_frames.
|
||||||
|
|
||||||
// 4. The output process as specified in section 8.9 is invoked.
|
// 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));
|
TRY(create_video_frame(frame_context));
|
||||||
|
|
||||||
// 5. The reference frame update process as specified in section 8.10 is invoked.
|
// 5. The reference frame update process as specified in section 8.10 is invoked.
|
||||||
|
@ -79,6 +79,12 @@ DecoderErrorOr<void> Decoder::decode_frame(ReadonlyBytes frame_data)
|
||||||
|
|
||||||
DecoderErrorOr<void> Decoder::create_video_frame(FrameContext const& frame_context)
|
DecoderErrorOr<void> 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;
|
u32 decoded_y_width = frame_context.columns() * 8;
|
||||||
Gfx::Size<u32> output_y_size = frame_context.size();
|
Gfx::Size<u32> output_y_size = frame_context.size();
|
||||||
auto decoded_uv_width = decoded_y_width >> m_parser->m_subsampling_x;
|
auto decoded_uv_width = decoded_y_width >> m_parser->m_subsampling_x;
|
||||||
|
|
|
@ -104,7 +104,7 @@ DecoderErrorOr<FrameContext> Parser::parse_frame(ReadonlyBytes frame_data)
|
||||||
TRY(refresh_probs());
|
TRY(refresh_probs());
|
||||||
|
|
||||||
m_previous_frame_size = frame_context.size();
|
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;
|
return frame_context;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,8 @@ DecoderErrorOr<FrameContext> Parser::uncompressed_header()
|
||||||
|
|
||||||
m_last_frame_type = m_frame_type;
|
m_last_frame_type = m_frame_type;
|
||||||
m_frame_type = TRY(read_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());
|
m_error_resilient_mode = TRY_READ(m_bit_stream->read_bit());
|
||||||
|
|
||||||
Gfx::Size<u32> frame_size;
|
Gfx::Size<u32> frame_size;
|
||||||
|
@ -185,7 +186,7 @@ DecoderErrorOr<FrameContext> Parser::uncompressed_header()
|
||||||
m_refresh_frame_flags = 0xFF;
|
m_refresh_frame_flags = 0xFF;
|
||||||
m_frame_is_intra = true;
|
m_frame_is_intra = true;
|
||||||
} else {
|
} 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) {
|
if (!m_error_resilient_mode) {
|
||||||
m_reset_frame_context = TRY_READ(m_bit_stream->read_bits(2));
|
m_reset_frame_context = TRY_READ(m_bit_stream->read_bits(2));
|
||||||
|
|
|
@ -149,7 +149,6 @@ private:
|
||||||
bool m_loop_filter_delta_enabled { false };
|
bool m_loop_filter_delta_enabled { false };
|
||||||
FrameType m_frame_type { FrameType::KeyFrame };
|
FrameType m_frame_type { FrameType::KeyFrame };
|
||||||
FrameType m_last_frame_type { FrameType::KeyFrame };
|
FrameType m_last_frame_type { FrameType::KeyFrame };
|
||||||
bool m_show_frame { false };
|
|
||||||
bool m_error_resilient_mode { false };
|
bool m_error_resilient_mode { false };
|
||||||
bool m_frame_is_intra { false };
|
bool m_frame_is_intra { false };
|
||||||
u8 m_reset_frame_context { 0 };
|
u8 m_reset_frame_context { 0 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue