pipeline: raspberrypi: Read config parameters from a file

Add the ability to read the platform configuration parameters from a
config file provided by the user through the LIBCAMERA_RPI_CONFIG_FILE
environment variable. Use the PipelineHandler::configurationFile()
helper to determine the full path of the file.

Provide an example configuration file named example.yaml. Currently two
parameters are available through the json file:

"min_unicam_buffers" The minimum number of internal Unicam buffers to
allocate.

"min_total_unicam_buffers" The minimum number of internal + external
Unicam buffers that must be allocated.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Naushir Patuck
2023-01-27 15:43:14 +00:00
committed by Kieran Bingham
parent 8b267c24a0
commit 8c53b2498b
5 changed files with 92 additions and 0 deletions
@@ -0,0 +1,32 @@
{
"version": 1.0,
"target": "bcm2835",
"pipeline_handler":
{
# The minimum number of internal buffers to be allocated for
# Unicam. This value must be greater than 0, but less than or
# equal to min_total_unicam_buffers.
#
# A larger number of internal buffers can reduce the occurrence
# of frame drops during high CPU loads, but might also cause
# additional latency in the system.
#
# Note that the pipeline handler might override this value and
# not allocate any internal buffers if it knows they will never
# be used. For example if the RAW stream is marked as mandatory
# and there are no dropped frames signalled for algorithm
# convergence.
#
# "min_unicam_buffers": 2,
# The minimum total (internal + external) buffer count used for
# Unicam. The number of internal buffers allocated for Unicam is
# given by:
#
# internal buffer count = max(min_unicam_buffers,
# min_total_unicam_buffers - external buffer count)
#
# "min_total_unicam_buffers": 4
}
}
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: CC0-1.0
conf_files = files([
'example.yaml',
])
install_data(conf_files,
install_dir : pipeline_data_dir / 'raspberrypi')
@@ -6,3 +6,5 @@ libcamera_sources += files([
'raspberrypi.cpp',
'rpi_stream.cpp',
])
subdir('data')
@@ -14,6 +14,7 @@
#include <unordered_set>
#include <utility>
#include <libcamera/base/file.h>
#include <libcamera/base/shared_fd.h>
#include <libcamera/base/utils.h>
@@ -40,6 +41,7 @@
#include "libcamera/internal/media_device.h"
#include "libcamera/internal/pipeline_handler.h"
#include "libcamera/internal/v4l2_videodevice.h"
#include "libcamera/internal/yaml_parser.h"
#include "delayed_controls.h"
#include "dma_heaps.h"
@@ -1214,6 +1216,7 @@ int PipelineHandlerRPi::queueRequestDevice(Camera *camera, Request *request)
*/
stream->setExternalBuffer(buffer);
}
/*
* If no buffer is provided by the request for this stream, we
* queue a nullptr to the stream to signify that it must use an
@@ -1718,6 +1721,48 @@ int RPiCameraData::loadPipelineConfiguration()
.minTotalUnicamBuffers = 4,
};
char const *configFromEnv = utils::secure_getenv("LIBCAMERA_RPI_CONFIG_FILE");
if (!configFromEnv || *configFromEnv == '\0')
return 0;
std::string filename = std::string(configFromEnv);
File file(filename);
if (!file.open(File::OpenModeFlag::ReadOnly)) {
LOG(RPI, Error) << "Failed to open configuration file '" << filename << "'";
return -EIO;
}
LOG(RPI, Info) << "Using configuration file '" << filename << "'";
std::unique_ptr<YamlObject> root = YamlParser::parse(file);
if (!root) {
LOG(RPI, Warning) << "Failed to parse configuration file, using defaults";
return 0;
}
std::optional<double> ver = (*root)["version"].get<double>();
if (!ver || *ver != 1.0) {
LOG(RPI, Error) << "Unexpected configuration file version reported";
return -EINVAL;
}
const YamlObject &phConfig = (*root)["pipeline_handler"];
config_.minUnicamBuffers =
phConfig["min_unicam_buffers"].get<unsigned int>(config_.minUnicamBuffers);
config_.minTotalUnicamBuffers =
phConfig["min_total_unicam_buffers"].get<unsigned int>(config_.minTotalUnicamBuffers);
if (config_.minTotalUnicamBuffers < config_.minUnicamBuffers) {
LOG(RPI, Error) << "Invalid configuration: min_total_unicam_buffers must be >= min_unicam_buffers";
return -EINVAL;
}
if (config_.minTotalUnicamBuffers < 1) {
LOG(RPI, Error) << "Invalid configuration: min_total_unicam_buffers must be >= 1";
return -EINVAL;
}
return 0;
}