From patchwork Fri Jun 9 14:31:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cedric Nugteren X-Patchwork-Id: 18723 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 129CEC3220 for ; Fri, 9 Jun 2023 14:31:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 673F061E55; Fri, 9 Jun 2023 16:31:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1686321111; bh=CIwF9qAgRlvvWFyHGl6rIftyENmxJIkfvOrlgK7FJFM=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=fv2r93+b5UclRVhgPszauh2rMGmZyh7PEP5ALfs+gWUOfBH1v/0oPHI5qzyfijjwm kCr6NPoEpoPe04wqFXd3oOoZEuGj8RlcOPY/s3viA3y6jTaUq6wZYoNDvrQ5ofO5gn sX2qCs2BfK9zttcIjzydkGWM4SpN3xVfLDAAYNaxzu9vkoy9VXAPGg/WelejvNCxMv HBzqs3er3UhetnFQ83e63xoWudCrQIrRzGiNyg9y6oUx+hFpJ44kqOkQNnwWBS9TkM dai85t5pImwMABVdHv5Ue6h+hPuK0Q970KPKwv93hgIu5YkRPp+MzyyJLzX7wIYNgk NJLG9yQal5dUQ== Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 07B2961E4E for ; Fri, 9 Jun 2023 16:31:49 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=plumerai.com header.i=@plumerai.com header.b="rt3Ypmiq"; dkim-atps=neutral Received: by mail-ej1-x635.google.com with SMTP id a640c23a62f3a-97668583210so278692566b.1 for ; Fri, 09 Jun 2023 07:31:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=plumerai.com; s=google; t=1686321108; x=1688913108; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=MCSLbAV7rAsv6nC+4rmvVkwtrrOBWzDyqzJdjso3e6U=; b=rt3YpmiqLRi7HxhAaxbU1LvB0rhuPdJC08ogmCHKv4OaG/7hfMH/dfcBykbTKQ3Dyi TL7wGZ2NqqolkBA/YqOh5b/kXuM+9bhFkd/eAqzCf9XCydiMSyjYagy3eZLXp8HVtj4K Cxlqg7Sat1ldrL5ne7VzI582Lq09XO6gqHMy8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686321108; x=1688913108; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=MCSLbAV7rAsv6nC+4rmvVkwtrrOBWzDyqzJdjso3e6U=; b=RbUyEyY1fHUDoQmTvWFu2GPqgKmdwgRXZ+75f5zQe+uRzTm+GEQWEMQbvO/KNb78f1 ARk1LDWDcO/Jl7nIyumJaghADOv0G9W1OWNeXH0k1oxy7jwClTMY+FX3t7pQ7JQ8mGvt bomHqZ6FkDPyuk1yajy3VwomGSNTD42BFx9SXFyN76OTjuxDgg6djWMAFZ4Q/3uH/h04 BxNTjLQZuorbPgp5l37PHbwzIw1ZWqE5o2pBtK6sr0byuTmlA40JZXiK0Q/2biNwcJEQ f0W3pqL6kBuXDre8FL8U5/unjtKqDrv9KbnhUfAdfGm6pYx4OmDK6eJwSsoZV65sp1VV FusQ== X-Gm-Message-State: AC+VfDxQ3YJzd3UpQc5HMLjEtj9NQkYP32bFaoer6DhFsPXLUuxEtRvh pnyfshFgTakvS5eTXp4Qh1R20gjJIQD5bS61l2o= X-Google-Smtp-Source: ACHHUZ4Uhkn+55+sDIphN2TJ7Qj47eTfyHA9XZFS6tIXZzs2u6gGFdY4jdH1t5f6OuAMZi/w9dDBfA== X-Received: by 2002:a17:907:3f82:b0:97a:e496:c121 with SMTP id hr2-20020a1709073f8200b0097ae496c121mr1174511ejc.69.1686321108322; Fri, 09 Jun 2023 07:31:48 -0700 (PDT) Received: from kaylee.. (92-68-83-157.biz.kpn.net. [92.68.83.157]) by smtp.gmail.com with ESMTPSA id f10-20020a170906824a00b00971433ed5fesm1348023ejx.184.2023.06.09.07.31.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Jun 2023 07:31:47 -0700 (PDT) X-Google-Original-From: Cedric Nugteren To: libcamera-devel@lists.libcamera.org Date: Fri, 9 Jun 2023 16:31:42 +0200 Message-Id: <20230609143142.77049-1-web@cedricnugteren.nl> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3] gstreamer: Add enable_auto_focus option to the GStreamer plugin 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: Cedric Nugteren via libcamera-devel From: Cedric Nugteren Reply-To: Cedric Nugteren Cc: Cedric Nugteren Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Cameras such as the PiCam 3 support auto-focus, but the GStreamer plugin for libcamera does not enable auto-focus. With this patch auto-focus can be enabled for cameras that support it. By default it is disabled, which means default behaviour remains unchanged. For cameras that do not support auto-focus, an error message shows up if auto-focus is enabled. This was tested on cameras that do not support auto-focus (e.g. PiCam2) and was tested on a camera that does support auto-focus (PiCam3) by setting it to AfModeContinous, observing auto-focus, and by setting it to AfModeManual or by not setting the option, both resulting in auto-focus being disabled. Bug: https://bugs.libcamera.org/show_bug.cgi?id=188. Signed-off-by: Cedric Nugteren Reviewed-by: Maarten Lankhorst Reviewed-by: Kieran Bingham Reviewed-by: Umang Jain Tested-by: Umang Jain --- Changes since v1: - Now re-using the GParamSpec variables instead of re-creating. - Use bool instead of gboolean for enable_auto_focus. - Remove changes from the reconfigure_element functions. Changes since v2: - Fix a typo in the commit message (remove 'it'). - Fix the link to the actual bug. - Apply the style suggestions of utils/checkstyle.py. - Start the commit message with 'gstreamer:'. - Change the boolean to a 3-option AfMode enum and change variable names and strings accordingly. --- src/gstreamer/gstlibcameraprovider.cpp | 14 ++++++++++++ src/gstreamer/gstlibcamerasrc.cpp | 30 ++++++++++++++++++++++++- src/gstreamer/gstlibcamerasrc.h | 31 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp index 6eb0a0eb..aece3506 100644 --- a/src/gstreamer/gstlibcameraprovider.cpp +++ b/src/gstreamer/gstlibcameraprovider.cpp @@ -31,6 +31,7 @@ GST_DEBUG_CATEGORY_STATIC(provider_debug); enum { PROP_DEVICE_NAME = 1, + PROP_AUTO_FOCUS_MODE = 2, }; #define GST_TYPE_LIBCAMERA_DEVICE gst_libcamera_device_get_type() @@ -40,6 +41,7 @@ G_DECLARE_FINAL_TYPE(GstLibcameraDevice, gst_libcamera_device, struct _GstLibcameraDevice { GstDevice parent; gchar *name; + int auto_focus_mode = libcamera::controls::AfModeManual; }; G_DEFINE_TYPE(GstLibcameraDevice, gst_libcamera_device, GST_TYPE_DEVICE) @@ -56,6 +58,7 @@ gst_libcamera_device_create_element(GstDevice *device, const gchar *name) g_assert(source); g_object_set(source, "camera-name", GST_LIBCAMERA_DEVICE(device)->name, nullptr); + g_object_set(source, "auto-focus-mode", GST_LIBCAMERA_DEVICE(device)->auto_focus_mode, nullptr); return source; } @@ -82,6 +85,9 @@ gst_libcamera_device_set_property(GObject *object, guint prop_id, case PROP_DEVICE_NAME: device->name = g_value_dup_string(value); break; + case PROP_AUTO_FOCUS_MODE: + device->auto_focus_mode = static_cast(g_value_get_enum(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -121,6 +127,14 @@ gst_libcamera_device_class_init(GstLibcameraDeviceClass *klass) (GParamFlags)(G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property(object_class, PROP_DEVICE_NAME, pspec); + pspec = g_param_spec_enum("auto-focus-mode", + "Set auto-focus mode", + "Available options: AfModeManual, " + "AfModeAuto or AfModeContinuous.", + gst_libcamera_auto_focus_get_type(), + static_cast(libcamera::controls::AfModeManual), + G_PARAM_WRITABLE); + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, pspec); } static GstDevice * diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index a10cbd4f..cfb8f70c 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { GstTask *task; gchar *camera_name; + int auto_focus_mode = libcamera::controls::AfModeManual; GstLibcameraSrcState *state; GstLibcameraAllocator *allocator; @@ -154,7 +155,8 @@ struct _GstLibcameraSrc { enum { PROP_0, - PROP_CAMERA_NAME + PROP_CAMERA_NAME, + PROP_AUTO_FOCUS_MODE, }; G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT, @@ -577,6 +579,18 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, gst_flow_combiner_add_pad(self->flow_combiner, srcpad); } + if (self->auto_focus_mode != libcamera::controls::AfModeManual) { + const ControlInfoMap &infoMap = state->cam_->controls(); + if (infoMap.find(&controls::AfMode) != infoMap.end()) { + state->initControls_.set(controls::AfMode, self->auto_focus_mode); + } else { + GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, + ("Failed to enable auto focus"), + ("AfMode not supported by this camera, " + "please retry with 'auto-focus-mode=AfModeManual'")); + } + } + ret = state->cam_->start(&state->initControls_); if (ret) { GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, @@ -659,6 +673,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, g_free(self->camera_name); self->camera_name = g_value_dup_string(value); break; + case PROP_AUTO_FOCUS_MODE: + self->auto_focus_mode = static_cast(g_value_get_enum(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -676,6 +693,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value, case PROP_CAMERA_NAME: g_value_set_string(value, self->camera_name); break; + case PROP_AUTO_FOCUS_MODE: + g_value_set_enum(value, static_cast(self->auto_focus_mode)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -844,4 +864,12 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); + spec = g_param_spec_enum("auto-focus-mode", + "Set auto-focus mode", + "Available options: AfModeManual, " + "AfModeAuto or AfModeContinuous.", + gst_libcamera_auto_focus_get_type(), + static_cast(libcamera::controls::AfModeManual), + G_PARAM_WRITABLE); + g_object_class_install_property(object_class, PROP_AUTO_FOCUS_MODE, spec); } diff --git a/src/gstreamer/gstlibcamerasrc.h b/src/gstreamer/gstlibcamerasrc.h index fdea2f10..0a88ba02 100644 --- a/src/gstreamer/gstlibcamerasrc.h +++ b/src/gstreamer/gstlibcamerasrc.h @@ -8,6 +8,8 @@ #pragma once +#include + #include G_BEGIN_DECLS @@ -17,3 +19,32 @@ G_DECLARE_FINAL_TYPE(GstLibcameraSrc, gst_libcamera_src, GST_LIBCAMERA, SRC, GstElement) G_END_DECLS + +inline GType +gst_libcamera_auto_focus_get_type() +{ + static GType type = 0; + static const GEnumValue values[] = { + { + static_cast(libcamera::controls::AfModeManual), + "AfModeManual", + "manual-focus", + }, + { + static_cast(libcamera::controls::AfModeAuto), + "AfModeAuto", + "automatic-auto-focus", + }, + { + static_cast(libcamera::controls::AfModeContinuous), + "AfModeContinuous", + "continuous-auto-focus", + }, + { 0, NULL, NULL } + }; + + if (!type) + type = g_enum_register_static("GstLibcameraAutoFocus", values); + + return type; +}