summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibVideo/VP9/Decoder.cpp34
-rw-r--r--Userland/Libraries/LibVideo/VP9/Parser.cpp60
-rw-r--r--Userland/Libraries/LibVideo/VP9/Parser.h18
3 files changed, 48 insertions, 64 deletions
diff --git a/Userland/Libraries/LibVideo/VP9/Decoder.cpp b/Userland/Libraries/LibVideo/VP9/Decoder.cpp
index 318216c963..bbe8b52c4e 100644
--- a/Userland/Libraries/LibVideo/VP9/Decoder.cpp
+++ b/Userland/Libraries/LibVideo/VP9/Decoder.cpp
@@ -87,13 +87,10 @@ DecoderErrorOr<void> Decoder::decode_frame(ReadonlyBytes frame_data)
DecoderErrorOr<void> Decoder::create_video_frame()
{
- size_t decoded_y_width = m_parser->m_mi_cols * 8;
- Gfx::Size<size_t> output_y_size = {
- m_parser->m_frame_width,
- m_parser->m_frame_height,
- };
+ u32 decoded_y_width = m_parser->m_mi_cols * 8;
+ Gfx::Size<u32> output_y_size = m_parser->m_frame_size;
auto decoded_uv_width = decoded_y_width >> m_parser->m_subsampling_x;
- Gfx::Size<size_t> output_uv_size = {
+ Gfx::Size<u32> output_uv_size = {
output_y_size.width() >> m_parser->m_subsampling_x,
output_y_size.height() >> m_parser->m_subsampling_y,
};
@@ -816,11 +813,11 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 x,
// − FrameHeight <= 16 * RefFrameHeight[ refIdx ]
if (m_parser->m_frame_store[reference_frame_index][plane].is_empty())
return DecoderError::format(DecoderErrorCategory::Corrupted, "Attempted to use reference frame {} that has not been saved", reference_frame_index);
- if (2 * m_parser->m_frame_width < m_parser->m_ref_frame_width[reference_frame_index]
- || 2 * m_parser->m_frame_height < m_parser->m_ref_frame_height[reference_frame_index])
+ auto ref_frame_size = m_parser->m_ref_frame_size[reference_frame_index];
+ auto double_frame_size = m_parser->m_frame_size.scaled_by(2);
+ if (double_frame_size.width() < ref_frame_size.width() || double_frame_size.height() < ref_frame_size.height())
return DecoderError::format(DecoderErrorCategory::Corrupted, "Inter frame size is too small relative to reference frame {}", reference_frame_index);
- if (m_parser->m_frame_width > 16 * m_parser->m_ref_frame_width[reference_frame_index]
- || m_parser->m_frame_height > 16 * m_parser->m_ref_frame_height[reference_frame_index])
+ if (!ref_frame_size.scaled_by(16).contains(m_parser->m_frame_size))
return DecoderError::format(DecoderErrorCategory::Corrupted, "Inter frame size is too large relative to reference frame {}", reference_frame_index);
// FIXME: Convert all the operations in this function to vector operations supported by
@@ -830,8 +827,8 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 x,
// A variable yScale is set equal to (RefFrameHeight[ refIdx ] << REF_SCALE_SHIFT) / FrameHeight.
// (xScale and yScale specify the size of the reference frame relative to the current frame in units where 16 is
// equivalent to the reference frame having the same size.)
- i32 x_scale = (m_parser->m_ref_frame_width[reference_frame_index] << REF_SCALE_SHIFT) / m_parser->m_frame_width;
- i32 y_scale = (m_parser->m_ref_frame_height[reference_frame_index] << REF_SCALE_SHIFT) / m_parser->m_frame_height;
+ i32 x_scale = (ref_frame_size.width() << REF_SCALE_SHIFT) / m_parser->m_frame_size.width();
+ i32 y_scale = (ref_frame_size.height() << REF_SCALE_SHIFT) / m_parser->m_frame_size.height();
// The variable baseX is set equal to (x * xScale) >> REF_SCALE_SHIFT.
// The variable baseY is set equal to (y * yScale) >> REF_SCALE_SHIFT.
@@ -885,7 +882,7 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 x,
// A variable ref specifying the reference frame contents is set equal to FrameStore[ refIdx ].
auto& reference_frame_buffer = m_parser->m_frame_store[reference_frame_index][plane];
- auto reference_frame_width = m_parser->m_ref_frame_width[reference_frame_index] >> subsampling_x;
+ auto reference_frame_width = m_parser->m_ref_frame_size[reference_frame_index].width() >> subsampling_x;
auto reference_frame_buffer_at = [&](u32 row, u32 column) -> u16& {
return reference_frame_buffer[row * reference_frame_width + column];
};
@@ -898,8 +895,8 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 x,
// The variable lastX is set equal to ( (RefFrameWidth[ refIdx ] + subX) >> subX) - 1.
// The variable lastY is set equal to ( (RefFrameHeight[ refIdx ] + subY) >> subY) - 1.
// (lastX and lastY specify the coordinates of the bottom right sample of the reference plane.)
- i32 scaled_right = ((m_parser->m_ref_frame_width[reference_frame_index] + subsampling_x) >> subsampling_x) - 1;
- i32 scaled_bottom = ((m_parser->m_ref_frame_height[reference_frame_index] + subsampling_y) >> subsampling_y) - 1;
+ i32 scaled_right = ((m_parser->m_ref_frame_size[reference_frame_index].width() + subsampling_x) >> subsampling_x) - 1;
+ i32 scaled_bottom = ((m_parser->m_ref_frame_size[reference_frame_index].height() + subsampling_y) >> subsampling_y) - 1;
// The variable intermediateHeight specifying the height required for the intermediate array is set equal to (((h -
// 1) * yStep + 15) >> 4) + 8.
@@ -1779,9 +1776,8 @@ DecoderErrorOr<void> Decoder::update_reference_frames()
for (auto i = 0; i < NUM_REF_FRAMES; i++) {
if ((refresh_flags & 1) != 0) {
// − RefFrameWidth[ i ] is set equal to FrameWidth.
- m_parser->m_ref_frame_width[i] = m_parser->m_frame_width;
// − RefFrameHeight[ i ] is set equal to FrameHeight.
- m_parser->m_ref_frame_height[i] = m_parser->m_frame_height;
+ m_parser->m_ref_frame_size[i] = m_parser->m_frame_size;
// − RefSubsamplingX[ i ] is set equal to subsampling_x.
m_parser->m_ref_subsampling_x[i] = m_parser->m_subsampling_x;
// − RefSubsamplingY[ i ] is set equal to subsampling_y.
@@ -1798,8 +1794,8 @@ DecoderErrorOr<void> Decoder::update_reference_frames()
// FIXME: Frame width is not equal to the buffer's stride. If we store the stride of the buffer with the reference
// frame, we can just copy the framebuffer data instead. Alternatively, we should crop the output framebuffer.
for (auto plane = 0u; plane < 3; plane++) {
- auto width = m_parser->m_frame_width;
- auto height = m_parser->m_frame_height;
+ auto width = m_parser->m_frame_size.width();
+ auto height = m_parser->m_frame_size.height();
auto stride = m_parser->m_mi_cols * 8;
if (plane > 0) {
diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp
index 300c3bca36..2355b9ae1b 100644
--- a/Userland/Libraries/LibVideo/VP9/Parser.cpp
+++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp
@@ -168,8 +168,8 @@ DecoderErrorOr<void> Parser::uncompressed_header()
if (m_frame_type == KeyFrame) {
TRY(frame_sync_code());
TRY(color_config());
- TRY(frame_size());
- TRY(render_size());
+ m_frame_size = TRY(frame_size());
+ m_render_size = TRY(render_size(m_frame_size));
m_refresh_frame_flags = 0xFF;
m_frame_is_intra = true;
} else {
@@ -193,20 +193,23 @@ DecoderErrorOr<void> Parser::uncompressed_header()
}
m_refresh_frame_flags = TRY_READ(m_bit_stream->read_f8());
- TRY(frame_size());
- TRY(render_size());
+ m_frame_size = TRY(frame_size());
+ m_render_size = TRY(render_size(m_frame_size));
} else {
m_refresh_frame_flags = TRY_READ(m_bit_stream->read_f8());
for (auto i = 0; i < 3; i++) {
m_ref_frame_idx[i] = TRY_READ(m_bit_stream->read_bits(3));
m_ref_frame_sign_bias[LastFrame + i] = TRY_READ(m_bit_stream->read_bit());
}
- TRY(frame_size_with_refs());
+ m_frame_size = TRY(frame_size_with_refs());
+ m_render_size = TRY(render_size(m_frame_size));
m_allow_high_precision_mv = TRY_READ(m_bit_stream->read_bit());
TRY(read_interpolation_filter());
}
}
+ compute_image_size();
+
if (!m_error_resilient_mode) {
m_refresh_frame_context = TRY_READ(m_bit_stream->read_bit());
m_frame_parallel_decoding_mode = TRY_READ(m_bit_stream->read_bit());
@@ -284,51 +287,38 @@ DecoderErrorOr<void> Parser::color_config()
return {};
}
-DecoderErrorOr<void> Parser::frame_size()
+DecoderErrorOr<Gfx::Size<u32>> Parser::frame_size()
{
- m_frame_width = TRY_READ(m_bit_stream->read_f16()) + 1;
- m_frame_height = TRY_READ(m_bit_stream->read_f16()) + 1;
- compute_image_size();
- return {};
+ return Gfx::Size<u32> { TRY_READ(m_bit_stream->read_f16()) + 1, TRY_READ(m_bit_stream->read_f16()) + 1 };
}
-DecoderErrorOr<void> Parser::render_size()
+DecoderErrorOr<Gfx::Size<u32>> Parser::render_size(Gfx::Size<u32> frame_size)
{
- if (TRY_READ(m_bit_stream->read_bit())) {
- m_render_width = TRY_READ(m_bit_stream->read_f16()) + 1;
- m_render_height = TRY_READ(m_bit_stream->read_f16()) + 1;
- } else {
- m_render_width = m_frame_width;
- m_render_height = m_frame_height;
- }
- return {};
+ if (!TRY_READ(m_bit_stream->read_bit()))
+ return frame_size;
+ return Gfx::Size<u32> { TRY_READ(m_bit_stream->read_f16()) + 1, TRY_READ(m_bit_stream->read_f16()) + 1 };
}
-DecoderErrorOr<void> Parser::frame_size_with_refs()
+DecoderErrorOr<Gfx::Size<u32>> Parser::frame_size_with_refs()
{
- bool found_ref;
+ Optional<Gfx::Size<u32>> size;
for (auto frame_index : m_ref_frame_idx) {
- found_ref = TRY_READ(m_bit_stream->read_bit());
- if (found_ref) {
- m_frame_width = m_ref_frame_width[frame_index];
- m_frame_height = m_ref_frame_height[frame_index];
+ if (TRY_READ(m_bit_stream->read_bit())) {
+ size.emplace(m_ref_frame_size[frame_index]);
break;
}
}
- if (!found_ref) {
- TRY(frame_size());
- } else {
- compute_image_size();
- }
+ if (size.has_value())
+ return size.value();
- return render_size();
+ return TRY(frame_size());
}
void Parser::compute_image_size()
{
- auto new_cols = (m_frame_width + 7u) >> 3u;
- auto new_rows = (m_frame_height + 7u) >> 3u;
+ auto new_cols = (m_frame_size.width() + 7u) >> 3u;
+ auto new_rows = (m_frame_size.height() + 7u) >> 3u;
// 7.2.6 Compute image size semantics
// When compute_image_size is invoked, the following ordered steps occur:
@@ -1728,8 +1718,8 @@ void Parser::append_sub8x8_mvs(i32 block, u8 ref_list)
void Parser::dump_info()
{
- outln("Frame dimensions: {}x{}", m_frame_width, m_frame_height);
- outln("Render dimensions: {}x{}", m_render_width, m_render_height);
+ outln("Frame dimensions: {}x{}", m_frame_size.width(), m_frame_size.height());
+ outln("Render dimensions: {}x{}", m_render_size.width(), m_render_size.height());
outln("Bit depth: {}", m_bit_depth);
outln("Show frame: {}", m_show_frame);
}
diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h
index 154a85a4ca..7d72a24014 100644
--- a/Userland/Libraries/LibVideo/VP9/Parser.h
+++ b/Userland/Libraries/LibVideo/VP9/Parser.h
@@ -11,7 +11,7 @@
#include <AK/OwnPtr.h>
#include <AK/Span.h>
#include <AK/Vector.h>
-#include <LibGfx/Forward.h>
+#include <LibGfx/Size.h>
#include <LibVideo/Color/CodingIndependentCodePoints.h>
#include <LibVideo/DecoderError.h>
@@ -60,9 +60,10 @@ private:
DecoderErrorOr<void> uncompressed_header();
DecoderErrorOr<void> frame_sync_code();
DecoderErrorOr<void> color_config();
- DecoderErrorOr<void> frame_size();
- DecoderErrorOr<void> render_size();
- DecoderErrorOr<void> frame_size_with_refs();
+ DecoderErrorOr<void> set_frame_size_and_compute_image_size();
+ DecoderErrorOr<Gfx::Size<u32>> frame_size();
+ DecoderErrorOr<Gfx::Size<u32>> frame_size_with_refs();
+ DecoderErrorOr<Gfx::Size<u32>> render_size(Gfx::Size<u32> frame_size);
void compute_image_size();
DecoderErrorOr<void> read_interpolation_filter();
DecoderErrorOr<void> loop_filter_params();
@@ -171,10 +172,8 @@ private:
ColorRange m_color_range;
bool m_subsampling_x { false };
bool m_subsampling_y { false };
- u32 m_frame_width { 0 };
- u32 m_frame_height { 0 };
- u16 m_render_width { 0 };
- u16 m_render_height { 0 };
+ Gfx::Size<u32> m_frame_size { 0, 0 };
+ Gfx::Size<u32> m_render_size { 0, 0 };
bool m_render_and_frame_size_different { false };
u32 m_mi_cols { 0 };
u32 m_mi_rows { 0 };
@@ -257,8 +256,7 @@ private:
MotionVector m_nearest_mv[2];
MotionVector m_best_mv[2];
// FIXME: Move these to a struct to store together in one array.
- u32 m_ref_frame_width[NUM_REF_FRAMES];
- u32 m_ref_frame_height[NUM_REF_FRAMES];
+ Gfx::Size<u32> m_ref_frame_size[NUM_REF_FRAMES];
bool m_ref_subsampling_x[NUM_REF_FRAMES];
bool m_ref_subsampling_y[NUM_REF_FRAMES];
u8 m_ref_bit_depth[NUM_REF_FRAMES];