Context.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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/BitStream.h>
  10. #include <AK/Error.h>
  11. #include <AK/FixedArray.h>
  12. #include <AK/MemoryStream.h>
  13. #include <LibGfx/Size.h>
  14. #include <LibVideo/Color/CodingIndependentCodePoints.h>
  15. #include <LibVideo/DecoderError.h>
  16. #include "BooleanDecoder.h"
  17. #include "ContextStorage.h"
  18. #include "Enums.h"
  19. #include "LookupTables.h"
  20. #include "MotionVector.h"
  21. #include "SyntaxElementCounter.h"
  22. #include "Utilities.h"
  23. namespace Video::VP9 {
  24. enum class FrameShowMode {
  25. CreateAndShowNewFrame,
  26. ShowExistingFrame,
  27. DoNotShowFrame,
  28. };
  29. struct Quantizers {
  30. u16 y_ac_quantizer { 0 };
  31. u16 uv_ac_quantizer { 0 };
  32. u16 y_dc_quantizer { 0 };
  33. u16 uv_dc_quantizer { 0 };
  34. };
  35. struct FrameContext {
  36. public:
  37. static ErrorOr<FrameContext> create(ReadonlyBytes data,
  38. Vector2D<FrameBlockContext>& contexts)
  39. {
  40. return FrameContext(
  41. data,
  42. TRY(try_make<FixedMemoryStream>(data)),
  43. TRY(try_make<SyntaxElementCounter>()),
  44. contexts);
  45. }
  46. FrameContext(FrameContext const&) = delete;
  47. FrameContext(FrameContext&&) = default;
  48. ReadonlyBytes stream_data;
  49. NonnullOwnPtr<FixedMemoryStream> stream;
  50. BigEndianInputBitStream bit_stream;
  51. DecoderErrorOr<BooleanDecoder> create_range_decoder(size_t size)
  52. {
  53. if (size > stream->remaining())
  54. return DecoderError::corrupted("Range decoder size invalid"sv);
  55. auto compressed_header_data = ReadonlyBytes(stream_data.data() + stream->offset(), size);
  56. // 9.2.1: The Boolean decoding process specified in section 9.2.2 is invoked to read a marker syntax element from the
  57. // bitstream. It is a requirement of bitstream conformance that the value read is equal to 0.
  58. auto decoder = DECODER_TRY(DecoderErrorCategory::Corrupted, BooleanDecoder::initialize(compressed_header_data));
  59. if (decoder.read_bool(128))
  60. return DecoderError::corrupted("Range decoder marker was non-zero"sv);
  61. DECODER_TRY(DecoderErrorCategory::Corrupted, bit_stream.discard(size));
  62. return decoder;
  63. }
  64. NonnullOwnPtr<SyntaxElementCounter> counter;
  65. u8 profile { 0 };
  66. FrameType type { FrameType::KeyFrame };
  67. bool is_inter_predicted() const { return type == FrameType::InterFrame; }
  68. bool error_resilient_mode { false };
  69. bool parallel_decoding_mode { false };
  70. bool should_replace_probability_context { false };
  71. bool shows_a_frame() const { return m_frame_show_mode != FrameShowMode::DoNotShowFrame; }
  72. bool shows_a_new_frame() const { return m_frame_show_mode == FrameShowMode::CreateAndShowNewFrame; }
  73. bool shows_existing_frame() const { return m_frame_show_mode == FrameShowMode::ShowExistingFrame; }
  74. void set_frame_hidden() { m_frame_show_mode = FrameShowMode::DoNotShowFrame; }
  75. void set_existing_frame_to_show(u8 index)
  76. {
  77. m_frame_show_mode = FrameShowMode::ShowExistingFrame;
  78. m_existing_frame_index = index;
  79. }
  80. u8 existing_frame_index() const { return m_existing_frame_index; }
  81. bool use_previous_frame_motion_vectors { false };
  82. ColorConfig color_config {};
  83. u8 reference_frames_to_update_flags { 0 };
  84. bool should_update_reference_frame_at_index(u8 index) const { return (reference_frames_to_update_flags & (1 << index)) != 0; }
  85. u8 probability_context_index { 0 };
  86. Gfx::Size<u32> size() const { return m_size; }
  87. ErrorOr<void> set_size(Gfx::Size<u32> size)
  88. {
  89. m_size = size;
  90. // From spec, compute_image_size( )
  91. m_rows = pixels_to_blocks(size.height() + 7u);
  92. m_columns = pixels_to_blocks(size.width() + 7u);
  93. return m_block_contexts.try_resize(m_rows, m_columns);
  94. }
  95. u32 rows() const { return m_rows; }
  96. u32 columns() const { return m_columns; }
  97. u32 superblock_rows() const { return blocks_ceiled_to_superblocks(rows()); }
  98. u32 superblock_columns() const { return blocks_ceiled_to_superblocks(columns()); }
  99. // Calculates the output size for each plane in the frame.
  100. Gfx::Size<u32> decoded_size(bool uv) const
  101. {
  102. if (uv) {
  103. return {
  104. y_size_to_uv_size(color_config.subsampling_y, blocks_to_pixels(columns())),
  105. y_size_to_uv_size(color_config.subsampling_y, blocks_to_pixels(rows())),
  106. };
  107. }
  108. return {
  109. blocks_to_pixels(columns()),
  110. blocks_to_pixels(rows()),
  111. };
  112. }
  113. Vector2D<FrameBlockContext> const& block_contexts() const { return m_block_contexts; }
  114. Gfx::Size<u32> render_size { 0, 0 };
  115. Gfx::Size<u16> log2_of_tile_counts { 0, 0 };
  116. // This group of fields is only needed for inter-predicted frames.
  117. Array<u8, 3> reference_frame_indices;
  118. Array<bool, ReferenceFrameType::LastFrame + 3> reference_frame_sign_biases;
  119. bool high_precision_motion_vectors_allowed { false };
  120. InterpolationFilter interpolation_filter { InterpolationFilter::Switchable };
  121. u8 loop_filter_level { 0 };
  122. u8 loop_filter_sharpness { 0 };
  123. bool loop_filter_delta_enabled { false };
  124. Array<i8, MAX_REF_FRAMES> loop_filter_reference_deltas;
  125. Array<i8, 2> loop_filter_mode_deltas;
  126. // Set based on quantization_params( ) in the spec.
  127. bool lossless { false };
  128. Array<Quantizers, MAX_SEGMENTS> segment_quantizers;
  129. bool segmentation_enabled { false };
  130. // Note: We can use Optional<Array<...>> for these tree probabilities, but unfortunately it seems to have measurable performance overhead.
  131. bool use_full_segment_id_tree { false };
  132. Array<u8, 7> full_segment_id_tree_probabilities;
  133. bool use_predicted_segment_id_tree { false };
  134. Array<u8, 3> predicted_segment_id_tree_probabilities;
  135. bool should_use_absolute_segment_base_quantizer { false };
  136. SegmentationFeatures segmentation_features;
  137. SegmentFeatureStatus get_segment_feature(u8 segment_id, SegmentFeature feature) const
  138. {
  139. return segmentation_features[segment_id][to_underlying(feature)];
  140. }
  141. u16 header_size_in_bytes { 0 };
  142. TransformMode transform_mode;
  143. // This group also is only needed for inter-predicted frames.
  144. ReferenceMode reference_mode;
  145. ReferenceFrameType fixed_reference_type;
  146. ReferenceFramePair variable_reference_types;
  147. private:
  148. friend struct TileContext;
  149. FrameContext(ReadonlyBytes data,
  150. NonnullOwnPtr<FixedMemoryStream> stream,
  151. NonnullOwnPtr<SyntaxElementCounter> counter,
  152. Vector2D<FrameBlockContext>& contexts)
  153. : stream_data(data)
  154. , stream(move(stream))
  155. , bit_stream(MaybeOwned<Stream>(*this->stream))
  156. , counter(move(counter))
  157. , m_block_contexts(contexts)
  158. {
  159. }
  160. FrameShowMode m_frame_show_mode { FrameShowMode::CreateAndShowNewFrame };
  161. u8 m_existing_frame_index { 0 };
  162. Gfx::Size<u32> m_size { 0, 0 };
  163. u32 m_rows { 0 };
  164. u32 m_columns { 0 };
  165. // FIXME: From spec: NOTE – We are using a 2D array to store the SubModes for clarity. It is possible to reduce memory
  166. // consumption by only storing one intra mode for each 8x8 horizontal and vertical position, i.e. to use two 1D
  167. // arrays instead.
  168. // I think should also apply to other fields that are only accessed relative to the current block. Worth looking
  169. // into how much of this context needs to be stored for the whole frame vs a row or column from the current tile.
  170. Vector2D<FrameBlockContext>& m_block_contexts;
  171. };
  172. static ErrorOr<NonZeroTokens> create_non_zero_tokens(u32 size_in_sub_blocks, bool subsampling)
  173. {
  174. return NonZeroTokens {
  175. TRY(FixedArray<bool>::create(size_in_sub_blocks)),
  176. TRY(FixedArray<bool>::create(size_in_sub_blocks >>= subsampling)),
  177. TRY(FixedArray<bool>::create(size_in_sub_blocks)),
  178. };
  179. }
  180. template<typename T>
  181. static Span<T> safe_slice(Span<T> span, u32 start, u32 size)
  182. {
  183. return span.slice(start, min(size, span.size() - start));
  184. }
  185. static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokensView non_zero_tokens, u32 start_in_sub_blocks, u32 size_in_sub_blocks, bool subsampling)
  186. {
  187. NonZeroTokensView result;
  188. // Y plane
  189. result[0] = safe_slice(non_zero_tokens[0], start_in_sub_blocks, size_in_sub_blocks);
  190. // UV planes
  191. start_in_sub_blocks >>= subsampling;
  192. size_in_sub_blocks >>= subsampling;
  193. result[1] = safe_slice(non_zero_tokens[1], start_in_sub_blocks, size_in_sub_blocks);
  194. result[2] = safe_slice(non_zero_tokens[2], start_in_sub_blocks, size_in_sub_blocks);
  195. return result;
  196. }
  197. static NonZeroTokensView create_non_zero_tokens_view(NonZeroTokens& non_zero_tokens, u32 start_in_sub_blocks, u32 size_in_sub_blocks, bool subsampling)
  198. {
  199. return create_non_zero_tokens_view({ non_zero_tokens[0].span(), non_zero_tokens[1].span(), non_zero_tokens[2].span() }, start_in_sub_blocks, size_in_sub_blocks, subsampling);
  200. }
  201. struct TileContext {
  202. public:
  203. static DecoderErrorOr<TileContext> try_create(FrameContext& frame_context, u32 tile_size, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end, PartitionContextView above_partition_context, NonZeroTokensView above_non_zero_tokens, SegmentationPredictionContextView above_segmentation_ids)
  204. {
  205. auto width = columns_end - columns_start;
  206. auto height = rows_end - rows_start;
  207. auto context_view = frame_context.m_block_contexts.view(rows_start, columns_start, height, width);
  208. return TileContext {
  209. frame_context,
  210. TRY(frame_context.create_range_decoder(tile_size)),
  211. DECODER_TRY_ALLOC(try_make<SyntaxElementCounter>()),
  212. rows_start,
  213. rows_end,
  214. columns_start,
  215. columns_end,
  216. context_view,
  217. above_partition_context,
  218. above_non_zero_tokens,
  219. above_segmentation_ids,
  220. DECODER_TRY_ALLOC(PartitionContext::create(superblocks_to_blocks(blocks_ceiled_to_superblocks(height)))),
  221. DECODER_TRY_ALLOC(create_non_zero_tokens(blocks_to_sub_blocks(height), frame_context.color_config.subsampling_y)),
  222. DECODER_TRY_ALLOC(SegmentationPredictionContext::create(height)),
  223. };
  224. }
  225. Vector2D<FrameBlockContext> const& frame_block_contexts() const { return frame_context.block_contexts(); }
  226. FrameContext const& frame_context;
  227. BooleanDecoder decoder;
  228. NonnullOwnPtr<SyntaxElementCounter> counter;
  229. u32 rows_start { 0 };
  230. u32 rows_end { 0 };
  231. u32 columns_start { 0 };
  232. u32 columns_end { 0 };
  233. u32 rows() const { return rows_end - rows_start; }
  234. u32 columns() const { return columns_end - columns_start; }
  235. Vector2DView<FrameBlockContext> block_contexts_view;
  236. PartitionContextView above_partition_context;
  237. NonZeroTokensView above_non_zero_tokens;
  238. SegmentationPredictionContextView above_segmentation_ids;
  239. PartitionContext left_partition_context;
  240. NonZeroTokens left_non_zero_tokens;
  241. SegmentationPredictionContext left_segmentation_ids;
  242. };
  243. struct BlockContext {
  244. static BlockContext create(TileContext& tile_context, u32 row, u32 column, BlockSubsize size)
  245. {
  246. auto contexts_view = tile_context.block_contexts_view.view(
  247. row - tile_context.rows_start,
  248. column - tile_context.columns_start,
  249. min<u32>(num_8x8_blocks_high_lookup[size], tile_context.frame_context.rows() - row),
  250. min<u32>(num_8x8_blocks_wide_lookup[size], tile_context.frame_context.columns() - column));
  251. auto size_in_blocks = block_size_to_blocks(size);
  252. auto size_in_sub_blocks = block_size_to_sub_blocks(get_subsampled_block_size(size, false, false));
  253. return BlockContext {
  254. .frame_context = tile_context.frame_context,
  255. .tile_context = tile_context,
  256. .decoder = tile_context.decoder,
  257. .counter = *tile_context.counter,
  258. .row = row,
  259. .column = column,
  260. .size = size,
  261. .contexts_view = contexts_view,
  262. .above_non_zero_tokens = create_non_zero_tokens_view(tile_context.above_non_zero_tokens, blocks_to_sub_blocks(column - tile_context.columns_start), size_in_sub_blocks.width(), tile_context.frame_context.color_config.subsampling_x),
  263. .above_segmentation_ids = safe_slice(tile_context.above_segmentation_ids, column - tile_context.columns_start, size_in_blocks.width()),
  264. .left_non_zero_tokens = create_non_zero_tokens_view(tile_context.left_non_zero_tokens, blocks_to_sub_blocks(row - tile_context.rows_start), size_in_sub_blocks.height(), tile_context.frame_context.color_config.subsampling_y),
  265. .left_segmentation_ids = safe_slice(tile_context.left_segmentation_ids.span(), row - tile_context.rows_start, size_in_blocks.height()),
  266. };
  267. }
  268. Vector2D<FrameBlockContext> const& frame_block_contexts() const { return frame_context.block_contexts(); }
  269. FrameContext const& frame_context;
  270. TileContext const& tile_context;
  271. BooleanDecoder& decoder;
  272. SyntaxElementCounter& counter;
  273. u32 row { 0 };
  274. u32 column { 0 };
  275. BlockSubsize size;
  276. Gfx::Size<u8> get_size_in_sub_blocks() const
  277. {
  278. return block_size_to_sub_blocks(size);
  279. }
  280. Vector2DView<FrameBlockContext> contexts_view;
  281. u8 segment_id { 0 };
  282. bool should_skip_residuals { false };
  283. TransformSize transform_size { Transform_4x4 };
  284. ReferenceFramePair reference_frame_types {};
  285. bool is_inter_predicted() const { return reference_frame_types.primary != ReferenceFrameType::None; }
  286. bool is_compound() const { return reference_frame_types.secondary != ReferenceFrameType::None; }
  287. Array<PredictionMode, 4> sub_block_prediction_modes {};
  288. PredictionMode y_prediction_mode() const { return sub_block_prediction_modes.last(); }
  289. PredictionMode& y_prediction_mode() { return sub_block_prediction_modes.last(); }
  290. PredictionMode uv_prediction_mode { 0 };
  291. InterpolationFilter interpolation_filter { EightTap };
  292. Array<MotionVectorPair, 4> sub_block_motion_vectors {};
  293. Array<i32, 1024> residual_tokens {};
  294. // Indexed by ReferenceFrame enum.
  295. Array<u8, 4> mode_context {};
  296. NonZeroTokensView above_non_zero_tokens;
  297. SegmentationPredictionContextView above_segmentation_ids;
  298. NonZeroTokensView left_non_zero_tokens;
  299. SegmentationPredictionContextView left_segmentation_ids;
  300. SegmentFeatureStatus get_segment_feature(SegmentFeature feature) const
  301. {
  302. return frame_context.get_segment_feature(segment_id, feature);
  303. }
  304. };
  305. struct BlockMotionVectorCandidateSet {
  306. MotionVector near_vector;
  307. MotionVector nearest_vector;
  308. MotionVector best_vector;
  309. };
  310. struct MotionVectorCandidate {
  311. ReferenceFrameType type;
  312. MotionVector vector;
  313. };
  314. }