mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 20:37:34 +00:00
LibVideo/VP9: Start parsing residuals (6.4.21-6.4.23)
Additionally, this uncovered a couple bugs with existing code, so those have been fixed. Currently, parsing a whole video does fail because we are now using a new calculation for frame width, but it hasn't been fully implemented yet.
This commit is contained in:
parent
cbff7c386a
commit
66628053d4
4 changed files with 131 additions and 8 deletions
|
@ -44,9 +44,10 @@ bool Decoder::parse_frame(ByteBuffer const& frame_data)
|
||||||
SAFE_CALL(compressed_header());
|
SAFE_CALL(compressed_header());
|
||||||
dbgln("Finished reading compressed header");
|
dbgln("Finished reading compressed header");
|
||||||
SAFE_CALL(m_bit_stream->exit_bool());
|
SAFE_CALL(m_bit_stream->exit_bool());
|
||||||
dbgln("Finished reading frame!");
|
|
||||||
|
|
||||||
SAFE_CALL(decode_tiles());
|
SAFE_CALL(decode_tiles());
|
||||||
|
|
||||||
|
dbgln("Finished reading frame!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +355,7 @@ bool Decoder::tile_info()
|
||||||
u16 Decoder::calc_min_log2_tile_cols()
|
u16 Decoder::calc_min_log2_tile_cols()
|
||||||
{
|
{
|
||||||
auto min_log_2 = 0u;
|
auto min_log_2 = 0u;
|
||||||
while ((u8)(MAX_TILE_WIDTH_B64 << min_log_2) < m_sb64_cols)
|
while ((u32)(MAX_TILE_WIDTH_B64 << min_log_2) < m_sb64_cols)
|
||||||
min_log_2++;
|
min_log_2++;
|
||||||
return min_log_2;
|
return min_log_2;
|
||||||
}
|
}
|
||||||
|
@ -780,8 +781,6 @@ bool Decoder::decode_partition(u32 row, u32 col, u8 block_subsize)
|
||||||
m_has_cols = (col + half_block_8x8) < m_mi_cols;
|
m_has_cols = (col + half_block_8x8) < m_mi_cols;
|
||||||
|
|
||||||
auto partition = m_tree_parser->parse_tree(SyntaxElementType::Partition);
|
auto partition = m_tree_parser->parse_tree(SyntaxElementType::Partition);
|
||||||
dbgln("Parsed partition value {}", partition);
|
|
||||||
|
|
||||||
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) {
|
||||||
SAFE_CALL(decode_block(row, col, subsize));
|
SAFE_CALL(decode_block(row, col, subsize));
|
||||||
|
@ -816,7 +815,10 @@ bool Decoder::decode_block(u32 row, u32 col, u8 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;
|
||||||
SAFE_CALL(mode_info());
|
SAFE_CALL(mode_info());
|
||||||
|
m_eob_total = 0;
|
||||||
|
SAFE_CALL(residual());
|
||||||
// FIXME: Finish implementing
|
// FIXME: Finish implementing
|
||||||
|
// note: when finished, re-enable calculate_default_intra_mode_probability's usage of m_sub_modes
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,6 +1106,81 @@ bool Decoder::read_mv(u8)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Decoder::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++) {
|
||||||
|
auto tx_size = (plane > 0) ? get_uv_tx_size() : m_tx_size;
|
||||||
|
auto step = 1 << tx_size;
|
||||||
|
auto plane_size = get_plane_block_size(block_size, plane);
|
||||||
|
auto num_4x4_w = num_4x4_blocks_wide_lookup[plane_size];
|
||||||
|
auto num_4x4_h = num_4x4_blocks_high_lookup[plane_size];
|
||||||
|
auto sub_x = (plane > 0) ? m_subsampling_x : 0;
|
||||||
|
auto sub_y = (plane > 0) ? m_subsampling_y : 0;
|
||||||
|
auto base_x = (m_mi_col * 8) >> sub_x;
|
||||||
|
auto base_y = (m_mi_row * 8) >> sub_y;
|
||||||
|
if (m_is_inter) {
|
||||||
|
if (m_mi_size < Block_8x8) {
|
||||||
|
for (auto y = 0; y < num_4x4_h; y++) {
|
||||||
|
for (auto x = 0; x < num_4x4_w; x++) {
|
||||||
|
SAFE_CALL(predict_inter(plane, base_x + (4 * x), base_y + (4 * y), 4, 4, (y * num_4x4_w) + x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SAFE_CALL(predict_inter(plane, base_x, base_y, num_4x4_w * 4, num_4x4_h * 4, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto max_x = (m_mi_cols * 8) >> sub_x;
|
||||||
|
auto max_y = (m_mi_rows * 8) >> sub_y;
|
||||||
|
auto block_index = 0;
|
||||||
|
for (auto y = 0; y < num_4x4_h; y += step) {
|
||||||
|
for (auto x = 0; x < num_4x4_w; x += step) {
|
||||||
|
auto start_x = base_x + (4 * x);
|
||||||
|
auto start_y = base_y + (4 * y);
|
||||||
|
auto non_zero = false;
|
||||||
|
if (start_x < max_x && start_y < max_y) {
|
||||||
|
if (!m_is_inter)
|
||||||
|
SAFE_CALL(predict_intra(plane, start_x, start_y, m_available_l || x > 0, m_available_u || y > 0, (x + step) < num_4x4_w, tx_size, block_index));
|
||||||
|
if (!m_skip) {
|
||||||
|
non_zero = tokens(plane, start_x, start_y, tx_size, block_index);
|
||||||
|
SAFE_CALL(reconstruct(plane, start_x, start_y, tx_size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto above_sub_context = m_above_nonzero_context[plane];
|
||||||
|
auto left_sub_context = m_left_nonzero_context[plane];
|
||||||
|
above_sub_context.resize_and_keep_capacity((start_x >> 2) + step);
|
||||||
|
left_sub_context.resize_and_keep_capacity((start_y >> 2) + step);
|
||||||
|
for (auto i = 0; i < step; i++) {
|
||||||
|
above_sub_context[(start_x >> 2) + i] = non_zero;
|
||||||
|
left_sub_context[(start_y >> 2) + i] = non_zero;
|
||||||
|
}
|
||||||
|
block_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TXSize Decoder::get_uv_tx_size()
|
||||||
|
{
|
||||||
|
if (m_mi_size < Block_8x8)
|
||||||
|
return TX_4x4;
|
||||||
|
return min(m_tx_size, max_txsize_lookup[get_plane_block_size(m_mi_size, 1)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockSubsize Decoder::get_plane_block_size(u32 subsize, u8 plane)
|
||||||
|
{
|
||||||
|
auto sub_x = (plane > 0) ? m_subsampling_x : 0;
|
||||||
|
auto sub_y = (plane > 0) ? m_subsampling_y : 0;
|
||||||
|
return ss_size_lookup[subsize][sub_x][sub_y];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decoder::tokens(size_t, u32, u32, TXSize, u32)
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Decoder::find_mv_refs(ReferenceFrame, int)
|
bool Decoder::find_mv_refs(ReferenceFrame, int)
|
||||||
{
|
{
|
||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
|
@ -1122,6 +1199,24 @@ bool Decoder::append_sub8x8_mvs(u8, u8)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Decoder::predict_intra(size_t, u32, u32, bool, bool, bool, TXSize, u32)
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decoder::predict_inter(size_t, u32, u32, u32, u32, u32)
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decoder::reconstruct(size_t, u32, u32, TXSize)
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Decoder::dump_info()
|
void Decoder::dump_info()
|
||||||
{
|
{
|
||||||
dbgln("Frame dimensions: {}x{}", m_frame_width, m_frame_height);
|
dbgln("Frame dimensions: {}x{}", m_frame_width, m_frame_height);
|
||||||
|
|
|
@ -107,12 +107,23 @@ private:
|
||||||
bool read_ref_frames();
|
bool read_ref_frames();
|
||||||
bool assign_mv(bool is_compound);
|
bool assign_mv(bool is_compound);
|
||||||
bool read_mv(u8 ref);
|
bool read_mv(u8 ref);
|
||||||
|
bool residual();
|
||||||
|
TXSize get_uv_tx_size();
|
||||||
|
BlockSubsize get_plane_block_size(u32 subsize, u8 plane);
|
||||||
|
bool tokens(size_t plane, u32 x, u32 y, TXSize size, u32 index);
|
||||||
|
|
||||||
/* (6.5) Motion Vector Prediction */
|
/* (6.5) Motion Vector Prediction */
|
||||||
bool find_mv_refs(ReferenceFrame, int block);
|
bool find_mv_refs(ReferenceFrame, int block);
|
||||||
bool find_best_ref_mvs(int ref_list);
|
bool find_best_ref_mvs(int ref_list);
|
||||||
bool append_sub8x8_mvs(u8 block, u8 ref_list);
|
bool append_sub8x8_mvs(u8 block, u8 ref_list);
|
||||||
|
|
||||||
|
/* (8.5) Prediction Processes */
|
||||||
|
bool 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);
|
||||||
|
bool predict_inter(size_t plane, u32 x, u32 y, u32 w, u32 h, u32 block_index);
|
||||||
|
|
||||||
|
/* (8.6) Reconstruction and Dequantization */
|
||||||
|
bool reconstruct(size_t plane, u32 x, u32 y, TXSize size);
|
||||||
|
|
||||||
u8 m_profile { 0 };
|
u8 m_profile { 0 };
|
||||||
u8 m_frame_to_show_map_index { 0 };
|
u8 m_frame_to_show_map_index { 0 };
|
||||||
u16 m_header_size_in_bytes { 0 };
|
u16 m_header_size_in_bytes { 0 };
|
||||||
|
@ -209,6 +220,7 @@ private:
|
||||||
Vector<Vector<Vector<IntraMode>>> m_sub_modes; // FIXME: Can we make these fixed sized allocations?
|
Vector<Vector<Vector<IntraMode>>> m_sub_modes; // FIXME: Can we make these fixed sized allocations?
|
||||||
u32 m_ref_frame_width[NUM_REF_FRAMES];
|
u32 m_ref_frame_width[NUM_REF_FRAMES];
|
||||||
u32 m_ref_frame_height[NUM_REF_FRAMES];
|
u32 m_ref_frame_height[NUM_REF_FRAMES];
|
||||||
|
u32 m_eob_total { 0 };
|
||||||
|
|
||||||
bool m_use_hp { false };
|
bool m_use_hp { false };
|
||||||
|
|
||||||
|
|
|
@ -200,4 +200,20 @@ static constexpr TXSize max_txsize_lookup[BLOCK_SIZES] = {
|
||||||
TX_32x32,
|
TX_32x32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr BlockSubsize ss_size_lookup[BLOCK_SIZES][2][2] = {
|
||||||
|
{ { Block_4x4, Block_Invalid }, { Block_Invalid, Block_Invalid } },
|
||||||
|
{ { Block_4x8, Block_4x4 }, { Block_Invalid, Block_Invalid } },
|
||||||
|
{ { Block_8x4, Block_Invalid }, { Block_4x4, Block_Invalid } },
|
||||||
|
{ { Block_8x8, Block_8x4 }, { Block_4x8, Block_4x4 } },
|
||||||
|
{ { Block_8x16, Block_8x8 }, { Block_Invalid, Block_4x8 } },
|
||||||
|
{ { Block_16x8, Block_Invalid }, { Block_8x8, Block_8x4 } },
|
||||||
|
{ { Block_16x16, Block_16x8 }, { Block_8x16, Block_8x8 } },
|
||||||
|
{ { Block_16x32, Block_16x16 }, { Block_Invalid, Block_8x16 } },
|
||||||
|
{ { Block_32x16, Block_Invalid }, { Block_16x16, Block_16x8 } },
|
||||||
|
{ { Block_32x32, Block_32x16 }, { Block_16x32, Block_16x16 } },
|
||||||
|
{ { Block_32x64, Block_32x32 }, { Block_Invalid, Block_16x32 } },
|
||||||
|
{ { Block_64x32, Block_Invalid }, { Block_32x32, Block_32x16 } },
|
||||||
|
{ { Block_64x64, Block_64x32 }, { Block_32x64, Block_32x32 } },
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,17 +207,17 @@ u8 TreeParser::calculate_default_intra_mode_probability(u8 node)
|
||||||
{
|
{
|
||||||
u32 above_mode, left_mode;
|
u32 above_mode, left_mode;
|
||||||
if (m_decoder.m_mi_size >= Block_8x8) {
|
if (m_decoder.m_mi_size >= Block_8x8) {
|
||||||
above_mode = AVAIL_U
|
above_mode = false // FIXME: AVAIL_U
|
||||||
? m_decoder.m_sub_modes[m_decoder.m_mi_row - 1][m_decoder.m_mi_col][2]
|
? m_decoder.m_sub_modes[m_decoder.m_mi_row - 1][m_decoder.m_mi_col][2]
|
||||||
: DcPred;
|
: DcPred;
|
||||||
left_mode = AVAIL_L
|
left_mode = false // FIXME: AVAIL_L
|
||||||
? m_decoder.m_sub_modes[m_decoder.m_mi_row][m_decoder.m_mi_col - 1][1]
|
? m_decoder.m_sub_modes[m_decoder.m_mi_row][m_decoder.m_mi_col - 1][1]
|
||||||
: DcPred;
|
: DcPred;
|
||||||
} else {
|
} else {
|
||||||
if (m_idy) {
|
if (m_idy) {
|
||||||
above_mode = m_decoder.m_block_sub_modes[m_idx];
|
above_mode = m_decoder.m_block_sub_modes[m_idx];
|
||||||
} else {
|
} else {
|
||||||
above_mode = AVAIL_U
|
above_mode = false // FIXME: AVAIL_U
|
||||||
? m_decoder.m_sub_modes[m_decoder.m_mi_row - 1][m_decoder.m_mi_col][2 + m_idx]
|
? m_decoder.m_sub_modes[m_decoder.m_mi_row - 1][m_decoder.m_mi_col][2 + m_idx]
|
||||||
: DcPred;
|
: DcPred;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ u8 TreeParser::calculate_default_intra_mode_probability(u8 node)
|
||||||
if (m_idx) {
|
if (m_idx) {
|
||||||
left_mode = m_decoder.m_block_sub_modes[m_idy * 2];
|
left_mode = m_decoder.m_block_sub_modes[m_idy * 2];
|
||||||
} else {
|
} else {
|
||||||
left_mode = AVAIL_L
|
left_mode = false // FIXME: AVAIL_L
|
||||||
? m_decoder.m_sub_modes[m_decoder.m_mi_row][m_decoder.m_mi_col - 1][1 + m_idy * 2]
|
? m_decoder.m_sub_modes[m_decoder.m_mi_row][m_decoder.m_mi_col - 1][1 + m_idy * 2]
|
||||||
: DcPred;
|
: DcPred;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue