summaryrefslogtreecommitdiff
path: root/src/libcamera/pipeline/vimc.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-05-01 01:06:34 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-05-23 01:07:38 +0300
commit2b1a908b5222e26317d761a18e91d6ede93b6e16 (patch)
tree4a207808ee0d82481ceb732fcc051fb19b508fed /src/libcamera/pipeline/vimc.cpp
parentadc61fc3ce911f32128b4d8f37d42272baf42d7b (diff)
libcamera: camera: Add a validation API to the CameraConfiguration class
The CameraConfiguration class implements a simple storage of StreamConfiguration with internal validation limited to verifying that the stream configurations are not empty. Extend this mechanism by implementing a smart validate() method backed by pipeline handlers. This new mechanism changes the semantic of the camera configuration. The Camera::generateConfiguration() operation still generates a default configuration based on roles, but now also supports generating empty configurations to be filled by applications. Applications can inspect the configuration, optionally modify it, and validate it. The validation implements "try" semantics and adjusts invalid configurations instead of rejecting them completely. Applications then decide whether to accept the modified configuration, or try again with a different set of parameters. Once the configuration is valid, it is passed to Camera::configure(), and pipeline handlers are guaranteed that the configuration they receive is valid. A reference to the Camera may need to be stored in the CameraConfiguration derived classes in order to access it from their validate() implementation. This must be stored as a std::shared_ptr<> as the CameraConfiguration instances belong to applications. In order to make this possible, make the Camera class inherit from std::shared_from_this<>. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Diffstat (limited to 'src/libcamera/pipeline/vimc.cpp')
-rw-r--r--src/libcamera/pipeline/vimc.cpp66
1 files changed, 65 insertions, 1 deletions
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index ed5b1ad4..0e4eede3 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -5,6 +5,9 @@
* vimc.cpp - Pipeline handler for the vimc device
*/
+#include <algorithm>
+#include <array>
+
#include <libcamera/camera.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
@@ -39,6 +42,14 @@ public:
Stream stream_;
};
+class VimcCameraConfiguration : public CameraConfiguration
+{
+public:
+ VimcCameraConfiguration();
+
+ Status validate() override;
+};
+
class PipelineHandlerVimc : public PipelineHandler
{
public:
@@ -68,6 +79,57 @@ private:
}
};
+VimcCameraConfiguration::VimcCameraConfiguration()
+ : CameraConfiguration()
+{
+}
+
+CameraConfiguration::Status VimcCameraConfiguration::validate()
+{
+ static const std::array<unsigned int, 3> formats{
+ V4L2_PIX_FMT_BGR24,
+ V4L2_PIX_FMT_RGB24,
+ V4L2_PIX_FMT_ARGB32,
+ };
+
+ Status status = Valid;
+
+ if (config_.empty())
+ return Invalid;
+
+ /* Cap the number of entries to the available streams. */
+ if (config_.size() > 1) {
+ config_.resize(1);
+ status = Adjusted;
+ }
+
+ StreamConfiguration &cfg = config_[0];
+
+ /* Adjust the pixel format. */
+ if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) ==
+ formats.end()) {
+ LOG(VIMC, Debug) << "Adjusting format to RGB24";
+ cfg.pixelFormat = V4L2_PIX_FMT_RGB24;
+ status = Adjusted;
+ }
+
+ /* Clamp the size based on the device limits. */
+ const Size size = cfg.size;
+
+ cfg.size.width = std::max(16U, std::min(4096U, cfg.size.width));
+ cfg.size.height = std::max(16U, std::min(2160U, cfg.size.height));
+
+ if (cfg.size != size) {
+ LOG(VIMC, Debug)
+ << "Adjusting size to " << cfg.size.toString();
+ status = Adjusted;
+ }
+
+ cfg.bufferCount = 4;
+
+ return status;
+}
+
PipelineHandlerVimc::PipelineHandlerVimc(CameraManager *manager)
: PipelineHandler(manager)
{
@@ -76,7 +138,7 @@ PipelineHandlerVimc::PipelineHandlerVimc(CameraManager *manager)
CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera,
const StreamRoles &roles)
{
- CameraConfiguration *config = new CameraConfiguration();
+ CameraConfiguration *config = new VimcCameraConfiguration();
if (roles.empty())
return config;
@@ -88,6 +150,8 @@ CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera,
config->addConfiguration(cfg);
+ config->validate();
+
return config;
}