From patchwork Thu Jun 23 23:22:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16353 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 44D89BD808 for ; Thu, 23 Jun 2022 23:22:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9E8666564C; Fri, 24 Jun 2022 01:22:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026560; bh=FNdfCE5dCVwt6ubffCyFVzxF28TYQ2u+eO5Fie62uR4=; 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=0W7gJy2old8jK3UgdlQlgv3UGj7PyaO/gknZfpt4YvklEYFz+tzUjpuibOH6ScwcO hXXX6AFyBV13QbkAurVtfqPNMVm7ewZrJKcxaclWrTq/w6jLJ7Y3AzWEHGhXi9rVBj Rg6EDuKmlUB3bThIen5Im+fu9l6guP1vWIR6j0ueGpFP4zXLDnIQoYklwxfC0i6klw 0MN9zNvi252mPNkImzUa+qxhDC/mvetDbmjJbqnR2spXN0ba4dJQkDkcQjRDKkfb64 BIddsb/CksK0OQYFteRZK7W4nj6j6GMpcYysIhilgLAU49C6KJSEzW4CCL69hWYbNo tKTsG1cesDVtg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 20F6A61FB2 for ; Fri, 24 Jun 2022 01:22:32 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Am/NOLOS"; 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 993D76BB; Fri, 24 Jun 2022 01:22:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026551; bh=FNdfCE5dCVwt6ubffCyFVzxF28TYQ2u+eO5Fie62uR4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Am/NOLOSIaAu+uMnNdx8ZN7KeUAc1uSIZE08dndDBujSk+DGz1ROtcYynr5VPIVbS r0DtW4K4t8z2EFR7J7x7OxYRI2NIFuBRAO2s0C008m77jzfIkL8fweZkAyTy3djtHR mxNiXa0w+LNBzhlBQ+tnWsWYbpjKwFL1WGSI8kSw= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:04 +0300 Message-Id: <20220623232210.18742-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220623232210.18742-1-laurent.pinchart@ideasonboard.com> References: <20220623232210.18742-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/13] 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 , Vedant Paranjape 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 --- 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 02fc913764f8..ee9c83fde777 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_(0) { } @@ -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 = 0; + 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 (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 (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);