diff options
-rw-r--r-- | src/libcamera/camera.cpp | 11 | ||||
-rw-r--r-- | src/libcamera/include/pipeline_handler.h | 2 | ||||
-rw-r--r-- | src/libcamera/pipeline/ipu3/ipu3.cpp | 146 | ||||
-rw-r--r-- | src/libcamera/pipeline/rkisp1/rkisp1.cpp | 20 | ||||
-rw-r--r-- | src/libcamera/pipeline/uvcvideo.cpp | 28 | ||||
-rw-r--r-- | src/libcamera/pipeline/vimc.cpp | 28 | ||||
-rw-r--r-- | src/libcamera/pipeline_handler.cpp | 41 |
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, ¶mBuffers_); 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 |