summaryrefslogtreecommitdiff
path: root/src/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa')
-rw-r--r--src/ipa/ipu3/ipu3.cpp3
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp3
2 files changed, 3 insertions, 3 deletions
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 38992a98..c903f751 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -6,7 +6,6 @@
*/
#include <stdint.h>
-#include <sys/mman.h>
#include <linux/intel-ipu3.h>
#include <linux/v4l2-controls.h>
@@ -211,7 +210,7 @@ void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)
for (const IPABuffer &buffer : buffers) {
const FrameBuffer fb(buffer.planes);
buffers_.emplace(buffer.id,
- MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));
+ MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));
}
}
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index e74bd8c7..7215b205 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -411,7 +411,8 @@ void IPARPi::mapBuffers(const std::vector<IPABuffer> &buffers)
{
for (const IPABuffer &buffer : buffers) {
const FrameBuffer fb(buffer.planes);
- buffers_.emplace(buffer.id, MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));
+ buffers_.emplace(buffer.id,
+ MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));
}
}
151'>151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2019, Google Inc.
# Copyright (C) 2024, Jaslo Ziska
#
# Authors:
# Laurent Pinchart <laurent.pinchart@ideasonboard.com>
# Jaslo Ziska <jaslo@ziska.de>
#
# Generate gstreamer control properties from YAML

import argparse
import jinja2
import re
import sys
import yaml

from controls import Control


exposed_controls = [
    'AeEnable', 'AeMeteringMode', 'AeConstraintMode', 'AeExposureMode',
    'ExposureValue', 'ExposureTime', 'AnalogueGain', 'AeFlickerPeriod',
    'Brightness', 'Contrast', 'AwbEnable', 'AwbMode', 'ColourGains',
    'Saturation', 'Sharpness', 'ColourCorrectionMatrix', 'ScalerCrop',
    'DigitalGain', 'AfMode', 'AfRange', 'AfSpeed', 'AfMetering', 'AfWindows',
    'LensPosition', 'Gamma',
]


def find_common_prefix(strings):
    prefix = strings[0]

    for string in strings[1:]:
        while string[:len(prefix)] != prefix and prefix:
            prefix = prefix[:len(prefix) - 1]
        if not prefix:
            break

    return prefix


def format_description(description):
    # Substitute doxygen keywords \sa (see also) and \todo
    description = re.sub(r'\\sa((?: \w+)+)',
                         lambda match: 'See also: ' + ', '.join(
                             map(kebab_case, match.group(1).strip().split(' '))
                         ) + '.', description)
    description = re.sub(r'\\todo', 'Todo:', description)

    description = description.strip().split('\n')
    return '\n'.join([
        '"' + line.replace('\\', r'\\').replace('"', r'\"') + ' "' for line in description if line
    ]).rstrip()


# Custom filter to allow indenting by a string prior to Jinja version 3.0
#
# This function can be removed and the calls to indent_str() replaced by the
# built-in indent() filter when dropping Jinja versions older than 3.0
def indent_str(s, indention):
    s += '\n'

    lines = s.splitlines()
    rv = lines.pop(0)

    if lines:
        rv += '\n' + '\n'.join(
            indention + line if line else line for line in lines
        )

    return rv


def snake_case(s):
    return ''.join([
        c.isupper() and ('_' + c.lower()) or c for c in s
    ]).strip('_')


def kebab_case(s):
    return snake_case(s).replace('_', '-')


def extend_control(ctrl):
    if ctrl.vendor != 'libcamera':
        ctrl.namespace = f'{ctrl.vendor}::'
        ctrl.vendor_prefix = f'{ctrl.vendor}-'
    else:
        ctrl.namespace = ''
        ctrl.vendor_prefix = ''

    ctrl.is_array = ctrl.size is not None

    if ctrl.is_enum:
        # Remove common prefix from enum variant names
        prefix = find_common_prefix([enum.name for enum in ctrl.enum_values])
        for enum in ctrl.enum_values:
            enum.gst_name = kebab_case(enum.name.removeprefix(prefix))

        ctrl.gtype = 'enum'
        ctrl.default = '0'
    elif ctrl.element_type == 'bool':
        ctrl.gtype = 'boolean'
        ctrl.default = 'false'
    elif ctrl.element_type == 'float':
        ctrl.gtype = 'float'
        ctrl.default = '0'
        ctrl.min = '-G_MAXFLOAT'
        ctrl.max = 'G_MAXFLOAT'
    elif ctrl.element_type == 'int32_t':
        ctrl.gtype = 'int'
        ctrl.default = '0'
        ctrl.min = 'G_MININT'
        ctrl.max = 'G_MAXINT'
    elif ctrl.element_type == 'int64_t':
        ctrl.gtype = 'int64'
        ctrl.default = '0'
        ctrl.min = 'G_MININT64'
        ctrl.max = 'G_MAXINT64'
    elif ctrl.element_type == 'uint8_t':
        ctrl.gtype = 'uchar'
        ctrl.default = '0'
        ctrl.min = '0'
        ctrl.max = 'G_MAXUINT8'
    elif ctrl.element_type == 'Rectangle':
        ctrl.is_rectangle = True
        ctrl.default = '0'
        ctrl.min = '0'
        ctrl.max = 'G_MAXINT'
    else:
        raise RuntimeError(f'The type `{ctrl.element_type}` is unknown')

    return ctrl


def main(argv):
    # Parse command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--output', '-o', metavar='file', type=str,
                        help='Output file name. Defaults to standard output if not specified.')
    parser.add_argument('--template', '-t', dest='template', type=str, required=True,
                        help='Template file name.')
    parser.add_argument('input', type=str, nargs='+',
                        help='Input file name.')

    args = parser.parse_args(argv[1:])

    controls = {}
    for input in args.input:
        data = yaml.safe_load(open(input, 'rb').read())

        vendor = data['vendor']
        ctrls = controls.setdefault(vendor, [])

        for ctrl in data['controls']:
            ctrl = Control(*ctrl.popitem(), vendor, mode='controls')

            if ctrl.name in exposed_controls:
                ctrls.append(extend_control(ctrl))

    data = {'controls': list(controls.items())}

    env = jinja2.Environment()
    env.filters['format_description'] = format_description
    env.filters['indent_str'] = indent_str
    env.filters['snake_case'] = snake_case
    env.filters['kebab_case'] = kebab_case
    template = env.from_string(open(args.template, 'r', encoding='utf-8').read())
    string = template.render(data)

    if args.output:
        with open(args.output, 'w', encoding='utf-8') as output:
            output.write(string)
    else:
        sys.stdout.write(string)

    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))