[libcamera-devel,v6,07/12] libcamera: ipu3: Implement camera start/stop

Message ID 20190402162134.3894-8-jacopo@jmondi.org
State Superseded
Headers show
Series
  • libcamera: ipu3: Add ImgU support
Related show

Commit Message

Jacopo Mondi April 2, 2019, 4:21 p.m. UTC
Start and stop video devices in the pipeline.

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

Patch

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 7eac36f0c561..7061f36b4495 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -86,6 +86,9 @@  public:
 	int exportBuffers(ImgUOutput *output, BufferPool *pool);
 	void freeBuffers();
 
+	int start();
+	int stop();
+
 	unsigned int index_;
 	std::string name_;
 	MediaDevice *media_;
@@ -125,6 +128,9 @@  public:
 	BufferPool *exportBuffers();
 	void freeBuffers();
 
+	int start();
+	int stop();
+
 	V4L2Device *output_;
 	V4L2Subdevice *csi2_;
 	V4L2Subdevice *sensor_;
@@ -349,25 +355,42 @@  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);
 }
@@ -778,6 +801,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
  */
@@ -971,6 +1038,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();
+}
+
 REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3);
 
 } /* namespace libcamera */