From patchwork Thu Jun 23 23:21:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16347 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 0E4E7BD808 for ; Thu, 23 Jun 2022 23:22:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 287706563E; Fri, 24 Jun 2022 01:22:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026551; bh=qua9aQjOuEGceXdbuVSrk+ABtj/736fvVqX3osuGcMo=; 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=0UX2lAdvU/E/4XVDjCudFDCcUb8l3rxNS3UAo4UqLE3Olv2RrtUCZvWqSJLRpEILr 5ec5g/dbmQAEeeDatu3HtyQF1BO3t9ezwNPLv4CHWcDxoP9/11aCwmDPGRMfoMROo+ KgOI69aQdb4/NmyXtuah/EIg8RWXxyVIX/inGFoTE4OZdco3S8F81WxdPyt4nBeufS Fb0A6tGnTsDXIBHf7MFlUknPycG+CRARG7u7lALjoryGKoHaAQs0TPzu70HeDZX7tD NToKNJ6HGM9MOXELauhLSlTshqmSElP8eRN2DX+3gA28kPLp+vXZ53P9oB5NyiaQTx +NNlPSTOv1nJg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4E6FA61FB2 for ; Fri, 24 Jun 2022 01:22:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="sCWZ9CFn"; 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 BC1AA6BB; Fri, 24 Jun 2022 01:22:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026549; bh=qua9aQjOuEGceXdbuVSrk+ABtj/736fvVqX3osuGcMo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sCWZ9CFnWzpK4KUnU1wKXgFT2iQ+n9lludia5tlAaLgkFfNFpl+Yhsam/k6OC6Ho8 cKHy3XqGLzBWTQbslbhiP+daLadqUKh0yo0p7TckzbY4Wa5yoGKlgqiJUubfcuYpED oJaJHnTN7yHd04jto+V4QGKOfUOIVOb/KIiP0WtU= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:21:58 +0300 Message-Id: <20220623232210.18742-2-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 01/13] gstreamer: Use gst_task_resume() when available 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" The gst_libcamera_resume_task() helper is an implementation of the gst_task_resume() function that predates its addition to GStreamer. Use gst_task_resume() when available, and rename gst_libcamera_resume_task() to gst_task_resume() to support older GStreamer versions. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne Reviewed-by: Umang Jain Reviewed-by: Vedant Paranjape --- src/gstreamer/gstlibcamera-utils.cpp | 16 ++++++++++------ src/gstreamer/gstlibcamera-utils.h | 4 +++- src/gstreamer/gstlibcamerasrc.cpp | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index 3f2422863c03..c97c0d438de2 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -224,16 +224,20 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg, stream_cfg.size.height = height; } -void -gst_libcamera_resume_task(GstTask *task) +#if !GST_CHECK_VERSION(1, 17, 1) +gboolean +gst_task_resume(GstTask *task) { /* We only want to resume the task if it's paused. */ GLibLocker lock(GST_OBJECT(task)); - if (GST_TASK_STATE(task) == GST_TASK_PAUSED) { - GST_TASK_STATE(task) = GST_TASK_STARTED; - GST_TASK_SIGNAL(task); - } + if (GST_TASK_STATE(task) != GST_TASK_PAUSED) + return FALSE; + + GST_TASK_STATE(task) = GST_TASK_STARTED; + GST_TASK_SIGNAL(task); + return TRUE; } +#endif G_LOCK_DEFINE_STATIC(cm_singleton_lock); static std::weak_ptr cm_singleton_ptr; diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h index d54f15885d0c..164189a28965 100644 --- a/src/gstreamer/gstlibcamera-utils.h +++ b/src/gstreamer/gstlibcamera-utils.h @@ -18,7 +18,9 @@ GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &fo GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg); void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg, GstCaps *caps); -void gst_libcamera_resume_task(GstTask *task); +#if !GST_CHECK_VERSION(1, 17, 1) +gboolean gst_task_resume(GstTask *task); +#endif std::shared_ptr gst_libcamera_get_camera_manager(int &ret); /** diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 46fd02d207be..9d6be075a474 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -192,7 +192,7 @@ GstLibcameraSrcState::requestCompleted(Request *request) gst_libcamera_pad_queue_buffer(srcpad, buffer); } - gst_libcamera_resume_task(this->src_->task); + gst_task_resume(src_->task); } static bool @@ -453,7 +453,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, GstLibcameraPool *pool = gst_libcamera_pool_new(self->allocator, stream_cfg.stream()); g_signal_connect_swapped(pool, "buffer-notify", - G_CALLBACK(gst_libcamera_resume_task), task); + G_CALLBACK(gst_task_resume), task); gst_libcamera_pad_set_pool(srcpad, pool); gst_flow_combiner_add_pad(self->flow_combiner, srcpad); From patchwork Thu Jun 23 23:21:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16348 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 B532EBD808 for ; Thu, 23 Jun 2022 23:22:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 70C7765637; Fri, 24 Jun 2022 01:22:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026552; bh=0wpZYTfLk/Mcc6U4ycBHRlBVzwvx/QvEUATQ8Os0Nes=; 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=NmRxF9zTc3Stjcol2eD0MUXbr9fj4YFhtok5TqgIE22HX2rwHNBOPKFjAGNow+yAs +L6PV8H7DIaF8LylBf4IEWCDuT+02EH2ncp2320YQ580ZOcG+KhxFrbzHJR/PYRqXu K5au1Y9ujTeuNN4cSH4YUwTC1Wc31EG+xfGvpoAElzXTeHiYLM4b9xSjeHahVw+7KX xGQNEJ1jiZpdRT+79con6ETrQbZUDSpsZeMJKKaMTaCzlQT1PDLhdcAoPbB34kp/sy D13xoadveagajpJg0Ry0tK2TpHbL7yNfUn4krmyeopXia4NFNEEZeD09RvKF9CNTmu Iv2Utx9Lk5EAA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A9AFA61FB2 for ; Fri, 24 Jun 2022 01:22:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CMjoRpaV"; 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 3A1D680A; Fri, 24 Jun 2022 01:22:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026549; bh=0wpZYTfLk/Mcc6U4ycBHRlBVzwvx/QvEUATQ8Os0Nes=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CMjoRpaVgc+qKYe4dzNa2jAscxBrleGV76UGYGTW//VPzL88tYvCPo8XF3Mj1hmwg 4MQnC97+tumuLXyS7GdkGq0mCP+ijhULfNhep/CWt7tHL1Fl4VstLSqpd0lAlO3v6R 1UvsQ7erqT3PXVktEeV0A1LT/T04ZfQLNiPUXGWE= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:21:59 +0300 Message-Id: <20220623232210.18742-3-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 02/13] gstreamer: Inline gst_libcamera_buffer_get_frame_buffer() 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" The gst_libcamera_buffer_get_frame_buffer() function retrieves a FrameBuffer corresponding to the GstBuffer. While the GstLibcameraPool class allocates the GstBuffer instances, associating them to a FrameBuffer is handled by GstLibcameraAllocator. The gst_libcamera_buffer_get_frame_buffer() function is ill-placed in gstlibcamerapool.cpp. Move it to gstlibcameraallocator.cpp, which allows inlining it in its single caller, simplifying the code flow. Signed-off-by: Laurent Pinchart --- src/gstreamer/gstlibcameraallocator.cpp | 3 ++- src/gstreamer/gstlibcameraallocator.h | 2 +- src/gstreamer/gstlibcamerapool.cpp | 7 ------- src/gstreamer/gstlibcamerapool.h | 2 -- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp index c740b8fc82a8..53693834eeff 100644 --- a/src/gstreamer/gstlibcameraallocator.cpp +++ b/src/gstreamer/gstlibcameraallocator.cpp @@ -252,8 +252,9 @@ gst_libcamera_allocator_get_pool_size(GstLibcameraAllocator *self, } FrameBuffer * -gst_libcamera_memory_get_frame_buffer(GstMemory *mem) +gst_libcamera_buffer_get_frame_buffer(GstBuffer *buffer) { + GstMemory *mem = gst_buffer_peek_memory(buffer, 0); auto *frame = reinterpret_cast(gst_mini_object_get_qdata(GST_MINI_OBJECT_CAST(mem), FrameWrap::getQuark())); return frame->buffer_; diff --git a/src/gstreamer/gstlibcameraallocator.h b/src/gstreamer/gstlibcameraallocator.h index 0a08c3bb3bbe..b1c038c50257 100644 --- a/src/gstreamer/gstlibcameraallocator.h +++ b/src/gstreamer/gstlibcameraallocator.h @@ -28,4 +28,4 @@ bool gst_libcamera_allocator_prepare_buffer(GstLibcameraAllocator *self, gsize gst_libcamera_allocator_get_pool_size(GstLibcameraAllocator *allocator, libcamera::Stream *stream); -libcamera::FrameBuffer *gst_libcamera_memory_get_frame_buffer(GstMemory *mem); +libcamera::FrameBuffer *gst_libcamera_buffer_get_frame_buffer(GstBuffer *buffer); diff --git a/src/gstreamer/gstlibcamerapool.cpp b/src/gstreamer/gstlibcamerapool.cpp index 1fde42135119..118bc6db7067 100644 --- a/src/gstreamer/gstlibcamerapool.cpp +++ b/src/gstreamer/gstlibcamerapool.cpp @@ -140,10 +140,3 @@ gst_libcamera_buffer_get_stream(GstBuffer *buffer) auto *self = (GstLibcameraPool *)buffer->pool; return self->stream; } - -FrameBuffer * -gst_libcamera_buffer_get_frame_buffer(GstBuffer *buffer) -{ - GstMemory *mem = gst_buffer_peek_memory(buffer, 0); - return gst_libcamera_memory_get_frame_buffer(mem); -} diff --git a/src/gstreamer/gstlibcamerapool.h b/src/gstreamer/gstlibcamerapool.h index 05795d21223e..06b38cb296fc 100644 --- a/src/gstreamer/gstlibcamerapool.h +++ b/src/gstreamer/gstlibcamerapool.h @@ -26,5 +26,3 @@ GstLibcameraPool *gst_libcamera_pool_new(GstLibcameraAllocator *allocator, libcamera::Stream *gst_libcamera_pool_get_stream(GstLibcameraPool *self); libcamera::Stream *gst_libcamera_buffer_get_stream(GstBuffer *buffer); - -libcamera::FrameBuffer *gst_libcamera_buffer_get_frame_buffer(GstBuffer *buffer); From patchwork Thu Jun 23 23:22:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16349 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 CAE1ABD808 for ; Thu, 23 Jun 2022 23:22:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C81B365649; Fri, 24 Jun 2022 01:22:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026555; bh=eIaNFEK/fkZTwMsMBv7ZufdKJmcG2AnPe5i8AztK3+c=; 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=FEQPbYTCElQjUU4HPK29RZ3aQV4b70fFvuIqXwhE/2EHJ4u6Sw5nSyY4lf9ApZ+Hi VXbJMW2iIGIhFm6cw3gw1+HJI/ZGvtppob12PlMvrgEadPcM997OmlFlen2UTtXDgF qBvDed1ElHgD3cUBzrpk1o1+P7dxwlQRtKDdXpPI33ev5aCM+TWemcU7MIo8N6VW+3 Qlct4/QU8H+PDtvHTRcfWZesdEJ1+rjwYXtRrnrHgOSBdqUTi6hjK5tUSuER89RveC wVXb1fesd2re//edTHEf+JUiNAS3LPhiL9dB2clARrs1Bwdagi03fg+jiJ24fQQtM3 c1E2npkSPMJ5A== 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 34D7165635 for ; Fri, 24 Jun 2022 01:22:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Ox2zxV2o"; 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 B04C06BB; Fri, 24 Jun 2022 01:22:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026550; bh=eIaNFEK/fkZTwMsMBv7ZufdKJmcG2AnPe5i8AztK3+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ox2zxV2ozfkE57kabegvvBkw52BQkCfCb6anM0O0AWRLrWxMr2fq6cDu6zNHe88p7 be3uGfCmXkNCgmfcnFvYfjjNgwSKfNgkjRAH+fRXrv/kpRH+CmuO94PDXFp2OlJvlw h/mQPFQNAJozDY8k9peAteb/w5uf4pzP8qS7kwuM= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:00 +0300 Message-Id: <20220623232210.18742-4-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 03/13] gstreamer: Move variable to loop scope 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" The GstBuffer variable in GstLibcameraSrcState::requestCompleted() is only used within the loop scope. Make it a local loop variable. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne Reviewed-by: Umang Jain --- src/gstreamer/gstlibcamerasrc.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 9d6be075a474..dea143961d69 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -165,10 +165,9 @@ GstLibcameraSrcState::requestCompleted(Request *request) return; } - GstBuffer *buffer; for (GstPad *srcpad : srcpads_) { Stream *stream = gst_libcamera_pad_get_stream(srcpad); - buffer = wrap->detachBuffer(stream); + GstBuffer *buffer = wrap->detachBuffer(stream); FrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer); From patchwork Thu Jun 23 23:22:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16350 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 D0047BD808 for ; Thu, 23 Jun 2022 23:22:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 95F6661FB2; Fri, 24 Jun 2022 01:22:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026558; bh=U5uDoigSLXuYOtlGcXh59NjMvxX+p5+F2ubYAla5zD0=; 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=YJ0QplKSXSFSeqDQSb1ehj6UoodtM/xYiudtMi16nb/KrNLXOfD4unsVncJqhLjQ5 M22hGNlp0yreP1+w8Xc5GKbWgvZgS2xu34EfvRONy0foIwsg3/HMqkr6UrlQTDC5AX K6RNbiFkcwmtpYR8lVV9kyerb2utpJMknfdzMFyPshulakfGFWccgtBvv/6QypdzOe h3mAsi5BKNVQxLpvFaI9pIV5Jb5oq4MjovUASu0/Sn8+wC7CDHCryq2TGl2scosW1Z K/ogZGQKkceGuj4IzLfuBEtHC0Yrf07M7QIP42GpbWHi/dVGxl6W/An36mL7GDfFdH SVVwiUORcXRoQ== 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 E9EA165639 for ; Fri, 24 Jun 2022 01:22:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="e0ubcb2Z"; 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 2EFDADD; Fri, 24 Jun 2022 01:22:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026550; bh=U5uDoigSLXuYOtlGcXh59NjMvxX+p5+F2ubYAla5zD0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e0ubcb2ZSR7TWPTr3PmHd1prA6wZ/hyBReKs/d26vEQHSDlgJPc7UtVKdrWYw/fMO zhqz5Ceh7mgILnAbry6KqD+8gjBbmyrgEbVDxRqq9leYL00Z5/wIglLFzGrsxMVAgC k4+QNLUpqCQwvGVJdleaHKJwpSgr+2v3ONk1LgyA= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:01 +0300 Message-Id: <20220623232210.18742-5-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 04/13] gstreamer: Pass Stream to RequestWrap::addBuffer() 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" For symmetry with RequestWrap::removeBuffer(), pass the Stream pointer to addBuffer(). This handles streams at the GstPad level instead of the GstBuffer level, which allows making the GstLibcameraPool API a bit cleaner by removing the gst_libcamera_buffer_get_stream() helper function. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne Reviewed-by: Umang Jain --- src/gstreamer/gstlibcamerapool.cpp | 7 ------- src/gstreamer/gstlibcamerapool.h | 2 -- src/gstreamer/gstlibcamerasrc.cpp | 8 ++++---- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/gstreamer/gstlibcamerapool.cpp b/src/gstreamer/gstlibcamerapool.cpp index 118bc6db7067..c7b7fe54cbe1 100644 --- a/src/gstreamer/gstlibcamerapool.cpp +++ b/src/gstreamer/gstlibcamerapool.cpp @@ -133,10 +133,3 @@ gst_libcamera_pool_get_stream(GstLibcameraPool *self) { return self->stream; } - -Stream * -gst_libcamera_buffer_get_stream(GstBuffer *buffer) -{ - auto *self = (GstLibcameraPool *)buffer->pool; - return self->stream; -} diff --git a/src/gstreamer/gstlibcamerapool.h b/src/gstreamer/gstlibcamerapool.h index 06b38cb296fc..0ad14be4adf3 100644 --- a/src/gstreamer/gstlibcamerapool.h +++ b/src/gstreamer/gstlibcamerapool.h @@ -24,5 +24,3 @@ GstLibcameraPool *gst_libcamera_pool_new(GstLibcameraAllocator *allocator, libcamera::Stream *stream); libcamera::Stream *gst_libcamera_pool_get_stream(GstLibcameraPool *self); - -libcamera::Stream *gst_libcamera_buffer_get_stream(GstBuffer *buffer); diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index dea143961d69..700bee2bf877 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -51,7 +51,7 @@ struct RequestWrap { RequestWrap(std::unique_ptr request); ~RequestWrap(); - void attachBuffer(GstBuffer *buffer); + void attachBuffer(Stream *stream, GstBuffer *buffer); GstBuffer *detachBuffer(Stream *stream); std::unique_ptr request_; @@ -71,10 +71,9 @@ RequestWrap::~RequestWrap() } } -void RequestWrap::attachBuffer(GstBuffer *buffer) +void RequestWrap::attachBuffer(Stream *stream, GstBuffer *buffer) { FrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer); - Stream *stream = gst_libcamera_buffer_get_stream(buffer); request_->addBuffer(stream, fb); @@ -275,6 +274,7 @@ gst_libcamera_src_task_run(gpointer user_data) std::make_unique(std::move(request)); for (GstPad *srcpad : state->srcpads_) { + Stream *stream = gst_libcamera_pad_get_stream(srcpad); GstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad); GstBuffer *buffer; GstFlowReturn ret; @@ -290,7 +290,7 @@ gst_libcamera_src_task_run(gpointer user_data) break; } - wrap->attachBuffer(buffer); + wrap->attachBuffer(stream, buffer); } if (wrap) { From patchwork Thu Jun 23 23:22:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16352 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 64415BD808 for ; Thu, 23 Jun 2022 23:22:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E3E8E65647; Fri, 24 Jun 2022 01:22:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026560; bh=O+zsmWCvcUzybHHKyq6uNTXMTa+3F2tPx2/ZWbHTpcs=; 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=v9CiollwtBjuwamR1X0X9XD+qO5QP93Q1L2nUn2D5s1MiqXqMdG9FA8KAkAMmxCYU QBy94z/G5iZk1a/qQjX4OAJguJbItx8rrmeGD0BdMI17nY9ouzY6Vt22h5QgBsitz+ Qb67lBGnSJ4NreO3XECUpHffEnSL4EWxxrhW5FP5mPZKL+1846cH2ZZuO/F+JqFdrJ 1jpc2P8Fh9xIomcbwde80NnFv8a5byyt8xXNKwBiNnN6SUiaXw4TuiM4HvLiUDjvLg ojzZQyIBt4ZpIjwhpqjk+tC/wcePpOg2wKHyA5sj8BxTxPk8eOZNkAVq02rd7upZPo KNTTmgwqXmgRg== 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 2CFAC6563F for ; Fri, 24 Jun 2022 01:22:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DmVz0yjJ"; 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 A194D6BB; Fri, 24 Jun 2022 01:22:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026550; bh=O+zsmWCvcUzybHHKyq6uNTXMTa+3F2tPx2/ZWbHTpcs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DmVz0yjJ1/utX6080k557Z0GBlSJO5loPh3kKKkD178sVx6aCWZeAAIRXVVBJZQEs tq9PeqqTWT7MiOigbyff8azvsIRyIBWZFkxyZEBKBMJskmSQS8BnORlFKfjpt9d6Fz C3VSwKRGmBggnwchY7i33Hql/zPB2ErK2s9Ecsts= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:02 +0300 Message-Id: <20220623232210.18742-6-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 05/13] gstreamer: Move timestamp calculation out of pad loop 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" The buffer pts and the pad latency are computed from the framebuffer timestamp, separately for each pad. Use the sensor timestamp provided through the request metadata instead, to compute the values once outside of the pads loop. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain --- src/gstreamer/gstlibcamerasrc.cpp | 34 ++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 700bee2bf877..a1fab71d4f09 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -34,6 +34,7 @@ #include #include +#include #include @@ -164,22 +165,35 @@ GstLibcameraSrcState::requestCompleted(Request *request) return; } + GstClockTime latency; + GstClockTime pts; + + if (GST_ELEMENT_CLOCK(src_)) { + int64_t timestamp = request->metadata().get(controls::SensorTimestamp); + + GstClockTime gst_base_time = GST_ELEMENT(src_)->base_time; + GstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_)); + /* \todo Need to expose which reference clock the timestamp relates to. */ + GstClockTime sys_now = g_get_monotonic_time() * 1000; + + /* 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; + } + 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_ELEMENT_CLOCK(src_)) { - GstClockTime gst_base_time = GST_ELEMENT(src_)->base_time; - GstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_)); - /* \todo Need to expose which reference clock the timestamp relates to. */ - GstClockTime sys_now = g_get_monotonic_time() * 1000; - - /* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */ - GstClockTime sys_base_time = sys_now - (gst_now - gst_base_time); - GST_BUFFER_PTS(buffer) = fb->metadata().timestamp - sys_base_time; - gst_libcamera_pad_set_latency(srcpad, sys_now - fb->metadata().timestamp); + if (pts) { + GST_BUFFER_PTS(buffer) = pts; + gst_libcamera_pad_set_latency(srcpad, latency); } else { GST_BUFFER_PTS(buffer) = 0; } From patchwork Thu Jun 23 23:22:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16351 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 A3365BD808 for ; Thu, 23 Jun 2022 23:22:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 451C665651; Fri, 24 Jun 2022 01:22:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026559; bh=ppGZ8deBlgpt1OXy2Tb99DwXpDsPR0U5NBjBV5Lby2U=; 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=RbILLX4Ae3LAhiTkpeVBhMQLFg35BC93hIKiRcLJje9M0N6CjOpG7Qugpk85H30iC XoB+cz6Ak8u8bExJ3D9Tv7D8df8eC1oxCi7EHuOS4Nx3/ggoR9XZH4O3NwZ/diD6kx bPBZ3SPaeT0mb3gR6rmTTfmcF/Hc8pWeowGFanIIqv19D3eGheGWzL7qYgkr5DNQhW AnuX0che6rjd7Sz8ofUmP15HTuBtONPel3BTvmu/nE0M80jLJvZtP7KpiK3ShYZAwX dV1UZHF8hCnstHGkutlDnRGzNmgxg1YtkcaULzG7cOFNiwwnAZlNxIfdM6/tvjSH/I Ytf92fvquAtZg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9A0F065641 for ; Fri, 24 Jun 2022 01:22:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cfiKYLh2"; 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 22693DD; 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=ppGZ8deBlgpt1OXy2Tb99DwXpDsPR0U5NBjBV5Lby2U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cfiKYLh2BcKdhqPHkAtHrKFluEFOB3P3393ljDLZKChyxn71DjZ9ZKAlKhOc9oBtg AJfntpoDD5H9Dy/uKMbbBrnNdZ8c+3rHnT77vZ4td1h+5aBz0yS+rrolBv1Q12pobN 0scBhhZ9jnLYyUFRWW3SHLGi+xndzKaj7TmSm/JQ= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:03 +0300 Message-Id: <20220623232210.18742-7-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 06/13] gstreamer: Rename queued requests queue to queuedRequests_ 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" To prepare for the addition of a completed requests queue, rename the existing queued requests queue from requests_ to queuedRequests_. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne Reviewed-by: Umang Jain --- src/gstreamer/gstlibcamerasrc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index a1fab71d4f09..02fc913764f8 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -108,7 +108,7 @@ struct GstLibcameraSrcState { std::shared_ptr cam_; std::unique_ptr config_; std::vector srcpads_; - std::queue> requests_; + std::queue> queuedRequests_; guint group_id_; void requestCompleted(Request *request); @@ -155,8 +155,8 @@ GstLibcameraSrcState::requestCompleted(Request *request) GST_DEBUG_OBJECT(src_, "buffers are ready"); - std::unique_ptr wrap = std::move(requests_.front()); - requests_.pop(); + std::unique_ptr wrap = std::move(queuedRequests_.front()); + queuedRequests_.pop(); g_return_if_fail(wrap->request_.get() == request); @@ -311,7 +311,7 @@ gst_libcamera_src_task_run(gpointer user_data) GLibLocker lock(GST_OBJECT(self)); GST_TRACE_OBJECT(self, "Requesting buffers"); state->cam_->queueRequest(wrap->request_.get()); - state->requests_.push(std::move(wrap)); + state->queuedRequests_.push(std::move(wrap)); /* The RequestWrap will be deleted in the completion handler. */ } 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); From patchwork Thu Jun 23 23:22:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16355 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 CA79CBD808 for ; Thu, 23 Jun 2022 23:22:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3F2186564D; Fri, 24 Jun 2022 01:22:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026564; bh=Bmj0CbPPhblz1y1eJVWLXduCnnxDflL7cFuTOBcc+SQ=; 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=EGeKZ9Ndom5wcPl3H3l0CaPMjzm6O1axFapkP4Ekkk8U1FT8/XeOMNK6LKbdghUzE FvIrRiiYbfZyIh4spIP983o/ujxGyWPUzY/VKXeEEyU+yjJE0ZMo+enalva6ZsSIAR NYqKJdOjZP6tEih6W23mfFd/ln/prVJJ/OU2GrHoxGCkoSjZu3pwtOiYdJCv+0mk0E fDaPwn2uO7jCuus1tQoawJGjTghM9iH4ORaLvKWCXiqifnW47ER3HUph9I089QALES lPn5pbyRzT6LVdfj7Pg7K3ik8naToIAZzF8XuAeHUg0n+uVh7wdqwjQeDqRHiJ0nIA zAmyAex5q2d6g== 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 87D6965643 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="VIVF+zpr"; 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 18A1CDD; Fri, 24 Jun 2022 01:22:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026552; bh=Bmj0CbPPhblz1y1eJVWLXduCnnxDflL7cFuTOBcc+SQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VIVF+zprcgDuTVQ0hyVNEVMp+mu130QOIYxAokT4xM1ltYHffBCZxRoQ+4cO4inOU Rq/78fOSZFBVp3saWzDI2LSTY92hysaConMO3kjsZKgCEJm4qXHO/Gy4riDhIdP5El u2qOzhI4IaXvIeZae7u9bnFVxbe0xXfSek5xsEx8= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:05 +0300 Message-Id: <20220623232210.18742-9-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 08/13] gstreamer: Combine the two pad loops in the task run handler 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" This simplifies the code, and allows removing the internal queue in the GstLibcameraPad object. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne --- src/gstreamer/gstlibcamerapad.cpp | 35 ------------------------------- src/gstreamer/gstlibcamerapad.h | 6 ------ src/gstreamer/gstlibcamerasrc.cpp | 11 ++++------ 3 files changed, 4 insertions(+), 48 deletions(-) diff --git a/src/gstreamer/gstlibcamerapad.cpp b/src/gstreamer/gstlibcamerapad.cpp index c00e81c8966e..87b4057ac101 100644 --- a/src/gstreamer/gstlibcamerapad.cpp +++ b/src/gstreamer/gstlibcamerapad.cpp @@ -18,7 +18,6 @@ struct _GstLibcameraPad { GstPad parent; StreamRole role; GstLibcameraPool *pool; - GQueue pending_buffers; GstClockTime latency; }; @@ -155,40 +154,6 @@ gst_libcamera_pad_get_stream(GstPad *pad) return nullptr; } -void -gst_libcamera_pad_queue_buffer(GstPad *pad, GstBuffer *buffer) -{ - auto *self = GST_LIBCAMERA_PAD(pad); - GLibLocker lock(GST_OBJECT(self)); - - g_queue_push_head(&self->pending_buffers, buffer); -} - -GstFlowReturn -gst_libcamera_pad_push_pending(GstPad *pad) -{ - auto *self = GST_LIBCAMERA_PAD(pad); - GstBuffer *buffer; - - { - GLibLocker lock(GST_OBJECT(self)); - buffer = GST_BUFFER(g_queue_pop_tail(&self->pending_buffers)); - } - - if (!buffer) - return GST_FLOW_OK; - - return gst_pad_push(pad, buffer); -} - -bool -gst_libcamera_pad_has_pending(GstPad *pad) -{ - auto *self = GST_LIBCAMERA_PAD(pad); - GLibLocker lock(GST_OBJECT(self)); - return self->pending_buffers.length > 0; -} - void gst_libcamera_pad_set_latency(GstPad *pad, GstClockTime latency) { diff --git a/src/gstreamer/gstlibcamerapad.h b/src/gstreamer/gstlibcamerapad.h index 207695173313..103ee57ab384 100644 --- a/src/gstreamer/gstlibcamerapad.h +++ b/src/gstreamer/gstlibcamerapad.h @@ -25,10 +25,4 @@ void gst_libcamera_pad_set_pool(GstPad *pad, GstLibcameraPool *pool); libcamera::Stream *gst_libcamera_pad_get_stream(GstPad *pad); -void gst_libcamera_pad_queue_buffer(GstPad *pad, GstBuffer *buffer); - -GstFlowReturn gst_libcamera_pad_push_pending(GstPad *pad); - -bool gst_libcamera_pad_has_pending(GstPad *pad); - void gst_libcamera_pad_set_latency(GstPad *pad, GstClockTime latency); diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index ee9c83fde777..e30d45fa2223 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -311,6 +311,9 @@ gst_libcamera_src_task_run(gpointer user_data) return; } + GstFlowReturn ret = GST_FLOW_OK; + gst_flow_combiner_reset(self->flow_combiner); + for (GstPad *srcpad : state->srcpads_) { Stream *stream = gst_libcamera_pad_get_stream(srcpad); GstBuffer *buffer = wrap->detachBuffer(stream); @@ -327,13 +330,7 @@ gst_libcamera_src_task_run(gpointer user_data) 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_) { - ret = gst_libcamera_pad_push_pending(srcpad); + ret = gst_pad_push(srcpad, buffer); ret = gst_flow_combiner_update_pad_flow(self->flow_combiner, srcpad, ret); } From patchwork Thu Jun 23 23:22:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16354 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 4D6AFBD808 for ; Thu, 23 Jun 2022 23:22:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C3D8265640; Fri, 24 Jun 2022 01:22:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026562; bh=uQlVlGNXE+ZZ97peDXLIfggYGTn6X4KrYw0QTQHCbA8=; 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=LrXeexDuhs7LX0b8+4fyTJqVoAfP4lbfUB6fzh1h+pv3QvhLIf8LArTy69AuUO6+W J96g4CXO610d1VcOlzJX93GvKkILle3V3bYn1vPmQADGyQuWgoRhLD6feV8ouycUVP VvNPeJv/aJtWOvI0d/ptVvPjmThUGa078n8kzVqyKumfkCLbQx6okiEbwLU0zS6W1K dKZVWQLaOU97CuO09n2o0mzExyEGBvOO8PjFa/67THKTF9mcvScUHEZXX+pBzsFS6L k/G/04ua63sGlMu8L42KHRmnYCzZBV0BK5Yi3Lqyo5rJ5xU4QexHZp2J1aGm0JyUbz C2l1HmyliyOCQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 16DFD65636 for ; Fri, 24 Jun 2022 01:22:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iU3Jo7xn"; 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 8D6F76BB; Fri, 24 Jun 2022 01:22:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026552; bh=uQlVlGNXE+ZZ97peDXLIfggYGTn6X4KrYw0QTQHCbA8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iU3Jo7xnPqHRXK+uZCBGH+Ikdn5LB3zHiPxFK0UVvL0YxpuYjjxj3FWD0TrV0+lnL C47OYGo0VvecvHLrCtw1j+6mKtv+mE99VqwRA8vGNX3019Xb3BLd0rNuJ0rSuLkPXP 3vG6O4XcjswZ7xfLt2KtD2dJHI8TnaAmLg+VjaUk= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:06 +0300 Message-Id: <20220623232210.18742-10-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 09/13] gstreamer: Use dedicated lock for request queues 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" Add a new lock to the GstLibcameraSrcState class to protect the queued and completed requests queues. This replaces the GstObject lock, and minimizes the lock contention between the request completion handler and the task run handler as the former must run as fast as possible. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne --- src/gstreamer/gstlibcamerasrc.cpp | 39 ++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index e30d45fa2223..b85ba39fb808 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -32,6 +32,8 @@ #include #include +#include + #include #include #include @@ -111,8 +113,13 @@ struct GstLibcameraSrcState { std::shared_ptr cam_; std::unique_ptr config_; std::vector srcpads_; - std::queue> queuedRequests_; - std::queue> completedRequests_; + + Mutex lock_; + std::queue> queuedRequests_ + LIBCAMERA_TSA_GUARDED_BY(lock_); + std::queue> completedRequests_ + LIBCAMERA_TSA_GUARDED_BY(lock_); + guint group_id_; void requestCompleted(Request *request); @@ -155,12 +162,15 @@ GstStaticPadTemplate request_src_template = { void GstLibcameraSrcState::requestCompleted(Request *request) { - GLibLocker lock(GST_OBJECT(src_)); - GST_DEBUG_OBJECT(src_, "buffers are ready"); - std::unique_ptr wrap = std::move(queuedRequests_.front()); - queuedRequests_.pop(); + std::unique_ptr wrap; + + { + MutexLocker locker(lock_); + wrap = std::move(queuedRequests_.front()); + queuedRequests_.pop(); + } g_return_if_fail(wrap->request_.get() == request); @@ -183,7 +193,10 @@ GstLibcameraSrcState::requestCompleted(Request *request) wrap->latency_ = sys_now - timestamp; } - completedRequests_.push(std::move(wrap)); + { + MutexLocker locker(lock_); + completedRequests_.push(std::move(wrap)); + } gst_task_resume(src_->task); } @@ -289,16 +302,17 @@ gst_libcamera_src_task_run(gpointer user_data) } if (wrap) { - GLibLocker lock(GST_OBJECT(self)); GST_TRACE_OBJECT(self, "Requesting buffers"); state->cam_->queueRequest(wrap->request_.get()); + + MutexLocker locker(state->lock_); state->queuedRequests_.push(std::move(wrap)); /* The RequestWrap will be deleted in the completion handler. */ } { - GLibLocker lock(GST_OBJECT(self)); + MutexLocker locker(state->lock_); if (!state->completedRequests_.empty()) { wrap = std::move(state->completedRequests_.front()); @@ -358,7 +372,7 @@ gst_libcamera_src_task_run(gpointer user_data) bool do_pause; { - GLibLocker lock(GST_OBJECT(self)); + MutexLocker locker(state->lock_); do_pause = state->completedRequests_.empty(); } @@ -513,7 +527,10 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task, state->cam_->stop(); - state->completedRequests_ = {}; + { + MutexLocker locker(state->lock_); + state->completedRequests_ = {}; + } for (GstPad *srcpad : state->srcpads_) gst_libcamera_pad_set_pool(srcpad, nullptr); From patchwork Thu Jun 23 23:22:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16356 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 0A14BBD808 for ; Thu, 23 Jun 2022 23:22:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A489665659; Fri, 24 Jun 2022 01:22:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026567; bh=/q7FTUIgh7FCA3PW9417UeXt7frh0GiAoe4hGHSb3EE=; 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=BOi/HOUQ2o/8p4wROtzau5RxMq31oqfDHMISmmNW5A7EEUfQW16f+WFD7DsKsZ8dH ovTtLIG+8gMm3VB2L5L/Ym7EZNp3TXPn3NM+0Q/7nv7N3KqR0ydbJGuPJ5x6m04Lsi jkxrGcBnqTqeVyYlhx7xQ3rQsAyeyg6IsFTypMGhBvR40yXGP0O0gaP1jsJs591/5F 8oc2EhWwNvn+OTKI5iPTNThioG6JxBURCz+jQiEdpAAL4Vl6gUDNhye4DzOo74cRNg wBh506H/1sq1ZzGePKod5mkirArrRWCQ5/usY4xiSMoAUPf4XalKC9uavdRqzeWUsc 6nq6hIwOVTVFA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8638F65645 for ; Fri, 24 Jun 2022 01:22:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="mETVWfuw"; 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 0E18E80A; Fri, 24 Jun 2022 01:22:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026553; bh=/q7FTUIgh7FCA3PW9417UeXt7frh0GiAoe4hGHSb3EE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mETVWfuw/DXpx6FqBuwo3tCuXNVVY58LMgbiUE+dmWhzvYV9iBbrCqQqEzXkNsfYM nmSnRAlVLsC/Y26C83lEUvjGk63uUDhJ+xEEyqYhL9THxRgaihuRPYs0sox+OK35oS wlHsj3Z/Yon7gxF7vN7DJQxiY6D3aFG2jvBnmVDY= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:07 +0300 Message-Id: <20220623232210.18742-11-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 10/13] gstreamer: Fix pads locking 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" The srcpads_ vector is protected by two different locks, the GstObject lock of the libcamerasrc element, and the stream_lock that covers the run function of the thread. This isn't correct. Use the stream_lock consistently to protect the pads. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne --- src/gstreamer/gstlibcamerasrc.cpp | 68 ++++++++++++++++--------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index b85ba39fb808..58a322b251c7 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -112,7 +112,8 @@ struct GstLibcameraSrcState { std::shared_ptr cm_; std::shared_ptr cam_; std::unique_ptr config_; - std::vector srcpads_; + + std::vector srcpads_; /* Protected by stream_lock */ Mutex lock_; std::queue> queuedRequests_ @@ -349,36 +350,34 @@ gst_libcamera_src_task_run(gpointer user_data) srcpad, ret); } + if (ret != GST_FLOW_OK) { + if (ret == GST_FLOW_EOS) { + g_autoptr(GstEvent) eos = gst_event_new_eos(); + guint32 seqnum = gst_util_seqnum_next(); + gst_event_set_seqnum(eos, seqnum); + for (GstPad *srcpad : state->srcpads_) + gst_pad_push_event(srcpad, gst_event_ref(eos)); + } else if (ret != GST_FLOW_FLUSHING) { + GST_ELEMENT_FLOW_ERROR(self, ret); + } + gst_task_stop(self->task); + return; + } + + /* + * Here we need to decide if we want to pause. This needs to + * happen in lock step with the callback thread which may want + * to resume the task and might push pending buffers. + */ + bool do_pause; + { - if (ret != GST_FLOW_OK) { - if (ret == GST_FLOW_EOS) { - g_autoptr(GstEvent) eos = gst_event_new_eos(); - guint32 seqnum = gst_util_seqnum_next(); - gst_event_set_seqnum(eos, seqnum); - for (GstPad *srcpad : state->srcpads_) - gst_pad_push_event(srcpad, gst_event_ref(eos)); - } else if (ret != GST_FLOW_FLUSHING) { - GST_ELEMENT_FLOW_ERROR(self, ret); - } - gst_task_stop(self->task); - return; - } - - /* - * Here we need to decide if we want to pause. This needs to - * happen in lock step with the callback thread which may want - * to resume the task and might push pending buffers. - */ - bool do_pause; - - { - MutexLocker locker(state->lock_); - do_pause = state->completedRequests_.empty(); - } - - if (do_pause) - gst_task_pause(self->task); + MutexLocker locker(state->lock_); + do_pause = state->completedRequests_.empty(); } + + if (do_pause) + gst_task_pause(self->task); } static void @@ -532,8 +531,11 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task, state->completedRequests_ = {}; } - for (GstPad *srcpad : state->srcpads_) - gst_libcamera_pad_set_pool(srcpad, nullptr); + { + GLibRecLocker locker(&self->stream_lock); + for (GstPad *srcpad : state->srcpads_) + gst_libcamera_pad_set_pool(srcpad, nullptr); + } g_clear_object(&self->allocator); g_clear_pointer(&self->flow_combiner, @@ -692,7 +694,7 @@ gst_libcamera_src_request_new_pad(GstElement *element, GstPadTemplate *templ, g_object_ref_sink(pad); if (gst_element_add_pad(element, pad)) { - GLibLocker lock(GST_OBJECT(self)); + GLibRecLocker lock(&self->stream_lock); self->state->srcpads_.push_back(reinterpret_cast(g_object_ref(pad))); } else { GST_ELEMENT_ERROR(element, STREAM, FAILED, @@ -712,7 +714,7 @@ gst_libcamera_src_release_pad(GstElement *element, GstPad *pad) GST_DEBUG_OBJECT(self, "Pad %" GST_PTR_FORMAT " being released", pad); { - GLibLocker lock(GST_OBJECT(self)); + GLibRecLocker lock(&self->stream_lock); std::vector &pads = self->state->srcpads_; auto begin_iterator = pads.begin(); auto end_iterator = pads.end(); From patchwork Thu Jun 23 23:22:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16357 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 206DFBD808 for ; Thu, 23 Jun 2022 23:22:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A1A6D65643; Fri, 24 Jun 2022 01:22:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026568; bh=yPq7c7ZfcOuJPpnugS8qksvhaHaqFLv94z6Yf6wu0fQ=; 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=uGyXCVMDUP1BpDLWD+Crlsvygx275xLOulO08XwLSeyYbA5WUMGbXI7g9R8V/8iKk 6QM5NmhLTRgAa0jmks2NjzVBn8J0vP9Y3WSy5C6Umy9FzX3q1vUfodqFxKm24vXQox NX1pdNmcPGOn0yQfgF8RR9sHAjYS197nXClTmDwy1LIda1nT+XZuDCdSttBKkYGFqH 0LkvBiAHRPPjutRh2UVrpLcChuvbsYy2fqdAuhccxusSp4EcIjoIqaqsLhUR2k6uGS iKg9Ju6L876Wob6VFVITUJWifA8sfTUXU6+M4sE8jU6JEtI8A1RFZ+EZjPNk9EuLBW FSB8KwfPn9tRg== 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 08BD265638 for ; Fri, 24 Jun 2022 01:22:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WSqWQPxK"; 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 81ED46BB; Fri, 24 Jun 2022 01:22:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026553; bh=yPq7c7ZfcOuJPpnugS8qksvhaHaqFLv94z6Yf6wu0fQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WSqWQPxKxyEp9xhW0tYZu37Z9stKFixMvkaZvdX/IUY7ZJvbSllCFSFNlMEThzcB3 qryMtj0tlSUWcs9ZRs3+vwbOVbgYpPpWnvgo06mmOmfY2pzXDUr/I+ICuw92aY/0DD FykH6EEUW0kHbEAN5D6G052Vwko9b1xJOeUgf62Q= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:08 +0300 Message-Id: <20220623232210.18742-12-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 11/13] gstreamer: Split request creation to a separate function 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" In order to prepare for creation and queuing of multiple requests, move the request creation and queueing code to a separate function. No functional change intended. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne --- src/gstreamer/gstlibcamerasrc.cpp | 76 +++++++++++++++++-------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 58a322b251c7..fb39d6093a3f 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -123,6 +123,7 @@ struct GstLibcameraSrcState { guint group_id_; + int queueRequest(); void requestCompleted(Request *request); }; @@ -160,6 +161,44 @@ GstStaticPadTemplate request_src_template = { "src_%u", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS }; +int GstLibcameraSrcState::queueRequest() +{ + std::unique_ptr request = cam_->createRequest(); + if (!request) + return -ENOMEM; + + std::unique_ptr wrap = + std::make_unique(std::move(request)); + + for (GstPad *srcpad : srcpads_) { + Stream *stream = gst_libcamera_pad_get_stream(srcpad); + GstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad); + GstBuffer *buffer; + GstFlowReturn ret; + + ret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool), + &buffer, nullptr); + if (ret != GST_FLOW_OK) { + /* + * RequestWrap has ownership of the request, and we + * won't be queueing this one due to lack of buffers. + */ + return -ENOBUFS; + } + + wrap->attachBuffer(stream, buffer); + } + + GST_TRACE_OBJECT(src_, "Requesting buffers"); + cam_->queueRequest(wrap->request_.get()); + + MutexLocker locker(lock_); + queuedRequests_.push(std::move(wrap)); + + /* The RequestWrap will be deleted in the completion handler. */ + return 0; +} + void GstLibcameraSrcState::requestCompleted(Request *request) { @@ -269,8 +308,8 @@ gst_libcamera_src_task_run(gpointer user_data) GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data); GstLibcameraSrcState *state = self->state; - std::unique_ptr request = state->cam_->createRequest(); - if (!request) { + int err = state->queueRequest(); + if (err == -ENOMEM) { GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT, ("Failed to allocate request for camera '%s'.", state->cam_->id().c_str()), @@ -279,38 +318,7 @@ gst_libcamera_src_task_run(gpointer user_data) return; } - std::unique_ptr wrap = - std::make_unique(std::move(request)); - - for (GstPad *srcpad : state->srcpads_) { - Stream *stream = gst_libcamera_pad_get_stream(srcpad); - GstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad); - GstBuffer *buffer; - GstFlowReturn ret; - - ret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool), - &buffer, nullptr); - if (ret != GST_FLOW_OK) { - /* - * RequestWrap has ownership of the request, and we - * won't be queueing this one due to lack of buffers. - */ - wrap.release(); - break; - } - - wrap->attachBuffer(stream, buffer); - } - - if (wrap) { - GST_TRACE_OBJECT(self, "Requesting buffers"); - state->cam_->queueRequest(wrap->request_.get()); - - MutexLocker locker(state->lock_); - state->queuedRequests_.push(std::move(wrap)); - - /* The RequestWrap will be deleted in the completion handler. */ - } + std::unique_ptr wrap; { MutexLocker locker(state->lock_); From patchwork Thu Jun 23 23:22:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16358 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 2C482BD808 for ; Thu, 23 Jun 2022 23:22:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AAC2C65646; Fri, 24 Jun 2022 01:22:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026569; bh=kuUV4cQDhCFEWyID8KjYDqKsQek9t8YM9CCLyC+tTtA=; 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=F4MG61uRQrBP9PokxLuohJeT1ZyBKFkomXOLHwl8nZhWeLxyVyrI59blgOLZSZHse o9mWvjVEgLmbmJPx/Uas3e+xD5fmrD9wGA/6PKE261J2iBbmdcAgYy8mxs2yk6JirN FQ1QHX3fPh72FW5TTf8Yn91Q7VjU5oql0y6H6Q/pNd7L1Mw0i0i4jK7Q3jrH3Vhavd x+v1d7oFwHIixUboFwC19i9Omvfq+73dkkaaqFisA2iQ7bw0Jnc+Nc/DHY17ZvBPRN YRXD4kulQIzawj0tCTb2Ht/xRfSSwREPu5iTuQecb7y9hAefnCfOb8zw7rW5zJnuQU sHtE9sKWMiGxg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7186365635 for ; Fri, 24 Jun 2022 01:22:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="VqyfgypR"; 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 F3B95DD; Fri, 24 Jun 2022 01:22:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026554; bh=kuUV4cQDhCFEWyID8KjYDqKsQek9t8YM9CCLyC+tTtA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VqyfgypRXQOpddR7Cho4y0v+6/5zlKZ1HaJIwCA27bWVJ01d2pwkZ4HF4zP5gds/X b1/T68BlZR9dxU+gQ0oSaEsoNhTG25wj11wf1EBwyjX2C3u4scEhi6yxxyW1NtAfwD mqL+/2n/otWRBhI+9gAPD9jFGdX1D28g9G4CwzpA= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:09 +0300 Message-Id: <20220623232210.18742-13-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 12/13] gstreamer: Split completed request processing to a separate function 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" Simplify the task run function futher by moving the processing of completed requests to a separate function. No functional change intended, only increased readability. Signed-off-by: Laurent Pinchart Reviewed-by: Nicolas Dufresne --- src/gstreamer/gstlibcamerasrc.cpp | 125 +++++++++++++++++------------- 1 file changed, 73 insertions(+), 52 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index fb39d6093a3f..3feb87254916 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -125,6 +125,7 @@ struct GstLibcameraSrcState { int queueRequest(); void requestCompleted(Request *request); + int processRequest(); }; struct _GstLibcameraSrc { @@ -241,6 +242,63 @@ GstLibcameraSrcState::requestCompleted(Request *request) gst_task_resume(src_->task); } +int GstLibcameraSrcState::processRequest() +{ + std::unique_ptr wrap; + + { + MutexLocker locker(lock_); + + if (!completedRequests_.empty()) { + wrap = std::move(completedRequests_.front()); + completedRequests_.pop(); + } + } + + if (!wrap) + return -ENODATA; + + GstFlowReturn ret = GST_FLOW_OK; + gst_flow_combiner_reset(src_->flow_combiner); + + 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 (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; + + ret = gst_pad_push(srcpad, buffer); + ret = gst_flow_combiner_update_pad_flow(src_->flow_combiner, + srcpad, ret); + } + + if (ret != GST_FLOW_OK) { + if (ret == GST_FLOW_EOS) { + g_autoptr(GstEvent) eos = gst_event_new_eos(); + guint32 seqnum = gst_util_seqnum_next(); + gst_event_set_seqnum(eos, seqnum); + for (GstPad *srcpad : srcpads_) + gst_pad_push_event(srcpad, gst_event_ref(eos)); + } else if (ret != GST_FLOW_FLUSHING) { + GST_ELEMENT_FLOW_ERROR(src_, ret); + } + + return -EPIPE; + } + + return 0; +} + static bool gst_libcamera_src_open(GstLibcameraSrc *self) { @@ -308,8 +366,13 @@ gst_libcamera_src_task_run(gpointer user_data) GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data); GstLibcameraSrcState *state = self->state; - int err = state->queueRequest(); - if (err == -ENOMEM) { + /* + * Create and queue one request. If no buffers are available the + * function returns -ENOBUFS, which we ignore here as that's not a + * fatal error. + */ + int ret = state->queueRequest(); + if (ret == -ENOMEM) { GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT, ("Failed to allocate request for camera '%s'.", state->cam_->id().c_str()), @@ -318,58 +381,16 @@ gst_libcamera_src_task_run(gpointer user_data) return; } - std::unique_ptr wrap; - - { - MutexLocker locker(state->lock_); - - if (!state->completedRequests_.empty()) { - wrap = std::move(state->completedRequests_.front()); - state->completedRequests_.pop(); - } - } - - if (!wrap) { - gst_task_pause(self->task); - return; - } - - GstFlowReturn ret = GST_FLOW_OK; - gst_flow_combiner_reset(self->flow_combiner); - - 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; - - ret = gst_pad_push(srcpad, buffer); - ret = gst_flow_combiner_update_pad_flow(self->flow_combiner, - srcpad, ret); - } - - if (ret != GST_FLOW_OK) { - if (ret == GST_FLOW_EOS) { - g_autoptr(GstEvent) eos = gst_event_new_eos(); - guint32 seqnum = gst_util_seqnum_next(); - gst_event_set_seqnum(eos, seqnum); - for (GstPad *srcpad : state->srcpads_) - gst_pad_push_event(srcpad, gst_event_ref(eos)); - } else if (ret != GST_FLOW_FLUSHING) { - GST_ELEMENT_FLOW_ERROR(self, ret); - } + /* Process one completed request, if available. */ + ret = state->processRequest(); + switch (ret) { + case -EPIPE: gst_task_stop(self->task); return; + + case -ENODATA: + gst_task_pause(self->task); + return; } /* From patchwork Thu Jun 23 23:22:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16359 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 6CFF7BD808 for ; Thu, 23 Jun 2022 23:22:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D29A66565C; Fri, 24 Jun 2022 01:22:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656026571; bh=NPCkwNXRJdjGrG38Wc76cbEo79KkSu6n0yqhqAccaj0=; 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=yCJlKeJU2LBlc5t/red5m940H+Yq8iDEYRZXWxP+Qz8vp6LUEi7+b57VaJ5AZSMI0 CbDLu8tr0Qjcy5CcRS40SsDmRLaZ6Nm5vlzWHZSey3vakm5QHWUR1dXtVljuIxIRmf onIG1Rx1jPCrLlGRCcf+9wo3FcfGxk+T+tf2nM36ZV+klu97YwI3nz+QPG0TBQRjj9 I3WeZCyZfRatVS4mnipNoSTmx8zD4Mq8GPwmJoL4XwhlWLigrCi8FUMW2gFkVNhsPz cMGr/cKTaIOGZErOLfhtddB/qi19T9j+p+mJIeq7/TPPJJ/Y4fQ8yNlKoSEXSUoZn6 yzlj76BiqvZ7Q== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E372765646 for ; Fri, 24 Jun 2022 01:22:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="LiOqdHn5"; 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 725BD6BB; Fri, 24 Jun 2022 01:22:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656026554; bh=NPCkwNXRJdjGrG38Wc76cbEo79KkSu6n0yqhqAccaj0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LiOqdHn5Uq3hcWU2dldkYYioiOYyMsEHbLDwmMF6G9CTip8Zv38I9XhxXbq0/3RWK OFZZkpnynUIDikyWTskk6s73Fwh6b/P0H4ASlKb2CFuNiy1WNhRdRT7ia2KGqDuzqz xhIP877V5FPeD4NkWZMrsWoIfpAhO+zvs7AndNuk= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Jun 2022 02:22:10 +0300 Message-Id: <20220623232210.18742-14-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 13/13] gstreamer: Fix race conditions in task pause/resume 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" The task run function races with two other threads that want to resume the task: the requestCompleted() handler and the buffer-notify signal handler. If the former queues completed requests or the latter queues back buffers to the pool, and then resume the task, after the task run handler checks the queues but before it attemps to pause the task, then the task may be paused without noticing that more work is available. The most immediate way to fix this is to take the stream_lock in the requestCompleted() and buffer-notify signal handlers, or cover the whole task run handler with the GstLibcameraSrcState lock. This could cause long delays in the requestCompleted() handler, so that's not a good option. Instead, add a wakeup flag, preotected by the GstLibcameraSrcState lock, that allows detection of a lost race, and retry the task run. Signed-off-by: Laurent Pinchart --- src/gstreamer/gstlibcamerasrc.cpp | 82 +++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 3feb87254916..59400f17ae85 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -120,6 +120,7 @@ struct GstLibcameraSrcState { LIBCAMERA_TSA_GUARDED_BY(lock_); std::queue> completedRequests_ LIBCAMERA_TSA_GUARDED_BY(lock_); + bool wakeup_ LIBCAMERA_TSA_GUARDED_BY(lock_); guint group_id_; @@ -237,14 +238,16 @@ GstLibcameraSrcState::requestCompleted(Request *request) { MutexLocker locker(lock_); completedRequests_.push(std::move(wrap)); - } + wakeup_ = true; - gst_task_resume(src_->task); + gst_task_resume(src_->task); + } } int GstLibcameraSrcState::processRequest() { std::unique_ptr wrap; + int err = 0; { MutexLocker locker(lock_); @@ -253,10 +256,13 @@ int GstLibcameraSrcState::processRequest() wrap = std::move(completedRequests_.front()); completedRequests_.pop(); } + + if (completedRequests_.empty()) + err = -ENOBUFS; } if (!wrap) - return -ENODATA; + return -ENOBUFS; GstFlowReturn ret = GST_FLOW_OK; gst_flow_combiner_reset(src_->flow_combiner); @@ -296,7 +302,7 @@ int GstLibcameraSrcState::processRequest() return -EPIPE; } - return 0; + return err; } static bool @@ -360,53 +366,88 @@ gst_libcamera_src_open(GstLibcameraSrc *self) return true; } +static void +gst_libcamera_src_task_resume(gpointer user_data) +{ + GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data); + GstLibcameraSrcState *state = self->state; + + MutexLocker locker(state->lock_); + state->wakeup_ = true; + gst_task_resume(self->task); +} + static void gst_libcamera_src_task_run(gpointer user_data) { GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data); GstLibcameraSrcState *state = self->state; + { + MutexLocker locker(state->lock_); + state->wakeup_ = true; + } + + bool doPause = true; + /* * Create and queue one request. If no buffers are available the * function returns -ENOBUFS, which we ignore here as that's not a * fatal error. */ int ret = state->queueRequest(); - if (ret == -ENOMEM) { + switch (ret) { + case 0: + /* + * The request was successfully queued, there may be enough + * buffers to create a new one. Don't pause the task to give it + * another try. + */ + doPause = false; + break; + + case -ENOMEM: GST_ELEMENT_ERROR(self, RESOURCE, NO_SPACE_LEFT, ("Failed to allocate request for camera '%s'.", state->cam_->id().c_str()), ("libcamera::Camera::createRequest() failed")); gst_task_stop(self->task); return; + + case -ENOBUFS: + default: + break; } - /* Process one completed request, if available. */ + /* + * Process one completed request, if available, and record if further + * requests are ready for processing. + */ ret = state->processRequest(); switch (ret) { + case -ENOBUFS: + doPause = false; + break; + case -EPIPE: gst_task_stop(self->task); return; - case -ENODATA: - gst_task_pause(self->task); - return; + case 0: + default: + break; } /* - * Here we need to decide if we want to pause. This needs to - * happen in lock step with the callback thread which may want - * to resume the task and might push pending buffers. + * Here we need to decide if we want to pause. This needs to happen in + * lock step with the requestCompleted callback and the buffer-notify + * signal handler that resume the task. */ - bool do_pause; - - { + if (doPause) { MutexLocker locker(state->lock_); - do_pause = state->completedRequests_.empty(); + if (!state->wakeup_) + gst_task_pause(self->task); } - - if (do_pause) - gst_task_pause(self->task); } static void @@ -517,7 +558,8 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, GstLibcameraPool *pool = gst_libcamera_pool_new(self->allocator, stream_cfg.stream()); g_signal_connect_swapped(pool, "buffer-notify", - G_CALLBACK(gst_task_resume), task); + G_CALLBACK(gst_libcamera_src_task_resume), + self); gst_libcamera_pad_set_pool(srcpad, pool); gst_flow_combiner_add_pad(self->flow_combiner, srcpad);