LibVideo/VP9: Begin reference frame update process (8.10)

This was required for correctly parsing more than one frame's
height/width data properly. Additionally, start handling failure
a little more gracefully. Since we don't fully parse a tile before
starting to parse the next tile, we will now no longer make it past
the first tile mark, meaning we should not handle that scenario well.
This commit is contained in:
FalseHonesty 2021-06-26 19:58:08 -04:00 committed by Andreas Kling
parent 514559f074
commit cf6b3d0ce9
6 changed files with 54 additions and 10 deletions

View file

@ -43,8 +43,10 @@ int main(int argc, char** argv)
auto const& frame = block.frame(0);
dbgln("Reading frame 0 from block @ {}", block.timestamp());
vp9_decoder.decode_frame(frame);
bool failed = !vp9_decoder.decode_frame(frame);
vp9_decoder.dump_frame_info();
if (failed)
return 1;
}
}

View file

@ -10,6 +10,7 @@ set(SOURCES
VP9/Symbols.h
VP9/SyntaxElementCounter.cpp
VP9/TreeParser.cpp
VP9/Utilities.h
)
serenity_lib(LibVideo video)

View file

@ -5,6 +5,7 @@
*/
#include "Decoder.h"
#include "Utilities.h"
namespace Video::VP9 {
@ -15,7 +16,13 @@ Decoder::Decoder()
bool Decoder::decode_frame(ByteBuffer const& frame_data)
{
return m_parser->parse_frame(frame_data);
SAFE_CALL(m_parser->parse_frame(frame_data));
// TODO:
// - #2
// - #3
// - #4
SAFE_CALL(update_reference_frames());
return true;
}
void Decoder::dump_frame_info()
@ -41,4 +48,18 @@ bool Decoder::reconstruct(size_t, u32, u32, TXSize)
return true;
}
bool 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);
if ((m_parser->m_refresh_frame_flags & (1 << i)) != 1)
continue;
m_parser->m_ref_frame_width[i] = m_parser->m_frame_width;
m_parser->m_ref_frame_height[i] = m_parser->m_frame_height;
// TODO: 1.3-1.7
}
// TODO: 2.1-2.2
return true;
}
}

View file

@ -27,6 +27,9 @@ private:
/* (8.6) Reconstruction and Dequantization */
bool reconstruct(size_t plane, u32 x, u32 y, TXSize size);
/* (8.10) Reference Frame Update Process */
bool update_reference_frames();
NonnullOwnPtr<Parser> m_parser;
};

View file

@ -6,6 +6,7 @@
#include "Parser.h"
#include "Decoder.h"
#include "Utilities.h"
namespace Video::VP9 {
@ -13,10 +14,6 @@ namespace Video::VP9 {
if (m_bit_stream->read_bit() != 0) \
return false
#define SAFE_CALL(call) \
if (!(call)) [[unlikely]] \
return false
Parser::Parser(Decoder& decoder)
: m_probability_tables(make<ProbabilityTables>())
, m_tree_parser(make<TreeParser>(*this))
@ -220,6 +217,7 @@ bool Parser::frame_size_with_refs()
for (auto frame_index : m_ref_frame_idx) {
found_ref = 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];
m_frame_height = m_ref_frame_height[frame_index];
break;
@ -1203,10 +1201,10 @@ bool Parser::append_sub8x8_mvs(u8, u8)
void Parser::dump_info()
{
dbgln("Frame dimensions: {}x{}", m_frame_width, m_frame_height);
dbgln("Render dimensions: {}x{}", m_render_width, m_render_height);
dbgln("Bit depth: {}", m_bit_depth);
dbgln("Interpolation filter: {}", (u8)m_interpolation_filter);
outln("Frame dimensions: {}x{}", m_frame_width, m_frame_height);
outln("Render dimensions: {}x{}", m_render_width, m_render_height);
outln("Bit depth: {}", m_bit_depth);
outln("Interpolation filter: {}", (u8)m_interpolation_filter);
}
}

View file

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
namespace Video::VP9 {
#define SAFE_CALL(call) \
do { \
if (!(call)) [[unlikely]] { \
dbgln("FAILED " #call); \
return false; \
} \
} while (0)
}