diff options
Diffstat (limited to 'Userland/Libraries/LibVideo/VP9/TreeParser.cpp')
-rw-r--r-- | Userland/Libraries/LibVideo/VP9/TreeParser.cpp | 392 |
1 files changed, 374 insertions, 18 deletions
diff --git a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp index 62fb8344dc..df6091c32e 100644 --- a/Userland/Libraries/LibVideo/VP9/TreeParser.cpp +++ b/Userland/Libraries/LibVideo/VP9/TreeParser.cpp @@ -108,31 +108,31 @@ u8 TreeParser::select_tree_probability(SyntaxElementType type, u8 node) case SyntaxElementType::Partition: return calculate_partition_probability(node); case SyntaxElementType::DefaultIntraMode: - break; + return calculate_default_intra_mode_probability(node); case SyntaxElementType::DefaultUVMode: - break; + return calculate_default_uv_mode_probability(node); case SyntaxElementType::IntraMode: - break; + return calculate_intra_mode_probability(node); case SyntaxElementType::SubIntraMode: - break; + return calculate_sub_intra_mode_probability(node); case SyntaxElementType::UVMode: - break; + return calculate_uv_mode_probability(node); case SyntaxElementType::SegmentID: - return m_decoder.m_segmentation_tree_probs[node]; + return calculate_segment_id_probability(node); case SyntaxElementType::Skip: return calculate_skip_probability(); case SyntaxElementType::SegIDPredicted: - break; + return calculate_seg_id_predicted_probability(); case SyntaxElementType::IsInter: - break; + return calculate_is_inter_probability(); case SyntaxElementType::CompMode: - break; + return calculate_comp_mode_probability(); case SyntaxElementType::CompRef: - break; + return calculate_comp_ref_probability(); case SyntaxElementType::SingleRefP1: - break; + return calculate_single_ref_p1_probability(); case SyntaxElementType::SingleRefP2: - break; + return calculate_single_ref_p2_probability(); case SyntaxElementType::MVSign: break; case SyntaxElementType::MVClass0Bit: @@ -140,11 +140,11 @@ u8 TreeParser::select_tree_probability(SyntaxElementType type, u8 node) case SyntaxElementType::MVBit: break; case SyntaxElementType::TXSize: - break; + return calculate_tx_size_probability(node); case SyntaxElementType::InterMode: - break; + return calculate_inter_mode_probability(node); case SyntaxElementType::InterpFilter: - break; + return calculate_interp_filter_probability(node); case SyntaxElementType::MVJoint: break; case SyntaxElementType::MVClass: @@ -165,6 +165,17 @@ u8 TreeParser::select_tree_probability(SyntaxElementType type, u8 node) TODO(); } +#define ABOVE_FRAME_0 m_decoder.m_above_ref_frame[0] +#define ABOVE_FRAME_1 m_decoder.m_above_ref_frame[1] +#define LEFT_FRAME_0 m_decoder.m_left_ref_frame[0] +#define LEFT_FRAME_1 m_decoder.m_left_ref_frame[1] +#define AVAIL_U m_decoder.m_available_u +#define AVAIL_L m_decoder.m_available_l +#define ABOVE_INTRA m_decoder.m_above_intra +#define LEFT_INTRA m_decoder.m_left_intra +#define ABOVE_SINGLE m_decoder.m_above_single +#define LEFT_SINGLE m_decoder.m_left_single + u8 TreeParser::calculate_partition_probability(u8 node) { int node2; @@ -192,18 +203,363 @@ u8 TreeParser::calculate_partition_probability(u8 node) return m_decoder.m_probability_tables->partition_probs()[m_ctx][node2]; } +u8 TreeParser::calculate_default_intra_mode_probability(u8 node) +{ + u32 above_mode, left_mode; + if (m_decoder.m_mi_size >= Block_8x8) { + above_mode = AVAIL_U + ? m_decoder.m_sub_modes[m_decoder.m_mi_row - 1][m_decoder.m_mi_col][2] + : DcPred; + left_mode = AVAIL_L + ? m_decoder.m_sub_modes[m_decoder.m_mi_row][m_decoder.m_mi_col - 1][1] + : DcPred; + } else { + if (m_idy) { + above_mode = m_decoder.m_block_sub_modes[m_idx]; + } else { + above_mode = AVAIL_U + ? m_decoder.m_sub_modes[m_decoder.m_mi_row - 1][m_decoder.m_mi_col][2 + m_idx] + : DcPred; + } + + if (m_idx) { + left_mode = m_decoder.m_block_sub_modes[m_idy * 2]; + } else { + left_mode = AVAIL_L + ? m_decoder.m_sub_modes[m_decoder.m_mi_row][m_decoder.m_mi_col - 1][1 + m_idy * 2] + : DcPred; + } + } + return m_decoder.m_probability_tables->kf_y_mode_probs()[above_mode][left_mode][node]; +} + +u8 TreeParser::calculate_default_uv_mode_probability(u8 node) +{ + return m_decoder.m_probability_tables->kf_uv_mode_prob()[m_decoder.m_y_mode][node]; +} + +u8 TreeParser::calculate_intra_mode_probability(u8 node) +{ + m_ctx = size_group_lookup[m_decoder.m_mi_size]; + return m_decoder.m_probability_tables->y_mode_probs()[m_ctx][node]; +} + +u8 TreeParser::calculate_sub_intra_mode_probability(u8 node) +{ + m_ctx = 0; + return m_decoder.m_probability_tables->y_mode_probs()[m_ctx][node]; +} + +u8 TreeParser::calculate_uv_mode_probability(u8 node) +{ + m_ctx = m_decoder.m_y_mode; + return m_decoder.m_probability_tables->uv_mode_probs()[m_ctx][node]; +} + +u8 TreeParser::calculate_segment_id_probability(u8 node) +{ + return m_decoder.m_segmentation_tree_probs[node]; +} + u8 TreeParser::calculate_skip_probability() { m_ctx = 0; - if (m_decoder.m_available_u) { + if (AVAIL_U) { // FIXME: m_ctx += m_skips[m_mi_row - 1][m_mi_col]; } - if (m_decoder.m_available_l) { + if (AVAIL_L) { // FIXME: m_ctx += m_skips[m_mi_row][m_mi_col - 1]; } return m_decoder.m_probability_tables->skip_prob()[m_ctx]; } +u8 TreeParser::calculate_seg_id_predicted_probability() +{ + m_ctx = m_decoder.m_left_seg_pred_context[m_decoder.m_mi_row] + m_decoder.m_above_seg_pred_context[m_decoder.m_mi_col]; + return m_decoder.m_segmentation_pred_prob[m_ctx]; +} + +u8 TreeParser::calculate_is_inter_probability() +{ + if (AVAIL_U && AVAIL_L) { + m_ctx = (LEFT_INTRA && ABOVE_INTRA) ? 3 : LEFT_INTRA || ABOVE_INTRA; + } else if (AVAIL_U || AVAIL_L) { + m_ctx = 2 * (AVAIL_U ? ABOVE_INTRA : LEFT_INTRA); + } else { + m_ctx = 0; + } + return m_decoder.m_probability_tables->is_inter_prob()[m_ctx]; +} + +u8 TreeParser::calculate_comp_mode_probability() +{ + if (AVAIL_U && AVAIL_L) { + if (ABOVE_SINGLE && LEFT_SINGLE) { + auto is_above_fixed = ABOVE_FRAME_0 == m_decoder.m_comp_fixed_ref; + auto is_left_fixed = LEFT_FRAME_0 == m_decoder.m_comp_fixed_ref; + m_ctx = is_above_fixed ^ is_left_fixed; + } else if (ABOVE_SINGLE) { + auto is_above_fixed = ABOVE_FRAME_0 == m_decoder.m_comp_fixed_ref; + m_ctx = 2 + (is_above_fixed || ABOVE_INTRA); + } else if (LEFT_SINGLE) { + auto is_left_fixed = LEFT_FRAME_0 == m_decoder.m_comp_fixed_ref; + m_ctx = 2 + (is_left_fixed || LEFT_INTRA); + } else { + m_ctx = 4; + } + } else if (AVAIL_U) { + if (ABOVE_SINGLE) { + m_ctx = ABOVE_FRAME_0 == m_decoder.m_comp_fixed_ref; + } else { + m_ctx = 3; + } + } else if (AVAIL_L) { + if (LEFT_SINGLE) { + m_ctx = LEFT_FRAME_0 == m_decoder.m_comp_fixed_ref; + } else { + m_ctx = 3; + } + } else { + m_ctx = 1; + } + return m_decoder.m_probability_tables->comp_mode_prob()[m_ctx]; +} + +u8 TreeParser::calculate_comp_ref_probability() +{ + auto fix_ref_idx = m_decoder.m_ref_frame_sign_bias[m_decoder.m_comp_fixed_ref]; + auto var_ref_idx = !fix_ref_idx; + if (AVAIL_U && AVAIL_L) { + if (ABOVE_INTRA && LEFT_INTRA) { + m_ctx = 2; + } else if (LEFT_INTRA) { + if (ABOVE_SINGLE) { + m_ctx = 1 + 2 * (ABOVE_FRAME_0 != m_decoder.m_comp_var_ref[1]); + } else { + m_ctx = 1 + 2 * (m_decoder.m_above_ref_frame[var_ref_idx] != m_decoder.m_comp_var_ref[1]); + } + } else if (ABOVE_INTRA) { + if (LEFT_SINGLE) { + m_ctx = 1 + 2 * (LEFT_FRAME_0 != m_decoder.m_comp_var_ref[1]); + } else { + m_ctx = 1 + 2 * (m_decoder.m_left_ref_frame[var_ref_idx] != m_decoder.m_comp_var_ref[1]); + } + } else { + auto var_ref_above = m_decoder.m_above_ref_frame[ABOVE_SINGLE ? 0 : var_ref_idx]; + auto var_ref_left = m_decoder.m_left_ref_frame[LEFT_SINGLE ? 0 : var_ref_idx]; + if (var_ref_above == var_ref_left && m_decoder.m_comp_var_ref[1] == var_ref_above) { + m_ctx = 0; + } else if (LEFT_SINGLE && ABOVE_SINGLE) { + if ((var_ref_above == m_decoder.m_comp_fixed_ref && var_ref_left == m_decoder.m_comp_var_ref[0]) + || (var_ref_left == m_decoder.m_comp_fixed_ref && var_ref_above == m_decoder.m_comp_var_ref[0])) { + m_ctx = 4; + } else if (var_ref_above == var_ref_left) { + m_ctx = 3; + } else { + m_ctx = 1; + } + } else if (LEFT_SINGLE || ABOVE_SINGLE) { + auto vrfc = LEFT_SINGLE ? var_ref_above : var_ref_left; + auto rfs = ABOVE_SINGLE ? var_ref_above : var_ref_left; + if (vrfc == m_decoder.m_comp_var_ref[1] && rfs != m_decoder.m_comp_var_ref[1]) { + m_ctx = 1; + } else if (rfs == m_decoder.m_comp_var_ref[1] && vrfc != m_decoder.m_comp_var_ref[1]) { + m_ctx = 2; + } else { + m_ctx = 4; + } + } else if (var_ref_above == var_ref_left) { + m_ctx = 4; + } else { + m_ctx = 2; + } + } + } else if (AVAIL_U) { + if (ABOVE_INTRA) { + m_ctx = 2; + } else { + if (ABOVE_SINGLE) { + m_ctx = 3 * (ABOVE_FRAME_0 != m_decoder.m_comp_var_ref[1]); + } else { + m_ctx = 4 * (m_decoder.m_above_ref_frame[var_ref_idx] != m_decoder.m_comp_var_ref[1]); + } + } + } else if (AVAIL_L) { + if (LEFT_INTRA) { + m_ctx = 2; + } else { + if (LEFT_SINGLE) { + m_ctx = 3 * (LEFT_FRAME_0 != m_decoder.m_comp_var_ref[1]); + } else { + m_ctx = 4 * (m_decoder.m_left_ref_frame[var_ref_idx] != m_decoder.m_comp_var_ref[1]); + } + } + } else { + m_ctx = 2; + } + + return m_decoder.m_probability_tables->comp_ref_prob()[m_ctx]; +} + +u8 TreeParser::calculate_single_ref_p1_probability() +{ + if (AVAIL_U && AVAIL_L) { + if (ABOVE_INTRA && LEFT_INTRA) { + m_ctx = 2; + } else if (LEFT_INTRA) { + if (ABOVE_SINGLE) { + m_ctx = 4 * (ABOVE_FRAME_0 == LastFrame); + } else { + m_ctx = 1 + (ABOVE_FRAME_0 == LastFrame || ABOVE_FRAME_1 == LastFrame); + } + } else if (ABOVE_INTRA) { + if (LEFT_SINGLE) { + m_ctx = 4 * (LEFT_FRAME_0 == LastFrame); + } else { + m_ctx = 1 + (LEFT_FRAME_0 == LastFrame || LEFT_FRAME_1 == LastFrame); + } + } else { + if (LEFT_SINGLE && ABOVE_SINGLE) { + m_ctx = 2 * (ABOVE_FRAME_0 == LastFrame) + 2 * (LEFT_FRAME_0 == LastFrame); + } else if (!LEFT_SINGLE && !ABOVE_SINGLE) { + auto above_is_last = ABOVE_FRAME_0 == LastFrame || ABOVE_FRAME_1 == LastFrame; + auto left_is_last = LEFT_FRAME_0 == LastFrame || LEFT_FRAME_1 == LastFrame; + m_ctx = 1 + (above_is_last || left_is_last); + } else { + auto rfs = ABOVE_SINGLE ? ABOVE_FRAME_0 : LEFT_FRAME_0; + auto crf1 = ABOVE_SINGLE ? LEFT_FRAME_0 : ABOVE_FRAME_0; + auto crf2 = ABOVE_SINGLE ? LEFT_FRAME_1 : ABOVE_FRAME_1; + m_ctx = crf1 == LastFrame || crf2 == LastFrame; + if (rfs == LastFrame) + m_ctx += 3; + } + } + } else if (AVAIL_U) { + if (ABOVE_INTRA) { + m_ctx = 2; + } else { + if (ABOVE_SINGLE) { + m_ctx = 4 * (ABOVE_FRAME_0 == LastFrame); + } else { + m_ctx = 1 + (ABOVE_FRAME_0 == LastFrame || ABOVE_FRAME_1 == LastFrame); + } + } + } else if (AVAIL_L) { + if (LEFT_INTRA) { + m_ctx = 2; + } else { + if (LEFT_SINGLE) { + m_ctx = 4 * (LEFT_FRAME_0 == LastFrame); + } else { + m_ctx = 1 + (LEFT_FRAME_0 == LastFrame || LEFT_FRAME_1 == LastFrame); + } + } + } else { + m_ctx = 2; + } + return m_decoder.m_probability_tables->single_ref_prob()[m_ctx][0]; +} + +u8 TreeParser::calculate_single_ref_p2_probability() +{ + if (AVAIL_U && AVAIL_L) { + if (ABOVE_INTRA && LEFT_INTRA) { + m_ctx = 2; + } else if (LEFT_INTRA) { + if (ABOVE_SINGLE) { + if (ABOVE_FRAME_0 == LastFrame) { + m_ctx = 3; + } else { + m_ctx = 4 * (ABOVE_FRAME_0 == GoldenFrame); + } + } else { + m_ctx = 1 + 2 * (ABOVE_FRAME_0 == GoldenFrame || ABOVE_FRAME_1 == GoldenFrame); + } + } else if (ABOVE_INTRA) { + if (LEFT_SINGLE) { + if (LEFT_FRAME_0 == LastFrame) { + m_ctx = 3; + } else { + m_ctx = 4 * (LEFT_FRAME_0 == GoldenFrame); + } + } else { + m_ctx = 1 + 2 * (LEFT_FRAME_0 == GoldenFrame || LEFT_FRAME_1 == GoldenFrame); + } + } else { + if (LEFT_SINGLE && ABOVE_SINGLE) { + auto above_last = ABOVE_FRAME_0 == LastFrame; + auto left_last = LEFT_FRAME_0 == LastFrame; + if (above_last && left_last) { + m_ctx = 3; + } else if (above_last) { + m_ctx = 4 * (LEFT_FRAME_0 == GoldenFrame); + } else if (left_last) { + m_ctx = 4 * (ABOVE_FRAME_0 == GoldenFrame); + } else { + m_ctx = 2 * (ABOVE_FRAME_0 == GoldenFrame) + 2 * (LEFT_FRAME_0 == GoldenFrame); + } + } else if (!LEFT_SINGLE && !ABOVE_SINGLE) { + if (ABOVE_FRAME_0 == LEFT_FRAME_0 && ABOVE_FRAME_1 == LEFT_FRAME_1) { + m_ctx = 3 * (ABOVE_FRAME_0 == GoldenFrame || ABOVE_FRAME_1 == GoldenFrame); + } else { + m_ctx = 2; + } + } else { + auto rfs = ABOVE_SINGLE ? ABOVE_FRAME_0 : LEFT_FRAME_0; + auto crf1 = ABOVE_SINGLE ? LEFT_FRAME_0 : ABOVE_FRAME_0; + auto crf2 = ABOVE_SINGLE ? LEFT_FRAME_1 : ABOVE_FRAME_1; + m_ctx = crf1 == GoldenFrame || crf2 == GoldenFrame; + if (rfs == GoldenFrame) { + m_ctx += 3; + } else if (rfs != AltRefFrame) { + m_ctx = 1 + (2 * m_ctx); + } + } + } + } else if (AVAIL_U) { + if (ABOVE_INTRA || (ABOVE_FRAME_0 == LastFrame && ABOVE_SINGLE)) { + m_ctx = 2; + } else if (ABOVE_SINGLE) { + m_ctx = 4 * (ABOVE_FRAME_0 == GoldenFrame); + } else { + m_ctx = 3 * (ABOVE_FRAME_0 == GoldenFrame || ABOVE_FRAME_1 == GoldenFrame); + } + } else if (AVAIL_L) { + if (LEFT_INTRA || (LEFT_FRAME_0 == LastFrame && LEFT_SINGLE)) { + m_ctx = 2; + } else if (LEFT_SINGLE) { + m_ctx = 4 * (LEFT_FRAME_0 == GoldenFrame); + } else { + m_ctx = 3 * (LEFT_FRAME_0 == GoldenFrame || LEFT_FRAME_1 == GoldenFrame); + } + } else { + m_ctx = 2; + } + return m_decoder.m_probability_tables->single_ref_prob()[m_ctx][1]; +} + +u8 TreeParser::calculate_tx_size_probability(u8 node) +{ + auto above = m_decoder.m_max_tx_size; + auto left = m_decoder.m_max_tx_size; + // FIXME: Fix varying above/left when Skips is implemented + m_ctx = (above + left) > m_decoder.m_max_tx_size; + return m_decoder.m_probability_tables->tx_probs()[m_decoder.m_max_tx_size][m_ctx][node]; +} + +u8 TreeParser::calculate_inter_mode_probability(u8 node) +{ + //FIXME: Implement when ModeContext is implemented + // m_ctx = m_decoder.m_mode_context[m_decoder.m_ref_frame[0]] + return m_decoder.m_probability_tables->inter_mode_probs()[m_ctx][node]; +} + +u8 TreeParser::calculate_interp_filter_probability(u8 node) +{ + // FIXME: Implement ctx calculation when InterpFilters is implemented + return m_decoder.m_probability_tables->interp_filter_probs()[m_ctx][node]; +} + void TreeParser::count_syntax_element(SyntaxElementType type, int value) { switch (type) { @@ -274,7 +630,7 @@ void TreeParser::count_syntax_element(SyntaxElementType type, int value) // No counting required return; } - VERIFY_NOT_REACHED(); + TODO(); } TreeParser::TreeSelection::TreeSelection(int const* values) |