Commit 0eb139aa authored by Dale Curtis's avatar Dale Curtis Committed by Commit Bot

Fix issues with odd sized VideoFrames and PaintCanvasVideoRenderer.

For 1x1 YUV images the sample size will be larger than the height, so
upon dividing the integer height by the sample size we get a result
of zero chunks for processing. Additionally, since the code wasn't
accounting for the last row of odd height frames, it would do nothing
on a 1x1 frame.

The fix is to ensure we always process an extra row in the last task
when we've got an odd height frame.

R=thomasanderson

Fixed: 1034955
Change-Id: Ic6733ffb31bd2040769d7bc63e9096aea756cbbb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2016359
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Reviewed-by: default avatarThomas Anderson <thomasanderson@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735077}
parent 9a26ee29
......@@ -470,10 +470,13 @@ void ConvertVideoFrameToRGBPixelsTask(const VideoFrame* video_frame,
}
base::CheckedNumeric<size_t> chunks = height / rows_per_chunk;
DCHECK_LE(height % rows_per_chunk, 1UL);
const size_t chunk_start = (chunks * task_index / n_tasks).ValueOrDie();
const size_t chunk_end = (chunks * (task_index + 1) / n_tasks).ValueOrDie();
const size_t rows = (chunk_end - chunk_start) * rows_per_chunk;
// Indivisible heights must process any remaining rows in the last task.
size_t rows = (chunk_end - chunk_start) * rows_per_chunk;
if (task_index + 1 == n_tasks)
rows += height % rows_per_chunk;
struct {
int stride;
......@@ -572,8 +575,7 @@ void ConvertVideoFrameToRGBPixelsTask(const VideoFrame* video_frame,
plane_meta[VideoFrame::kVPlane].stride,
plane_meta[VideoFrame::kAPlane].data,
plane_meta[VideoFrame::kAPlane].stride, pixels, row_bytes, width,
rows,
1); // 1 = enable RGB premultiplication by Alpha.
rows, 1); // 1 = enable RGB premultiplication by Alpha.
break;
case PIXEL_FORMAT_I444:
......@@ -1187,10 +1189,12 @@ void PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
}
constexpr size_t kTaskBytes = 1024 * 1024; // 1 MiB
const size_t frame_bytes = row_bytes * video_frame->visible_rect().height();
const size_t n_tasks =
std::min<size_t>(std::max<size_t>(1, frame_bytes / kTaskBytes),
base::SysInfo::NumberOfProcessors());
const size_t n_tasks = std::min<size_t>(
std::max<size_t>(
1, VideoFrame::AllocationSize(video_frame->format(),
video_frame->visible_rect().size()) /
kTaskBytes),
base::SysInfo::NumberOfProcessors());
base::WaitableEvent event;
base::RepeatingClosure barrier = base::BarrierClosure(
n_tasks,
......
......@@ -571,6 +571,16 @@ TEST_F(PaintCanvasVideoRendererTest, TransparentFrameSrcMode) {
bitmap()->getColor(0, 0));
}
TEST_F(PaintCanvasVideoRendererTest, TransparentFrameSrcMode1x1) {
target_canvas()->clear(SK_ColorRED);
// SRC mode completely overwrites the buffer.
auto frame = VideoFrame::CreateTransparentFrame(gfx::Size(1, 1));
PaintRotated(frame.get(), target_canvas(), gfx::RectF(1, 1), kNone,
SkBlendMode::kSrc, kNoTransformation);
EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
bitmap()->getColor(0, 0));
}
TEST_F(PaintCanvasVideoRendererTest, CopyTransparentFrame) {
target_canvas()->clear(SK_ColorRED);
Copy(VideoFrame::CreateTransparentFrame(gfx::Size(kWidth, kHeight)).get(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment