Improve ergonomics of dealing with pixel formats in v4l2 camera backend

Bug: webrtc:14830
Change-Id: Ib49bf65895fe008e75223abb03867d412c1b5a60
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291531
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39976}
This commit is contained in:
Andreas Pehrson 2023-01-27 16:09:27 +01:00 committed by WebRTC LUCI CQ
parent d3eddff30c
commit 32b64e895c
2 changed files with 17 additions and 18 deletions

View File

@ -228,10 +228,10 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) {
video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
video_fmt.fmt.pix.sizeimage = 0; video_fmt.fmt.pix.sizeimage = 0;
int totalFmts = 5;
unsigned int videoFormats[] = {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, 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}; V4L2_PIX_FMT_NV12};
constexpr int totalFmts = sizeof(videoFormats) / sizeof(unsigned int);
int sizes = 13; int sizes = 13;
unsigned int size[][2] = {{128, 96}, {160, 120}, {176, 144}, {320, 240}, unsigned int size[][2] = {{128, 96}, {160, 120}, {176, 144}, {320, 240},
@ -261,6 +261,8 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) {
cap.videoType = VideoType::kUYVY; cap.videoType = VideoType::kUYVY;
} else if (videoFormats[fmts] == V4L2_PIX_FMT_NV12) { } else if (videoFormats[fmts] == V4L2_PIX_FMT_NV12) {
cap.videoType = VideoType::kNV12; cap.videoType = VideoType::kNV12;
} else {
RTC_DCHECK_NOTREACHED();
} }
// get fps of current camera mode // get fps of current camera mode

View File

@ -115,23 +115,18 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
// Supported video formats in preferred order. // Supported video formats in preferred order.
// If the requested resolution is larger than VGA, we prefer MJPEG. Go for // If the requested resolution is larger than VGA, we prefer MJPEG. Go for
// I420 otherwise. // I420 otherwise.
const int nFormats = 6; unsigned int hdFmts[] = {
unsigned int fmts[nFormats]; V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV,
if (capability.width > 640 || capability.height > 480) { V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_JPEG,
fmts[0] = V4L2_PIX_FMT_MJPEG; };
fmts[1] = V4L2_PIX_FMT_YUV420; unsigned int sdFmts[] = {
fmts[2] = V4L2_PIX_FMT_YUYV; V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY,
fmts[3] = V4L2_PIX_FMT_UYVY; V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG,
fmts[4] = V4L2_PIX_FMT_NV12; };
fmts[5] = V4L2_PIX_FMT_JPEG; const bool isHd = capability.width > 640 || capability.height > 480;
} else { unsigned int* fmts = isHd ? hdFmts : sdFmts;
fmts[0] = V4L2_PIX_FMT_YUV420; static_assert(sizeof(hdFmts) == sizeof(sdFmts));
fmts[1] = V4L2_PIX_FMT_YUYV; constexpr int nFormats = sizeof(hdFmts) / sizeof(unsigned int);
fmts[2] = V4L2_PIX_FMT_UYVY;
fmts[3] = V4L2_PIX_FMT_NV12;
fmts[4] = V4L2_PIX_FMT_MJPEG;
fmts[5] = V4L2_PIX_FMT_JPEG;
}
// Enumerate image formats. // Enumerate image formats.
struct v4l2_fmtdesc fmt; struct v4l2_fmtdesc fmt;
@ -180,6 +175,8 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG || else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG ||
video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
_captureVideoType = VideoType::kMJPEG; _captureVideoType = VideoType::kMJPEG;
else
RTC_DCHECK_NOTREACHED();
// set format and frame size now // set format and frame size now
if (ioctl(_deviceFd, VIDIOC_S_FMT, &video_fmt) < 0) { if (ioctl(_deviceFd, VIDIOC_S_FMT, &video_fmt) < 0) {