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 {}; } /**