libcamera: software_isp: Handle queued input 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 input buffers from SoftwareIsp slots
when SoftwareIsp is stopped.  Let's track the queued input buffers and
return them back for capture in SoftwareIsp::stop().

The returned input buffers are marked as cancelled.  This is not
necessary at the moment but it gives the pipeline handlers chance to
deal with this if they need to.

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:09 +01:00 committed by Kieran Bingham
parent ba4715ffed
commit cd32e069ec
2 changed files with 18 additions and 1 deletions

View file

@ -102,6 +102,7 @@ private:
std::unique_ptr<ipa::soft::IPAProxySoft> ipa_; std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
bool running_; bool running_;
std::deque<FrameBuffer *> queuedInputBuffers_;
std::deque<FrameBuffer *> queuedOutputBuffers_; std::deque<FrameBuffer *> queuedOutputBuffers_;
}; };

View file

@ -303,6 +303,8 @@ int SoftwareIsp::queueBuffers(uint32_t frame, FrameBuffer *input,
return -EINVAL; return -EINVAL;
} }
queuedInputBuffers_.push_back(input);
for (auto iter = outputs.begin(); iter != outputs.end(); iter++) { for (auto iter = outputs.begin(); iter != outputs.end(); iter++) {
FrameBuffer *const buffer = iter->second; FrameBuffer *const buffer = iter->second;
queuedOutputBuffers_.push_back(buffer); queuedOutputBuffers_.push_back(buffer);
@ -329,6 +331,9 @@ int SoftwareIsp::start()
/** /**
* \brief Stops the Software ISP streaming operation * \brief Stops the Software ISP streaming operation
*
* All pending buffers are returned back as canceled before this function
* returns.
*/ */
void SoftwareIsp::stop() void SoftwareIsp::stop()
{ {
@ -344,6 +349,13 @@ void SoftwareIsp::stop()
outputBufferReady.emit(buffer); outputBufferReady.emit(buffer);
} }
queuedOutputBuffers_.clear(); queuedOutputBuffers_.clear();
for (auto buffer : queuedInputBuffers_) {
FrameMetadata &metadata = buffer->_d()->metadata();
metadata.status = FrameMetadata::FrameCancelled;
inputBufferReady.emit(buffer);
}
queuedInputBuffers_.clear();
} }
/** /**
@ -377,8 +389,12 @@ void SoftwareIsp::statsReady(uint32_t frame, uint32_t bufferId)
void SoftwareIsp::inputReady(FrameBuffer *input) void SoftwareIsp::inputReady(FrameBuffer *input)
{ {
if (running_) {
ASSERT(queuedInputBuffers_.front() == input);
queuedInputBuffers_.pop_front();
inputBufferReady.emit(input); inputBufferReady.emit(input);
} }
}
void SoftwareIsp::outputReady(FrameBuffer *output) void SoftwareIsp::outputReady(FrameBuffer *output)
{ {