mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +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:
parent
72efd9a5ff
commit
da9ff31166
Notes:
sideshowbarker
2024-07-17 06:08:13 +09:00
Author: https://github.com/Zaggy1024 Commit: https://github.com/SerenityOS/serenity/commit/da9ff31166 Pull-request: https://github.com/SerenityOS/serenity/pull/15363 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/FireFox317 Reviewed-by: https://github.com/MacDue Reviewed-by: https://github.com/davidot
5 changed files with 369 additions and 278 deletions
82
Userland/Libraries/LibVideo/DecoderError.h
Normal file
82
Userland/Libraries/LibVideo/DecoderError.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/SourceLocation.h>
|
||||
#include <AK/String.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace Video {
|
||||
|
||||
struct DecoderError;
|
||||
|
||||
template<typename T>
|
||||
using DecoderErrorOr = ErrorOr<T, DecoderError>;
|
||||
|
||||
enum class DecoderErrorCategory : u32 {
|
||||
Unknown,
|
||||
IO,
|
||||
// The input is corrupted.
|
||||
Corrupted,
|
||||
// The input uses features that are not yet implemented.
|
||||
NotImplemented,
|
||||
};
|
||||
|
||||
struct DecoderError {
|
||||
public:
|
||||
static DecoderError with_description(DecoderErrorCategory category, StringView description)
|
||||
{
|
||||
return DecoderError(category, description);
|
||||
}
|
||||
|
||||
template<typename... Parameters>
|
||||
static DecoderError format(DecoderErrorCategory category, CheckedFormatString<Parameters...>&& format_string, Parameters const&... parameters)
|
||||
{
|
||||
AK::VariadicFormatParams variadic_format_params { parameters... };
|
||||
return DecoderError::with_description(category, String::vformatted(format_string.view(), variadic_format_params));
|
||||
}
|
||||
|
||||
static DecoderError corrupted(StringView description, SourceLocation location = SourceLocation::current())
|
||||
{
|
||||
return DecoderError::format(DecoderErrorCategory::Corrupted, "{}: {}", location, description);
|
||||
}
|
||||
|
||||
static DecoderError not_implemented(SourceLocation location = SourceLocation::current())
|
||||
{
|
||||
return DecoderError::format(DecoderErrorCategory::NotImplemented, "{} is not implemented", location.function_name());
|
||||
}
|
||||
|
||||
DecoderErrorCategory category() { return m_category; }
|
||||
StringView description() { return m_description; }
|
||||
StringView string_literal() { return m_description; }
|
||||
|
||||
private:
|
||||
DecoderError(DecoderErrorCategory category, String description)
|
||||
: m_category(category)
|
||||
, m_description(move(description))
|
||||
{
|
||||
}
|
||||
|
||||
DecoderErrorCategory m_category { DecoderErrorCategory::Unknown };
|
||||
String m_description;
|
||||
};
|
||||
|
||||
#define DECODER_TRY(category, expression) \
|
||||
({ \
|
||||
auto _result = ((expression)); \
|
||||
if (_result.is_error()) [[unlikely]] { \
|
||||
auto _error_string = _result.release_error().string_literal(); \
|
||||
return DecoderError::format( \
|
||||
((category)), "{}: {}", \
|
||||
SourceLocation::current(), _error_string); \
|
||||
} \
|
||||
_result.release_value(); \
|
||||
})
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ Decoder::Decoder()
|
|||
{
|
||||
}
|
||||
|
||||
ErrorOr<void> Decoder::decode_frame(ByteBuffer const& frame_data)
|
||||
DecoderErrorOr<void> Decoder::decode_frame(ByteBuffer const& frame_data)
|
||||
{
|
||||
TRY(m_parser->parse_frame(frame_data));
|
||||
// TODO:
|
||||
|
@ -51,7 +51,7 @@ u8 Decoder::merge_probs(int const* tree, int index, u8* probs, u8* counts, u8 co
|
|||
return left_count + right_count;
|
||||
}
|
||||
|
||||
ErrorOr<void> Decoder::adapt_coef_probs()
|
||||
DecoderErrorOr<void> Decoder::adapt_coef_probs()
|
||||
{
|
||||
u8 update_factor;
|
||||
if (m_parser->m_frame_is_intra || m_parser->m_last_frame_type != KeyFrame)
|
||||
|
@ -96,7 +96,7 @@ ErrorOr<void> Decoder::adapt_coef_probs()
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
ErrorOr<void> Decoder::adapt_non_coef_probs()
|
||||
DecoderErrorOr<void> Decoder::adapt_non_coef_probs()
|
||||
{
|
||||
auto& probs = *m_parser->m_probability_tables;
|
||||
auto& counter = *m_parser->m_syntax_element_counter;
|
||||
|
@ -152,25 +152,25 @@ u8 Decoder::adapt_prob(u8 prob, u8 counts[2])
|
|||
return merge_prob(prob, counts[0], counts[1], COUNT_SAT, MAX_UPDATE_FACTOR);
|
||||
}
|
||||
|
||||
ErrorOr<void> Decoder::predict_intra(size_t, u32, u32, bool, bool, bool, TXSize, u32)
|
||||
DecoderErrorOr<void> Decoder::predict_intra(size_t, u32, u32, bool, bool, bool, TXSize, u32)
|
||||
{
|
||||
// TODO: Implement
|
||||
return Error::from_string_literal("predict_intra not implemented");
|
||||
return DecoderError::not_implemented();
|
||||
}
|
||||
|
||||
ErrorOr<void> Decoder::predict_inter(size_t, u32, u32, u32, u32, u32)
|
||||
DecoderErrorOr<void> Decoder::predict_inter(size_t, u32, u32, u32, u32, u32)
|
||||
{
|
||||
// TODO: Implement
|
||||
return Error::from_string_literal("predict_inter not implemented");
|
||||
return DecoderError::not_implemented();
|
||||
}
|
||||
|
||||
ErrorOr<void> Decoder::reconstruct(size_t, u32, u32, TXSize)
|
||||
DecoderErrorOr<void> Decoder::reconstruct(size_t, u32, u32, TXSize)
|
||||
{
|
||||
// TODO: Implement
|
||||
return Error::from_string_literal("reconstruct not implemented");
|
||||
return DecoderError::not_implemented();
|
||||
}
|
||||
|
||||
ErrorOr<void> Decoder::update_reference_frames()
|
||||
DecoderErrorOr<void> Decoder::update_reference_frames()
|
||||
{
|
||||
for (auto i = 0; i < NUM_REF_FRAMES; i++) {
|
||||
dbgln("updating frame {}? {}", i, (m_parser->m_refresh_frame_flags & (1 << i)) == 1);
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Parser.h"
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/Error.h>
|
||||
#include <LibVideo/DecoderError.h>
|
||||
|
||||
#include "Parser.h"
|
||||
|
||||
namespace Video::VP9 {
|
||||
|
||||
|
@ -18,27 +20,27 @@ class Decoder {
|
|||
|
||||
public:
|
||||
Decoder();
|
||||
ErrorOr<void> decode_frame(ByteBuffer const&);
|
||||
DecoderErrorOr<void> decode_frame(ByteBuffer const&);
|
||||
void dump_frame_info();
|
||||
|
||||
private:
|
||||
/* (8.4) Probability Adaptation Process */
|
||||
u8 merge_prob(u8 pre_prob, u8 count_0, u8 count_1, u8 count_sat, u8 max_update_factor);
|
||||
u8 merge_probs(int const* tree, int index, u8* probs, u8* counts, u8 count_sat, u8 max_update_factor);
|
||||
ErrorOr<void> adapt_coef_probs();
|
||||
ErrorOr<void> adapt_non_coef_probs();
|
||||
DecoderErrorOr<void> adapt_coef_probs();
|
||||
DecoderErrorOr<void> adapt_non_coef_probs();
|
||||
void adapt_probs(int const* tree, u8* probs, u8* counts);
|
||||
u8 adapt_prob(u8 prob, u8 counts[2]);
|
||||
|
||||
/* (8.5) Prediction Processes */
|
||||
ErrorOr<void> predict_intra(size_t plane, u32 x, u32 y, bool have_left, bool have_above, bool not_on_right, TXSize tx_size, u32 block_index);
|
||||
ErrorOr<void> predict_inter(size_t plane, u32 x, u32 y, u32 w, u32 h, u32 block_index);
|
||||
DecoderErrorOr<void> predict_intra(size_t plane, u32 x, u32 y, bool have_left, bool have_above, bool not_on_right, TXSize tx_size, u32 block_index);
|
||||
DecoderErrorOr<void> predict_inter(size_t plane, u32 x, u32 y, u32 w, u32 h, u32 block_index);
|
||||
|
||||
/* (8.6) Reconstruction and Dequantization */
|
||||
ErrorOr<void> reconstruct(size_t plane, u32 x, u32 y, TXSize size);
|
||||
DecoderErrorOr<void> reconstruct(size_t plane, u32 transform_block_x, u32 transform_block_y, TXSize transform_block_size);
|
||||
|
||||
/* (8.10) Reference Frame Update Process */
|
||||
ErrorOr<void> update_reference_frames();
|
||||
DecoderErrorOr<void> update_reference_frames();
|
||||
|
||||
NonnullOwnPtr<Parser> m_parser;
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -7,14 +7,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
#include <LibVideo/DecoderError.h>
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "LookupTables.h"
|
||||
#include "MV.h"
|
||||
#include "ProbabilityTables.h"
|
||||
#include "SyntaxElementCounter.h"
|
||||
#include "TreeParser.h"
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
|
||||
namespace Video::VP9 {
|
||||
|
||||
|
@ -27,23 +30,12 @@ class Parser {
|
|||
public:
|
||||
explicit Parser(Decoder&);
|
||||
~Parser();
|
||||
ErrorOr<void> parse_frame(ByteBuffer const&);
|
||||
DecoderErrorOr<void> parse_frame(ByteBuffer const&);
|
||||
void dump_info();
|
||||
|
||||
private:
|
||||
ErrorOr<FrameType> read_frame_type()
|
||||
{
|
||||
if (TRY(m_bit_stream->read_bit()))
|
||||
return NonKeyFrame;
|
||||
return KeyFrame;
|
||||
}
|
||||
|
||||
ErrorOr<ColorRange> read_color_range()
|
||||
{
|
||||
if (TRY(m_bit_stream->read_bit()))
|
||||
return FullSwing;
|
||||
return StudioSwing;
|
||||
}
|
||||
DecoderErrorOr<FrameType> read_frame_type();
|
||||
DecoderErrorOr<ColorRange> read_color_range();
|
||||
|
||||
/* Utilities */
|
||||
void clear_context(Vector<u8>& context, size_t size);
|
||||
|
@ -53,84 +45,84 @@ private:
|
|||
|
||||
/* (6.1) Frame Syntax */
|
||||
bool trailing_bits();
|
||||
ErrorOr<void> refresh_probs();
|
||||
DecoderErrorOr<void> refresh_probs();
|
||||
|
||||
/* (6.2) Uncompressed Header Syntax */
|
||||
ErrorOr<void> uncompressed_header();
|
||||
ErrorOr<void> frame_sync_code();
|
||||
ErrorOr<void> color_config();
|
||||
ErrorOr<void> frame_size();
|
||||
ErrorOr<void> render_size();
|
||||
ErrorOr<void> frame_size_with_refs();
|
||||
DecoderErrorOr<void> uncompressed_header();
|
||||
DecoderErrorOr<void> frame_sync_code();
|
||||
DecoderErrorOr<void> color_config();
|
||||
DecoderErrorOr<void> frame_size();
|
||||
DecoderErrorOr<void> render_size();
|
||||
DecoderErrorOr<void> frame_size_with_refs();
|
||||
void compute_image_size();
|
||||
ErrorOr<void> read_interpolation_filter();
|
||||
ErrorOr<void> loop_filter_params();
|
||||
ErrorOr<void> quantization_params();
|
||||
ErrorOr<i8> read_delta_q();
|
||||
ErrorOr<void> segmentation_params();
|
||||
ErrorOr<u8> read_prob();
|
||||
ErrorOr<void> tile_info();
|
||||
DecoderErrorOr<void> read_interpolation_filter();
|
||||
DecoderErrorOr<void> loop_filter_params();
|
||||
DecoderErrorOr<void> quantization_params();
|
||||
DecoderErrorOr<i8> read_delta_q();
|
||||
DecoderErrorOr<void> segmentation_params();
|
||||
DecoderErrorOr<u8> read_prob();
|
||||
DecoderErrorOr<void> tile_info();
|
||||
u16 calc_min_log2_tile_cols();
|
||||
u16 calc_max_log2_tile_cols();
|
||||
void setup_past_independence();
|
||||
|
||||
/* (6.3) Compressed Header Syntax */
|
||||
ErrorOr<void> compressed_header();
|
||||
ErrorOr<void> read_tx_mode();
|
||||
ErrorOr<void> tx_mode_probs();
|
||||
ErrorOr<u8> diff_update_prob(u8 prob);
|
||||
ErrorOr<u8> decode_term_subexp();
|
||||
DecoderErrorOr<void> compressed_header();
|
||||
DecoderErrorOr<void> read_tx_mode();
|
||||
DecoderErrorOr<void> tx_mode_probs();
|
||||
DecoderErrorOr<u8> diff_update_prob(u8 prob);
|
||||
DecoderErrorOr<u8> decode_term_subexp();
|
||||
u8 inv_remap_prob(u8 delta_prob, u8 prob);
|
||||
u8 inv_recenter_nonneg(u8 v, u8 m);
|
||||
ErrorOr<void> read_coef_probs();
|
||||
ErrorOr<void> read_skip_prob();
|
||||
ErrorOr<void> read_inter_mode_probs();
|
||||
ErrorOr<void> read_interp_filter_probs();
|
||||
ErrorOr<void> read_is_inter_probs();
|
||||
ErrorOr<void> frame_reference_mode();
|
||||
ErrorOr<void> frame_reference_mode_probs();
|
||||
ErrorOr<void> read_y_mode_probs();
|
||||
ErrorOr<void> read_partition_probs();
|
||||
ErrorOr<void> mv_probs();
|
||||
ErrorOr<u8> update_mv_prob(u8 prob);
|
||||
DecoderErrorOr<void> read_coef_probs();
|
||||
DecoderErrorOr<void> read_skip_prob();
|
||||
DecoderErrorOr<void> read_inter_mode_probs();
|
||||
DecoderErrorOr<void> read_interp_filter_probs();
|
||||
DecoderErrorOr<void> read_is_inter_probs();
|
||||
DecoderErrorOr<void> frame_reference_mode();
|
||||
DecoderErrorOr<void> frame_reference_mode_probs();
|
||||
DecoderErrorOr<void> read_y_mode_probs();
|
||||
DecoderErrorOr<void> read_partition_probs();
|
||||
DecoderErrorOr<void> mv_probs();
|
||||
DecoderErrorOr<u8> update_mv_prob(u8 prob);
|
||||
void setup_compound_reference_mode();
|
||||
|
||||
/* (6.4) Decode Tiles Syntax */
|
||||
ErrorOr<void> decode_tiles();
|
||||
DecoderErrorOr<void> decode_tiles();
|
||||
void clear_above_context();
|
||||
u32 get_tile_offset(u32 tile_num, u32 mis, u32 tile_size_log2);
|
||||
ErrorOr<void> decode_tile();
|
||||
DecoderErrorOr<void> decode_tile();
|
||||
void clear_left_context();
|
||||
ErrorOr<void> decode_partition(u32 row, u32 col, u8 block_subsize);
|
||||
ErrorOr<void> decode_block(u32 row, u32 col, u8 subsize);
|
||||
ErrorOr<void> mode_info();
|
||||
ErrorOr<void> intra_frame_mode_info();
|
||||
ErrorOr<void> intra_segment_id();
|
||||
ErrorOr<void> read_skip();
|
||||
DecoderErrorOr<void> decode_partition(u32 row, u32 col, u8 block_subsize);
|
||||
DecoderErrorOr<void> decode_block(u32 row, u32 col, u8 subsize);
|
||||
DecoderErrorOr<void> mode_info();
|
||||
DecoderErrorOr<void> intra_frame_mode_info();
|
||||
DecoderErrorOr<void> intra_segment_id();
|
||||
DecoderErrorOr<void> read_skip();
|
||||
bool seg_feature_active(u8 feature);
|
||||
ErrorOr<void> read_tx_size(bool allow_select);
|
||||
ErrorOr<void> inter_frame_mode_info();
|
||||
ErrorOr<void> inter_segment_id();
|
||||
DecoderErrorOr<void> read_tx_size(bool allow_select);
|
||||
DecoderErrorOr<void> inter_frame_mode_info();
|
||||
DecoderErrorOr<void> inter_segment_id();
|
||||
u8 get_segment_id();
|
||||
ErrorOr<void> read_is_inter();
|
||||
ErrorOr<void> intra_block_mode_info();
|
||||
ErrorOr<void> inter_block_mode_info();
|
||||
ErrorOr<void> read_ref_frames();
|
||||
ErrorOr<void> assign_mv(bool is_compound);
|
||||
ErrorOr<void> read_mv(u8 ref);
|
||||
ErrorOr<i32> read_mv_component(u8 component);
|
||||
ErrorOr<void> residual();
|
||||
DecoderErrorOr<void> read_is_inter();
|
||||
DecoderErrorOr<void> intra_block_mode_info();
|
||||
DecoderErrorOr<void> inter_block_mode_info();
|
||||
DecoderErrorOr<void> read_ref_frames();
|
||||
DecoderErrorOr<void> assign_mv(bool is_compound);
|
||||
DecoderErrorOr<void> read_mv(u8 ref);
|
||||
DecoderErrorOr<i32> read_mv_component(u8 component);
|
||||
DecoderErrorOr<void> residual();
|
||||
TXSize get_uv_tx_size();
|
||||
BlockSubsize get_plane_block_size(u32 subsize, u8 plane);
|
||||
ErrorOr<bool> tokens(size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
|
||||
DecoderErrorOr<bool> tokens(size_t plane, u32 x, u32 y, TXSize tx_size, u32 block_index);
|
||||
u32 const* get_scan(size_t plane, TXSize tx_size, u32 block_index);
|
||||
ErrorOr<i32> read_coef(Token token);
|
||||
DecoderErrorOr<i32> read_coef(Token token);
|
||||
|
||||
/* (6.5) Motion Vector Prediction */
|
||||
ErrorOr<void> find_mv_refs(ReferenceFrame, int block);
|
||||
ErrorOr<void> find_best_ref_mvs(int ref_list);
|
||||
ErrorOr<void> append_sub8x8_mvs(u8 block, u8 ref_list);
|
||||
bool use_mv_hp(MV const& delta_mv);
|
||||
DecoderErrorOr<void> find_mv_refs(ReferenceFrame, int block);
|
||||
DecoderErrorOr<void> find_best_ref_mvs(int ref_list);
|
||||
DecoderErrorOr<void> append_sub8x8_mvs(u8 block, u8 ref_list);
|
||||
DecoderErrorOr<bool> use_mv_hp(MV const& delta_mv);
|
||||
|
||||
u8 m_profile { 0 };
|
||||
u8 m_frame_to_show_map_index { 0 };
|
||||
|
|
Loading…
Reference in a new issue