[libcamera-devel,v2,15/16] libcamera: pipeline: Support importing buffers

Message ID 20190713172351.25452-16-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • Add support for external buffers
Related show

Commit Message

Laurent Pinchart July 13, 2019, 5:23 p.m. UTC
From: Jacopo Mondi <jacopo@jmondi.org>

Add support for importing external buffers in all pipeline handlers.

Use the stream memory type in the pipeline handlers during buffer
allocation to import buffers to or export buffers from the video device.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp     | 49 ++++++++++++++++++------
 src/libcamera/pipeline/rkisp1/rkisp1.cpp |  6 ++-
 src/libcamera/pipeline/uvcvideo.cpp      |  5 ++-
 src/libcamera/pipeline/vimc.cpp          |  5 ++-
 4 files changed, 51 insertions(+), 14 deletions(-)

Comments

Niklas Söderlund July 14, 2019, 11:01 a.m. UTC | #1
Hi Jacopo, Laurent,

Thanks for your patch.

On 2019-07-13 20:23:50 +0300, Laurent Pinchart wrote:
> From: Jacopo Mondi <jacopo@jmondi.org>
> 
> Add support for importing external buffers in all pipeline handlers.
> 
> Use the stream memory type in the pipeline handlers during buffer
> allocation to import buffers to or export buffers from the video device.
> 
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>

