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);
lass="hl opt">, int interval); /* * This hook is OPTIONAL. * * It is non NULL If the framebuffer driver supports "update-on-demand" * and the given rectangle is the area of the screen that gets * updated during (*post)(). * * This is useful on devices that are able to DMA only a portion of * the screen to the display panel, upon demand -- as opposed to * constantly refreshing the panel 60 times per second, for instance. * * Only the area defined by this rectangle is guaranteed to be valid, that * is, the driver is not allowed to post anything outside of this * rectangle. * * The rectangle evaluated during (*post)() and specifies which area * of the buffer passed in (*post)() shall to be posted. * * return -EINVAL if width or height <=0, or if left or top < 0 */ int (*setUpdateRect)(struct framebuffer_device_t* window, int left, int top, int width, int height); /* * Post <buffer> to the display (display it on the screen) * The buffer must have been allocated with the * GRALLOC_USAGE_HW_FB usage flag. * buffer must be the same width and height as the display and must NOT * be locked. * * The buffer is shown during the next VSYNC. * * If the same buffer is posted again (possibly after some other buffer), * post() will block until the the first post is completed. * * Internally, post() is expected to lock the buffer so that a * subsequent call to gralloc_module_t::(*lock)() with USAGE_RENDER or * USAGE_*_WRITE will block until it is safe; that is typically once this * buffer is shown and another buffer has been posted. * * Returns 0 on success or -errno on error. */ int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer); /* * The (*compositionComplete)() method must be called after the * compositor has finished issuing GL commands for client buffers. */ int (*compositionComplete)(struct framebuffer_device_t* dev); /* * This hook is OPTIONAL. * * If non NULL it will be caused by SurfaceFlinger on dumpsys */ void (*dump)(struct framebuffer_device_t* dev, char *buff, int buff_len); /* * (*enableScreen)() is used to either blank (enable=0) or * unblank (enable=1) the screen this framebuffer is attached to. * * Returns 0 on success or -errno on error. */ int (*enableScreen)(struct framebuffer_device_t* dev, int enable); void* reserved_proc[6]; } framebuffer_device_t; /** convenience API for opening and closing a supported device */ static inline int framebuffer_open(const struct hw_module_t* module, struct framebuffer_device_t** device) { return module->methods->open(module, GRALLOC_HARDWARE_FB0, TO_HW_DEVICE_T_OPEN(device)); } static inline int framebuffer_close(struct framebuffer_device_t* device) { return device->common.close(&device->common); } __END_DECLS #endif // ANDROID_FB_INTERFACE_H