summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibVideo
diff options
context:
space:
mode:
authorZaggy1024 <zaggy1024@gmail.com>2023-04-13 14:03:02 -0500
committerTim Flynn <trflynn89@pm.me>2023-04-14 07:11:45 -0400
commit08b90bb2d02c8e960ce271673346dede287370f8 (patch)
tree6ccada4f4d7724d10c39fa3589a50636701da25a /Userland/Libraries/LibVideo
parentbc49af08b4b4ff1dffbb882d9ba0e79c53d9fdba (diff)
downloadserenity-08b90bb2d02c8e960ce271673346dede287370f8.zip
LibVideo/VP9: Clamp reference frame prediction coords outside loops
Moving the clamping of the coordinates of the reference frame samples as well as some bounds checks outside of the loop reduces the branches needed in the `predict_inter_block()` significantly. This results in a whopping ~41% improvement in decode performance of an inter-prediction-heavy YouTube video (~35.4s -> ~20.8s).
Diffstat (limited to 'Userland/Libraries/LibVideo')
-rw-r--r--Userland/Libraries/LibVideo/VP9/Decoder.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/Userland/Libraries/LibVideo/VP9/Decoder.cpp b/Userland/Libraries/LibVideo/VP9/Decoder.cpp
index 70f098742d..7c740b1425 100644
--- a/Userland/Libraries/LibVideo/VP9/Decoder.cpp
+++ b/Userland/Libraries/LibVideo/VP9/Decoder.cpp
@@ -939,15 +939,19 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
return intermediate_buffer[row * width + column];
};
+ // Check our reference frame bounds before starting the loop.
+ reference_frame_buffer_at(scaled_bottom, scaled_right);
+
for (auto row = 0u; row < intermediate_height; row++) {
+ auto clamped_row = static_cast<size_t>(clip_3(0, scaled_bottom, (offset_scaled_block_y >> 4) + static_cast<i32>(row) - 3));
+ u16 const* scan_line = &reference_frame_buffer_at(clamped_row, 0);
+
for (auto column = 0u; column < width; column++) {
auto samples_start = offset_scaled_block_x + static_cast<i32>(scaled_step_x * column);
i32 accumulated_samples = 0;
for (auto t = 0u; t < 8u; t++) {
- auto sample = reference_frame_buffer_at(
- clip_3(0, scaled_bottom, (offset_scaled_block_y >> 4) + static_cast<i32>(row) - 3),
- clip_3(0, scaled_right, (samples_start >> 4) + static_cast<i32>(t) - 3));
+ auto sample = scan_line[clip_3(0, scaled_right, (samples_start >> 4) + static_cast<i32>(t) - 3)];
accumulated_samples += subpel_filters[block_context.interpolation_filter][samples_start & 15][t] * sample;
}
intermediate_buffer_at(row, column) = clip_1(block_context.frame_context.color_config.bit_depth, rounded_right_shift(accumulated_samples, 7));
@@ -957,11 +961,14 @@ DecoderErrorOr<void> Decoder::predict_inter_block(u8 plane, BlockContext const&
for (auto row = 0u; row < height; row++) {
for (auto column = 0u; column < width; column++) {
auto samples_start = (offset_scaled_block_y & 15) + static_cast<i32>(scaled_step_y * row);
+ auto const* scan_column = &intermediate_buffer_at(samples_start >> 4, column);
+ auto const* subpel_filters_for_samples = subpel_filters[block_context.interpolation_filter][samples_start & 15];
i32 accumulated_samples = 0;
for (auto t = 0u; t < 8u; t++) {
- auto sample = intermediate_buffer_at((samples_start >> 4) + t, column);
- accumulated_samples += subpel_filters[block_context.interpolation_filter][samples_start & 15][t] * sample;
+ auto sample = *scan_column;
+ accumulated_samples += subpel_filters_for_samples[t] * sample;
+ scan_column += width;
}
block_buffer_at(row, column) = clip_1(block_context.frame_context.color_config.bit_depth, rounded_right_shift(accumulated_samples, 7));
}