From patchwork Mon Feb 25 12:10:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 615 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B6BEE600FB for ; Mon, 25 Feb 2019 13:10:18 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 4C6DF100008; Mon, 25 Feb 2019 12:10:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 25 Feb 2019 13:10:32 +0100 Message-Id: <20190225121037.11415-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225121037.11415-1-jacopo@jmondi.org> References: <20190225121037.11415-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/6] libcamera: v4l2_subdevice: Store media entity 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: Mon, 25 Feb 2019 12:10:18 -0000 Store the media entity backing the V4L2Subdevice and add a deviceName() method to retrieve the human readable name of the subdevice, which is created using the name of the associated media entity. Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_subdevice.h | 5 ++++- src/libcamera/v4l2_subdevice.cpp | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index 82fa6685ab52..fcfbee5af106 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -9,9 +9,10 @@ #include +#include "media_object.h" + namespace libcamera { -class MediaEntity; struct Rectangle; struct V4L2SubdeviceFormat { @@ -32,6 +33,7 @@ public: void close(); std::string deviceNode() const { return deviceNode_; } + std::string deviceName() const { return entity_->name(); } int setCrop(unsigned int pad, Rectangle *rect); int setCompose(unsigned int pad, Rectangle *rect); @@ -43,6 +45,7 @@ private: int setSelection(unsigned int pad, unsigned int target, Rectangle *rect); + const MediaEntity *entity_; std::string deviceNode_; int fd_; }; diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index b436f73cc75f..ebf87f0124cb 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -88,7 +88,7 @@ LOG_DEFINE_CATEGORY(V4L2Subdev) * path */ V4L2Subdevice::V4L2Subdevice(const MediaEntity *entity) - : deviceNode_(entity->deviceNode()), fd_(-1) + : entity_(entity), deviceNode_(entity->deviceNode()), fd_(-1) { } @@ -147,6 +147,13 @@ void V4L2Subdevice::close() * \return The subdevice's device node system path */ +/** + * \fn V4L2Subdevice::deviceName() + * \brief Retrieve the name of the media entity associated with the subdevice + * + * \return The name of the media entity the subdevice is associated to + */ + /** * \brief Set a crop rectangle on one of the V4L2 subdevice pads * \param[in] pad The 0-indexed pad number the rectangle is to be applied to From patchwork Mon Feb 25 12:10:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 616 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5E978610B3 for ; Mon, 25 Feb 2019 13:10:19 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id DD105100008; Mon, 25 Feb 2019 12:10:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 25 Feb 2019 13:10:33 +0100 Message-Id: <20190225121037.11415-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225121037.11415-1-jacopo@jmondi.org> References: <20190225121037.11415-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/6] libcamera: v4l2_subdevice: Implement ENUM_FRAME_SIZES 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: Mon, 25 Feb 2019 12:10:19 -0000 Implement enumFormat() methods to enumerate the available image resolutions on the subdevice. Signed-off-by: Jacopo Mondi --- src/libcamera/include/v4l2_subdevice.h | 8 +++ src/libcamera/v4l2_subdevice.cpp | 93 ++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index fcfbee5af106..cb033a76933c 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -7,7 +7,9 @@ #ifndef __LIBCAMERA_V4L2_SUBDEVICE_H__ #define __LIBCAMERA_V4L2_SUBDEVICE_H__ +#include #include +#include #include "media_object.h" @@ -38,16 +40,22 @@ public: int setCrop(unsigned int pad, Rectangle *rect); int setCompose(unsigned int pad, Rectangle *rect); + std::vector &formats(unsigned int pad); int getFormat(unsigned int pad, V4L2SubdeviceFormat *format); int setFormat(unsigned int pad, V4L2SubdeviceFormat *format); private: + int listPadFormats(unsigned int pad, + std::vector *formats); + void listFormats(); int setSelection(unsigned int pad, unsigned int target, Rectangle *rect); const MediaEntity *entity_; std::string deviceNode_; int fd_; + + std::map> formats_; }; } /* namespace libcamera */ diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index ebf87f0124cb..0e9c654579dc 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -5,6 +5,10 @@ * v4l2_subdevice.cpp - V4L2 Subdevice */ +#include +#include +#include + #include #include #include @@ -116,6 +120,8 @@ int V4L2Subdevice::open() } fd_ = ret; + listFormats(); + return 0; } @@ -178,6 +184,17 @@ int V4L2Subdevice::setCompose(unsigned int pad, Rectangle *rect) return setSelection(pad, V4L2_SEL_TGT_COMPOSE, rect); } +/** + * \brief List the sub-device image resolutions and formats on \a pad + * \param[in] pad The 0-indexed pad number to enumerate formats on + * + * \return A vector of image formats, or an empty vector on error + */ +std::vector &V4L2Subdevice::formats(unsigned int pad) +{ + return formats_[pad]; +} + /** * \brief Retrieve the image format set on one of the V4L2 subdevice pads * \param[in] pad The 0-indexed pad number the format is to be retrieved from @@ -242,6 +259,82 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format) return 0; } +int V4L2Subdevice::listPadFormats(unsigned int pad, + std::vector *formats) +{ + struct v4l2_subdev_frame_size_enum sizeEnum = {}; + struct v4l2_subdev_mbus_code_enum mbusEnum = {}; + int ret; + + mbusEnum.index = 0; + mbusEnum.pad = pad; + mbusEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; + + while (!(ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbusEnum))) { + sizeEnum.index = 0; + sizeEnum.code = mbusEnum.code; + sizeEnum.pad = pad; + sizeEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; + + while (!(ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, + &sizeEnum))) { + + /* Store the minimum and maximum reported sizes. */ + V4L2SubdeviceFormat minFormat = { + .mbus_code = mbusEnum.code, + .width = sizeEnum.min_width, + .height = sizeEnum.min_height, + }; + formats->push_back(minFormat); + + V4L2SubdeviceFormat maxFormat = { + .mbus_code = mbusEnum.code, + .width = sizeEnum.max_width, + .height = sizeEnum.max_height, + }; + formats->push_back(maxFormat); + + sizeEnum.index++; + } + + if (-errno != -EINVAL) { + LOG(V4L2Subdev, Error) + << "Unable to enumerate format on pad " << pad + << " of " << deviceNode_ << ": " + << strerror(-ret); + return ret; + } + + mbusEnum.index++; + } + + if (-errno != -EINVAL) { + LOG(V4L2Subdev, Error) + << "Unable to enumerate format on pad " << pad + << " of " << deviceNode_ << ": " << strerror(-ret); + return ret; + } + + return 0; +} + +void V4L2Subdevice::listFormats() +{ + int ret; + + for (MediaPad *pad : entity_->pads()) { + std::vector formats = {}; + ret = listPadFormats(pad->index(), &formats); + if (ret) { + formats = {}; + formats_[pad->index()] = formats; + continue; + } + + formats_[pad->index()] = formats; + } +} + int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, Rectangle *rect) { From patchwork Mon Feb 25 12:10:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 617 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 091A0610BF for ; Mon, 25 Feb 2019 13:10:20 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 86ED4100010; Mon, 25 Feb 2019 12:10:19 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 25 Feb 2019 13:10:34 +0100 Message-Id: <20190225121037.11415-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225121037.11415-1-jacopo@jmondi.org> References: <20190225121037.11415-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/6] libcamera: v4l2_device: Add support for META_CAPTURE devices 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: Mon, 25 Feb 2019 12:10:21 -0000 Add support for devices that provide video meta-data to v4l2_device.cpp and re-arrange bufferType handling in open() method. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/libcamera/include/v4l2_device.h | 4 +++ src/libcamera/v4l2_device.cpp | 38 +++++++++++++++++------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 1d31d1b403bc..52eb6785cc15 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -53,6 +53,10 @@ struct V4L2Capability final : v4l2_capability { return device_caps() & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE); } + bool isMeta() const + { + return device_caps() & V4L2_CAP_META_CAPTURE; + } bool isOutput() const { return device_caps() & (V4L2_CAP_VIDEO_OUTPUT | diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 24e115554a99..8be8af7a2893 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -79,6 +79,15 @@ LOG_DEFINE_CATEGORY(V4L2) * \return True if the device can output video frames */ +/** + * \fn bool V4L2Capability::isMeta() + * \brief Identify if the device is capable of providing video meta-data + * + * FIXME: add support for META_OUTPUT, introduced in Linux v4.20 + * + * \return True if the device can provide video meta-data + */ + /** * \fn bool V4L2Capability::hasStreaming() * \brief Determine if the device can perform Streaming I/O @@ -280,33 +289,32 @@ int V4L2Device::open() << "Opened device " << caps_.bus_info() << ": " << caps_.driver() << ": " << caps_.card(); - if (!caps_.isCapture() && !caps_.isOutput()) { - LOG(V4L2, Debug) << "Device is not a supported type"; - return -EINVAL; - } - if (!caps_.hasStreaming()) { LOG(V4L2, Error) << "Device does not support streaming I/O"; return -EINVAL; } - if (caps_.isCapture()) + /* + * Set buffer type and wait for read notifications on CAPTURE devices + * (POLLIN), and write notifications for OUTPUT devices (POLLOUT). + */ + if (caps_.isCapture()) { + fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); bufferType_ = caps_.isMultiplanar() ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE; - else + } else if (caps_.isOutput()) { + fdEvent_ = new EventNotifier(fd_, EventNotifier::Write); bufferType_ = caps_.isMultiplanar() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT; - - /* - * We wait for Read notifications on CAPTURE devices (POLLIN), and - * Write notifications for OUTPUT devices (POLLOUT). - */ - if (caps_.isCapture()) + } else if (caps_.isMeta()) { fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); - else - fdEvent_ = new EventNotifier(fd_, EventNotifier::Write); + bufferType_ = V4L2_BUF_TYPE_META_CAPTURE; + } else { + LOG(V4L2, Debug) << "Device is not a supported type"; + return -EINVAL; + } fdEvent_->activated.connect(this, &V4L2Device::bufferAvailable); fdEvent_->setEnabled(false); From patchwork Mon Feb 25 12:10:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 618 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 92D30600FB for ; Mon, 25 Feb 2019 13:10:20 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 29E8F100008; Mon, 25 Feb 2019 12:10:19 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 25 Feb 2019 13:10:35 +0100 Message-Id: <20190225121037.11415-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225121037.11415-1-jacopo@jmondi.org> References: <20190225121037.11415-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/6] test: v4l2_subdevice: Add format handling test 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: Mon, 25 Feb 2019 12:10:21 -0000 Add test for video format get and set operations on V4L2Subdevice class. Signed-off-by: Jacopo Mondi --- test/meson.build | 1 + test/v4l2_subdevice/meson.build | 10 +++ test/v4l2_subdevice/test_formats.cpp | 79 ++++++++++++++++++ test/v4l2_subdevice/v4l2_subdevice_test.cpp | 90 +++++++++++++++++++++ test/v4l2_subdevice/v4l2_subdevice_test.h | 36 +++++++++ 5 files changed, 216 insertions(+) create mode 100644 test/v4l2_subdevice/meson.build create mode 100644 test/v4l2_subdevice/test_formats.cpp create mode 100644 test/v4l2_subdevice/v4l2_subdevice_test.cpp create mode 100644 test/v4l2_subdevice/v4l2_subdevice_test.h diff --git a/test/meson.build b/test/meson.build index d515a716207e..5fb16fa6afb6 100644 --- a/test/meson.build +++ b/test/meson.build @@ -3,6 +3,7 @@ subdir('libtest') subdir('media_device') subdir('pipeline') subdir('v4l2_device') +subdir('v4l2_subdevice') public_tests = [ ['event', 'event.cpp'], diff --git a/test/v4l2_subdevice/meson.build b/test/v4l2_subdevice/meson.build new file mode 100644 index 000000000000..a4359fe1bc19 --- /dev/null +++ b/test/v4l2_subdevice/meson.build @@ -0,0 +1,10 @@ +v4l2_subdevice_tests = [ + [ 'test_formats', 'test_formats.cpp'], +] + +foreach t : v4l2_subdevice_tests + exe = executable(t[0], [t[1], 'v4l2_subdevice_test.cpp'], + link_with : test_libraries, + include_directories : test_includes_internal) + test(t[0], exe, suite: 'v4l2_subdevice', is_parallel: false) +endforeach diff --git a/test/v4l2_subdevice/test_formats.cpp b/test/v4l2_subdevice/test_formats.cpp new file mode 100644 index 000000000000..91b460f64e7e --- /dev/null +++ b/test/v4l2_subdevice/test_formats.cpp @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 Subdevice format handling test + */ + +#include +#include + +#include "v4l2_subdevice.h" + +#include "v4l2_subdevice_test.h" + +using namespace std; +using namespace libcamera; + +/* Test format handling on the "Scaler" subdevice of vimc media device. */ + +class FormatHandlingTest : public V4L2SubdeviceTest +{ +protected: + int run(); +}; + +int FormatHandlingTest::run() +{ + V4L2SubdeviceFormat format = {}; + + /* + * Get format on a non-existing Scaler pad: expect failure. + */ + int ret = scaler_->getFormat(2, &format); + if (!ret) { + cerr << "Get format on a non existing pad should fail" << endl; + return TestFail; + } + + ret = scaler_->getFormat(0, &format); + if (ret) { + cerr << "Failed to get format" << endl; + return TestFail; + } + + /* + * Set unrealistic image resolutions and make sure it gets updated. + */ + format.width = UINT_MAX; + format.height = UINT_MAX; + ret = scaler_->setFormat(0, &format); + if (ret) { + cerr << "Failed to set format: image resolution is wrong, but " + << "setFormat() should not fail." << endl; + return TestFail; + } + + if (format.width == UINT_MAX || format.height == UINT_MAX) { + cerr << "Failed to update image format" << endl; + return TestFail; + } + + format.width = 0; + format.height = 0; + ret = scaler_->setFormat(0, &format); + if (ret) { + cerr << "Failed to set format: image resolution is wrong, but " + << "setFormat() should not fail." << endl; + return TestFail; + } + + if (format.width == 0 || format.height == 0) { + cerr << "Failed to update image format" << endl; + return TestFail; + } + + return TestPass; +} + +TEST_REGISTER(FormatHandlingTest); diff --git a/test/v4l2_subdevice/v4l2_subdevice_test.cpp b/test/v4l2_subdevice/v4l2_subdevice_test.cpp new file mode 100644 index 000000000000..10fe2655e5e4 --- /dev/null +++ b/test/v4l2_subdevice/v4l2_subdevice_test.cpp @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * v4l2_subdevice_test.cpp - V4L2 subdevice test + */ + +#include +#include +#include + +#include "device_enumerator.h" +#include "media_device.h" +#include "v4l2_subdevice.h" + +#include "v4l2_subdevice_test.h" + +using namespace std; +using namespace libcamera; + +/* + * This test runs on vimc media device. For a description of vimc, in the + * context of libcamera testingrefer to + * 'test/media_device/media_device_link_test.cpp' file. + * + * If the vimc module is not loaded, the test gets skipped. + */ + +int V4L2SubdeviceTest::init() +{ + enumerator_ = DeviceEnumerator::create(); + if (!enumerator_) { + cerr << "Failed to create device enumerator" << endl; + return TestFail; + } + + if (enumerator_->enumerate()) { + cerr << "Failed to enumerate media devices" << endl; + return TestFail; + } + + DeviceMatch dm("vimc"); + media_ = std::move(enumerator_->search(dm)); + if (!media_) { + cerr << "Unable to find \'vimc\' media device node" << endl; + return TestSkip; + } + + media_->acquire(); + + int ret = media_->open(); + if (ret) { + cerr << "Unable to open media device: " << media_->deviceNode() + << ": " << strerror(ret) << endl; + media_->release(); + return TestSkip; + } + + MediaEntity *videoEntity = media_->getEntityByName("Scaler"); + if (!videoEntity) { + cerr << "Unable to find media entity 'Scaler'" << endl; + media_->release(); + return TestSkip; + } + + scaler_ = new V4L2Subdevice(videoEntity); + if (!scaler_) { + cerr << "Unable to create media device from media entity: " + << videoEntity->deviceNode(); + media_->release(); + return TestSkip; + } + + ret = scaler_->open(); + if (ret) { + cerr << "Unable to open video subdevice " + << scaler_->deviceNode() << endl; + media_->release(); + return TestSkip; + } + + return 0; +} + +void V4L2SubdeviceTest::cleanup() +{ + media_->release(); + + delete scaler_; +} diff --git a/test/v4l2_subdevice/v4l2_subdevice_test.h b/test/v4l2_subdevice/v4l2_subdevice_test.h new file mode 100644 index 000000000000..7b64c6122745 --- /dev/null +++ b/test/v4l2_subdevice/v4l2_subdevice_test.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * v4l2_subdevice_test.h - V4L2 subdevice test + */ + +#ifndef __LIBCAMERA_V4L2_SUBDEVICE_TEST_H_ +#define __LIBCAMERA_V4L2_SUBDEVICE_TEST_H_ + +#include + +#include "device_enumerator.h" +#include "media_device.h" +#include "test.h" +#include "v4l2_subdevice.h" + +using namespace libcamera; + +class V4L2SubdeviceTest : public Test +{ +public: + V4L2SubdeviceTest() + : scaler_(nullptr){}; + +protected: + int init(); + virtual int run() = 0; + void cleanup(); + + std::unique_ptr enumerator_; + std::shared_ptr media_; + V4L2Subdevice *scaler_; +}; + +#endif /* __LIBCAMERA_V4L2_SUBDEVICE_TEST_H_ */ From patchwork Mon Feb 25 12:10:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 619 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3CCDA600FB for ; Mon, 25 Feb 2019 13:10:21 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id BF81F100008; Mon, 25 Feb 2019 12:10:20 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 25 Feb 2019 13:10:36 +0100 Message-Id: <20190225121037.11415-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225121037.11415-1-jacopo@jmondi.org> References: <20190225121037.11415-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 5/6] test: v4l2_subdevice: Add ListFormat test 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: Mon, 25 Feb 2019 12:10:21 -0000 Add test to list formats on a v4l2 subdevice. Signed-off-by: Jacopo Mondi --- test/v4l2_subdevice/list_formats.cpp | 76 ++++++++++++++++++++++++++++ test/v4l2_subdevice/meson.build | 1 + 2 files changed, 77 insertions(+) create mode 100644 test/v4l2_subdevice/list_formats.cpp diff --git a/test/v4l2_subdevice/list_formats.cpp b/test/v4l2_subdevice/list_formats.cpp new file mode 100644 index 000000000000..a726b11df5f9 --- /dev/null +++ b/test/v4l2_subdevice/list_formats.cpp @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 Subdevice format handling test + */ + +#include +#include + +#include "v4l2_subdevice.h" + +#include "v4l2_subdevice_test.h" + +using namespace std; +using namespace libcamera; + +/* List image formats on the "Scaler" subdevice of vimc media device. */ + +class ListFormatsTest : public V4L2SubdeviceTest +{ +protected: + int run(); + +private: + void printFormats(unsigned int pad, + std::vector &formats); +}; + +void ListFormatsTest::printFormats(unsigned int pad, + std::vector &formats) +{ + cout << "Enumerate formats on pad " << pad << endl; + for (V4L2SubdeviceFormat &format : formats) { + cout << " Mbus code: 0x" << hex << format.mbus_code << endl; + cout << " Width: " << dec << format.width << endl; + cout << " Height: " << dec << format.height << endl; + } +} + +int ListFormatsTest::run() +{ + /* List all formats available on existing "Scaler" pads. */ + std::vector formats = {}; + + formats = scaler_->formats(0); + if (formats.empty()) { + cerr << "Failed to list formats on pad 0 of sudevice " + << scaler_->deviceNode() << endl; + return TestFail; + } + printFormats(0, formats); + + formats = {}; + formats = scaler_->formats(1); + if (formats.empty()) { + cerr << "Failed to list formats on pad 1 of sudevice " + << scaler_->deviceNode() << endl; + return TestFail; + } + printFormats(1, formats); + + /* List format on a non-existing pad, format vector shall be empty. */ + formats = {}; + formats = scaler_->formats(2); + if (!formats.empty()) { + cerr << "Listing formats on non-existing pad 2 of subdevice " + << scaler_->deviceNode() + <<" should return an empty format list" << endl; + return TestFail; + } + + return TestPass; +} + +TEST_REGISTER(ListFormatsTest); diff --git a/test/v4l2_subdevice/meson.build b/test/v4l2_subdevice/meson.build index a4359fe1bc19..6023d15e1558 100644 --- a/test/v4l2_subdevice/meson.build +++ b/test/v4l2_subdevice/meson.build @@ -1,4 +1,5 @@ v4l2_subdevice_tests = [ + [ 'list_formats', 'list_formats.cpp'], [ 'test_formats', 'test_formats.cpp'], ] From patchwork Mon Feb 25 12:10:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 620 Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C90CA610C9 for ; Mon, 25 Feb 2019 13:10:21 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 57269100008; Mon, 25 Feb 2019 12:10:21 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 25 Feb 2019 13:10:37 +0100 Message-Id: <20190225121037.11415-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225121037.11415-1-jacopo@jmondi.org> References: <20190225121037.11415-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/6] test: v4l2_device: Add format handling test 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: Mon, 25 Feb 2019 12:10:22 -0000 Add test for V4L2Device set and get format methods. Signed-off-by: Jacopo Mondi --- test/v4l2_device/meson.build | 1 + test/v4l2_device/test_formats.cpp | 65 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 test/v4l2_device/test_formats.cpp diff --git a/test/v4l2_device/meson.build b/test/v4l2_device/meson.build index 9f7a7545ac9b..e5e50faac282 100644 --- a/test/v4l2_device/meson.build +++ b/test/v4l2_device/meson.build @@ -6,6 +6,7 @@ v4l2_device_tests = [ [ 'stream_on_off', 'stream_on_off.cpp' ], [ 'capture_async', 'capture_async.cpp' ], [ 'buffer_sharing', 'buffer_sharing.cpp' ], + [ 'test_formats', 'test_formats.cpp' ], ] foreach t : v4l2_device_tests diff --git a/test/v4l2_device/test_formats.cpp b/test/v4l2_device/test_formats.cpp new file mode 100644 index 000000000000..dcb05a3904f7 --- /dev/null +++ b/test/v4l2_device/test_formats.cpp @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 device format handling test + */ + +#include +#include + +#include "v4l2_device.h" + +#include "v4l2_device_test.h" + +using namespace std; +using namespace libcamera; + +class Format : public V4L2DeviceTest +{ +protected: + int run(); +}; + +int Format::run() +{ + V4L2DeviceFormat format = {}; + + int ret = capture_->getFormat(&format); + if (ret) { + cerr << "Failed to get format" << endl; + return TestFail; + } + + format.width = UINT_MAX; + format.height = UINT_MAX; + ret = capture_->setFormat(&format); + if (ret) { + cerr << "Failed to set format: image resolution is wrong, but " + << "setFormat() should not fail." << endl; + return TestFail; + } + + if (format.width == UINT_MAX || format.height == UINT_MAX) { + cerr << "Failed to update image format" << endl; + return TestFail; + } + + format.width = 0; + format.height = 0; + ret = capture_->setFormat(&format); + if (ret) { + cerr << "Failed to set format: image resolution is wrong, but " + << "setFormat() should not fail." << endl; + return TestFail; + } + + if (format.width == 0 || format.height == 0) { + cerr << "Failed to update image format" << endl; + return TestFail; + } + + return TestPass; +} + +TEST_REGISTER(Format);