[RFC PATCH 1/4] libcamera: pipeline_handler: Move waitingRequests_ into camera class
Sven Püschel
s.pueschel at pengutronix.de
Tue May 27 11:06:31 CEST 2025
Hi Barnabás,
On 5/27/25 09:27, Barnabás Pőcze wrote:
> Hi
>
> 2025. 05. 26. 23:42 keltezéssel, Stefan Klug írta:
>> The waiting requests of one camera should not be able to influence
>> queuing to another camera. Therefore change the single waitingRequests_
>> queue into one queue per camera.
>>
>> Signed-off-by: Stefan Klug <stefan.klug at ideasonboard.com>
>> ---
>> include/libcamera/internal/camera.h | 2 ++
>> include/libcamera/internal/pipeline_handler.h | 3 --
>> src/libcamera/pipeline_handler.cpp | 34 +++++++++++++------
>> 3 files changed, 25 insertions(+), 14 deletions(-)
>>
>> diff --git a/include/libcamera/internal/camera.h
>> b/include/libcamera/internal/camera.h
>> index 18f5c32a18e4..8a2e9ed5894d 100644
>> --- a/include/libcamera/internal/camera.h
>> +++ b/include/libcamera/internal/camera.h
>> @@ -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_;
>>
>> diff --git a/include/libcamera/internal/pipeline_handler.h
>> b/include/libcamera/internal/pipeline_handler.h
>> index 972a2fa65310..dedc29e815fb 100644
>> --- a/include/libcamera/internal/pipeline_handler.h
>> +++ b/include/libcamera/internal/pipeline_handler.h
>> @@ -8,7 +8,6 @@
>> #pragma once
>>
>> #include <memory>
>> -#include <queue>
>> #include <string>
>> #include <sys/types.h>
>> #include <vector>
>> @@ -94,8 +93,6 @@ private:
>> std::vector<std::shared_ptr<MediaDevice>> mediaDevices_;
>> std::vector<std::weak_ptr<Camera>> cameras_;
>>
>> - std::queue<Request *> waitingRequests_;
>> -
>> const char *name_;
>> unsigned int useCount_;
>>
>> diff --git a/src/libcamera/pipeline_handler.cpp
>> b/src/libcamera/pipeline_handler.cpp
>> index d84dff3c9f19..14d8602e67d8 100644
>> --- a/src/libcamera/pipeline_handler.cpp
>> +++ b/src/libcamera/pipeline_handler.cpp
>> @@ -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;
>> @@ -444,7 +445,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);
>> }
>> @@ -480,13 +483,20 @@ void PipelineHandler::doQueueRequest(Request
>> *request)
>> */
>> void PipelineHandler::doQueueRequests()
>> {
>> - while (!waitingRequests_.empty()) {
>> - Request *request = waitingRequests_.front();
>> - if (!request->_d()->prepared_)
>> - break;
>> + for (const std::weak_ptr<Camera> &ptr : cameras_) {
>> + std::shared_ptr<Camera> camera = ptr.lock();
>> + if (!camera)
>> + continue;
>>
>> - doQueueRequest(request);
>> - waitingRequests_.pop();
>> + Camera::Private *data = camera->_d();
>> + while (!data->waitingRequests_.empty()) {
>
> As far as I understand `doQueueRequests()` runs when a request becomes
> "prepared".
> So I would expect the above inner loop to be sufficient. Is there any
> reason why
> the waiting request queues of all cameras are processed?
This results from the fact that the patchset splits the waitingRequests_
from the PipelineHandler to the (multiple) individual Camera classes.
Therefore an additional outer loop is necessary to iterate though all
camera class instances holding potential waitingRequests_.
I would propose to add a Camera shared pointer as an argument to the
doQueueRequests function (and adjust the signal) to avoid looping over
all cameras.
>
>
>> + Request *request = data->waitingRequests_.front();
>> + if (!request->_d()->prepared_)
>> + break;
>> +
>> + doQueueRequest(request);
>> + data->waitingRequests_.pop();
>> + }
>> }
>> }
>>
>> @@ -562,6 +572,8 @@ void PipelineHandler::completeRequest(Request
>> *request)
>> data->queuedRequests_.pop_front();
>> camera->requestComplete(req);
>> }
>> +
>> + doQueueRequests();
>
> This only purpose of this is to handle early stopping due to
> `maxQueuedRequestsDevice()`, right?
> If so, then I think this should be in the next patch.
yeah, exactly. I agree to move it to the next patch.
Sincerely
Sven
>
>
> Regards,
> Barnabás Pőcze
>
>
>> }
>>
>> /**
>> --
>> 2.43.0
>>
>
>
More information about the libcamera-devel
mailing list