From patchwork Tue Feb 5 00:06:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 504 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 58C0160DB8 for ; Tue, 5 Feb 2019 01:07:52 +0100 (CET) X-Halon-ID: 12e273c5-28da-11e9-b530-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from localhost.localdomain (unknown [81.164.19.127]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 12e273c5-28da-11e9-b530-005056917a89; Tue, 05 Feb 2019 01:07:49 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Feb 2019 01:06:56 +0100 Message-Id: <20190205000702.15370-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> References: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 1/7] libcamera: pipelines: implement start and stop of a camera 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: Tue, 05 Feb 2019 00:07:52 -0000 The camera need methods to start and stop capturing once it have been configured. Extend the pipeline API to provide this and implement stubs in all pipeline handlers. Signed-off-by: Niklas Söderlund --- src/libcamera/include/pipeline_handler.h | 3 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 14 ++++++++++++ src/libcamera/pipeline/uvcvideo.cpp | 14 ++++++++++++ src/libcamera/pipeline/vimc.cpp | 14 ++++++++++++ src/libcamera/pipeline_handler.cpp | 27 ++++++++++++++++++++++++ 5 files changed, 72 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index b4321f0fa0f765be..4bfe45aaf78e34ab 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -45,6 +45,9 @@ public: virtual int configureStreams(Camera *camera, std::map &config) = 0; + virtual int start(const Camera *camera) = 0; + virtual void stop(const Camera *camera) = 0; + virtual bool match(DeviceEnumerator *enumerator) = 0; protected: diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 7823bbb55d9bde16..3bf196051f2ebdbc 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -34,6 +34,9 @@ public: int configureStreams(Camera *camera, std::map &config) override; + int start(const Camera *camera) override; + void stop(const Camera *camera) override; + bool match(DeviceEnumerator *enumerator); private: @@ -104,6 +107,17 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera, return 0; } +int PipelineHandlerIPU3::start(const Camera *camera) +{ + LOG(IPU3, Error) << "TODO: start camera"; + return 0; +} + +void PipelineHandlerIPU3::stop(const Camera *camera) +{ + LOG(IPU3, Error) << "TODO: stop camera"; +} + bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) { DeviceMatch cio2_dm("ipu3-cio2"); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index ad4d45d0698519b6..e6a15c58a63cf76b 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -30,6 +30,9 @@ public: int configureStreams(Camera *camera, std::map &config) override; + int start(const Camera *camera) override; + void stop(const Camera *camera) override; + bool match(DeviceEnumerator *enumerator); private: @@ -82,6 +85,17 @@ int PipelineHandlerUVC::configureStreams(Camera *camera, return 0; } +int PipelineHandlerUVC::start(const Camera *camera) +{ + LOG(UVC, Error) << "TODO: start camera"; + return 0; +} + +void PipelineHandlerUVC::stop(const Camera *camera) +{ + LOG(UVC, Error) << "TODO: stop camera"; +} + bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { DeviceMatch dm("uvcvideo"); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 900477e257232b70..11eca0cd4d9a6e0c 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -30,6 +30,9 @@ public: int configureStreams(Camera *camera, std::map &config) override; + int start(const Camera *camera) override; + void stop(const Camera *camera) override; + bool match(DeviceEnumerator *enumerator); private: @@ -77,6 +80,17 @@ int PipeHandlerVimc::configureStreams(Camera *camera, return 0; } +int PipeHandlerVimc::start(const Camera *camera) +{ + LOG(VIMC, Error) << "TODO: start camera"; + return 0; +} + +void PipeHandlerVimc::stop(const Camera *camera) +{ + LOG(VIMC, Error) << "TODO: stop camera"; +} + bool PipeHandlerVimc::match(DeviceEnumerator *enumerator) { DeviceMatch dm("vimc"); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 3a560e10c442717f..fa5f780cea34fc8f 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -109,6 +109,33 @@ PipelineHandler::~PipelineHandler() * \return 0 on success or a negative error code on error. */ +/** + * \fn PipelineHandler::start() + * \brief Start capturing from a group of streams + * \param[in] camera The camera to start + * + * Start the group of streams that have been configured for capture by + * \a configureStreams(). The intended caller of this interface is + * the Camera class which will in turn will receive the call from the + * application to indicate that it's done configuring the streams + * and are ready to capture. + * + * \return 0 on success or a negative error code on error. + */ + +/** + * \fn PipelineHandler::stop() + * \brief Stop capturing from all running streams + * \param[in] camera The camera to stop + * + * Stop processing requests, finish processing all already queued requests + * and once all buffers on all streams have been dequeued stop capturing + * from all running streams. Finish processing of queued requests do not + * necessarily involve processing them by the capture hardware but notifying + * the application that a queued request was not processed due to the fact + * that the camera was stopped before they could be processed. + */ + /** * \fn PipelineHandler::match(DeviceEnumerator *enumerator) * \brief Match media devices and create camera instances From patchwork Tue Feb 5 00:06:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 505 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se Return-Path: Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EB8E660DBD for ; Tue, 5 Feb 2019 01:07:54 +0100 (CET) X-Halon-ID: 1387d972-28da-11e9-b530-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from localhost.localdomain (unknown [81.164.19.127]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 1387d972-28da-11e9-b530-005056917a89; Tue, 05 Feb 2019 01:07:51 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Feb 2019 01:06:57 +0100 Message-Id: <20190205000702.15370-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> References: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 2/7] libcamera: pipelines: add buffer and request 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: Tue, 05 Feb 2019 00:07:55 -0000 To allow a pipeline handler to provide buffers for request creation and later processing of requests it needs to be extended with methods to allocate/free buffers and a way to queue requests to the pipeline. Add the interfaces for these methods in the PipelineHandler base class and extend all pipeline handler with stubs to be expanded later to actually perform the appropriate actions for each pipeline. This initial implementation only considers the allocation of new buffers. Future work would need to expand this to also cover importing buffers the camera from an external source. Signed-off-by: Niklas Söderlund --- src/libcamera/include/pipeline_handler.h | 8 ++++ src/libcamera/pipeline/ipu3/ipu3.cpp | 24 ++++++++++++ src/libcamera/pipeline/uvcvideo.cpp | 24 ++++++++++++ src/libcamera/pipeline/vimc.cpp | 24 ++++++++++++ src/libcamera/pipeline_handler.cpp | 47 ++++++++++++++++++++++++ 5 files changed, 127 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index 4bfe45aaf78e34ab..fab6d3ee1f3e04d7 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -14,10 +14,12 @@ namespace libcamera { +class BufferPool; class Camera; class CameraManager; class DeviceEnumerator; class MediaDevice; +class Request; class Stream; class StreamConfiguration; @@ -45,9 +47,15 @@ public: virtual int configureStreams(Camera *camera, std::map &config) = 0; + virtual std::map allocateBuffers(Camera *camera, + std::map &config) = 0; + virtual int freeBuffers(Camera *camera) = 0; + virtual int start(const Camera *camera) = 0; virtual void stop(const Camera *camera) = 0; + virtual int queueRequest(const Camera *camera, Request *request) = 0; + virtual bool match(DeviceEnumerator *enumerator) = 0; protected: diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 3bf196051f2ebdbc..881afe3a4779f46d 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -34,9 +34,16 @@ public: int configureStreams(Camera *camera, std::map &config) override; + std::map + allocateBuffers(Camera *camera, + std::map &config) override; + int freeBuffers(Camera *camera) override; + int start(const Camera *camera) override; void stop(const Camera *camera) override; + int queueRequest(const Camera *camera, Request *request) override; + bool match(DeviceEnumerator *enumerator); private: @@ -107,6 +114,18 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera, return 0; } +std::map +PipelineHandlerIPU3::allocateBuffers(Camera *camera, + std::map &config) +{ + return std::map {}; +} + +int PipelineHandlerIPU3::freeBuffers(Camera *camera) +{ + return 0; +} + int PipelineHandlerIPU3::start(const Camera *camera) { LOG(IPU3, Error) << "TODO: start camera"; @@ -118,6 +137,11 @@ void PipelineHandlerIPU3::stop(const Camera *camera) LOG(IPU3, Error) << "TODO: stop camera"; } +int PipelineHandlerIPU3::queueRequest(const Camera *camera, Request *request) +{ + return 0; +} + bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) { DeviceMatch cio2_dm("ipu3-cio2"); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index e6a15c58a63cf76b..8b3f0ce7e2112564 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -30,9 +30,16 @@ public: int configureStreams(Camera *camera, std::map &config) override; + std::map + allocateBuffers(Camera *camera, + std::map &config) override; + int freeBuffers(Camera *camera) override; + int start(const Camera *camera) override; void stop(const Camera *camera) override; + int queueRequest(const Camera *camera, Request *request) override; + bool match(DeviceEnumerator *enumerator); private: @@ -85,6 +92,18 @@ int PipelineHandlerUVC::configureStreams(Camera *camera, return 0; } +std::map +PipelineHandlerUVC::allocateBuffers(Camera *camera, + std::map &config) +{ + return std::map {}; +} + +int PipelineHandlerUVC::freeBuffers(Camera *camera) +{ + return 0; +} + int PipelineHandlerUVC::start(const Camera *camera) { LOG(UVC, Error) << "TODO: start camera"; @@ -96,6 +115,11 @@ void PipelineHandlerUVC::stop(const Camera *camera) LOG(UVC, Error) << "TODO: stop camera"; } +int PipelineHandlerUVC::queueRequest(const Camera *camera, Request *request) +{ + return 0; +} + bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { DeviceMatch dm("uvcvideo"); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 11eca0cd4d9a6e0c..23a8250ec8b691b5 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -30,9 +30,16 @@ public: int configureStreams(Camera *camera, std::map &config) override; + std::map + allocateBuffers(Camera *camera, + std::map &config) override; + int freeBuffers(Camera *camera) override; + int start(const Camera *camera) override; void stop(const Camera *camera) override; + int queueRequest(const Camera *camera, Request *request) override; + bool match(DeviceEnumerator *enumerator); private: @@ -80,6 +87,18 @@ int PipeHandlerVimc::configureStreams(Camera *camera, return 0; } +std::map +PipeHandlerVimc::allocateBuffers(Camera *camera, + std::map &config) +{ + return std::map {}; +} + +int PipeHandlerVimc::freeBuffers(Camera *camera) +{ + return 0; +} + int PipeHandlerVimc::start(const Camera *camera) { LOG(VIMC, Error) << "TODO: start camera"; @@ -91,6 +110,11 @@ void PipeHandlerVimc::stop(const Camera *camera) LOG(VIMC, Error) << "TODO: stop camera"; } +int PipeHandlerVimc::queueRequest(const Camera *camera, Request *request) +{ + return 0; +} + bool PipeHandlerVimc::match(DeviceEnumerator *enumerator) { DeviceMatch dm("vimc"); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index fa5f780cea34fc8f..7df115cfcb90c83a 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -109,6 +109,39 @@ PipelineHandler::~PipelineHandler() * \return 0 on success or a negative error code on error. */ +/** + * \fn PipelineHandler::allocateBuffers() + * \brief Allocate buffers for a group of streams + * \param[in] camera The camera to allocate buffer for + * \param[in] config The stream setup and format describing the buffers + * + * After a camera's format have been configure and before a camera can be + * started buffers needs to be associated with it. Allocation new buffers from + * the streams involved in the captured is one option to associated buffers + * with a capture. + * + * The intended caller of this interface is the Camera class which is + * responsible for configure the streams and formats of a capture sessions + * as well as making sure there are buffers available to actually start the + * camera. + * + * \return 0 on success or a negative error code on error. + */ + +/** + * \fn PipelineHandler::freeBuffers() + * \brief Free all buffers associated to a camera + * \param[in] camera The camera to free all buffers from + * + * After a capture session have been stopped all buffers associated with the + * camera needs to be freed to allow the memory to be reused in future capture + * sessions. The intended caller of this interface is the Camera object + * responsible for stopping the camera and once it's stopped freeing its + * resources. + * + * \return 0 on success or a negative error code on error. + */ + /** * \fn PipelineHandler::start() * \brief Start capturing from a group of streams @@ -136,6 +169,20 @@ PipelineHandler::~PipelineHandler() * that the camera was stopped before they could be processed. */ +/** + * \fn PipelineHandler::queueRequest() + * \brief Queue a request to the camera + * \param[in] camera The camera to queue request on + * \param[in] request The request to queue + * + * Each request the camera should handle needs to be queued to the hardware + * thru the pipeline handler. The pipeline handler needs to examine the request, + * apply the requested controls with the V4L2 request and queue the buffers + * contained in the request to the correct video device. + * + * \return 0 on success or a negative error code on error. + */ + /** * \fn PipelineHandler::match(DeviceEnumerator *enumerator) * \brief Match media devices and create camera instances From patchwork Tue Feb 5 00:06:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 506 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7068E60DC2 for ; Tue, 5 Feb 2019 01:07:56 +0100 (CET) X-Halon-ID: 14d7db0e-28da-11e9-b530-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from localhost.localdomain (unknown [81.164.19.127]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 14d7db0e-28da-11e9-b530-005056917a89; Tue, 05 Feb 2019 01:07:53 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Feb 2019 01:06:58 +0100 Message-Id: <20190205000702.15370-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> References: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 3/7] libcamera: camera: implement start and stop of a camera 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: Tue, 05 Feb 2019 00:07:56 -0000 Add an interface for the application to start and stop a camera. Once a camera is started the pipeline handler of the camera will begin processing request queued to the camera by the application until it's stopped. Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 4 ++++ src/libcamera/camera.cpp | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 4940c344440e2ca2..de338c616641c074 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -15,6 +15,7 @@ namespace libcamera { +class Buffer; class PipelineHandler; class Stream; class StreamConfiguration; @@ -41,6 +42,9 @@ public: streamConfiguration(std::vector &streams); int configureStreams(std::map &config); + int start(); + int stop(); + private: Camera(PipelineHandler *pipe, const std::string &name); ~Camera(); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index bcf3d54ab1c3eb29..bf09acfdb9cd0007 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include "log.h" @@ -248,4 +249,51 @@ int Camera::configureStreams(std::map &config) return pipe_->configureStreams(this, config); } +/** + * \brief Start capture from camera + * + * Start the camera capture session. Once the camera is started the application + * can queue requests to the camera to process and return to the application + * until the capture session is terminated with \a stop(). + * + * \return 0 on success or a negative error code on error. + * \retval -ENODEV The camera is not connected to any hardware + * \retval -EACCES The user has not acquired exclusive access to the camera + */ +int Camera::start() +{ + if (disconnected_) + return -ENODEV; + + if (!acquired_) + return -EACCES; + + return pipe_->start(this); +} + +/** + * \brief Stop capture from camera + * + * Stop the running capture session. Once the camera is stooped the may not + * queue any new requests and any already queued requests might that have not + * been queued to the hardware might be returned to the application not + * fulfilled. + * + * \return 0 on success or a negative error code on error. + * \retval -ENODEV The camera is not connected to any hardware + * \retval -EACCES The user has not acquired exclusive access to the camera + */ +int Camera::stop() +{ + if (disconnected_) + return -ENODEV; + + if (!acquired_) + return -EACCES; + + pipe_->stop(this); + + return 0; +} + } /* namespace libcamera */ From patchwork Tue Feb 5 00:06:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 507 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 018CA60DC2 for ; Tue, 5 Feb 2019 01:07:57 +0100 (CET) X-Halon-ID: 15faf8e0-28da-11e9-b530-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from localhost.localdomain (unknown [81.164.19.127]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 15faf8e0-28da-11e9-b530-005056917a89; Tue, 05 Feb 2019 01:07:55 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Feb 2019 01:06:59 +0100 Message-Id: <20190205000702.15370-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> References: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 4/7] libcamera: camera: add request 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: Tue, 05 Feb 2019 00:07:58 -0000 Add support to the camera to create and queue requests. The application needs methods to get hold of buffers and creating requests. Once a request is created it can be queued to the camera and the application will asynchronously be notified once the request is completed and be able to process all the buffers involved in the request. At this point the request objects contains no controls be configured, this needs to be extended in the future once the library supports v4l2 controls and requests. Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 7 +++ src/libcamera/camera.cpp | 102 ++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index de338c616641c074..f6991a50900e6956 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -16,7 +16,9 @@ namespace libcamera { class Buffer; +class BufferPool; class PipelineHandler; +class Request; class Stream; class StreamConfiguration; @@ -42,6 +44,10 @@ public: streamConfiguration(std::vector &streams); int configureStreams(std::map &config); + BufferPool *bufferPool(Stream *); + Request *createRequest(std::map &resources); + int queueRequest(Request *request); + int start(); int stop(); @@ -55,6 +61,7 @@ private: std::shared_ptr pipe_; std::string name_; std::vector streams_; + std::map bufferPools_; bool acquired_; bool disconnected_; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index bf09acfdb9cd0007..de78536993601ee3 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -246,7 +246,107 @@ int Camera::configureStreams(std::map &config) if (!config.size()) return -EINVAL; - return pipe_->configureStreams(this, config); + int ret = pipe_->configureStreams(this, config); + if (ret) + return ret; + + bufferPools_ = pipe_->allocateBuffers(this, config); + if (!bufferPools_.size()) + return -EINVAL; + + return 0; +} + +/** + * \brief Retrieve the buffer pool for a stream + * \param[in] stream Stream to retrieve buffer pool from + * + * Retrieve the buffer pool for a specific stream, if one exists. To be able to + * queue request to the camera the application needs to create requests and + * attache buffers to the request. To get hold of buffers to associate with the + * request the streams buffer pool needs to be retrieved. This interface allows + * the application to get hold of the streams buffer pool. + * + * The buffer pools are created when the application configures the camera, + * prior to configuration of the camera no buffer pools exists this calling + * this function at that time will return a nullptr. + * + * \return pointer to the buffer pool, nullptr on error + */ +BufferPool *Camera::bufferPool(Stream *stream) +{ + if (disconnected_) + return nullptr; + + if (!acquired_) + return nullptr; + + if (bufferPools_.find(stream) == bufferPools_.end()) + return nullptr; + + return bufferPools_[stream]; +} + +/** + * \brief Create a request object for the camera + * \param[in] resources Array of streams and buffer to create a request from + * + * Before an application can queue a request to the camera it needs to be + * created, this interface allows the application to create such requests. The + * application needs to supply a map of streams and buffers that the request + * should process once it's queued to the camera. + * + * Once a request object have been created the application can set controls + * that are to be used to capture the particular frame before queuing it to + * the camera. + * + * \return pointer to the buffer pool, nullptr on error + */ +Request *Camera::createRequest(std::map &resources) +{ + if (disconnected_) + return nullptr; + + if (!acquired_) + return nullptr; + + if (resources.size() == 0) + return nullptr; + + return new Request(resources); +} + +/** + * \brief Queue a request to the camera + * \param[in] request The request to queue to the camera + * + * The application can once its got hold of a request queue it to a running + * camera at any point. The application get hold of a request by either creating + * it or reusing a old request once it's been completed and the application have + * no further use of the buffers it contained. + * + * Once a request have been queued to the camera it will be notified once the + * request is complete and the associated buffers can be consumed. + * + * \return 0 on success or a negative error code on error. + * \retval -ENODEV The camera is not connected to any hardware + * \retval -EACCES The user has not acquired exclusive access to the camera + */ +int Camera::queueRequest(Request *request) +{ + if (disconnected_) + return -ENODEV; + + if (!acquired_) + return -EACCES; + + int ret = request->prepare(); + if (ret) { + LOG(Camera, Error) << "Failed to connect request resources"; + return ret; + } + + return pipe_->queueRequest(this, request); } /** From patchwork Tue Feb 5 00:07:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 508 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E38D60DC9 for ; Tue, 5 Feb 2019 01:07:58 +0100 (CET) X-Halon-ID: 168d0373-28da-11e9-b530-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from localhost.localdomain (unknown [81.164.19.127]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 168d0373-28da-11e9-b530-005056917a89; Tue, 05 Feb 2019 01:07:56 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Feb 2019 01:07:00 +0100 Message-Id: <20190205000702.15370-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> References: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 5/7] libcamera: pipeline: uvcvideo: add allocateBuffers and freeBuffers 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: Tue, 05 Feb 2019 00:07:58 -0000 Allow the UVC pipeline to allocate and free buffers for the single stream attached to the camera. The buffers are allocated and freed utilising the V4L2Device requestBuffers() and releaseBuffers() interface. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/uvcvideo.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 8b3f0ce7e2112564..3685dbf9d19c3d7d 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -96,12 +96,21 @@ std::map PipelineHandlerUVC::allocateBuffers(Camera *camera, std::map &config) { - return std::map {}; + StreamConfiguration *cfg = &config[&stream_]; + + LOG(UVC, Debug) << "Requesting " << cfg->bufferCount << " buffers"; + + BufferPool *pool = video_->requestBuffers(cfg->bufferCount); + + if (!pool) + LOG(UVC, Error) << "Failed to acquire a buffer pool"; + + return std::map { {&stream_, pool} }; } int PipelineHandlerUVC::freeBuffers(Camera *camera) { - return 0; + return video_->releaseBuffers(); } int PipelineHandlerUVC::start(const Camera *camera) From patchwork Tue Feb 5 00:07:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 509 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BEAFA60DCB for ; Tue, 5 Feb 2019 01:07:59 +0100 (CET) X-Halon-ID: 1708876c-28da-11e9-b530-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from localhost.localdomain (unknown [81.164.19.127]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 1708876c-28da-11e9-b530-005056917a89; Tue, 05 Feb 2019 01:07:56 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Feb 2019 01:07:01 +0100 Message-Id: <20190205000702.15370-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> References: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 6/7] libcamera: pipeline: uvcvideo: Add queueRequest 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: Tue, 05 Feb 2019 00:08:00 -0000 From: Kieran Bingham Extract the buffer from the Request bufferMap. The uvcvideo only supports a single stream and so expects only a single buffer to queue. Queue the retrieved buffer with the video device for processing. Signed-off-by: Kieran Bingham --- src/libcamera/pipeline/uvcvideo.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 3685dbf9d19c3d7d..632a4b4b09189240 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include "device_enumerator.h" @@ -126,6 +127,19 @@ void PipelineHandlerUVC::stop(const Camera *camera) int PipelineHandlerUVC::queueRequest(const Camera *camera, Request *request) { + /* Set any controls, queue any buffers */ + + if (request->bufferMap.find(&stream_) == request->bufferMap.end()) { + LOG(UVC, Error) + << "Attempt to queue request with invalid stream"; + + return -ENOENT; + } + + Buffer *buffer = request->bufferMap[&stream_]; + + video_->queueBuffer(buffer); + return 0; } From patchwork Tue Feb 5 00:07:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 510 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se Return-Path: Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BDEFD60DC5 for ; Tue, 5 Feb 2019 01:07:59 +0100 (CET) X-Halon-ID: 177e89ee-28da-11e9-b530-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from localhost.localdomain (unknown [81.164.19.127]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 177e89ee-28da-11e9-b530-005056917a89; Tue, 05 Feb 2019 01:07:57 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Feb 2019 01:07:02 +0100 Message-Id: <20190205000702.15370-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> References: <20190205000702.15370-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 7/7] libcamera: pipeline: uvcvideo: add camera start and stop 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: Tue, 05 Feb 2019 00:08:00 -0000 Expand the stubs to actually start and stop the UVC video device. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/uvcvideo.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 632a4b4b09189240..8c0d2c09aafa5f37 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -116,13 +116,16 @@ int PipelineHandlerUVC::freeBuffers(Camera *camera) int PipelineHandlerUVC::start(const Camera *camera) { - LOG(UVC, Error) << "TODO: start camera"; - return 0; + LOG(UVC, Debug) << "Stream On"; + + return video_->streamOn(); } void PipelineHandlerUVC::stop(const Camera *camera) { - LOG(UVC, Error) << "TODO: stop camera"; + LOG(UVC, Debug) << "Stream Off"; + + video_->streamOff(); } int PipelineHandlerUVC::queueRequest(const Camera *camera, Request *request)