From fd9a1e1d9833531ce61874db7d999f0f5776c4a4 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Wed, 9 Nov 2022 12:04:28 +0100 Subject: [PATCH] modules/video_capture: add NV12 support on Linux Add native NV12 support on Linux v4l2 video_capture module. Bug: webrtc:14650 Change-Id: I97e2010be4f15168b218da4855be8b0e985008a5 Signed-off-by: Dimitri John Ledkov Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/282841 Reviewed-by: Harald Alvestrand Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#38753} --- AUTHORS | 1 + modules/video_capture/device_info_impl.cc | 3 ++- modules/video_capture/linux/device_info_v4l2.cc | 7 +++++-- modules/video_capture/linux/video_capture_v4l2.cc | 12 ++++++++---- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/AUTHORS b/AUTHORS index c991ce8fe5..7c7cb34709 100644 --- a/AUTHORS +++ b/AUTHORS @@ -138,6 +138,7 @@ Pengfei Han Agora IO <*@agora.io> ARM Holdings <*@arm.com> BroadSoft Inc. <*@broadsoft.com> +Canonical Ltd <*@canonical.com> CoSMo Software Consulting, Pte Ltd <*@cosmosoftware.io> Facebook Inc. <*@fb.com> Google Inc. <*@google.com> diff --git a/modules/video_capture/device_info_impl.cc b/modules/video_capture/device_info_impl.cc index ac78cbc84a..ff32a78580 100644 --- a/modules/video_capture/device_info_impl.cc +++ b/modules/video_capture/device_info_impl.cc @@ -148,7 +148,8 @@ int32_t DeviceInfoImpl::GetBestMatchedCapability( (capability.videoType == requested.videoType || capability.videoType == VideoType::kI420 || capability.videoType == VideoType::kYUY2 || - capability.videoType == VideoType::kYV12)) { + capability.videoType == VideoType::kYV12 || + capability.videoType == VideoType::kNV12)) { bestVideoType = capability.videoType; bestformatIndex = tmp; } diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc index c1062d4078..5af58015a7 100644 --- a/modules/video_capture/linux/device_info_v4l2.cc +++ b/modules/video_capture/linux/device_info_v4l2.cc @@ -228,9 +228,10 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; video_fmt.fmt.pix.sizeimage = 0; - int totalFmts = 4; + int totalFmts = 5; unsigned int videoFormats[] = {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY}; + V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, + V4L2_PIX_FMT_NV12}; int sizes = 13; unsigned int size[][2] = {{128, 96}, {160, 120}, {176, 144}, {320, 240}, @@ -258,6 +259,8 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { cap.videoType = VideoType::kMJPEG; } else if (videoFormats[fmts] == V4L2_PIX_FMT_UYVY) { cap.videoType = VideoType::kUYVY; + } else if (videoFormats[fmts] == V4L2_PIX_FMT_NV12) { + cap.videoType = VideoType::kNV12; } // get fps of current camera mode diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc index 2655fbefaa..5101a67e0c 100644 --- a/modules/video_capture/linux/video_capture_v4l2.cc +++ b/modules/video_capture/linux/video_capture_v4l2.cc @@ -115,20 +115,22 @@ int32_t VideoCaptureModuleV4L2::StartCapture( // Supported video formats in preferred order. // If the requested resolution is larger than VGA, we prefer MJPEG. Go for // I420 otherwise. - const int nFormats = 5; + const int nFormats = 6; unsigned int fmts[nFormats]; if (capability.width > 640 || capability.height > 480) { fmts[0] = V4L2_PIX_FMT_MJPEG; fmts[1] = V4L2_PIX_FMT_YUV420; fmts[2] = V4L2_PIX_FMT_YUYV; fmts[3] = V4L2_PIX_FMT_UYVY; - fmts[4] = V4L2_PIX_FMT_JPEG; + fmts[4] = V4L2_PIX_FMT_NV12; + fmts[5] = V4L2_PIX_FMT_JPEG; } else { fmts[0] = V4L2_PIX_FMT_YUV420; fmts[1] = V4L2_PIX_FMT_YUYV; fmts[2] = V4L2_PIX_FMT_UYVY; - fmts[3] = V4L2_PIX_FMT_MJPEG; - fmts[4] = V4L2_PIX_FMT_JPEG; + fmts[3] = V4L2_PIX_FMT_NV12; + fmts[4] = V4L2_PIX_FMT_MJPEG; + fmts[5] = V4L2_PIX_FMT_JPEG; } // Enumerate image formats. @@ -173,6 +175,8 @@ int32_t VideoCaptureModuleV4L2::StartCapture( _captureVideoType = VideoType::kI420; else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) _captureVideoType = VideoType::kUYVY; + else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) + _captureVideoType = VideoType::kNV12; else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG || video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) _captureVideoType = VideoType::kMJPEG;