> ---
>  src/libcamera/pipeline/ipu3/ipu3.cpp     | 49 ++++++++++++++++++------
>  src/libcamera/pipeline/rkisp1/rkisp1.cpp |  6 ++-
>  src/libcamera/pipeline/uvcvideo.cpp      |  5 ++-
>  src/libcamera/pipeline/vimc.cpp          |  5 ++-
>  4 files changed, 51 insertions(+), 14 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 488e89f25c5e..9ac5a5387dec 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -69,8 +69,9 @@ public:
>  	int configureOutput(ImgUOutput *output,
>  			    const StreamConfiguration &cfg);
>  
> -	int importBuffers(BufferPool *pool);
> -	int exportBuffers(ImgUOutput *output, BufferPool *pool);
> +	int importInputBuffers(BufferPool *pool);
> +	int importOutputBuffers(ImgUOutput *output, BufferPool *pool);
> +	int exportOutputBuffers(ImgUOutput *output, BufferPool *pool);
>  	void freeBuffers();
>  
>  	int start();
> @@ -605,7 +606,7 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
>  	if (!pool)
>  		return -ENOMEM;
>  
> -	ret = imgu->importBuffers(pool);
> +	ret = imgu->importInputBuffers(pool);
>  	if (ret)
>  		goto error;
>  
> @@ -616,7 +617,7 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
>  	 */
>  	bufferCount = pool->count();
>  	imgu->stat_.pool->createBuffers(bufferCount);
> -	ret = imgu->exportBuffers(&imgu->stat_, imgu->stat_.pool);
> +	ret = imgu->exportOutputBuffers(&imgu->stat_, imgu->stat_.pool);
>  	if (ret)
>  		goto error;
>  
> @@ -625,7 +626,10 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
>  		IPU3Stream *stream = static_cast<IPU3Stream *>(s);
>  		ImgUDevice::ImgUOutput *dev = stream->device_;
>  
> -		ret = imgu->exportBuffers(dev, &stream->bufferPool());
> +		if (stream->memoryType() == InternalMemory)
> +			ret = imgu->exportOutputBuffers(dev, &stream->bufferPool());
> +		else
> +			ret = imgu->importOutputBuffers(dev, &stream->bufferPool());
>  		if (ret)
>  			goto error;
>  	}
> @@ -637,8 +641,8 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
>  	if (!outStream->active_) {
>  		bufferCount = vfStream->configuration().bufferCount;
>  		outStream->device_->pool->createBuffers(bufferCount);
> -		ret = imgu->exportBuffers(outStream->device_,
> -					  outStream->device_->pool);
> +		ret = imgu->exportOutputBuffers(outStream->device_,
> +						outStream->device_->pool);
>  		if (ret)
>  			goto error;
>  	}
> @@ -646,8 +650,8 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
>  	if (!vfStream->active_) {
>  		bufferCount = outStream->configuration().bufferCount;
>  		vfStream->device_->pool->createBuffers(bufferCount);
> -		ret = imgu->exportBuffers(vfStream->device_,
> -					  vfStream->device_->pool);
> +		ret = imgu->exportOutputBuffers(vfStream->device_,
> +						vfStream->device_->pool);
>  		if (ret)
>  			goto error;
>  	}
> @@ -1113,7 +1117,7 @@ int ImgUDevice::configureOutput(ImgUOutput *output,
>   * \param[in] pool The buffer pool to import
>   * \return 0 on success or a negative error code otherwise
>   */
> -int ImgUDevice::importBuffers(BufferPool *pool)
> +int ImgUDevice::importInputBuffers(BufferPool *pool)
>  {
>  	int ret = input_->importBuffers(pool);
>  	if (ret) {
> @@ -1134,7 +1138,7 @@ int ImgUDevice::importBuffers(BufferPool *pool)
>   *
>   * \return 0 on success or a negative error code otherwise
>   */
> -int ImgUDevice::exportBuffers(ImgUOutput *output, BufferPool *pool)
> +int ImgUDevice::exportOutputBuffers(ImgUOutput *output, BufferPool *pool)
>  {
>  	int ret = output->dev->exportBuffers(pool);
>  	if (ret) {
> @@ -1146,6 +1150,29 @@ int ImgUDevice::exportBuffers(ImgUOutput *output, BufferPool *pool)
>  	return 0;
>  }
>  
> +/**
> + * \brief Reserve buffers in \a output from the provided \a pool
> + * \param[in] output The ImgU output device
> + * \param[in] pool The buffer pool used to reserve buffers in \a output
> + *
> + * Reserve a number of buffers equal to the number of buffers in \a pool
> + * in the \a output device.
> + *
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::importOutputBuffers(ImgUOutput *output, BufferPool *pool)
> +{
> +	int ret = output->dev->importBuffers(pool);
> +	if (ret) {
> +		LOG(IPU3, Error)
> +			<< "Failed to import buffer in " << output->name
> +			<< " ImgU device";
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * \brief Release buffers for all the ImgU video devices
>   */
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index cc33a2cb2572..efa9604bc1e3 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -319,7 +319,11 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera,
>  					   const std::set<Stream *> &streams)
>  {
>  	Stream *stream = *streams.begin();
> -	return video_->exportBuffers(&stream->bufferPool());
> +
> +	if (stream->memoryType() == InternalMemory)
> +		return video_->exportBuffers(&stream->bufferPool());
> +	else
> +		return video_->importBuffers(&stream->bufferPool());
>  }
>  
>  int PipelineHandlerRkISP1::freeBuffers(Camera *camera,
> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
> index b299c5da8471..8965210550d2 100644
> --- a/src/libcamera/pipeline/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo.cpp
> @@ -200,7 +200,10 @@ int PipelineHandlerUVC::allocateBuffers(Camera *camera,
>  
>  	LOG(UVC, Debug) << "Requesting " << cfg.bufferCount << " buffers";
>  
> -	return data->video_->exportBuffers(&stream->bufferPool());
> +	if (stream->memoryType() == InternalMemory)
> +		return data->video_->exportBuffers(&stream->bufferPool());
> +	else
> +		return data->video_->importBuffers(&stream->bufferPool());
>  }
>  
>  int PipelineHandlerUVC::freeBuffers(Camera *camera,
> diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
> index 7d96c3645c06..61b68a32ea50 100644
> --- a/src/libcamera/pipeline/vimc.cpp
> +++ b/src/libcamera/pipeline/vimc.cpp
> @@ -202,7 +202,10 @@ int PipelineHandlerVimc::allocateBuffers(Camera *camera,
>  
>  	LOG(VIMC, Debug) << "Requesting " << cfg.bufferCount << " buffers";
>  
> -	return data->video_->exportBuffers(&stream->bufferPool());
> +	if (stream->memoryType() == InternalMemory)
> +		return data->video_->exportBuffers(&stream->bufferPool());
> +	else
> +		return data->video_->importBuffers(&stream->bufferPool());
>  }
>  
>  int PipelineHandlerVimc::freeBuffers(Camera *camera,
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 488e89f25c5e..9ac5a5387dec 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -69,8 +69,9 @@  public:
 	int configureOutput(ImgUOutput *output,
 			    const StreamConfiguration &cfg);
 
-	int importBuffers(BufferPool *pool);
-	int exportBuffers(ImgUOutput *output, BufferPool *pool);
+	int importInputBuffers(BufferPool *pool);
+	int importOutputBuffers(ImgUOutput *output, BufferPool *pool);
+	int exportOutputBuffers(ImgUOutput *output, BufferPool *pool);
 	void freeBuffers();
 
 	int start();
@@ -605,7 +606,7 @@  int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 	if (!pool)
 		return -ENOMEM;
 
-	ret = imgu->importBuffers(pool);
+	ret = imgu->importInputBuffers(pool);
 	if (ret)
 		goto error;
 
@@ -616,7 +617,7 @@  int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 	 */
 	bufferCount = pool->count();
 	imgu->stat_.pool->createBuffers(bufferCount);
-	ret = imgu->exportBuffers(&imgu->stat_, imgu->stat_.pool);
+	ret = imgu->exportOutputBuffers(&imgu->stat_, imgu->stat_.pool);
 	if (ret)
 		goto error;
 
@@ -625,7 +626,10 @@  int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 		IPU3Stream *stream = static_cast<IPU3Stream *>(s);
 		ImgUDevice::ImgUOutput *dev = stream->device_;
 
-		ret = imgu->exportBuffers(dev, &stream->bufferPool());
+		if (stream->memoryType() == InternalMemory)
+			ret = imgu->exportOutputBuffers(dev, &stream->bufferPool());
+		else
+			ret = imgu->importOutputBuffers(dev, &stream->bufferPool());
 		if (ret)
 			goto error;
 	}
@@ -637,8 +641,8 @@  int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 	if (!outStream->active_) {
 		bufferCount = vfStream->configuration().bufferCount;
 		outStream->device_->pool->createBuffers(bufferCount);
-		ret = imgu->exportBuffers(outStream->device_,
-					  outStream->device_->pool);
+		ret = imgu->exportOutputBuffers(outStream->device_,
+						outStream->device_->pool);
 		if (ret)
 			goto error;
 	}
@@ -646,8 +650,8 @@  int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 	if (!vfStream->active_) {
 		bufferCount = outStream->configuration().bufferCount;
 		vfStream->device_->pool->createBuffers(bufferCount);
-		ret = imgu->exportBuffers(vfStream->device_,
-					  vfStream->device_->pool);
+		ret = imgu->exportOutputBuffers(vfStream->device_,
+						vfStream->device_->pool);
 		if (ret)
 			goto error;
 	}
@@ -1113,7 +1117,7 @@  int ImgUDevice::configureOutput(ImgUOutput *output,
  * \param[in] pool The buffer pool to import
  * \return 0 on success or a negative error code otherwise
  */
-int ImgUDevice::importBuffers(BufferPool *pool)
+int ImgUDevice::importInputBuffers(BufferPool *pool)
 {
 	int ret = input_->importBuffers(pool);
 	if (ret) {
@@ -1134,7 +1138,7 @@  int ImgUDevice::importBuffers(BufferPool *pool)
  *
  * \return 0 on success or a negative error code otherwise
  */
-int ImgUDevice::exportBuffers(ImgUOutput *output, BufferPool *pool)
+int ImgUDevice::exportOutputBuffers(ImgUOutput *output, BufferPool *pool)
 {
 	int ret = output->dev->exportBuffers(pool);
 	if (ret) {
@@ -1146,6 +1150,29 @@  int ImgUDevice::exportBuffers(ImgUOutput *output, BufferPool *pool)
 	return 0;
 }
 
+/**
+ * \brief Reserve buffers in \a output from the provided \a pool
+ * \param[in] output The ImgU output device
+ * \param[in] pool The buffer pool used to reserve buffers in \a output
+ *
+ * Reserve a number of buffers equal to the number of buffers in \a pool
+ * in the \a output device.
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+int ImgUDevice::importOutputBuffers(ImgUOutput *output, BufferPool *pool)
+{
+	int ret = output->dev->importBuffers(pool);
+	if (ret) {
+		LOG(IPU3, Error)
+			<< "Failed to import buffer in " << output->name
+			<< " ImgU device";
+		return ret;
+	}
+
+	return 0;
+}
+
 /**
  * \brief Release buffers for all the ImgU video devices
  */
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index cc33a2cb2572..efa9604bc1e3 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -319,7 +319,11 @@  int PipelineHandlerRkISP1::allocateBuffers(Camera *camera,
 					   const std::set<Stream *> &streams)
 {
 	Stream *stream = *streams.begin();
-	return video_->exportBuffers(&stream->bufferPool());
+
+	if (stream->memoryType() == InternalMemory)
+		return video_->exportBuffers(&stream->bufferPool());
+	else
+		return video_->importBuffers(&stream->bufferPool());
 }
 
 int PipelineHandlerRkISP1::freeBuffers(Camera *camera,
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index b299c5da8471..8965210550d2 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -200,7 +200,10 @@  int PipelineHandlerUVC::allocateBuffers(Camera *camera,
 
 	LOG(UVC, Debug) << "Requesting " << cfg.bufferCount << " buffers";
 
-	return data->video_->exportBuffers(&stream->bufferPool());
+	if (stream->memoryType() == InternalMemory)
+		return data->video_->exportBuffers(&stream->bufferPool());
+	else
+		return data->video_->importBuffers(&stream->bufferPool());
 }
 
 int PipelineHandlerUVC::freeBuffers(Camera *camera,
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 7d96c3645c06..61b68a32ea50 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -202,7 +202,10 @@  int PipelineHandlerVimc::allocateBuffers(Camera *camera,
 
 	LOG(VIMC, Debug) << "Requesting " << cfg.bufferCount << " buffers";
 
-	return data->video_->exportBuffers(&stream->bufferPool());
+	if (stream->memoryType() == InternalMemory)
+		return data->video_->exportBuffers(&stream->bufferPool());
+	else
+		return data->video_->importBuffers(&stream->bufferPool());
 }
 
 int PipelineHandlerVimc::freeBuffers(Camera *camera,