Show a patch.

GET /api/1.1/patches/16442/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 16442,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/16442/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/16442/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220630000251.31295-7-laurent.pinchart@ideasonboard.com>",
    "date": "2022-06-30T00:02:45",
    "name": "[libcamera-devel,v2,06/12] gstreamer: Handle completed requests in the libcamerasrc task",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "bb66a4f62368a8fabe299cdc06f837cb424b6520",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/16442/mbox/",
    "series": [
        {
            "id": 3234,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3234/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3234",
            "date": "2022-06-30T00:02:39",
            "name": "gstreamer: Queue multiple requests",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/3234/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/16442/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/16442/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>",
        "X-Original-To": "parsemail@patchwork.libcamera.org",
        "Delivered-To": "parsemail@patchwork.libcamera.org",
        "Received": [
            "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 3D315BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 30 Jun 2022 00:03:28 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A85876563F;\n\tThu, 30 Jun 2022 02:03:27 +0200 (CEST)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EDA065641\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Jun 2022 02:03:17 +0200 (CEST)",
            "from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 307C759D;\n\tThu, 30 Jun 2022 02:03:17 +0200 (CEST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656547407;\n\tbh=daSkBUqMGuW7q9N/BmNV/l8m4/bCX/bMskfiaEbpzsA=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=ZY9uENotfJ33nYfW8zCJc6P5S9h7RntsTgqMPAmU2AuDldP3eUKNQ9lvEqAzQf/jY\n\tK1RIOVQ/QVB5aDae35jv3kBc8wjsSmS3AzNGPM0/pIXX12/VKsEqSIfB80jfBKchu9\n\tcttaOqA+vg5Be7St1Rt5nFSv/cwOWagaFz9onlbsugFuZ5jFsE/ueyZEafhfGBwPuh\n\tIS1gXayFLNLoRpbLcQhL346lMqYoVEjP/6xzdgdL8Xl0BqJnLBdgRAhxlJCSMhCdOq\n\t84Fgg5ttID3Z3QuNXWN09Ju5KAxGPFhB5kr3W2scBsFEQGX8MZOOOVH8XY9t49YH/u\n\t9wTOOBAq1ag1w==",
            "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656547397;\n\tbh=daSkBUqMGuW7q9N/BmNV/l8m4/bCX/bMskfiaEbpzsA=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=IKrEtFFNWaTUjYxDXoo8NKo42SzAYHRNmNrFL0QXnbGGhOWR+J4j8Zl8WvWY3muXv\n\tMc/+rfn+5EFda/BfHHg3T7hMBHFGoqOJQKHVQGXrx/qmLVNMHGaBTvPnJwqUiZ6IrR\n\tOIhee4DvMlEn5vqGLyEGp82K0K63DZFSk4wGz/ZI="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"IKrEtFFN\"; dkim-atps=neutral",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Thu, 30 Jun 2022 03:02:45 +0300",
        "Message-Id": "<20220630000251.31295-7-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.35.1",
        "In-Reply-To": "<20220630000251.31295-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20220630000251.31295-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v2 06/12] gstreamer: Handle completed\n\trequests in the libcamerasrc task",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "From": "Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "Cc": "Nicolas Dufresne <nicolas.dufresne@collabora.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Move the request wrap to a completed queue in the request completion\nhandler to move more of the request completion processing to the\nlibcamerasrc task. This lowers the amount of time spent in the\ncompletion handler, and prepares for reworking the usage of locks.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\nChanges since v1:\n\n- Use GST_CLOCK_TIME_NONE and GST_CLOCK_TIME_IS_VALID()\n---\n src/gstreamer/gstlibcamerasrc.cpp | 82 ++++++++++++++++++-------------\n 1 file changed, 48 insertions(+), 34 deletions(-)",
    "diff": "diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\nindex f2f48d53991a..2cb915637874 100644\n--- a/src/gstreamer/gstlibcamerasrc.cpp\n+++ b/src/gstreamer/gstlibcamerasrc.cpp\n@@ -57,10 +57,13 @@ struct RequestWrap {\n \n \tstd::unique_ptr<Request> request_;\n \tstd::map<Stream *, GstBuffer *> buffers_;\n+\n+\tGstClockTime latency_;\n+\tGstClockTime pts_;\n };\n \n RequestWrap::RequestWrap(std::unique_ptr<Request> request)\n-\t: request_(std::move(request))\n+\t: request_(std::move(request)), latency_(0), pts_(GST_CLOCK_TIME_NONE)\n {\n }\n \n@@ -109,6 +112,7 @@ struct GstLibcameraSrcState {\n \tstd::unique_ptr<CameraConfiguration> config_;\n \tstd::vector<GstPad *> srcpads_;\n \tstd::queue<std::unique_ptr<RequestWrap>> queuedRequests_;\n+\tstd::queue<std::unique_ptr<RequestWrap>> completedRequests_;\n \tguint group_id_;\n \n \tvoid requestCompleted(Request *request);\n@@ -165,9 +169,6 @@ GstLibcameraSrcState::requestCompleted(Request *request)\n \t\treturn;\n \t}\n \n-\tGstClockTime latency;\n-\tGstClockTime pts;\n-\n \tif (GST_ELEMENT_CLOCK(src_)) {\n \t\tint64_t timestamp = request->metadata().get(controls::SensorTimestamp);\n \n@@ -178,31 +179,11 @@ GstLibcameraSrcState::requestCompleted(Request *request)\n \n \t\t/* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */\n \t\tGstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);\n-\t\tpts = timestamp - sys_base_time;\n-\t\tlatency = sys_now - timestamp;\n-\t} else {\n-\t\tlatency = 0;\n-\t\tpts = GST_CLOCK_TIME_NONE;\n+\t\twrap->pts_ = timestamp - sys_base_time;\n+\t\twrap->latency_ = sys_now - timestamp;\n \t}\n \n-\tfor (GstPad *srcpad : srcpads_) {\n-\t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n-\t\tGstBuffer *buffer = wrap->detachBuffer(stream);\n-\n-\t\tFrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer);\n-\n-\t\tif (GST_CLOCK_TIME_IS_VALID(pts)) {\n-\t\t\tGST_BUFFER_PTS(buffer) = pts;\n-\t\t\tgst_libcamera_pad_set_latency(srcpad, latency);\n-\t\t} else {\n-\t\t\tGST_BUFFER_PTS(buffer) = 0;\n-\t\t}\n-\n-\t\tGST_BUFFER_OFFSET(buffer) = fb->metadata().sequence;\n-\t\tGST_BUFFER_OFFSET_END(buffer) = fb->metadata().sequence;\n-\n-\t\tgst_libcamera_pad_queue_buffer(srcpad, buffer);\n-\t}\n+\tcompletedRequests_.push(std::move(wrap));\n \n \tgst_task_resume(src_->task);\n }\n@@ -316,6 +297,39 @@ gst_libcamera_src_task_run(gpointer user_data)\n \t\t/* The RequestWrap will be deleted in the completion handler. */\n \t}\n \n+\t{\n+\t\tGLibLocker lock(GST_OBJECT(self));\n+\n+\t\tif (!state->completedRequests_.empty()) {\n+\t\t\twrap = std::move(state->completedRequests_.front());\n+\t\t\tstate->completedRequests_.pop();\n+\t\t}\n+\t}\n+\n+\tif (!wrap) {\n+\t\tgst_task_pause(self->task);\n+\t\treturn;\n+\t}\n+\n+\tfor (GstPad *srcpad : state->srcpads_) {\n+\t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n+\t\tGstBuffer *buffer = wrap->detachBuffer(stream);\n+\n+\t\tFrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer);\n+\n+\t\tif (GST_CLOCK_TIME_IS_VALID(wrap->pts_)) {\n+\t\t\tGST_BUFFER_PTS(buffer) = wrap->pts_;\n+\t\t\tgst_libcamera_pad_set_latency(srcpad, wrap->latency_);\n+\t\t} else {\n+\t\t\tGST_BUFFER_PTS(buffer) = 0;\n+\t\t}\n+\n+\t\tGST_BUFFER_OFFSET(buffer) = fb->metadata().sequence;\n+\t\tGST_BUFFER_OFFSET_END(buffer) = fb->metadata().sequence;\n+\n+\t\tgst_libcamera_pad_queue_buffer(srcpad, buffer);\n+\t}\n+\n \tGstFlowReturn ret = GST_FLOW_OK;\n \tgst_flow_combiner_reset(self->flow_combiner);\n \tfor (GstPad *srcpad : state->srcpads_) {\n@@ -344,13 +358,11 @@ gst_libcamera_src_task_run(gpointer user_data)\n \t\t * happen in lock step with the callback thread which may want\n \t\t * to resume the task and might push pending buffers.\n \t\t */\n-\t\tGLibLocker lock(GST_OBJECT(self));\n-\t\tbool do_pause = true;\n-\t\tfor (GstPad *srcpad : state->srcpads_) {\n-\t\t\tif (gst_libcamera_pad_has_pending(srcpad)) {\n-\t\t\t\tdo_pause = false;\n-\t\t\t\tbreak;\n-\t\t\t}\n+\t\tbool do_pause;\n+\n+\t\t{\n+\t\t\tGLibLocker lock(GST_OBJECT(self));\n+\t\t\tdo_pause = state->completedRequests_.empty();\n \t\t}\n \n \t\tif (do_pause)\n@@ -504,6 +516,8 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task,\n \n \tstate->cam_->stop();\n \n+\tstate->completedRequests_ = {};\n+\n \tfor (GstPad *srcpad : state->srcpads_)\n \t\tgst_libcamera_pad_set_pool(srcpad, nullptr);\n \n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "06/12"
    ]
}