From 4cb388a1eb683149c922391d5cf3a72e82a10ffb Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 11 Dec 2025 23:22:40 +0000 Subject: [PATCH] libcamera: software_isp: debayer: Introduce a start() / stop() methods to the debayer object In order to initialise and deinitialise gpuisp we need to be able to setup EGL in the same thread as Debayer::process() happens in. This requires extending the Debayer object to provide start and stop methods which are triggered through invokeMethod in the same way as process() is. Introduce start() and stop() methods to the Debayer class. Trigger those methods as described above via invokeMethod. The debayer_egl class will take care of initialising and de-initialising as necessary. Debayer CPU sees no functional change. Per feedback from Barnabas the stop method is using blocking synchronisation and thus we drop ispWorkerThread_.removeMessages(). [bod: Made method blocking not queued per Robert's bugfixes] Signed-off-by: Bryan O'Donoghue Reviewed-by: Milan Zamazal Signed-off-by: Kieran Bingham --- src/libcamera/software_isp/debayer.cpp | 25 +++++++++++++++++++++ src/libcamera/software_isp/debayer.h | 2 ++ src/libcamera/software_isp/software_isp.cpp | 8 +++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 4b6bab7f..25d83e88 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -336,6 +336,31 @@ Debayer::~Debayer() * debayer processing. */ +/** + * \fn int Debayer::start() + * \brief Execute a start signal in the debayer object from workerthread context + * + * The start() method is invoked so that a Debayer object can initialise + * internal variables or data. It is called from the software_isp::start + * method. + * + * This method is particularly useful with DebayerEGL as it allows for the + * initialisation of the EGL stack after configure in a thread-safe manner. + */ + +/** + * \fn void Debayer::stop() + * \brief Stop the debayering process and perform cleanup + * + * The stop() method is invoked as the logically corollary of start(). + * Debayer::stop() will be called by software_isp::stop() allowing for any + * cleanup which should happend with stop(). + * + * The stop method similar to start() is useful for DebayerEGL as it allows + * for cleanup of EGL context and/or data that happens in + * DebayerEGL::start. + */ + /** * \fn void Debayer::setParams(DebayerParams ¶ms) * \brief Select the bayer params to use for the next frame debayer diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index 807dfabc..b8287166 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -48,6 +48,8 @@ public: strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0; virtual void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params) = 0; + virtual int start() { return 0; } + virtual void stop() {} virtual SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) = 0; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 928a2520..7c9ad916 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -347,7 +347,9 @@ int SoftwareIsp::start() return ret; ispWorkerThread_.start(); - return 0; + + return debayer_->invokeMethod(&DebayerCpu::start, + ConnectionTypeBlocking); } /** @@ -358,9 +360,11 @@ int SoftwareIsp::start() */ void SoftwareIsp::stop() { + debayer_->invokeMethod(&DebayerCpu::stop, + ConnectionTypeBlocking); + ispWorkerThread_.exit(); ispWorkerThread_.wait(); - ispWorkerThread_.removeMessages(debayer_.get()); Thread::current()->dispatchMessages(Message::Type::InvokeMessage, this);