From patchwork Thu Jul 9 13:28:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 8719 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 029EDBD792 for ; Thu, 9 Jul 2020 13:29:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C500861218; Thu, 9 Jul 2020 15:29:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="qvuyi2Le"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D0FD261184 for ; Thu, 9 Jul 2020 15:28:58 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9A163525; Thu, 9 Jul 2020 15:28:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1594301338; bh=PxDSet/16HucKK+x7HS6TY+XJlYm0Q10XoAIslw2Nlc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qvuyi2LeobF0VNAPgLMxW3T9cAYoC7bL32A7YEoSo2NLytMMlNgS7C159w5/5hlBE ip3ByCeW533tHKa0Pqj8Vl49r3fKGVjqQc1wenFog7XaMvdPGsdWzKdDNsVFWTkkho 1yDz9kgkLdS+Ys2Ep1GUu6oU1voNM9TKa/d/uwZg= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Thu, 9 Jul 2020 22:28:16 +0900 Message-Id: <20200709132835.112593-5-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200709132835.112593-1-paul.elder@ideasonboard.com> References: <20200709132835.112593-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 04/23] libcamera: V4L2VideoDevice: Add tryFormat 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add tryFormat and its variations (meta, single-plane, multi-plane) to V4L2VideoDevice. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- Cosmetic change in v5 Changes in v4: - merge tryFormat{Meta,Multiplane,SinglePlane} into setFormat with a flag New in v3 --- include/libcamera/internal/v4l2_videodevice.h | 7 +-- src/libcamera/v4l2_videodevice.cpp | 50 ++++++++++++++----- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 4d21f5a..fb4c0aa 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -186,6 +186,7 @@ public: const V4L2Capability &caps() const { return caps_; } int getFormat(V4L2DeviceFormat *format); + int tryFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format); std::map> formats(uint32_t code = 0); @@ -217,13 +218,13 @@ protected: private: int getFormatMeta(V4L2DeviceFormat *format); - int setFormatMeta(V4L2DeviceFormat *format); + int trySetFormatMeta(V4L2DeviceFormat *format, bool set); int getFormatMultiplane(V4L2DeviceFormat *format); - int setFormatMultiplane(V4L2DeviceFormat *format); + int trySetFormatMultiplane(V4L2DeviceFormat *format, bool set); int getFormatSingleplane(V4L2DeviceFormat *format); - int setFormatSingleplane(V4L2DeviceFormat *format); + int trySetFormatSingleplane(V4L2DeviceFormat *format, bool set); std::vector enumPixelformats(uint32_t code); std::vector enumSizes(V4L2PixelFormat pixelFormat); diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 3614b2e..e0d2201 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -723,6 +723,26 @@ int V4L2VideoDevice::getFormat(V4L2DeviceFormat *format) return getFormatSingleplane(format); } +/** + * \brief Try an image format on the V4L2 video device + * \param[inout] format The image format to test applicability to the video device + * + * Try the supplied \a format on the video device without applying it, returning + * the format that would be applied. This is equivalent to setFormat(), except + * that the device configuration is not changed. + * + * \return 0 on success or a negative error code otherwise + */ +int V4L2VideoDevice::tryFormat(V4L2DeviceFormat *format) +{ + if (caps_.isMeta()) + return trySetFormatMeta(format, false); + else if (caps_.isMultiplanar()) + return trySetFormatMultiplane(format, false); + else + return trySetFormatSingleplane(format, false); +} + /** * \brief Configure an image format on the V4L2 video device * \param[inout] format The image format to apply to the video device @@ -735,11 +755,11 @@ int V4L2VideoDevice::getFormat(V4L2DeviceFormat *format) int V4L2VideoDevice::setFormat(V4L2DeviceFormat *format) { if (caps_.isMeta()) - return setFormatMeta(format); + return trySetFormatMeta(format, true); else if (caps_.isMultiplanar()) - return setFormatMultiplane(format); + return trySetFormatMultiplane(format, true); else - return setFormatSingleplane(format); + return trySetFormatSingleplane(format, true); } int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format) @@ -765,7 +785,7 @@ int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format) return 0; } -int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format) +int V4L2VideoDevice::trySetFormatMeta(V4L2DeviceFormat *format, bool set) { struct v4l2_format v4l2Format = {}; struct v4l2_meta_format *pix = &v4l2Format.fmt.meta; @@ -774,9 +794,11 @@ int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format) v4l2Format.type = bufferType_; pix->dataformat = format->fourcc; pix->buffersize = format->planes[0].size; - ret = ioctl(VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format); if (ret) { - LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); + LOG(V4L2, Error) + << "Unable to " << (set ? "set" : "try") + << " format: " << strerror(-ret); return ret; } @@ -820,7 +842,7 @@ int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format) return 0; } -int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format) +int V4L2VideoDevice::trySetFormatMultiplane(V4L2DeviceFormat *format, bool set) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format_mplane *pix = &v4l2Format.fmt.pix_mp; @@ -838,9 +860,11 @@ int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format) pix->plane_fmt[i].sizeimage = format->planes[i].size; } - ret = ioctl(VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format); if (ret) { - LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); + LOG(V4L2, Error) + << "Unable to " << (set ? "set" : "try") + << " format: " << strerror(-ret); return ret; } @@ -883,7 +907,7 @@ int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format) return 0; } -int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format) +int V4L2VideoDevice::trySetFormatSingleplane(V4L2DeviceFormat *format, bool set) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format *pix = &v4l2Format.fmt.pix; @@ -895,9 +919,11 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format) pix->pixelformat = format->fourcc; pix->bytesperline = format->planes[0].bpl; pix->field = V4L2_FIELD_NONE; - ret = ioctl(VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format); if (ret) { - LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); + LOG(V4L2, Error) + << "Unable to " << (set ? "set" : "try") + << " format: " << strerror(-ret); return ret; }