[libcamera-devel] [PATCH v8 08/13] libcamera: ipu3: Implement camera start/stop

Jacopo Mondi jacopo at jmondi.org
Wed Apr 3 10:01:43 CEST 2019


Start and stop video devices in the pipeline.

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 104 +++++++++++++++++++++++++--
 1 file changed, 97 insertions(+), 7 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index a838fd3a096d..d8a41543243e 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -70,6 +70,9 @@ public:
 	int exportBuffers(ImgUOutput *output, BufferPool *pool);
 	void freeBuffers();
 
+	int start();
+	int stop();
+
 	unsigned int index_;
 	std::string name_;
 	MediaDevice *media_;
@@ -109,6 +112,9 @@ public:
 	BufferPool *exportBuffers();
 	void freeBuffers();
 
+	int start();
+	int stop();
+
 	static int mediaBusToFormat(unsigned int code);
 
 	V4L2Device *output_;
@@ -335,25 +341,43 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera, Stream *stream)
 int PipelineHandlerIPU3::start(Camera *camera)
 {
 	IPU3CameraData *data = cameraData(camera);
-	V4L2Device *cio2 = data->cio2_.output_;
+	CIO2Device *cio2 = &data->cio2_;
+	ImgUDevice *imgu = data->imgu_;
 	int ret;
 
-	ret = cio2->streamOn();
+	/*
+	 * Start the ImgU video devices, buffers will be queued to the
+	 * ImgU output and viewfinder when requests will be queued.
+	 */
+	ret = cio2->start();
+	if (ret)
+		goto error;
+
+	ret = imgu->start();
 	if (ret) {
-		LOG(IPU3, Info) << "Failed to start camera " << camera->name();
-		return ret;
+		imgu->stop();
+		cio2->stop();
+		goto error;
 	}
 
 	return 0;
+
+error:
+	LOG(IPU3, Error) << "Failed to start camera " << camera->name();
+
+	return ret;
 }
 
 void PipelineHandlerIPU3::stop(Camera *camera)
 {
 	IPU3CameraData *data = cameraData(camera);
-	V4L2Device *cio2 = data->cio2_.output_;
+	int ret;
 
-	if (cio2->streamOff())
-		LOG(IPU3, Info) << "Failed to stop camera " << camera->name();
+	ret = data->cio2_.stop();
+	ret |= data->imgu_->stop();
+	if (ret)
+		LOG(IPU3, Warning) << "Failed to stop camera "
+				   << camera->name();
 
 	PipelineHandler::stop(camera);
 }
@@ -764,6 +788,50 @@ void ImgUDevice::freeBuffers()
 		LOG(IPU3, Error) << "Failed to release ImgU input buffers";
 }
 
+int ImgUDevice::start()
+{
+	int ret;
+
+	/* Start the ImgU video devices. */
+	ret = output_.dev->streamOn();
+	if (ret) {
+		LOG(IPU3, Error) << "Failed to start ImgU output";
+		return ret;
+	}
+
+	ret = viewfinder_.dev->streamOn();
+	if (ret) {
+		LOG(IPU3, Error) << "Failed to start ImgU viewfinder";
+		return ret;
+	}
+
+	ret = stat_.dev->streamOn();
+	if (ret) {
+		LOG(IPU3, Error) << "Failed to start ImgU stat";
+		return ret;
+	}
+
+	ret = input_->streamOn();
+	if (ret) {
+		LOG(IPU3, Error) << "Failed to start ImgU input";
+		return ret;
+	}
+
+	return 0;
+}
+
+int ImgUDevice::stop()
+{
+	int ret;
+
+	ret = output_.dev->streamOff();
+	ret |= viewfinder_.dev->streamOff();
+	ret |= stat_.dev->streamOff();
+	ret |= input_->streamOff();
+
+	return ret;
+}
+
 /*------------------------------------------------------------------------------
  * CIO2 Device
  */
@@ -957,6 +1025,28 @@ void CIO2Device::freeBuffers()
 		LOG(IPU3, Error) << "Failed to release CIO2 buffers";
 }
 
+int CIO2Device::start()
+{
+	int ret;
+
+	for (Buffer &buffer : pool_.buffers()) {
+		ret = output_->queueBuffer(&buffer);
+		if (ret)
+			return ret;
+	}
+
+	ret = output_->streamOn();
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int CIO2Device::stop()
+{
+	return output_->streamOff();
+}
+
 int CIO2Device::mediaBusToFormat(unsigned int code)
 {
 	switch (code) {
-- 
2.21.0



More information about the libcamera-devel mailing list