summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/camera.cpp11
-rw-r--r--src/libcamera/include/pipeline_handler.h2
-rw-r--r--src/libcamera/pipeline/ipu3/ipu3.cpp146
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp20
-rw-r--r--src/libcamera/pipeline/uvcvideo.cpp28
-rw-r--r--src/libcamera/pipeline/vimc.cpp28
-rw-r--r--src/libcamera/pipeline_handler.cpp41
7 files changed, 101 insertions, 175 deletions
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 3192dfb4..5593c1b3 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -915,13 +915,6 @@ int Camera::start()
LOG(Camera, Debug) << "Starting capture";
- for (Stream *stream : p_->activeStreams_) {
- ret = p_->pipe_->invokeMethod(&PipelineHandler::importFrameBuffers,
- ConnectionTypeDirect, this, stream);
- if (ret < 0)
- return ret;
- }
-
ret = p_->pipe_->invokeMethod(&PipelineHandler::start,
ConnectionTypeBlocking, this);
if (ret)
@@ -959,10 +952,6 @@ int Camera::stop()
p_->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,
this);
- for (Stream *stream : p_->activeStreams_)
- p_->pipe_->invokeMethod(&PipelineHandler::freeFrameBuffers,
- ConnectionTypeBlocking, this, stream);
-
return 0;
}
diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h
index db6c3104..3fcfeda4 100644
--- a/src/libcamera/include/pipeline_handler.h
+++ b/src/libcamera/include/pipeline_handler.h
@@ -76,8 +76,6 @@ public:
virtual int exportFrameBuffers(Camera *camera, Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;
- virtual int importFrameBuffers(Camera *camera, Stream *stream) = 0;
- virtual void freeFrameBuffers(Camera *camera, Stream *stream) = 0;
virtual int start(Camera *camera) = 0;
virtual void stop(Camera *camera) = 0;
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 2edca02e..55ce8fa1 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -71,6 +71,7 @@ public:
int configureOutput(ImgUOutput *output,
const StreamConfiguration &cfg);
+ int allocateBuffers(IPU3CameraData *data, unsigned int bufferCount);
void freeBuffers(IPU3CameraData *data);
int start();
@@ -207,8 +208,6 @@ public:
int exportFrameBuffers(Camera *camera, Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
- int importFrameBuffers(Camera *camera, Stream *stream) override;
- void freeFrameBuffers(Camera *camera, Stream *stream) override;
int start(Camera *camera) override;
void stop(Camera *camera) override;
@@ -624,23 +623,6 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,
return video->exportBuffers(count, buffers);
}
-int PipelineHandlerIPU3::importFrameBuffers(Camera *camera, Stream *stream)
-{
- IPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);
- V4L2VideoDevice *video = ipu3stream->device_->dev;
- unsigned int count = stream->configuration().bufferCount;
-
- return video->importBuffers(count);
-}
-
-void PipelineHandlerIPU3::freeFrameBuffers(Camera *camera, Stream *stream)
-{
- IPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);
- V4L2VideoDevice *video = ipu3stream->device_->dev;
-
- video->releaseBuffers();
-}
-
/**
* \todo Clarify if 'viewfinder' and 'stat' nodes have to be set up and
* started even if not in use. As of now, if not properly configured and
@@ -652,69 +634,24 @@ void PipelineHandlerIPU3::freeFrameBuffers(Camera *camera, Stream *stream)
int PipelineHandlerIPU3::allocateBuffers(Camera *camera)
{
IPU3CameraData *data = cameraData(camera);
- IPU3Stream *outStream = &data->outStream_;
- IPU3Stream *vfStream = &data->vfStream_;
CIO2Device *cio2 = &data->cio2_;
ImgUDevice *imgu = data->imgu_;
unsigned int bufferCount;
int ret;
- /* Share buffers between CIO2 output and ImgU input. */
ret = cio2->allocateBuffers();
if (ret < 0)
return ret;
bufferCount = ret;
- ret = imgu->input_->importBuffers(bufferCount);
- if (ret) {
- LOG(IPU3, Error) << "Failed to import ImgU input buffers";
- goto error;
- }
-
- /*
- * Use for the stat's internal pool the same number of buffers as for
- * the input pool.
- * \todo To be revised when we'll actually use the stat node.
- */
- ret = imgu->stat_.dev->allocateBuffers(bufferCount, &imgu->stat_.buffers);
+ ret = imgu->allocateBuffers(data, bufferCount);
if (ret < 0) {
- LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers";
- goto error;
- }
-
- /*
- * Allocate buffers also on non-active outputs; use the same number
- * of buffers as the active ones.
- */
- if (!outStream->active_) {
- ImgUDevice::ImgUOutput *output = outStream->device_;
-
- ret = output->dev->allocateBuffers(bufferCount, &output->buffers);
- if (ret < 0) {
- LOG(IPU3, Error) << "Failed to allocate ImgU "
- << output->name << " buffers";
- goto error;
- }
- }
-
- if (!vfStream->active_) {
- ImgUDevice::ImgUOutput *output = vfStream->device_;
-
- ret = output->dev->allocateBuffers(bufferCount, &output->buffers);
- if (ret < 0) {
- LOG(IPU3, Error) << "Failed to allocate ImgU "
- << output->name << " buffers";
- goto error;
- }
+ cio2->freeBuffers();
+ return ret;
}
return 0;
-
-error:
- freeBuffers(camera);
-
- return ret;
}
int PipelineHandlerIPU3::freeBuffers(Camera *camera)
@@ -1156,27 +1093,82 @@ int ImgUDevice::configureOutput(ImgUOutput *output,
}
/**
+ * \brief Allocate buffers for all the ImgU video devices
+ */
+int ImgUDevice::allocateBuffers(IPU3CameraData *data, unsigned int bufferCount)
+{
+ IPU3Stream *outStream = &data->outStream_;
+ IPU3Stream *vfStream = &data->vfStream_;
+
+ /* Share buffers between CIO2 output and ImgU input. */
+ int ret = input_->importBuffers(bufferCount);
+ if (ret) {
+ LOG(IPU3, Error) << "Failed to import ImgU input buffers";
+ return ret;
+ }
+
+ /*
+ * Use for the stat's internal pool the same number of buffers as for
+ * the input pool.
+ * \todo To be revised when we'll actually use the stat node.
+ */
+ ret = stat_.dev->allocateBuffers(bufferCount, &stat_.buffers);
+ if (ret < 0) {
+ LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers";
+ goto error;
+ }
+
+ /*
+ * Allocate buffers for both outputs. If an output is active, prepare
+ * for buffer import, otherwise allocate internal buffers. Use the same
+ * number of buffers in either case.
+ */
+ if (outStream->active_)
+ ret = output_.dev->importBuffers(bufferCount);
+ else
+ ret = output_.dev->allocateBuffers(bufferCount,
+ &output_.buffers);
+ if (ret < 0) {
+ LOG(IPU3, Error) << "Failed to allocate ImgU output buffers";
+ goto error;
+ }
+
+ if (vfStream->active_)
+ ret = viewfinder_.dev->importBuffers(bufferCount);
+ else
+ ret = viewfinder_.dev->allocateBuffers(bufferCount,
+ &viewfinder_.buffers);
+ if (ret < 0) {
+ LOG(IPU3, Error) << "Failed to allocate ImgU viewfinder buffers";
+ goto error;
+ }
+
+ return 0;
+
+error:
+ freeBuffers(data);
+
+ return ret;
+}
+
+/**
* \brief Release buffers for all the ImgU video devices
*/
void ImgUDevice::freeBuffers(IPU3CameraData *data)
{
int ret;
- if (!data->outStream_.active_) {
- ret = output_.dev->releaseBuffers();
- if (ret)
- LOG(IPU3, Error) << "Failed to release ImgU output buffers";
- }
+ ret = output_.dev->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error) << "Failed to release ImgU output buffers";
ret = stat_.dev->releaseBuffers();
if (ret)
LOG(IPU3, Error) << "Failed to release ImgU stat buffers";
- if (!data->vfStream_.active_) {
- ret = viewfinder_.dev->releaseBuffers();
- if (ret)
- LOG(IPU3, Error) << "Failed to release ImgU viewfinder buffers";
- }
+ ret = viewfinder_.dev->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error) << "Failed to release ImgU viewfinder buffers";
ret = input_->releaseBuffers();
if (ret)
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index eafb6d91..737e3314 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -174,8 +174,6 @@ public:
int exportFrameBuffers(Camera *camera, Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
- int importFrameBuffers(Camera *camera, Stream *stream) override;
- void freeFrameBuffers(Camera *camera, Stream *stream) override;
int start(Camera *camera) override;
void stop(Camera *camera) override;
@@ -667,17 +665,6 @@ int PipelineHandlerRkISP1::exportFrameBuffers(Camera *camera, Stream *stream,
return video_->exportBuffers(count, buffers);
}
-int PipelineHandlerRkISP1::importFrameBuffers(Camera *camera, Stream *stream)
-{
- unsigned int count = stream->configuration().bufferCount;
- return video_->importBuffers(count);
-}
-
-void PipelineHandlerRkISP1::freeFrameBuffers(Camera *camera, Stream *stream)
-{
- video_->releaseBuffers();
-}
-
int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
{
RkISP1CameraData *data = cameraData(camera);
@@ -688,6 +675,10 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
for (const Stream *s : camera->streams())
maxBuffers = std::max(maxBuffers, s->configuration().bufferCount);
+ ret = video_->importBuffers(count);
+ if (ret < 0)
+ goto error;
+
ret = param_->allocateBuffers(maxBuffers, &paramBuffers_);
if (ret < 0)
goto error;
@@ -748,6 +739,9 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera)
if (stat_->releaseBuffers())
LOG(RkISP1, Error) << "Failed to release stat buffers";
+ if (video_->releaseBuffers())
+ LOG(RkISP1, Error) << "Failed to release video buffers";
+
return 0;
}
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 9876d8c9..73114975 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -67,8 +67,6 @@ public:
int exportFrameBuffers(Camera *camera, Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
- int importFrameBuffers(Camera *camera, Stream *stream) override;
- void freeFrameBuffers(Camera *camera, Stream *stream) override;
int start(Camera *camera) override;
void stop(Camera *camera) override;
@@ -214,31 +212,29 @@ int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,
return data->video_->exportBuffers(count, buffers);
}
-int PipelineHandlerUVC::importFrameBuffers(Camera *camera, Stream *stream)
+int PipelineHandlerUVC::start(Camera *camera)
{
UVCCameraData *data = cameraData(camera);
- unsigned int count = stream->configuration().bufferCount;
+ unsigned int count = data->stream_.configuration().bufferCount;
- return data->video_->importBuffers(count);
-}
-
-void PipelineHandlerUVC::freeFrameBuffers(Camera *camera, Stream *stream)
-{
- UVCCameraData *data = cameraData(camera);
+ int ret = data->video_->importBuffers(count);
+ if (ret < 0)
+ return ret;
- data->video_->releaseBuffers();
-}
+ ret = data->video_->streamOn();
+ if (ret < 0) {
+ data->video_->releaseBuffers();
+ return ret;
+ }
-int PipelineHandlerUVC::start(Camera *camera)
-{
- UVCCameraData *data = cameraData(camera);
- return data->video_->streamOn();
+ return 0;
}
void PipelineHandlerUVC::stop(Camera *camera)
{
UVCCameraData *data = cameraData(camera);
data->video_->streamOff();
+ data->video_->releaseBuffers();
}
int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 097bbd5b..fa84f0c1 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -83,8 +83,6 @@ public:
int exportFrameBuffers(Camera *camera, Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
- int importFrameBuffers(Camera *camera, Stream *stream) override;
- void freeFrameBuffers(Camera *camera, Stream *stream) override;
int start(Camera *camera) override;
void stop(Camera *camera) override;
@@ -267,31 +265,29 @@ int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream,
return data->video_->exportBuffers(count, buffers);
}
-int PipelineHandlerVimc::importFrameBuffers(Camera *camera, Stream *stream)
+int PipelineHandlerVimc::start(Camera *camera)
{
VimcCameraData *data = cameraData(camera);
- unsigned int count = stream->configuration().bufferCount;
+ unsigned int count = data->stream_.configuration().bufferCount;
- return data->video_->importBuffers(count);
-}
-
-void PipelineHandlerVimc::freeFrameBuffers(Camera *camera, Stream *stream)
-{
- VimcCameraData *data = cameraData(camera);
+ int ret = data->video_->importBuffers(count);
+ if (ret < 0)
+ return ret;
- data->video_->releaseBuffers();
-}
+ ret = data->video_->streamOn();
+ if (ret < 0) {
+ data->video_->releaseBuffers();
+ return ret;
+ }
-int PipelineHandlerVimc::start(Camera *camera)
-{
- VimcCameraData *data = cameraData(camera);
- return data->video_->streamOn();
+ return 0;
}
void PipelineHandlerVimc::stop(Camera *camera)
{
VimcCameraData *data = cameraData(camera);
data->video_->streamOff();
+ data->video_->releaseBuffers();
}
int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request)
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index e5034c54..254d341f 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -325,7 +325,7 @@ const ControlList &PipelineHandler::properties(Camera *camera)
/**
* \fn PipelineHandler::exportFrameBuffers()
- * \brief Allocate buffers for \a stream
+ * \brief Allocate and export buffers for \a stream
* \param[in] camera The camera
* \param[in] stream The stream to allocate buffers for
* \param[out] buffers Array of buffers successfully allocated
@@ -348,45 +348,6 @@ const ControlList &PipelineHandler::properties(Camera *camera)
*/
/**
- * \fn PipelineHandler::importFrameBuffers()
- * \brief Prepare \a stream to use external buffers
- * \param[in] camera The camera
- * \param[in] stream The stream to prepare for import
- *
- * This method prepares the pipeline handler to use buffers provided by the
- * application for the \a stream.
- *
- * The method may only be called after the Camera has been configured and before
- * it gets started, or after it gets stopped. It shall be called only for
- * streams that are part of the active camera configuration, and at most once
- * per stream until buffers for the stream are freed with freeFrameBuffers().
- *
- * importFrameBuffers() shall also allocate all other resources required by the
- * pipeline handler for the stream to prepare for starting the Camera.
- *
- * The only intended caller is Camera::start().
- *
- * \context This function is called from the CameraManager thread.
- *
- * \return 0 on success or a negative error code otherwise
- */
-
-/**
- * \fn PipelineHandler::freeFrameBuffers()
- * \brief Free buffers allocated from the stream
- * \param[in] camera The camera
- * \param[in] stream The stream to free buffers for
- *
- * This method shall release all resources allocated for the \a stream by
- * importFrameBuffers(). It shall be called only after a successful call that
- * method, and only once per stream.
- *
- * The only intended callers are Camera::stop() and Camera::freeFrameBuffers().
- *
- * \context This function is called from the CameraManager thread.
- */
-
-/**
* \fn PipelineHandler::start()
* \brief Start capturing from a group of streams
* \param[in] camera The camera to start