[libcamera-devel] [PATCH 2/3] pipeline: raspberrypi: Simplify image/embedded buffer matching logic
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Feb 8 00:54:19 CET 2022
Hi Naush,
Thank you for the patch.
On Mon, Feb 07, 2022 at 03:12:13PM +0000, Naushir Patuck wrote:
> Simplify the image and embedded buffer matching logic by removing the assumption
> that we require a buffer match between the two streams. Instead, if an image
> buffer does not match with an embedded data buffer, simply use the ControlList
> provided by DelayedControls for the sensor parameters.
>
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> ---
> .../pipeline/raspberrypi/raspberrypi.cpp | 141 ++++--------------
> 1 file changed, 31 insertions(+), 110 deletions(-)
>
> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> index 0755de84c70c..af234bd18c5b 100644
> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> @@ -2081,122 +2081,43 @@ void RPiCameraData::tryRunPipeline()
>
> bool RPiCameraData::findMatchingBuffers(BayerFrame &bayerFrame, FrameBuffer *&embeddedBuffer)
> {
> - unsigned int embeddedRequeueCount = 0, bayerRequeueCount = 0;
> -
> - /* Loop until we find a matching bayer and embedded data buffer. */
> - while (!bayerQueue_.empty()) {
> - /* Start with the front of the bayer queue. */
> - FrameBuffer *bayerBuffer = bayerQueue_.front().buffer;
> -
> - /*
> - * Find the embedded data buffer with a matching timestamp to pass to
> - * the IPA. Any embedded buffers with a timestamp lower than the
> - * current bayer buffer will be removed and re-queued to the driver.
> - */
> - uint64_t ts = bayerBuffer->metadata().timestamp;
> - embeddedBuffer = nullptr;
> - while (!embeddedQueue_.empty()) {
> - FrameBuffer *b = embeddedQueue_.front();
> - if (!unicam_[Unicam::Embedded].isExternal() && b->metadata().timestamp < ts) {
> - embeddedQueue_.pop();
> - unicam_[Unicam::Embedded].returnBuffer(b);
> - embeddedRequeueCount++;
> - LOG(RPI, Warning) << "Dropping unmatched input frame in stream "
> - << unicam_[Unicam::Embedded].name();
> - } else if (unicam_[Unicam::Embedded].isExternal() || b->metadata().timestamp == ts) {
> - /* We pop the item from the queue lower down. */
> - embeddedBuffer = b;
> - break;
> - } else {
> - break; /* Only higher timestamps from here. */
> - }
> - }
> -
> - if (!embeddedBuffer) {
> - bool flushedBuffers = false;
> -
> - LOG(RPI, Debug) << "Could not find matching embedded buffer";
> -
> - if (!sensorMetadata_) {
> - /*
> - * If there is no sensor metadata, simply return the
> - * first bayer frame in the queue.
> - */
> - LOG(RPI, Debug) << "Returning bayer frame without a match";
> - bayerFrame = std::move(bayerQueue_.front());
> - bayerQueue_.pop();
> - embeddedBuffer = nullptr;
> - return true;
> - }
> -
> - if (!embeddedQueue_.empty()) {
> - /*
> - * Not found a matching embedded buffer for the bayer buffer in
> - * the front of the queue. This buffer is now orphaned, so requeue
> - * it back to the device.
> - */
> - unicam_[Unicam::Image].returnBuffer(bayerQueue_.front().buffer);
> - bayerQueue_.pop();
> - bayerRequeueCount++;
> - LOG(RPI, Warning) << "Dropping unmatched input frame in stream "
> - << unicam_[Unicam::Image].name();
> - }
> -
> - /*
> - * If we have requeued all available embedded data buffers in this loop,
> - * then we are fully out of sync, so might as well requeue all the pending
> - * bayer buffers.
> - */
> - if (embeddedRequeueCount == unicam_[Unicam::Embedded].getBuffers().size()) {
> - /* The embedded queue must be empty at this point! */
> - ASSERT(embeddedQueue_.empty());
> -
> - LOG(RPI, Warning) << "Flushing bayer stream!";
> - while (!bayerQueue_.empty()) {
> - unicam_[Unicam::Image].returnBuffer(bayerQueue_.front().buffer);
> - bayerQueue_.pop();
> - }
> - flushedBuffers = true;
> - }
> + if (bayerQueue_.empty())
> + return false;
>
> - /*
> - * Similar to the above, if we have requeued all available bayer buffers in
> - * the loop, then we are fully out of sync, so might as well requeue all the
> - * pending embedded data buffers.
> - */
> - if (bayerRequeueCount == unicam_[Unicam::Image].getBuffers().size()) {
> - /* The bayer queue must be empty at this point! */
> - ASSERT(bayerQueue_.empty());
> -
> - LOG(RPI, Warning) << "Flushing embedded data stream!";
> - while (!embeddedQueue_.empty()) {
> - unicam_[Unicam::Embedded].returnBuffer(embeddedQueue_.front());
> - embeddedQueue_.pop();
> - }
> - flushedBuffers = true;
> - }
> + /* Start with the front of the bayer queue. */
> + bayerFrame = std::move(bayerQueue_.front());
> + bayerQueue_.pop();
>
> - /*
> - * If the embedded queue has become empty, we cannot do any more.
> - * Similarly, if we have flushed any one of our queues, we cannot do
> - * any more. Return from here without a buffer pair.
> - */
> - if (embeddedQueue_.empty() || flushedBuffers)
> - return false;
> - } else {
> - /*
> - * We have found a matching bayer and embedded data buffer, so
> - * nothing more to do apart from assigning the bayer frame and
> - * popping the buffers from the queue.
> - */
> - bayerFrame = std::move(bayerQueue_.front());
> - bayerQueue_.pop();
> + /*
> + * Find the embedded data buffer with a matching timestamp to pass to
> + * the IPA. Any embedded buffers with a timestamp lower than the
> + * current bayer buffer will be removed and re-queued to the driver.
> + */
> + uint64_t ts = bayerFrame.buffer->metadata().timestamp;
> + embeddedBuffer = nullptr;
> + while (!embeddedQueue_.empty()) {
> + FrameBuffer *b = embeddedQueue_.front();
> + if (b->metadata().timestamp < ts) {
> + embeddedQueue_.pop();
> + unicam_[Unicam::Embedded].returnBuffer(b);
> + LOG(RPI, Debug) << "Dropping unmatched input frame in stream "
> + << unicam_[Unicam::Embedded].name();
> + } else if (b->metadata().timestamp == ts) {
It would be very nice if we could switch to using sequence numbers
instead of timestamps, comparing timestamps for equality always looks
dangerous to me (even if I know Unicam handles this fine).
This looks like a nice simplification,
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> + /* Found a match! */
> + embeddedBuffer = b;
> embeddedQueue_.pop();
> - return true;
> + break;
> + } else {
> + break; /* Only higher timestamps from here. */
> }
> }
>
> - return false;
> + if (!embeddedBuffer && sensorMetadata_) {
> + /* Log if there is no matching embedded data buffer found. */
> + LOG(RPI, Debug) << "Returning bayer frame without a matching embedded buffer.";
> + }
> +
> + return true;
> }
>
> REGISTER_PIPELINE_HANDLER(PipelineHandlerRPi)
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list