@@ -1099,14 +1099,15 @@ int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S
int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
{
RkISP1CameraData *data = cameraData(camera);
+ utils::ScopeExitActions actions;
unsigned int ipaBufferId = 1;
int ret;
- auto errorCleanup = utils::scope_exit{ [&]() {
+ actions += [&]() {
paramBuffers_.clear();
statBuffers_.clear();
mainPathBuffers_.clear();
- } };
+ };
if (!isRaw_) {
ret = param_->allocateBuffers(kRkISP1InternalBufferCount, ¶mBuffers_);
@@ -1127,6 +1128,22 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
for (std::unique_ptr<FrameBuffer> &buffer : mainPathBuffers_)
availableMainPathBuffers_.push(buffer.get());
+ } else if (data->mainPath_->isEnabled()) {
+ ret = mainPath_.importBuffers(data->mainPathStream_.configuration().bufferCount);
+
+ if (ret < 0)
+ return ret;
+
+ actions += [&]() { mainPath_.releaseBuffers(); };
+ }
+
+ if (hasSelfPath_ && data->selfPath_->isEnabled()) {
+ ret = selfPath_.importBuffers(data->selfPathStream_.configuration().bufferCount);
+
+ if (ret < 0)
+ return ret;
+
+ actions += [&]() { selfPath_.releaseBuffers(); };
}
auto pushBuffers = [&](const std::vector<std::unique_ptr<FrameBuffer>> &buffers,
@@ -1147,7 +1164,7 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
data->ipa_->mapBuffers(data->ipaBuffers_);
- errorCleanup.release();
+ actions.release();
return 0;
}
@@ -1181,6 +1198,12 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera)
if (stat_->releaseBuffers())
LOG(RkISP1, Error) << "Failed to release stat buffers";
+ if (mainPath_.releaseBuffers())
+ LOG(RkISP1, Error) << "Failed to release main path buffers";
+
+ if (hasSelfPath_ && selfPath_.releaseBuffers())
+ LOG(RkISP1, Error) << "Failed to release self path buffers";
+
return 0;
}
@@ -1263,16 +1286,17 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
}
if (data->mainPath_->isEnabled()) {
- ret = mainPath_.start(data->mainPathStream_.configuration().bufferCount);
+ ret = mainPath_.streamOn();
if (ret)
return ret;
- actions += [&]() { mainPath_.stop(); };
+ actions += [&]() { mainPath_.streamOff(); };
}
if (hasSelfPath_ && data->selfPath_->isEnabled()) {
- ret = selfPath_.start(data->selfPathStream_.configuration().bufferCount);
+ ret = selfPath_.streamOn();
if (ret)
return ret;
+ actions += [&]() { selfPath_.streamOff(); };
}
isp_->setFrameStartEnabled(true);
@@ -1299,8 +1323,8 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera)
data->ipa_->stop();
if (hasSelfPath_)
- selfPath_.stop();
- mainPath_.stop();
+ selfPath_.streamOff();
+ mainPath_.streamOff();
if (!isRaw_) {
ret = stat_->streamOff();
@@ -1664,9 +1688,9 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
return false;
isp_->frameStart.connect(this, &PipelineHandlerRkISP1::frameStart);
- mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::imageBufferReady);
+ mainPath_.bufferReady.connect(this, &PipelineHandlerRkISP1::imageBufferReady);
if (hasSelfPath_)
- selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::imageBufferReady);
+ selfPath_.bufferReady.connect(this, &PipelineHandlerRkISP1::imageBufferReady);
stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statBufferReady);
param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramBufferReady);
@@ -8,6 +8,7 @@
#include "rkisp1_path.h"
#include <array>
+#include <memory>
#include <linux/media-bus-format.h>
@@ -58,7 +59,7 @@ const std::map<PixelFormat, uint32_t> formatToMediaBus = {
RkISP1Path::RkISP1Path(const char *name, const Span<const PixelFormat> &formats,
const Size &minResolution, const Size &maxResolution)
- : name_(name), running_(false), formats_(formats),
+ : name_(name), formats_(formats),
minResolution_(minResolution), maxResolution_(maxResolution),
link_(nullptr)
{
@@ -77,6 +78,7 @@ bool RkISP1Path::init(std::shared_ptr<MediaDevice> media)
if (video_->open() < 0)
return false;
+ video_->bufferReady.connect(this, [this](FrameBuffer *buffer) { this->bufferReady.emit(buffer); });
populateFormats();
link_ = media->link("rkisp1_isp", 2, resizer, 0);
@@ -480,44 +482,6 @@ int RkISP1Path::configure(const StreamConfiguration &config,
return 0;
}
-int RkISP1Path::start(unsigned int bufferCount)
-{
- int ret;
-
- if (running_)
- return -EBUSY;
-
- ret = video_->importBuffers(bufferCount);
- if (ret)
- return ret;
-
- ret = video_->streamOn();
- if (ret) {
- LOG(RkISP1, Error)
- << "Failed to start " << name_ << " path";
-
- video_->releaseBuffers();
- return ret;
- }
-
- running_ = true;
-
- return 0;
-}
-
-void RkISP1Path::stop()
-{
- if (!running_)
- return;
-
- if (video_->streamOff())
- LOG(RkISP1, Warning) << "Failed to stop " << name_ << " path";
-
- video_->releaseBuffers();
-
- running_ = false;
-}
-
/*
* \todo Remove the hardcoded resolutions and formats once kernels older than
* v6.4 will stop receiving LTS support (scheduled for December 2027 for v6.1).
@@ -58,19 +58,34 @@ public:
return video_->exportBuffers(bufferCount, buffers);
}
- int start(unsigned int bufferCount);
- void stop();
+ int allocateBuffers(unsigned int bufferCount,
+ std::vector<std::unique_ptr<FrameBuffer>> *buffers)
+ {
+ return video_->allocateBuffers(bufferCount, buffers);
+ }
+
+ int importBuffers(unsigned int count)
+ {
+ return video_->importBuffers(count);
+ }
+
+ int releaseBuffers()
+ {
+ return video_->releaseBuffers();
+ }
+
+ int streamOn() { return video_->streamOn(); };
+ int streamOff() { return video_->streamOff(); };
int queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); }
- Signal<FrameBuffer *> &bufferReady() { return video_->bufferReady; }
const Size &maxResolution() const { return maxResolution_; }
+ Signal<FrameBuffer *> bufferReady;
private:
void populateFormats();
Size filterSensorResolution(const CameraSensor *sensor);
const char *name_;
- bool running_;
const Span<const PixelFormat> formats_;
std::set<PixelFormat> streamFormats_;
The BufferQueue delegate expects an interface equal to the one provided by the V4L2VideoDevice. Modify the RkISP1Path class to support that interface to prepare for the migration to BufferQueue. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> --- Changes in v2: - Added this patch --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 44 ++++++++++++++----- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 42 ++---------------- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 23 ++++++++-- 3 files changed, 56 insertions(+), 53 deletions(-)