From patchwork Thu Feb 7 21:21:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 544 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 5667A610B3 for ; Thu, 7 Feb 2019 22:21:28 +0100 (CET) Received: from localhost.localdomain (unknown [149.254.234.206]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 76F62567; Thu, 7 Feb 2019 22:21:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549574488; bh=Kx2RrxQC4y3ZhPm8fExrDxplTK4s45n0LOOgSqbgMjs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EobfsUHaIdl9dJMxpN9p+buXQBqrw9N7K3M/xv7+H7s1Ffnqt6k5ebOCZvWIE3WTs PJLP5+jM/s7KQvlR2FWXuqjSZmTQ4lGLECRYoBOAhYVz9eAY/lEPV1dIwVz16+1Ve0 BwGj2wDd/boUjWha/Y1EztuYp2+uN7HgheAs7zgg= From: Kieran Bingham To: LibCamera Devel Date: Thu, 7 Feb 2019 21:21:15 +0000 Message-Id: <20190207212119.30299-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> References: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/5] libcamera: media_device: Provide the default 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: Thu, 07 Feb 2019 21:21:28 -0000 Add a helper to identify the default entity from a media device. Utilise it in the two places which iterate the entities manually, to allocated a V4L2Device from the default entity. Signed-off-by: Kieran Bingham --- src/libcamera/include/media_device.h | 1 + src/libcamera/media_device.cpp | 15 +++++++++++++++ src/libcamera/pipeline/uvcvideo.cpp | 10 ++++------ test/v4l2_device/v4l2_device_test.cpp | 12 +++++------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h index 9f038093b2b2..361e8f4a4b86 100644 --- a/src/libcamera/include/media_device.h +++ b/src/libcamera/include/media_device.h @@ -42,6 +42,7 @@ public: const std::vector &entities() const { return entities_; } MediaEntity *getEntityByName(const std::string &name) const; + MediaEntity *defaultEntity() const; MediaLink *link(const std::string &sourceName, unsigned int sourceIdx, const std::string &sinkName, unsigned int sinkIdx); diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index 800ed330fe6d..4af90e1590a1 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -319,6 +319,21 @@ MediaEntity *MediaDevice::getEntityByName(const std::string &name) const return nullptr; } +/** + * \brief Return the default MediaEntity within a MediaDevice + * \return The default entity if specified, or a nullptr otherwise + */ +MediaEntity *MediaDevice::defaultEntity() const +{ + for (MediaEntity *entity : entities_) { + if (entity->flags() & MEDIA_ENT_FL_DEFAULT) { + return entity; + } + } + + return nullptr; +} + /** * \brief Retrieve the MediaLink connecting two pads, identified by entity * names and pad indexes diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index fc31c52c0ecd..ed8228bb2fc6 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -146,13 +146,11 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) media_->acquire(); - for (MediaEntity *entity : media_->entities()) { - if (entity->flags() & MEDIA_ENT_FL_DEFAULT) { - video_ = new V4L2Device(entity); - break; - } - } + MediaEntity *entity = media_->defaultEntity(); + if (!entity) + return false; + video_ = new V4L2Device(entity); if (!video_ || video_->open()) { if (!video_) LOG(UVC, Error) << "Could not find a default video device"; diff --git a/test/v4l2_device/v4l2_device_test.cpp b/test/v4l2_device/v4l2_device_test.cpp index 18d014caf4c8..dd28cccada6b 100644 --- a/test/v4l2_device/v4l2_device_test.cpp +++ b/test/v4l2_device/v4l2_device_test.cpp @@ -46,15 +46,13 @@ int V4L2DeviceTest::init() media_->acquire(); - for (MediaEntity *entity : media_->entities()) { - if (entity->flags() & MEDIA_ENT_FL_DEFAULT) { - dev_ = new V4L2Device(entity); - break; - } - } + MediaEntity *entity = media_->defaultEntity(); + if (!entity) + return TestFail; + dev_ = new V4L2Device(entity); if (!dev_) - return TestSkip; + return TestFail; return dev_->open(); } From patchwork Thu Feb 7 21:21:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 545 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8665E610B2 for ; Thu, 7 Feb 2019 22:21:29 +0100 (CET) Received: from localhost.localdomain (unknown [149.254.234.206]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 73D7DF9; Thu, 7 Feb 2019 22:21:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549574489; bh=qZWhhbD8CZDP5thj16LSwckC4h6VnN9+WbOXIs/ZKqA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lNgrc/UZv539RHyA/lJdrG7NShksWeOM6ZSe7de5GxpPuTBpcrUtzJ5TcdOaA+xPM sCb87pMzGpYg/jQ7dpTDu4evpVIipzc4wkVlLbml9pscPULRfblW+wnLFa2b82JgLa KMGXHIlZiyAK61TXxo/X0QgHsdHIpME1ioN6mgd0= From: Kieran Bingham To: LibCamera Devel Date: Thu, 7 Feb 2019 21:21:16 +0000 Message-Id: <20190207212119.30299-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> References: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/5] libcamera: v4l2_device: importBuffers 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, 07 Feb 2019 21:21:29 -0000 Provide the ability to import a BufferPool into the V4L2Device allowing external dmabuf backed buffers to be queued. Signed-off-by: Kieran Bingham --- src/libcamera/include/v4l2_device.h | 1 + src/libcamera/v4l2_device.cpp | 45 ++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 988e646c5de1..3acb5e466d64 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -98,6 +98,7 @@ public: int setFormat(V4L2DeviceFormat *format); int exportBuffers(unsigned int count, BufferPool *pool); + int importBuffers(BufferPool *pool); int releaseBuffers(); int queueBuffer(Buffer *buffer); diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 64325ff9f5d9..c654e6dd7b8d 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -633,6 +633,36 @@ int V4L2Device::createPlane(Buffer *buffer, unsigned int planeIndex, return 0; } +/** + * \brief Import the externally allocated \a pool of buffers + * \param[in] pool BufferPool of buffers to import + * \return 0 on success or a negative error code otherwise + */ +int V4L2Device::importBuffers(BufferPool *pool) +{ + unsigned int allocatedBuffers; + int ret; + + memoryType_ = V4L2_MEMORY_DMABUF; + + ret = requestBuffers(pool->count()); + if (ret < 0) + return ret; + + allocatedBuffers = ret; + if (allocatedBuffers < pool->count()) { + LOG(V4L2, Error) + << "Not enough buffers provided by V4L2Device"; + requestBuffers(0); + return -ENOMEM; + } + + LOG(V4L2, Debug) << "Device using an externally provided pool"; + bufferPool_ = pool; + + return 0; +} + /** * \brief Release all internally allocated buffers */ @@ -670,7 +700,20 @@ int V4L2Device::queueBuffer(Buffer *buffer) buf.type = bufferType_; buf.memory = memoryType_; - if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) { + bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type); + + if (buf.memory == V4L2_MEMORY_DMABUF) { + if (multiPlanar) { + for (unsigned int p = 0; + p < buffer->planes().size(); + p++) + planes[p].m.fd = buffer->planes()[p].dmabuf(); + } else { + buf.m.fd = buffer->planes()[0].dmabuf(); + } + } + + if (multiPlanar) { buf.length = buffer->planes().size(); buf.m.planes = planes; } From patchwork Thu Feb 7 21:21:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 546 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 8130E610B2 for ; Thu, 7 Feb 2019 22:21:30 +0100 (CET) Received: from localhost.localdomain (unknown [149.254.234.206]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 72FDB567; Thu, 7 Feb 2019 22:21:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549574490; bh=uM0dtpORdwrd7i/94nuuDpNb15N8o0D51ie8gmna0pg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oTBKr4f4A/gckaIgSUPxKjDThoxkeUv0sflqOjdgmZgava+cn13o4wfpfdXvJX6jI 7Avnoo7cFXp0YV0j4pmTnAgOqT/33zyPGFnrY0m7vLJSp2/tFZZ6IBwXRVFNMNJrw6 kjMeqUMYy1HU5sTNqYY5456SEEMubVDdv8USlwPY= From: Kieran Bingham To: LibCamera Devel Date: Thu, 7 Feb 2019 21:21:17 +0000 Message-Id: <20190207212119.30299-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> References: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/5] test: v4l2_device: Provide buffer sharing 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: Thu, 07 Feb 2019 21:21:30 -0000 Obtain two V4L2Devices and use one to obtain a BufferPool. Propogate the formats from the first to the second device and then commence sending buffers between the two devices in a ping-pong fashion. Signed-off-by: Kieran Bingham --- test/v4l2_device/buffer_sharing.cpp | 178 ++++++++++++++++++++++++++++ test/v4l2_device/meson.build | 1 + 2 files changed, 179 insertions(+) create mode 100644 test/v4l2_device/buffer_sharing.cpp diff --git a/test/v4l2_device/buffer_sharing.cpp b/test/v4l2_device/buffer_sharing.cpp new file mode 100644 index 000000000000..0e96f7b894bd --- /dev/null +++ b/test/v4l2_device/buffer_sharing.cpp @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 API tests + */ + +#include + +#include +#include +#include +#include + +#include "v4l2_device_test.h" + +#include "log.h" + +LOG_DEFINE_CATEGORY(Test) + +class BufferSharingTest : public V4L2DeviceTest +{ +public: + BufferSharingTest() + : output_(nullptr), framesCapture(0), framesOutput(0){}; + +private: + const unsigned int bufferCount = 4; + + V4L2Device *output_; + std::shared_ptr secondMedia_; + + unsigned int framesCapture; + unsigned int framesOutput; + +protected: + int init() + { + int ret = V4L2DeviceTest::init(); + if (ret) + return ret; + + DeviceMatch uvcvideo("uvcvideo"); + uvcvideo.add("Logitech BRIO"); + + secondMedia_ = std::move(enumerator_->search(uvcvideo)); + if (!secondMedia_) { + LOG(Test, Info) << "No Brio found"; + return TestSkip; + } + + secondMedia_->acquire(); + + MediaEntity *entity = secondMedia_->defaultEntity(); + if (!entity) + return TestFail; + + output_ = new V4L2Device(entity); + if (!output_) + return TestFail; + + ret = output_->open(); + if (ret) + return TestFail; + + V4L2DeviceFormat format; + + ret = dev_->getFormat(&format); + if (ret) { + return TestFail; + } + + LOG(Test, Info) << "Successfully obtained format from source"; + + ret = output_->setFormat(&format); + if (ret) + return TestFail; + + LOG(Test, Info) << "Successfully set format to output"; + + pool_.createBuffers(bufferCount); + + ret = dev_->exportBuffers(bufferCount, &pool_); + if (ret) + return TestFail; + + ret = output_->importBuffers(&pool_); + if (ret) { + std::cerr << "Failed to import buffers" << std::endl; + return TestFail; + } + + return 0; + } + + void receiveSourceBuffer(Buffer *buffer) + { + std::cout << "Received source buffer: " << buffer->index() + << " sequence " << buffer->sequence() << std::endl; + + output_->queueBuffer(buffer); + framesCapture++; + } + + void receiveDestinationBuffer(Buffer *buffer) + { + std::cout << "Received destination buffer: " << buffer->index() + << " sequence " << buffer->sequence() << std::endl; + + dev_->queueBuffer(buffer); + framesOutput++; + } + + int run() + { + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); + Timer timeout; + int ret; + + dev_->bufferReady.connect(this, &BufferSharingTest::receiveSourceBuffer); + output_->bufferReady.connect(this, &BufferSharingTest::receiveDestinationBuffer); + + /* Queue all the buffers to the device. */ + for (Buffer &b : pool_.buffers()) { + if (dev_->queueBuffer(&b)) + return TestFail; + } + + ret = dev_->streamOn(); + if (ret) + return TestFail; + + ret = output_->streamOn(); + if (ret) + return TestFail; + + timeout.start(5000); + while (timeout.isRunning()) + dispatcher->processEvents(); + + if ((framesCapture < 1) || (framesOutput < 1)) { + std::cout << "Failed to process any frames within timeout." << std::endl; + return TestFail; + } + + if ((framesCapture < 30) || (framesOutput < 30)) { + std::cout << "Failed to process 30 frames within timeout." << std::endl; + return TestFail; + } + + std::cout + << "Processed " << framesCapture << " capture frames" + << " and " << framesOutput << " output frames" + << std::endl; + + ret = dev_->streamOff(); + if (ret) + return TestFail; + + ret = output_->streamOff(); + if (ret) + return TestFail; + + return TestPass; + } + + void cleanup() + { + if (secondMedia_) + secondMedia_->release(); + + delete output_; + + V4L2DeviceTest::cleanup(); + } +}; + +TEST_REGISTER(BufferSharingTest); diff --git a/test/v4l2_device/meson.build b/test/v4l2_device/meson.build index ec2c7f9f11ff..9f7a7545ac9b 100644 --- a/test/v4l2_device/meson.build +++ b/test/v4l2_device/meson.build @@ -5,6 +5,7 @@ v4l2_device_tests = [ [ 'request_buffers', 'request_buffers.cpp' ], [ 'stream_on_off', 'stream_on_off.cpp' ], [ 'capture_async', 'capture_async.cpp' ], + [ 'buffer_sharing', 'buffer_sharing.cpp' ], ] foreach t : v4l2_device_tests From patchwork Thu Feb 7 21:21:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 547 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F0C7E610B2 for ; Thu, 7 Feb 2019 22:21:32 +0100 (CET) Received: from localhost.localdomain (unknown [149.254.234.206]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 909D1F9; Thu, 7 Feb 2019 22:21:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549574492; bh=n2ZfEbMbZsPjWwZOX5Vw16iOoWiFMo9ApdnPsIvxsY0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TxUQcG6npLyq1bDbGzuwN4T3f9skko27XSrcjzz+OzJkvemTYDuCJFFxT7p0J4pa3 Rmx+eAfVDLc84hj28xTYOjMcwzaUVJerBMsbiYJpydBHipgHM5QXZQJSH3tmMiFcre OPtDyGj4V6GjyxFb+RnjSD/S76K8mYzMp0Ike6Dw= From: Kieran Bingham To: LibCamera Devel Date: Thu, 7 Feb 2019 21:21:18 +0000 Message-Id: <20190207212119.30299-5-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> References: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/5] libcamera: v4l2_device: Simplify exportBuffers() 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, 07 Feb 2019 21:21:33 -0000 exportBuffers() can only operate on an existing BufferPool allocation. The pool identifies its size through its .count() method. Passing a count in to the exportBuffers() call is redundant and can be incorrect if the value is not the same as the BufferPool size. Simplify the function and remove the unnecessary argument, correcting all uses throughout the code base. While we're here, remove the createBuffers() helper from the V4L2DeviceTest which only served to obfuscate which pool the buffers were being allocated for. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- src/libcamera/include/v4l2_device.h | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 3 +-- src/libcamera/pipeline/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 2 +- src/libcamera/v4l2_device.cpp | 15 ++++++--------- test/v4l2_device/buffer_sharing.cpp | 2 +- test/v4l2_device/capture_async.cpp | 4 ++-- test/v4l2_device/request_buffers.cpp | 4 ++-- test/v4l2_device/stream_on_off.cpp | 4 ++-- test/v4l2_device/v4l2_device_test.h | 2 -- 10 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 3acb5e466d64..98fa2110efb5 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -97,7 +97,7 @@ public: int getFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format); - int exportBuffers(unsigned int count, BufferPool *pool); + int exportBuffers(BufferPool *pool); int importBuffers(BufferPool *pool); int releaseBuffers(); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 34b03995ae31..677e127dd738 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -191,8 +191,7 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) if (!cfg.bufferCount) return -EINVAL; - int ret = data->cio2_->exportBuffers(cfg.bufferCount, - &stream->bufferPool()); + int ret = data->cio2_->exportBuffers(&stream->bufferPool()); if (ret) { LOG(IPU3, Error) << "Failed to request memory"; return ret; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index ed8228bb2fc6..1a0dcb582670 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -102,7 +102,7 @@ int PipelineHandlerUVC::allocateBuffers(Camera *camera, Stream *stream) LOG(UVC, Debug) << "Requesting " << cfg.bufferCount << " buffers"; - return video_->exportBuffers(cfg.bufferCount, &stream->bufferPool()); + return video_->exportBuffers(&stream->bufferPool()); } int PipelineHandlerUVC::freeBuffers(Camera *camera, Stream *stream) diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 0e9ad7b59ee5..06627b1cb847 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -101,7 +101,7 @@ int PipeHandlerVimc::allocateBuffers(Camera *camera, Stream *stream) LOG(VIMC, Debug) << "Requesting " << cfg.bufferCount << " buffers"; - return video_->exportBuffers(cfg.bufferCount, &stream->bufferPool()); + return video_->exportBuffers(&stream->bufferPool()); } int PipeHandlerVimc::freeBuffers(Camera *camera, Stream *stream) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index c654e6dd7b8d..c2e4d0ea8db2 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -526,13 +526,12 @@ int V4L2Device::requestBuffers(unsigned int count) } /** - * \brief Request \a count buffers to be allocated from the device and stored in - * the buffer pool provided. - * \param[in] count Number of buffers to allocate + * \brief Request buffers to be allocated from the device and stored in the + * buffer pool provided. * \param[out] pool BufferPool to populate with buffers * \return 0 on success or a negative error code otherwise */ -int V4L2Device::exportBuffers(unsigned int count, BufferPool *pool) +int V4L2Device::exportBuffers(BufferPool *pool) { unsigned int allocatedBuffers; unsigned int i; @@ -540,21 +539,19 @@ int V4L2Device::exportBuffers(unsigned int count, BufferPool *pool) memoryType_ = V4L2_MEMORY_MMAP; - ret = requestBuffers(count); + ret = requestBuffers(pool->count()); if (ret < 0) return ret; allocatedBuffers = ret; - if (allocatedBuffers < count) { + if (allocatedBuffers < pool->count()) { LOG(V4L2, Error) << "Not enough buffers provided by V4L2Device"; requestBuffers(0); return -ENOMEM; } - count = ret; - /* Map the buffers. */ - for (i = 0; i < count; ++i) { + for (i = 0; i < pool->count(); ++i) { struct v4l2_plane planes[VIDEO_MAX_PLANES] = {}; struct v4l2_buffer buf = {}; struct Buffer &buffer = pool->buffers()[i]; diff --git a/test/v4l2_device/buffer_sharing.cpp b/test/v4l2_device/buffer_sharing.cpp index 0e96f7b894bd..ca086f2728f1 100644 --- a/test/v4l2_device/buffer_sharing.cpp +++ b/test/v4l2_device/buffer_sharing.cpp @@ -80,7 +80,7 @@ protected: pool_.createBuffers(bufferCount); - ret = dev_->exportBuffers(bufferCount, &pool_); + ret = dev_->exportBuffers(&pool_); if (ret) return TestFail; diff --git a/test/v4l2_device/capture_async.cpp b/test/v4l2_device/capture_async.cpp index 7a0735f65535..d3e20ed86b98 100644 --- a/test/v4l2_device/capture_async.cpp +++ b/test/v4l2_device/capture_async.cpp @@ -38,9 +38,9 @@ protected: Timer timeout; int ret; - createBuffers(bufferCount); + pool_.createBuffers(bufferCount); - ret = dev_->exportBuffers(bufferCount, &pool_); + ret = dev_->exportBuffers(&pool_); if (ret) return TestFail; diff --git a/test/v4l2_device/request_buffers.cpp b/test/v4l2_device/request_buffers.cpp index bc6ff2c18a57..26d7d9528982 100644 --- a/test/v4l2_device/request_buffers.cpp +++ b/test/v4l2_device/request_buffers.cpp @@ -19,9 +19,9 @@ protected: */ const unsigned int bufferCount = 8; - createBuffers(bufferCount); + pool_.createBuffers(bufferCount); - int ret = dev_->exportBuffers(bufferCount, &pool_); + int ret = dev_->exportBuffers(&pool_); if (ret) return TestFail; diff --git a/test/v4l2_device/stream_on_off.cpp b/test/v4l2_device/stream_on_off.cpp index b564d2a2ab67..861d8d695813 100644 --- a/test/v4l2_device/stream_on_off.cpp +++ b/test/v4l2_device/stream_on_off.cpp @@ -14,9 +14,9 @@ protected: { const unsigned int bufferCount = 8; - createBuffers(bufferCount); + pool_.createBuffers(bufferCount); - int ret = dev_->exportBuffers(bufferCount, &pool_); + int ret = dev_->exportBuffers(&pool_); if (ret) return TestFail; diff --git a/test/v4l2_device/v4l2_device_test.h b/test/v4l2_device/v4l2_device_test.h index f22f0bb555d8..43539655f85b 100644 --- a/test/v4l2_device/v4l2_device_test.h +++ b/test/v4l2_device/v4l2_device_test.h @@ -24,8 +24,6 @@ class V4L2DeviceTest : public Test public: V4L2DeviceTest() : dev_(nullptr){}; - void createBuffers(unsigned int qty) { pool_.createBuffers(qty); } - protected: int init(); void cleanup(); From patchwork Thu Feb 7 21:21:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 548 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 008CB610B3 for ; Thu, 7 Feb 2019 22:21:37 +0100 (CET) Received: from localhost.localdomain (unknown [149.254.234.206]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0E757F9; Thu, 7 Feb 2019 22:21:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549574496; bh=ndQnb27rLBCb/+/ucf16XyMpMw3lAxY30gT4Ygqhu3I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mnKpXyz17CfLcB5rh94M8f7i18dP2ADZDkFUS2APMHZu6/c6389yMIkNeZhmJ0j3W oC5a4wZwprA90fzUG65QpffW2dm66X/v6tm1agxMBwUcS7MqoFbQlLJkB2Wyjmr4DO v8fR24ux9Fv/MXP/k/SEQTlnUkjA/BB88GjJ8mDQ= From: Kieran Bingham To: LibCamera Devel Date: Thu, 7 Feb 2019 21:21:19 +0000 Message-Id: <20190207212119.30299-6-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> References: <20190207212119.30299-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/5] libcamera: v4l2_device: Provide V4L2 Log helper 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, 07 Feb 2019 21:21:37 -0000 Add a V4L2DEVICE_LOG Macro helper to prepend the V4L2 Video Device node to every log output. This is particularly useful when more than one V4L2Device is utilised in the system. Signed-off-by: Kieran Bingham --- src/libcamera/v4l2_device.cpp | 48 +++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index c2e4d0ea8db2..ce977613ff20 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -28,6 +28,8 @@ namespace libcamera { LOG_DEFINE_CATEGORY(V4L2) +#define V4L2DEVICE_LOG(severity) LOG(V4L2, severity) << deviceNode_ << ": " + /** * \struct V4L2Capability * \brief struct v4l2_capability object wrapper and helpers @@ -254,14 +256,14 @@ int V4L2Device::open() int ret; if (isOpen()) { - LOG(V4L2, Error) << "Device already open"; + V4L2DEVICE_LOG(Error) << "Device already open"; return -EBUSY; } ret = ::open(deviceNode_.c_str(), O_RDWR | O_NONBLOCK); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Failed to open V4L2 device '" << deviceNode_ << "': " << strerror(-ret); return ret; @@ -271,24 +273,25 @@ int V4L2Device::open() ret = ioctl(fd_, VIDIOC_QUERYCAP, &caps_); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Failed to query device capabilities: " << strerror(-ret); return ret; } - LOG(V4L2, Debug) + V4L2DEVICE_LOG(Debug) << "Opened '" << deviceNode_ << "' " << caps_.bus_info() << ": " << caps_.driver() << ": " << caps_.card(); if (!caps_.isCapture() && !caps_.isOutput()) { - LOG(V4L2, Debug) << "Device is not a supported type"; + V4L2DEVICE_LOG(Debug) << "Device is not a supported type"; return -EINVAL; } if (!caps_.hasStreaming()) { - LOG(V4L2, Error) << "Device does not support streaming I/O"; + V4L2DEVICE_LOG(Error) + << "Device does not support streaming I/O"; return -EINVAL; } @@ -513,13 +516,13 @@ int V4L2Device::requestBuffers(unsigned int count) ret = ioctl(fd_, VIDIOC_REQBUFS, &rb); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Unable to request " << count << " buffers: " << strerror(-ret); return ret; } - LOG(V4L2, Debug) + V4L2DEVICE_LOG(Debug) << deviceNode_ << ":" << rb.count << " buffers requested."; return rb.count; @@ -545,7 +548,8 @@ int V4L2Device::exportBuffers(BufferPool *pool) allocatedBuffers = ret; if (allocatedBuffers < pool->count()) { - LOG(V4L2, Error) << "Not enough buffers provided by V4L2Device"; + V4L2DEVICE_LOG(Error) + << "Not enough buffers provided by V4L2Device"; requestBuffers(0); return -ENOMEM; } @@ -565,7 +569,7 @@ int V4L2Device::exportBuffers(BufferPool *pool) ret = ioctl(fd_, VIDIOC_QUERYBUF, &buf); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Unable to query buffer " << i << ": " << strerror(-ret); break; @@ -583,7 +587,7 @@ int V4L2Device::exportBuffers(BufferPool *pool) } if (ret) { - LOG(V4L2, Error) << "Failed to create plane"; + V4L2DEVICE_LOG(Error) << "Failed to create plane"; break; } } @@ -605,7 +609,7 @@ int V4L2Device::createPlane(Buffer *buffer, unsigned int planeIndex, struct v4l2_exportbuffer expbuf = {}; int ret; - LOG(V4L2, Debug) + V4L2DEVICE_LOG(Debug) << "Buffer " << buffer->index() << " plane " << planeIndex << ": length=" << length; @@ -618,7 +622,7 @@ int V4L2Device::createPlane(Buffer *buffer, unsigned int planeIndex, ret = ioctl(fd_, VIDIOC_EXPBUF, &expbuf); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Failed to export buffer: " << strerror(-ret); return ret; } @@ -648,13 +652,13 @@ int V4L2Device::importBuffers(BufferPool *pool) allocatedBuffers = ret; if (allocatedBuffers < pool->count()) { - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Not enough buffers provided by V4L2Device"; requestBuffers(0); return -ENOMEM; } - LOG(V4L2, Debug) << "Device using an externally provided pool"; + V4L2DEVICE_LOG(Debug) << "Device using an externally provided pool"; bufferPool_ = pool; return 0; @@ -665,7 +669,7 @@ int V4L2Device::importBuffers(BufferPool *pool) */ int V4L2Device::releaseBuffers() { - LOG(V4L2, Debug) << "Releasing bufferPool"; + V4L2DEVICE_LOG(Debug) << "Releasing bufferPool"; requestBuffers(0); bufferPool_ = nullptr; @@ -715,12 +719,12 @@ int V4L2Device::queueBuffer(Buffer *buffer) buf.m.planes = planes; } - LOG(V4L2, Debug) << "Queueing buffer " << buf.index; + V4L2DEVICE_LOG(Debug) << "Queueing buffer " << buf.index; ret = ioctl(fd_, VIDIOC_QBUF, &buf); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Failed to queue buffer " << buf.index << ": " << strerror(-ret); return ret; @@ -757,7 +761,7 @@ Buffer *V4L2Device::dequeueBuffer() ret = ioctl(fd_, VIDIOC_DQBUF, &buf); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Failed to dequeue buffer: " << strerror(-ret); return nullptr; } @@ -793,7 +797,7 @@ void V4L2Device::bufferAvailable(EventNotifier *notifier) if (!buffer) return; - LOG(V4L2, Debug) << "Buffer " << buffer->index() << " is available"; + V4L2DEVICE_LOG(Debug) << "Buffer " << buffer->index() << " is available"; /* Notify anyone listening to the device. */ bufferReady.emit(buffer); @@ -819,7 +823,7 @@ int V4L2Device::streamOn() ret = ioctl(fd_, VIDIOC_STREAMON, &bufferType_); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Failed to start streaming: " << strerror(-ret); return ret; } @@ -841,7 +845,7 @@ int V4L2Device::streamOff() ret = ioctl(fd_, VIDIOC_STREAMOFF, &bufferType_); if (ret < 0) { ret = -errno; - LOG(V4L2, Error) + V4L2DEVICE_LOG(Error) << "Failed to stop streaming: " << strerror(-ret); return ret; }