/* * Copyright (c) 2021, Hunter Salyer * Copyright (c) 2022, Gregory Bertilson * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include "ContextStorage.h" #include "LookupTables.h" #include "MotionVector.h" #include "ProbabilityTables.h" #include "SyntaxElementCounter.h" #include "TreeParser.h" namespace Video::VP9 { class Decoder; struct FrameContext; struct TileContext; struct BlockContext; struct MotionVectorCandidate; struct QuantizationParameters; class Parser { friend class TreeParser; friend class Decoder; public: explicit Parser(Decoder&); ~Parser(); DecoderErrorOr parse_frame(ReadonlyBytes); private: /* Annex B: Superframes are a method of storing multiple coded frames into a single chunk * See also section 5.26. */ Vector parse_superframe_sizes(ReadonlyBytes); DecoderErrorOr read_video_full_range_flag(BigEndianInputBitStream&); /* (6.1) Frame Syntax */ bool trailing_bits(); DecoderErrorOr refresh_probs(FrameContext const&); /* (6.2) Uncompressed Header Syntax */ DecoderErrorOr uncompressed_header(FrameContext& frame_context); DecoderErrorOr frame_sync_code(BigEndianInputBitStream&); DecoderErrorOr parse_color_config(BigEndianInputBitStream&, u8 profile); DecoderErrorOr> parse_frame_size(BigEndianInputBitStream&); DecoderErrorOr> parse_frame_size_with_refs(BigEndianInputBitStream&, Array const& reference_indices); DecoderErrorOr> parse_render_size(BigEndianInputBitStream&, Gfx::Size frame_size); DecoderErrorOr compute_image_size(FrameContext&); DecoderErrorOr read_interpolation_filter(BigEndianInputBitStream&); DecoderErrorOr loop_filter_params(FrameContext&); DecoderErrorOr read_delta_q(BigEndianInputBitStream&); DecoderErrorOr segmentation_params(FrameContext&); DecoderErrorOr read_prob(BigEndianInputBitStream&); static void precalculate_quantizers(FrameContext& frame_context, QuantizationParameters quantization_parameters); DecoderErrorOr parse_tile_counts(FrameContext&); void setup_past_independence(); /* (6.3) Compressed Header Syntax */ DecoderErrorOr compressed_header(FrameContext&); DecoderErrorOr read_tx_mode(BooleanDecoder&, FrameContext const&); DecoderErrorOr tx_mode_probs(BooleanDecoder&); DecoderErrorOr diff_update_prob(BooleanDecoder&, u8 prob); DecoderErrorOr decode_term_subexp(BooleanDecoder&); u8 inv_remap_prob(u8 delta_prob, u8 prob); u8 inv_recenter_nonneg(u8 v, u8 m); DecoderErrorOr read_coef_probs(BooleanDecoder&, TransformMode); DecoderErrorOr read_skip_prob(BooleanDecoder&); DecoderErrorOr read_inter_mode_probs(BooleanDecoder&); DecoderErrorOr read_interp_filter_probs(BooleanDecoder&); DecoderErrorOr read_is_inter_probs(BooleanDecoder&); DecoderErrorOr frame_reference_mode(FrameContext&, BooleanDecoder&); DecoderErrorOr frame_reference_mode_probs(BooleanDecoder&, FrameContext const&); DecoderErrorOr read_y_mode_probs(BooleanDecoder&); DecoderErrorOr read_partition_probs(BooleanDecoder&); DecoderErrorOr mv_probs(BooleanDecoder&, FrameContext const&); DecoderErrorOr update_mv_prob(BooleanDecoder&, u8 prob); /* (6.4) Decode Tiles Syntax */ DecoderErrorOr decode_tiles(FrameContext&); DecoderErrorOr decode_tile(TileContext&); void clear_left_context(TileContext&); DecoderErrorOr decode_partition(TileContext&, u32 row, u32 column, BlockSubsize subsize); DecoderErrorOr decode_block(TileContext&, u32 row, u32 column, BlockSubsize subsize); DecoderErrorOr mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr intra_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr set_intra_segment_id(BlockContext&); DecoderErrorOr read_should_skip_residuals(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr read_tx_size(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select); DecoderErrorOr inter_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr set_inter_segment_id(BlockContext&); u8 get_segment_id(BlockContext const&); DecoderErrorOr read_is_inter(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr intra_block_mode_info(BlockContext&); DecoderErrorOr inter_block_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr read_ref_frames(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context); DecoderErrorOr get_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&); DecoderErrorOr read_motion_vector(BlockContext const&, BlockMotionVectorCandidates const&, ReferenceIndex); DecoderErrorOr read_single_motion_vector_component(BooleanDecoder&, SyntaxElementCounter&, u8 component, bool use_high_precision); DecoderErrorOr residual(BlockContext&, bool has_block_above, bool has_block_left); DecoderErrorOr tokens(BlockContext&, size_t plane, u32 x, u32 y, TransformSize, TransformSet, Array token_cache); DecoderErrorOr read_coef(BooleanDecoder&, u8 bit_depth, Token token); /* (6.5) Motion Vector Prediction */ MotionVectorPair find_reference_motion_vectors(BlockContext&, ReferenceFrameType, i32 block); void select_best_sub_block_reference_motion_vectors(BlockContext&, BlockMotionVectorCandidates&, i32 block, ReferenceIndex); size_t get_image_index(FrameContext const&, u32 row, u32 column) const; MotionVectorCandidate get_motion_vector_from_current_or_previous_frame(BlockContext const&, MotionVector candidate_vector, ReferenceIndex, bool use_prev); void add_motion_vector_if_reference_frame_type_is_same(BlockContext const&, MotionVector candidate_vector, ReferenceFrameType ref_frame, Vector& list, bool use_prev); void add_motion_vector_if_reference_frame_type_is_different(BlockContext const&, MotionVector candidate_vector, ReferenceFrameType ref_frame, Vector& list, bool use_prev); bool m_is_first_compute_image_size_invoke { true }; Gfx::Size m_previous_frame_size { 0, 0 }; bool m_previous_show_frame { false }; ColorConfig m_previous_color_config; FrameType m_previous_frame_type { FrameType::KeyFrame }; Array m_previous_loop_filter_ref_deltas; Array m_previous_loop_filter_mode_deltas; bool m_previous_should_use_absolute_segment_base_quantizer; SegmentationFeatures m_previous_segmentation_features; ReferenceFrame m_reference_frames[NUM_REF_FRAMES]; Vector2D m_reusable_frame_block_contexts; Vector2D m_previous_block_contexts; OwnPtr m_probability_tables; Decoder& m_decoder; Vector>> m_worker_threads; }; }