summaryrefslogtreecommitdiff
path: root/src/ipa/raspberrypi/controller/rpi/sdn.cpp
blob: 9384550983e7ca8fb2edf94adafd00ee5b0aa724 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
74
75
/* SPDX-License-Identifier: BSD-2-Clause */
/*
 * Copyright (C) 2019-2021, Raspberry Pi (Trading) Limited
 *
 * sdn.cpp - SDN (spatial denoise) control algorithm
 */

#include <libcamera/base/log.h>

#include "../denoise_status.h"
#include "../noise_status.h"

#include "sdn.hpp"

using namespace RPiController;
using namespace libcamera;

LOG_DEFINE_CATEGORY(RPiSdn)

// Calculate settings for the spatial denoise block using the noise profile in
// the image metadata.

#define NAME "rpi.sdn"

Sdn::Sdn(Controller *controller)
	: DenoiseAlgorithm(controller), mode_(DenoiseMode::ColourOff)
{
}

char const *Sdn::Name() const
{
	return NAME;
}

void Sdn::Read(boost::property_tree::ptree const &params)
{
	deviation_ = params.get<double>("deviation", 3.2);
	strength_ = params.get<double>("strength", 0.75);
}

void Sdn::Initialise() {}

void Sdn::Prepare(Metadata *image_metadata)
{
	struct NoiseStatus noise_status = {};
	noise_status.noise_slope = 3.0; // in case no metadata
	if (image_metadata->Get("noise.status", noise_status) != 0)
		LOG(RPiSdn, Warning) << "no noise profile found";
	LOG(RPiSdn, Debug)
		<< "Noise profile: constant " << noise_status.noise_constant
		<< " slope " << noise_status.noise_slope;
	struct DenoiseStatus status;
	status.noise_constant = noise_status.noise_constant * deviation_;
	status.noise_slope = noise_status.noise_slope * deviation_;
	status.strength = strength_;
	status.mode = static_cast<std::underlying_type_t<DenoiseMode>>(mode_);
	image_metadata->Set("denoise.status", status);
	LOG(RPiSdn, Debug)
		<< "programmed constant " << status.noise_constant
		<< " slope " << status.noise_slope
		<< " strength " << status.strength;
}

void Sdn::SetMode(DenoiseMode mode)
{
	// We only distinguish between off and all other modes.
	mode_ = mode;
}

// Register algorithm with the system.
static Algorithm *Create(Controller *controller)
{
	return (Algorithm *)new Sdn(controller);
}
static RegisterAlgorithm reg(NAME, &Create);
s="hl str">brief ' + description[0] return '\n'.join([(line and ' * ' or ' *') + line for line in description]) def generate_cpp(controls): enum_doc_start_template = string.Template('''/** * \\enum ${name}Enum * \\brief Supported ${name} values''') enum_doc_value_template = string.Template(''' * \\var ${value} ${description}''') doc_template = string.Template('''/** * \\var ${name} ${description} */''') def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, "${name}");') enum_values_doc = string.Template('''/** * \\var ${name}Values * \\brief List of all $name supported values */''') enum_values_start = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values = {''') enum_values_values = string.Template('''\tstatic_cast<int32_t>(${name}),''') ctrls_doc = [] ctrls_def = [] draft_ctrls_doc = [] draft_ctrls_def = [] ctrls_map = [] for ctrl in controls: name, ctrl = ctrl.popitem() id_name = snake_case(name).upper() ctrl_type = ctrl['type'] if ctrl_type == 'string': ctrl_type = 'std::string' elif ctrl.get('size'): ctrl_type = 'Span<const %s>' % ctrl_type info = { 'name': name, 'type': ctrl_type, 'description': format_description(ctrl['description']), 'id_name': id_name, } target_doc = ctrls_doc target_def = ctrls_def if ctrl.get('draft'): target_doc = draft_ctrls_doc target_def = draft_ctrls_def enum = ctrl.get('enum') if enum: enum_doc = [] enum_doc.append(enum_doc_start_template.substitute(info)) num_entries = 0 for entry in enum: value_info = { 'name': name, 'value': entry['name'], 'description': format_description(entry['description']), } enum_doc.append(enum_doc_value_template.substitute(value_info)) num_entries += 1 enum_doc = '\n *\n'.join(enum_doc) enum_doc += '\n */' target_doc.append(enum_doc) values_info = { 'name': info['name'], 'size': num_entries, } target_doc.append(enum_values_doc.substitute(values_info)) target_def.append(enum_values_start.substitute(values_info)) for entry in enum: value_info = { 'name': entry['name'] } target_def.append(enum_values_values.substitute(value_info)) target_def.append("};") target_doc.append(doc_template.substitute(info)) target_def.append(def_template.substitute(info)) if ctrl.get('draft'): name = 'draft::' + name ctrls_map.append('\t{ ' + id_name + ', &' + name + ' },') return { 'controls_doc': '\n\n'.join(ctrls_doc), 'controls_def': '\n'.join(ctrls_def), 'draft_controls_doc': '\n\n'.join(draft_ctrls_doc), 'draft_controls_def': '\n\n'.join(draft_ctrls_def), 'controls_map': '\n'.join(ctrls_map), } def generate_h(controls): enum_template_start = string.Template('''enum ${name}Enum {''') enum_value_template = string.Template('''\t${name} = ${value},''') enum_values_template = string.Template('''extern const std::array<const ControlValue, ${size}> ${name}Values;''') template = string.Template('''extern const Control<${type}> ${name};''') ctrls = [] draft_ctrls = [] ids = [] id_value = 1 for ctrl in controls: name, ctrl = ctrl.popitem() id_name = snake_case(name).upper() ids.append('\t' + id_name + ' = ' + str(id_value) + ',') ctrl_type = ctrl['type'] if ctrl_type == 'string': ctrl_type = 'std::string' elif ctrl.get('size'): ctrl_type = 'Span<const %s>' % ctrl_type info = { 'name': name, 'type': ctrl_type, } target_ctrls = ctrls if ctrl.get('draft'): target_ctrls = draft_ctrls enum = ctrl.get('enum') if enum: target_ctrls.append(enum_template_start.substitute(info)) num_entries = 0 for entry in enum: value_info = { 'name': entry['name'], 'value': entry['value'], } target_ctrls.append(enum_value_template.substitute(value_info)) num_entries += 1 target_ctrls.append("};") values_info = { 'name': info['name'], 'size': num_entries, } target_ctrls.append(enum_values_template.substitute(values_info)) target_ctrls.append(template.substitute(info)) id_value += 1 return {