libcamera: software_isp: Handle queued output buffers on stop

When SoftwareIsp stops, input and output buffers queued to it may not
yet be fully processed.  They will be eventually returned but stop means
stop, there should be no processing related actions invoked afterwards.

Let's stop forwarding processed output buffers from the SoftwareIsp
slots once SoftwareIsp is stopped.  Let's track the queued output
buffers and mark those still pending as cancelled in SoftwareIsp::stop
and return them to the pipeline handler.

Dealing with input buffers is addressed in a separate patch.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Milan Zamazal 2025-02-25 16:06:08 +01:00 committed by Kieran Bingham
parent b72d789475
commit ba4715ffed
2 changed files with 22 additions and 3 deletions

View file

@ -7,6 +7,7 @@
#pragma once
#include <deque>
#include <functional>
#include <initializer_list>
#include <map>
@ -101,6 +102,7 @@ private:
std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
bool running_;
std::deque<FrameBuffer *> queuedOutputBuffers_;
};
} /* namespace libcamera */

View file

@ -13,10 +13,13 @@
#include <sys/types.h>
#include <unistd.h>
#include <libcamera/base/log.h>
#include <libcamera/controls.h>
#include <libcamera/formats.h>
#include <libcamera/stream.h>
#include "libcamera/internal/framebuffer.h"
#include "libcamera/internal/ipa_manager.h"
#include "libcamera/internal/software_isp/debayer_params.h"
@ -300,8 +303,11 @@ int SoftwareIsp::queueBuffers(uint32_t frame, FrameBuffer *input,
return -EINVAL;
}
for (auto iter = outputs.begin(); iter != outputs.end(); iter++)
process(frame, input, iter->second);
for (auto iter = outputs.begin(); iter != outputs.end(); iter++) {
FrameBuffer *const buffer = iter->second;
queuedOutputBuffers_.push_back(buffer);
process(frame, input, buffer);
}
return 0;
}
@ -331,6 +337,13 @@ void SoftwareIsp::stop()
running_ = false;
ipa_->stop();
for (auto buffer : queuedOutputBuffers_) {
FrameMetadata &metadata = buffer->_d()->metadata();
metadata.status = FrameMetadata::FrameCancelled;
outputBufferReady.emit(buffer);
}
queuedOutputBuffers_.clear();
}
/**
@ -369,7 +382,11 @@ void SoftwareIsp::inputReady(FrameBuffer *input)
void SoftwareIsp::outputReady(FrameBuffer *output)
{
outputBufferReady.emit(output);
if (running_) {
ASSERT(queuedOutputBuffers_.front() == output);
queuedOutputBuffers_.pop_front();
outputBufferReady.emit(output);
}
}
} /* namespace libcamera */