From patchwork Sat Jul 23 09:53:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16740 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 C0432BE173 for ; Sat, 23 Jul 2022 09:53:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 786C663315; Sat, 23 Jul 2022 11:53:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570029; bh=ArpbPgOsEsRlAYmL84t9r72AurH5FKNwpuhY/Hg5Ibs=; 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=gU6ycnpUZiCj0lZsSXzOoX1trG0ONECMGObiKooCQ9HcjYc7lnnYdtHvW21wQpUgA ZNVYhB1qjeR/FCfQtACD/ZFtZp7jpRPf0jqQpoN61u9mqgZ9sgFWMrUJCzVhixj5z+ 1kv549t37m+Hmq0j+g61RSsexlA2kSlWRIeaMZ9tnXVAkNYXDNKOBUT6Zaa54fjHXM QkTyrSpgXAWKmakxy8tSQJGHH+aeNEPcwQv4M6H+ChhIwUSXx1G8rBUS6KSXQgCAYq F6m6CQA2tmxfvkLAM0KUwCIc2+qhapHYvLIqppcVql7W+AfQ0fw6Fo8E5pHL78aqGi f9yyyhsfRd4Lg== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 01F946330E for ; Sat, 23 Jul 2022 11:53:48 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 9F8931BF20A; Sat, 23 Jul 2022 09:53:45 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:23 +0200 Message-Id: <20220723095330.43542-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/8] 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 Sat Jul 23 09:53:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16741 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 8D5FEBE173 for ; Sat, 23 Jul 2022 09:53:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 43C9F63318; Sat, 23 Jul 2022 11:53:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570034; bh=bMoHreOwzOKKMc0amupIX1iTjk8koHqdj2oVGPGBVYc=; 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=NT7yABd0KbQmChDxw6H+u4IJcFR+q3wN/FuJri+kh56dy+H2fDZG1On14V14EHWQ1 qfJBAoBeXECy/6WuiyfT9lG262753pbi/za8qexSF91KWq0nkiewQp2CkSzfE+m5nP MvSGRdyf8rC9WdfwKSubQfPuxAsiSRdjIhrZDXDBT66IGnn1ucCZqU7WMBovKsWomD SExSgVtMmAquVmaJLMYSXdkGifLgaToxEf1UxlltkOySSPB69a6zGBIDiZLpUB1aZn SZf6PPRH/MAaj1p+8qMDWgczMTmlTur4x2Ry1F0ZVK9f9EJqF5SvWYFYezzb73FdNz e+avTcTYTANxw== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C2806330E for ; Sat, 23 Jul 2022 11:53:53 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 98CAD1BF209; Sat, 23 Jul 2022 09:53:48 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:24 +0200 Message-Id: <20220723095330.43542-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/8] 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 Sat Jul 23 09:53:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16742 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 8AE4ABE173 for ; Sat, 23 Jul 2022 09:53:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3D2156331B; Sat, 23 Jul 2022 11:53:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570038; bh=/jsKirIRalvHntF2kCXkmjnSBj9IEI2fvgMKwdFEScg=; 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=pwuywjz6yqlKnGFIcdujDD04Uf2kSFg8rUKJFXWe5pyBtANbOOihHhscLb2+7OpbV snQEWinX7epZH87g2LMbuVCKRUwYgBN0/PDTXOCk1ipQgH3nXVxBhcIUc+zu6BhJBM u3567MAlKqDeIAJULwO2v2a0Yxg8Qu/3aglFabxcIr79fLHO2NofVaIOCqgbhh19TW jj62qwqDYZN7251GSl1UQ2cVMiHivyi9/oYaawCxohrqRK4lPb5VyTJoy7AOxy4yug HGfo4+maXCw0CVUs973lLrg7mjbN69wguDjoVTNtCabgSB7vNDFi14sk9VfpE9RFN+ qs6va06ihhqsg== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BC2576330E for ; Sat, 23 Jul 2022 11:53:55 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id A7CC01BF204; Sat, 23 Jul 2022 09:53:53 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:25 +0200 Message-Id: <20220723095330.43542-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/8] 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 9d5614152430..6e813bcb094a 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(cfgPixFmt); + format.fourcc = V4L2PixelFormat::fromPixelFormat(cfgPixFmt)[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 62d173bb6cd1..47e2150b4332 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); @@ -287,7 +287,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 Sat Jul 23 09:53:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16743 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 28774BE173 for ; Sat, 23 Jul 2022 09:54:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DD8DD63315; Sat, 23 Jul 2022 11:53:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570039; bh=ZRDFbJH/EIccVvGQT805+JELa2SJPgXnKK4tqWwT1Ok=; 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=ReTgWiXxQBwX4i21ruW2J7MmtSQqOpVOWo1Li9YM4YCMfY0XkpYknmoVy6QR3wKS4 BKmFqCCcHQjB58iVAYPgMiszSrYOxSiM39cYf4dhUVEu4taJ0RipUvUoOBTmIrXCbt 5O/gXvy+9je2rkdVk8Pq16FidoJvGUXt8Tk5x+5ORVdU0PwCzCFRUAWqiDXKq5g4H4 PQgEcSNFHmUbpuVl+3IiaJomHQaAx7ZWINc3RLc4M9L6cypKwTWqj+SMw9qnW6J4Ng GkfyTnRmG8a2bE33f+zXHUN9mumHw8wFyzNHBj6mgJyuJQLy3+l1vtQiw8PTV3l/GI HpZVr3ME+mw3g== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EE25C63316 for ; Sat, 23 Jul 2022 11:53:57 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 06D501BF20A; Sat, 23 Jul 2022 09:53:55 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:26 +0200 Message-Id: <20220723095330.43542-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/8] 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 | 10 +++--- 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, 61 insertions(+), 35 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 6e813bcb094a..4f60224729e3 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(cfgPixFmt)[0]; + format.fourcc = dev->toV4L2PixelFormat(cfgPixFmt); 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 47e2150b4332..acaaa64c949a 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); @@ -220,7 +220,7 @@ std::vector SimpleConverter::formats(PixelFormat input) return {}; } - if (v4l2Format.fourcc != V4L2PixelFormat::fromPixelFormat(input)) { + if (v4l2Format.fourcc != m2m_->output()->toV4L2PixelFormat(input)) { LOG(SimplePipeline, Debug) << "Input format " << input << " not supported."; return {}; @@ -287,7 +287,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 Sat Jul 23 09:53:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16744 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 BBED7BE173 for ; Sat, 23 Jul 2022 09:54:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 789AD63318; Sat, 23 Jul 2022 11:54:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570053; bh=b8tt0KPTmJnOfdIuY69kIJODREf8ppGAjSdnD/iuccw=; 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=QshmGr3oH+eydLjFKM7lpg0cxGDV5AmpBF9RG5Rug07s9W/3spwMtFvQZP2UaxV41 /r7BhEt1Z/t9/XrjgYfwaY82rcd7zHwRz8aMj3kFyjIrzsxSEoOhEj3diR/Y0QZSEd c4bMNN18sQ3/6h/tXBuDEjaiHBEwQYrLGuHaRPj+K3QDRwf9pdo8tW7iLv/8s/YIZz pNmCrPdCCOG2laeE8EF4waLpgMU08kqevjVdGQEH+wsSEz9uy/f58FU7T69x2qai1x FJ+sJYr4VbZKgPTLaZpOsRC2d50YGfXM6SzMezUXQnrcz9SZj8ZAa9RBZTJTZEgh7C NwEsLe+GUESQA== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 42A9D6330E for ; Sat, 23 Jul 2022 11:54:12 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 3BFE01BF207; Sat, 23 Jul 2022 09:53:57 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:27 +0200 Message-Id: <20220723095330.43542-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 5/8] 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 Sat Jul 23 09:53:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16745 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 5C74EBE173 for ; Sat, 23 Jul 2022 09:54:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 197346331B; Sat, 23 Jul 2022 11:54:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570057; bh=W4t/laySClNJw1u9vyAMEbpDCAxoN7T8DlUDQfp7+II=; 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=kWrfawqZSpFXs0U93n5xsVQgvE3OJ2H8pMj/L56cYJG3t/O1SjJkf8oKMflvg4iss ez68UDaa5WA1udIBkDh3ewp8g8wsYYXP3fe1fcIFTE7bD8WKhCMttWs5ugzr/4x4Do bvHirBnenFc8btFCCYxqIYxtdqonAM1zuGJQHjerzoOiHUwt4tqPIn8IFQAVEpOteN Ae02MVQLs9pxV5AlAejubk8cFgKgMcnpRBp3vzK/CEItiiYzkD6glbq45Xg5RafQy2 w5CebjcLd6/ETWjhbq456TbHzLgvBRkG4JjRsrilmEqVl+pJq2M87YdouCiDEnluLe 8UxAgP/Wig6jQ== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5D0986330E for ; Sat, 23 Jul 2022 11:54:15 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id A15AC1BF20D; Sat, 23 Jul 2022 09:54:12 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:28 +0200 Message-Id: <20220723095330.43542-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/8] 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 Sat Jul 23 09:53:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16746 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 F1E0ABE173 for ; Sat, 23 Jul 2022 09:54:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B363F63313; Sat, 23 Jul 2022 11:54:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570059; bh=LjB52t49HIdA+C3UCIW3Kz6qybxJwlduNjpfr85aPvw=; 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=FWFRVZ/aQo0p0WDRa4LbLK5ey43jtfkbX9RGTPZvpqwYkreK9zZCnxfRNENRyMGvM NBJtUWWVMloVewK+1GRpNa6YnOfJqielH2tZanFWv0sBdf0C46eHdezv7hhuT91gqy GcfV5dI7eo+Y/FyFFENpklgY2oCavubwASq8VIpi+hlQY7A0JQku9XsdvmF+HOC7+2 FFWrx2JcKR54i6SnrEovycQBXYJ5ZpPNW4SXRzJ9tsMQNiK4HuDt5A1VhP4pBci4Fm /DHUmqficd4p4d620EaYYWjRRHDor/FMKVcqOXKtEjersJz0G80b9vpvUkfLunFjKt Bg93Cs7WvR0Dg== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D81C26330D for ; Sat, 23 Jul 2022 11:54:18 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id F3DDB1BF207; Sat, 23 Jul 2022 09:54:15 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:29 +0200 Message-Id: <20220723095330.43542-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 7/8] 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 Reviewed-by: Laurent Pinchart --- 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, From patchwork Sat Jul 23 09:53:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16747 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 A07E1BE173 for ; Sat, 23 Jul 2022 09:54:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 603CC63318; Sat, 23 Jul 2022 11:54:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1658570063; bh=TNmhER/6vcCjomAJMxRoFjHfiVSzZ3e3UoIOzQmmC2M=; 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=oBJFqdQL4uMB0aIbodbdMdWV4ZkdLMViggReFirwk7LXcUyvc2MmXuJ4JxutJuyEy +/KMVXeDZeEljXDNpNdAPx/BoDIKqTITijzbaMUabzoJz7QaPI0OGFAoQdfB9deEN2 yPnqbD/h1zL9CjmSIisNkLI/fUhgWTVzuYZT5wV/K9rzEdCxBfh5nOJ2M/0K/PBgeE 4sDcMRa3jE/inNtUelOwSwJ6Haif4+FNZkA9CHUjUSU5WZ6XdGl+ksAZ/8U5ieUv7h bwE8arknbZYBKT5Aei563pwUuJ+tJ/G6V1Bs3ClAD77qYwAi4UizDlD5r1dnCIsw9j +agqqB3zwKTew== Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B2F896330D for ; Sat, 23 Jul 2022 11:54:21 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 989DA1BF204; Sat, 23 Jul 2022 09:54:19 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Sat, 23 Jul 2022 11:53:30 +0200 Message-Id: <20220723095330.43542-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220723095330.43542-1-jacopo@jmondi.org> References: <20220723095330.43542-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 8/8] libcamera: v4l2_pixelformat: Map formats::MJPEG to V4L2_PIX_FMT_JPEG 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" Map the application visibile formats::MJPEG format to the V4L2_PIX_FMT_JPEG format. Both V4L2_PIX_FMT_JPEG and V4L2_PIX_FMT_MJPEG map to the same libcamera MJPEG format. Signed-off-by: Jacopo Mondi --- src/libcamera/v4l2_pixelformat.cpp | 2 ++ 1 file changed, 2 insertions(+) -- 2.37.1 diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index 7ab63f092a28..8d3bc5d534c5 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -183,6 +183,8 @@ const std::map vpf2pf{ /* Compressed formats. */ { V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), { formats::MJPEG, "Motion-JPEG" } }, + { V4L2PixelFormat(V4L2_PIX_FMT_JPEG), + { formats::MJPEG, "JPEG JFIF" } }, }; } /* namespace */