summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibVideo/VP9
diff options
context:
space:
mode:
authorZaggy1024 <zaggy1024@gmail.com>2022-11-26 02:57:48 -0600
committerAndreas Kling <kling@serenityos.org>2022-11-30 08:28:30 +0100
commitf4af6714d2596af15a651c7ddfe07f40d84d03ae (patch)
tree88726e6919c33e117cf734b57e7fbf78143e2148 /Userland/Libraries/LibVideo/VP9
parentfacb779b995c36cf47a310851f54d55b08e63834 (diff)
downloadserenity-f4af6714d2596af15a651c7ddfe07f40d84d03ae.zip
LibVideo/VP9: Move persistent context storage to a different header
Moving these to another header allows Parser.h to include less context structs/classes that were previously in Context.h. This change will also allow consolidating some common calculations into Context.h, since we won't be polluting the VP9 namespace as much. There are quite a few duplicate calculations for block size, transform size, number of horizontal and vertical sub-blocks per block, all of which could be moved to Context.h to allow for code deduplication and more semantic code where those calculations are needed.
Diffstat (limited to 'Userland/Libraries/LibVideo/VP9')
-rw-r--r--Userland/Libraries/LibVideo/VP9/Context.h238
-rw-r--r--Userland/Libraries/LibVideo/VP9/ContextStorage.h251
-rw-r--r--Userland/Libraries/LibVideo/VP9/Decoder.cpp1
-rw-r--r--Userland/Libraries/LibVideo/VP9/Parser.cpp1
-rw-r--r--Userland/Libraries/LibVideo/VP9/Parser.h7
-rw-r--r--Userland/Libraries/LibVideo/VP9/TreeParser.h12
6 files changed, 271 insertions, 239 deletions
diff --git a/Userland/Libraries/LibVideo/VP9/Context.h b/Userland/Libraries/LibVideo/VP9/Context.h
index 31b68e1140..2a71a595a1 100644
--- a/Userland/Libraries/LibVideo/VP9/Context.h
+++ b/Userland/Libraries/LibVideo/VP9/Context.h
@@ -12,253 +12,19 @@
#include <LibGfx/Size.h>
#include <LibVideo/Color/CodingIndependentCodePoints.h>
+#include "ContextStorage.h"
#include "Enums.h"
#include "LookupTables.h"
#include "MotionVector.h"
namespace Video::VP9 {
-template<typename T>
-struct ReferencePair {
- T primary;
- T secondary;
-
- T& operator[](ReferenceIndex index)
- {
- switch (index) {
- case ReferenceIndex::Primary:
- return primary;
- case ReferenceIndex::Secondary:
- return secondary;
- default:
- VERIFY_NOT_REACHED();
- }
- }
-
- T const& operator[](ReferenceIndex index) const
- {
- return const_cast<ReferencePair<T>&>(*this)[index];
- }
-};
-
-typedef ReferencePair<ReferenceFrameType> ReferenceFramePair;
-typedef ReferencePair<MotionVector> MotionVectorPair;
-
-template<typename T>
-class Vector2D;
-
-template<typename T>
-class Vector2DView {
-public:
- u32 top() const { return m_top; }
- u32 left() const { return m_left; }
- u32 height() const { return m_height; }
- u32 width() const { return m_width; }
-
- T const& operator[](size_t index) const { return m_storage[index]; }
- size_t size() const { return m_storage->size(); }
-
- T& at(u32 relative_row, u32 relative_column)
- {
- VERIFY(relative_row < height());
- VERIFY(relative_column < width());
- return m_storage->at(top() + relative_row, left() + relative_column);
- }
- T const& at(u32 relative_row, u32 relative_column) const
- {
- VERIFY(relative_row < height());
- VERIFY(relative_column < width());
- return m_storage->at(top() + relative_row, left() + relative_column);
- }
-
- Vector2DView<T> view(u32 top, u32 left, u32 height, u32 width)
- {
- VERIFY(top + height <= this->height());
- VERIFY(left + width <= this->width());
- return Vector2DView<T>(m_storage, this->top() + top, this->left() + left, height, width);
- }
-
-private:
- friend class Vector2D<T>;
-
- Vector2DView(Vector2D<T>* const storage, u32 top, u32 left, u32 height, u32 width)
- : m_storage(storage)
- , m_top(top)
- , m_left(left)
- , m_height(height)
- , m_width(width)
- {
- }
-
- Vector2D<T>* const m_storage;
- u32 const m_top { 0 };
- u32 const m_left { 0 };
- u32 const m_height { 0 };
- u32 const m_width { 0 };
-};
-
-template<typename T>
-class Vector2D {
-public:
- ~Vector2D()
- {
- if (m_storage)
- free(m_storage);
- m_storage = nullptr;
- m_width = 0;
- m_height = 0;
- }
-
- ErrorOr<void> try_resize(u32 height, u32 width)
- {
- if (height != m_height && width != m_width) {
- this->~Vector2D();
- size_t size = height * width;
- auto* new_storage = static_cast<T*>(malloc(size * sizeof(T)));
- if (!new_storage)
- return Error::from_errno(ENOMEM);
- m_storage = new_storage;
- m_height = height;
- m_width = width;
- }
-
- return {};
- }
-
- u32 height() const { return m_height; }
- u32 width() const { return m_width; }
-
- size_t index_at(u32 row, u32 column) const
- {
- VERIFY(row < height());
- VERIFY(column < width());
- return row * width() + column;
- }
-
- T& operator[](size_t index) { return m_storage[index]; }
- T const& operator[](size_t index) const { return m_storage[index]; }
- size_t size() const { return m_height * m_width; }
-
- T& at(u32 row, u32 column)
- {
- return m_storage[index_at(row, column)];
- }
- T const& at(u32 row, u32 column) const
- {
- return m_storage[index_at(row, column)];
- }
-
- template<typename OtherT>
- ErrorOr<void> try_resize_to_match_other_vector2d(Vector2D<OtherT> const& other)
- {
- return try_resize(other.height(), other.width());
- }
-
- template<typename OtherT, typename Function>
- void copy_to(Vector2D<OtherT>& other, Function function) const
- {
- VERIFY(width() <= other.width());
- VERIFY(height() <= other.height());
- for (u32 row = 0; row < height(); row++) {
- for (u32 column = 0; column < width(); column++)
- other.at(row, column) = function(at(row, column));
- }
- }
-
- void copy_to(Vector2D<T>& other) const
- {
- VERIFY(width() <= other.width());
- VERIFY(height() <= other.height());
- for (u32 row = 0; row < height(); row++) {
- auto other_index = other.index_at(row, 0);
- AK::TypedTransfer<T>::copy(&m_storage[index_at(row, 0)], &other[other_index], width());
- }
- }
-
- void reset()
- {
- for (size_t i = 0; i < size(); i++)
- m_storage[i] = T();
- }
-
- Vector2DView<T> view(u32 top, u32 left, u32 height, u32 width)
- {
- VERIFY(top + height <= this->height());
- VERIFY(left + width <= this->width());
- return Vector2DView<T>(this, top, left, height, width);
- }
-
-private:
- u32 m_height { 0 };
- u32 m_width { 0 };
- T* m_storage { nullptr };
-};
-
-struct TokensContext {
- TXSize m_tx_size;
- bool m_is_uv_plane;
- bool m_is_inter;
- u8 m_band;
- u8 m_context_index;
-};
-
-// Block context that is kept for the lifetime of a frame.
-struct FrameBlockContext {
- bool is_intra_predicted() const { return ref_frames.primary == ReferenceFrameType::None; }
- bool is_single_reference() const { return ref_frames.secondary == ReferenceFrameType::None; }
- MotionVectorPair primary_motion_vector_pair() const { return sub_block_motion_vectors[3]; }
-
- bool is_available { false };
- bool skip_coefficients { false };
- TXSize tx_size { TXSize::TX_4x4 };
- PredictionMode y_mode { PredictionMode::DcPred };
- Array<PredictionMode, 4> sub_modes { PredictionMode::DcPred, PredictionMode::DcPred, PredictionMode::DcPred, PredictionMode::DcPred };
- InterpolationFilter interpolation_filter { InterpolationFilter::EightTap };
- ReferenceFramePair ref_frames { ReferenceFrameType::None, ReferenceFrameType::None };
- Array<MotionVectorPair, 4> sub_block_motion_vectors;
- u8 segment_id { 0 };
-};
-
-// Block context that is kept between frames until explictly cleared.
-struct PersistentBlockContext {
- PersistentBlockContext()
- : available(false)
- {
- }
-
- PersistentBlockContext(FrameBlockContext const& frame_context)
- : available(frame_context.is_available)
- , ref_frames(frame_context.ref_frames)
- , primary_motion_vector_pair(frame_context.primary_motion_vector_pair())
- , segment_id(frame_context.segment_id)
- {
- }
-
- bool available { false };
- ReferenceFramePair ref_frames { ReferenceFrameType::None, ReferenceFrameType::None };
- MotionVectorPair primary_motion_vector_pair {};
- u8 segment_id { 0 };
-};
-
enum class FrameShowMode {
CreateAndShowNewFrame,
ShowExistingFrame,
DoNotShowFrame,
};
-struct ColorConfig {
- u8 bit_depth { 8 };
- ColorSpace color_space { ColorSpace::Bt601 };
- ColorRange color_range { ColorRange::Studio };
- bool subsampling_x { true };
- bool subsampling_y { true };
-};
-
-struct SegmentFeature {
- bool enabled { false };
- u8 value { 0 };
-};
-
struct FrameContext {
public:
FrameContext(Vector2D<FrameBlockContext>& contexts)
@@ -445,8 +211,6 @@ struct BlockMotionVectorCandidateSet {
MotionVector best_vector;
};
-using BlockMotionVectorCandidates = ReferencePair<BlockMotionVectorCandidateSet>;
-
struct MotionVectorCandidate {
ReferenceFrameType type;
MotionVector vector;
diff --git a/Userland/Libraries/LibVideo/VP9/ContextStorage.h b/Userland/Libraries/LibVideo/VP9/ContextStorage.h
new file mode 100644
index 0000000000..30156f5f60
--- /dev/null
+++ b/Userland/Libraries/LibVideo/VP9/ContextStorage.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
+ * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Array.h>
+#include <AK/Error.h>
+#include <LibGfx/Size.h>
+#include <LibVideo/Color/CodingIndependentCodePoints.h>
+
+#include "Enums.h"
+#include "LookupTables.h"
+#include "MotionVector.h"
+
+namespace Video::VP9 {
+
+template<typename T>
+struct ReferencePair {
+ T primary;
+ T secondary;
+
+ T& operator[](ReferenceIndex index)
+ {
+ switch (index) {
+ case ReferenceIndex::Primary:
+ return primary;
+ case ReferenceIndex::Secondary:
+ return secondary;
+ default:
+ VERIFY_NOT_REACHED();
+ }
+ }
+
+ T const& operator[](ReferenceIndex index) const
+ {
+ return const_cast<ReferencePair<T>&>(*this)[index];
+ }
+};
+
+typedef ReferencePair<ReferenceFrameType> ReferenceFramePair;
+typedef ReferencePair<MotionVector> MotionVectorPair;
+
+template<typename T>
+class Vector2D;
+
+template<typename T>
+class Vector2DView {
+public:
+ u32 top() const { return m_top; }
+ u32 left() const { return m_left; }
+ u32 height() const { return m_height; }
+ u32 width() const { return m_width; }
+
+ T const& operator[](size_t index) const { return m_storage[index]; }
+ size_t size() const { return m_storage->size(); }
+
+ T& at(u32 relative_row, u32 relative_column)
+ {
+ VERIFY(relative_row < height());
+ VERIFY(relative_column < width());
+ return m_storage->at(top() + relative_row, left() + relative_column);
+ }
+ T const& at(u32 relative_row, u32 relative_column) const
+ {
+ VERIFY(relative_row < height());
+ VERIFY(relative_column < width());
+ return m_storage->at(top() + relative_row, left() + relative_column);
+ }
+
+ Vector2DView<T> view(u32 top, u32 left, u32 height, u32 width)
+ {
+ VERIFY(top + height <= this->height());
+ VERIFY(left + width <= this->width());
+ return Vector2DView<T>(m_storage, this->top() + top, this->left() + left, height, width);
+ }
+
+private:
+ friend class Vector2D<T>;
+
+ Vector2DView(Vector2D<T>* const storage, u32 top, u32 left, u32 height, u32 width)
+ : m_storage(storage)
+ , m_top(top)
+ , m_left(left)
+ , m_height(height)
+ , m_width(width)
+ {
+ }
+
+ Vector2D<T>* const m_storage;
+ u32 const m_top { 0 };
+ u32 const m_left { 0 };
+ u32 const m_height { 0 };
+ u32 const m_width { 0 };
+};
+
+template<typename T>
+class Vector2D {
+public:
+ ~Vector2D()
+ {
+ if (m_storage)
+ free(m_storage);
+ m_storage = nullptr;
+ m_width = 0;
+ m_height = 0;
+ }
+
+ ErrorOr<void> try_resize(u32 height, u32 width)
+ {
+ if (height != m_height && width != m_width) {
+ this->~Vector2D();
+ size_t size = height * width;
+ auto* new_storage = static_cast<T*>(malloc(size * sizeof(T)));
+ if (!new_storage)
+ return Error::from_errno(ENOMEM);
+ m_storage = new_storage;
+ m_height = height;
+ m_width = width;
+ }
+
+ return {};
+ }
+
+ u32 height() const { return m_height; }
+ u32 width() const { return m_width; }
+
+ size_t index_at(u32 row, u32 column) const
+ {
+ VERIFY(row < height());
+ VERIFY(column < width());
+ return row * width() + column;
+ }
+
+ T& operator[](size_t index) { return m_storage[index]; }
+ T const& operator[](size_t index) const { return m_storage[index]; }
+ size_t size() const { return m_height * m_width; }
+
+ T& at(u32 row, u32 column)
+ {
+ return m_storage[index_at(row, column)];
+ }
+ T const& at(u32 row, u32 column) const
+ {
+ return m_storage[index_at(row, column)];
+ }
+
+ template<typename OtherT, typename Function>
+ void copy_to(Vector2D<OtherT>& other, Function function) const
+ {
+ VERIFY(width() <= other.width());
+ VERIFY(height() <= other.height());
+ for (u32 row = 0; row < height(); row++) {
+ for (u32 column = 0; column < width(); column++)
+ other.at(row, column) = function(at(row, column));
+ }
+ }
+
+ void copy_to(Vector2D<T>& other) const
+ {
+ VERIFY(width() <= other.width());
+ VERIFY(height() <= other.height());
+ for (u32 row = 0; row < height(); row++) {
+ auto other_index = other.index_at(row, 0);
+ AK::TypedTransfer<T>::copy(&m_storage[index_at(row, 0)], &other[other_index], width());
+ }
+ }
+
+ template<typename OtherT>
+ ErrorOr<void> try_resize_to_match_other_vector2d(Vector2D<OtherT> const& other)
+ {
+ return try_resize(other.height(), other.width());
+ }
+
+ void reset()
+ {
+ for (size_t i = 0; i < size(); i++)
+ m_storage[i] = T();
+ }
+
+ Vector2DView<T> view(u32 top, u32 left, u32 height, u32 width)
+ {
+ VERIFY(top + height <= this->height());
+ VERIFY(left + width <= this->width());
+ return Vector2DView<T>(this, top, left, height, width);
+ }
+
+private:
+ u32 m_height { 0 };
+ u32 m_width { 0 };
+ T* m_storage { nullptr };
+};
+
+// Block context that is kept for the lifetime of a frame.
+struct FrameBlockContext {
+ bool is_intra_predicted() const { return ref_frames.primary == ReferenceFrameType::None; }
+ bool is_single_reference() const { return ref_frames.secondary == ReferenceFrameType::None; }
+ MotionVectorPair primary_motion_vector_pair() const { return sub_block_motion_vectors[3]; }
+
+ bool is_available { false };
+ bool skip_coefficients { false };
+ TXSize tx_size { TXSize::TX_4x4 };
+ PredictionMode y_mode { PredictionMode::DcPred };
+ Array<PredictionMode, 4> sub_modes { PredictionMode::DcPred, PredictionMode::DcPred, PredictionMode::DcPred, PredictionMode::DcPred };
+ InterpolationFilter interpolation_filter { InterpolationFilter::EightTap };
+ ReferenceFramePair ref_frames { ReferenceFrameType::None, ReferenceFrameType::None };
+ Array<MotionVectorPair, 4> sub_block_motion_vectors;
+ u8 segment_id { 0 };
+};
+
+// Block context that is kept between frames until explictly cleared.
+struct PersistentBlockContext {
+ PersistentBlockContext()
+ : available(false)
+ {
+ }
+
+ PersistentBlockContext(FrameBlockContext const& frame_context)
+ : available(frame_context.is_available)
+ , ref_frames(frame_context.ref_frames)
+ , primary_motion_vector_pair(frame_context.primary_motion_vector_pair())
+ , segment_id(frame_context.segment_id)
+ {
+ }
+
+ bool available { false };
+ ReferenceFramePair ref_frames { ReferenceFrameType::None, ReferenceFrameType::None };
+ MotionVectorPair primary_motion_vector_pair {};
+ u8 segment_id { 0 };
+};
+
+struct SegmentFeature {
+ bool enabled { false };
+ u8 value { 0 };
+};
+
+struct ColorConfig {
+ u8 bit_depth { 8 };
+ ColorSpace color_space { ColorSpace::Bt601 };
+ ColorRange color_range { ColorRange::Studio };
+ bool subsampling_x { true };
+ bool subsampling_y { true };
+};
+
+struct BlockMotionVectorCandidateSet;
+using BlockMotionVectorCandidates = ReferencePair<BlockMotionVectorCandidateSet>;
+
+}
diff --git a/Userland/Libraries/LibVideo/VP9/Decoder.cpp b/Userland/Libraries/LibVideo/VP9/Decoder.cpp
index 252618254b..c0fe2c4cd5 100644
--- a/Userland/Libraries/LibVideo/VP9/Decoder.cpp
+++ b/Userland/Libraries/LibVideo/VP9/Decoder.cpp
@@ -9,6 +9,7 @@
#include <LibGfx/Size.h>
#include <LibVideo/Color/CodingIndependentCodePoints.h>
+#include "Context.h"
#include "Decoder.h"
#include "Utilities.h"
diff --git a/Userland/Libraries/LibVideo/VP9/Parser.cpp b/Userland/Libraries/LibVideo/VP9/Parser.cpp
index ca31c6731a..374cea9fb0 100644
--- a/Userland/Libraries/LibVideo/VP9/Parser.cpp
+++ b/Userland/Libraries/LibVideo/VP9/Parser.cpp
@@ -9,6 +9,7 @@
#include <LibGfx/Point.h>
#include <LibGfx/Size.h>
+#include "Context.h"
#include "Decoder.h"
#include "Parser.h"
#include "Utilities.h"
diff --git a/Userland/Libraries/LibVideo/VP9/Parser.h b/Userland/Libraries/LibVideo/VP9/Parser.h
index 3dc86578d1..47db261b1a 100644
--- a/Userland/Libraries/LibVideo/VP9/Parser.h
+++ b/Userland/Libraries/LibVideo/VP9/Parser.h
@@ -16,7 +16,7 @@
#include <LibVideo/DecoderError.h>
#include "BitStream.h"
-#include "Context.h"
+#include "ContextStorage.h"
#include "LookupTables.h"
#include "MotionVector.h"
#include "ProbabilityTables.h"
@@ -27,6 +27,11 @@ namespace Video::VP9 {
class Decoder;
+struct FrameContext;
+struct TileContext;
+struct BlockContext;
+struct MotionVectorCandidate;
+
class Parser {
friend class TreeParser;
friend class Decoder;
diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.h b/Userland/Libraries/LibVideo/VP9/TreeParser.h
index 4002402a69..02400bd093 100644
--- a/Userland/Libraries/LibVideo/VP9/TreeParser.h
+++ b/Userland/Libraries/LibVideo/VP9/TreeParser.h
@@ -8,7 +8,7 @@
#pragma once
#include "BitStream.h"
-#include "Context.h"
+#include "ContextStorage.h"
#include "Enums.h"
#include "ProbabilityTables.h"
#include "SyntaxElementCounter.h"
@@ -17,6 +17,16 @@ namespace Video::VP9 {
class Parser;
+struct FrameBlockContext;
+
+struct TokensContext {
+ TXSize m_tx_size;
+ bool m_is_uv_plane;
+ bool m_is_inter;
+ u8 m_band;
+ u8 m_context_index;
+};
+
class TreeParser {
public:
// FIXME: Move or remove this class once it is unused in the header.