#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2020, Google Inc. # # Author: Laurent Pinchart # # Generate formats definitions from YAML import argparse import re import string import sys import yaml class DRMFourCC(object): format_regex = re.compile(r"#define (DRM_FORMAT_[A-Z0-9_]+)[ \t]+fourcc_code\(('.', '.', '.', '.')\)") mod_vendor_regex = re.compile(r"#define DRM_FORMAT_MOD_VENDOR_([A-Z0-9_]+)[ \t]+([0-9a-fA-Fx]+)") mod_regex = re.compile(r"#define ([A-Za-z0-9_]+)[ \t]+fourcc_mod_code\(([A-Z0-9_]+), ([0-9a-fA-Fx]+)\)") def __init__(self, filename): self.formats = {} self.vendors = {} self.mods = {} for line in open(filename, 'rb').readlines(): line = line.decode('utf-8') match = DRMFourCC.format_regex.match(line) if match: format, fourcc = match.groups() self.formats[format] = fourcc continue match = DRMFourCC.mod_vendor_regex.match(line) if match: vendor, value = match.groups() self.vendors[vendor] = int(value, 0) continue match = DRMFourCC.mod_regex.match(line) if match: mod, vendor, value = match.groups() self.mods[mod] = (vendor, int(value, 0)) continue def fourcc(self, name): return self.formats[name] def mod(self, name): vendor, value = self.mods[name] return self.vendors[vendor], value def generate_h(formats, drm_fourcc): template = string.Template('constexpr PixelFormat ${name}{ __fourcc(${fourcc}), __mod(${mod}) };') fmts = [] for format in formats: name, format = format.popitem() fourcc = drm_fourcc.fourcc(format['fourcc']) if format.get('big-endian'): fourcc += '| DRM_FORMAT_BIG_ENDIAN' data = { 'name': name, 'fourcc': fourcc, 'mod': '0, 0', } mod = format.get('mod') if mod: data['mod'] = '%u, %u' % drm_fourcc.mod(mod) fmts.append(template.substitute(data)) return {'formats': '\n'.join(fmts)} def fill_template(template, data): template = open(template, 'rb').read() template = template.decode('utf-8') template = string.Template(template) return template.substitute(data) def main(argv): # Parse command line arguments 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, help='Template file name.') parser.add_argument('drm_fourcc', type=str, help='Path to drm_fourcc.h.') args = parser.parse_args(argv[1:]) data = open(args.input, 'rb').read() formats = yaml.safe_load(data)['formats'] drm_fourcc = DRMFourCC(args.drm_fourcc) data = generate_h(formats, drm_fourcc) data = fill_template(args.template, data) if args.output: output = open(args.output, 'wb') output.write(data.encode('utf-8')) output.close() else: sys.stdout.write(data) return 0 if __name__ == '__main__': sys.exit(main(sys.argv)) href='#n15'>15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2022, Ideas on Board Oy
 *
 * Capture session configuration script
 */

#pragma once

#include <map>
#include <memory>
#include <string>

#include <libcamera/camera.h>
#include <libcamera/controls.h>

#include <yaml.h>

class CaptureScript
{
public:
	CaptureScript(std::shared_ptr<libcamera::Camera> camera,
		      const std::string &fileName);

	bool valid() const { return valid_; }

	const libcamera::ControlList &frameControls(unsigned int frame);

private:
	struct EventDeleter {
		void operator()(yaml_event_t *event) const
		{
			yaml_event_delete(event);
			delete event;
		}
	};
	using EventPtr = std::unique_ptr<yaml_event_t, EventDeleter>;

	std::map<std::string, const libcamera::ControlId *> controls_;
	std::map<unsigned int, libcamera::ControlList> frameControls_;
	std::shared_ptr<libcamera::Camera> camera_;
	yaml_parser_t parser_;
	unsigned int loop_;
	bool valid_;

	EventPtr nextEvent(yaml_event_type_t expectedType = YAML_NO_EVENT);
	bool checkEvent(const EventPtr &event, yaml_event_type_t expectedType) const;
	static std::string eventScalarValue(const EventPtr &event);
	static std::string eventTypeName(yaml_event_type_t type);

	int parseScript(FILE *script);

	int parseProperties();
	int parseProperty();
	int parseFrames();
	int parseFrame(EventPtr event);
	int parseControl(EventPtr event, libcamera::ControlList &controls);

	libcamera::ControlValue parseScalarControl(const libcamera::ControlId *id,
						   const std::string repr);
	libcamera::ControlValue parseArrayControl(const libcamera::ControlId *id,
						  const std::vector<std::string> &repr);

	std::string parseScalar();
	libcamera::ControlValue parseRectangles();
	std::vector<std::vector<std::string>> parseArrays();
	std::vector<std::string> parseSingleArray();

	void unpackFailure(const libcamera::ControlId *id,
			   const std::string &repr);
	libcamera::ControlValue unpackControl(const libcamera::ControlId *id);
	libcamera::Rectangle unpackRectangle(const std::vector<std::string> &strVec);
};