From patchwork Thu Jun 30 00:02:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16442 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 3D315BD808 for ; Thu, 30 Jun 2022 00:03:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A85876563F; Thu, 30 Jun 2022 02:03:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656547407; bh=daSkBUqMGuW7q9N/BmNV/l8m4/bCX/bMskfiaEbpzsA=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=ZY9uENotfJ33nYfW8zCJc6P5S9h7RntsTgqMPAmU2AuDldP3eUKNQ9lvEqAzQf/jY K1RIOVQ/QVB5aDae35jv3kBc8wjsSmS3AzNGPM0/pIXX12/VKsEqSIfB80jfBKchu9 cttaOqA+vg5Be7St1Rt5nFSv/cwOWagaFz9onlbsugFuZ5jFsE/ueyZEafhfGBwPuh IS1gXayFLNLoRpbLcQhL346lMqYoVEjP/6xzdgdL8Xl0BqJnLBdgRAhxlJCSMhCdOq 84Fgg5ttID3Z3QuNXWN09Ju5KAxGPFhB5kr3W2scBsFEQGX8MZOOOVH8XY9t49YH/u 9wTOOBAq1ag1w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EDA065641 for ; Thu, 30 Jun 2022 02:03:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="IKrEtFFN"; dkim-atps=neutral Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 307C759D; Thu, 30 Jun 2022 02:03:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656547397; bh=daSkBUqMGuW7q9N/BmNV/l8m4/bCX/bMskfiaEbpzsA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IKrEtFFNWaTUjYxDXoo8NKo42SzAYHRNmNrFL0QXnbGGhOWR+J4j8Zl8WvWY3muXv Mc/+rfn+5EFda/BfHHg3T7hMBHFGoqOJQKHVQGXrx/qmLVNMHGaBTvPnJwqUiZ6IrR OIhee4DvMlEn5vqGLyEGp82K0K63DZFSk4wGz/ZI= To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jun 2022 03:02:45 +0300 Message-Id: <20220630000251.31295-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220630000251.31295-1-laurent.pinchart@ideasonboard.com> References: <20220630000251.31295-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 06/12] gstreamer: Handle completed requests in the libcamerasrc task 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Cc: Nicolas Dufresne Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Move the request wrap to a completed queue in the request completion handler to move more of the request completion processing to the libcamerasrc task. This lowers the amount of time spent in the completion handler, and prepares for reworking the usage of locks. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain --- Changes since v1: - Use GST_CLOCK_TIME_NONE and GST_CLOCK_TIME_IS_VALID() --- src/gstreamer/gstlibcamerasrc.cpp | 82 ++++++++++++++++++------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index f2f48d53991a..2cb915637874 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -57,10 +57,13 @@ struct RequestWrap { std::unique_ptr request_; std::map buffers_; + + GstClockTime latency_; + GstClockTime pts_; }; RequestWrap::RequestWrap(std::unique_ptr request) - : request_(std::move(request)) + : request_(std::move(request)), latency_(0), pts_(GST_CLOCK_TIME_NONE) { } @@ -109,6 +112,7 @@ struct GstLibcameraSrcState { std::unique_ptr config_; std::vector srcpads_; std::queue> queuedRequests_; + std::queue> completedRequests_; guint group_id_; void requestCompleted(Request *request); @@ -165,9 +169,6 @@ GstLibcameraSrcState::requestCompleted(Request *request) return; } - GstClockTime latency; - GstClockTime pts; - if (GST_ELEMENT_CLOCK(src_)) { int64_t timestamp = request->metadata().get(controls::SensorTimestamp); @@ -178,31 +179,11 @@ GstLibcameraSrcState::requestCompleted(Request *request) /* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */ GstClockTime sys_base_time = sys_now - (gst_now - gst_base_time); - pts = timestamp - sys_base_time; - latency = sys_now - timestamp; - } else { - latency = 0; - pts = GST_CLOCK_TIME_NONE; + wrap->pts_ = timestamp - sys_base_time; + wrap->latency_ = sys_now - timestamp; } - for (GstPad *srcpad : srcpads_) { - Stream *stream = gst_libcamera_pad_get_stream(srcpad); - GstBuffer *buffer = wrap->detachBuffer(stream); - - FrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer); - - if (GST_CLOCK_TIME_IS_VALID(pts)) { - GST_BUFFER_PTS(buffer) = pts; - gst_libcamera_pad_set_latency(srcpad, latency); - } else { - GST_BUFFER_PTS(buffer) = 0; - } - - GST_BUFFER_OFFSET(buffer) = fb->metadata().sequence; - GST_BUFFER_OFFSET_END(buffer) = fb->metadata().sequence; - - gst_libcamera_pad_queue_buffer(srcpad, buffer); - } + completedRequests_.push(std::move(wrap)); gst_task_resume(src_->task); } @@ -316,6 +297,39 @@ gst_libcamera_src_task_run(gpointer user_data) /* The RequestWrap will be deleted in the completion handler. */ } + { + GLibLocker lock(GST_OBJECT(self)); + + if (!state->completedRequests_.empty()) { + wrap = std::move(state->completedRequests_.front()); + state->completedRequests_.pop(); + } + } + + if (!wrap) { + gst_task_pause(self->task); + return; + } + + for (GstPad *srcpad : state->srcpads_) { + Stream *stream = gst_libcamera_pad_get_stream(srcpad); + GstBuffer *buffer = wrap->detachBuffer(stream); + + FrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer); + + if (GST_CLOCK_TIME_IS_VALID(wrap->pts_)) { + GST_BUFFER_PTS(buffer) = wrap->pts_; + gst_libcamera_pad_set_latency(srcpad, wrap->latency_); + } else { + GST_BUFFER_PTS(buffer) = 0; + } + + GST_BUFFER_OFFSET(buffer) = fb->metadata().sequence; + GST_BUFFER_OFFSET_END(buffer) = fb->metadata().sequence; + + gst_libcamera_pad_queue_buffer(srcpad, buffer); + } + GstFlowReturn ret = GST_FLOW_OK; gst_flow_combiner_reset(self->flow_combiner); for (GstPad *srcpad : state->srcpads_) { @@ -344,13 +358,11 @@ gst_libcamera_src_task_run(gpointer user_data) * happen in lock step with the callback thread which may want * to resume the task and might push pending buffers. */ - GLibLocker lock(GST_OBJECT(self)); - bool do_pause = true; - for (GstPad *srcpad : state->srcpads_) { - if (gst_libcamera_pad_has_pending(srcpad)) { - do_pause = false; - break; - } + bool do_pause; + + { + GLibLocker lock(GST_OBJECT(self)); + do_pause = state->completedRequests_.empty(); } if (do_pause) @@ -504,6 +516,8 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task, state->cam_->stop(); + state->completedRequests_ = {}; + for (GstPad *srcpad : state->srcpads_) gst_libcamera_pad_set_pool(srcpad, nullptr);