mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibVideo/VP9: Put reference frames into a struct
This commit is contained in:
parent
e6b696fe24
commit
f5ea6c89df
Notes:
sideshowbarker
2024-07-17 21:26:19 +09:00
Author: https://github.com/Zaggy1024 Commit: https://github.com/SerenityOS/serenity/commit/f5ea6c89df Pull-request: https://github.com/SerenityOS/serenity/pull/16238
4 changed files with 32 additions and 24 deletions
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <AK/Array.h>
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibVideo/Color/CodingIndependentCodePoints.h>
|
||||
|
||||
|
@ -257,4 +258,14 @@ using SegmentationPredictionContextView = Span<u8>;
|
|||
using PartitionContext = FixedArray<u8>;
|
||||
using PartitionContextView = Span<u8>;
|
||||
|
||||
struct ReferenceFrame {
|
||||
Gfx::Size<u32> size { 0, 0 };
|
||||
bool subsampling_x { false };
|
||||
bool subsampling_y { false };
|
||||
u8 bit_depth { 0 };
|
||||
Array<Vector<u16>, 3> frame_planes {};
|
||||
|
||||
bool is_valid() { return bit_depth > 0; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -797,13 +797,13 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
|
|||
// − 2 * FrameHeight >= RefFrameHeight[ refIdx ]
|
||||
// − FrameWidth <= 16 * RefFrameWidth[ refIdx ]
|
||||
// − FrameHeight <= 16 * RefFrameHeight[ refIdx ]
|
||||
if (m_parser->m_frame_store[reference_frame_index][plane].is_empty())
|
||||
auto& reference_frame = m_parser->m_reference_frames[reference_frame_index];
|
||||
if (!reference_frame.is_valid())
|
||||
return DecoderError::format(DecoderErrorCategory::Corrupted, "Attempted to use reference frame {} that has not been saved", reference_frame_index);
|
||||
auto ref_frame_size = m_parser->m_ref_frame_size[reference_frame_index];
|
||||
auto double_frame_size = block_context.frame_context.size().scaled_by(2);
|
||||
if (double_frame_size.width() < ref_frame_size.width() || double_frame_size.height() < ref_frame_size.height())
|
||||
if (double_frame_size.width() < reference_frame.size.width() || double_frame_size.height() < reference_frame.size.height())
|
||||
return DecoderError::format(DecoderErrorCategory::Corrupted, "Inter frame size is too small relative to reference frame {}", reference_frame_index);
|
||||
if (!ref_frame_size.scaled_by(16).contains(block_context.frame_context.size()))
|
||||
if (!reference_frame.size.scaled_by(16).contains(block_context.frame_context.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
|
||||
|
@ -813,8 +813,8 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
|
|||
// 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 = (ref_frame_size.width() << REF_SCALE_SHIFT) / block_context.frame_context.size().width();
|
||||
i32 y_scale = (ref_frame_size.height() << REF_SCALE_SHIFT) / block_context.frame_context.size().height();
|
||||
i32 x_scale = (reference_frame.size.width() << REF_SCALE_SHIFT) / block_context.frame_context.size().width();
|
||||
i32 y_scale = (reference_frame.size.height() << REF_SCALE_SHIFT) / block_context.frame_context.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.
|
||||
|
@ -868,8 +868,8 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
|
|||
// The output from this process is the 2D array named pred containing inter predicted samples.
|
||||
|
||||
// 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_size[reference_frame_index].width() >> subsampling_x;
|
||||
auto& reference_frame_buffer = reference_frame.frame_planes[plane];
|
||||
auto reference_frame_width = reference_frame.size.width() >> subsampling_x;
|
||||
auto reference_frame_buffer_at = [&](u32 row, u32 column) -> u16& {
|
||||
return reference_frame_buffer[row * reference_frame_width + column];
|
||||
};
|
||||
|
@ -881,8 +881,8 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
|
|||
// 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_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;
|
||||
i32 scaled_right = ((reference_frame.size.width() + subsampling_x) >> subsampling_x) - 1;
|
||||
i32 scaled_bottom = ((reference_frame.size.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.
|
||||
|
@ -1761,15 +1761,17 @@ DecoderErrorOr<void> Decoder::update_reference_frames(FrameContext const& frame_
|
|||
// is equal to 1 (i.e. if (refresh_frame_flags>>i)&1 is equal to 1):
|
||||
for (u8 i = 0; i < NUM_REF_FRAMES; i++) {
|
||||
if (frame_context.should_update_reference_frame_at_index(i)) {
|
||||
auto& reference_frame = m_parser->m_reference_frames[i];
|
||||
|
||||
// − RefFrameWidth[ i ] is set equal to FrameWidth.
|
||||
// − RefFrameHeight[ i ] is set equal to FrameHeight.
|
||||
m_parser->m_ref_frame_size[i] = frame_context.size();
|
||||
reference_frame.size = frame_context.size();
|
||||
// − RefSubsamplingX[ i ] is set equal to subsampling_x.
|
||||
m_parser->m_ref_subsampling_x[i] = frame_context.color_config.subsampling_x;
|
||||
reference_frame.subsampling_x = frame_context.color_config.subsampling_x;
|
||||
// − RefSubsamplingY[ i ] is set equal to subsampling_y.
|
||||
m_parser->m_ref_subsampling_y[i] = frame_context.color_config.subsampling_y;
|
||||
reference_frame.subsampling_y = frame_context.color_config.subsampling_y;
|
||||
// − RefBitDepth[ i ] is set equal to BitDepth.
|
||||
m_parser->m_ref_bit_depth[i] = frame_context.color_config.bit_depth;
|
||||
reference_frame.bit_depth = frame_context.color_config.bit_depth;
|
||||
|
||||
// − FrameStore[ i ][ 0 ][ y ][ x ] is set equal to CurrFrame[ 0 ][ y ][ x ] for x = 0..FrameWidth-1, for y =
|
||||
// 0..FrameHeight-1.
|
||||
|
@ -1791,7 +1793,7 @@ DecoderErrorOr<void> Decoder::update_reference_frames(FrameContext const& frame_
|
|||
}
|
||||
|
||||
auto original_buffer = get_output_buffer(plane);
|
||||
auto& frame_store_buffer = m_parser->m_frame_store[i][plane];
|
||||
auto& frame_store_buffer = reference_frame.frame_planes[plane];
|
||||
frame_store_buffer.resize_and_keep_capacity(width * height);
|
||||
|
||||
for (auto x = 0u; x < width; x++) {
|
||||
|
|
|
@ -357,7 +357,9 @@ DecoderErrorOr<Gfx::Size<u32>> Parser::parse_frame_size_with_refs(Array<u8, 3> c
|
|||
Optional<Gfx::Size<u32>> size;
|
||||
for (auto frame_index : reference_indices) {
|
||||
if (TRY_READ(m_bit_stream->read_bit())) {
|
||||
size.emplace(m_ref_frame_size[frame_index]);
|
||||
if (!m_reference_frames[frame_index].is_valid())
|
||||
return DecoderError::corrupted("Frame size referenced a frame that does not exist"sv);
|
||||
size.emplace(m_reference_frames[frame_index].size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <AK/Array.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibVideo/Color/CodingIndependentCodePoints.h>
|
||||
#include <LibVideo/DecoderError.h>
|
||||
|
@ -139,13 +138,7 @@ private:
|
|||
bool m_previous_should_use_absolute_segment_base_quantizer;
|
||||
Array<Array<SegmentFeature, SEG_LVL_MAX>, MAX_SEGMENTS> m_previous_segmentation_features;
|
||||
|
||||
// FIXME: Move these to a struct to store together in one array.
|
||||
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];
|
||||
|
||||
Vector<u16> m_frame_store[NUM_REF_FRAMES][3];
|
||||
ReferenceFrame m_reference_frames[NUM_REF_FRAMES];
|
||||
|
||||
Vector2D<FrameBlockContext> m_reusable_frame_block_contexts;
|
||||
Vector2D<PersistentBlockContext> m_previous_block_contexts;
|
||||
|
|
Loading…
Reference in a new issue