Context.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 <LibGfx/Size.h>
  11. #include <LibVideo/Color/CodingIndependentCodePoints.h>
  12. #include "ContextStorage.h"
  13. #include "Enums.h"
  14. #include "LookupTables.h"
  15. #include "MotionVector.h"
  16. #include "Utilities.h"
  17. namespace Video::VP9 {
  18. enum class FrameShowMode {
  19. CreateAndShowNewFrame,
  20. ShowExistingFrame,
  21. DoNotShowFrame,
  22. };
  23. struct FrameContext {
  24. public:
  25. FrameContext(Vector2D<FrameBlockContext>& contexts)
  26. : m_block_contexts(contexts)
  27. {
  28. }
  29. u8 profile { 0 };
  30. FrameType type { FrameType::KeyFrame };
  31. bool is_inter_predicted() const { return type == FrameType::InterFrame; }
  32. bool error_resilient_mode { false };
  33. bool parallel_decoding_mode { false };
  34. bool should_replace_probability_context { false };
  35. bool shows_a_frame() const { return m_frame_show_mode != FrameShowMode::DoNotShowFrame; }
  36. bool shows_a_new_frame() const { return m_frame_show_mode == FrameShowMode::CreateAndShowNewFrame; }
  37. bool shows_existing_frame() const { return m_frame_show_mode == FrameShowMode::ShowExistingFrame; }
  38. void set_frame_hidden() { m_frame_show_mode = FrameShowMode::DoNotShowFrame; }
  39. void set_existing_frame_to_show(u8 index)
  40. {
  41. m_frame_show_mode = FrameShowMode::ShowExistingFrame;
  42. m_existing_frame_index = index;
  43. }
  44. u8 existing_frame_index() const { return m_existing_frame_index; }
  45. ColorConfig color_config {};
  46. u8 reference_frames_to_update_flags { 0 };
  47. bool should_update_reference_frame_at_index(u8 index) const { return (reference_frames_to_update_flags & (1 << index)) != 0; }
  48. u8 probability_context_index { 0 };
  49. Gfx::Size<u32> size() const { return m_size; }
  50. ErrorOr<void> set_size(Gfx::Size<u32> size)
  51. {
  52. m_size = size;
  53. // From spec, compute_image_size( )
  54. m_rows = (size.height() + 7u) >> 3u;
  55. m_columns = (size.width() + 7u) >> 3u;
  56. return m_block_contexts.try_resize(m_rows, m_columns);
  57. }
  58. u32 rows() const { return m_rows; }
  59. u32 columns() const { return m_columns; }
  60. u32 superblock_rows() const { return (rows() + 7u) >> 3u; }
  61. u32 superblock_columns() const { return (columns() + 7u) >> 3u; }
  62. Vector2D<FrameBlockContext> const& block_contexts() const { return m_block_contexts; }
  63. Gfx::Size<u32> render_size { 0, 0 };
  64. Gfx::Size<u16> log2_of_tile_counts { 0, 0 };
  65. // This group of fields is only needed for inter-predicted frames.
  66. Array<u8, 3> reference_frame_indices;
  67. Array<bool, LastFrame + 3> reference_frame_sign_biases;
  68. bool high_precision_motion_vectors_allowed { false };
  69. InterpolationFilter interpolation_filter { InterpolationFilter::Switchable };
  70. u8 loop_filter_level { 0 };
  71. u8 loop_filter_sharpness { 0 };
  72. bool loop_filter_delta_enabled { false };
  73. Array<i8, MAX_REF_FRAMES> loop_filter_reference_deltas;
  74. Array<i8, 2> loop_filter_mode_deltas;
  75. u8 base_quantizer_index { 0 };
  76. i8 y_dc_quantizer_index_delta { 0 };
  77. i8 uv_dc_quantizer_index_delta { 0 };
  78. i8 uv_ac_quantizer_index_delta { 0 };
  79. bool is_lossless() const
  80. {
  81. // From quantization_params( ) in the spec.
  82. return base_quantizer_index == 0 && y_dc_quantizer_index_delta == 0 && uv_dc_quantizer_index_delta == 0 && uv_ac_quantizer_index_delta == 0;
  83. }
  84. bool segmentation_enabled { false };
  85. // Note: We can use Optional<Array<...>> for these tree probabilities, but unfortunately it seems to have measurable performance overhead.
  86. bool use_full_segment_id_tree { false };
  87. Array<u8, 7> full_segment_id_tree_probabilities;
  88. bool use_predicted_segment_id_tree { false };
  89. Array<u8, 3> predicted_segment_id_tree_probabilities;
  90. bool should_use_absolute_segment_base_quantizer { false };
  91. Array<Array<SegmentFeature, SEG_LVL_MAX>, MAX_SEGMENTS> segmentation_features;
  92. u16 header_size_in_bytes { 0 };
  93. TXMode transform_mode;
  94. // This group also is only needed for inter-predicted frames.
  95. ReferenceMode reference_mode;
  96. ReferenceFrameType fixed_reference_type;
  97. ReferenceFramePair variable_reference_types;
  98. private:
  99. friend struct TileContext;
  100. FrameShowMode m_frame_show_mode { FrameShowMode::CreateAndShowNewFrame };
  101. u8 m_existing_frame_index { 0 };
  102. Gfx::Size<u32> m_size { 0, 0 };
  103. u32 m_rows { 0 };
  104. u32 m_columns { 0 };
  105. // FIXME: From spec: NOTE – We are using a 2D array to store the SubModes for clarity. It is possible to reduce memory
  106. // consumption by only storing one intra mode for each 8x8 horizontal and vertical position, i.e. to use two 1D
  107. // arrays instead.
  108. // I think should also apply to other fields that are only accessed relative to the current block. Worth looking
  109. // into how much of this context needs to be stored for the whole frame vs a row or column from the current tile.
  110. Vector2D<FrameBlockContext>& m_block_contexts;
  111. };
  112. struct TileContext {
  113. public:
  114. TileContext(FrameContext& frame_context, u32 rows_start, u32 rows_end, u32 columns_start, u32 columns_end)
  115. : frame_context(frame_context)
  116. , rows_start(rows_start)
  117. , rows_end(rows_end)
  118. , columns_start(columns_start)
  119. , columns_end(columns_end)
  120. , block_contexts_view(frame_context.m_block_contexts.view(rows_start, columns_start, rows_end - rows_start, columns_end - columns_start))
  121. {
  122. }
  123. Vector2D<FrameBlockContext> const& frame_block_contexts() const { return frame_context.block_contexts(); }
  124. FrameContext const& frame_context;
  125. u32 rows_start { 0 };
  126. u32 rows_end { 0 };
  127. u32 columns_start { 0 };
  128. u32 columns_end { 0 };
  129. Vector2DView<FrameBlockContext> block_contexts_view;
  130. };
  131. struct BlockContext {
  132. BlockContext(TileContext& tile_context, u32 row, u32 column, BlockSubsize size)
  133. : frame_context(tile_context.frame_context)
  134. , tile_context(tile_context)
  135. , row(row)
  136. , column(column)
  137. , size(size)
  138. , contexts_view(tile_context.block_contexts_view.view(row - tile_context.rows_start, column - tile_context.columns_start,
  139. min<u32>(num_8x8_blocks_high_lookup[size], tile_context.frame_context.rows() - row),
  140. min<u32>(num_8x8_blocks_wide_lookup[size], tile_context.frame_context.columns() - column)))
  141. {
  142. }
  143. Vector2D<FrameBlockContext> const& frame_block_contexts() const { return frame_context.block_contexts(); }
  144. FrameContext const& frame_context;
  145. TileContext const& tile_context;
  146. u32 row { 0 };
  147. u32 column { 0 };
  148. BlockSubsize size;
  149. Gfx::Size<u8> get_size_in_sub_blocks() const
  150. {
  151. return block_size_to_sub_blocks(size);
  152. }
  153. Vector2DView<FrameBlockContext> contexts_view;
  154. u8 segment_id { 0 };
  155. bool should_skip_residuals { false };
  156. TXSize tx_size { TXSize::TX_4x4 };
  157. ReferenceFramePair reference_frame_types;
  158. bool is_inter_predicted() const { return reference_frame_types.primary != ReferenceFrameType::None; }
  159. bool is_compound() const { return reference_frame_types.secondary != ReferenceFrameType::None; }
  160. Array<PredictionMode, 4> sub_block_prediction_modes;
  161. PredictionMode y_prediction_mode() const { return sub_block_prediction_modes.last(); }
  162. PredictionMode& y_prediction_mode() { return sub_block_prediction_modes.last(); }
  163. PredictionMode uv_prediction_mode { 0 };
  164. InterpolationFilter interpolation_filter { EightTap };
  165. Array<MotionVectorPair, 4> sub_block_motion_vectors;
  166. };
  167. struct BlockMotionVectorCandidateSet {
  168. MotionVector near_vector;
  169. MotionVector nearest_vector;
  170. MotionVector best_vector;
  171. };
  172. struct MotionVectorCandidate {
  173. ReferenceFrameType type;
  174. MotionVector vector;
  175. };
  176. }