[libcamera-devel] [PATCH v5 07/12] pipeline: raspberrypi: Read config parameters from a file
Kieran Bingham
kieran.bingham at ideasonboard.com
Fri Jan 20 12:05:26 CET 2023
Quoting Naushir Patuck via libcamera-devel (2023-01-18 08:59:48)
> 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.
I think this needs an addition to Documentation/environment_variables.rst
> 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 at raspberrypi.com>
> Reviewed-by: David Plowman <david.plowman at raspberrypi.com>
> ---
> .../pipeline/raspberrypi/data/example.yaml | 20 +++++++++
> .../pipeline/raspberrypi/data/meson.build | 8 ++++
> .../pipeline/raspberrypi/meson.build | 2 +
> .../pipeline/raspberrypi/raspberrypi.cpp | 45 +++++++++++++++++++
> 4 files changed, 75 insertions(+)
> create mode 100644 src/libcamera/pipeline/raspberrypi/data/example.yaml
> create mode 100644 src/libcamera/pipeline/raspberrypi/data/meson.build
>
> diff --git a/src/libcamera/pipeline/raspberrypi/data/example.yaml b/src/libcamera/pipeline/raspberrypi/data/example.yaml
> new file mode 100644
> index 000000000000..001a906af528
> --- /dev/null
> +++ b/src/libcamera/pipeline/raspberrypi/data/example.yaml
> @@ -0,0 +1,20 @@
> +{
> + "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.
> + "min_unicam_buffers": 2,
I anticipate we'll want somewhere specific to document every
configuration file option. I expect this is ok for the moment, but we
need to do better at documenting the public API.
> +
> + # 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
Reading above as min_unicam_buffers must be less than or equal to
min_total_unicam_buffers really makes me wonder why this isn't set up so
it's an additional buffer count rather than a total buffer count.
Also we now have different documentation here in an example file, vs
what's in the code...
What will be the definitive source of information ?
I expect it will be the code - so hopefully we can generate
public API documentation from that ?
> + }
> +}
> diff --git a/src/libcamera/pipeline/raspberrypi/data/meson.build b/src/libcamera/pipeline/raspberrypi/data/meson.build
> new file mode 100644
> index 000000000000..1c70433bbcbc
> --- /dev/null
> +++ b/src/libcamera/pipeline/raspberrypi/data/meson.build
> @@ -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')
> diff --git a/src/libcamera/pipeline/raspberrypi/meson.build b/src/libcamera/pipeline/raspberrypi/meson.build
> index 6064a3f00122..59e8fb18c555 100644
> --- a/src/libcamera/pipeline/raspberrypi/meson.build
> +++ b/src/libcamera/pipeline/raspberrypi/meson.build
> @@ -6,3 +6,5 @@ libcamera_sources += files([
> 'raspberrypi.cpp',
> 'rpi_stream.cpp',
> ])
> +
> +subdir('data')
> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> index 6ed4cc2c7ba7..2b396f1db9b6 100644
> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> @@ -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>
>
> @@ -39,6 +40,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"
> @@ -1150,6 +1152,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
> @@ -1683,6 +1686,48 @@ int RPiCameraData::configurePipeline()
> .minTotalUnicamBuffers = 4,
> };
>
> + char const *configFromEnv = utils::secure_getenv("LIBCAMERA_RPI_CONFIG_FILE");
> + if (!configFromEnv || *configFromEnv == '\0')
> + return 0;
This seems like the sort of thing users might want to set for the whole
system and make sure it stays configured. Which will warrant development
of a 'libcamera configuration file' - which would then have the ability
to set a default file here perhaps?
How do you expect users to currently handle this ? I guess your
libcamera-apps will set this env var perhaps? But will that then cause
users to have a different experience vs libcamera-apps and say any
generic app or the gstreamer pipeline ?
> +
> + 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, Error) << "Failed to parse configuration file, using defaults";
> + return -EINVAL;
> + }
> +
> + 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;
> }
>
> --
> 2.25.1
>
More information about the libcamera-devel
mailing list