1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 08:27:46 +00:00

LibVideo: Make new DecoderError class to report useful errors

This allows runtime strings, so we can format the errors to make them
more helpful. Errors in the VP9 decoder will now print out a function,
filename and line number for where a read or bitstream requirement
has failed.

The DecoderErrorCategory enum will classify the errors so library users
can show general user-friendly error messages, while providing the
debug information separately.

Any non-DecoderErrorOr<> results can be wrapped by DECODER_TRY to
return from decoder functions. This will also add the extra information
mentioned above to the error message.
This commit is contained in:
Zaggy1024 2022-09-13 19:40:37 -05:00 committed by Andrew Kaster
parent 72efd9a5ff
commit da9ff31166
5 changed files with 369 additions and 278 deletions

View file

@ -12,6 +12,8 @@
namespace Video::VP9 {
#define TRY_READ(expression) DECODER_TRY(DecoderErrorCategory::Corrupted, expression)
Parser::Parser(Decoder& decoder)
: m_probability_tables(make<ProbabilityTables>())
, m_tree_parser(make<TreeParser>(*this))
@ -40,7 +42,7 @@ void Parser::cleanup_tile_allocations()
}
/* (6.1) */
ErrorOr<void> Parser::parse_frame(ByteBuffer const& frame_data)
DecoderErrorOr<void> Parser::parse_frame(ByteBuffer const& frame_data)
{
m_bit_stream = make<BitStream>(frame_data.data(), frame_data.size());
m_syntax_element_counter = make<SyntaxElementCounter>();
@ -48,18 +50,18 @@ ErrorOr<void> Parser::parse_frame(ByteBuffer const& frame_data)
TRY(uncompressed_header());
dbgln("Finished reading uncompressed header");
if (!trailing_bits())
return Error::from_string_literal("parse_frame: Trailing bits were non-zero");
return DecoderError::corrupted("Trailing bits were non-zero"sv);
if (m_header_size_in_bytes == 0)
return Error::from_string_literal("parse_frame: Frame header is zero-sized");
return DecoderError::corrupted("Frame header is zero-sized"sv);
m_probability_tables->load_probs(m_frame_context_idx);
m_probability_tables->load_probs2(m_frame_context_idx);
m_syntax_element_counter->clear_counts();
TRY(m_bit_stream->init_bool(m_header_size_in_bytes));
TRY_READ(m_bit_stream->init_bool(m_header_size_in_bytes));
dbgln("Reading compressed header with size {}", m_header_size_in_bytes);
TRY(compressed_header());
dbgln("Finished reading compressed header");
TRY(m_bit_stream->exit_bool());
TRY_READ(m_bit_stream->exit_bool());
TRY(decode_tiles());
TRY(refresh_probs());
@ -77,7 +79,7 @@ bool Parser::trailing_bits()
return true;
}
ErrorOr<void> Parser::refresh_probs()
DecoderErrorOr<void> Parser::refresh_probs()
{
if (!m_error_resilient_mode && !m_frame_parallel_decoding_mode) {
m_probability_tables->load_probs(m_frame_context_idx);
@ -92,20 +94,34 @@ ErrorOr<void> Parser::refresh_probs()
return {};
}
/* (6.2) */
ErrorOr<void> Parser::uncompressed_header()
DecoderErrorOr<FrameType> Parser::read_frame_type()
{
auto frame_marker = TRY(m_bit_stream->read_bits(2));
if (TRY_READ(m_bit_stream->read_bit()))
return NonKeyFrame;
return KeyFrame;
}
DecoderErrorOr<ColorRange> Parser::read_color_range()
{
if (TRY_READ(m_bit_stream->read_bit()))
return FullSwing;
return StudioSwing;
}
/* (6.2) */
DecoderErrorOr<void> Parser::uncompressed_header()
{
auto frame_marker = TRY_READ(m_bit_stream->read_bits(2));
if (frame_marker != 2)
return Error::from_string_literal("uncompressed_header: Frame marker must be 2");
auto profile_low_bit = TRY(m_bit_stream->read_bit());
auto profile_high_bit = TRY(m_bit_stream->read_bit());
return DecoderError::corrupted("uncompressed_header: Frame marker must be 2"sv);
auto profile_low_bit = TRY_READ(m_bit_stream->read_bit());
auto profile_high_bit = TRY_READ(m_bit_stream->read_bit());
m_profile = (profile_high_bit << 1u) + profile_low_bit;
if (m_profile == 3 && TRY(m_bit_stream->read_bit()))
return Error::from_string_literal("uncompressed_header: Profile 3 reserved bit was non-zero");
auto show_existing_frame = TRY(m_bit_stream->read_bit());
if (m_profile == 3 && TRY_READ(m_bit_stream->read_bit()))
return DecoderError::corrupted("uncompressed_header: Profile 3 reserved bit was non-zero"sv);
auto show_existing_frame = TRY_READ(m_bit_stream->read_bit());
if (show_existing_frame) {
m_frame_to_show_map_index = TRY(m_bit_stream->read_bits(3));
m_frame_to_show_map_index = TRY_READ(m_bit_stream->read_bits(3));
m_header_size_in_bytes = 0;
m_refresh_frame_flags = 0;
m_loop_filter_level = 0;
@ -114,8 +130,8 @@ ErrorOr<void> Parser::uncompressed_header()
m_last_frame_type = m_frame_type;
m_frame_type = TRY(read_frame_type());
m_show_frame = TRY(m_bit_stream->read_bit());
m_error_resilient_mode = TRY(m_bit_stream->read_bit());
m_show_frame = TRY_READ(m_bit_stream->read_bit());
m_error_resilient_mode = TRY_READ(m_bit_stream->read_bit());
if (m_frame_type == KeyFrame) {
TRY(frame_sync_code());
@ -125,10 +141,10 @@ ErrorOr<void> Parser::uncompressed_header()
m_refresh_frame_flags = 0xFF;
m_frame_is_intra = true;
} else {
m_frame_is_intra = !m_show_frame && TRY(m_bit_stream->read_bit());
m_frame_is_intra = !m_show_frame && TRY_READ(m_bit_stream->read_bit());
if (!m_error_resilient_mode) {
m_reset_frame_context = TRY(m_bit_stream->read_bits(2));
m_reset_frame_context = TRY_READ(m_bit_stream->read_bits(2));
} else {
m_reset_frame_context = 0;
}
@ -144,30 +160,30 @@ ErrorOr<void> Parser::uncompressed_header()
m_bit_depth = 8;
}
m_refresh_frame_flags = TRY(m_bit_stream->read_f8());
m_refresh_frame_flags = TRY_READ(m_bit_stream->read_f8());
TRY(frame_size());
TRY(render_size());
} else {
m_refresh_frame_flags = TRY(m_bit_stream->read_f8());
m_refresh_frame_flags = TRY_READ(m_bit_stream->read_f8());
for (auto i = 0; i < 3; i++) {
m_ref_frame_idx[i] = TRY(m_bit_stream->read_bits(3));
m_ref_frame_sign_bias[LastFrame + i] = TRY(m_bit_stream->read_bit());
m_ref_frame_idx[i] = TRY_READ(m_bit_stream->read_bits(3));
m_ref_frame_sign_bias[LastFrame + i] = TRY_READ(m_bit_stream->read_bit());
}
TRY(frame_size_with_refs());
m_allow_high_precision_mv = TRY(m_bit_stream->read_bit());
m_allow_high_precision_mv = TRY_READ(m_bit_stream->read_bit());
TRY(read_interpolation_filter());
}
}
if (!m_error_resilient_mode) {
m_refresh_frame_context = TRY(m_bit_stream->read_bit());
m_frame_parallel_decoding_mode = TRY(m_bit_stream->read_bit());
m_refresh_frame_context = TRY_READ(m_bit_stream->read_bit());
m_frame_parallel_decoding_mode = TRY_READ(m_bit_stream->read_bit());
} else {
m_refresh_frame_context = false;
m_frame_parallel_decoding_mode = true;
}
m_frame_context_idx = TRY(m_bit_stream->read_bits(2));
m_frame_context_idx = TRY_READ(m_bit_stream->read_bits(2));
if (m_frame_is_intra || m_error_resilient_mode) {
setup_past_independence();
if (m_frame_type == KeyFrame || m_error_resilient_mode || m_reset_frame_context == 3) {
@ -185,41 +201,41 @@ ErrorOr<void> Parser::uncompressed_header()
TRY(segmentation_params());
TRY(tile_info());
m_header_size_in_bytes = TRY(m_bit_stream->read_f16());
m_header_size_in_bytes = TRY_READ(m_bit_stream->read_f16());
return {};
}
ErrorOr<void> Parser::frame_sync_code()
DecoderErrorOr<void> Parser::frame_sync_code()
{
if (TRY(m_bit_stream->read_f8()) != 0x49)
return Error::from_string_literal("frame_sync_code: Byte 0 was not 0x49.");
if (TRY(m_bit_stream->read_f8()) != 0x83)
return Error::from_string_literal("frame_sync_code: Byte 1 was not 0x83.");
if (TRY(m_bit_stream->read_f8()) != 0x42)
return Error::from_string_literal("frame_sync_code: Byte 2 was not 0x42.");
if (TRY_READ(m_bit_stream->read_f8()) != 0x49)
return DecoderError::corrupted("frame_sync_code: Byte 0 was not 0x49."sv);
if (TRY_READ(m_bit_stream->read_f8()) != 0x83)
return DecoderError::corrupted("frame_sync_code: Byte 1 was not 0x83."sv);
if (TRY_READ(m_bit_stream->read_f8()) != 0x42)
return DecoderError::corrupted("frame_sync_code: Byte 2 was not 0x42."sv);
return {};
}
ErrorOr<void> Parser::color_config()
DecoderErrorOr<void> Parser::color_config()
{
if (m_profile >= 2) {
m_bit_depth = TRY(m_bit_stream->read_bit()) ? 12 : 10;
m_bit_depth = TRY_READ(m_bit_stream->read_bit()) ? 12 : 10;
} else {
m_bit_depth = 8;
}
auto color_space = TRY(m_bit_stream->read_bits(3));
auto color_space = TRY_READ(m_bit_stream->read_bits(3));
VERIFY(color_space <= RGB);
m_color_space = static_cast<ColorSpace>(color_space);
if (color_space != RGB) {
m_color_range = TRY(read_color_range());
if (m_profile == 1 || m_profile == 3) {
m_subsampling_x = TRY(m_bit_stream->read_bit());
m_subsampling_y = TRY(m_bit_stream->read_bit());
if (TRY(m_bit_stream->read_bit()))
return Error::from_string_literal("color_config: Subsampling reserved zero was set");
m_subsampling_x = TRY_READ(m_bit_stream->read_bit());
m_subsampling_y = TRY_READ(m_bit_stream->read_bit());
if (TRY_READ(m_bit_stream->read_bit()))
return DecoderError::corrupted("color_config: Subsampling reserved zero was set"sv);
} else {
m_subsampling_x = true;
m_subsampling_y = true;
@ -229,26 +245,26 @@ ErrorOr<void> Parser::color_config()
if (m_profile == 1 || m_profile == 3) {
m_subsampling_x = false;
m_subsampling_y = false;
if (TRY(m_bit_stream->read_bit()))
return Error::from_string_literal("color_config: RGB reserved zero was set");
if (TRY_READ(m_bit_stream->read_bit()))
return DecoderError::corrupted("color_config: RGB reserved zero was set"sv);
}
}
return {};
}
ErrorOr<void> Parser::frame_size()
DecoderErrorOr<void> Parser::frame_size()
{
m_frame_width = TRY(m_bit_stream->read_f16()) + 1;
m_frame_height = TRY(m_bit_stream->read_f16()) + 1;
m_frame_width = TRY_READ(m_bit_stream->read_f16()) + 1;
m_frame_height = TRY_READ(m_bit_stream->read_f16()) + 1;
compute_image_size();
return {};
}
ErrorOr<void> Parser::render_size()
DecoderErrorOr<void> Parser::render_size()
{
if (TRY(m_bit_stream->read_bit())) {
m_render_width = TRY(m_bit_stream->read_f16()) + 1;
m_render_height = TRY(m_bit_stream->read_f16()) + 1;
if (TRY_READ(m_bit_stream->read_bit())) {
m_render_width = TRY_READ(m_bit_stream->read_f16()) + 1;
m_render_height = TRY_READ(m_bit_stream->read_f16()) + 1;
} else {
m_render_width = m_frame_width;
m_render_height = m_frame_height;
@ -256,11 +272,11 @@ ErrorOr<void> Parser::render_size()
return {};
}
ErrorOr<void> Parser::frame_size_with_refs()
DecoderErrorOr<void> Parser::frame_size_with_refs()
{
bool found_ref;
for (auto frame_index : m_ref_frame_idx) {
found_ref = TRY(m_bit_stream->read_bit());
found_ref = TRY_READ(m_bit_stream->read_bit());
if (found_ref) {
dbgln("Reading size from ref frame {}", frame_index);
m_frame_width = m_ref_frame_width[frame_index];
@ -286,30 +302,30 @@ void Parser::compute_image_size()
m_sb64_rows = (m_mi_rows + 7u) >> 3u;
}
ErrorOr<void> Parser::read_interpolation_filter()
DecoderErrorOr<void> Parser::read_interpolation_filter()
{
if (TRY(m_bit_stream->read_bit())) {
if (TRY_READ(m_bit_stream->read_bit())) {
m_interpolation_filter = Switchable;
} else {
m_interpolation_filter = literal_to_type[TRY(m_bit_stream->read_bits(2))];
m_interpolation_filter = literal_to_type[TRY_READ(m_bit_stream->read_bits(2))];
}
return {};
}
ErrorOr<void> Parser::loop_filter_params()
DecoderErrorOr<void> Parser::loop_filter_params()
{
m_loop_filter_level = TRY(m_bit_stream->read_bits(6));
m_loop_filter_sharpness = TRY(m_bit_stream->read_bits(3));
m_loop_filter_delta_enabled = TRY(m_bit_stream->read_bit());
m_loop_filter_level = TRY_READ(m_bit_stream->read_bits(6));
m_loop_filter_sharpness = TRY_READ(m_bit_stream->read_bits(3));
m_loop_filter_delta_enabled = TRY_READ(m_bit_stream->read_bit());
if (m_loop_filter_delta_enabled) {
if (TRY(m_bit_stream->read_bit())) {
if (TRY_READ(m_bit_stream->read_bit())) {
for (auto& loop_filter_ref_delta : m_loop_filter_ref_deltas) {
if (TRY(m_bit_stream->read_bit()))
loop_filter_ref_delta = TRY(m_bit_stream->read_s(6));
if (TRY_READ(m_bit_stream->read_bit()))
loop_filter_ref_delta = TRY_READ(m_bit_stream->read_s(6));
}
for (auto& loop_filter_mode_delta : m_loop_filter_mode_deltas) {
if (TRY(m_bit_stream->read_bit()))
loop_filter_mode_delta = TRY(m_bit_stream->read_s(6));
if (TRY_READ(m_bit_stream->read_bit()))
loop_filter_mode_delta = TRY_READ(m_bit_stream->read_s(6));
}
}
}
@ -317,9 +333,9 @@ ErrorOr<void> Parser::loop_filter_params()
return {};
}
ErrorOr<void> Parser::quantization_params()
DecoderErrorOr<void> Parser::quantization_params()
{
auto base_q_idx = TRY(m_bit_stream->read_f8());
auto base_q_idx = TRY_READ(m_bit_stream->read_f8());
auto delta_q_y_dc = TRY(read_delta_q());
auto delta_q_uv_dc = TRY(read_delta_q());
auto delta_q_uv_ac = TRY(read_delta_q());
@ -327,44 +343,44 @@ ErrorOr<void> Parser::quantization_params()
return {};
}
ErrorOr<i8> Parser::read_delta_q()
DecoderErrorOr<i8> Parser::read_delta_q()
{
if (TRY(m_bit_stream->read_bit()))
return m_bit_stream->read_s(4);
if (TRY_READ(m_bit_stream->read_bit()))
return TRY_READ(m_bit_stream->read_s(4));
return 0;
}
ErrorOr<void> Parser::segmentation_params()
DecoderErrorOr<void> Parser::segmentation_params()
{
m_segmentation_enabled = TRY(m_bit_stream->read_bit());
m_segmentation_enabled = TRY_READ(m_bit_stream->read_bit());
if (!m_segmentation_enabled)
return {};
m_segmentation_update_map = TRY(m_bit_stream->read_bit());
m_segmentation_update_map = TRY_READ(m_bit_stream->read_bit());
if (m_segmentation_update_map) {
for (auto& segmentation_tree_prob : m_segmentation_tree_probs)
segmentation_tree_prob = TRY(read_prob());
m_segmentation_temporal_update = TRY(m_bit_stream->read_bit());
m_segmentation_temporal_update = TRY_READ(m_bit_stream->read_bit());
for (auto& segmentation_pred_prob : m_segmentation_pred_prob)
segmentation_pred_prob = m_segmentation_temporal_update ? TRY(read_prob()) : 255;
}
auto segmentation_update_data = (TRY(m_bit_stream->read_bit()));
auto segmentation_update_data = (TRY_READ(m_bit_stream->read_bit()));
if (!segmentation_update_data)
return {};
m_segmentation_abs_or_delta_update = TRY(m_bit_stream->read_bit());
m_segmentation_abs_or_delta_update = TRY_READ(m_bit_stream->read_bit());
for (auto i = 0; i < MAX_SEGMENTS; i++) {
for (auto j = 0; j < SEG_LVL_MAX; j++) {
auto feature_value = 0;
auto feature_enabled = TRY(m_bit_stream->read_bit());
auto feature_enabled = TRY_READ(m_bit_stream->read_bit());
m_feature_enabled[i][j] = feature_enabled;
if (feature_enabled) {
auto bits_to_read = segmentation_feature_bits[j];
feature_value = TRY(m_bit_stream->read_bits(bits_to_read));
feature_value = TRY_READ(m_bit_stream->read_bits(bits_to_read));
if (segmentation_feature_signed[j]) {
if (TRY(m_bit_stream->read_bit()))
if (TRY_READ(m_bit_stream->read_bit()))
feature_value = -feature_value;
}
}
@ -375,27 +391,27 @@ ErrorOr<void> Parser::segmentation_params()
return {};
}
ErrorOr<u8> Parser::read_prob()
DecoderErrorOr<u8> Parser::read_prob()
{
if (TRY(m_bit_stream->read_bit()))
return TRY(m_bit_stream->read_f8());
if (TRY_READ(m_bit_stream->read_bit()))
return TRY_READ(m_bit_stream->read_f8());
return 255;
}
ErrorOr<void> Parser::tile_info()
DecoderErrorOr<void> Parser::tile_info()
{
auto min_log2_tile_cols = calc_min_log2_tile_cols();
auto max_log2_tile_cols = calc_max_log2_tile_cols();
m_tile_cols_log2 = min_log2_tile_cols;
while (m_tile_cols_log2 < max_log2_tile_cols) {
if (TRY(m_bit_stream->read_bit()))
if (TRY_READ(m_bit_stream->read_bit()))
m_tile_cols_log2++;
else
break;
}
m_tile_rows_log2 = TRY(m_bit_stream->read_bit());
m_tile_rows_log2 = TRY_READ(m_bit_stream->read_bit());
if (m_tile_rows_log2) {
m_tile_rows_log2 += TRY(m_bit_stream->read_bit());
m_tile_rows_log2 += TRY_READ(m_bit_stream->read_bit());
}
return {};
}
@ -438,7 +454,7 @@ void Parser::setup_past_independence()
m_probability_tables->reset_probs();
}
ErrorOr<void> Parser::compressed_header()
DecoderErrorOr<void> Parser::compressed_header()
{
TRY(read_tx_mode());
if (m_tx_mode == TXModeSelect)
@ -459,20 +475,20 @@ ErrorOr<void> Parser::compressed_header()
return {};
}
ErrorOr<void> Parser::read_tx_mode()
DecoderErrorOr<void> Parser::read_tx_mode()
{
if (m_lossless) {
m_tx_mode = Only_4x4;
} else {
auto tx_mode = TRY(m_bit_stream->read_literal(2));
auto tx_mode = TRY_READ(m_bit_stream->read_literal(2));
if (tx_mode == Allow_32x32)
tx_mode += TRY(m_bit_stream->read_literal(1));
tx_mode += TRY_READ(m_bit_stream->read_literal(1));
m_tx_mode = static_cast<TXMode>(tx_mode);
}
return {};
}
ErrorOr<void> Parser::tx_mode_probs()
DecoderErrorOr<void> Parser::tx_mode_probs()
{
auto& tx_probs = m_probability_tables->tx_probs();
for (auto i = 0; i < TX_SIZE_CONTEXTS; i++) {
@ -490,9 +506,9 @@ ErrorOr<void> Parser::tx_mode_probs()
return {};
}
ErrorOr<u8> Parser::diff_update_prob(u8 prob)
DecoderErrorOr<u8> Parser::diff_update_prob(u8 prob)
{
auto update_prob = TRY(m_bit_stream->read_bool(252));
auto update_prob = TRY_READ(m_bit_stream->read_bool(252));
if (update_prob) {
auto delta_prob = TRY(decode_term_subexp());
prob = inv_remap_prob(delta_prob, prob);
@ -500,19 +516,19 @@ ErrorOr<u8> Parser::diff_update_prob(u8 prob)
return prob;
}
ErrorOr<u8> Parser::decode_term_subexp()
DecoderErrorOr<u8> Parser::decode_term_subexp()
{
if (TRY(m_bit_stream->read_literal(1)) == 0)
return TRY(m_bit_stream->read_literal(4));
if (TRY(m_bit_stream->read_literal(1)) == 0)
return TRY(m_bit_stream->read_literal(4)) + 16;
if (TRY(m_bit_stream->read_literal(1)) == 0)
return TRY(m_bit_stream->read_literal(5)) + 32;
if (TRY_READ(m_bit_stream->read_literal(1)) == 0)
return TRY_READ(m_bit_stream->read_literal(4));
if (TRY_READ(m_bit_stream->read_literal(1)) == 0)
return TRY_READ(m_bit_stream->read_literal(4)) + 16;
if (TRY_READ(m_bit_stream->read_literal(1)) == 0)
return TRY_READ(m_bit_stream->read_literal(5)) + 32;
auto v = TRY(m_bit_stream->read_literal(7));
auto v = TRY_READ(m_bit_stream->read_literal(7));
if (v < 65)
return v + 64;
return (v << 1u) - 1 + TRY(m_bit_stream->read_literal(1));
return (v << 1u) - 1 + TRY_READ(m_bit_stream->read_literal(1));
}
u8 Parser::inv_remap_prob(u8 delta_prob, u8 prob)
@ -533,11 +549,11 @@ u8 Parser::inv_recenter_nonneg(u8 v, u8 m)
return m + (v >> 1u);
}
ErrorOr<void> Parser::read_coef_probs()
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 update_probs = TRY(m_bit_stream->read_literal(1));
auto update_probs = TRY_READ(m_bit_stream->read_literal(1));
if (update_probs == 1) {
for (auto i = 0; i < 2; i++) {
for (auto j = 0; j < 2; j++) {
@ -557,14 +573,14 @@ ErrorOr<void> Parser::read_coef_probs()
return {};
}
ErrorOr<void> Parser::read_skip_prob()
DecoderErrorOr<void> Parser::read_skip_prob()
{
for (auto i = 0; i < SKIP_CONTEXTS; i++)
m_probability_tables->skip_prob()[i] = TRY(diff_update_prob(m_probability_tables->skip_prob()[i]));
return {};
}
ErrorOr<void> Parser::read_inter_mode_probs()
DecoderErrorOr<void> Parser::read_inter_mode_probs()
{
for (auto i = 0; i < INTER_MODE_CONTEXTS; i++) {
for (auto j = 0; j < INTER_MODES - 1; j++)
@ -573,7 +589,7 @@ ErrorOr<void> Parser::read_inter_mode_probs()
return {};
}
ErrorOr<void> Parser::read_interp_filter_probs()
DecoderErrorOr<void> Parser::read_interp_filter_probs()
{
for (auto i = 0; i < INTERP_FILTER_CONTEXTS; i++) {
for (auto j = 0; j < SWITCHABLE_FILTERS - 1; j++)
@ -582,14 +598,14 @@ ErrorOr<void> Parser::read_interp_filter_probs()
return {};
}
ErrorOr<void> Parser::read_is_inter_probs()
DecoderErrorOr<void> Parser::read_is_inter_probs()
{
for (auto i = 0; i < IS_INTER_CONTEXTS; i++)
m_probability_tables->is_inter_prob()[i] = TRY(diff_update_prob(m_probability_tables->is_inter_prob()[i]));
return {};
}
ErrorOr<void> Parser::frame_reference_mode()
DecoderErrorOr<void> Parser::frame_reference_mode()
{
auto compound_reference_allowed = false;
for (size_t i = 2; i <= REFS_PER_FRAME; i++) {
@ -597,11 +613,11 @@ ErrorOr<void> Parser::frame_reference_mode()
compound_reference_allowed = true;
}
if (compound_reference_allowed) {
auto non_single_reference = TRY(m_bit_stream->read_literal(1));
auto non_single_reference = TRY_READ(m_bit_stream->read_literal(1));
if (non_single_reference == 0) {
m_reference_mode = SingleReference;
} else {
auto reference_select = TRY(m_bit_stream->read_literal(1));
auto reference_select = TRY_READ(m_bit_stream->read_literal(1));
if (reference_select == 0)
m_reference_mode = CompoundReference;
else
@ -614,7 +630,7 @@ ErrorOr<void> Parser::frame_reference_mode()
return {};
}
ErrorOr<void> Parser::frame_reference_mode_probs()
DecoderErrorOr<void> Parser::frame_reference_mode_probs()
{
if (m_reference_mode == ReferenceModeSelect) {
for (auto i = 0; i < COMP_MODE_CONTEXTS; i++) {
@ -638,7 +654,7 @@ ErrorOr<void> Parser::frame_reference_mode_probs()
return {};
}
ErrorOr<void> Parser::read_y_mode_probs()
DecoderErrorOr<void> Parser::read_y_mode_probs()
{
for (auto i = 0; i < BLOCK_SIZE_GROUPS; i++) {
for (auto j = 0; j < INTRA_MODES - 1; j++) {
@ -649,7 +665,7 @@ ErrorOr<void> Parser::read_y_mode_probs()
return {};
}
ErrorOr<void> Parser::read_partition_probs()
DecoderErrorOr<void> Parser::read_partition_probs()
{
for (auto i = 0; i < PARTITION_CONTEXTS; i++) {
for (auto j = 0; j < PARTITION_TYPES - 1; j++) {
@ -660,7 +676,7 @@ ErrorOr<void> Parser::read_partition_probs()
return {};
}
ErrorOr<void> Parser::mv_probs()
DecoderErrorOr<void> Parser::mv_probs()
{
for (auto j = 0; j < MV_JOINTS - 1; j++) {
auto& mv_joint_probs = m_probability_tables->mv_joint_probs();
@ -707,10 +723,10 @@ ErrorOr<void> Parser::mv_probs()
return {};
}
ErrorOr<u8> Parser::update_mv_prob(u8 prob)
DecoderErrorOr<u8> Parser::update_mv_prob(u8 prob)
{
if (TRY(m_bit_stream->read_bool(252))) {
return (TRY(m_bit_stream->read_literal(7)) << 1u) | 1u;
if (TRY_READ(m_bit_stream->read_bool(252))) {
return (TRY_READ(m_bit_stream->read_literal(7)) << 1u) | 1u;
}
return prob;
}
@ -751,7 +767,7 @@ void Parser::allocate_tile_data()
m_allocated_dimensions = dimensions;
}
ErrorOr<void> Parser::decode_tiles()
DecoderErrorOr<void> Parser::decode_tiles()
{
auto tile_cols = 1 << m_tile_cols_log2;
auto tile_rows = 1 << m_tile_rows_log2;
@ -764,15 +780,15 @@ ErrorOr<void> Parser::decode_tiles()
if (last_tile)
tile_size = m_bit_stream->bytes_remaining();
else
tile_size = TRY(m_bit_stream->read_bits(32));
tile_size = TRY_READ(m_bit_stream->read_bits(32));
m_mi_row_start = get_tile_offset(tile_row, m_mi_rows, m_tile_rows_log2);
m_mi_row_end = get_tile_offset(tile_row + 1, m_mi_rows, m_tile_rows_log2);
m_mi_col_start = get_tile_offset(tile_col, m_mi_cols, m_tile_cols_log2);
m_mi_col_end = get_tile_offset(tile_col + 1, m_mi_cols, m_tile_cols_log2);
TRY(m_bit_stream->init_bool(tile_size));
TRY_READ(m_bit_stream->init_bool(tile_size));
TRY(decode_tile());
TRY(m_bit_stream->exit_bool());
TRY_READ(m_bit_stream->exit_bool());
}
}
return {};
@ -806,7 +822,7 @@ u32 Parser::get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2)
return min(offset, mis);
}
ErrorOr<void> Parser::decode_tile()
DecoderErrorOr<void> Parser::decode_tile()
{
for (auto row = m_mi_row_start; row < m_mi_row_end; row += 8) {
clear_left_context();
@ -826,17 +842,17 @@ void Parser::clear_left_context()
clear_context(m_left_partition_context, m_sb64_rows * 8);
}
ErrorOr<void> Parser::decode_partition(u32 row, u32 col, u8 block_subsize)
DecoderErrorOr<void> Parser::decode_partition(u32 row, u32 col, u8 block_subsize)
{
if (row >= m_mi_rows || col >= m_mi_cols)
return Error::from_string_literal("decode_partition: Row or column were outside valid ranges");
return DecoderError::corrupted("Row or column were outside valid ranges"sv);
m_block_subsize = block_subsize;
m_num_8x8 = num_8x8_blocks_wide_lookup[block_subsize];
auto half_block_8x8 = m_num_8x8 >> 1;
m_has_rows = (row + half_block_8x8) < m_mi_rows;
m_has_cols = (col + half_block_8x8) < m_mi_cols;
auto partition = TRY(m_tree_parser->parse_tree(SyntaxElementType::Partition));
auto partition = TRY_READ(m_tree_parser->parse_tree(SyntaxElementType::Partition));
auto subsize = subsize_lookup[partition][block_subsize];
if (subsize < Block_8x8 || partition == PartitionNone) {
TRY(decode_block(row, col, subsize));
@ -863,7 +879,7 @@ ErrorOr<void> Parser::decode_partition(u32 row, u32 col, u8 block_subsize)
return {};
}
ErrorOr<void> Parser::decode_block(u32 row, u32 col, u8 subsize)
DecoderErrorOr<void> Parser::decode_block(u32 row, u32 col, u8 subsize)
{
m_mi_row = row;
m_mi_col = col;
@ -902,7 +918,7 @@ ErrorOr<void> Parser::decode_block(u32 row, u32 col, u8 subsize)
return {};
}
ErrorOr<void> Parser::mode_info()
DecoderErrorOr<void> Parser::mode_info()
{
if (m_frame_is_intra)
TRY(intra_frame_mode_info());
@ -911,7 +927,7 @@ ErrorOr<void> Parser::mode_info()
return {};
}
ErrorOr<void> Parser::intra_frame_mode_info()
DecoderErrorOr<void> Parser::intra_frame_mode_info()
{
TRY(intra_segment_id());
TRY(read_skip());
@ -920,7 +936,7 @@ ErrorOr<void> Parser::intra_frame_mode_info()
m_ref_frame[1] = None;
m_is_inter = false;
if (m_mi_size >= Block_8x8) {
m_default_intra_mode = TRY(m_tree_parser->parse_tree<IntraMode>(SyntaxElementType::DefaultIntraMode));
m_default_intra_mode = TRY_READ(m_tree_parser->parse_tree<IntraMode>(SyntaxElementType::DefaultIntraMode));
m_y_mode = m_default_intra_mode;
for (auto& block_sub_mode : m_block_sub_modes)
block_sub_mode = m_y_mode;
@ -930,7 +946,7 @@ ErrorOr<void> Parser::intra_frame_mode_info()
for (auto idy = 0; idy < 2; idy += m_num_4x4_h) {
for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
m_tree_parser->set_default_intra_mode_variables(idx, idy);
m_default_intra_mode = TRY(m_tree_parser->parse_tree<IntraMode>(SyntaxElementType::DefaultIntraMode));
m_default_intra_mode = TRY_READ(m_tree_parser->parse_tree<IntraMode>(SyntaxElementType::DefaultIntraMode));
for (auto y = 0; y < m_num_4x4_h; y++) {
for (auto x = 0; x < m_num_4x4_w; x++) {
auto index = (idy + y) * 2 + idx + x;
@ -943,25 +959,25 @@ ErrorOr<void> Parser::intra_frame_mode_info()
}
m_y_mode = m_default_intra_mode;
}
m_uv_mode = TRY(m_tree_parser->parse_tree<u8>(SyntaxElementType::DefaultUVMode));
m_uv_mode = TRY_READ(m_tree_parser->parse_tree<u8>(SyntaxElementType::DefaultUVMode));
return {};
}
ErrorOr<void> Parser::intra_segment_id()
DecoderErrorOr<void> Parser::intra_segment_id()
{
if (m_segmentation_enabled && m_segmentation_update_map)
m_segment_id = TRY(m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID));
m_segment_id = TRY_READ(m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID));
else
m_segment_id = 0;
return {};
}
ErrorOr<void> Parser::read_skip()
DecoderErrorOr<void> Parser::read_skip()
{
if (seg_feature_active(SEG_LVL_SKIP))
m_skip = true;
else
m_skip = TRY(m_tree_parser->parse_tree<bool>(SyntaxElementType::Skip));
m_skip = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::Skip));
return {};
}
@ -970,17 +986,17 @@ bool Parser::seg_feature_active(u8 feature)
return m_segmentation_enabled && m_feature_enabled[m_segment_id][feature];
}
ErrorOr<void> Parser::read_tx_size(bool allow_select)
DecoderErrorOr<void> Parser::read_tx_size(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(m_tree_parser->parse_tree<TXSize>(SyntaxElementType::TXSize));
m_tx_size = TRY_READ(m_tree_parser->parse_tree<TXSize>(SyntaxElementType::TXSize));
else
m_tx_size = min(m_max_tx_size, tx_mode_to_biggest_tx_size[m_tx_mode]);
return {};
}
ErrorOr<void> Parser::inter_frame_mode_info()
DecoderErrorOr<void> Parser::inter_frame_mode_info()
{
m_left_ref_frame[0] = m_available_l ? m_ref_frames[m_mi_row * m_mi_cols + (m_mi_col - 1)] : IntraFrame;
m_above_ref_frame[0] = m_available_u ? m_ref_frames[(m_mi_row - 1) * m_mi_cols + m_mi_col] : IntraFrame;
@ -1002,7 +1018,7 @@ ErrorOr<void> Parser::inter_frame_mode_info()
return {};
}
ErrorOr<void> Parser::inter_segment_id()
DecoderErrorOr<void> Parser::inter_segment_id()
{
if (!m_segmentation_enabled) {
m_segment_id = 0;
@ -1014,15 +1030,15 @@ ErrorOr<void> Parser::inter_segment_id()
return {};
}
if (!m_segmentation_temporal_update) {
m_segment_id = TRY(m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID));
m_segment_id = TRY_READ(m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID));
return {};
}
auto seg_id_predicted = TRY(m_tree_parser->parse_tree<bool>(SyntaxElementType::SegIDPredicted));
auto seg_id_predicted = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::SegIDPredicted));
if (seg_id_predicted)
m_segment_id = predicted_segment_id;
else
m_segment_id = TRY(m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID));
m_segment_id = TRY_READ(m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID));
for (size_t i = 0; i < num_8x8_blocks_wide_lookup[m_mi_size]; i++)
m_above_seg_pred_context[m_mi_col + i] = seg_id_predicted;
for (size_t i = 0; i < num_8x8_blocks_high_lookup[m_mi_size]; i++)
@ -1045,21 +1061,21 @@ u8 Parser::get_segment_id()
return segment;
}
ErrorOr<void> Parser::read_is_inter()
DecoderErrorOr<void> Parser::read_is_inter()
{
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(m_tree_parser->parse_tree<bool>(SyntaxElementType::IsInter));
m_is_inter = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::IsInter));
return {};
}
ErrorOr<void> Parser::intra_block_mode_info()
DecoderErrorOr<void> Parser::intra_block_mode_info()
{
m_ref_frame[0] = IntraFrame;
m_ref_frame[1] = None;
if (m_mi_size >= Block_8x8) {
m_y_mode = TRY(m_tree_parser->parse_tree<u8>(SyntaxElementType::IntraMode));
m_y_mode = TRY_READ(m_tree_parser->parse_tree<u8>(SyntaxElementType::IntraMode));
for (auto& block_sub_mode : m_block_sub_modes)
block_sub_mode = m_y_mode;
} else {
@ -1068,7 +1084,7 @@ ErrorOr<void> Parser::intra_block_mode_info()
u8 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(m_tree_parser->parse_tree<u8>(SyntaxElementType::SubIntraMode));
sub_intra_mode = TRY_READ(m_tree_parser->parse_tree<u8>(SyntaxElementType::SubIntraMode));
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;
@ -1077,11 +1093,11 @@ ErrorOr<void> Parser::intra_block_mode_info()
}
m_y_mode = sub_intra_mode;
}
m_uv_mode = TRY(m_tree_parser->parse_tree<u8>(SyntaxElementType::UVMode));
m_uv_mode = TRY_READ(m_tree_parser->parse_tree<u8>(SyntaxElementType::UVMode));
return {};
}
ErrorOr<void> Parser::inter_block_mode_info()
DecoderErrorOr<void> Parser::inter_block_mode_info()
{
TRY(read_ref_frames());
for (auto j = 0; j < 2; j++) {
@ -1094,11 +1110,11 @@ ErrorOr<void> Parser::inter_block_mode_info()
if (seg_feature_active(SEG_LVL_SKIP)) {
m_y_mode = ZeroMv;
} else if (m_mi_size >= Block_8x8) {
auto inter_mode = TRY(m_tree_parser->parse_tree(SyntaxElementType::InterMode));
auto inter_mode = TRY_READ(m_tree_parser->parse_tree(SyntaxElementType::InterMode));
m_y_mode = NearestMv + inter_mode;
}
if (m_interpolation_filter == Switchable)
m_interp_filter = TRY(m_tree_parser->parse_tree<InterpolationFilter>(SyntaxElementType::InterpFilter));
m_interp_filter = TRY_READ(m_tree_parser->parse_tree<InterpolationFilter>(SyntaxElementType::InterpFilter));
else
m_interp_filter = m_interpolation_filter;
if (m_mi_size < Block_8x8) {
@ -1106,7 +1122,7 @@ ErrorOr<void> Parser::inter_block_mode_info()
m_num_4x4_h = num_4x4_blocks_high_lookup[m_mi_size];
for (auto idy = 0; idy < 2; idy += m_num_4x4_h) {
for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
auto inter_mode = TRY(m_tree_parser->parse_tree(SyntaxElementType::InterMode));
auto inter_mode = TRY_READ(m_tree_parser->parse_tree(SyntaxElementType::InterMode));
m_y_mode = NearestMv + inter_mode;
if (m_y_mode == NearestMv || m_y_mode == NearMv) {
for (auto j = 0; j < 1 + is_compound; j++)
@ -1134,7 +1150,7 @@ ErrorOr<void> Parser::inter_block_mode_info()
return {};
}
ErrorOr<void> Parser::read_ref_frames()
DecoderErrorOr<void> Parser::read_ref_frames()
{
if (seg_feature_active(SEG_LVL_REF_FRAME)) {
m_ref_frame[0] = static_cast<ReferenceFrame>(m_feature_data[m_segment_id][SEG_LVL_REF_FRAME]);
@ -1143,19 +1159,19 @@ ErrorOr<void> Parser::read_ref_frames()
}
ReferenceMode comp_mode;
if (m_reference_mode == ReferenceModeSelect)
comp_mode = TRY(m_tree_parser->parse_tree<ReferenceMode>(SyntaxElementType::CompMode));
comp_mode = TRY_READ(m_tree_parser->parse_tree<ReferenceMode>(SyntaxElementType::CompMode));
else
comp_mode = m_reference_mode;
if (comp_mode == CompoundReference) {
auto idx = m_ref_frame_sign_bias[m_comp_fixed_ref];
auto comp_ref = TRY(m_tree_parser->parse_tree(SyntaxElementType::CompRef));
auto comp_ref = TRY_READ(m_tree_parser->parse_tree(SyntaxElementType::CompRef));
m_ref_frame[idx] = m_comp_fixed_ref;
m_ref_frame[!idx] = m_comp_var_ref[comp_ref];
return {};
}
auto single_ref_p1 = TRY(m_tree_parser->parse_tree<bool>(SyntaxElementType::SingleRefP1));
auto single_ref_p1 = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::SingleRefP1));
if (single_ref_p1) {
auto single_ref_p2 = TRY(m_tree_parser->parse_tree<bool>(SyntaxElementType::SingleRefP2));
auto single_ref_p2 = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::SingleRefP2));
m_ref_frame[0] = single_ref_p2 ? AltRefFrame : GoldenFrame;
} else {
m_ref_frame[0] = LastFrame;
@ -1164,7 +1180,7 @@ ErrorOr<void> Parser::read_ref_frames()
return {};
}
ErrorOr<void> Parser::assign_mv(bool is_compound)
DecoderErrorOr<void> Parser::assign_mv(bool is_compound)
{
m_mv[1] = 0;
for (auto i = 0; i < 1 + is_compound; i++) {
@ -1181,11 +1197,11 @@ ErrorOr<void> Parser::assign_mv(bool is_compound)
return {};
}
ErrorOr<void> Parser::read_mv(u8 ref)
DecoderErrorOr<void> Parser::read_mv(u8 ref)
{
m_use_hp = m_allow_high_precision_mv && use_mv_hp(m_best_mv[ref]);
m_use_hp = m_allow_high_precision_mv && TRY(use_mv_hp(m_best_mv[ref]));
MV diff_mv;
auto mv_joint = TRY(m_tree_parser->parse_tree<MvJoint>(SyntaxElementType::MVJoint));
auto mv_joint = TRY_READ(m_tree_parser->parse_tree<MvJoint>(SyntaxElementType::MVJoint));
if (mv_joint == MvJointHzvnz || mv_joint == MvJointHnzvnz)
diff_mv.set_row(TRY(read_mv_component(0)));
if (mv_joint == MvJointHnzvz || mv_joint == MvJointHnzvnz)
@ -1194,31 +1210,31 @@ ErrorOr<void> Parser::read_mv(u8 ref)
return {};
}
ErrorOr<i32> Parser::read_mv_component(u8)
DecoderErrorOr<i32> Parser::read_mv_component(u8)
{
auto mv_sign = TRY(m_tree_parser->parse_tree<bool>(SyntaxElementType::MVSign));
auto mv_class = TRY(m_tree_parser->parse_tree<MvClass>(SyntaxElementType::MVClass));
auto mv_sign = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::MVSign));
auto mv_class = TRY_READ(m_tree_parser->parse_tree<MvClass>(SyntaxElementType::MVClass));
u32 mag;
if (mv_class == MvClass0) {
auto mv_class0_bit = TRY(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVClass0Bit));
auto mv_class0_fr = TRY(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVClass0FR));
auto mv_class0_hp = TRY(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVClass0HP));
auto mv_class0_bit = TRY_READ(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVClass0Bit));
auto mv_class0_fr = TRY_READ(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVClass0FR));
auto mv_class0_hp = TRY_READ(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVClass0HP));
mag = ((mv_class0_bit << 3) | (mv_class0_fr << 1) | mv_class0_hp) + 1;
} else {
auto d = 0;
for (size_t i = 0; i < mv_class; i++) {
auto mv_bit = TRY(m_tree_parser->parse_tree<bool>(SyntaxElementType::MVBit));
auto mv_bit = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::MVBit));
d |= mv_bit << i;
}
mag = CLASS0_SIZE << (mv_class + 2);
auto mv_fr = TRY(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVFR));
auto mv_hp = TRY(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVHP));
auto mv_fr = TRY_READ(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVFR));
auto mv_hp = TRY_READ(m_tree_parser->parse_tree<u32>(SyntaxElementType::MVHP));
mag += ((d << 3) | (mv_fr << 1) | mv_hp) + 1;
}
return (mv_sign ? -1 : 1) * static_cast<i32>(mag);
}
ErrorOr<void> Parser::residual()
DecoderErrorOr<void> Parser::residual()
{
auto block_size = m_mi_size < Block_8x8 ? Block_8x8 : static_cast<BlockSubsize>(m_mi_size);
for (size_t plane = 0; plane < 3; plane++) {
@ -1287,7 +1303,7 @@ BlockSubsize Parser::get_plane_block_size(u32 subsize, u8 plane)
return ss_size_lookup[subsize][sub_x][sub_y];
}
ErrorOr<bool> Parser::tokens(size_t plane, u32 start_x, u32 start_y, TXSize tx_size, u32 block_index)
DecoderErrorOr<bool> Parser::tokens(size_t plane, u32 start_x, u32 start_y, TXSize tx_size, u32 block_index)
{
m_tree_parser->set_start_x_and_y(start_x, start_y);
size_t segment_eob = 16 << (tx_size << 1);
@ -1299,18 +1315,18 @@ ErrorOr<bool> Parser::tokens(size_t plane, u32 start_x, u32 start_y, TXSize tx_s
auto band = (tx_size == TX_4x4) ? coefband_4x4[c] : coefband_8x8plus[c];
m_tree_parser->set_tokens_variables(band, c, plane, tx_size, pos);
if (check_eob) {
auto more_coefs = TRY(m_tree_parser->parse_tree<bool>(SyntaxElementType::MoreCoefs));
auto more_coefs = TRY_READ(m_tree_parser->parse_tree<bool>(SyntaxElementType::MoreCoefs));
if (!more_coefs)
break;
}
auto token = TRY(m_tree_parser->parse_tree<Token>(SyntaxElementType::Token));
auto token = TRY_READ(m_tree_parser->parse_tree<Token>(SyntaxElementType::Token));
m_token_cache[pos] = energy_class[token];
if (token == ZeroToken) {
m_tokens[pos] = 0;
check_eob = false;
} else {
i32 coef = TRY(read_coef(token));
auto sign_bit = TRY(m_bit_stream->read_literal(1));
auto sign_bit = TRY_READ(m_bit_stream->read_literal(1));
m_tokens[pos] = sign_bit ? -coef : coef;
check_eob = true;
}
@ -1358,47 +1374,46 @@ u32 const* Parser::get_scan(size_t plane, TXSize tx_size, u32 block_index)
return default_scan_32x32;
}
ErrorOr<i32> Parser::read_coef(Token token)
DecoderErrorOr<i32> Parser::read_coef(Token token)
{
auto cat = extra_bits[token][0];
auto num_extra = extra_bits[token][1];
auto coef = extra_bits[token][2];
if (token == DctValCat6) {
for (size_t e = 0; e < (u8)(m_bit_depth - 8); e++) {
auto high_bit = TRY(m_bit_stream->read_bool(255));
auto high_bit = TRY_READ(m_bit_stream->read_bool(255));
coef += high_bit << (5 + m_bit_depth - e);
}
}
for (size_t e = 0; e < num_extra; e++) {
auto coef_bit = TRY(m_bit_stream->read_bool(cat_probs[cat][e]));
auto coef_bit = TRY_READ(m_bit_stream->read_bool(cat_probs[cat][e]));
coef += coef_bit << (num_extra - 1 - e);
}
return coef;
}
ErrorOr<void> Parser::find_mv_refs(ReferenceFrame, int)
DecoderErrorOr<void> Parser::find_mv_refs(ReferenceFrame, int)
{
// TODO: Implement
return Error::from_string_literal("find_mv_refs: Not implemented");
return DecoderError::not_implemented();
}
ErrorOr<void> Parser::find_best_ref_mvs(int)
DecoderErrorOr<void> Parser::find_best_ref_mvs(int)
{
// TODO: Implement
return Error::from_string_literal("find_best_ref_mvs: Not implemented");
return DecoderError::not_implemented();
}
ErrorOr<void> Parser::append_sub8x8_mvs(u8, u8)
DecoderErrorOr<void> Parser::append_sub8x8_mvs(u8, u8)
{
// TODO: Implement
return Error::from_string_literal("append_sub8x8_mvs: Not implemented");
return DecoderError::not_implemented();
}
bool Parser::use_mv_hp(const MV&)
DecoderErrorOr<bool> Parser::use_mv_hp(const MV&)
{
// TODO: Implement
VERIFY(false);
return true;
return DecoderError::not_implemented();
}
void Parser::dump_info()