mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 05:57:44 +00:00
LibVideo/VP9: Remove m_mi_row and col fields from the parser
These are now passed as parameters to each function that uses them. These will later be moved to a struct to further reduce the amount of parameters that get passed around. Above and left per-frame block contexts are now also parameters passed to the functions that use them instead of being retrieved when needed from a field. This will allow them to be more easily moved to a tile- specific context later.
This commit is contained in:
parent
4a4aa697d9
commit
10d207959d
4 changed files with 94 additions and 120 deletions
|
@ -721,7 +721,7 @@ MotionVector Decoder::select_motion_vector(u8 plane, u8 ref_list, u32 block_inde
|
|||
+ m_parser->m_block_mvs[ref_list][2] + m_parser->m_block_mvs[ref_list][3]);
|
||||
}
|
||||
|
||||
MotionVector Decoder::clamp_motion_vector(u8 plane, MotionVector vector)
|
||||
MotionVector Decoder::clamp_motion_vector(u8 plane, u32 block_row, u32 block_column, MotionVector vector)
|
||||
{
|
||||
// FIXME: This function is named very similarly to Parser::clamp_mv. Rename one or the other?
|
||||
|
||||
|
@ -736,12 +736,12 @@ MotionVector Decoder::clamp_motion_vector(u8 plane, MotionVector vector)
|
|||
// The output array clampedMv is specified by the following steps:
|
||||
i32 blocks_high = num_8x8_blocks_high_lookup[m_parser->m_mi_size];
|
||||
// Casts must be done here to prevent subtraction underflow from wrapping the values.
|
||||
i32 mb_to_top_edge = -(static_cast<i32>(m_parser->m_mi_row * MI_SIZE) * 16) >> subsampling_y;
|
||||
i32 mb_to_bottom_edge = (((static_cast<i32>(m_parser->m_mi_rows) - blocks_high - static_cast<i32>(m_parser->m_mi_row)) * MI_SIZE) * 16) >> subsampling_y;
|
||||
i32 mb_to_top_edge = -(static_cast<i32>(block_row * MI_SIZE) * 16) >> subsampling_y;
|
||||
i32 mb_to_bottom_edge = (((static_cast<i32>(m_parser->m_mi_rows) - blocks_high - static_cast<i32>(block_row)) * MI_SIZE) * 16) >> subsampling_y;
|
||||
|
||||
i32 blocks_wide = num_8x8_blocks_wide_lookup[m_parser->m_mi_size];
|
||||
i32 mb_to_left_edge = -(static_cast<i32>(m_parser->m_mi_col * MI_SIZE) * 16) >> subsampling_x;
|
||||
i32 mb_to_right_edge = (((static_cast<i32>(m_parser->m_mi_cols) - blocks_wide - static_cast<i32>(m_parser->m_mi_col)) * MI_SIZE) * 16) >> subsampling_x;
|
||||
i32 mb_to_left_edge = -(static_cast<i32>(block_column * MI_SIZE) * 16) >> subsampling_x;
|
||||
i32 mb_to_right_edge = (((static_cast<i32>(m_parser->m_mi_cols) - blocks_wide - static_cast<i32>(block_column)) * MI_SIZE) * 16) >> subsampling_x;
|
||||
|
||||
i32 subpel_left = (INTERP_EXTEND + ((blocks_wide * MI_SIZE) >> subsampling_x)) << SUBPEL_BITS;
|
||||
i32 subpel_right = subpel_left - SUBPEL_SHIFTS;
|
||||
|
@ -753,7 +753,7 @@ MotionVector Decoder::clamp_motion_vector(u8 plane, MotionVector vector)
|
|||
};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 x, u32 y, u32 width, u32 height, u32 block_index, Span<u16> block_buffer)
|
||||
DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 block_row, u32 block_column, u32 x, u32 y, u32 width, u32 height, u32 block_index, Span<u16> block_buffer)
|
||||
{
|
||||
VERIFY(width <= maximum_block_dimensions && height <= maximum_block_dimensions);
|
||||
// 2. The motion vector selection process in section 8.5.2.1 is invoked with plane, refList, blockIdx as inputs
|
||||
|
@ -762,7 +762,7 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 x,
|
|||
|
||||
// 3. The motion vector clamping process in section 8.5.2.2 is invoked with plane, mv as inputs and the output
|
||||
// being the clamped motion vector clampedMv
|
||||
auto clamped_vector = clamp_motion_vector(plane, motion_vector);
|
||||
auto clamped_vector = clamp_motion_vector(plane, block_row, block_column, motion_vector);
|
||||
|
||||
// 4. The motion vector scaling process in section 8.5.2.3 is invoked with plane, refList, x, y, clampedMv as
|
||||
// inputs and the output being the initial location startX, startY, and the step sizes stepX, stepY.
|
||||
|
@ -923,7 +923,7 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, u8 ref_list, u32 x,
|
|||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Decoder::predict_inter(u8 plane, u32 x, u32 y, u32 width, u32 height, u32 block_index)
|
||||
DecoderErrorOr<void> Decoder::predict_inter(u8 plane, u32 block_row, u32 block_column, u32 x, u32 y, u32 width, u32 height, u32 block_index)
|
||||
{
|
||||
// The inter prediction process is invoked for inter coded blocks. When MiSize is smaller than BLOCK_8X8, the
|
||||
// prediction is done with a granularity of 4x4 samples, otherwise the whole plane is predicted at the same time.
|
||||
|
@ -942,7 +942,7 @@ DecoderErrorOr<void> Decoder::predict_inter(u8 plane, u32 x, u32 y, u32 width, u
|
|||
// 2. through 5.
|
||||
Array<u16, maximum_block_size> predicted_buffer;
|
||||
auto predicted_span = predicted_buffer.span().trim(width * height);
|
||||
TRY(predict_inter_block(plane, 0, x, y, width, height, block_index, predicted_span));
|
||||
TRY(predict_inter_block(plane, 0, block_row, block_column, x, y, width, height, block_index, predicted_span));
|
||||
auto predicted_buffer_at = [&](Span<u16> buffer, u32 row, u32 column) -> u16& {
|
||||
return buffer[row * width + column];
|
||||
};
|
||||
|
@ -976,7 +976,7 @@ DecoderErrorOr<void> Decoder::predict_inter(u8 plane, u32 x, u32 y, u32 width, u
|
|||
// for i = 0..h-1 and j = 0..w-1.
|
||||
Array<u16, maximum_block_size> second_predicted_buffer;
|
||||
auto second_predicted_span = second_predicted_buffer.span().trim(width * height);
|
||||
TRY(predict_inter_block(plane, 1, x, y, width, height, block_index, second_predicted_span));
|
||||
TRY(predict_inter_block(plane, 1, block_row, block_column, x, y, width, height, block_index, second_predicted_span));
|
||||
|
||||
for (auto i = 0u; i < height_in_frame_buffer; i++) {
|
||||
for (auto j = 0u; j < width_in_frame_buffer; j++)
|
||||
|
|
|
@ -61,15 +61,15 @@ private:
|
|||
DecoderErrorOr<void> predict_intra(u8 plane, u32 x, u32 y, bool have_left, bool have_above, bool not_on_right, TXSize tx_size, u32 block_index);
|
||||
|
||||
// (8.5.1) Inter prediction process
|
||||
DecoderErrorOr<void> predict_inter(u8 plane, u32 x, u32 y, u32 width, u32 height, u32 block_index);
|
||||
DecoderErrorOr<void> predict_inter(u8 plane, u32 block_row, u32 block_column, u32 x, u32 y, u32 width, u32 height, u32 block_index);
|
||||
// (8.5.2.1) Motion vector selection process
|
||||
MotionVector select_motion_vector(u8 plane, u8 ref_list, u32 block_index);
|
||||
// (8.5.2.2) Motion vector clamping process
|
||||
MotionVector clamp_motion_vector(u8 plane, MotionVector vector);
|
||||
MotionVector clamp_motion_vector(u8 plane, u32 block_row, u32 block_column, MotionVector vector);
|
||||
// (8.5.2.3) Motion vector scaling process
|
||||
DecoderErrorOr<MotionVector> scale_motion_vector(u8 plane, u8 ref_list, u32 x, u32 y, MotionVector vector);
|
||||
// From (8.5.1) Inter prediction process, steps 2-5
|
||||
DecoderErrorOr<void> predict_inter_block(u8 plane, u8 ref_list, u32 x, u32 y, u32 width, u32 height, u32 block_index, Span<u16> block_buffer);
|
||||
DecoderErrorOr<void> predict_inter_block(u8 plane, u8 ref_list, u32 block_row, u32 block_column, u32 x, u32 y, u32 width, u32 height, u32 block_index, Span<u16> block_buffer);
|
||||
|
||||
/* (8.6) Reconstruction and Dequantization */
|
||||
|
||||
|
|
|
@ -929,16 +929,14 @@ size_t Parser::get_image_index(u32 row, u32 column) const
|
|||
return row * m_mi_cols + column;
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::decode_block(u32 row, u32 col, BlockSubsize subsize)
|
||||
DecoderErrorOr<void> Parser::decode_block(u32 row, u32 column, BlockSubsize subsize)
|
||||
{
|
||||
m_mi_row = row;
|
||||
m_mi_col = col;
|
||||
m_mi_size = subsize;
|
||||
m_available_u = row > 0;
|
||||
m_available_l = col > m_mi_col_start;
|
||||
TRY(mode_info());
|
||||
auto above_context = row > 0 ? m_frame_block_contexts.at(row - 1, column) : FrameBlockContext();
|
||||
auto left_context = column > m_mi_col_start ? m_frame_block_contexts.at(row, column - 1) : FrameBlockContext();
|
||||
TRY(mode_info(row, column, above_context, left_context));
|
||||
m_eob_total = 0;
|
||||
TRY(residual());
|
||||
TRY(residual(row, column, above_context.is_available, left_context.is_available));
|
||||
if (m_is_inter && subsize >= Block_8x8 && m_eob_total == 0)
|
||||
m_skip = true;
|
||||
|
||||
|
@ -947,36 +945,34 @@ DecoderErrorOr<void> Parser::decode_block(u32 row, u32 col, BlockSubsize subsize
|
|||
// See here:
|
||||
// https://github.com/webmproject/libvpx/blob/705bf9de8c96cfe5301451f1d7e5c90a41c64e5f/vp9/decoder/vp9_decodeframe.c#L917
|
||||
auto maximum_block_y = min<u32>(num_8x8_blocks_high_lookup[subsize], m_mi_rows - row);
|
||||
auto maximum_block_x = min<u32>(num_8x8_blocks_wide_lookup[subsize], m_mi_cols - col);
|
||||
auto maximum_block_x = min<u32>(num_8x8_blocks_wide_lookup[subsize], m_mi_cols - column);
|
||||
|
||||
for (size_t y = 0; y < maximum_block_y; y++) {
|
||||
for (size_t x = 0; x < maximum_block_x; x++)
|
||||
m_frame_block_contexts.at(row + y, col + x) = 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 };
|
||||
m_frame_block_contexts.at(row + y, column + x) = 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 };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::mode_info()
|
||||
DecoderErrorOr<void> Parser::mode_info(u32 row, u32 column, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
if (m_frame_is_intra)
|
||||
TRY(intra_frame_mode_info());
|
||||
TRY(intra_frame_mode_info(above_context, left_context));
|
||||
else
|
||||
TRY(inter_frame_mode_info());
|
||||
TRY(inter_frame_mode_info(row, column, above_context, left_context));
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::intra_frame_mode_info()
|
||||
DecoderErrorOr<void> Parser::intra_frame_mode_info(FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
TRY(intra_segment_id());
|
||||
TRY(read_skip());
|
||||
TRY(read_tx_size(true));
|
||||
TRY(read_skip(above_context, left_context));
|
||||
TRY(read_tx_size(above_context, left_context, true));
|
||||
m_ref_frame[0] = IntraFrame;
|
||||
m_ref_frame[1] = None;
|
||||
m_is_inter = false;
|
||||
// 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.
|
||||
auto above_context = get_above_context();
|
||||
auto left_context = get_left_context();
|
||||
if (m_mi_size >= Block_8x8) {
|
||||
m_y_mode = TRY_READ(TreeParser::parse_default_intra_mode(*m_bit_stream, *m_probability_tables, m_mi_size, above_context, left_context, m_block_sub_modes, 0, 0));
|
||||
for (auto& block_sub_mode : m_block_sub_modes)
|
||||
|
@ -1011,26 +1007,12 @@ DecoderErrorOr<void> Parser::intra_segment_id()
|
|||
return {};
|
||||
}
|
||||
|
||||
FrameBlockContext Parser::get_above_context() const
|
||||
{
|
||||
if (!m_available_u)
|
||||
return FrameBlockContext { .is_available = false };
|
||||
return m_frame_block_contexts.at(m_mi_row - 1, m_mi_col);
|
||||
}
|
||||
|
||||
FrameBlockContext Parser::get_left_context() const
|
||||
{
|
||||
if (!m_available_l)
|
||||
return FrameBlockContext { .is_available = false };
|
||||
return m_frame_block_contexts.at(m_mi_row, m_mi_col - 1);
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_skip()
|
||||
DecoderErrorOr<void> Parser::read_skip(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, get_above_context(), get_left_context()));
|
||||
m_skip = TRY_READ(TreeParser::parse_skip(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, above_context, left_context));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -1040,37 +1022,37 @@ bool Parser::seg_feature_active(u8 feature)
|
|||
return m_segmentation_enabled && m_feature_enabled[m_segment_id][feature];
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_tx_size(bool allow_select)
|
||||
DecoderErrorOr<void> Parser::read_tx_size(FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select)
|
||||
{
|
||||
m_max_tx_size = max_txsize_lookup[m_mi_size];
|
||||
if (allow_select && m_tx_mode == TXModeSelect && m_mi_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, get_above_context(), get_left_context()));
|
||||
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 {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::inter_frame_mode_info()
|
||||
DecoderErrorOr<void> Parser::inter_frame_mode_info(u32 row, u32 column, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
TRY(inter_segment_id());
|
||||
TRY(read_skip());
|
||||
TRY(read_is_inter());
|
||||
TRY(read_tx_size(!m_skip || !m_is_inter));
|
||||
TRY(inter_segment_id(row, column));
|
||||
TRY(read_skip(above_context, left_context));
|
||||
TRY(read_is_inter(above_context, left_context));
|
||||
TRY(read_tx_size(above_context, left_context, !m_skip || !m_is_inter));
|
||||
if (m_is_inter) {
|
||||
TRY(inter_block_mode_info());
|
||||
TRY(inter_block_mode_info(row, column, above_context, left_context));
|
||||
} else {
|
||||
TRY(intra_block_mode_info());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::inter_segment_id()
|
||||
DecoderErrorOr<void> Parser::inter_segment_id(u32 row, u32 column)
|
||||
{
|
||||
if (!m_segmentation_enabled) {
|
||||
m_segment_id = 0;
|
||||
return {};
|
||||
}
|
||||
auto predicted_segment_id = get_segment_id();
|
||||
auto predicted_segment_id = get_segment_id(row, column);
|
||||
if (!m_segmentation_update_map) {
|
||||
m_segment_id = predicted_segment_id;
|
||||
return {};
|
||||
|
@ -1080,48 +1062,48 @@ DecoderErrorOr<void> Parser::inter_segment_id()
|
|||
return {};
|
||||
}
|
||||
|
||||
auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(*m_bit_stream, m_segmentation_pred_prob, m_left_seg_pred_context[m_mi_row], m_above_seg_pred_context[m_mi_col]));
|
||||
auto seg_id_predicted = TRY_READ(TreeParser::parse_segment_id_predicted(*m_bit_stream, m_segmentation_pred_prob, m_left_seg_pred_context[row], m_above_seg_pred_context[column]));
|
||||
if (seg_id_predicted)
|
||||
m_segment_id = predicted_segment_id;
|
||||
else
|
||||
m_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[m_mi_size]; i++) {
|
||||
auto index = m_mi_col + i;
|
||||
auto index = column + i;
|
||||
// (7.4.1) AboveSegPredContext[ i ] only needs to be set to 0 for i = 0..MiCols-1.
|
||||
if (index < m_above_seg_pred_context.size())
|
||||
m_above_seg_pred_context[index] = seg_id_predicted;
|
||||
}
|
||||
for (size_t i = 0; i < num_8x8_blocks_high_lookup[m_mi_size]; i++) {
|
||||
auto index = m_mi_row + i;
|
||||
auto index = row + i;
|
||||
// (7.4.1) LeftSegPredContext[ i ] only needs to be set to 0 for i = 0..MiRows-1.
|
||||
if (index < m_above_seg_pred_context.size())
|
||||
m_left_seg_pred_context[m_mi_row + i] = seg_id_predicted;
|
||||
m_left_seg_pred_context[row + i] = seg_id_predicted;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
u8 Parser::get_segment_id()
|
||||
u8 Parser::get_segment_id(u32 row, u32 column)
|
||||
{
|
||||
auto bw = num_8x8_blocks_wide_lookup[m_mi_size];
|
||||
auto bh = num_8x8_blocks_high_lookup[m_mi_size];
|
||||
auto xmis = min(m_mi_cols - m_mi_col, (u32)bw);
|
||||
auto ymis = min(m_mi_rows - m_mi_row, (u32)bh);
|
||||
auto xmis = min(m_mi_cols - column, (u32)bw);
|
||||
auto ymis = min(m_mi_rows - row, (u32)bh);
|
||||
u8 segment = 7;
|
||||
for (size_t y = 0; y < ymis; y++) {
|
||||
for (size_t x = 0; x < xmis; x++) {
|
||||
segment = min(segment, m_previous_block_contexts.index_at(m_mi_row + y, m_mi_col + x));
|
||||
segment = min(segment, m_previous_block_contexts.index_at(row + y, column + x));
|
||||
}
|
||||
}
|
||||
return segment;
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_is_inter()
|
||||
DecoderErrorOr<void> Parser::read_is_inter(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, get_above_context(), get_left_context()));
|
||||
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 {};
|
||||
}
|
||||
|
||||
|
@ -1152,13 +1134,13 @@ DecoderErrorOr<void> Parser::intra_block_mode_info()
|
|||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::inter_block_mode_info()
|
||||
DecoderErrorOr<void> Parser::inter_block_mode_info(u32 row, u32 column, FrameBlockContext above_context, FrameBlockContext left_context)
|
||||
{
|
||||
TRY(read_ref_frames());
|
||||
TRY(read_ref_frames(above_context, left_context));
|
||||
for (auto j = 0; j < 2; j++) {
|
||||
if (m_ref_frame[j] > IntraFrame) {
|
||||
find_mv_refs(m_ref_frame[j], -1);
|
||||
find_best_ref_mvs(j);
|
||||
find_mv_refs(row, column, m_ref_frame[j], -1);
|
||||
find_best_ref_mvs(row, column, j);
|
||||
}
|
||||
}
|
||||
auto is_compound = m_ref_frame[1] > IntraFrame;
|
||||
|
@ -1168,7 +1150,7 @@ DecoderErrorOr<void> Parser::inter_block_mode_info()
|
|||
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_interpolation_filter == Switchable)
|
||||
m_interp_filter = TRY_READ(TreeParser::parse_interpolation_filter(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, get_above_context(), get_left_context()));
|
||||
m_interp_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 = m_interpolation_filter;
|
||||
if (m_mi_size < Block_8x8) {
|
||||
|
@ -1179,7 +1161,7 @@ DecoderErrorOr<void> Parser::inter_block_mode_info()
|
|||
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++)
|
||||
append_sub8x8_mvs(idy * 2 + idx, j);
|
||||
append_sub8x8_mvs(row, column, idy * 2 + idx, j);
|
||||
}
|
||||
TRY(assign_mv(is_compound));
|
||||
for (auto y = 0; y < m_num_4x4_h; y++) {
|
||||
|
@ -1203,7 +1185,7 @@ DecoderErrorOr<void> Parser::inter_block_mode_info()
|
|||
return {};
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::read_ref_frames()
|
||||
DecoderErrorOr<void> Parser::read_ref_frames(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]);
|
||||
|
@ -1211,8 +1193,6 @@ DecoderErrorOr<void> Parser::read_ref_frames()
|
|||
return {};
|
||||
}
|
||||
ReferenceMode comp_mode;
|
||||
auto above_context = get_above_context();
|
||||
auto left_context = get_left_context();
|
||||
if (m_reference_mode == ReferenceModeSelect)
|
||||
comp_mode = TRY_READ(TreeParser::parse_comp_mode(*m_bit_stream, *m_probability_tables, *m_syntax_element_counter, m_comp_fixed_ref, above_context, left_context));
|
||||
else
|
||||
|
@ -1311,7 +1291,7 @@ Gfx::Size<size_t> Parser::get_decoded_size_for_plane(u8 plane)
|
|||
return { point.x(), point.y() };
|
||||
}
|
||||
|
||||
DecoderErrorOr<void> Parser::residual()
|
||||
DecoderErrorOr<void> Parser::residual(u32 row, u32 column, bool has_block_above, bool has_block_left)
|
||||
{
|
||||
auto block_size = m_mi_size < Block_8x8 ? Block_8x8 : static_cast<BlockSubsize>(m_mi_size);
|
||||
for (u8 plane = 0; plane < 3; plane++) {
|
||||
|
@ -1322,17 +1302,17 @@ DecoderErrorOr<void> Parser::residual()
|
|||
auto num_4x4_h = num_4x4_blocks_high_lookup[plane_size];
|
||||
auto sub_x = (plane > 0) ? m_subsampling_x : 0;
|
||||
auto sub_y = (plane > 0) ? m_subsampling_y : 0;
|
||||
auto base_x = (m_mi_col * 8) >> sub_x;
|
||||
auto base_y = (m_mi_row * 8) >> sub_y;
|
||||
auto base_x = (column * 8) >> sub_x;
|
||||
auto base_y = (row * 8) >> sub_y;
|
||||
if (m_is_inter) {
|
||||
if (m_mi_size < Block_8x8) {
|
||||
for (auto y = 0; y < num_4x4_h; y++) {
|
||||
for (auto x = 0; x < num_4x4_w; x++) {
|
||||
TRY(m_decoder.predict_inter(plane, base_x + (4 * x), base_y + (4 * y), 4, 4, (y * num_4x4_w) + x));
|
||||
TRY(m_decoder.predict_inter(plane, row, column, base_x + (4 * x), base_y + (4 * y), 4, 4, (y * num_4x4_w) + x));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TRY(m_decoder.predict_inter(plane, base_x, base_y, num_4x4_w * 4, num_4x4_h * 4, 0));
|
||||
TRY(m_decoder.predict_inter(plane, row, column, base_x, base_y, num_4x4_w * 4, num_4x4_h * 4, 0));
|
||||
}
|
||||
}
|
||||
auto max_x = (m_mi_cols * 8) >> sub_x;
|
||||
|
@ -1345,7 +1325,7 @@ DecoderErrorOr<void> Parser::residual()
|
|||
auto non_zero = false;
|
||||
if (start_x < max_x && start_y < max_y) {
|
||||
if (!m_is_inter)
|
||||
TRY(m_decoder.predict_intra(plane, start_x, start_y, m_available_l || x > 0, m_available_u || y > 0, (x + step) < num_4x4_w, tx_size, block_index));
|
||||
TRY(m_decoder.predict_intra(plane, 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) {
|
||||
non_zero = TRY(tokens(plane, start_x, start_y, tx_size, block_index));
|
||||
TRY(m_decoder.reconstruct(plane, start_x, start_y, tx_size));
|
||||
|
@ -1541,16 +1521,16 @@ void Parser::if_diff_ref_frame_add_mv(u32 candidate_row, u32 candidate_column, R
|
|||
}
|
||||
}
|
||||
|
||||
MotionVector Parser::clamp_mv(MotionVector vector, i32 border)
|
||||
MotionVector Parser::clamp_mv(u32 row, u32 column, MotionVector vector, i32 border)
|
||||
{
|
||||
i32 blocks_high = num_8x8_blocks_high_lookup[m_mi_size];
|
||||
// Casts must be done here to prevent subtraction underflow from wrapping the values.
|
||||
i32 mb_to_top_edge = -8 * (static_cast<i32>(m_mi_row) * MI_SIZE);
|
||||
i32 mb_to_bottom_edge = 8 * ((static_cast<i32>(m_mi_rows) - blocks_high - static_cast<i32>(m_mi_row)) * MI_SIZE);
|
||||
i32 mb_to_top_edge = -8 * (static_cast<i32>(row) * MI_SIZE);
|
||||
i32 mb_to_bottom_edge = 8 * ((static_cast<i32>(m_mi_rows) - blocks_high - static_cast<i32>(row)) * MI_SIZE);
|
||||
|
||||
i32 blocks_wide = num_8x8_blocks_wide_lookup[m_mi_size];
|
||||
i32 mb_to_left_edge = -8 * (static_cast<i32>(m_mi_col) * MI_SIZE);
|
||||
i32 mb_to_right_edge = 8 * ((static_cast<i32>(m_mi_cols) - blocks_wide - static_cast<i32>(m_mi_col)) * MI_SIZE);
|
||||
i32 mb_to_left_edge = -8 * (static_cast<i32>(column) * MI_SIZE);
|
||||
i32 mb_to_right_edge = 8 * ((static_cast<i32>(m_mi_cols) - blocks_wide - static_cast<i32>(column)) * MI_SIZE);
|
||||
|
||||
return {
|
||||
clip_3(mb_to_top_edge - border, mb_to_bottom_edge + border, vector.row()),
|
||||
|
@ -1558,14 +1538,14 @@ MotionVector Parser::clamp_mv(MotionVector vector, i32 border)
|
|||
};
|
||||
}
|
||||
|
||||
void Parser::clamp_mv_ref(u8 i)
|
||||
void Parser::clamp_mv_ref(u32 row, u32 column, u8 i)
|
||||
{
|
||||
MotionVector& vector = m_ref_list_mv[i];
|
||||
vector = clamp_mv(vector, MV_BORDER);
|
||||
vector = clamp_mv(row, column, vector, MV_BORDER);
|
||||
}
|
||||
|
||||
// 6.5.1 Find MV refs syntax
|
||||
void Parser::find_mv_refs(ReferenceFrameType reference_frame, i32 block)
|
||||
void Parser::find_mv_refs(u32 row, u32 column, ReferenceFrameType reference_frame, i32 block)
|
||||
{
|
||||
m_ref_mv_count = 0;
|
||||
bool different_ref_found = false;
|
||||
|
@ -1574,7 +1554,7 @@ void Parser::find_mv_refs(ReferenceFrameType reference_frame, i32 block)
|
|||
m_ref_list_mv[0] = {};
|
||||
m_ref_list_mv[1] = {};
|
||||
|
||||
MotionVector base_coordinates = MotionVector(m_mi_row, m_mi_col);
|
||||
MotionVector base_coordinates = MotionVector(row, column);
|
||||
|
||||
for (auto i = 0u; i < 2; i++) {
|
||||
auto offset_vector = mv_ref_blocks[m_mi_size][i];
|
||||
|
@ -1612,7 +1592,7 @@ void Parser::find_mv_refs(ReferenceFrameType reference_frame, i32 block)
|
|||
}
|
||||
}
|
||||
if (m_use_prev_frame_mvs)
|
||||
if_same_ref_frame_add_mv(m_mi_row, m_mi_col, reference_frame, true);
|
||||
if_same_ref_frame_add_mv(row, column, reference_frame, true);
|
||||
|
||||
if (different_ref_found) {
|
||||
for (auto i = 0u; i < MVREF_NEIGHBOURS; i++) {
|
||||
|
@ -1622,11 +1602,11 @@ void Parser::find_mv_refs(ReferenceFrameType reference_frame, i32 block)
|
|||
}
|
||||
}
|
||||
if (m_use_prev_frame_mvs)
|
||||
if_diff_ref_frame_add_mv(m_mi_row, m_mi_col, reference_frame, true);
|
||||
if_diff_ref_frame_add_mv(row, column, reference_frame, true);
|
||||
|
||||
m_mode_context[reference_frame] = counter_to_context[context_counter];
|
||||
for (auto i = 0u; i < MAX_MV_REF_CANDIDATES; i++)
|
||||
clamp_mv_ref(i);
|
||||
clamp_mv_ref(row, column, i);
|
||||
}
|
||||
|
||||
bool Parser::use_mv_hp(MotionVector const& vector)
|
||||
|
@ -1634,7 +1614,7 @@ bool Parser::use_mv_hp(MotionVector const& vector)
|
|||
return (abs(vector.row()) >> 3) < COMPANDED_MVREF_THRESH && (abs(vector.column()) >> 3) < COMPANDED_MVREF_THRESH;
|
||||
}
|
||||
|
||||
void Parser::find_best_ref_mvs(u8 ref_list)
|
||||
void Parser::find_best_ref_mvs(u32 row, u32 column, u8 ref_list)
|
||||
{
|
||||
for (auto i = 0u; i < MAX_MV_REF_CANDIDATES; i++) {
|
||||
auto delta = m_ref_list_mv[i];
|
||||
|
@ -1647,7 +1627,7 @@ void Parser::find_best_ref_mvs(u8 ref_list)
|
|||
delta_column += delta_column > 0 ? -1 : 1;
|
||||
}
|
||||
delta = { delta_row, delta_column };
|
||||
m_ref_list_mv[i] = clamp_mv(delta, (BORDERINPIXELS - INTERP_EXTEND) << 3);
|
||||
m_ref_list_mv[i] = clamp_mv(row, column, delta, (BORDERINPIXELS - INTERP_EXTEND) << 3);
|
||||
}
|
||||
|
||||
m_nearest_mv[ref_list] = m_ref_list_mv[0];
|
||||
|
@ -1655,10 +1635,10 @@ void Parser::find_best_ref_mvs(u8 ref_list)
|
|||
m_best_mv[ref_list] = m_ref_list_mv[0];
|
||||
}
|
||||
|
||||
void Parser::append_sub8x8_mvs(i32 block, u8 ref_list)
|
||||
void Parser::append_sub8x8_mvs(u32 row, u32 column, i32 block, u8 ref_list)
|
||||
{
|
||||
MotionVector sub_8x8_mvs[2];
|
||||
find_mv_refs(m_ref_frame[ref_list], block);
|
||||
find_mv_refs(row, column, m_ref_frame[ref_list], block);
|
||||
auto destination_index = 0;
|
||||
if (block == 0) {
|
||||
for (auto i = 0u; i < 2; i++)
|
||||
|
|
|
@ -84,8 +84,6 @@ private:
|
|||
u8 inv_remap_prob(u8 delta_prob, u8 prob);
|
||||
u8 inv_recenter_nonneg(u8 v, u8 m);
|
||||
DecoderErrorOr<void> read_coef_probs();
|
||||
FrameBlockContext get_above_context() const;
|
||||
FrameBlockContext get_left_context() const;
|
||||
DecoderErrorOr<void> read_skip_prob();
|
||||
DecoderErrorOr<void> read_inter_mode_probs();
|
||||
DecoderErrorOr<void> read_interp_filter_probs();
|
||||
|
@ -105,24 +103,24 @@ private:
|
|||
DecoderErrorOr<void> decode_tile();
|
||||
void clear_left_context();
|
||||
DecoderErrorOr<void> decode_partition(u32 row, u32 column, BlockSubsize subsize);
|
||||
DecoderErrorOr<void> decode_block(u32 row, u32 col, BlockSubsize subsize);
|
||||
DecoderErrorOr<void> mode_info();
|
||||
DecoderErrorOr<void> intra_frame_mode_info();
|
||||
DecoderErrorOr<void> decode_block(u32 row, u32 column, BlockSubsize subsize);
|
||||
DecoderErrorOr<void> mode_info(u32 row, u32 column, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> intra_frame_mode_info(FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> intra_segment_id();
|
||||
DecoderErrorOr<void> read_skip();
|
||||
DecoderErrorOr<void> read_skip(FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
bool seg_feature_active(u8 feature);
|
||||
DecoderErrorOr<void> read_tx_size(bool allow_select);
|
||||
DecoderErrorOr<void> inter_frame_mode_info();
|
||||
DecoderErrorOr<void> inter_segment_id();
|
||||
u8 get_segment_id();
|
||||
DecoderErrorOr<void> read_is_inter();
|
||||
DecoderErrorOr<void> read_tx_size(FrameBlockContext above_context, FrameBlockContext left_context, bool allow_select);
|
||||
DecoderErrorOr<void> inter_frame_mode_info(u32 row, u32 column, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> inter_segment_id(u32 row, u32 column);
|
||||
u8 get_segment_id(u32 row, u32 column);
|
||||
DecoderErrorOr<void> read_is_inter(FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> intra_block_mode_info();
|
||||
DecoderErrorOr<void> inter_block_mode_info();
|
||||
DecoderErrorOr<void> read_ref_frames();
|
||||
DecoderErrorOr<void> inter_block_mode_info(u32 row, u32 column, FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> read_ref_frames(FrameBlockContext above_context, FrameBlockContext left_context);
|
||||
DecoderErrorOr<void> assign_mv(bool is_compound);
|
||||
DecoderErrorOr<void> read_mv(u8 ref);
|
||||
DecoderErrorOr<i32> read_mv_component(u8 component);
|
||||
DecoderErrorOr<void> residual();
|
||||
DecoderErrorOr<void> residual(u32 row, u32 column, bool has_block_above, bool has_block_left);
|
||||
TXSize get_uv_tx_size();
|
||||
BlockSubsize get_plane_block_size(u32 subsize, u8 plane);
|
||||
DecoderErrorOr<bool> tokens(size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
|
||||
|
@ -130,13 +128,13 @@ private:
|
|||
DecoderErrorOr<i32> read_coef(Token token);
|
||||
|
||||
/* (6.5) Motion Vector Prediction */
|
||||
void find_mv_refs(ReferenceFrameType, i32 block);
|
||||
void find_best_ref_mvs(u8 ref_list);
|
||||
void find_mv_refs(u32 row, u32 column, ReferenceFrameType, i32 block);
|
||||
void find_best_ref_mvs(u32 row, u32 column, u8 ref_list);
|
||||
bool use_mv_hp(MotionVector const& delta_mv);
|
||||
void append_sub8x8_mvs(i32 block, u8 ref_list);
|
||||
void append_sub8x8_mvs(u32 row, u32 column, i32 block, u8 ref_list);
|
||||
bool is_inside(i32 row, i32 column);
|
||||
void clamp_mv_ref(u8 i);
|
||||
MotionVector clamp_mv(MotionVector mvec, i32 border);
|
||||
void clamp_mv_ref(u32 row, u32 column, u8 i);
|
||||
MotionVector clamp_mv(u32 row, u32 column, MotionVector mvec, i32 border);
|
||||
size_t get_image_index(u32 row, u32 column) const;
|
||||
void get_block_mv(u32 candidate_row, u32 candidate_column, u8 ref_list, bool use_prev);
|
||||
void if_same_ref_frame_add_mv(u32 candidate_row, u32 candidate_column, ReferenceFrameType ref_frame, bool use_prev);
|
||||
|
@ -212,11 +210,7 @@ private:
|
|||
u32 m_mi_row_end { 0 };
|
||||
u32 m_mi_col_start { 0 };
|
||||
u32 m_mi_col_end { 0 };
|
||||
u32 m_mi_row { 0 };
|
||||
u32 m_mi_col { 0 };
|
||||
BlockSubsize m_mi_size { 0 };
|
||||
bool m_available_u { false };
|
||||
bool m_available_l { false };
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue