mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
LibVideo/VP9: Move more block fields into the BlockContext struct
This includes the segment IDs, transform block sizes, prediction modes, sub-block counts, interpolation filters and sub-block motion vectors.
This commit is contained in:
parent
f4e835635f
commit
6533c5f6a8
Notes:
sideshowbarker
2024-07-17 05:58:46 +09:00
Author: https://github.com/Zaggy1024 Commit: https://github.com/SerenityOS/serenity/commit/6533c5f6a8 Pull-request: https://github.com/SerenityOS/serenity/pull/16238
4 changed files with 174 additions and 188 deletions
|
@ -203,7 +203,7 @@ struct TokensContext {
|
|||
struct FrameBlockContext {
|
||||
bool is_intra_predicted() const { return ref_frames[0] == ReferenceFrameType::None; }
|
||||
bool is_single_reference() const { return ref_frames[1] == ReferenceFrameType::None; }
|
||||
MotionVectorPair primary_motion_vector_pair() const { return { sub_block_motion_vectors[0][3], sub_block_motion_vectors[1][3] }; }
|
||||
MotionVectorPair primary_motion_vector_pair() const { return sub_block_motion_vectors[3]; }
|
||||
|
||||
bool is_available { false };
|
||||
bool skip_coefficients { false };
|
||||
|
@ -212,7 +212,7 @@ struct FrameBlockContext {
|
|||
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<Array<MotionVector, 4>, 2> sub_block_motion_vectors {};
|
||||
Array<MotionVectorPair, 4> sub_block_motion_vectors;
|
||||
u8 segment_id { 0 };
|
||||
};
|
||||
|
||||
|
@ -382,8 +382,31 @@ struct BlockContext {
|
|||
u32 row { 0 };
|
||||
u32 column { 0 };
|
||||
BlockSubsize size;
|
||||
Gfx::Size<u8> get_size_in_4x4_blocks() const
|
||||
{
|
||||
auto width = num_4x4_blocks_wide_lookup[size];
|
||||
auto height = num_4x4_blocks_high_lookup[size];
|
||||
return Gfx::Size<u8>(width, height);
|
||||
}
|
||||
|
||||
Vector2DView<FrameBlockContext> contexts_view;
|
||||
|
||||
u8 segment_id { 0 };
|
||||
bool should_skip_residuals { false };
|
||||
|
||||
TXSize tx_size { TXSize::TX_4x4 };
|
||||
|
||||
ReferenceFramePair reference_frame_types;
|
||||
bool is_inter_predicted() const { return reference_frame_types[0] > ReferenceFrameType::None; }
|
||||
bool is_compound() const { return reference_frame_types[1] > ReferenceFrameType::None; }
|
||||
|
||||
Array<PredictionMode, 4> sub_block_prediction_modes;
|
||||
PredictionMode y_prediction_mode() const { return sub_block_prediction_modes.last(); }
|
||||
PredictionMode& y_prediction_mode() { return sub_block_prediction_modes.last(); }
|
||||
PredictionMode uv_prediction_mode { 0 };
|
||||
|
||||
InterpolationFilter interpolation_filter { EightTap };
|
||||
Array<MotionVectorPair, 4> sub_block_motion_vectors;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -351,11 +351,11 @@ DecoderErrorOr<void> Decoder::predict_intra(u8 plane, BlockContext const& block_
|
|||
// 3. Otherwise, mode is set equal to sub_modes[ blockIdx ].
|
||||
PredictionMode mode;
|
||||
if (plane > 0)
|
||||
mode = m_parser->m_uv_mode;
|
||||
mode = block_context.uv_prediction_mode;
|
||||
else if (block_context.size >= Block_8x8)
|
||||
mode = m_parser->m_y_mode;
|
||||
mode = block_context.y_prediction_mode();
|
||||
else
|
||||
mode = m_parser->m_block_sub_modes[block_index];
|
||||
mode = block_context.sub_block_prediction_modes[block_index];
|
||||
|
||||
// The variable log2Size specifying the base 2 logarithm of the width of the transform block is set equal to txSz + 2.
|
||||
u8 log2_of_block_size = tx_size + 2;
|
||||
|
@ -700,31 +700,33 @@ MotionVector Decoder::select_motion_vector(u8 plane, BlockContext const& block_c
|
|||
};
|
||||
};
|
||||
|
||||
auto vectors = block_context.sub_block_motion_vectors;
|
||||
|
||||
// The motion vector array mv is derived as follows:
|
||||
// − If plane is equal to 0, or MiSize is greater than or equal to BLOCK_8X8, mv is set equal to
|
||||
// BlockMvs[ refList ][ blockIdx ].
|
||||
if (plane == 0 || block_context.size >= Block_8x8)
|
||||
return m_parser->m_block_mvs[ref_list][block_index];
|
||||
return vectors[block_index][ref_list];
|
||||
// − Otherwise, if subsampling_x is equal to 0 and subsampling_y is equal to 0, mv is set equal to
|
||||
// BlockMvs[ refList ][ blockIdx ].
|
||||
if (!block_context.frame_context.color_config.subsampling_x && !block_context.frame_context.color_config.subsampling_y)
|
||||
return m_parser->m_block_mvs[ref_list][block_index];
|
||||
return vectors[block_index][ref_list];
|
||||
// − Otherwise, if subsampling_x is equal to 0 and subsampling_y is equal to 1, mv[ comp ] is set equal to
|
||||
// round_mv_comp_q2( BlockMvs[ refList ][ blockIdx ][ comp ] + BlockMvs[ refList ][ blockIdx + 2 ][ comp ] )
|
||||
// for comp = 0..1.
|
||||
if (!block_context.frame_context.color_config.subsampling_x && block_context.frame_context.color_config.subsampling_y)
|
||||
return round_mv_comp_q2(m_parser->m_block_mvs[ref_list][block_index] + m_parser->m_block_mvs[ref_list][block_index + 2]);
|
||||
return round_mv_comp_q2(vectors[block_index][ref_list] + vectors[block_index + 2][ref_list]);
|
||||
// − Otherwise, if subsampling_x is equal to 1 and subsampling_y is equal to 0, mv[ comp ] is set equal to
|
||||
// round_mv_comp_q2( BlockMvs[ refList ][ blockIdx ][ comp ] + BlockMvs[ refList ][ blockIdx + 1 ][ comp ] )
|
||||
// for comp = 0..1.
|
||||
if (block_context.frame_context.color_config.subsampling_x && !block_context.frame_context.color_config.subsampling_y)
|
||||
return round_mv_comp_q2(m_parser->m_block_mvs[ref_list][block_index] + m_parser->m_block_mvs[ref_list][block_index + 1]);
|
||||
return round_mv_comp_q2(vectors[block_index][ref_list] + vectors[block_index + 1][ref_list]);
|
||||
// − Otherwise, (subsampling_x is equal to 1 and subsampling_y is equal to 1), mv[ comp ] is set equal to
|
||||
// round_mv_comp_q4( BlockMvs[ refList ][ 0 ][ comp ] + BlockMvs[ refList ][ 1 ][ comp ] +
|
||||
// BlockMvs[ refList ][ 2 ][ comp ] + BlockMvs[ refList ][ 3 ][ comp ] ) for comp = 0..1.
|
||||
VERIFY(block_context.frame_context.color_config.subsampling_x && block_context.frame_context.color_config.subsampling_y);
|
||||
return round_mv_comp_q4(m_parser->m_block_mvs[ref_list][0] + m_parser->m_block_mvs[ref_list][1]
|
||||
+ m_parser->m_block_mvs[ref_list][2] + m_parser->m_block_mvs[ref_list][3]);
|
||||
return round_mv_comp_q4(vectors[0][ref_list] + vectors[1][ref_list]
|
||||
+ vectors[2][ref_list] + vectors[3][ref_list]);
|
||||
}
|
||||
|
||||
MotionVector Decoder::clamp_motion_vector(u8 plane, BlockContext const& block_context, u32 block_row, u32 block_column, MotionVector vector)
|
||||
|
@ -787,7 +789,7 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
|
|||
|
||||
// A variable refIdx specifying which reference frame is being used is set equal to
|
||||
// ref_frame_idx[ ref_frame[ refList ] - LAST_FRAME ].
|
||||
auto reference_frame_index = block_context.frame_context.reference_frame_indices[m_parser->m_ref_frame[ref_list] - LastFrame];
|
||||
auto reference_frame_index = block_context.frame_context.reference_frame_indices[block_context.reference_frame_types[ref_list] - LastFrame];
|
||||
|
||||
// It is a requirement of bitstream conformance that all the following conditions are satisfied:
|
||||
// − 2 * FrameWidth >= RefFrameWidth[ refIdx ]
|
||||
|
@ -907,7 +909,7 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
|
|||
auto sample = reference_frame_buffer_at(
|
||||
clip_3(0, scaled_bottom, (offset_scaled_block_y >> 4) + static_cast<i32>(row) - 3),
|
||||
clip_3(0, scaled_right, (samples_start >> 4) + static_cast<i32>(t) - 3));
|
||||
accumulated_samples += subpel_filters[m_parser->m_interp_filter][samples_start & 15][t] * sample;
|
||||
accumulated_samples += subpel_filters[block_context.interpolation_filter][samples_start & 15][t] * sample;
|
||||
}
|
||||
intermediate_buffer_at(row, column) = clip_1(block_context.frame_context.color_config.bit_depth, round_2(accumulated_samples, 7));
|
||||
}
|
||||
|
@ -920,7 +922,7 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
|
|||
i32 accumulated_samples = 0;
|
||||
for (auto t = 0u; t < 8u; t++) {
|
||||
auto sample = intermediate_buffer_at((samples_start >> 4) + t, column);
|
||||
accumulated_samples += subpel_filters[m_parser->m_interp_filter][samples_start & 15][t] * sample;
|
||||
accumulated_samples += subpel_filters[block_context.interpolation_filter][samples_start & 15][t] * sample;
|
||||
}
|
||||
block_buffer_at(row, column) = clip_1(block_context.frame_context.color_config.bit_depth, round_2(accumulated_samples, 7));
|
||||
}
|
||||
|
@ -942,7 +944,7 @@ DecoderErrorOr<void> Decoder::predict_inter(u8 plane, BlockContext const& block_
|
|||
// The outputs of this process are inter predicted samples in the current frame CurrFrame.
|
||||
|
||||
// The variable isCompound is set equal to ref_frame[ 1 ] > NONE.
|
||||
auto is_compound = m_parser->m_ref_frame[1] > None;
|
||||
auto is_compound = block_context.reference_frame_types[1] > None;
|
||||
// The prediction arrays are formed by the following ordered steps:
|
||||
// 1. The variable refList is set equal to 0.
|
||||
// 2. through 5.
|
||||
|
@ -1022,9 +1024,9 @@ u8 Decoder::get_base_quantizer_index(BlockContext const& block_context)
|
|||
{
|
||||
// The function get_qindex( ) returns the quantizer index for the current block and is specified by the following:
|
||||
// − If seg_feature_active( SEG_LVL_ALT_Q ) is equal to 1 the following ordered steps apply:
|
||||
if (m_parser->seg_feature_active(SEG_LVL_ALT_Q)) {
|
||||
if (m_parser->seg_feature_active(block_context, SEG_LVL_ALT_Q)) {
|
||||
// 1. Set the variable data equal to FeatureData[ segment_id ][ SEG_LVL_ALT_Q ].
|
||||
auto data = m_parser->m_feature_data[m_parser->m_segment_id][SEG_LVL_ALT_Q];
|
||||
auto data = m_parser->m_feature_data[block_context.segment_id][SEG_LVL_ALT_Q];
|
||||
|
||||
// 2. If segmentation_abs_or_delta_update is equal to 0, set data equal to base_q_idx + data
|
||||
if (!m_parser->m_segmentation_abs_or_delta_update) {
|
||||
|
|
|
@ -632,8 +632,8 @@ u8 Parser::inv_recenter_nonneg(u8 v, u8 m)
|
|||
|
||||
DecoderErrorOr<void> Parser::read_coef_probs()
|
||||
{
|
||||
m_max_tx_size = tx_mode_to_biggest_tx_size[m_tx_mode];
|
||||
for (u8 tx_size = 0; tx_size <= m_max_tx_size; tx_size++) {
|
||||
auto max_tx_size = tx_mode_to_biggest_tx_size[m_tx_mode];
|
||||
for (u8 tx_size = 0; tx_size <= max_tx_size; tx_size++) {
|
||||
auto update_probs = TRY_READ(m_bit_stream->read_literal(1));
|
||||
if (update_probs == 1) {
|
||||
for (auto i = 0; i < 2; i++) {
|
||||
|
@ -963,12 +963,12 @@ DecoderErrorOr<void> Parser::decode_block(TileContext& tile_context, u32 row, u3
|
|||
|
||||
TRY(mode_info(block_context, above_context, left_context));
|
||||
auto had_residual_tokens = TRY(residual(block_context, above_context.is_available, left_context.is_available));
|
||||
if (m_is_inter && subsize >= Block_8x8 && !had_residual_tokens)
|
||||
m_skip = true;
|
||||
if (block_context.is_inter_predicted() && subsize >= Block_8x8 && !had_residual_tokens)
|
||||
block_context.should_skip_residuals = true;
|
||||
|
||||
for (size_t y = 0; y < block_context.contexts_view.height(); y++) {
|
||||
for (size_t x = 0; x < block_context.contexts_view.width(); x++) {
|
||||
auto sub_block_context = FrameBlockContext { true, m_skip, m_tx_size, m_y_mode, m_block_sub_modes, m_interp_filter, m_ref_frame, m_block_mvs, m_segment_id };
|
||||
auto sub_block_context = FrameBlockContext { true, block_context.should_skip_residuals, block_context.tx_size, block_context.y_prediction_mode(), block_context.sub_block_prediction_modes, block_context.interpolation_filter, block_context.reference_frame_types, block_context.sub_block_motion_vectors, block_context.segment_id };
|
||||
block_context.contexts_view.at(y, x) = sub_block_context;
|
||||
VERIFY(block_context.frame_block_contexts().at(row + y, column + x).tx_size == sub_block_context.tx_size);
|
||||
}
|
||||
|
@ -987,81 +987,72 @@ DecoderErrorOr<void> Parser::mode_info(BlockContext& block_context, FrameBlockCo
|
|||
|
||||
DecoderErrorOr<void> Parser::intra_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
TRY(intra_segment_id());
|
||||
TRY(read_skip(above_context, left_context));
|
||||
TRY(read_tx_size(block_context, above_context, left_context, true));
|
||||
m_ref_frame[0] = IntraFrame;
|
||||
m_ref_frame[1] = None;
|
||||
m_is_inter = false;
|
||||
block_context.reference_frame_types = { ReferenceFrameType::None, ReferenceFrameType::None };
|
||||
VERIFY(!block_context.is_inter_predicted());
|
||||
TRY(set_intra_segment_id(block_context));
|
||||
block_context.should_skip_residuals = TRY(read_should_skip_residuals(block_context, above_context, left_context));
|
||||
block_context.tx_size = TRY(read_tx_size(block_context, above_context, left_context, true));
|
||||
// FIXME: This if statement is also present in parse_default_intra_mode. The selection of parameters for
|
||||
// the probability table lookup should be inlined here.
|
||||
if (block_context.size >= Block_8x8) {
|
||||
m_y_mode = TRY_READ(TreeParser::parse_default_intra_mode(*m_bit_stream, *m_probability_tables, block_context.size, above_context, left_context, m_block_sub_modes, 0, 0));
|
||||
for (auto& block_sub_mode : m_block_sub_modes)
|
||||
block_sub_mode = m_y_mode;
|
||||
auto mode = TRY_READ(TreeParser::parse_default_intra_mode(*m_bit_stream, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, 0, 0));
|
||||
for (auto& block_sub_mode : block_context.sub_block_prediction_modes)
|
||||
block_sub_mode = mode;
|
||||
} else {
|
||||
m_num_4x4_w = num_4x4_blocks_wide_lookup[block_context.size];
|
||||
m_num_4x4_h = num_4x4_blocks_high_lookup[block_context.size];
|
||||
for (auto idy = 0; idy < 2; idy += m_num_4x4_h) {
|
||||
for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
|
||||
auto sub_mode = TRY_READ(TreeParser::parse_default_intra_mode(*m_bit_stream, *m_probability_tables, block_context.size, above_context, left_context, m_block_sub_modes, idx, idy));
|
||||
auto size_in_4x4_blocks = block_context.get_size_in_4x4_blocks();
|
||||
for (auto idy = 0; idy < 2; idy += size_in_4x4_blocks.height()) {
|
||||
for (auto idx = 0; idx < 2; idx += size_in_4x4_blocks.width()) {
|
||||
auto sub_mode = TRY_READ(TreeParser::parse_default_intra_mode(*m_bit_stream, *m_probability_tables, block_context.size, above_context, left_context, block_context.sub_block_prediction_modes, idx, idy));
|
||||
|
||||
for (auto y = 0; y < m_num_4x4_h; y++) {
|
||||
for (auto x = 0; x < m_num_4x4_w; x++) {
|
||||
for (auto y = 0; y < size_in_4x4_blocks.height(); y++) {
|
||||
for (auto x = 0; x < size_in_4x4_blocks.width(); x++) {
|
||||
auto index = (idy + y) * 2 + idx + x;
|
||||
m_block_sub_modes[index] = sub_mode;
|
||||
block_context.sub_block_prediction_modes[index] = sub_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_y_mode = m_block_sub_modes.last();
|
||||
}
|
||||
m_uv_mode = TRY_READ(TreeParser::parse_default_uv_mode(*m_bit_stream, *m_probability_tables, m_y_mode));
|
||||
block_context.uv_prediction_mode = TRY_READ(TreeParser::parse_default_uv_mode(*m_bit_stream, *m_probability_tables, block_context.y_prediction_mode()));
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::intra_segment_id()
|
||||
DecoderErrorOr<void> Parser::set_intra_segment_id(BlockContext& block_context)
|
||||
{
|
||||
if (m_segmentation_enabled && m_segmentation_update_map)
|
||||
m_segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
|
||||
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
|
||||
else
|
||||
m_segment_id = 0;
|
||||
block_context.segment_id = 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_skip(FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
DecoderErrorOr<bool> Parser::read_should_skip_residuals(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
if (seg_feature_active(SEG_LVL_SKIP)) {
|
||||
m_skip = true;
|
||||
} else {
|
||||
m_skip = TRY_READ(TreeParser::parse_skip(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
}
|
||||
return {};
|
||||
if (seg_feature_active(block_context, SEG_LVL_SKIP))
|
||||
return true;
|
||||
return TRY_READ(TreeParser::parse_skip(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
}
|
||||
|
||||
bool Parser::seg_feature_active(u8 feature)
|
||||
bool Parser::seg_feature_active(BlockContext const& block_context, u8 feature)
|
||||
{
|
||||
return m_segmentation_enabled && m_feature_enabled[m_segment_id][feature];
|
||||
return m_segmentation_enabled && m_feature_enabled[block_context.segment_id][feature];
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_tx_size(BlockContext const& block_context, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select)
|
||||
DecoderErrorOr<TXSize> Parser::read_tx_size(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select)
|
||||
{
|
||||
// FIXME: This probably doesn't need to set max_tx_size, and can also return the TXSize it reads.
|
||||
m_max_tx_size = max_txsize_lookup[block_context.size];
|
||||
auto max_tx_size = max_txsize_lookup[block_context.size];
|
||||
if (allow_select && m_tx_mode == TXModeSelect && block_context.size >= Block_8x8)
|
||||
m_tx_size = TRY_READ(TreeParser::parse_tx_size(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_max_tx_size, above_context, left_context));
|
||||
else
|
||||
m_tx_size = min(m_max_tx_size, tx_mode_to_biggest_tx_size[m_tx_mode]);
|
||||
return {};
|
||||
return (TRY_READ(TreeParser::parse_tx_size(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, max_tx_size, above_context, left_context)));
|
||||
return min(max_tx_size, tx_mode_to_biggest_tx_size[m_tx_mode]);
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::inter_frame_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
TRY(inter_segment_id(block_context));
|
||||
TRY(read_skip(above_context, left_context));
|
||||
TRY(read_is_inter(above_context, left_context));
|
||||
TRY(read_tx_size(block_context, above_context, left_context, !m_skip || !m_is_inter));
|
||||
if (m_is_inter) {
|
||||
TRY(set_inter_segment_id(block_context));
|
||||
block_context.should_skip_residuals = TRY(read_should_skip_residuals(block_context, above_context, left_context));
|
||||
auto is_inter = TRY(read_is_inter(block_context, above_context, left_context));
|
||||
block_context.tx_size = TRY(read_tx_size(block_context, above_context, left_context, !block_context.should_skip_residuals || !is_inter));
|
||||
if (is_inter) {
|
||||
TRY(inter_block_mode_info(block_context, above_context, left_context));
|
||||
} else {
|
||||
TRY(intra_block_mode_info(block_context));
|
||||
|
@ -1069,27 +1060,27 @@ DecoderErrorOr<void> Parser::inter_frame_mode_info(BlockContext& block_context,
|
|||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::inter_segment_id(BlockContext const& block_context)
|
||||
DecoderErrorOr<void> Parser::set_inter_segment_id(BlockContext& block_context)
|
||||
{
|
||||
if (!m_segmentation_enabled) {
|
||||
m_segment_id = 0;
|
||||
block_context.segment_id = 0;
|
||||
return {};
|
||||
}
|
||||
auto predicted_segment_id = get_segment_id(block_context);
|
||||
if (!m_segmentation_update_map) {
|
||||
m_segment_id = predicted_segment_id;
|
||||
block_context.segment_id = predicted_segment_id;
|
||||
return {};
|
||||
}
|
||||
if (!m_segmentation_temporal_update) {
|
||||
m_segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
|
||||
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
|
||||
return {};
|
||||
}
|
||||
|
||||
auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(*m_bit_stream, m_segmentation_pred_prob, m_left_seg_pred_context[block_context.row], m_above_seg_pred_context[block_context.column]));
|
||||
if (seg_id_predicted)
|
||||
m_segment_id = predicted_segment_id;
|
||||
block_context.segment_id = predicted_segment_id;
|
||||
else
|
||||
m_segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
|
||||
block_context.segment_id = TRY_READ(TreeParser::parse_segment_id(*m_bit_stream, m_segmentation_tree_probs));
|
||||
|
||||
for (size_t i = 0; i < num_8x8_blocks_wide_lookup[block_context.size]; i++) {
|
||||
auto index = block_context.column + i;
|
||||
|
@ -1121,98 +1112,87 @@ u8 Parser::get_segment_id(BlockContext const& block_context)
|
|||
return segment;
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_is_inter(FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
DecoderErrorOr<bool> Parser::read_is_inter(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
if (seg_feature_active(SEG_LVL_REF_FRAME))
|
||||
m_is_inter = m_feature_data[m_segment_id][SEG_LVL_REF_FRAME] != IntraFrame;
|
||||
else
|
||||
m_is_inter = TRY_READ(TreeParser::parse_block_is_inter_predicted(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
return {};
|
||||
if (seg_feature_active(block_context, SEG_LVL_REF_FRAME))
|
||||
return m_feature_data[block_context.segment_id][SEG_LVL_REF_FRAME] != IntraFrame;
|
||||
return TRY_READ(TreeParser::parse_block_is_inter_predicted(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::intra_block_mode_info(BlockContext& block_context)
|
||||
{
|
||||
m_ref_frame[0] = IntraFrame;
|
||||
m_ref_frame[1] = None;
|
||||
block_context.reference_frame_types = { ReferenceFrameType::None, ReferenceFrameType::None };
|
||||
VERIFY(!block_context.is_inter_predicted());
|
||||
auto& sub_modes = block_context.sub_block_prediction_modes;
|
||||
if (block_context.size >= Block_8x8) {
|
||||
m_y_mode = TRY_READ(TreeParser::parse_intra_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, block_context.size));
|
||||
for (auto& block_sub_mode : m_block_sub_modes)
|
||||
block_sub_mode = m_y_mode;
|
||||
auto mode = TRY_READ(TreeParser::parse_intra_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, block_context.size));
|
||||
for (auto& block_sub_mode : sub_modes)
|
||||
block_sub_mode = mode;
|
||||
} else {
|
||||
m_num_4x4_w = num_4x4_blocks_wide_lookup[block_context.size];
|
||||
m_num_4x4_h = num_4x4_blocks_high_lookup[block_context.size];
|
||||
PredictionMode sub_intra_mode;
|
||||
for (auto idy = 0; idy < 2; idy += m_num_4x4_h) {
|
||||
for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
|
||||
sub_intra_mode = TRY_READ(TreeParser::parse_sub_intra_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter));
|
||||
for (auto y = 0; y < m_num_4x4_h; y++) {
|
||||
for (auto x = 0; x < m_num_4x4_w; x++)
|
||||
m_block_sub_modes[(idy + y) * 2 + idx + x] = sub_intra_mode;
|
||||
auto size_in_4x4_blocks = block_context.get_size_in_4x4_blocks();
|
||||
for (auto idy = 0; idy < 2; idy += size_in_4x4_blocks.height()) {
|
||||
for (auto idx = 0; idx < 2; idx += size_in_4x4_blocks.width()) {
|
||||
auto sub_intra_mode = TRY_READ(TreeParser::parse_sub_intra_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter));
|
||||
for (auto y = 0; y < size_in_4x4_blocks.height(); y++) {
|
||||
for (auto x = 0; x < size_in_4x4_blocks.width(); x++)
|
||||
sub_modes[(idy + y) * 2 + idx + x] = sub_intra_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_y_mode = sub_intra_mode;
|
||||
}
|
||||
m_uv_mode = TRY_READ(TreeParser::parse_uv_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_y_mode));
|
||||
block_context.uv_prediction_mode = TRY_READ(TreeParser::parse_uv_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, block_context.y_prediction_mode()));
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::inter_block_mode_info(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
TRY(read_ref_frames(block_context, above_context, left_context));
|
||||
VERIFY(block_context.is_inter_predicted());
|
||||
for (auto j = 0; j < 2; j++) {
|
||||
if (m_ref_frame[j] > IntraFrame) {
|
||||
find_mv_refs(block_context, m_ref_frame[j], -1);
|
||||
if (block_context.reference_frame_types[j] > IntraFrame) {
|
||||
find_mv_refs(block_context, block_context.reference_frame_types[j], -1);
|
||||
find_best_ref_mvs(block_context, j);
|
||||
}
|
||||
}
|
||||
auto is_compound = m_ref_frame[1] > IntraFrame;
|
||||
if (seg_feature_active(SEG_LVL_SKIP)) {
|
||||
m_y_mode = PredictionMode::ZeroMv;
|
||||
if (seg_feature_active(block_context, SEG_LVL_SKIP)) {
|
||||
block_context.y_prediction_mode() = PredictionMode::ZeroMv;
|
||||
} else if (block_context.size >= Block_8x8) {
|
||||
m_y_mode = TRY_READ(TreeParser::parse_inter_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_mode_context[m_ref_frame[0]]));
|
||||
block_context.y_prediction_mode() = TRY_READ(TreeParser::parse_inter_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_mode_context[block_context.reference_frame_types[0]]));
|
||||
}
|
||||
if (block_context.frame_context.interpolation_filter == Switchable)
|
||||
m_interp_filter = TRY_READ(TreeParser::parse_interpolation_filter(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
block_context.interpolation_filter = TRY_READ(TreeParser::parse_interpolation_filter(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
else
|
||||
m_interp_filter = block_context.frame_context.interpolation_filter;
|
||||
block_context.interpolation_filter = block_context.frame_context.interpolation_filter;
|
||||
if (block_context.size < Block_8x8) {
|
||||
m_num_4x4_w = num_4x4_blocks_wide_lookup[block_context.size];
|
||||
m_num_4x4_h = num_4x4_blocks_high_lookup[block_context.size];
|
||||
for (auto idy = 0; idy < 2; idy += m_num_4x4_h) {
|
||||
for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
|
||||
m_y_mode = TRY_READ(TreeParser::parse_inter_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_mode_context[m_ref_frame[0]]));
|
||||
if (m_y_mode == PredictionMode::NearestMv || m_y_mode == PredictionMode::NearMv) {
|
||||
for (auto j = 0; j < 1 + is_compound; j++)
|
||||
auto size_in_4x4_blocks = block_context.get_size_in_4x4_blocks();
|
||||
for (auto idy = 0; idy < 2; idy += size_in_4x4_blocks.height()) {
|
||||
for (auto idx = 0; idx < 2; idx += size_in_4x4_blocks.width()) {
|
||||
block_context.y_prediction_mode() = TRY_READ(TreeParser::parse_inter_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_mode_context[block_context.reference_frame_types[0]]));
|
||||
if (block_context.y_prediction_mode() == PredictionMode::NearestMv || block_context.y_prediction_mode() == PredictionMode::NearMv) {
|
||||
for (auto j = 0; j < 1 + block_context.is_compound(); j++)
|
||||
append_sub8x8_mvs(block_context, idy * 2 + idx, j);
|
||||
}
|
||||
TRY(assign_mv(block_context, is_compound));
|
||||
for (auto y = 0; y < m_num_4x4_h; y++) {
|
||||
for (auto x = 0; x < m_num_4x4_w; x++) {
|
||||
auto block = (idy + y) * 2 + idx + x;
|
||||
for (auto ref_list = 0; ref_list < 1 + is_compound; ref_list++) {
|
||||
m_block_mvs[ref_list][block] = m_mv[ref_list];
|
||||
}
|
||||
auto new_motion_vector_pair = TRY(assign_mv(block_context));
|
||||
for (auto y = 0; y < size_in_4x4_blocks.height(); y++) {
|
||||
for (auto x = 0; x < size_in_4x4_blocks.width(); x++) {
|
||||
auto sub_block_index = (idy + y) * 2 + idx + x;
|
||||
block_context.sub_block_motion_vectors[sub_block_index] = new_motion_vector_pair;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
TRY(assign_mv(block_context, is_compound));
|
||||
for (auto ref_list = 0; ref_list < 1 + is_compound; ref_list++) {
|
||||
for (auto block = 0; block < 4; block++) {
|
||||
m_block_mvs[ref_list][block] = m_mv[ref_list];
|
||||
}
|
||||
}
|
||||
auto new_motion_vector_pair = TRY(assign_mv(block_context));
|
||||
for (auto block = 0; block < 4; block++)
|
||||
block_context.sub_block_motion_vectors[block] = new_motion_vector_pair;
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_ref_frames(BlockContext& block_context, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
if (seg_feature_active(SEG_LVL_REF_FRAME)) {
|
||||
m_ref_frame[0] = static_cast<ReferenceFrameType>(m_feature_data[m_segment_id][SEG_LVL_REF_FRAME]);
|
||||
m_ref_frame[1] = None;
|
||||
if (seg_feature_active(block_context, SEG_LVL_REF_FRAME)) {
|
||||
block_context.reference_frame_types = { static_cast<ReferenceFrameType>(m_feature_data[block_context.segment_id][SEG_LVL_REF_FRAME]), None };
|
||||
return {};
|
||||
}
|
||||
ReferenceMode comp_mode;
|
||||
|
@ -1228,40 +1208,45 @@ DecoderErrorOr<void> Parser::read_ref_frames(BlockContext& block_context, FrameB
|
|||
// FIXME: Create an enum for compound frame references using names Primary and Secondary.
|
||||
auto comp_ref = TRY_READ(TreeParser::parse_comp_ref(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_comp_fixed_ref, m_comp_var_ref, variable_reference_index, above_context, left_context));
|
||||
|
||||
m_ref_frame[fixed_reference_index] = m_comp_fixed_ref;
|
||||
m_ref_frame[variable_reference_index] = m_comp_var_ref[comp_ref];
|
||||
block_context.reference_frame_types[fixed_reference_index] = m_comp_fixed_ref;
|
||||
block_context.reference_frame_types[variable_reference_index] = m_comp_var_ref[comp_ref];
|
||||
return {};
|
||||
}
|
||||
// FIXME: Maybe consolidate this into a tree. Context is different between part 1 and 2 but still, it would look nice here.
|
||||
auto single_ref_p1 = TRY_READ(TreeParser::parse_single_ref_part_1(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
if (single_ref_p1) {
|
||||
auto single_ref_p2 = TRY_READ(TreeParser::parse_single_ref_part_2(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
m_ref_frame[0] = single_ref_p2 ? AltRefFrame : GoldenFrame;
|
||||
block_context.reference_frame_types[0] = single_ref_p2 ? AltRefFrame : GoldenFrame;
|
||||
} else {
|
||||
m_ref_frame[0] = LastFrame;
|
||||
block_context.reference_frame_types[0] = LastFrame;
|
||||
}
|
||||
m_ref_frame[1] = None;
|
||||
block_context.reference_frame_types[1] = None;
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::assign_mv(BlockContext const& block_context, bool is_compound)
|
||||
DecoderErrorOr<MotionVectorPair> Parser::assign_mv(BlockContext const& block_context)
|
||||
{
|
||||
m_mv[1] = {};
|
||||
for (auto i = 0; i < 1 + is_compound; i++) {
|
||||
if (m_y_mode == PredictionMode::NewMv) {
|
||||
TRY(read_mv(block_context, i));
|
||||
} else if (m_y_mode == PredictionMode::NearestMv) {
|
||||
m_mv[i] = m_nearest_mv[i];
|
||||
} else if (m_y_mode == PredictionMode::NearMv) {
|
||||
m_mv[i] = m_near_mv[i];
|
||||
} else {
|
||||
m_mv[i] = {};
|
||||
MotionVectorPair result;
|
||||
for (auto i = 0; i < 1 + block_context.is_compound(); i++) {
|
||||
switch (block_context.y_prediction_mode()) {
|
||||
case PredictionMode::NewMv:
|
||||
result[i] = TRY(read_mv(block_context, i));
|
||||
break;
|
||||
case PredictionMode::NearestMv:
|
||||
result[i] = m_nearest_mv[i];
|
||||
break;
|
||||
case PredictionMode::NearMv:
|
||||
result[i] = m_near_mv[i];
|
||||
break;
|
||||
default:
|
||||
result[i] = {};
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
return result;
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_mv(BlockContext const& block_context, u8 ref)
|
||||
DecoderErrorOr<MotionVector> Parser::read_mv(BlockContext const& block_context, u8 ref)
|
||||
{
|
||||
m_use_hp = block_context.frame_context.high_precision_motion_vectors_allowed && use_mv_hp(m_best_mv[ref]);
|
||||
MotionVector diff_mv;
|
||||
|
@ -1271,10 +1256,7 @@ DecoderErrorOr<void> Parser::read_mv(BlockContext const& block_context, u8 ref)
|
|||
if (mv_joint == MvJointHnzvz || mv_joint == MvJointHnzvnz)
|
||||
diff_mv.set_column(TRY(read_mv_component(1)));
|
||||
|
||||
// FIXME: We probably don't need to assign MVs to a field, these can just
|
||||
// be returned and assigned where they are requested.
|
||||
m_mv[ref] = m_best_mv[ref] + diff_mv;
|
||||
return {};
|
||||
return m_best_mv[ref] + diff_mv;
|
||||
}
|
||||
|
||||
DecoderErrorOr<i32> Parser::read_mv_component(u8 component)
|
||||
|
@ -1334,7 +1316,7 @@ DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_bloc
|
|||
bool had_residual_tokens = false;
|
||||
auto block_size = block_context.size < Block_8x8 ? Block_8x8 : block_context.size;
|
||||
for (u8 plane = 0; plane < 3; plane++) {
|
||||
auto tx_size = (plane > 0) ? get_uv_tx_size(block_context.frame_context.color_config.subsampling_x, block_context.frame_context.color_config.subsampling_y, m_tx_size, block_context.size) : m_tx_size;
|
||||
auto tx_size = (plane > 0) ? get_uv_tx_size(block_context.frame_context.color_config.subsampling_x, block_context.frame_context.color_config.subsampling_y, block_context.tx_size, block_context.size) : block_context.tx_size;
|
||||
auto step = 1 << tx_size;
|
||||
auto plane_size = get_plane_block_size(block_context.frame_context.color_config.subsampling_x, block_context.frame_context.color_config.subsampling_y, block_size, plane);
|
||||
auto num_4x4_w = num_4x4_blocks_wide_lookup[plane_size];
|
||||
|
@ -1343,7 +1325,7 @@ DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_bloc
|
|||
auto sub_y = (plane > 0) ? block_context.frame_context.color_config.subsampling_y : 0;
|
||||
auto base_x = (block_context.column * 8) >> sub_x;
|
||||
auto base_y = (block_context.row * 8) >> sub_y;
|
||||
if (m_is_inter) {
|
||||
if (block_context.is_inter_predicted()) {
|
||||
if (block_context.size < Block_8x8) {
|
||||
for (auto y = 0; y < num_4x4_h; y++) {
|
||||
for (auto x = 0; x < num_4x4_w; x++) {
|
||||
|
@ -1363,9 +1345,9 @@ DecoderErrorOr<bool> Parser::residual(BlockContext& block_context, bool has_bloc
|
|||
auto start_y = base_y + (4 * y);
|
||||
auto non_zero = false;
|
||||
if (start_x < max_x && start_y < max_y) {
|
||||
if (!m_is_inter)
|
||||
if (!block_context.is_inter_predicted())
|
||||
TRY(m_decoder.predict_intra(plane, block_context, start_x, start_y, has_block_left || x > 0, has_block_above || y > 0, (x + step) < num_4x4_w, tx_size, block_index));
|
||||
if (!m_skip) {
|
||||
if (!block_context.should_skip_residuals) {
|
||||
non_zero = TRY(tokens(block_context, plane, start_x, start_y, tx_size, block_index));
|
||||
had_residual_tokens = had_residual_tokens || non_zero;
|
||||
TRY(m_decoder.reconstruct(plane, block_context, start_x, start_y, tx_size));
|
||||
|
@ -1400,7 +1382,7 @@ DecoderErrorOr<bool> Parser::tokens(BlockContext& block_context, size_t plane, u
|
|||
for (; c < segment_eob; c++) {
|
||||
auto pos = scan[c];
|
||||
auto band = (tx_size == TX_4x4) ? coefband_4x4[c] : coefband_8x8plus[c];
|
||||
auto tokens_context = TreeParser::get_tokens_context(block_context.frame_context.color_config.subsampling_x, block_context.frame_context.color_config.subsampling_y, block_context.frame_context.rows(), block_context.frame_context.columns(), m_above_nonzero_context, m_left_nonzero_context, m_token_cache, tx_size, m_tx_type, plane, start_x, start_y, pos, m_is_inter, band, c);
|
||||
auto tokens_context = TreeParser::get_tokens_context(block_context.frame_context.color_config.subsampling_x, block_context.frame_context.color_config.subsampling_y, block_context.frame_context.rows(), block_context.frame_context.columns(), m_above_nonzero_context, m_left_nonzero_context, m_token_cache, tx_size, m_tx_type, plane, start_x, start_y, pos, block_context.is_inter_predicted(), band, c);
|
||||
if (check_eob) {
|
||||
auto more_coefs = TRY_READ(TreeParser::parse_more_coefficients(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, tokens_context));
|
||||
if (!more_coefs)
|
||||
|
@ -1428,12 +1410,12 @@ u32 const* Parser::get_scan(BlockContext const& block_context, size_t plane, TXS
|
|||
if (plane > 0 || tx_size == TX_32x32) {
|
||||
m_tx_type = DCT_DCT;
|
||||
} else if (tx_size == TX_4x4) {
|
||||
if (block_context.frame_context.is_lossless() || m_is_inter)
|
||||
if (block_context.frame_context.is_lossless() || block_context.is_inter_predicted())
|
||||
m_tx_type = DCT_DCT;
|
||||
else
|
||||
m_tx_type = mode_to_txfm_map[to_underlying(block_context.size < Block_8x8 ? m_block_sub_modes[block_index] : m_y_mode)];
|
||||
m_tx_type = mode_to_txfm_map[to_underlying(block_context.size < Block_8x8 ? block_context.sub_block_prediction_modes[block_index] : block_context.y_prediction_mode())];
|
||||
} else {
|
||||
m_tx_type = mode_to_txfm_map[to_underlying(m_y_mode)];
|
||||
m_tx_type = mode_to_txfm_map[to_underlying(block_context.y_prediction_mode())];
|
||||
}
|
||||
if (tx_size == TX_4x4) {
|
||||
if (m_tx_type == ADST_DCT)
|
||||
|
@ -1600,7 +1582,7 @@ void Parser::find_mv_refs(BlockContext& block_context, ReferenceFrameType refere
|
|||
{ 3, 3 }
|
||||
};
|
||||
auto index = block >= 0 ? idx_n_column_to_subblock[block][offset_vector.column() == 0] : 3;
|
||||
m_candidate_mv[ref_list] = context.sub_block_motion_vectors[ref_list][index];
|
||||
m_candidate_mv[ref_list] = context.sub_block_motion_vectors[index][ref_list];
|
||||
|
||||
add_mv_ref_list(ref_list);
|
||||
break;
|
||||
|
@ -1663,17 +1645,17 @@ void Parser::find_best_ref_mvs(BlockContext& block_context, u8 ref_list)
|
|||
void Parser::append_sub8x8_mvs(BlockContext& block_context, i32 block, u8 ref_list)
|
||||
{
|
||||
MotionVector sub_8x8_mvs[2];
|
||||
find_mv_refs(block_context, m_ref_frame[ref_list], block);
|
||||
find_mv_refs(block_context, block_context.reference_frame_types[ref_list], block);
|
||||
auto destination_index = 0;
|
||||
if (block == 0) {
|
||||
for (auto i = 0u; i < 2; i++)
|
||||
sub_8x8_mvs[destination_index++] = m_ref_list_mv[i];
|
||||
} else if (block <= 2) {
|
||||
sub_8x8_mvs[destination_index++] = m_block_mvs[ref_list][0];
|
||||
sub_8x8_mvs[destination_index++] = block_context.sub_block_motion_vectors[0][ref_list];
|
||||
} else {
|
||||
sub_8x8_mvs[destination_index++] = m_block_mvs[ref_list][2];
|
||||
sub_8x8_mvs[destination_index++] = block_context.sub_block_motion_vectors[2][ref_list];
|
||||
for (auto index = 1; index >= 0 && destination_index < 2; index--) {
|
||||
auto block_vector = m_block_mvs[ref_list][index];
|
||||
auto block_vector = block_context.sub_block_motion_vectors[index][ref_list];
|
||||
if (block_vector != sub_8x8_mvs[0])
|
||||
sub_8x8_mvs[destination_index++] = block_vector;
|
||||
}
|
||||
|
|
|
@ -105,19 +105,19 @@ private:
|
|||
DecoderErrorOr<void> decode_block(TileContext&, u32 row, u32 column, BlockSubsize subsize);
|
||||
DecoderErrorOr<void> mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> intra_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> intra_segment_id();
|
||||
DecoderErrorOr<void> read_skip(FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
bool seg_feature_active(u8 feature);
|
||||
DecoderErrorOr<void> read_tx_size(BlockContext const&, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select);
|
||||
DecoderErrorOr<void> set_intra_segment_id(BlockContext&);
|
||||
DecoderErrorOr<bool> read_should_skip_residuals(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
bool seg_feature_active(BlockContext const&, u8 feature);
|
||||
DecoderErrorOr<TXSize> read_tx_size(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select);
|
||||
DecoderErrorOr<void> inter_frame_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> inter_segment_id(BlockContext const&);
|
||||
DecoderErrorOr<void> set_inter_segment_id(BlockContext&);
|
||||
u8 get_segment_id(BlockContext const&);
|
||||
DecoderErrorOr<void> read_is_inter(FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<bool> read_is_inter(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> intra_block_mode_info(BlockContext&);
|
||||
DecoderErrorOr<void> inter_block_mode_info(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> read_ref_frames(BlockContext&, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> assign_mv(BlockContext const&, bool is_compound);
|
||||
DecoderErrorOr<void> read_mv(BlockContext const&, u8 ref);
|
||||
DecoderErrorOr<MotionVectorPair> assign_mv(BlockContext const&);
|
||||
DecoderErrorOr<MotionVector> read_mv(BlockContext const&, u8 ref);
|
||||
DecoderErrorOr<i32> read_mv_component(u8 component);
|
||||
DecoderErrorOr<bool> residual(BlockContext&, bool has_block_above, bool has_block_left);
|
||||
DecoderErrorOr<bool> tokens(BlockContext&, size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
|
||||
|
@ -167,25 +167,6 @@ private:
|
|||
Vector<u8> m_above_partition_context;
|
||||
Vector<u8> m_left_partition_context;
|
||||
|
||||
u8 m_segment_id { 0 };
|
||||
// FIXME: Should this be an enum?
|
||||
// skip equal to 0 indicates that there may be some transform coefficients to read for this block; skip equal to 1
|
||||
// indicates that there are no transform coefficients.
|
||||
//
|
||||
// skip may be set to 0 even if transform blocks contain immediate end of block markers.
|
||||
bool m_skip { false };
|
||||
TXSize m_max_tx_size { TX_4x4 };
|
||||
TXSize m_tx_size { TX_4x4 };
|
||||
ReferenceFramePair m_ref_frame;
|
||||
bool m_is_inter { false };
|
||||
PredictionMode m_y_mode { 0 };
|
||||
Array<PredictionMode, 4> m_block_sub_modes;
|
||||
u8 m_num_4x4_w { 0 };
|
||||
u8 m_num_4x4_h { 0 };
|
||||
PredictionMode m_uv_mode { 0 }; // FIXME: Is u8 the right size?
|
||||
// The current block's interpolation filter.
|
||||
InterpolationFilter m_interp_filter { EightTap };
|
||||
MotionVectorPair m_mv;
|
||||
MotionVectorPair m_near_mv;
|
||||
MotionVectorPair m_nearest_mv;
|
||||
MotionVectorPair m_best_mv;
|
||||
|
@ -205,8 +186,6 @@ private:
|
|||
ReferenceMode m_reference_mode;
|
||||
ReferenceFrameType m_comp_fixed_ref;
|
||||
ReferenceFramePair m_comp_var_ref;
|
||||
// FIXME: Use Array<MotionVectorPair, 4> instead.
|
||||
Array<Array<MotionVector, 4>, 2> m_block_mvs;
|
||||
|
||||
MotionVectorPair m_candidate_mv;
|
||||
ReferenceFramePair m_candidate_frame;
|
||||
|
|
Loading…
Reference in a new issue