Patch Detail
Show a patch.
GET /api/patches/2749/?format=api
{ "id": 2749, "url": "https://patchwork.libcamera.org/api/patches/2749/?format=api", "web_url": "https://patchwork.libcamera.org/patch/2749/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/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": "<20200129033210.278800-16-nicolas@ndufresne.ca>", "date": "2020-01-29T03:32:02", "name": "[libcamera-devel,v1,15/23] gst: libcamerasrc: Implement minimal caps negotiation", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "3b7006b6826a801a73a7c9b5993c6a69cde26b04", "submitter": { "id": 30, "url": "https://patchwork.libcamera.org/api/people/30/?format=api", "name": "Nicolas Dufresne", "email": "nicolas@ndufresne.ca" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/2749/mbox/", "series": [ { "id": 648, "url": "https://patchwork.libcamera.org/api/series/648/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=648", "date": "2020-01-29T03:31:47", "name": "GStreamer Element for libcamera", "version": 1, "mbox": "https://patchwork.libcamera.org/series/648/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/2749/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/2749/checks/", "tags": {}, "headers": { "Return-Path": "<nicolas@ndufresne.ca>", "Received": [ "from bhuna.collabora.co.uk (bhuna.collabora.co.uk\n\t[IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 141F4608CA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jan 2020 04:35:36 +0100 (CET)", "from nicolas-tpx395.localdomain (unknown\n\t[IPv6:2002:c0de:c115:0:66fc:8b:2a38:8313])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits))\n\t(No client certificate requested) (Authenticated sender: nicolas)\n\tby bhuna.collabora.co.uk (Postfix) with ESMTPSA id 8568028EA9F;\n\tWed, 29 Jan 2020 03:35:34 +0000 (GMT)" ], "From": "Nicolas Dufresne <nicolas@ndufresne.ca>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Nicolas Dufresne <nicolas.dufresne@collabora.com>", "Date": "Tue, 28 Jan 2020 22:32:02 -0500", "Message-Id": "<20200129033210.278800-16-nicolas@ndufresne.ca>", "X-Mailer": "git-send-email 2.24.1", "In-Reply-To": "<20200129033210.278800-1-nicolas@ndufresne.ca>", "References": "<20200129033210.278800-1-nicolas@ndufresne.ca>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v1 15/23] gst: libcamerasrc: Implement\n\tminimal caps negotiation", "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>", "X-List-Received-Date": "Wed, 29 Jan 2020 03:35:36 -0000" }, "content": "From: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n\nThis is not expected to work in every possible cases, but should be sufficient as\nan initial implementation. What is does it that it turns the StreamFormats into\ncaps and query downstream caps with that as a filter.\n\nThe result is the subset of caps that can be used. We then keep the first\nstructure in that result and fixate using the default values found in\nStreamConfiguration as a default in case a range is available.\n\nWe then validate this configuration and turn the potentially modified\nconfiguration into caps that we push downstream. Note that we strust the order\nin StreamFormats as being sorted best first, but this is not currently in\nlibcamera.\n\nSigned-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n---\n src/gstreamer/gstlibcamerasrc.cpp | 71 +++++++++++++++++++++++++++++++\n 1 file changed, 71 insertions(+)", "diff": "diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\nindex b1a21dc..7b478fa 100644\n--- a/src/gstreamer/gstlibcamerasrc.cpp\n+++ b/src/gstreamer/gstlibcamerasrc.cpp\n@@ -24,6 +24,7 @@ GST_DEBUG_CATEGORY_STATIC(source_debug);\n struct GstLibcameraSrcState {\n \tstd::shared_ptr<CameraManager> cm;\n \tstd::shared_ptr<Camera> cam;\n+\tstd::unique_ptr<CameraConfiguration> config;\n \tstd::vector<GstPad *> srcpads;\n };\n \n@@ -132,16 +133,86 @@ gst_libcamera_src_task_enter(GstTask *task, GThread *thread, gpointer user_data)\n \tSTREAM_LOCKER(user_data);\n \tGstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);\n \tGstLibcameraSrcState *state = self->state;\n+\tGstFlowReturn flow_ret = GST_FLOW_OK;\n \n \tGST_DEBUG_OBJECT(self, \"Streaming thread has started\");\n \n \tguint group_id = gst_util_group_id_next();\n+\tStreamRoles roles;\n \tfor (GstPad *srcpad : state->srcpads) {\n \t\t/* Create stream-id and push stream-start */\n \t\tg_autofree gchar *stream_id = gst_pad_create_stream_id(srcpad, GST_ELEMENT(self), nullptr);\n \t\tGstEvent *event = gst_event_new_stream_start(stream_id);\n \t\tgst_event_set_group_id(event, group_id);\n \t\tgst_pad_push_event(srcpad, event);\n+\n+\t\t/* Collect the streams roles for the next iteration */\n+\t\troles.push_back(gst_libcamera_pad_get_role(srcpad));\n+\t}\n+\n+\t/* Generate the stream configurations, there should be one per pad */\n+\tstate->config = state->cam->generateConfiguration(roles);\n+\tg_assert(state->config->size() == state->srcpads.size());\n+\n+\tfor (gsize i = 0; i < state->srcpads.size(); i++) {\n+\t\tGstPad *srcpad = state->srcpads[i];\n+\t\tStreamConfiguration &stream_cfg = state->config->at(i);\n+\n+\t\t/* Retreive the supported caps */\n+\t\tg_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());\n+\t\tg_autoptr(GstCaps) caps = gst_pad_peer_query_caps(srcpad, filter);\n+\t\tif (gst_caps_is_empty(caps)) {\n+\t\t\tflow_ret = GST_FLOW_NOT_NEGOTIATED;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Fixate caps and configure the stream */\n+\t\tcaps = gst_caps_make_writable(caps);\n+\t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps);\n+\t}\n+\n+\tif (flow_ret != GST_FLOW_OK)\n+\t\tgoto done;\n+\n+\t/* Validate the configuration */\n+\tif (state->config->validate() == CameraConfiguration::Invalid) {\n+\t\tflow_ret = GST_FLOW_NOT_NEGOTIATED;\n+\t\tgoto done;\n+\t}\n+\n+\t/* Regardless if it has been modified, create clean caps and push the\n+\t * caps event, downstream will decide if hte caps are acceptable */\n+\tfor (gsize i = 0; i < state->srcpads.size(); i++) {\n+\t\tGstPad *srcpad = state->srcpads[i];\n+\t\tconst StreamConfiguration &stream_cfg = state->config->at(i);\n+\n+\t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg);\n+\t\tif (!gst_pad_push_event(srcpad, gst_event_new_caps(caps))) {\n+\t\t\tflow_ret = GST_FLOW_NOT_NEGOTIATED;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tret = state->cam->configure(state->config.get());\n+\tif (ret) {\n+\t\tGST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,\n+\t\t\t\t (\"Failed to configure camera: %s\", g_strerror(-ret)),\n+\t\t\t\t (\"Camera.configure() failed with error code %i\", ret));\n+\t\tgst_task_stop(task);\n+\t\treturn;\n+\t}\n+\n+done:\n+\tswitch (flow_ret) {\n+\tcase GST_FLOW_NOT_NEGOTIATED:\n+\t\tfor (GstPad *srcpad : state->srcpads) {\n+\t\t\tgst_pad_push_event(srcpad, gst_event_new_eos());\n+\t\t}\n+\t\tGST_ELEMENT_FLOW_ERROR(self, flow_ret);\n+\t\tgst_task_stop(task);\n+\t\treturn;\n+\tdefault:\n+\t\tbreak;\n \t}\n }\n \n", "prefixes": [ "libcamera-devel", "v1", "15/23" ] }