mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 21:27:34 +00:00
LibVideo/VP9: Implement most of inter_frame_mode_info (6.4.11-6.4.14)
This commit is contained in:
parent
e687f05b42
commit
42fdaa7f60
4 changed files with 115 additions and 14 deletions
|
@ -828,7 +828,7 @@ bool Decoder::intra_frame_mode_info()
|
||||||
m_ref_frame[1] = None;
|
m_ref_frame[1] = None;
|
||||||
m_is_inter = false;
|
m_is_inter = false;
|
||||||
if (m_mi_size >= Block_8x8) {
|
if (m_mi_size >= Block_8x8) {
|
||||||
m_default_intra_mode = static_cast<IntraMode>(m_tree_parser->parse_tree(SyntaxElementType::DefaultIntraMode));
|
m_default_intra_mode = m_tree_parser->parse_tree<IntraMode>(SyntaxElementType::DefaultIntraMode);
|
||||||
m_y_mode = m_default_intra_mode;
|
m_y_mode = m_default_intra_mode;
|
||||||
for (auto b = 0; b < 4; b++)
|
for (auto b = 0; b < 4; b++)
|
||||||
m_sub_modes[b] = m_y_mode;
|
m_sub_modes[b] = m_y_mode;
|
||||||
|
@ -837,7 +837,7 @@ bool Decoder::intra_frame_mode_info()
|
||||||
m_num_4x4_h = num_4x4_blocks_high_lookup[m_mi_size];
|
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 idy = 0; idy < 2; idy += m_num_4x4_h) {
|
||||||
for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
|
for (auto idx = 0; idx < 2; idx += m_num_4x4_w) {
|
||||||
m_default_intra_mode = static_cast<IntraMode>(m_tree_parser->parse_tree(SyntaxElementType::DefaultIntraMode));
|
m_default_intra_mode = m_tree_parser->parse_tree<IntraMode>(SyntaxElementType::DefaultIntraMode);
|
||||||
for (auto y = 0; y < m_num_4x4_h; y++) {
|
for (auto y = 0; y < m_num_4x4_h; y++) {
|
||||||
for (auto x = 0; x < m_num_4x4_w; x++) {
|
for (auto x = 0; x < m_num_4x4_w; x++) {
|
||||||
auto index = (idy + y) * 2 + idx + x;
|
auto index = (idy + y) * 2 + idx + x;
|
||||||
|
@ -850,14 +850,14 @@ bool Decoder::intra_frame_mode_info()
|
||||||
}
|
}
|
||||||
m_y_mode = m_default_intra_mode;
|
m_y_mode = m_default_intra_mode;
|
||||||
}
|
}
|
||||||
m_uv_mode = m_tree_parser->parse_tree(SyntaxElementType::DefaultUVMode);
|
m_uv_mode = m_tree_parser->parse_tree<u8>(SyntaxElementType::DefaultUVMode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Decoder::intra_segment_id()
|
bool Decoder::intra_segment_id()
|
||||||
{
|
{
|
||||||
if (m_segmentation_enabled && m_segmentation_update_map) {
|
if (m_segmentation_enabled && m_segmentation_update_map) {
|
||||||
m_segment_id = m_tree_parser->parse_tree(SyntaxElementType::SegmentID);
|
m_segment_id = m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID);
|
||||||
} else {
|
} else {
|
||||||
m_segment_id = 0;
|
m_segment_id = 0;
|
||||||
}
|
}
|
||||||
|
@ -867,9 +867,9 @@ bool Decoder::intra_segment_id()
|
||||||
bool Decoder::read_skip()
|
bool Decoder::read_skip()
|
||||||
{
|
{
|
||||||
if (seg_feature_active(SEG_LVL_SKIP)) {
|
if (seg_feature_active(SEG_LVL_SKIP)) {
|
||||||
m_skip = 1;
|
m_skip = true;
|
||||||
} else {
|
} else {
|
||||||
m_skip = m_tree_parser->parse_tree(SyntaxElementType::Skip);
|
m_skip = m_tree_parser->parse_tree<bool>(SyntaxElementType::Skip);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -883,7 +883,7 @@ bool Decoder::read_tx_size(bool allow_select)
|
||||||
{
|
{
|
||||||
m_max_tx_size = max_txsize_lookup[m_mi_size];
|
m_max_tx_size = max_txsize_lookup[m_mi_size];
|
||||||
if (allow_select && m_tx_mode == TXModeSelect && m_mi_size >= Block_8x8) {
|
if (allow_select && m_tx_mode == TXModeSelect && m_mi_size >= Block_8x8) {
|
||||||
m_tx_size = static_cast<TXSize>(m_tree_parser->parse_tree(SyntaxElementType::TXSize));
|
m_tx_size = m_tree_parser->parse_tree<TXSize>(SyntaxElementType::TXSize);
|
||||||
} else {
|
} else {
|
||||||
m_tx_size = min(m_max_tx_size, tx_mode_to_biggest_tx_size[m_tx_mode]);
|
m_tx_size = min(m_max_tx_size, tx_mode_to_biggest_tx_size[m_tx_mode]);
|
||||||
}
|
}
|
||||||
|
@ -892,7 +892,87 @@ bool Decoder::read_tx_size(bool allow_select)
|
||||||
|
|
||||||
bool Decoder::inter_frame_mode_info()
|
bool Decoder::inter_frame_mode_info()
|
||||||
{
|
{
|
||||||
// FIXME: Implement
|
m_left_ref_frame[0] = m_available_l ? m_ref_frames[m_mi_row][m_mi_col - 1][0] : IntraFrame;
|
||||||
|
m_above_ref_frame[0] = m_available_u ? m_ref_frames[m_mi_row - 1][m_mi_col][0] : IntraFrame;
|
||||||
|
m_left_ref_frame[1] = m_available_l ? m_ref_frames[m_mi_row][m_mi_col - 1][1] : None;
|
||||||
|
m_above_ref_frame[1] = m_available_u ? m_ref_frames[m_mi_row - 1][m_mi_col][1] : None;
|
||||||
|
m_left_intra = m_left_ref_frame[0] <= IntraFrame;
|
||||||
|
m_above_intra = m_above_ref_frame[0] <= IntraFrame;
|
||||||
|
m_left_single = m_left_ref_frame[1] <= None;
|
||||||
|
m_above_single = m_above_ref_frame[1] <= None;
|
||||||
|
SAFE_CALL(inter_segment_id());
|
||||||
|
SAFE_CALL(read_skip());
|
||||||
|
SAFE_CALL(read_is_inter());
|
||||||
|
SAFE_CALL(read_tx_size(!m_skip || !m_is_inter));
|
||||||
|
if (m_is_inter) {
|
||||||
|
SAFE_CALL(inter_block_mode_info());
|
||||||
|
} else {
|
||||||
|
SAFE_CALL(intra_block_mode_info());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decoder::inter_segment_id()
|
||||||
|
{
|
||||||
|
if (!m_segmentation_enabled) {
|
||||||
|
m_segment_id = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto predicted_segment_id = get_segment_id();
|
||||||
|
if (!m_segmentation_update_map) {
|
||||||
|
m_segment_id = predicted_segment_id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!m_segmentation_temporal_update) {
|
||||||
|
m_segment_id = m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto seg_id_predicted = m_tree_parser->parse_tree<bool>(SyntaxElementType::SegIDPredicted);
|
||||||
|
if (seg_id_predicted)
|
||||||
|
m_segment_id = predicted_segment_id;
|
||||||
|
else
|
||||||
|
m_segment_id = m_tree_parser->parse_tree<u8>(SyntaxElementType::SegmentID);
|
||||||
|
for (auto i = 0u; i < num_8x8_blocks_wide_lookup[m_mi_size]; i++)
|
||||||
|
m_above_seg_pred_context[m_mi_col + i] = seg_id_predicted;
|
||||||
|
for (auto i = 0u; i < num_8x8_blocks_high_lookup[m_mi_size]; i++)
|
||||||
|
m_left_seg_pred_context[m_mi_row + i] = seg_id_predicted;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 Decoder::get_segment_id()
|
||||||
|
{
|
||||||
|
auto bw = num_8x8_blocks_wide_lookup[m_mi_size];
|
||||||
|
auto bh = num_8x8_blocks_high_lookup[m_mi_size];
|
||||||
|
auto xmis = min(m_mi_cols - m_mi_col, (u32)bw);
|
||||||
|
auto ymis = min(m_mi_rows - m_mi_row, (u32)bh);
|
||||||
|
u8 segment = 7;
|
||||||
|
for (auto y = 0u; y < ymis; y++) {
|
||||||
|
for (auto x = 0u; x < xmis; x++) {
|
||||||
|
segment = min(segment, m_prev_segment_ids[m_mi_row + y][m_mi_col + x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decoder::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 = m_tree_parser->parse_tree<bool>(SyntaxElementType::IsInter);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decoder::inter_block_mode_info()
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decoder::intra_block_mode_info()
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,13 @@ private:
|
||||||
bool read_skip();
|
bool read_skip();
|
||||||
bool seg_feature_active(u8 feature);
|
bool seg_feature_active(u8 feature);
|
||||||
bool read_tx_size(bool allow_select);
|
bool read_tx_size(bool allow_select);
|
||||||
|
|
||||||
bool inter_frame_mode_info();
|
bool inter_frame_mode_info();
|
||||||
|
bool inter_segment_id();
|
||||||
|
u8 get_segment_id();
|
||||||
|
bool read_is_inter();
|
||||||
|
bool inter_block_mode_info();
|
||||||
|
|
||||||
|
bool intra_block_mode_info();
|
||||||
|
|
||||||
u8 m_profile { 0 };
|
u8 m_profile { 0 };
|
||||||
u8 m_frame_to_show_map_index { 0 };
|
u8 m_frame_to_show_map_index { 0 };
|
||||||
|
@ -158,8 +163,8 @@ private:
|
||||||
u32 m_mi_size { 0 };
|
u32 m_mi_size { 0 };
|
||||||
bool m_available_u { false };
|
bool m_available_u { false };
|
||||||
bool m_available_l { false };
|
bool m_available_l { false };
|
||||||
int m_segment_id { 0 };
|
u8 m_segment_id { 0 };
|
||||||
int m_skip { false };
|
bool m_skip { false };
|
||||||
u8 m_num_8x8 { 0 };
|
u8 m_num_8x8 { 0 };
|
||||||
bool m_has_rows { false };
|
bool m_has_rows { false };
|
||||||
bool m_has_cols { false };
|
bool m_has_cols { false };
|
||||||
|
@ -176,6 +181,14 @@ private:
|
||||||
u8 m_num_4x4_w { 0 };
|
u8 m_num_4x4_w { 0 };
|
||||||
u8 m_num_4x4_h { 0 };
|
u8 m_num_4x4_h { 0 };
|
||||||
u8 m_uv_mode { 0 }; // FIXME: Is u8 the right size?
|
u8 m_uv_mode { 0 }; // FIXME: Is u8 the right size?
|
||||||
|
ReferenceFrame m_left_ref_frame[2];
|
||||||
|
ReferenceFrame m_above_ref_frame[2];
|
||||||
|
Vector<Vector<Vector<ReferenceFrame>>> m_ref_frames; // TODO: Can we make these fixed sized allocations?
|
||||||
|
bool m_left_intra { false };
|
||||||
|
bool m_above_intra { false };
|
||||||
|
bool m_left_single { false };
|
||||||
|
bool m_above_single { false };
|
||||||
|
Vector<Vector<u8>> m_prev_segment_ids;
|
||||||
|
|
||||||
bool m_use_hp { false };
|
bool m_use_hp { false };
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
namespace Video::VP9 {
|
namespace Video::VP9 {
|
||||||
|
|
||||||
int TreeParser::parse_tree(SyntaxElementType type)
|
template<typename T>
|
||||||
|
T TreeParser::parse_tree(SyntaxElementType type)
|
||||||
{
|
{
|
||||||
auto tree_selection = select_tree(type);
|
auto tree_selection = select_tree(type);
|
||||||
int value;
|
int value;
|
||||||
|
@ -25,9 +26,15 @@ int TreeParser::parse_tree(SyntaxElementType type)
|
||||||
value = -n;
|
value = -n;
|
||||||
}
|
}
|
||||||
count_syntax_element(type, value);
|
count_syntax_element(type, value);
|
||||||
return value;
|
return static_cast<T>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template int TreeParser::parse_tree(SyntaxElementType);
|
||||||
|
template bool TreeParser::parse_tree(SyntaxElementType);
|
||||||
|
template u8 TreeParser::parse_tree(SyntaxElementType);
|
||||||
|
template IntraMode TreeParser::parse_tree(SyntaxElementType);
|
||||||
|
template TXSize TreeParser::parse_tree(SyntaxElementType);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select a tree value based on the type of syntax element being parsed, as well as some parser state, as specified in section 9.3.1
|
* Select a tree value based on the type of syntax element being parsed, as well as some parser state, as specified in section 9.3.1
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -41,7 +41,8 @@ public:
|
||||||
TreeSelectionValue m_value;
|
TreeSelectionValue m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
int parse_tree(SyntaxElementType type);
|
template<typename T = int>
|
||||||
|
T parse_tree(SyntaxElementType type);
|
||||||
TreeSelection select_tree(SyntaxElementType type);
|
TreeSelection select_tree(SyntaxElementType type);
|
||||||
u8 select_tree_probability(SyntaxElementType type, u8 node);
|
u8 select_tree_probability(SyntaxElementType type, u8 node);
|
||||||
void count_syntax_element(SyntaxElementType type, int value);
|
void count_syntax_element(SyntaxElementType type, int value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue