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-17 14:59:21 +02:00
parent c0586867a9
commit 0c5523c908
4 changed files with 28 additions and 14 deletions
+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();
}
}