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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user