From patchwork Fri Jul 15 13:50:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16639 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 2DA00BE173 for ; Fri, 15 Jul 2022 13:50:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DDA456330A; Fri, 15 Jul 2022 15:50:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1657893023; bh=yhqz4FlRpnpMxJBSwMS9fSRXeXaEjGZxygwCKjoIrfg=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=p1wmhf/RUJHPUtsb3D76pFC38MrI8Ey6ugH06+g/yIik/DMdtC42Kry5jSmqjyyee Q9sEn+5AjCSHxUs8evwTMYOEDlmnU7/3tSvhgTPPVR3cuU6zPPIBsfyotEi+OHLiuh IptG1gFA87XR2wnqk34Qd/oGn4niYlDIFQfPH49mP9jP9LD44rjsDZ9MBUgThk68b1 lvcvCeJ9o7SAuqcfUGspP74I9rwnMtKXxJPz6KuNs8SaSkkb6LWkq4wXWBUI70NEUt AApAhJO3jbTdaWIn5XWtjHPB5YZTIx82mU2wM8LuGKueYmywNbj9JSLo/oySiB9Fc4 Q0EaQFb3GTXCQ== Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 792BA63313 for ; Fri, 15 Jul 2022 15:50:20 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 28BA160004; Fri, 15 Jul 2022 13:50:18 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Jul 2022 15:50:01 +0200 Message-Id: <20220715135007.53574-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220715135007.53574-1-jacopo@jmondi.org> References: <20220715135007.53574-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/7] libcamera: formats: Support multiple V4L2 pixel formats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: jozef@mlich.cz, Pavel Machek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Associate a list of V4L2PixelFormat entries to a libcamera Format in the PixelFormatInfo. This change prepares for supporting through a single libcamera Format devices which use different but equivalent versions of the same format, like V4L2_PIX_FMT_MJPEG and V4L2_PIX_FMT_JPEG. Change the existing users to always use the first entry to not break the build. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/formats.h | 4 +- src/libcamera/formats.cpp | 248 +++++++++++++-------------- src/libcamera/v4l2_pixelformat.cpp | 2 +- 3 files changed, 127 insertions(+), 127 deletions(-) diff --git a/include/libcamera/internal/formats.h b/include/libcamera/internal/formats.h index ee599765be47..90c8b2cda78a 100644 --- a/include/libcamera/internal/formats.h +++ b/include/libcamera/internal/formats.h @@ -54,8 +54,8 @@ public: const char *name; PixelFormat format; struct { - V4L2PixelFormat single; - V4L2PixelFormat multi; + std::vector single; + std::vector multi; } v4l2Formats; unsigned int bitsPerPixel; enum ColourEncoding colourEncoding; diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index 283ecb3d89d8..f7e9adc7ff77 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -157,8 +157,8 @@ const std::map pixelFormatInfo{ .name = "RGB565", .format = formats::RGB565, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_RGB565), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_RGB565) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -170,8 +170,8 @@ const std::map pixelFormatInfo{ .name = "RGB565_BE", .format = formats::RGB565_BE, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_RGB565X), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_RGB565X) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -183,8 +183,8 @@ const std::map pixelFormatInfo{ .name = "BGR888", .format = formats::BGR888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_RGB24), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_RGB24) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -196,8 +196,8 @@ const std::map pixelFormatInfo{ .name = "RGB888", .format = formats::RGB888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_BGR24), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_BGR24) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -209,8 +209,8 @@ const std::map pixelFormatInfo{ .name = "XRGB8888", .format = formats::XRGB8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_XBGR32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_XBGR32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -222,8 +222,8 @@ const std::map pixelFormatInfo{ .name = "XBGR8888", .format = formats::XBGR8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_RGBX32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_RGBX32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -235,8 +235,8 @@ const std::map pixelFormatInfo{ .name = "RGBX8888", .format = formats::RGBX8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_BGRX32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_BGRX32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -248,8 +248,8 @@ const std::map pixelFormatInfo{ .name = "BGRX8888", .format = formats::BGRX8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_XRGB32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_XRGB32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -261,8 +261,8 @@ const std::map pixelFormatInfo{ .name = "ABGR8888", .format = formats::ABGR8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_RGBA32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_RGBA32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -274,8 +274,8 @@ const std::map pixelFormatInfo{ .name = "ARGB8888", .format = formats::ARGB8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_ABGR32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_ABGR32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -287,8 +287,8 @@ const std::map pixelFormatInfo{ .name = "BGRA8888", .format = formats::BGRA8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_ARGB32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_ARGB32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -300,8 +300,8 @@ const std::map pixelFormatInfo{ .name = "RGBA8888", .format = formats::RGBA8888, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_BGRA32), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_BGRA32) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 32, .colourEncoding = PixelFormatInfo::ColourEncodingRGB, @@ -315,8 +315,8 @@ const std::map pixelFormatInfo{ .name = "YUYV", .format = formats::YUYV, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_YUYV), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_YUYV) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -328,8 +328,8 @@ const std::map pixelFormatInfo{ .name = "YVYU", .format = formats::YVYU, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_YVYU), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_YVYU) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -341,8 +341,8 @@ const std::map pixelFormatInfo{ .name = "UYVY", .format = formats::UYVY, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_UYVY), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_UYVY) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -354,8 +354,8 @@ const std::map pixelFormatInfo{ .name = "VYUY", .format = formats::VYUY, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_VYUY), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_VYUY) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -369,8 +369,8 @@ const std::map pixelFormatInfo{ .name = "NV12", .format = formats::NV12, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_NV12), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_NV12M), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_NV12) }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_NV12M) }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -382,8 +382,8 @@ const std::map pixelFormatInfo{ .name = "NV21", .format = formats::NV21, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_NV21), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_NV21M), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_NV21) }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_NV21M) }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -395,8 +395,8 @@ const std::map pixelFormatInfo{ .name = "NV16", .format = formats::NV16, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_NV16), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_NV16M), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_NV16) }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_NV16M) }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -408,8 +408,8 @@ const std::map pixelFormatInfo{ .name = "NV61", .format = formats::NV61, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_NV61), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_NV61M), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_NV61) }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_NV61M) }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -421,8 +421,8 @@ const std::map pixelFormatInfo{ .name = "NV24", .format = formats::NV24, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_NV24), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_NV24) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -434,8 +434,8 @@ const std::map pixelFormatInfo{ .name = "NV42", .format = formats::NV42, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_NV42), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_NV42) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -447,8 +447,8 @@ const std::map pixelFormatInfo{ .name = "YUV420", .format = formats::YUV420, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_YUV420), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_YUV420M), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_YUV420) }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_YUV420M) }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -460,8 +460,8 @@ const std::map pixelFormatInfo{ .name = "YVU420", .format = formats::YVU420, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_YVU420), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_YVU420M), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_YVU420) }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_YVU420M) }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -473,8 +473,8 @@ const std::map pixelFormatInfo{ .name = "YUV422", .format = formats::YUV422, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_YUV422P), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_YUV422M), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_YUV422P) }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_YUV422M) }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -486,8 +486,8 @@ const std::map pixelFormatInfo{ .name = "YVU422", .format = formats::YVU422, .v4l2Formats = { - .single = V4L2PixelFormat(), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_YVU422M), + .single = { V4L2PixelFormat() }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_YVU422M) }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -499,8 +499,8 @@ const std::map pixelFormatInfo{ .name = "YUV444", .format = formats::YUV444, .v4l2Formats = { - .single = V4L2PixelFormat(), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_YUV444M), + .single = { V4L2PixelFormat() }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_YUV444M) }, }, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -512,8 +512,8 @@ const std::map pixelFormatInfo{ .name = "YVU444", .format = formats::YVU444, .v4l2Formats = { - .single = V4L2PixelFormat(), - .multi = V4L2PixelFormat(V4L2_PIX_FMT_YVU444M), + .single = { V4L2PixelFormat() }, + .multi = { V4L2PixelFormat(V4L2_PIX_FMT_YVU444M) }, }, .bitsPerPixel = 24, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -527,8 +527,8 @@ const std::map pixelFormatInfo{ .name = "R8", .format = formats::R8, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_GREY), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_GREY) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -540,8 +540,8 @@ const std::map pixelFormatInfo{ .name = "R10", .format = formats::R10, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_Y10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_Y10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -553,8 +553,8 @@ const std::map pixelFormatInfo{ .name = "R12", .format = formats::R12, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_Y12), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_Y12) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -566,8 +566,8 @@ const std::map pixelFormatInfo{ .name = "R10_CSI2P", .format = formats::R10, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_Y10P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_Y10P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -581,8 +581,8 @@ const std::map pixelFormatInfo{ .name = "SBGGR8", .format = formats::SBGGR8, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -594,8 +594,8 @@ const std::map pixelFormatInfo{ .name = "SGBRG8", .format = formats::SGBRG8, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -607,8 +607,8 @@ const std::map pixelFormatInfo{ .name = "SGRBG8", .format = formats::SGRBG8, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -620,8 +620,8 @@ const std::map pixelFormatInfo{ .name = "SRGGB8", .format = formats::SRGGB8, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 8, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -633,8 +633,8 @@ const std::map pixelFormatInfo{ .name = "SBGGR10", .format = formats::SBGGR10, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -646,8 +646,8 @@ const std::map pixelFormatInfo{ .name = "SGBRG10", .format = formats::SGBRG10, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -659,8 +659,8 @@ const std::map pixelFormatInfo{ .name = "SGRBG10", .format = formats::SGRBG10, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -672,8 +672,8 @@ const std::map pixelFormatInfo{ .name = "SRGGB10", .format = formats::SRGGB10, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -685,8 +685,8 @@ const std::map pixelFormatInfo{ .name = "SBGGR10_CSI2P", .format = formats::SBGGR10_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -698,8 +698,8 @@ const std::map pixelFormatInfo{ .name = "SGBRG10_CSI2P", .format = formats::SGBRG10_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -711,8 +711,8 @@ const std::map pixelFormatInfo{ .name = "SGRBG10_CSI2P", .format = formats::SGRBG10_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -724,8 +724,8 @@ const std::map pixelFormatInfo{ .name = "SRGGB10_CSI2P", .format = formats::SRGGB10_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -737,8 +737,8 @@ const std::map pixelFormatInfo{ .name = "SBGGR12", .format = formats::SBGGR12, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -750,8 +750,8 @@ const std::map pixelFormatInfo{ .name = "SGBRG12", .format = formats::SGBRG12, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -763,8 +763,8 @@ const std::map pixelFormatInfo{ .name = "SGRBG12", .format = formats::SGRBG12, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -776,8 +776,8 @@ const std::map pixelFormatInfo{ .name = "SRGGB12", .format = formats::SRGGB12, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -789,8 +789,8 @@ const std::map pixelFormatInfo{ .name = "SBGGR12_CSI2P", .format = formats::SBGGR12_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -802,8 +802,8 @@ const std::map pixelFormatInfo{ .name = "SGBRG12_CSI2P", .format = formats::SGBRG12_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -815,8 +815,8 @@ const std::map pixelFormatInfo{ .name = "SGRBG12_CSI2P", .format = formats::SGRBG12_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -828,8 +828,8 @@ const std::map pixelFormatInfo{ .name = "SRGGB12_CSI2P", .format = formats::SRGGB12_CSI2P, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 12, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -841,8 +841,8 @@ const std::map pixelFormatInfo{ .name = "SBGGR16", .format = formats::SBGGR16, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -854,8 +854,8 @@ const std::map pixelFormatInfo{ .name = "SGBRG16", .format = formats::SGBRG16, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -867,8 +867,8 @@ const std::map pixelFormatInfo{ .name = "SGRBG16", .format = formats::SGRBG16, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -880,8 +880,8 @@ const std::map pixelFormatInfo{ .name = "SRGGB16", .format = formats::SRGGB16, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 16, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -893,8 +893,8 @@ const std::map pixelFormatInfo{ .name = "SBGGR10_IPU3", .format = formats::SBGGR10_IPU3, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -907,8 +907,8 @@ const std::map pixelFormatInfo{ .name = "SGBRG10_IPU3", .format = formats::SGBRG10_IPU3, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -920,8 +920,8 @@ const std::map pixelFormatInfo{ .name = "SGRBG10_IPU3", .format = formats::SGRBG10_IPU3, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -933,8 +933,8 @@ const std::map pixelFormatInfo{ .name = "SRGGB10_IPU3", .format = formats::SRGGB10_IPU3, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 10, .colourEncoding = PixelFormatInfo::ColourEncodingRAW, @@ -948,8 +948,8 @@ const std::map pixelFormatInfo{ .name = "MJPEG", .format = formats::MJPEG, .v4l2Formats = { - .single = V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), - .multi = V4L2PixelFormat(), + .single = { V4L2PixelFormat(V4L2_PIX_FMT_MJPEG) }, + .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 0, .colourEncoding = PixelFormatInfo::ColourEncodingYUV, @@ -996,8 +996,8 @@ const PixelFormatInfo &PixelFormatInfo::info(const V4L2PixelFormat &format) { const auto &info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(), [format](auto pair) { - return pair.second.v4l2Formats.single == format || - pair.second.v4l2Formats.multi == format; + return pair.second.v4l2Formats.single[0] == format || + pair.second.v4l2Formats.multi[0] == format; }); if (info == pixelFormatInfo.end()) return pixelFormatInfoInvalid; diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index 58fc4e9d2032..cf6c1858bd1a 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -321,7 +321,7 @@ V4L2PixelFormat V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat, if (!info.isValid()) return V4L2PixelFormat(); - return multiplanar ? info.v4l2Formats.multi : info.v4l2Formats.single; + return multiplanar ? info.v4l2Formats.multi[0] : info.v4l2Formats.single[0]; } /** From patchwork Fri Jul 15 13:50:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16640 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E4905BE173 for ; Fri, 15 Jul 2022 13:50:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 77A1763313; Fri, 15 Jul 2022 15:50:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1657893024; bh=c/6gB4SSC3yvs7YlwjXpTq0TLFezDfDgjJD+2CEst8M=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=q0C/tocOxbx/MOpkFI20lH5yYcoRA1e07+wlCUmF1hDTIAhaaL1X9LbSNREswxq12 t0LrOuU+Na5vBVIW2YzYhFYg4JtcnCeQe3hXxzRprg035BjVLTKZCZTod51EpD1P5x yuO3w8sY8IStbz1YnmEkimaFznqjjwted8wFqOKoB4mFfJljWzPtcufOBd6sM2w4iC 5QsDF9+TkMEB4yfmQSRyaKzdpkWMJvaziE0HotKhECY4S+0tFEu05p2dtczZRlxcbT Lknx/cCKwqInPaflXPukExUs53/bSnX1vShPlmiHCFkAdSuwoQYpCdpGraCDXYskIz JkLRAkZRMPEYA== Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::223]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C86D46330A for ; Fri, 15 Jul 2022 15:50:21 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 9CEA86000A; Fri, 15 Jul 2022 13:50:20 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Jul 2022 15:50:02 +0200 Message-Id: <20220715135007.53574-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220715135007.53574-1-jacopo@jmondi.org> References: <20220715135007.53574-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/7] libcamera: formats: Search PixelFormatInfo on multiple formats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: jozef@mlich.cz, Pavel Machek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The PixelFormatInfo::info(const V4L2PixelFormat &format) function returns the PixelFormatInfo associated with a V4L2 pixel format. As we prepare to associate multiple V4L2 formats to a single PixelFormatInfo rework the function to search the given V4L2 format in a list. Signed-off-by: Jacopo Mondi --- src/libcamera/formats.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index f7e9adc7ff77..86fc698a0f4e 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -994,10 +994,19 @@ const PixelFormatInfo &PixelFormatInfo::info(const PixelFormat &format) */ const PixelFormatInfo &PixelFormatInfo::info(const V4L2PixelFormat &format) { + auto matchFormats = [&format](const std::vector &formats) { + const auto &it = std::find_if(formats.begin(), formats.end(), + [&format](const V4L2PixelFormat &fmt) { + return format == fmt; + }); + + return it == formats.end() ? false : true; + }; + const auto &info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(), - [format](auto pair) { - return pair.second.v4l2Formats.single[0] == format || - pair.second.v4l2Formats.multi[0] == format; + [&matchFormats](auto &pair) { + return matchFormats(pair.second.v4l2Formats.single) || + matchFormats(pair.second.v4l2Formats.multi); }); if (info == pixelFormatInfo.end()) return pixelFormatInfoInvalid; From patchwork Fri Jul 15 13:50:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16641 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 6D077BE173 for ; Fri, 15 Jul 2022 13:50:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 034F66331C; Fri, 15 Jul 2022 15:50:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1657893026; bh=kB5V6ZYhOif8/B69RxWU2gF8W9eQavO9ZjYs+bHCKQY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=zFkfdEv+GtE57L9eB62ytAgE6MYxgxFyWtUKm7Suzy/C8RHa6pDWqgQ2vJHbNJvSp YmgollMxJRyRnUrYKbNvvigNJXzFeqRIYhSu8JICcMUSrWTfEllc8+WIkUi/PEoGL2 XN1LVBwtYq6cdG8HkHV8UmUEBQBH2uftj6Vg10Y8KDuxK0CqpRXu5WK6LAA3x027UY cjz5ObALUxUfhcRbFBD2UWJO8c0I0f1Zo5iajARl1d4TQkrlhYaaZ564ApeqAIUSx9 KpidDvV8b7Roj2R0UXHP6VRF2cGp7mUpvkOIPKUkea3VmmSBNpRqcT/g0zvoVdyxU3 Bp5hDu4qPxtzQ== Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 38DC06330F for ; Fri, 15 Jul 2022 15:50:23 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 0B47C6000F; Fri, 15 Jul 2022 13:50:21 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Jul 2022 15:50:03 +0200 Message-Id: <20220715135007.53574-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220715135007.53574-1-jacopo@jmondi.org> References: <20220715135007.53574-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/7] libcamera: v4l2_pixelformat: Return a format list in fromPixelFormat() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: jozef@mlich.cz, Pavel Machek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" As we prepare to associate multiple V4L2 FourCC to a single libcamera format, make the V4L2PixelFormat::fromPixelFormat() return a list of formats and convert all its users to pick the first one. This change prepares to re-introduce V4L2VideoDevice::toV4L2PixelFormat() which will instead match the list of V4L2 FourCC against the formats supported by the video device. While at it, reword the V4L2PixelFormat::fromPixelFormat() documentation to distinguish between planar/multiplanar and contiguous/non-contiguous. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/v4l2_pixelformat.h | 6 ++++-- src/libcamera/pipeline/ipu3/cio2.cpp | 2 +- src/libcamera/pipeline/ipu3/imgu.cpp | 2 +- .../pipeline/raspberrypi/raspberrypi.cpp | 12 +++++------ src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 6 +++--- src/libcamera/pipeline/simple/converter.cpp | 8 ++++---- src/libcamera/pipeline/simple/simple.cpp | 4 ++-- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 6 +++--- src/libcamera/pipeline/vimc/vimc.cpp | 8 ++++---- src/libcamera/v4l2_pixelformat.cpp | 20 +++++++++---------- src/v4l2/v4l2_camera_proxy.cpp | 6 +++--- test/libtest/buffer_source.cpp | 2 +- 12 files changed, 42 insertions(+), 40 deletions(-) diff --git a/include/libcamera/internal/v4l2_pixelformat.h b/include/libcamera/internal/v4l2_pixelformat.h index fb2d5d0b93df..750f31fc1926 100644 --- a/include/libcamera/internal/v4l2_pixelformat.h +++ b/include/libcamera/internal/v4l2_pixelformat.h @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -44,8 +45,9 @@ public: const char *description() const; PixelFormat toPixelFormat() const; - static V4L2PixelFormat fromPixelFormat(const PixelFormat &pixelFormat, - bool multiplanar = false); + static std::vector + fromPixelFormat(const PixelFormat &pixelFormat, + bool multiplanar = false); private: uint32_t fourcc_; diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 08e254f75eee..4a13d16973e9 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -203,7 +203,7 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat) if (itInfo == mbusCodesToPixelFormat.end()) return -EINVAL; - outputFormat->fourcc = V4L2PixelFormat::fromPixelFormat(itInfo->second); + outputFormat->fourcc = V4L2PixelFormat::fromPixelFormat(itInfo->second)[0]; outputFormat->size = sensorFormat.size; outputFormat->planesCount = 1; diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index 59305f85073c..251164001ffd 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -558,7 +558,7 @@ int ImgUDevice::configureVideoDevice(V4L2VideoDevice *dev, unsigned int pad, return 0; *outputFormat = {}; - outputFormat->fourcc = V4L2PixelFormat::fromPixelFormat(formats::NV12); + outputFormat->fourcc = V4L2PixelFormat::fromPixelFormat(formats::NV12)[0]; outputFormat->size = cfg.size; outputFormat->planesCount = 2; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index fdc24cd530c2..f698d3329429 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -96,7 +96,7 @@ V4L2DeviceFormat toV4L2DeviceFormat(const V4L2SubdeviceFormat &format, const PixelFormat pix = mbusCodeToPixelFormat(format.mbus_code, packingReq); V4L2DeviceFormat deviceFormat; - deviceFormat.fourcc = V4L2PixelFormat::fromPixelFormat(pix); + deviceFormat.fourcc = V4L2PixelFormat::fromPixelFormat(pix)[0]; deviceFormat.size = format.size; deviceFormat.colorSpace = format.colorSpace; return deviceFormat; @@ -516,14 +516,14 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() V4L2VideoDevice::Formats fmts = dev->formats(); - if (fmts.find(V4L2PixelFormat::fromPixelFormat(cfgPixFmt)) == fmts.end()) { + if (fmts.find(V4L2PixelFormat::fromPixelFormat(cfgPixFmt)[0]) == fmts.end()) { /* If we cannot find a native format, use a default one. */ cfgPixFmt = formats::NV12; status = Adjusted; } V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; format.size = cfg.size; format.colorSpace = cfg.colorSpace; @@ -783,7 +783,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) RPi::Stream *stream = i == maxIndex ? &data->isp_[Isp::Output0] : &data->isp_[Isp::Output1]; - V4L2PixelFormat fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + V4L2PixelFormat fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; format.size = cfg.size; format.fourcc = fourcc; format.colorSpace = cfg.colorSpace; @@ -829,7 +829,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) maxSize = Size(320, 240); format = {}; format.size = maxSize; - format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::YUV420); + format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::YUV420)[0]; /* No one asked for output, so the color space doesn't matter. */ format.colorSpace = ColorSpace::Jpeg; ret = data->isp_[Isp::Output0].dev()->setFormat(&format); @@ -862,7 +862,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) output1Format.size = (format.size / 2).boundedTo(limit).alignedDownTo(2, 2); output1Format.colorSpace = format.colorSpace; - output1Format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::YUV420); + output1Format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::YUV420)[0]; LOG(RPI, Debug) << "Setting ISP Output1 (internal) to " << output1Format; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index 6f175758665d..f4e71bab00ed 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -81,7 +81,7 @@ CameraConfiguration::Status RkISP1Path::validate(StreamConfiguration *cfg) cfg->bufferCount = RKISP1_BUFFER_COUNT; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg->pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg->pixelFormat)[0]; format.size = cfg->size; int ret = video_->tryFormat(&format); @@ -147,7 +147,7 @@ int RkISP1Path::configure(const StreamConfiguration &config, const PixelFormatInfo &info = PixelFormatInfo::info(config.pixelFormat); V4L2DeviceFormat outputFormat; - outputFormat.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat); + outputFormat.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat)[0]; outputFormat.size = config.size; outputFormat.planesCount = info.numPlanes(); @@ -156,7 +156,7 @@ int RkISP1Path::configure(const StreamConfiguration &config, return ret; if (outputFormat.size != config.size || - outputFormat.fourcc != V4L2PixelFormat::fromPixelFormat(config.pixelFormat)) { + outputFormat.fourcc != V4L2PixelFormat::fromPixelFormat(config.pixelFormat)[0]) { LOG(RkISP1, Error) << "Unable to configure capture in " << config.toString(); return -EINVAL; diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp index 77c44fc8714f..490ee5eb4ec4 100644 --- a/src/libcamera/pipeline/simple/converter.cpp +++ b/src/libcamera/pipeline/simple/converter.cpp @@ -46,7 +46,7 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg, const StreamConfiguration &outputCfg) { V4L2PixelFormat videoFormat = - V4L2PixelFormat::fromPixelFormat(inputCfg.pixelFormat); + V4L2PixelFormat::fromPixelFormat(inputCfg.pixelFormat)[0]; V4L2DeviceFormat format; format.fourcc = videoFormat; @@ -71,7 +71,7 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg, } /* Set the pixel format and size on the output. */ - videoFormat = V4L2PixelFormat::fromPixelFormat(outputCfg.pixelFormat); + videoFormat = V4L2PixelFormat::fromPixelFormat(outputCfg.pixelFormat)[0]; format = {}; format.fourcc = videoFormat; format.size = outputCfg.size; @@ -210,7 +210,7 @@ std::vector SimpleConverter::formats(PixelFormat input) * enumerate the conversion capabilities on its output (V4L2 capture). */ V4L2DeviceFormat v4l2Format; - v4l2Format.fourcc = V4L2PixelFormat::fromPixelFormat(input); + v4l2Format.fourcc = V4L2PixelFormat::fromPixelFormat(input)[0]; v4l2Format.size = { 1, 1 }; int ret = m2m_->output()->setFormat(&v4l2Format); @@ -281,7 +281,7 @@ SimpleConverter::strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) { V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(pixelFormat)[0]; format.size = size; int ret = m2m_->capture()->tryFormat(&format); diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index bc0cb1a00c2a..33a7b4e57deb 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -918,7 +918,7 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() return Invalid; } else { V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; format.size = cfg.size; int ret = data_->video_->tryFormat(&format); @@ -1028,7 +1028,7 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) return ret; /* Configure the video node. */ - V4L2PixelFormat videoFormat = V4L2PixelFormat::fromPixelFormat(pipeConfig->captureFormat); + V4L2PixelFormat videoFormat = V4L2PixelFormat::fromPixelFormat(pipeConfig->captureFormat)[0]; V4L2DeviceFormat captureFormat; captureFormat.fourcc = videoFormat; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 53b2f23ab029..338aff02aff0 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -149,7 +149,7 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() cfg.bufferCount = 4; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; format.size = cfg.size; int ret = data_->video_->tryFormat(&format); @@ -205,7 +205,7 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config) int ret; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; format.size = cfg.size; ret = data->video_->setFormat(&format); @@ -213,7 +213,7 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config) return ret; if (format.size != cfg.size || - format.fourcc != V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)) + format.fourcc != V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]) return -EINVAL; cfg.setStream(&data->stream_); diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 3379ac5cd47d..b88b30fff108 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -171,7 +171,7 @@ CameraConfiguration::Status VimcCameraConfiguration::validate() cfg.bufferCount = 4; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; format.size = cfg.size; int ret = data_->video_->tryFormat(&format); @@ -275,7 +275,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) return ret; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; format.size = cfg.size; ret = data->video_->setFormat(&format); @@ -283,7 +283,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) return ret; if (format.size != cfg.size || - format.fourcc != V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)) + format.fourcc != V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]) return -EINVAL; /* @@ -598,7 +598,7 @@ int VimcCameraData::allocateMockIPABuffers() constexpr unsigned int kBufCount = 2; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::BGR888); + format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::BGR888)[0]; format.size = Size (160, 120); int ret = video_->setFormat(&format); diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index cf6c1858bd1a..7ab63f092a28 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -302,26 +302,26 @@ PixelFormat V4L2PixelFormat::toPixelFormat() const } /** - * \brief Convert \a pixelFormat to its corresponding V4L2PixelFormat + * \brief Convert \a pixelFormat to a list of corresponding V4L2PixelFormat * \param[in] pixelFormat The PixelFormat to convert * \param[in] multiplanar V4L2 Multiplanar API support flag * - * Multiple V4L2 formats may exist for one PixelFormat when the format uses - * multiple planes, as V4L2 defines separate 4CCs for contiguous and separate - * planes formats. Set the \a multiplanar parameter to false to select a format - * with contiguous planes, or to true to select a format with non-contiguous - * planes. + * Multiple V4L2 formats may exist for one PixelFormat. This function returns + * the list of V4L2 formats and distinguish if the format describes contiguous + * or non-contiguous planes as V4L2 defines separate 4CCs for the two variants. + * This function uses the \a multiplanar argument, defaulted to false, + * to select formats with non-contiguous or contiguous planes. * * \return The V4L2PixelFormat corresponding to \a pixelFormat */ -V4L2PixelFormat V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat, - bool multiplanar) +std::vector V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat, + bool multiplanar) { const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat); if (!info.isValid()) - return V4L2PixelFormat(); + return {}; - return multiplanar ? info.v4l2Formats.multi[0] : info.v4l2Formats.single[0]; + return multiplanar ? info.v4l2Formats.multi : info.v4l2Formats.single; } /** diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 26a227da6db2..55ff62cdb430 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -182,7 +182,7 @@ void V4L2CameraProxy::setFmtFromConfig(const StreamConfiguration &streamConfig) v4l2PixFormat_.width = size.width; v4l2PixFormat_.height = size.height; - v4l2PixFormat_.pixelformat = V4L2PixelFormat::fromPixelFormat(streamConfig.pixelFormat); + v4l2PixFormat_.pixelformat = V4L2PixelFormat::fromPixelFormat(streamConfig.pixelFormat)[0]; v4l2PixFormat_.field = V4L2_FIELD_NONE; v4l2PixFormat_.bytesperline = streamConfig.stride; v4l2PixFormat_.sizeimage = streamConfig.frameSize; @@ -290,7 +290,7 @@ int V4L2CameraProxy::vidioc_enum_fmt(V4L2CameraFile *file, struct v4l2_fmtdesc * return -EINVAL; PixelFormat format = streamConfig_.formats().pixelformats()[arg->index]; - V4L2PixelFormat v4l2Format = V4L2PixelFormat::fromPixelFormat(format); + V4L2PixelFormat v4l2Format = V4L2PixelFormat::fromPixelFormat(format)[0]; arg->flags = format == formats::MJPEG ? V4L2_FMT_FLAG_COMPRESSED : 0; utils::strlcpy(reinterpret_cast(arg->description), @@ -333,7 +333,7 @@ int V4L2CameraProxy::tryFormat(struct v4l2_format *arg) arg->fmt.pix.width = config.size.width; arg->fmt.pix.height = config.size.height; - arg->fmt.pix.pixelformat = V4L2PixelFormat::fromPixelFormat(config.pixelFormat); + arg->fmt.pix.pixelformat = V4L2PixelFormat::fromPixelFormat(config.pixelFormat)[0]; arg->fmt.pix.field = V4L2_FIELD_NONE; arg->fmt.pix.bytesperline = config.stride; arg->fmt.pix.sizeimage = config.frameSize; diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp index 1b261697279a..84f1169c9f5f 100644 --- a/test/libtest/buffer_source.cpp +++ b/test/libtest/buffer_source.cpp @@ -72,7 +72,7 @@ int BufferSource::allocate(const StreamConfiguration &config) } format.size = config.size; - format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat); + format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat)[0]; if (video->setFormat(&format)) { std::cout << "Failed to set format on output device" << std::endl; return TestFail; From patchwork Fri Jul 15 13:50:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16642 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 1BA42BE173 for ; Fri, 15 Jul 2022 13:50:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D2BFF63316; Fri, 15 Jul 2022 15:50:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1657893027; bh=d+ZqRzYN9HV4NS0KM8HZIvMH+JcHoEMolqRjFp5wA/c=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=RxJa8qy4QkhVGxCv5Mnk7zuNcRcn7dyKYa6ZPJ3mbDiZXToHma+y0jCj9LKKmexWz l0ry9KLl2bArGuxp0QX8FLHudf30YNf7YMWnHTUf00FRMcIr6QUBOeCA00kcPrXqYZ 4Cyr6/PiILysdeDrkgrm+oQ+zc+QCFsuMfAjUC5ZIpMNpdCC/FuyJPJAmonq0YNAXu sShe0Y7YsDrPgWWqwT5txrkfrp5ARCI7pyIq+6mhy5GsNk2dMGc/MXvGMBKketeJD3 EOT1k287/dp70mBURsRk8rAC3FCLF5JWoeSw1Em0hrck112BUWcvTP5OlCpUBj3YTJ wBC1ukvnd6gyg== Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::223]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9B4D96331A for ; Fri, 15 Jul 2022 15:50:24 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 757566000C; Fri, 15 Jul 2022 13:50:23 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Jul 2022 15:50:04 +0200 Message-Id: <20220715135007.53574-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220715135007.53574-1-jacopo@jmondi.org> References: <20220715135007.53574-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/7] libcamera: v4l2_videodevice: Reintroduce toV4L2PixelFormat() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: jozef@mlich.cz, Pavel Machek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This is a partial revert of commit 395d43d6d75b ("libcamera: v4l2_videodevice: Drop toV4L2PixelFormat()") The function was removed because it incorrectly maps non-contigous V4L2 format variants (ie V4L2_PIX_FMT_YUV420M) to the API version supported by the video device (singleplanar API and multiplanar API). It was decided at the time to remove the function and let its users call directly V4L2PixelFormat::fromPixelFormat() which accepts a 'multiplanar' flags. As we now aim to associate multiple V4L2PixelFormat to a single libcamera format, it is necessary to verify which of them is actually supported by the video device. Hence re-introduce V4L2VideoDevice::toV4L2PixelFormat() and convert all the V4L2PixelFormat::fromPixelFormat() users to use it. The V4L2 compatibility layer is the only outliner as it doesn't have a video device to poke, hence it still uses V4L2PixelFormat::fromPixelFormat() and defaults to the first format. Next patches will implement the device format matching logic and handle the non-contiguous plane issue in V4L2VideoDevice::toV4L2PixelFormat(). Signed-off-by: Jacopo Mondi --- Documentation/guides/pipeline-handler.rst | 7 ++-- include/libcamera/internal/v4l2_videodevice.h | 2 ++ src/libcamera/pipeline/ipu3/cio2.cpp | 2 +- src/libcamera/pipeline/ipu3/imgu.cpp | 2 +- .../pipeline/raspberrypi/raspberrypi.cpp | 34 +++++++++++-------- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 6 ++-- src/libcamera/pipeline/simple/converter.cpp | 8 ++--- src/libcamera/pipeline/simple/simple.cpp | 2 +- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 4 +-- src/libcamera/pipeline/vimc/vimc.cpp | 8 ++--- src/libcamera/v4l2_videodevice.cpp | 17 ++++++++++ test/libtest/buffer_source.cpp | 2 +- 12 files changed, 60 insertions(+), 34 deletions(-) diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index 2d55666d094f..dcb6971e46f0 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -971,7 +971,8 @@ with the fourcc and size attributes to apply directly to the capture device node. The fourcc attribute is a `V4L2PixelFormat`_ and differs from the ``libcamera::PixelFormat``. Converting the format requires knowledge of the plane configuration for multiplanar formats, so you must explicitly convert it -using the helper ``V4L2PixelFormat::fromPixelFormat()``. +using the helper ``V4L2VideoDevice::toV4L2PixelFormat()`` provided by the +V4L2VideoDevice instance of which the format will be applied on. .. _V4L2DeviceFormat: https://libcamera.org/api-html/classlibcamera_1_1V4L2DeviceFormat.html .. _V4L2PixelFormat: https://libcamera.org/api-html/classlibcamera_1_1V4L2PixelFormat.html @@ -981,7 +982,7 @@ Add the following code beneath the code from above: .. code-block:: cpp V4L2DeviceFormat format = {}; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat); + format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; Set the video device format defined above using the @@ -1001,7 +1002,7 @@ Continue the implementation with the following code: return ret; if (format.size != cfg.size || - format.fourcc != V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)) + format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat)) return -EINVAL; Finally, store and set stream-specific data reflecting the state of the stream. diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 8525acbc558d..29fa0bbaf670 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -228,6 +228,8 @@ public: static std::unique_ptr fromEntityName(const MediaDevice *media, const std::string &entity); + V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat) const; + protected: std::string logPrefix() const override; diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 4a13d16973e9..d4e523af24b4 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -203,7 +203,7 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat) if (itInfo == mbusCodesToPixelFormat.end()) return -EINVAL; - outputFormat->fourcc = V4L2PixelFormat::fromPixelFormat(itInfo->second)[0]; + outputFormat->fourcc = output_->toV4L2PixelFormat(itInfo->second); outputFormat->size = sensorFormat.size; outputFormat->planesCount = 1; diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index 251164001ffd..531879f18183 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -558,7 +558,7 @@ int ImgUDevice::configureVideoDevice(V4L2VideoDevice *dev, unsigned int pad, return 0; *outputFormat = {}; - outputFormat->fourcc = V4L2PixelFormat::fromPixelFormat(formats::NV12)[0]; + outputFormat->fourcc = dev->toV4L2PixelFormat(formats::NV12); outputFormat->size = cfg.size; outputFormat->planesCount = 2; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index f698d3329429..52e71d0ad0bd 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -90,13 +90,14 @@ PixelFormat mbusCodeToPixelFormat(unsigned int mbus_code, return pix; } -V4L2DeviceFormat toV4L2DeviceFormat(const V4L2SubdeviceFormat &format, +V4L2DeviceFormat toV4L2DeviceFormat(const V4L2VideoDevice *dev, + const V4L2SubdeviceFormat &format, BayerFormat::Packing packingReq) { const PixelFormat pix = mbusCodeToPixelFormat(format.mbus_code, packingReq); V4L2DeviceFormat deviceFormat; - deviceFormat.fourcc = V4L2PixelFormat::fromPixelFormat(pix)[0]; + deviceFormat.fourcc = dev->toV4L2PixelFormat(pix); deviceFormat.size = format.size; deviceFormat.colorSpace = format.colorSpace; return deviceFormat; @@ -422,15 +423,15 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() * Calculate the best sensor mode we can use based on * the user request. */ + V4L2VideoDevice *unicam = data_->unicam_[Unicam::Image].dev(); const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); unsigned int bitDepth = info.isValid() ? info.bitsPerPixel : defaultRawBitDepth; V4L2SubdeviceFormat sensorFormat = findBestFormat(data_->sensorFormats_, cfg.size, bitDepth); BayerFormat::Packing packing = BayerFormat::Packing::CSI2; if (info.isValid() && !info.packed) packing = BayerFormat::Packing::None; - V4L2DeviceFormat unicamFormat = toV4L2DeviceFormat(sensorFormat, - packing); - int ret = data_->unicam_[Unicam::Image].dev()->tryFormat(&unicamFormat); + V4L2DeviceFormat unicamFormat = toV4L2DeviceFormat(unicam, sensorFormat, packing); + int ret = unicam->tryFormat(&unicamFormat); if (ret) return Invalid; @@ -516,14 +517,14 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() V4L2VideoDevice::Formats fmts = dev->formats(); - if (fmts.find(V4L2PixelFormat::fromPixelFormat(cfgPixFmt)[0]) == fmts.end()) { + if (fmts.find(dev->toV4L2PixelFormat(cfgPixFmt)) == fmts.end()) { /* If we cannot find a native format, use a default one. */ cfgPixFmt = formats::NV12; status = Adjusted; } V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; + format.fourcc = dev->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; format.colorSpace = cfg.colorSpace; @@ -751,8 +752,9 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) if (ret) return ret; - V4L2DeviceFormat unicamFormat = toV4L2DeviceFormat(sensorFormat, packing); - ret = data->unicam_[Unicam::Image].dev()->setFormat(&unicamFormat); + V4L2VideoDevice *unicam = data->unicam_[Unicam::Image].dev(); + V4L2DeviceFormat unicamFormat = toV4L2DeviceFormat(unicam, sensorFormat, packing); + ret = unicam->setFormat(&unicamFormat); if (ret) return ret; @@ -783,7 +785,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) RPi::Stream *stream = i == maxIndex ? &data->isp_[Isp::Output0] : &data->isp_[Isp::Output1]; - V4L2PixelFormat fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; + V4L2PixelFormat fourcc = stream->dev()->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; format.fourcc = fourcc; format.colorSpace = cfg.colorSpace; @@ -826,13 +828,15 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) * statistics coming from the hardware. */ if (!output0Set) { + V4L2VideoDevice *dev = data->isp_[Isp::Output0].dev(); + maxSize = Size(320, 240); format = {}; format.size = maxSize; - format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::YUV420)[0]; + format.fourcc = dev->toV4L2PixelFormat(formats::YUV420); /* No one asked for output, so the color space doesn't matter. */ format.colorSpace = ColorSpace::Jpeg; - ret = data->isp_[Isp::Output0].dev()->setFormat(&format); + ret = dev->setFormat(&format); if (ret) { LOG(RPI, Error) << "Failed to set default format on ISP Output0: " @@ -856,18 +860,20 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) * colour denoise will not run. */ if (!output1Set) { + V4L2VideoDevice *dev = data->isp_[Isp::Output1].dev(); + V4L2DeviceFormat output1Format; constexpr Size maxDimensions(1200, 1200); const Size limit = maxDimensions.boundedToAspectRatio(format.size); output1Format.size = (format.size / 2).boundedTo(limit).alignedDownTo(2, 2); output1Format.colorSpace = format.colorSpace; - output1Format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::YUV420)[0]; + output1Format.fourcc = dev->toV4L2PixelFormat(formats::YUV420); LOG(RPI, Debug) << "Setting ISP Output1 (internal) to " << output1Format; - ret = data->isp_[Isp::Output1].dev()->setFormat(&output1Format); + ret = dev->setFormat(&output1Format); if (ret) { LOG(RPI, Error) << "Failed to set format on ISP Output1: " << ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index f4e71bab00ed..2d38f0fb37ab 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -81,7 +81,7 @@ CameraConfiguration::Status RkISP1Path::validate(StreamConfiguration *cfg) cfg->bufferCount = RKISP1_BUFFER_COUNT; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg->pixelFormat)[0]; + format.fourcc = video_->toV4L2PixelFormat(cfg->pixelFormat); format.size = cfg->size; int ret = video_->tryFormat(&format); @@ -147,7 +147,7 @@ int RkISP1Path::configure(const StreamConfiguration &config, const PixelFormatInfo &info = PixelFormatInfo::info(config.pixelFormat); V4L2DeviceFormat outputFormat; - outputFormat.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat)[0]; + outputFormat.fourcc = video_->toV4L2PixelFormat(config.pixelFormat); outputFormat.size = config.size; outputFormat.planesCount = info.numPlanes(); @@ -156,7 +156,7 @@ int RkISP1Path::configure(const StreamConfiguration &config, return ret; if (outputFormat.size != config.size || - outputFormat.fourcc != V4L2PixelFormat::fromPixelFormat(config.pixelFormat)[0]) { + outputFormat.fourcc != video_->toV4L2PixelFormat(config.pixelFormat)) { LOG(RkISP1, Error) << "Unable to configure capture in " << config.toString(); return -EINVAL; diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp index 490ee5eb4ec4..11d9f572a0de 100644 --- a/src/libcamera/pipeline/simple/converter.cpp +++ b/src/libcamera/pipeline/simple/converter.cpp @@ -46,7 +46,7 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg, const StreamConfiguration &outputCfg) { V4L2PixelFormat videoFormat = - V4L2PixelFormat::fromPixelFormat(inputCfg.pixelFormat)[0]; + m2m_->output()->toV4L2PixelFormat(inputCfg.pixelFormat); V4L2DeviceFormat format; format.fourcc = videoFormat; @@ -71,7 +71,7 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg, } /* Set the pixel format and size on the output. */ - videoFormat = V4L2PixelFormat::fromPixelFormat(outputCfg.pixelFormat)[0]; + videoFormat = m2m_->capture()->toV4L2PixelFormat(outputCfg.pixelFormat); format = {}; format.fourcc = videoFormat; format.size = outputCfg.size; @@ -210,7 +210,7 @@ std::vector SimpleConverter::formats(PixelFormat input) * enumerate the conversion capabilities on its output (V4L2 capture). */ V4L2DeviceFormat v4l2Format; - v4l2Format.fourcc = V4L2PixelFormat::fromPixelFormat(input)[0]; + v4l2Format.fourcc = m2m_->output()->toV4L2PixelFormat(input); v4l2Format.size = { 1, 1 }; int ret = m2m_->output()->setFormat(&v4l2Format); @@ -281,7 +281,7 @@ SimpleConverter::strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) { V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(pixelFormat)[0]; + format.fourcc = m2m_->capture()->toV4L2PixelFormat(pixelFormat); format.size = size; int ret = m2m_->capture()->tryFormat(&format); diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 33a7b4e57deb..65a483c14379 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -918,7 +918,7 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() return Invalid; } else { V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; + format.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; int ret = data_->video_->tryFormat(&format); diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 338aff02aff0..cf870d26e3c3 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -149,7 +149,7 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() cfg.bufferCount = 4; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; + format.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; int ret = data_->video_->tryFormat(&format); @@ -205,7 +205,7 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config) int ret; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; + format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; ret = data->video_->setFormat(&format); diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index b88b30fff108..153cf849bb18 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -171,7 +171,7 @@ CameraConfiguration::Status VimcCameraConfiguration::validate() cfg.bufferCount = 4; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; + format.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; int ret = data_->video_->tryFormat(&format); @@ -275,7 +275,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) return ret; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]; + format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; ret = data->video_->setFormat(&format); @@ -283,7 +283,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) return ret; if (format.size != cfg.size || - format.fourcc != V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat)[0]) + format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat)) return -EINVAL; /* @@ -598,7 +598,7 @@ int VimcCameraData::allocateMockIPABuffers() constexpr unsigned int kBufCount = 2; V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat::fromPixelFormat(formats::BGR888)[0]; + format.fourcc = video_->toV4L2PixelFormat(formats::BGR888); format.size = Size (160, 120); int ret = video_->setFormat(&format); diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 63911339f96e..43c3d0f69266 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -1989,6 +1989,23 @@ V4L2VideoDevice::fromEntityName(const MediaDevice *media, return std::make_unique(mediaEntity); } +/** + * \brief Convert \a PixelFormat to its corresponding V4L2 FourCC + * \param[in] pixelFormat The PixelFormat to convert + * + * For multiplanar formats, the V4L2 format variant (contiguous or + * non-contiguous planes) is selected automatically based on the capabilities + * of the video device. If the video device supports the V4L2 multiplanar API, + * non-contiguous formats are preferred. + * + * \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat + */ +V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat) const +{ + return V4L2PixelFormat::fromPixelFormat(pixelFormat, + caps_.isMultiplanar())[0]; +} + /** * \class V4L2M2MDevice * \brief Memory-to-Memory video device diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp index 84f1169c9f5f..dde11f365e43 100644 --- a/test/libtest/buffer_source.cpp +++ b/test/libtest/buffer_source.cpp @@ -72,7 +72,7 @@ int BufferSource::allocate(const StreamConfiguration &config) } format.size = config.size; - format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat)[0]; + format.fourcc = video->toV4L2PixelFormat(config.pixelFormat); if (video->setFormat(&format)) { std::cout << "Failed to set format on output device" << std::endl; return TestFail; From patchwork Fri Jul 15 13:50:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16643 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 9D526BE173 for ; Fri, 15 Jul 2022 13:50:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 65A1D63321; Fri, 15 Jul 2022 15:50:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1657893028; bh=6mdHx4ftcLUdI3VBL+yXdKQLM6DwYHnxc4PojlzUZlk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=yqesC1qsR/LhF8XBr6JcKrgpLzSZ1P3b1K9u5FV7HwSTxQ90WiAEpejIRDAu3lZey OW+r3PAEmlfuyU15q1b4oG2vMK4SN2vMGrJuGX9M6hvhVX1HbRw75JMFqQwj7LO81z T2t4vM7GWATy73xFdsvj45vBgnib+3Vh0O9VjlD3DTXSlsKrUlHOZ0NqlSZHQS3HUk e6Lxh0ABjUzgymfRbgTvq6X6xymp2Hz/T1x7JhlR3sMMDGoUUoCj2MyKIIOHCKAoCf RnyzrkcqwcWxVvtd0jQzS1MT8Cvhdwus8RV68N7Vj5yTCWrzKABV/aYpbTWT9IDHmf XfClwdnvNPlbQ== Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::223]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 162FC6331D for ; Fri, 15 Jul 2022 15:50:26 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id D5FDD60010; Fri, 15 Jul 2022 13:50:24 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Jul 2022 15:50:05 +0200 Message-Id: <20220715135007.53574-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220715135007.53574-1-jacopo@jmondi.org> References: <20220715135007.53574-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/7] libcamera: v4l2_videodevice: Match formats supported by the device X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: jozef@mlich.cz, Pavel Machek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that V4L2PixelFormat::fromPixelFormat() returns a list of formats to chose from by checking which ones are actually supported by the video device. The first format found to match one of the device supported ones is returned. As V4L2VideoDevice::toV4L2PixelFormat() is a const function which uses other functions of the class, those functions has to be made const as well. In particular: - enumPixelformats() and enumSizes() do not modify the class state and can safely be made const. - formats() uses the above functions and does not itself modify the class state and can be made const - add a const version of V4L2Device::ioctl() to be used by the now const functions Signed-off-by: Jacopo Mondi --- include/libcamera/internal/v4l2_device.h | 1 + include/libcamera/internal/v4l2_videodevice.h | 6 ++-- src/libcamera/v4l2_device.cpp | 15 +++++++++ src/libcamera/v4l2_videodevice.cpp | 31 ++++++++++++++----- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h index a52a5f2c99f9..f7ec3c7004a6 100644 --- a/include/libcamera/internal/v4l2_device.h +++ b/include/libcamera/internal/v4l2_device.h @@ -55,6 +55,7 @@ protected: int setFd(UniqueFD fd); int ioctl(unsigned long request, void *argp); + int ioctl(unsigned long request, void *argp) const; int fd() const { return fd_.get(); } diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 29fa0bbaf670..6d8850c99afd 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -205,7 +205,7 @@ public: int getFormat(V4L2DeviceFormat *format); int tryFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format); - Formats formats(uint32_t code = 0); + Formats formats(uint32_t code = 0) const; int setSelection(unsigned int target, Rectangle *rect); @@ -251,8 +251,8 @@ private: int getFormatSingleplane(V4L2DeviceFormat *format); int trySetFormatSingleplane(V4L2DeviceFormat *format, bool set); - std::vector enumPixelformats(uint32_t code); - std::vector enumSizes(V4L2PixelFormat pixelFormat); + std::vector enumPixelformats(uint32_t code) const; + std::vector enumSizes(V4L2PixelFormat pixelFormat) const; int requestBuffers(unsigned int count, enum v4l2_memory memoryType); int createBuffers(unsigned int count, diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 3fc8438f6579..59f92403db80 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -459,6 +459,21 @@ int V4L2Device::ioctl(unsigned long request, void *argp) return 0; } +/** + * \copydoc ioctl() + */ +int V4L2Device::ioctl(unsigned long request, void *argp) const +{ + /* + * Printing out an error message is usually better performed + * in the caller, which can provide more context. + */ + if (::ioctl(fd_.get(), request, argp) < 0) + return -errno; + + return 0; +} + /** * \fn V4L2Device::deviceNode() * \brief Retrieve the device node path diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 43c3d0f69266..a3242ba755c0 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -1045,7 +1045,7 @@ int V4L2VideoDevice::trySetFormatSingleplane(V4L2DeviceFormat *format, bool set) * * \return A list of the supported video device formats */ -V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code) +V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code) const { Formats formats; @@ -1067,7 +1067,7 @@ V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code) return formats; } -std::vector V4L2VideoDevice::enumPixelformats(uint32_t code) +std::vector V4L2VideoDevice::enumPixelformats(uint32_t code) const { std::vector formats; int ret; @@ -1101,7 +1101,7 @@ std::vector V4L2VideoDevice::enumPixelformats(uint32_t code) return formats; } -std::vector V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat) +std::vector V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat) const { std::vector sizes; int ret; @@ -1990,20 +1990,37 @@ V4L2VideoDevice::fromEntityName(const MediaDevice *media, } /** - * \brief Convert \a PixelFormat to its corresponding V4L2 FourCC + * \brief Convert \a PixelFormat to one of the device supported V4L2 FourCC * \param[in] pixelFormat The PixelFormat to convert * + * Convert a\ pixelformat to a V4L2 FourCC that is known to be supported by + * the video device. + * * For multiplanar formats, the V4L2 format variant (contiguous or * non-contiguous planes) is selected automatically based on the capabilities * of the video device. If the video device supports the V4L2 multiplanar API, * non-contiguous formats are preferred. * - * \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat + * \return The V4L2PixelFormat corresponding to \a pixelFormat or an invalid + * PixelFormat if \a pixelFormat is not supported by the video device */ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat) const { - return V4L2PixelFormat::fromPixelFormat(pixelFormat, - caps_.isMultiplanar())[0]; + std::vector deviceFormats = enumPixelformats(0); + std::vector v4l2PixelFormats = + V4L2PixelFormat::fromPixelFormat(pixelFormat, caps_.isMultiplanar()); + + for (const V4L2PixelFormat &v4l2Format : v4l2PixelFormats) { + auto it = std::find_if(deviceFormats.begin(), deviceFormats.end(), + [&v4l2Format](const V4L2PixelFormat &deviceFormat) { + return v4l2Format == deviceFormat; + }); + + if (it != deviceFormats.end()) + return v4l2Format; + } + + return {}; } /** From patchwork Fri Jul 15 13:50:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16644 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 1FF75BE173 for ; Fri, 15 Jul 2022 13:50:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D37246331E; Fri, 15 Jul 2022 15:50:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1657893030; bh=xsOmi0ExAprMxJ0HW3/9PchbaC2LQxkXWJ+JkZTpw/w=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=aIrKU66eVOSLnfLcMY7DnZRQviKQaKvqHAmpwSCKdGnvALwiqz7gb1jB4vkXjctRs hOMRHriPqUB9VLxd9wpLLK3g4BVsLe3v0OL6Ns+eOke4dGURNX0VeXsebt50E/RqUE rDC1nK3deaZG7JfG9QtVJGXV6Ztr4oCjv9yPE3qkknvZ3MvD8ON7VfFtB+piWwGHc2 M6hNuqY42489QYdyhM5oaM+6Fe6Rz+32X6Y+/mVGOdC0SB3JgHVe1x+cW72/wGUaJk 6SbEaI7Q9Y/vKiE56GbKl1UTiXJH4EoVQfM2MukFoYhmrLcS/GHPTYwoJsvMz+xt+G JHj+CoQpXuf5Q== Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::223]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 68B2D63316 for ; Fri, 15 Jul 2022 15:50:27 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 3F29860005; Fri, 15 Jul 2022 13:50:26 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Jul 2022 15:50:06 +0200 Message-Id: <20220715135007.53574-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220715135007.53574-1-jacopo@jmondi.org> References: <20220715135007.53574-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 6/7] libcamera: v4l2_videodevice: Add multiplanar argument to toV4L2PixelFormat X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: jozef@mlich.cz, Pavel Machek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The toV4L2PixelFormat() function selects which V4L2 format variant to use (contiguous planes vs non-contiguous version) by using video device multiplanar API from the capabilities. The isMultiplanar() function however verifies if the video device uses the singleplanar or the multiplanar V4L2 API, something which is unrelated to the format variant to use. Add a 'multiplanar' flag, which defaults to false, to the toV4L2PixelFormat() function to allow explicit selection of the format variant. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/v4l2_videodevice.h | 3 ++- src/libcamera/v4l2_videodevice.cpp | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 6d8850c99afd..64296c5849f2 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -228,7 +228,8 @@ public: static std::unique_ptr fromEntityName(const MediaDevice *media, const std::string &entity); - V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat) const; + V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat, + bool multiplanar = false) const; protected: std::string logPrefix() const override; diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index a3242ba755c0..767ab2361ef5 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -1992,23 +1992,24 @@ V4L2VideoDevice::fromEntityName(const MediaDevice *media, /** * \brief Convert \a PixelFormat to one of the device supported V4L2 FourCC * \param[in] pixelFormat The PixelFormat to convert + * \param[in] multiplanar Use the multiplanar format version, default to false * * Convert a\ pixelformat to a V4L2 FourCC that is known to be supported by * the video device. * - * For multiplanar formats, the V4L2 format variant (contiguous or - * non-contiguous planes) is selected automatically based on the capabilities - * of the video device. If the video device supports the V4L2 multiplanar API, - * non-contiguous formats are preferred. + * V4L2 defines different format variants for the same format when using + * contiguous or non-contiguous planes. The \a multiplanar parameter allows + * to select which variant to use. * * \return The V4L2PixelFormat corresponding to \a pixelFormat or an invalid * PixelFormat if \a pixelFormat is not supported by the video device */ -V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat) const +V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat, + bool multiplanar) const { std::vector deviceFormats = enumPixelformats(0); std::vector v4l2PixelFormats = - V4L2PixelFormat::fromPixelFormat(pixelFormat, caps_.isMultiplanar()); + V4L2PixelFormat::fromPixelFormat(pixelFormat, multiplanar); for (const V4L2PixelFormat &v4l2Format : v4l2PixelFormats) { auto it = std::find_if(deviceFormats.begin(), deviceFormats.end(), From patchwork Fri Jul 15 13:50:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16645 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7B842C3274 for ; Fri, 15 Jul 2022 13:50:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4329D63325; Fri, 15 Jul 2022 15:50:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1657893031; bh=aRjSCXAQuNkdIKSUN+wY1r4RD2HhNObZ04hzesEBcgI=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Q5P7GugKxcDyYVX/LHy204EFtCPgHDoETmaqe9hJ3GeyFzuPGoFY2NnUQ7keexTJr AVzxtl9eYGs/f1DP39dkQV1VCKzssxNEAsgt3DKdgQxJoSH5NL/A1heovbzz2Upc1a LlSE5bmuWqFsaKNJe4DwVNkYO9sSxnAkA3aFaO8AAxD0xREuwX3dF+8TggyjxQTPXH 084Lfzp62v7HFy5WO2oBBXObS2OwN/QIwK9fQk608P3UjIEtf3VnusaZtNS48/+T6T SA8kmiCehew8OFNqBvtRrQQbWjgG/cp79L7Cb25d+uPnLdsi8MYZiXf5Wf19ieWP1Q 9S63Otl4x5J6g== Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C25276331A for ; Fri, 15 Jul 2022 15:50:28 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 9C91660002; Fri, 15 Jul 2022 13:50:27 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Jul 2022 15:50:07 +0200 Message-Id: <20220715135007.53574-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220715135007.53574-1-jacopo@jmondi.org> References: <20220715135007.53574-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 7/7] libcamera: formats: Map V4L2_PIX_FMT_JPEG to formats::MJPEG X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: jozef@mlich.cz, Pavel Machek Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The V4L2_PIX_FMT_JPEG and V4L2_PIX_FMT_MJPEG formats are under-specified and are used interchangeably by kernel drivers. Map both of them to formats::MJPEG and use the newly re-introduced V4L2VideoDevice::toV4L2PixelFormat() to map to the one actually used by the video device. Signed-off-by: Jacopo Mondi --- src/libcamera/formats.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index 86fc698a0f4e..564ccc1b5a62 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -948,7 +948,10 @@ const std::map pixelFormatInfo{ .name = "MJPEG", .format = formats::MJPEG, .v4l2Formats = { - .single = { V4L2PixelFormat(V4L2_PIX_FMT_MJPEG) }, + .single = { + V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), + V4L2PixelFormat(V4L2_PIX_FMT_JPEG), + }, .multi = { V4L2PixelFormat() }, }, .bitsPerPixel = 0,