From de86c8253db5efb59b937cc7bcf726b6cba61507 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Mon, 12 Jul 2021 21:16:21 +0900 Subject: [PATCH] virtio: video: decoder: fix NV12 plane format A NV12 frame is made of one Y plane at full resolution, and one plane include one U and one V component for each four pixels. Thus the size of the second plane should be half of that of the first one. This is important to get right as ffmpeg conversion functions wil rely on this information and will fail if the computed size is bigger than the target buffer. BUG=b:161774071 BUG=b:169295147 TEST=Android Youtube plays properly on Hatch. Change-Id: I4196983389def3a4914c076d68067874041fab55 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3023743 Tested-by: kokoro Commit-Queue: Alexandre Courbot Reviewed-by: Keiichi Watanabe --- devices/src/virtio/video/decoder/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/devices/src/virtio/video/decoder/mod.rs b/devices/src/virtio/video/decoder/mod.rs index cefb6835c1..f6b0db9a0e 100644 --- a/devices/src/virtio/video/decoder/mod.rs +++ b/devices/src/virtio/video/decoder/mod.rs @@ -339,11 +339,19 @@ impl Context { let rect_width: u32 = (visible_rect.right - visible_rect.left) as u32; let rect_height: u32 = (visible_rect.bottom - visible_rect.top) as u32; - let plane_size = rect_width * rect_height; - let stride = rect_width; let plane_formats = vec![ - PlaneFormat { plane_size, stride }, - PlaneFormat { plane_size, stride }, + // Y plane, 1 sample per pixel. + PlaneFormat { + plane_size: rect_width * rect_height, + stride: rect_width, + }, + // UV plane, 1 sample per group of 4 pixels for U and V. + PlaneFormat { + // Add one vertical line so odd resolutions result in an extra UV line to cover all the + // Y samples. + plane_size: rect_width * ((rect_height + 1) / 2), + stride: rect_width, + }, ]; self.out_params = Params {