From 106ae7ada173101df987d3d321adbfd4dbffa104 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Thu, 29 Sep 2022 06:37:50 +0900 Subject: [PATCH] virtio: video: Tolerate and fixup zero plane encoder SetParam requests. Per virtio-video spec, if the device encounters a field with value it does not support, it should update the field with a valid value and then return that. It's actually debatable whether an empty plane array is allowed in the first place, but this seems to be what happens in the case we use a non- default format (everything but NV12) from FFmpeg v4l2m2m. Moreover, the guest kernel currently ignores SetParams errors, so it seems justifiable that we should avoid rejecting this input and instead gracefully handle it. With this change + later commit introducing the FFmpeg encoder, FFmpeg in the guest works with `-pix_fmt yuv420p -c:v vp8/h265_v4l2m2m`. Note that for VP8 a WebM container should be used. VP9 was not supported as an encoder accelerator somehow so this was not tested. BUG=b:239897269 TEST=cargo test --features "video-encoder,video-decoder,ffmpeg" -p devices video TEST=Linux guest test described above Change-Id: I843af7cef35cc231b8668efcf716a48a37959c86 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3924264 Commit-Queue: Tatsuyuki Ishi Reviewed-by: Alexandre Courbot --- devices/src/virtio/video/encoder/mod.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/devices/src/virtio/video/encoder/mod.rs b/devices/src/virtio/video/encoder/mod.rs index 8470a7fd6a..767e2ab4a2 100644 --- a/devices/src/virtio/video/encoder/mod.rs +++ b/devices/src/virtio/video/encoder/mod.rs @@ -1074,11 +1074,6 @@ impl EncoderDevice { return Err(VideoError::InvalidOperation); } - // There should be at least a single plane. - if plane_formats.is_empty() { - return Err(VideoError::InvalidArgument); - } - let desired_format = format.or(stream.src_params.format).unwrap_or(Format::NV12); self.cros_capabilities.populate_src_params( @@ -1086,7 +1081,7 @@ impl EncoderDevice { desired_format, frame_width, frame_height, - plane_formats[0].stride, + plane_formats.get(0).map(|fmt| fmt.stride).unwrap_or(0), )?; stream.dst_params.frame_width = frame_width;