{"id":13489,"url":"https://patchwork.libcamera.org/api/patches/13489/?format=json","web_url":"https://patchwork.libcamera.org/patch/13489/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20210825150744.1183551-1-nicolas@ndufresne.ca>","date":"2021-08-25T15:07:44","name":"[libcamera-devel] gstreamer: Fix usage of default size for fixation","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"057c9afbdf46b1da9b81d66ada3de738489e402c","submitter":{"id":30,"url":"https://patchwork.libcamera.org/api/people/30/?format=json","name":"Nicolas Dufresne","email":"nicolas@ndufresne.ca"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/13489/mbox/","series":[{"id":2393,"url":"https://patchwork.libcamera.org/api/series/2393/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=2393","date":"2021-08-25T15:07:44","name":"[libcamera-devel] gstreamer: Fix usage of default size for fixation","version":1,"mbox":"https://patchwork.libcamera.org/series/2393/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/13489/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/13489/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 86917BD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 25 Aug 2021 15:08:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 042C468891;\n\tWed, 25 Aug 2021 17:08:02 +0200 (CEST)","from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A222560259\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 25 Aug 2021 17:08:00 +0200 (CEST)","from [127.0.0.1] (localhost [127.0.0.1])\n\t(Authenticated sender: nicolas) with ESMTPSA id C944D1F413C8"],"From":"Nicolas Dufresne <nicolas@ndufresne.ca>","To":"libcamera-devel@lists.libcamera.org","Date":"Wed, 25 Aug 2021 11:07:44 -0400","Message-Id":"<20210825150744.1183551-1-nicolas@ndufresne.ca>","X-Mailer":"git-send-email 2.31.1","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH] gstreamer: Fix usage of default size for\n\tfixation","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>","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":"From: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n\nEven thought this is not formaly documented, all pipeline managers sets a\ndefault value to StreamConfiguration::size. The original fixation code was\nattempting to use it, but as it was truncating the caps to its first structure\nit would never actually find a best match.\n\nIn this patch, instead of truncating, we weight various matches using the\nproduct of the width and height delta. We also split delta from ranges\nappart and prefer fixed size over them as ranges are not reliable.\n\nThis patch also removes the related todo, as it seems that libcamera core won't\ngo further then providing this default value and won't be sorting the format and\nsize lists.\n\nSigned-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n---\n src/gstreamer/gstlibcamera-utils.cpp | 51 +++++++++++++++++++++++++---\n src/gstreamer/gstlibcamerasrc.cpp    |  4 ---\n 2 files changed, 47 insertions(+), 8 deletions(-)","diff":"diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp\nindex 61370d5f..007d6a64 100644\n--- a/src/gstreamer/gstlibcamera-utils.cpp\n+++ b/src/gstreamer/gstlibcamera-utils.cpp\n@@ -136,14 +136,57 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n \t\t\t\t\t GstCaps *caps)\n {\n \tGstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat);\n+\tguint i;\n+\tgint best_fixed = -1, best_in_range = -1;\n+\tGstStructure *s;\n+\n+\t/*\n+\t * These are delta weight computed from:\n+\t *   ABS(width - stream_cfg.size.width) * ABS(height - stream_cfg.size.height)\n+\t */\n+\tguint best_fixed_delta = G_MAXUINT;\n+\tguint best_in_range_delta = G_MAXUINT;\n \n \t/* First fixate the caps using default configuration value. */\n \tg_assert(gst_caps_is_writable(caps));\n-\tcaps = gst_caps_truncate(caps);\n-\tGstStructure *s = gst_caps_get_structure(caps, 0);\n \n-\tgst_structure_fixate_field_nearest_int(s, \"width\", stream_cfg.size.width);\n-\tgst_structure_fixate_field_nearest_int(s, \"height\", stream_cfg.size.height);\n+\t/* Lookup the structure for a close match to the stream_cfg.size */\n+\tfor (i = 0; i < gst_caps_get_size(caps); i++) {\n+\t\ts = gst_caps_get_structure(caps, i);\n+\t\tgint width, height;\n+\t\tguint delta;\n+\n+\t\tif (gst_structure_has_field_typed(s, \"width\", G_TYPE_INT) &&\n+\t\t    gst_structure_has_field_typed(s, \"height\", G_TYPE_INT)) {\n+\t\t\tgst_structure_get_int(s, \"width\", &width);\n+\t\t\tgst_structure_get_int(s, \"width\", &height);\n+\n+\t\t\tdelta = ABS(width - (gint)stream_cfg.size.width) * ABS(height - (gint)stream_cfg.size.height);\n+\n+\t\t\tif (delta < best_fixed_delta) {\n+\t\t\t\tbest_fixed_delta = delta;\n+\t\t\t\tbest_fixed = i;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tgst_structure_fixate_field_nearest_int(s, \"width\", stream_cfg.size.width);\n+\t\t\tgst_structure_fixate_field_nearest_int(s, \"height\", stream_cfg.size.height);\n+\t\t\tgst_structure_get_int(s, \"width\", &width);\n+\t\t\tgst_structure_get_int(s, \"width\", &height);\n+\n+\t\t\tdelta = ABS(width - (gint)stream_cfg.size.width) * ABS(height - (gint)stream_cfg.size.height);\n+\n+\t\t\tif (delta < best_in_range_delta) {\n+\t\t\t\tbest_in_range_delta = delta;\n+\t\t\t\tbest_in_range = i;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* Prefer reliable fixed value over ranges */\n+\tif (best_fixed >= 0)\n+\t\ts = gst_caps_get_structure(caps, best_fixed);\n+\telse\n+\t\ts = gst_caps_get_structure(caps, best_in_range);\n \n \tif (gst_structure_has_name(s, \"video/x-raw\")) {\n \t\tconst gchar *format = gst_video_format_to_string(gst_format);\ndiff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\nindex b243aeb3..4c7b36ae 100644\n--- a/src/gstreamer/gstlibcamerasrc.cpp\n+++ b/src/gstreamer/gstlibcamerasrc.cpp\n@@ -25,10 +25,6 @@\n  *  - Add timestamp support\n  *  - Use unique names to select the camera devices\n  *  - Add GstVideoMeta support (strides and offsets)\n- *\n- * \\todo libcamera UVC drivers picks the lowest possible resolution first, this\n- * should be fixed so that we get a decent resolution and framerate for the\n- * role by default.\n  */\n \n #include \"gstlibcamerasrc.h\"\n","prefixes":["libcamera-devel"]}