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:
committed by
Kieran Bingham
parent
8b267c24a0
commit
8c53b2498b
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user