From patchwork Thu Jun 30 00:02:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16448 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 30EE0BD808 for ; Thu, 30 Jun 2022 00:03:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BDD4F65652; Thu, 30 Jun 2022 02:03:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1656547415; bh=/Y6Gh5gSlLJaNtCb6JdJ/0zj1CcdRKeiIr10vTYnpTs=; 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=AjvAMr4dEA45/kytqWew8qLJ6pZ5zDWwe2Zx2w6zOve/nmXgKCs/nx6KueWotjmX+ lNbWNB1zuPLq6aq51SL3UOVfQvtuKu1ukZLOpwzQWT8/yZKiuLpeV833KBGW+jTuh3 El4abZxse7vf6U86WSzsJ1fE0ytqZ9wXcewfrpaSjMTfvUrIMUEDqCw5C4suC5c7oB 7Quf99/VYMj22LQPf4mfnTTReP3H9WGzfV8IXQH9zh4jsy1I/IZSWb79SzvG0imaCl 14ccQsXNdczYUis7OY1WMK4/p9eThJjHQAbH8KUn0XacXBVVMhwtdHqUDzrHen1osY clNQPIUltAkOg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 27E5A65638 for ; Thu, 30 Jun 2022 02:03:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gIZ+cejF"; 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 AD87D6D1; Thu, 30 Jun 2022 02:03:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1656547399; bh=/Y6Gh5gSlLJaNtCb6JdJ/0zj1CcdRKeiIr10vTYnpTs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gIZ+cejFd4P1oy96FWt/n07RZOvCAfXvHFmFFTUj12f45z1InL+D4eRimqY6Xc0n2 SwwvmJnWMbOrDvH8c1VleOJzpLho+wxbDSIl2k5VdQggRKXYBDE42zql9KyP/1nTIw zeZ6KJcVREUshNiGvKAyPlWl2j61TesJ9AdGLexM= To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jun 2022 03:02:50 +0300 Message-Id: <20220630000251.31295-12-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 11/12] 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 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 Reviewed-by: Umang Jain --- Changes since v1: - Add comment about locking requirement --- src/gstreamer/gstlibcamerasrc.cpp | 126 ++++++++++++++++++------------ 1 file changed, 74 insertions(+), 52 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index d63083d0cd8f..9ea59631a9f2 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -135,6 +135,7 @@ struct GstLibcameraSrcState { int queueRequest(); void requestCompleted(Request *request); + int processRequest(); }; struct _GstLibcameraSrc { @@ -254,6 +255,64 @@ GstLibcameraSrcState::requestCompleted(Request *request) gst_task_resume(src_->task); } +/* Must be called with stream_lock held. */ +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 (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; + + 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) { @@ -321,8 +380,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()), @@ -331,58 +395,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 (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; - - 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; } /*