[PATCH v2 3/7] libcamera: rkisp1: Track request->sequence() instead of frame_
Dan Scally
dan.scally at ideasonboard.com
Wed Feb 21 11:36:01 CET 2024
Hi Jacopo, thanks for the review
On 21/02/2024 10:00, Jacopo Mondi wrote:
> Hi Dan
>
> On Tue, Feb 20, 2024 at 04:43:13PM +0000, Daniel Scally wrote:
>> The rkisp1 pipeline handler currently tries to track the frame number
>> from V4L2 to provide an index to the IPA module's FCQueue - this is
>> not necessary, the Request's sequence does the same job perfectly
>> well.
>>
>> Note that the association of controls and calculated parameters with
>> specific frames is not affected here - the parameters are always
>> applied based on the most recently processed statistics, and the
>> applied controls are fetched separately using the V4L2 provided
>> buffer->metadata().sequence, which value is also internally tracked
>> by DelayedControls.
> Considering that currently data->frame_ gets incremented only when a
> new request is queued, this doesn't (in principle) change the
> current behaviour if not for the removal of:
>
> if (data->frame_ <= buffer->metadata().sequence)
> data->frame_ = buffer->metadata().sequence + 1;
>
> The RkISP1 ISP driver has a global frame counter, shared by all video
> devices, which is incremented at each vsync. Being the ISP in-line,
> the sequence number in buffers coming from the video devices actually
> represent the sensor's frame sequence numbers.
>
> The above lines adjust the frame_ value to the 'next' sensor's frame
> number in case of a request underrun from the application (ie
> application does not provide requests fast enough to keep up with the
> frames produced by the sensor).
>
> Now, with your change we always index frames on the IPA FCQ with a
> consecutive incresaing counter with no gaps in between (the request
> sequence number). How does this work in the context of
> per-frame-control ?
I'm not really clear how that is envisioned to work, so I don't know.
> Will we be able to detect request queueing
> underrun and tell applications that they're late (the PFC error
> condition we spoke when implementing FCQ) ?
On bufferComplete we will, because buffer->metadata().sequence will differ from
buffer->request()->sequence.
>
> With this change we lose the notion of "which frame (as produced by
> the sensor) a request is associated with" and even if delayed controls
> helps by tracking the sensor's controls separately, it's something which
> might not have implications on the current non-PFC implementation, but
> will have to be taken into account once we move in that direction ?
>
> (How is this patch related to the rest of the series ? Is it required
> to get rid of FrameInfo ?)
It's required in the sense that by the time bufferReady()/statReady() is called the data->frame_
member will have been advanced by a subsequent call to queueRequestDevice(), so we couldn't stick to
the current behaviour of using frame number to index the FCQ without somehow tracking the frame
number for a particular request (currently that's done through info->frame which is set in
queueRequestDevice()). If we need to do that to maintain the current behaviour then let's just go
with your plan of deriving a pipeline specific Request::Private class so we can store it there.
Thanks
Dan
>
>> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
>> ---
>> Changes in v2:
>>
>> - In statReady() I no longer used request->sequence() to fetch from
>> delayedCtrls_ - ensuring that we only use the V4L2 reported sequence
>> there.
>>
>> src/libcamera/pipeline/rkisp1/rkisp1.cpp | 23 +++++++++--------------
>> 1 file changed, 9 insertions(+), 14 deletions(-)
>>
>> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
>> index 586b46d6..d926c83c 100644
>> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
>> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
>> @@ -88,7 +88,7 @@ class RkISP1CameraData : public Camera::Private
>> public:
>> RkISP1CameraData(PipelineHandler *pipe, RkISP1MainPath *mainPath,
>> RkISP1SelfPath *selfPath)
>> - : Camera::Private(pipe), frame_(0), frameInfo_(pipe),
>> + : Camera::Private(pipe), frameInfo_(pipe),
>> mainPath_(mainPath), selfPath_(selfPath)
>> {
>> }
>> @@ -100,7 +100,6 @@ public:
>> Stream selfPathStream_;
>> std::unique_ptr<CameraSensor> sensor_;
>> std::unique_ptr<DelayedControls> delayedCtrls_;
>> - unsigned int frame_;
>> std::vector<IPABuffer> ipaBuffers_;
>> RkISP1Frames frameInfo_;
>>
>> @@ -214,7 +213,7 @@ RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)
>> RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request,
>> bool isRaw)
>> {
>> - unsigned int frame = data->frame_;
>> + unsigned int frame = request->sequence();
>>
>> FrameBuffer *paramBuffer = nullptr;
>> FrameBuffer *statBuffer = nullptr;
>> @@ -235,6 +234,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req
>>
>> statBuffer = pipe_->availableStatBuffers_.front();
>> pipe_->availableStatBuffers_.pop();
>> + statBuffer->_d()->setRequest(request);
>> }
>>
>> FrameBuffer *mainPathBuffer = request->findBuffer(&data->mainPathStream_);
>> @@ -935,8 +935,6 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
>> return ret;
>> }
>>
>> - data->frame_ = 0;
>> -
>> if (!isRaw_) {
>> ret = param_->streamOn();
>> if (ret) {
>> @@ -1028,7 +1026,7 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
>> if (!info)
>> return -ENOENT;
>>
>> - data->ipa_->queueRequest(data->frame_, request->controls());
>> + data->ipa_->queueRequest(request->sequence(), request->controls());
>> if (isRaw_) {
>> if (info->mainPathBuffer)
>> data->mainPath_->queueBuffer(info->mainPathBuffer);
>> @@ -1036,12 +1034,10 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
>> if (data->selfPath_ && info->selfPathBuffer)
>> data->selfPath_->queueBuffer(info->selfPathBuffer);
>> } else {
>> - data->ipa_->fillParamsBuffer(data->frame_,
>> + data->ipa_->fillParamsBuffer(request->sequence(),
>> info->paramBuffer->cookie());
>> }
>>
>> - data->frame_++;
>> -
>> return 0;
>> }
>>
>> @@ -1276,7 +1272,8 @@ void PipelineHandlerRkISP1::bufferReady(FrameBuffer *buffer)
>> if (isRaw_) {
>> const ControlList &ctrls =
>> data->delayedCtrls_->get(metadata.sequence);
>> - data->ipa_->processStatsBuffer(info->frame, 0, ctrls);
>> + data->ipa_->processStatsBuffer(request->sequence(),
>> + 0, ctrls);
>> }
>> } else {
>> if (isRaw_)
>> @@ -1304,6 +1301,7 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)
>> {
>> ASSERT(activeCamera_);
>> RkISP1CameraData *data = cameraData(activeCamera_);
>> + Request *request = buffer->request();
>>
>> RkISP1FrameInfo *info = data->frameInfo_.find(buffer);
>> if (!info)
>> @@ -1315,10 +1313,7 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)
>> return;
>> }
>>
>> - if (data->frame_ <= buffer->metadata().sequence)
>> - data->frame_ = buffer->metadata().sequence + 1;
>> -
>> - data->ipa_->processStatsBuffer(info->frame, info->statBuffer->cookie(),
>> + data->ipa_->processStatsBuffer(request->sequence(), info->statBuffer->cookie(),
>> data->delayedCtrls_->get(buffer->metadata().sequence));
>> }
>>
>> --
>> 2.34.1
>>
More information about the libcamera-devel
mailing list