From patchwork Fri Nov 10 10:59:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19195 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 AAD85BDE6B for ; Fri, 10 Nov 2023 11:00:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8A27A629AF; Fri, 10 Nov 2023 12:00:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1699614002; bh=FNFGzC5HF+ifNcYw5R4MlHlpFomJsHZkSQWiEXKPNHs=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=dbALBVYY7o6X5wP8U78nBvgXJ5C6vfKbgP3yS2TfPm3pMWnmBGXWeebqJNYZD4EQc n+XDrfccizGcOft4QqO/1LwLOc/JrC1NcQH8ZdQGKQmZV4ZTo4bgQL7SaJbz92wrUC 0CTu6jYH3ynIPYKs37W9xXtG74c6z3IB+vc36o/ZuVg1YZXIZCMEnlcKbBMFF7nkbF lHJc6vZEp1cBF1MH2LCPHQ9cJQKpPrWHrpX+eBHEBym79CVuyfWT6lWyanXthLHjhj Tbhgqmt+YXEspNmLFMjdUgYXiuNT2H8wnF1g2YdE7UNV8mUfrB8caGVoslXx4ZyTww 8WKCNFw9KvpMg== Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 26FFB629C0 for ; Fri, 10 Nov 2023 11:59:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="k3ZCJqV8"; dkim-atps=neutral Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-408425c7c10so14343805e9.0 for ; Fri, 10 Nov 2023 02:59:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1699613998; x=1700218798; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7zG4YADsqfXxky8HV1UlKl3gSBl6yLhKvKdAQ0eg5Pw=; b=k3ZCJqV8fxEBn2f2uoU5LKnnra2Vcy8Mbg0Kq9LjrnybHdeDiQPwvc1vB+vpR0r5le uVHhpAERPrReFKwWuOEI51vseRjo22s1MhY7iyurjarswRU8lnbKmg+KT2ZR0Nn5bX4m xY4mIKN9Rq0d1N/IXhy4UnZ/zpKHDyHrsiXC4nLyUZ1luue+/4aeE64yt4KlT2B5OT7d /TPgFe36t23M5SUaFMoyuEAGfCtHWHK1+rBUx9/rxm3wGubxOSLS/Tdz3heUzbBtDMLN sckM78wWhJm+Gi7cr0LXgOMMrDApgLYXWmJeK5zHfDi2VPBkbuqTaAlt1WGGAUdI6ilp /fbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699613998; x=1700218798; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7zG4YADsqfXxky8HV1UlKl3gSBl6yLhKvKdAQ0eg5Pw=; b=Z3V57MDC8F/t2p2MFTHzafp5Cl+tv7a/l6cfc/FJ16a7fg9g/c+5E+SBgk27xWv2Qm 8SsXl9y7PVYm+T8znJUkuUZ/sC1baNOs7EJTXM3vt9OpSpLfHnDq9qjGbZTwYFhIIG+s MEL2fT3gKdL8MErKCvOtvMbxxWT3hYiYdsTOyI12bPyl0rOvTa6Fuv3z7VEdVMktwogV 5lCHrxqLMo1cZKzGn8XfAiKJxrHYElvRtDyrIQinPYjk+Ysrjnx4F69ZJIQuokOPRnnL 1vFJ9cXLaXPOWrCsEHBkAMp9R/+4x7kBos8ztXr/bWtPXIhzKWdHB59Ei9Vv4VxN7an/ wmBg== X-Gm-Message-State: AOJu0YwLtNLgjRmcT7xOko4qIoXVFY656k0Za8qv3Tgb2xgdnk0wknZt lTGFuiV6ZFyYase5qhTczcDcuWjkccyKWJe8s1sdTg== X-Google-Smtp-Source: AGHT+IF6x4PiKwj7/Lc97QqZzcw4eZ2WuYIzwRUFBNtysJsIMDgMNOIJfK0zIAOc8q5ZuSL/zRiG3A== X-Received: by 2002:a05:600c:4ed0:b0:40a:43d3:2348 with SMTP id g16-20020a05600c4ed000b0040a43d32348mr1630236wmq.35.1699613998115; Fri, 10 Nov 2023 02:59:58 -0800 (PST) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id r15-20020a05600c35cf00b0040531f5c51asm4883156wmq.5.2023.11.10.02.59.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Nov 2023 02:59:57 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Fri, 10 Nov 2023 10:59:59 +0000 Message-Id: <20231110110002.21381-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231110110002.21381-1-naush@raspberrypi.com> References: <20231110110002.21381-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 2/5] controls: build: Allow separate vendor control YAML files 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add support for using separate YAML files for vendor specific controls. This simplifies management of vendor control definitions and avoids possible merge conflicts when changing the control_ids.yaml file for core and draft controls. The mapping of vendor/pipeline handler to control file is done through the vendor_controls_mapping variable in include/libcamera/meson.build. The command line argument handling for the gen-py-controls.py and gen-controls.py have now changed to allow multiple input files to be provided. This means that all positional arguments have been replaced by non-positional equivalents. Add a new control_ids_rpi.yaml file to hold the Raspberry Pi specific vendor controls. This contains a single control PispConfigDumpFile that will be used in the Pi 5 pipeline handler as a trigger to dump the Backend configuration as a JSON file. Signed-off-by: Naushir Patuck --- include/libcamera/meson.build | 48 ++++++++++++++++++++++++++--- meson.build | 2 ++ src/libcamera/control_ids_rpi.yaml | 17 ++++++++++ src/libcamera/meson.build | 19 ++++++++++-- src/py/libcamera/gen-py-controls.py | 12 +++++--- src/py/libcamera/meson.build | 26 ++++++++++------ utils/gen-controls.py | 15 +++++---- 7 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 src/libcamera/control_ids_rpi.yaml diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index f736cca07228..f8af51174f08 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -32,21 +32,61 @@ install_headers(libcamera_public_headers, libcamera_headers_install_dir = get_option('includedir') / libcamera_include_dir -# control_ids.h and property_ids.h +# control_ids.h and property_ids.h and associated modes control_source_files = { 'control_ids': 'controls', 'property_ids': 'properties', } +vendor_mappings = { + # Mapping of vendor (pipeline handler) specific controls files + 'controls': + { + 'rpi/pisp': 'control_ids_rpi.yaml', + 'rpi/vc4': 'control_ids_rpi.yaml' + }, + # Mapping of vendor (pipeline handler) specific properties files + 'properties': + { + + } +} + control_headers = [] +vendor_ctrl_files = [] +vendor_prop_files = [] foreach header, mode : control_source_files - input_files = files('../../src/libcamera/' + header +'.yaml', header + '.h.in') + # Start by populating the vendor specific mappings into vendor_ctrl_files + # vendor_prop_files. These will be cached for later use. + vendor_files = [] + foreach pipeline, file : vendor_mappings[mode] + if pipeline not in pipelines + continue + endif + if file not in vendor_files + vendor_files += file + endif + endforeach + + if mode == 'controls' + vendor_ctrl_files = vendor_files + else + vendor_prop_files = vendor_files + endif + + input_files = files('../../src/libcamera/' + header +'.yaml') + + foreach file : vendor_files + input_files += files('../../src/libcamera/' + file) + endforeach + + template_file = files(header + '.h.in') control_headers += custom_target(header + '_h', input : input_files, output : header + '.h', - command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@', - '--mode', mode], + command : [gen_controls, '-o', '@OUTPUT@', '-i', '@INPUT@', + '--mode', mode, '-t', template_file], install : true, install_dir : libcamera_headers_install_dir) endforeach diff --git a/meson.build b/meson.build index e9a1c7e360ce..1423abf16c77 100644 --- a/meson.build +++ b/meson.build @@ -267,6 +267,8 @@ py_mod.find_installation('python3', modules : py_modules) summary({ 'Enabled pipelines': pipelines, 'Enabled IPA modules': enabled_ipa_names, + 'Vendor controls': vendor_ctrl_files, + 'Vendor properties': vendor_prop_files, 'Hotplug support': libudev.found(), 'Tracing support': tracing_enabled, 'Android support': android_enabled, diff --git a/src/libcamera/control_ids_rpi.yaml b/src/libcamera/control_ids_rpi.yaml new file mode 100644 index 000000000000..239904a008a8 --- /dev/null +++ b/src/libcamera/control_ids_rpi.yaml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Copyright (C) 2023, Raspberry Pi Ltd +# +%YAML 1.1 +--- +controls: + + - PispConfigDumpFile: + type: string + vendor: rpi + description: | + Triggers the Raspberry Pi PiSP pipeline handler to generate a JSON + formatted dump of the Backend configuration to the filename given by the + value of the control. + +... diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index e49bf850b355..8891052a3316 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -128,12 +128,25 @@ endif control_sources = [] foreach source, mode : control_source_files - input_files = files(source +'.yaml', source + '.cpp.in') + input_files = files(source +'.yaml') + + # Add the vendor specific files to the input. + if mode == 'controls' + vendor_files = vendor_ctrl_files + else + vendor_files = vendor_prop_files + endif + + foreach file : vendor_files + input_files += files(file) + endforeach + + template_file = files(source + '.cpp.in') control_sources += custom_target(source + '_cpp', input : input_files, output : source + '.cpp', - command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@', - '--mode', mode]) + command : [gen_controls, '-o', '@OUTPUT@', '-i', '@INPUT@', + '--mode', mode, '-t', template_file]) endforeach libcamera_sources += control_sources diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py index e89de674966a..a32ef09c2f48 100755 --- a/src/py/libcamera/gen-py-controls.py +++ b/src/py/libcamera/gen-py-controls.py @@ -91,9 +91,9 @@ def main(argv): parser = argparse.ArgumentParser() parser.add_argument('-o', dest='output', metavar='file', type=str, help='Output file name. Defaults to standard output if not specified.') - parser.add_argument('input', type=str, - help='Input file name.') - parser.add_argument('template', type=str, + parser.add_argument('-i', dest='inputs', type=str, nargs='+', required=True, + help='Input file name(s).') + parser.add_argument('-t', dest='template', type=str, required=True, help='Template file name.') parser.add_argument('--mode', type=str, required=True, help='Mode is either "controls" or "properties"') @@ -103,8 +103,10 @@ def main(argv): print(f'Invalid mode option "{args.mode}"', file=sys.stderr) return -1 - data = open(args.input, 'rb').read() - controls = yaml.safe_load(data)['controls'] + controls = [] + for input in args.inputs: + data = open(input, 'rb').read() + controls += yaml.safe_load(data)['controls'] data = generate_py(controls, args.mode) diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build index f58c7198ee9e..e4bc208b4ac1 100644 --- a/src/py/libcamera/meson.build +++ b/src/py/libcamera/meson.build @@ -28,29 +28,35 @@ pycamera_sources = files([ # Generate controls -gen_py_controls_input_files = files([ - '../../libcamera/control_ids.yaml', - 'py_controls_generated.cpp.in', -]) +gen_py_controls_input_files = files('../../libcamera/control_ids.yaml') + +foreach file : vendor_ctrl_files + gen_py_controls_input_files += files('../../libcamera/' + file) +endforeach gen_py_controls = files('gen-py-controls.py') +gen_py_controls_template = files('py_controls_generated.cpp.in') pycamera_sources += custom_target('py_gen_controls', input : gen_py_controls_input_files, output : ['py_controls_generated.cpp'], - command : [gen_py_controls, '--mode', 'controls', '-o', '@OUTPUT@', '@INPUT@']) + command : [gen_py_controls, '--mode', 'controls', '-o', '@OUTPUT@', '-i', '@INPUT@', + '-t', gen_py_controls_template]) # Generate properties -gen_py_property_enums_input_files = files([ - '../../libcamera/property_ids.yaml', - 'py_properties_generated.cpp.in', -]) +gen_py_property_enums_input_files = files('../../libcamera/property_ids.yaml') +gen_py_property_template = files('py_properties_generated.cpp.in') + +foreach file : vendor_prop_files + gen_py_property_enums_input_files += files('../../libcamera/' + file) +endforeach pycamera_sources += custom_target('py_gen_properties', input : gen_py_property_enums_input_files, output : ['py_properties_generated.cpp'], - command : [gen_py_controls, '--mode', 'properties', '-o', '@OUTPUT@', '@INPUT@']) + command : [gen_py_controls, '--mode', 'properties', '-o', '@OUTPUT@', '-i', '@INPUT@', + '-t', gen_py_property_template]) # Generate formats diff --git a/utils/gen-controls.py b/utils/gen-controls.py index dd55753e792c..3c490a562676 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -362,18 +362,21 @@ def main(argv): # Parse command line arguments parser = argparse.ArgumentParser() - parser.add_argument('-o', dest='output', metavar='file', type=str, + parser.add_argument('-o', dest='output', metavar='file', type=str, required=True, help='Output file name. Defaults to standard output if not specified.') - parser.add_argument('input', type=str, - help='Input file name.') - parser.add_argument('template', type=str, + parser.add_argument('-i', dest='inputs', type=str, nargs='+', required=True, + help='Input file name(s).') + parser.add_argument('-t', dest='template', type=str, required=True, help='Template file name.') parser.add_argument('--mode', type=str, required=True, choices=['controls', 'properties'], help='Mode of operation') args = parser.parse_args(argv[1:]) - data = open(args.input, 'rb').read() - controls = yaml.safe_load(data)['controls'] + controls = [] + for input in args.inputs: + data = open(input, 'rb').read() + controls = controls + yaml.safe_load(data)['controls'] + controls = [Control(*ctrl.popitem()) for ctrl in controls] if args.template.endswith('.cpp.in'):