From patchwork Sun Jan 31 22:46:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 11087 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 3635EBD808 for ; Sun, 31 Jan 2021 22:47:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ECE46683F9; Sun, 31 Jan 2021 23:47:38 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="kJ5KPWd0"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E5E2F683DD for ; Sun, 31 Jan 2021 23:47:30 +0100 (CET) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6DA07145C; Sun, 31 Jan 2021 23:47:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1612133250; bh=u+pC3266rubsngdrw/0GegTHaDvdoizTRyIRuXLKRt8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kJ5KPWd0R1zq4f78HOA4lZ13q9kERZZLjQ4APuxgxUbtr3pUuVo/2YNo8axKXRJZR /vyP4GXSHtlTwxYQPsKBoWfmP/RZf/UzH0kZBSBMxbFs7VTiZRKhQ1kWf3ycg4CN6S Etu/mX0LSfHdFzr25bWewTC0xaqQ9CZ9WZ+uUzWI= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 1 Feb 2021 00:46:50 +0200 Message-Id: <20210131224702.8838-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20210131224702.8838-1-laurent.pinchart@ideasonboard.com> References: <20210131224702.8838-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/20] libcamera: pipeline: simple: converter: Decouple input and output completion X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Phi-Bang Nguyen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The SimpleConverter API signals completion of input and output buffer pairs. This unnecessarily delays requeueing the input buffer to the video capture queue until the output buffer completes, and also delays signalling request completion until the input buffer completes. While this shouldn't cause large delays in practice, it will also not scale when multi-stream support will be added to the converter class. To address the current issue and prepare for the future, decouple signalling of input and output buffers completion. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder --- src/libcamera/pipeline/simple/converter.cpp | 24 +++++-------------- src/libcamera/pipeline/simple/converter.h | 11 ++++----- src/libcamera/pipeline/simple/simple.cpp | 26 +++++++++++++-------- 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp index f782fbc63b09..8324baedc198 100644 --- a/src/libcamera/pipeline/simple/converter.cpp +++ b/src/libcamera/pipeline/simple/converter.cpp @@ -45,8 +45,8 @@ SimpleConverter::SimpleConverter(MediaDevice *media) return; } - m2m_->output()->bufferReady.connect(this, &SimpleConverter::outputBufferReady); - m2m_->capture()->bufferReady.connect(this, &SimpleConverter::captureBufferReady); + m2m_->output()->bufferReady.connect(this, &SimpleConverter::m2mInputBufferReady); + m2m_->capture()->bufferReady.connect(this, &SimpleConverter::m2mOutputBufferReady); } std::vector SimpleConverter::formats(PixelFormat input) @@ -247,26 +247,14 @@ int SimpleConverter::queueBuffers(FrameBuffer *input, FrameBuffer *output) return 0; } -void SimpleConverter::captureBufferReady(FrameBuffer *buffer) +void SimpleConverter::m2mInputBufferReady(FrameBuffer *buffer) { - if (!outputDoneQueue_.empty()) { - FrameBuffer *other = outputDoneQueue_.front(); - outputDoneQueue_.pop(); - bufferReady.emit(other, buffer); - } else { - captureDoneQueue_.push(buffer); - } + inputBufferReady.emit(buffer); } -void SimpleConverter::outputBufferReady(FrameBuffer *buffer) +void SimpleConverter::m2mOutputBufferReady(FrameBuffer *buffer) { - if (!captureDoneQueue_.empty()) { - FrameBuffer *other = captureDoneQueue_.front(); - captureDoneQueue_.pop(); - bufferReady.emit(buffer, other); - } else { - outputDoneQueue_.push(buffer); - } + outputBufferReady.emit(buffer); } } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/simple/converter.h b/src/libcamera/pipeline/simple/converter.h index 780bfa8f7832..739b24df0200 100644 --- a/src/libcamera/pipeline/simple/converter.h +++ b/src/libcamera/pipeline/simple/converter.h @@ -9,7 +9,6 @@ #define __LIBCAMERA_PIPELINE_SIMPLE_CONVERTER_H__ #include -#include #include #include @@ -47,17 +46,15 @@ public: int queueBuffers(FrameBuffer *input, FrameBuffer *output); - Signal bufferReady; + Signal inputBufferReady; + Signal outputBufferReady; private: - void captureBufferReady(FrameBuffer *buffer); - void outputBufferReady(FrameBuffer *buffer); + void m2mInputBufferReady(FrameBuffer *buffer); + void m2mOutputBufferReady(FrameBuffer *buffer); std::unique_ptr m2m_; - std::queue captureDoneQueue_; - std::queue outputDoneQueue_; - unsigned int inputBufferCount_; unsigned int outputBufferCount_; }; diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 20a4ebca94fd..7f9c57234256 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -144,7 +144,8 @@ private: } void bufferReady(FrameBuffer *buffer); - void converterDone(FrameBuffer *input, FrameBuffer *output); + void converterInputDone(FrameBuffer *buffer); + void converterOutputDone(FrameBuffer *buffer); MediaDevice *media_; std::map> videos_; @@ -768,7 +769,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) << "Failed to create converter, disabling format conversion"; converter_.reset(); } else { - converter_->bufferReady.connect(this, &SimplePipelineHandler::converterDone); + converter_->inputBufferReady.connect(this, &SimplePipelineHandler::converterInputDone); + converter_->outputBufferReady.connect(this, &SimplePipelineHandler::converterOutputDone); } } @@ -925,19 +927,23 @@ void SimplePipelineHandler::bufferReady(FrameBuffer *buffer) completeRequest(request); } -void SimplePipelineHandler::converterDone(FrameBuffer *input, - FrameBuffer *output) +void SimplePipelineHandler::converterInputDone(FrameBuffer *buffer) { ASSERT(activeCamera_); SimpleCameraData *data = cameraData(activeCamera_); - /* Complete the request. */ - Request *request = output->request(); - completeBuffer(request, output); - completeRequest(request); - /* Queue the input buffer back for capture. */ - data->video_->queueBuffer(input); + data->video_->queueBuffer(buffer); +} + +void SimplePipelineHandler::converterOutputDone(FrameBuffer *buffer) +{ + ASSERT(activeCamera_); + + /* Complete the request. */ + Request *request = buffer->request(); + completeBuffer(request, buffer); + completeRequest(request); } REGISTER_PIPELINE_HANDLER(SimplePipelineHandler)