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

LibVideo/VP9: Add SAFE_CALL macro to help propagate failure state

This commit is contained in:
FalseHonesty 2021-05-05 21:54:15 -04:00 committed by Andreas Kling
parent 741677b992
commit cc1a9e3d1c

View file

@ -12,6 +12,10 @@ namespace Video::VP9 {
if (m_bit_stream->read_bit() != 0) \ if (m_bit_stream->read_bit() != 0) \
return false return false
#define SAFE_CALL(call) \
if (!(call)) [[unlikely]] \
return false
Decoder::Decoder() Decoder::Decoder()
: m_probability_tables(make<ProbabilityTables>()) : m_probability_tables(make<ProbabilityTables>())
, m_tree_parser(make<TreeParser>(*this)) , m_tree_parser(make<TreeParser>(*this))
@ -23,11 +27,9 @@ bool Decoder::parse_frame(const ByteBuffer& frame_data)
m_bit_stream = make<BitStream>(frame_data.data(), frame_data.size()); m_bit_stream = make<BitStream>(frame_data.data(), frame_data.size());
m_syntax_element_counter = make<SyntaxElementCounter>(); m_syntax_element_counter = make<SyntaxElementCounter>();
if (!uncompressed_header()) SAFE_CALL(uncompressed_header());
return false;
dbgln("Finished reading uncompressed header"); dbgln("Finished reading uncompressed header");
if (!trailing_bits()) SAFE_CALL(trailing_bits());
return false;
if (m_header_size_in_bytes == 0) { if (m_header_size_in_bytes == 0) {
// FIXME: Do we really need to read all of these bits? // FIXME: Do we really need to read all of these bits?
// while (m_bit_stream->get_position() < m_start_bit_pos + (8 * frame_data.size())) // while (m_bit_stream->get_position() < m_start_bit_pos + (8 * frame_data.size()))
@ -39,17 +41,14 @@ bool Decoder::parse_frame(const ByteBuffer& frame_data)
m_probability_tables->load_probs2(m_frame_context_idx); m_probability_tables->load_probs2(m_frame_context_idx);
m_syntax_element_counter->clear_counts(); m_syntax_element_counter->clear_counts();
if (!m_bit_stream->init_bool(m_header_size_in_bytes)) SAFE_CALL(m_bit_stream->init_bool(m_header_size_in_bytes));
return false;
dbgln("Reading compressed header"); dbgln("Reading compressed header");
if (!compressed_header()) SAFE_CALL(compressed_header());
return false;
dbgln("Finished reading compressed header"); dbgln("Finished reading compressed header");
if (!m_bit_stream->exit_bool()) SAFE_CALL(m_bit_stream->exit_bool());
return false;
dbgln("Finished reading frame!"); dbgln("Finished reading frame!");
decode_tiles(); SAFE_CALL(decode_tiles());
return true; return true;
} }
@ -78,14 +77,10 @@ bool Decoder::uncompressed_header()
m_error_resilient_mode = m_bit_stream->read_bit(); m_error_resilient_mode = m_bit_stream->read_bit();
if (m_frame_type == KeyFrame) { if (m_frame_type == KeyFrame) {
if (!frame_sync_code()) SAFE_CALL(frame_sync_code());
return false; SAFE_CALL(color_config());
if (!color_config()) SAFE_CALL(frame_size());
return false; SAFE_CALL(render_size());
if (!frame_size())
return false;
if (!render_size())
return false;
m_refresh_frame_flags = 0xFF; m_refresh_frame_flags = 0xFF;
m_frame_is_intra = true; m_frame_is_intra = true;
} else { } else {
@ -98,11 +93,9 @@ bool Decoder::uncompressed_header()
} }
if (m_frame_is_intra) { if (m_frame_is_intra) {
if (!frame_sync_code()) SAFE_CALL(frame_sync_code());
return false;
if (m_profile > 0) { if (m_profile > 0) {
if (!color_config()) SAFE_CALL(color_config());
return false;
} else { } else {
m_color_space = Bt601; m_color_space = Bt601;
m_subsampling_x = true; m_subsampling_x = true;
@ -111,19 +104,17 @@ bool Decoder::uncompressed_header()
} }
m_refresh_frame_flags = m_bit_stream->read_f8(); m_refresh_frame_flags = m_bit_stream->read_f8();
if (!frame_size()) SAFE_CALL(frame_size());
return false; SAFE_CALL(render_size());
if (!render_size())
return false;
} else { } else {
m_refresh_frame_flags = m_bit_stream->read_f8(); m_refresh_frame_flags = m_bit_stream->read_f8();
for (auto i = 0; i < 3; i++) { for (auto i = 0; i < 3; i++) {
m_ref_frame_idx[i] = m_bit_stream->read_f(3); m_ref_frame_idx[i] = m_bit_stream->read_f(3);
m_ref_frame_sign_bias[LastFrame + i] = m_bit_stream->read_bit(); m_ref_frame_sign_bias[LastFrame + i] = m_bit_stream->read_bit();
} }
frame_size_with_refs(); SAFE_CALL(frame_size_with_refs());
m_allow_high_precision_mv = m_bit_stream->read_bit(); m_allow_high_precision_mv = m_bit_stream->read_bit();
read_interpolation_filter(); SAFE_CALL(read_interpolation_filter());
} }
} }
@ -137,7 +128,7 @@ bool Decoder::uncompressed_header()
m_frame_context_idx = m_bit_stream->read_f(2); m_frame_context_idx = m_bit_stream->read_f(2);
if (m_frame_is_intra || m_error_resilient_mode) { if (m_frame_is_intra || m_error_resilient_mode) {
setup_past_independence(); SAFE_CALL(setup_past_independence());
if (m_frame_type == KeyFrame || m_error_resilient_mode || m_reset_frame_context == 3) { if (m_frame_type == KeyFrame || m_error_resilient_mode || m_reset_frame_context == 3) {
for (auto i = 0; i < 4; i++) { for (auto i = 0; i < 4; i++) {
m_probability_tables->save_probs(i); m_probability_tables->save_probs(i);
@ -148,10 +139,10 @@ bool Decoder::uncompressed_header()
m_frame_context_idx = 0; m_frame_context_idx = 0;
} }
loop_filter_params(); SAFE_CALL(loop_filter_params());
quantization_params(); SAFE_CALL(quantization_params());
segmentation_params(); SAFE_CALL(segmentation_params());
tile_info(); SAFE_CALL(tile_info());
m_header_size_in_bytes = m_bit_stream->read_f16(); m_header_size_in_bytes = m_bit_stream->read_f16();
@ -205,7 +196,7 @@ bool Decoder::frame_size()
{ {
m_frame_width = m_bit_stream->read_f16() + 1; m_frame_width = m_bit_stream->read_f16() + 1;
m_frame_height = m_bit_stream->read_f16() + 1; m_frame_height = m_bit_stream->read_f16() + 1;
compute_image_size(); SAFE_CALL(compute_image_size());
return true; return true;
} }
@ -234,12 +225,13 @@ bool Decoder::frame_size_with_refs()
} }
} }
if (!found_ref) if (!found_ref) {
frame_size(); SAFE_CALL(frame_size());
else } else {
compute_image_size(); SAFE_CALL(compute_image_size());
}
render_size(); SAFE_CALL(render_size());
return true; return true;
} }
@ -318,8 +310,7 @@ bool Decoder::segmentation_params()
} }
} }
if (!m_bit_stream->read_bit()) SAFE_CALL(m_bit_stream->read_bit());
return true;
m_segmentation_abs_or_delta_update = m_bit_stream->read_bit(); m_segmentation_abs_or_delta_update = m_bit_stream->read_bit();
for (auto i = 0; i < MAX_SEGMENTS; i++) { for (auto i = 0; i < MAX_SEGMENTS; i++) {
@ -417,23 +408,23 @@ bool Decoder::trailing_bits()
bool Decoder::compressed_header() bool Decoder::compressed_header()
{ {
read_tx_mode(); SAFE_CALL(read_tx_mode());
if (m_tx_mode == TXModeSelect) { if (m_tx_mode == TXModeSelect) {
tx_mode_probs(); SAFE_CALL(tx_mode_probs());
} }
read_coef_probs(); SAFE_CALL(read_coef_probs());
read_skip_prob(); SAFE_CALL(read_skip_prob());
if (!m_frame_is_intra) { if (!m_frame_is_intra) {
read_inter_mode_probs(); SAFE_CALL(read_inter_mode_probs());
if (m_interpolation_filter == Switchable) { if (m_interpolation_filter == Switchable) {
read_interp_filter_probs(); SAFE_CALL(read_interp_filter_probs());
} }
read_is_inter_probs(); SAFE_CALL(read_is_inter_probs());
frame_reference_mode(); SAFE_CALL(frame_reference_mode());
frame_reference_mode_probs(); SAFE_CALL(frame_reference_mode_probs());
read_y_mode_probs(); SAFE_CALL(read_y_mode_probs());
read_partition_probs(); SAFE_CALL(read_partition_probs());
mv_probs(); SAFE_CALL(mv_probs());
} }
return true; return true;
} }
@ -588,7 +579,7 @@ bool Decoder::frame_reference_mode()
m_reference_mode = CompoundReference; m_reference_mode = CompoundReference;
else else
m_reference_mode = ReferenceModeSelect; m_reference_mode = ReferenceModeSelect;
setup_compound_reference_mode(); SAFE_CALL(setup_compound_reference_mode());
} }
} else { } else {
m_reference_mode = SingleReference; m_reference_mode = SingleReference;
@ -719,8 +710,7 @@ bool Decoder::decode_tiles()
{ {
auto tile_cols = 1 << m_tile_cols_log2; auto tile_cols = 1 << m_tile_cols_log2;
auto tile_rows = 1 << m_tile_rows_log2; auto tile_rows = 1 << m_tile_rows_log2;
if (!clear_above_context()) SAFE_CALL(clear_above_context());
return false;
for (auto tile_row = 0; tile_row < tile_rows; tile_row++) { for (auto tile_row = 0; tile_row < tile_rows; tile_row++) {
for (auto tile_col = 0; tile_col < tile_cols; tile_col++) { for (auto tile_col = 0; tile_col < tile_cols; tile_col++) {
auto last_tile = (tile_row == tile_rows - 1) && (tile_col == tile_cols - 1); auto last_tile = (tile_row == tile_rows - 1) && (tile_col == tile_cols - 1);
@ -730,9 +720,9 @@ bool Decoder::decode_tiles()
m_mi_row_end = get_tile_offset(tile_row + 1, 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_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); m_mi_col_end = get_tile_offset(tile_col + 1, m_mi_cols, m_tile_cols_log2);
m_bit_stream->init_bool(tile_size); SAFE_CALL(m_bit_stream->init_bool(tile_size));
decode_tile(); SAFE_CALL(decode_tile());
m_bit_stream->exit_bool(); SAFE_CALL(m_bit_stream->exit_bool());
} }
} }
@ -766,13 +756,11 @@ u32 Decoder::get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2)
bool Decoder::decode_tile() bool Decoder::decode_tile()
{ {
for (auto row = m_mi_row_start; row < m_mi_row_end; row += 8) { for (auto row = m_mi_row_start; row < m_mi_row_end; row += 8) {
if (!clear_left_context()) SAFE_CALL(clear_left_context());
return false;
m_row = row; m_row = row;
for (auto col = m_mi_col_start; col < m_mi_col_end; col += 8) { for (auto col = m_mi_col_start; col < m_mi_col_end; col += 8) {
m_col = col; m_col = col;
if (!decode_partition(row, col, Block_64x64)) SAFE_CALL(decode_partition(row, col, Block_64x64));
return false;
} }
} }
return true; return true;
@ -801,11 +789,9 @@ bool Decoder::decode_partition(u32 row, u32 col, u8 block_subsize)
auto subsize = subsize_lookup[partition][block_subsize]; auto subsize = subsize_lookup[partition][block_subsize];
if (subsize < Block_8x8 || partition == PartitionNone) { if (subsize < Block_8x8 || partition == PartitionNone) {
if (!decode_block(row, col, subsize)) SAFE_CALL(decode_block(row, col, subsize));
return false;
} else if (partition == PartitionHorizontal) { } else if (partition == PartitionHorizontal) {
if (!decode_block(row, col, subsize)) SAFE_CALL(decode_block(row, col, subsize));
return false;
// FIXME: if (hasRows) // FIXME: if (hasRows)
// decode_block(r + halfBlock8x8, c, subsize) // decode_block(r + halfBlock8x8, c, subsize)
} }
@ -821,8 +807,7 @@ bool Decoder::decode_block(u32 row, u32 col, u8 subsize)
m_mi_size = subsize; m_mi_size = subsize;
m_available_u = row > 0; m_available_u = row > 0;
m_available_l = col > m_mi_col_start; m_available_l = col > m_mi_col_start;
if (!mode_info()) SAFE_CALL(mode_info());
return false;
// FIXME: Finish implementing // FIXME: Finish implementing
return true; return true;
} }
@ -836,12 +821,9 @@ bool Decoder::mode_info()
bool Decoder::intra_frame_mode_info() bool Decoder::intra_frame_mode_info()
{ {
if (!intra_segment_id()) SAFE_CALL(intra_segment_id());
return false; SAFE_CALL(read_skip());
if (!read_skip()) SAFE_CALL(read_tx_size(true));
return false;
if (!read_tx_size(true))
return false;
// FIXME: Finish implementing // FIXME: Finish implementing
return true; return true;
} }