libcamera: pipeline_handler: Move waitingRequests_ into camera class

The waiting requests of one camera should not be able to influence
queuing to another camera. Currently a request that is in the
waitingQueue and waiting for preparation blocks all requests of other
cameras even if they are already prepared. To fix that replace the
single waitingRequests_ queue with one queue per camera.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Umang Jain <uajain@igalia.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Sven Püschel <s.pueschel@pengutronix.de>
This commit is contained in:
Stefan Klug
2025-07-18 12:53:29 +02:00
parent c0586867a9
commit 0c5523c908
4 changed files with 28 additions and 14 deletions
+2
View File
@@ -10,6 +10,7 @@
#include <atomic>
#include <list>
#include <memory>
#include <queue>
#include <set>
#include <stdint.h>
#include <string>
@@ -36,6 +37,7 @@ public:
const PipelineHandler *pipe() const { return pipe_.get(); }
std::list<Request *> queuedRequests_;
std::queue<Request *> waitingRequests_;
ControlInfoMap controlInfo_;
ControlList properties_;
@@ -8,7 +8,6 @@
#pragma once
#include <memory>
#include <queue>
#include <string>
#include <sys/types.h>
#include <vector>
@@ -89,13 +88,11 @@ private:
virtual void disconnect();
void doQueueRequest(Request *request);
void doQueueRequests();
void doQueueRequests(Camera *camera);
std::vector<std::shared_ptr<MediaDevice>> mediaDevices_;
std::vector<std::weak_ptr<Camera>> cameras_;
std::queue<Request *> waitingRequests_;
const char *name_;
unsigned int useCount_;
+9
View File
@@ -628,6 +628,15 @@ Camera::Private::~Private()
* PipelineHandler::completeRequest()
*/
/**
* \var Camera::Private::waitingRequests_
* \brief The queue of waiting requests
*
* This queue tracks all requests that can not yet be queued to the device.
* Either because they are not yet prepared or because the maximum number of
* queued requests was reached.
*/
/**
* \var Camera::Private::controlInfo_
* \brief The set of controls supported by the camera
+16 -10
View File
@@ -363,15 +363,16 @@ void PipelineHandler::stop(Camera *camera)
/* Stop the pipeline handler and let the queued requests complete. */
stopDevice(camera);
Camera::Private *data = camera->_d();
/* Cancel and signal as complete all waiting requests. */
while (!waitingRequests_.empty()) {
Request *request = waitingRequests_.front();
waitingRequests_.pop();
while (!data->waitingRequests_.empty()) {
Request *request = data->waitingRequests_.front();
data->waitingRequests_.pop();
cancelRequest(request);
}
/* Make sure no requests are pending. */
Camera::Private *data = camera->_d();
ASSERT(data->queuedRequests_.empty());
data->requestSequence_ = 0;
@@ -414,7 +415,9 @@ void PipelineHandler::registerRequest(Request *request)
* Connect the request prepared signal to notify the pipeline handler
* when a request is ready to be processed.
*/
request->_d()->prepared.connect(this, &PipelineHandler::doQueueRequests);
request->_d()->prepared.connect(this, [this, request]() {
doQueueRequests(request->_d()->camera());
});
}
/**
@@ -444,7 +447,9 @@ void PipelineHandler::queueRequest(Request *request)
{
LIBCAMERA_TRACEPOINT(request_queue, request);
waitingRequests_.push(request);
Camera *camera = request->_d()->camera();
Camera::Private *data = camera->_d();
data->waitingRequests_.push(request);
request->_d()->prepare(300ms);
}
@@ -478,15 +483,16 @@ void PipelineHandler::doQueueRequest(Request *request)
* Iterate the list of waiting requests and queue them to the device one
* by one if they have been prepared.
*/
void PipelineHandler::doQueueRequests()
void PipelineHandler::doQueueRequests(Camera *camera)
{
while (!waitingRequests_.empty()) {
Request *request = waitingRequests_.front();
Camera::Private *data = camera->_d();
while (!data->waitingRequests_.empty()) {
Request *request = data->waitingRequests_.front();
if (!request->_d()->prepared_)
break;
doQueueRequest(request);
waitingRequests_.pop();
data->waitingRequests_.pop();
}
}