Skip to content

Commit

Permalink
pipeline: raspberrypi: Read config parameters from a file
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: David Plowman <[email protected]>
Signed-off-by: Kieran Bingham <[email protected]>
  • Loading branch information
naushir authored and kbingham committed Jan 31, 2023
1 parent 8b267c2 commit 8c53b24
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Documentation/environment_variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ LIBCAMERA_IPA_MODULE_PATH

Example value: ``${HOME}/.libcamera/lib:/opt/libcamera/vendor/lib``

LIBCAMERA_RPI_CONFIG_FILE
Define a custom configuration file to use in the Raspberry Pi pipeline handler.

Example value: ``/usr/local/share/libcamera/pipeline/raspberrypi/minimal_mem.yaml``

Further details
---------------

Expand Down
32 changes: 32 additions & 0 deletions src/libcamera/pipeline/raspberrypi/data/example.yaml
Original file line number Diff line number Diff line change
@@ -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
}
}
8 changes: 8 additions & 0 deletions src/libcamera/pipeline/raspberrypi/data/meson.build
Original file line number Diff line number Diff line change
@@ -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')
2 changes: 2 additions & 0 deletions src/libcamera/pipeline/raspberrypi/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ libcamera_sources += files([
'raspberrypi.cpp',
'rpi_stream.cpp',
])

subdir('data')
45 changes: 45 additions & 0 deletions src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 8c53b24

Please sign in to comment.