From patchwork Thu May 23 13:58:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 1270 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AC7A060E4C for ; Thu, 23 May 2019 15:59:05 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2CD3F5A9; Thu, 23 May 2019 15:59:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1558619945; bh=fQR6EYg8bvGZyxZxt9HtJ6OF4ililgkffIPllMn/89c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MDPdKd6psv/au5RAq57RNOpru9c8EgP20s95SD5oPY6YzBgpHCnmRosYqvDRuJ83Z a6bBHK9qM+B6Kd02m/n0mbQo/EHib1Ln6pyT+2nb72x5mbF7DOsg66XleXlRSHlb1F UtfIcCtIMmqsKc78D3GJc5z1JMWNNJIYDgOokKvE= From: Kieran Bingham To: LibCamera Devel Date: Thu, 23 May 2019 14:58:58 +0100 Message-Id: <20190523135900.24029-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190523135900.24029-1-kieran.bingham@ideasonboard.com> References: <20190523135900.24029-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/3] libcamera: v4l2_device: Add tryFormat support X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 May 2019 13:59:06 -0000 Extend the internal functionality of setFormat{Single,Multi}plane to allow 'trying' a format. This provides the facility of checking a format with the driver before committing to it. Signed-off-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- src/libcamera/include/v4l2_device.h | 7 +++++-- src/libcamera/v4l2_device.cpp | 29 +++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 2e7bd1e7f4cc..a08615c3bd9a 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -126,6 +126,7 @@ public: int getFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format); + int tryFormat(V4L2DeviceFormat *format); int exportBuffers(BufferPool *pool); int importBuffers(BufferPool *pool); @@ -145,10 +146,12 @@ protected: private: int getFormatSingleplane(V4L2DeviceFormat *format); - int setFormatSingleplane(V4L2DeviceFormat *format); + int trySetFormatSingleplane(V4L2DeviceFormat *format, + unsigned long request); int getFormatMultiplane(V4L2DeviceFormat *format); - int setFormatMultiplane(V4L2DeviceFormat *format); + int trySetFormatMultiplane(V4L2DeviceFormat *format, + unsigned long request); int requestBuffers(unsigned int count); int createPlane(Buffer *buffer, unsigned int plane, diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 8366ffc4db55..2cdbc2696e55 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -434,8 +434,23 @@ int V4L2Device::getFormat(V4L2DeviceFormat *format) */ int V4L2Device::setFormat(V4L2DeviceFormat *format) { - return caps_.isMultiplanar() ? setFormatMultiplane(format) : - setFormatSingleplane(format); + return caps_.isMultiplanar() ? trySetFormatMultiplane(format, VIDIOC_S_FMT) : + trySetFormatSingleplane(format, VIDIOC_S_FMT); +} + +/** + * \brief Validate an image format on the V4L2 device + * \param[inout] format The image format to apply to the device + * + * Try the supplied \a format on the device, and return the format parameters + * that would have been applied, as \ref V4L2Device::setFormat would do. + * + * \return 0 on success or a negative error code otherwise + */ +int V4L2Device::tryFormat(V4L2DeviceFormat *format) +{ + return caps_.isMultiplanar() ? trySetFormatMultiplane(format, VIDIOC_TRY_FMT) : + trySetFormatSingleplane(format, VIDIOC_TRY_FMT); } int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *format) @@ -462,7 +477,8 @@ int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *format) return 0; } -int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format) +int V4L2Device::trySetFormatSingleplane(V4L2DeviceFormat *format, + unsigned long request) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format *pix = &v4l2Format.fmt.pix; @@ -475,7 +491,7 @@ int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format) pix->bytesperline = format->planes[0].bpl; pix->field = V4L2_FIELD_NONE; - ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(fd_, request, &v4l2Format); if (ret) { ret = -errno; LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); @@ -523,7 +539,8 @@ int V4L2Device::getFormatMultiplane(V4L2DeviceFormat *format) return 0; } -int V4L2Device::setFormatMultiplane(V4L2DeviceFormat *format) +int V4L2Device::trySetFormatMultiplane(V4L2DeviceFormat *format, + unsigned long request) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format_mplane *pix = &v4l2Format.fmt.pix_mp; @@ -541,7 +558,7 @@ int V4L2Device::setFormatMultiplane(V4L2DeviceFormat *format) pix->plane_fmt[i].sizeimage = format->planes[i].size; } - ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(fd_, request, &v4l2Format); if (ret) { ret = -errno; LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); From patchwork Thu May 23 13:58:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 1271 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DB27060DE9 for ; Thu, 23 May 2019 15:59:05 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7842CB7C; Thu, 23 May 2019 15:59:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1558619945; bh=a0eycquhtYysrCMaRms7fN5KsRROLlUE7QgcgkNOKy8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=niAbE98GzyHMBRdtnmebjFM7Oce0aCWzHD499TvWfQPiGb16JJk9IGfsDeKOKcbFb x5hvx0h4IR6ZgR0utNwjRPJ9i88dFxiJwuLEETniH8DMOTDdqEkcRK0tiiimJ0P0fS hUgC96g0f3pLYUN1GkCDYNChf+xHk0LkMMrb6rW4= From: Kieran Bingham To: LibCamera Devel Date: Thu, 23 May 2019 14:58:59 +0100 Message-Id: <20190523135900.24029-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190523135900.24029-1-kieran.bingham@ideasonboard.com> References: <20190523135900.24029-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/3] test: v4l2_device: Extend formats test with tryFromat() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 May 2019 13:59:06 -0000 Add a new test to verify the tryFormat() functionality updates the attempted format. Signed-off-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- test/v4l2_device/formats.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/v4l2_device/formats.cpp b/test/v4l2_device/formats.cpp index 6be045ff754c..1ed9901a9e4e 100644 --- a/test/v4l2_device/formats.cpp +++ b/test/v4l2_device/formats.cpp @@ -31,6 +31,22 @@ protected: return TestFail; } + format.size = { UINT_MAX, UINT_MAX }; + ret = capture_->tryFormat(&format); + if (ret) { + cerr << "Failed to try format: image resolution is invalid: " + << "(UINT_MAX x UINT_MAX) but setFormat() should not fail." + << endl; + return TestFail; + } + + if (format.size.width == UINT_MAX || + format.size.height == UINT_MAX) { + cerr << "Failed to update image (try) format = (UINT_MAX x UINT_MAX)" + << endl; + return TestFail; + } + format.size = { UINT_MAX, UINT_MAX }; ret = capture_->setFormat(&format); if (ret) { From patchwork Thu May 23 13:59:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 1272 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DB5960E4C for ; Thu, 23 May 2019 15:59:06 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BD9BDB93; Thu, 23 May 2019 15:59:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1558619945; bh=ngTtArm6h9Ki5s6nJfol2JanyMaJy0woc7tnpLqFMmU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VvTFYP7msVRyoxCgkJIcNS4TMYRu2F1WosbXpE+s6PvwLDFRVgrCZqOl4lHBRSjrv 9Gs0Z7TNRXX64bUZGWFLYL3r6gkjrZlg1Nl6coleiunpxqBYkeBn9UYE5IBMYVBivo MO2n1aVsoS7GzeAKj39iZuEhOTSY+AbEKHSjk9tk= From: Kieran Bingham To: LibCamera Devel Date: Thu, 23 May 2019 14:59:00 +0100 Message-Id: <20190523135900.24029-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190523135900.24029-1-kieran.bingham@ideasonboard.com> References: <20190523135900.24029-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/3] libcamera: pipeline: uvc: Use the device to validate formats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 May 2019 13:59:06 -0000 UVC pipelines are highly variable, and we can not define their configuration restrictions within the UVC pipeline handler directly. Update the UVCCameraConfiguration to store the UVCCameraData (storing a reference to the camera as a means of borrowing a reference to the camera data). We then validate the configuration by the tryFormat() operation on the UVC V4L2Device. Signed-off-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- src/libcamera/pipeline/uvcvideo.cpp | 36 +++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 45260f34c8f5..df321c6e64a6 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -42,9 +42,18 @@ public: class UVCCameraConfiguration : public CameraConfiguration { public: - UVCCameraConfiguration(); + UVCCameraConfiguration(Camera *camera, UVCCameraData *data); Status validate() override; + +private: + /* + * The UVCCameraConfiguration instance is guaranteed to be valid as long + * as the corresponding Camera instance is valid. In order to borrow a + * reference to the camera data, store a new reference to the camera. + */ + std::shared_ptr camera_; + const UVCCameraData *data_; }; class PipelineHandlerUVC : public PipelineHandler @@ -76,9 +85,12 @@ private: } }; -UVCCameraConfiguration::UVCCameraConfiguration() +UVCCameraConfiguration::UVCCameraConfiguration(Camera *camera, + UVCCameraData *data) : CameraConfiguration() { + camera_ = camera->shared_from_this(); + data_ = data; } CameraConfiguration::Status UVCCameraConfiguration::validate() @@ -96,17 +108,20 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() StreamConfiguration &cfg = config_[0]; - /* \todo: Validate the configuration against the device capabilities. */ - const unsigned int pixelFormat = cfg.pixelFormat; - const Size size = cfg.size; + V4L2DeviceFormat format; + format.fourcc = cfg.pixelFormat; + format.size = cfg.size; - cfg.pixelFormat = V4L2_PIX_FMT_YUYV; - cfg.size = { 640, 480 }; + /* Validate the format on the device. */ + data_->video_->tryFormat(&format); - if (cfg.pixelFormat != pixelFormat || cfg.size != size) { + if (cfg.pixelFormat != format.fourcc || cfg.size != format.size) { LOG(UVC, Debug) << "Adjusting configuration from " << cfg.toString() - << " to " << cfg.size.toString() << "-YUYV"; + << " to " << format.toString(); + + cfg.pixelFormat = format.fourcc; + cfg.size = format.size; status = Adjusted; } @@ -123,7 +138,8 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, const StreamRoles &roles) { - CameraConfiguration *config = new UVCCameraConfiguration(); + UVCCameraData *data = cameraData(camera); + CameraConfiguration *config = new UVCCameraConfiguration(camera, data); if (roles.empty()) return config;