ContextStorage.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  3. * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Array.h>
  9. #include <AK/Error.h>
  10. #include <AK/Vector.h>
  11. #include <LibGfx/Size.h>
  12. #include <LibVideo/Color/CodingIndependentCodePoints.h>
  13. #include "Enums.h"
  14. #include "LookupTables.h"
  15. #include "MotionVector.h"
  16. namespace Video::VP9 {
  17. template<typename T>
  18. struct ReferencePair {
  19. T primary;
  20. T secondary;
  21. T& operator[](ReferenceIndex index)
  22. {
  23. switch (index) {
  24. case ReferenceIndex::Primary:
  25. return primary;
  26. case ReferenceIndex::Secondary:
  27. return secondary;
  28. default:
  29. VERIFY_NOT_REACHED();
  30. }
  31. }
  32. T const& operator[](ReferenceIndex index) const
  33. {
  34. return const_cast<ReferencePair<T>&>(*this)[index];
  35. }
  36. };
  37. typedef ReferencePair<ReferenceFrameType> ReferenceFramePair;
  38. typedef ReferencePair<MotionVector> MotionVectorPair;
  39. template<typename T>
  40. class Vector2D;
  41. template<typename T>
  42. class Vector2DView {
  43. public:
  44. u32 top() const { return m_top; }
  45. u32 left() const { return m_left; }
  46. u32 height() const { return m_height; }
  47. u32 width() const { return m_width; }
  48. T const& operator[](size_t index) const { return m_storage[index]; }
  49. size_t size() const { return m_storage->size(); }
  50. T& at(u32 relative_row, u32 relative_column)
  51. {
  52. VERIFY(relative_row < height());
  53. VERIFY(relative_column < width());
  54. return m_storage->at(top() + relative_row, left() + relative_column);
  55. }
  56. T const& at(u32 relative_row, u32 relative_column) const
  57. {
  58. VERIFY(relative_row < height());
  59. VERIFY(relative_column < width());
  60. return m_storage->at(top() + relative_row, left() + relative_column);
  61. }
  62. Vector2DView<T> view(u32 top, u32 left, u32 height, u32 width)
  63. {
  64. VERIFY(top + height <= this->height());
  65. VERIFY(left + width <= this->width());
  66. return Vector2DView<T>(m_storage, this->top() + top, this->left() + left, height, width);
  67. }
  68. private:
  69. friend class Vector2D<T>;
  70. Vector2DView(Vector2D<T>* const storage, u32 top, u32 left, u32 height, u32 width)
  71. : m_storage(storage)
  72. , m_top(top)
  73. , m_left(left)
  74. , m_height(height)
  75. , m_width(width)
  76. {
  77. }
  78. Vector2D<T>* const m_storage;
  79. u32 const m_top { 0 };
  80. u32 const m_left { 0 };
  81. u32 const m_height { 0 };
  82. u32 const m_width { 0 };
  83. };
  84. template<typename T>
  85. class Vector2D {
  86. public:
  87. ~Vector2D()
  88. {
  89. clear_storage();
  90. }
  91. ErrorOr<void> try_resize(u32 height, u32 width)
  92. {
  93. if (height != m_height && width != m_width) {
  94. clear_storage();
  95. size_t size = height * width;
  96. auto* new_storage = new (nothrow) T[size];
  97. if (!new_storage)
  98. return Error::from_errno(ENOMEM);
  99. m_storage = new_storage;
  100. m_height = height;
  101. m_width = width;
  102. }
  103. return {};
  104. }
  105. u32 height() const { return m_height; }
  106. u32 width() const { return m_width; }
  107. size_t index_at(u32 row, u32 column) const
  108. {
  109. VERIFY(row < height());
  110. VERIFY(column < width());
  111. return row * width() + column;
  112. }
  113. T& operator[](size_t index) { return m_storage[index]; }
  114. T const& operator[](size_t index) const { return m_storage[index]; }
  115. size_t size() const { return m_height * m_width; }
  116. T& at(u32 row, u32 column)
  117. {
  118. return m_storage[index_at(row, column)];
  119. }
  120. T const& at(u32 row, u32 column) const
  121. {
  122. return m_storage[index_at(row, column)];
  123. }
  124. void assign(u32 row, u32 column, T&& value)
  125. {
  126. new (&m_storage[index_at(row, column)]) T(move(value));
  127. }
  128. template<typename OtherT, typename Function>
  129. void copy_to(Vector2D<OtherT>& other, Function function) const
  130. {
  131. VERIFY(width() <= other.width());
  132. VERIFY(height() <= other.height());
  133. for (u32 row = 0; row < height(); row++) {
  134. for (u32 column = 0; column < width(); column++)
  135. other.at(row, column) = function(at(row, column));
  136. }
  137. }
  138. void copy_to(Vector2D<T>& other) const
  139. {
  140. VERIFY(width() <= other.width());
  141. VERIFY(height() <= other.height());
  142. for (u32 row = 0; row < height(); row++) {
  143. auto other_index = other.index_at(row, 0);
  144. AK::TypedTransfer<T>::copy(&m_storage[index_at(row, 0)], &other[other_index], width());
  145. }
  146. }
  147. template<typename OtherT>
  148. ErrorOr<void> try_resize_to_match_other_vector2d(Vector2D<OtherT> const& other)
  149. {
  150. return try_resize(other.height(), other.width());
  151. }
  152. void reset()
  153. {
  154. for (size_t i = 0; i < size(); i++)
  155. m_storage[i] = T();
  156. }
  157. Vector2DView<T> view(u32 top, u32 left, u32 height, u32 width)
  158. {
  159. VERIFY(top + height <= this->height());
  160. VERIFY(left + width <= this->width());
  161. return Vector2DView<T>(this, top, left, height, width);
  162. }
  163. private:
  164. void clear_storage()
  165. {
  166. delete[] m_storage;
  167. m_storage = nullptr;
  168. m_width = 0;
  169. m_height = 0;
  170. }
  171. u32 m_height { 0 };
  172. u32 m_width { 0 };
  173. T* m_storage { nullptr };
  174. };
  175. // Block context that is kept for the lifetime of a frame.
  176. struct FrameBlockContext {
  177. bool is_intra_predicted() const { return ref_frames.primary == ReferenceFrameType::None; }
  178. bool is_single_reference() const { return ref_frames.secondary == ReferenceFrameType::None; }
  179. MotionVectorPair primary_motion_vector_pair() const { return sub_block_motion_vectors[3]; }
  180. bool is_available { false };
  181. bool skip_coefficients { false };
  182. TransformSize transform_size { Transform_4x4 };
  183. PredictionMode y_mode { PredictionMode::DcPred };
  184. Array<PredictionMode, 4> sub_modes { PredictionMode::DcPred, PredictionMode::DcPred, PredictionMode::DcPred, PredictionMode::DcPred };
  185. InterpolationFilter interpolation_filter { InterpolationFilter::EightTap };
  186. ReferenceFramePair ref_frames { ReferenceFrameType::None, ReferenceFrameType::None };
  187. Array<MotionVectorPair, 4> sub_block_motion_vectors;
  188. u8 segment_id { 0 };
  189. };
  190. // Block context that is kept between frames until explicitly cleared.
  191. struct PersistentBlockContext {
  192. PersistentBlockContext()
  193. : available(false)
  194. {
  195. }
  196. PersistentBlockContext(FrameBlockContext const& frame_context)
  197. : available(frame_context.is_available)
  198. , ref_frames(frame_context.ref_frames)
  199. , primary_motion_vector_pair(frame_context.primary_motion_vector_pair())
  200. , segment_id(frame_context.segment_id)
  201. {
  202. }
  203. bool available { false };
  204. ReferenceFramePair ref_frames { ReferenceFrameType::None, ReferenceFrameType::None };
  205. MotionVectorPair primary_motion_vector_pair {};
  206. u8 segment_id { 0 };
  207. };
  208. struct SegmentFeatureStatus {
  209. bool enabled { false };
  210. u8 value { 0 };
  211. };
  212. using SegmentFeatures = Array<SegmentFeatureStatus, to_underlying(SegmentFeature::Sentinel)>;
  213. using SegmentationFeatures = Array<SegmentFeatures, MAX_SEGMENTS>;
  214. struct ColorConfig {
  215. u8 bit_depth { 8 };
  216. ColorSpace color_space { ColorSpace::Bt601 };
  217. VideoFullRangeFlag color_range { VideoFullRangeFlag::Studio };
  218. bool subsampling_x { true };
  219. bool subsampling_y { true };
  220. };
  221. struct BlockMotionVectorCandidateSet;
  222. using BlockMotionVectorCandidates = ReferencePair<BlockMotionVectorCandidateSet>;
  223. using NonZeroTokens = Array<FixedArray<bool>, 3>;
  224. using NonZeroTokensView = Array<Span<bool>, 3>;
  225. using SegmentationPredictionContext = FixedArray<u8>;
  226. using SegmentationPredictionContextView = Span<u8>;
  227. using PartitionContext = FixedArray<u8>;
  228. using PartitionContextView = Span<u8>;
  229. struct ReferenceFrame {
  230. Gfx::Size<u32> size { 0, 0 };
  231. bool subsampling_x { false };
  232. bool subsampling_y { false };
  233. u8 bit_depth { 0 };
  234. Array<Vector<u16>, 3> frame_planes {};
  235. bool is_valid() const { return bit_depth > 0; }
  236. // These values are set at the start of each inter frame to be used during prediction.
  237. i32 x_scale { 0 };
  238. i32 y_scale { 0 };
  239. i32 scaled_step_x { 0 };
  240. i32 scaled_step_y { 0 };
  241. };
  242. }