| Message ID | 20260129082814.1777779-7-paul.elder@ideasonboard.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
Hi Paul, Thank you for the patch! Quoting Paul Elder (2026-01-29 08:28:12) > Add hooks into the CameraManager to call into the LayerManager on all > relevant public-facing interface of Camera. > > The entry point for each function into the LayerManager has been > chosen based on the capabilities that we want to expose to Layer > implementations. > > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> > > --- > Changes in v6: > - merge the metadata returned by the layers in requestCompleted into the > request's metadata to forward it to the application > > No change in v5 > > No change in v4 > > Changes in v3: > - send the copy of controls returned by LayerManager::start() > - each Camera now has a LayerController that it can call into, > shortening each hook call significantly > > Changes in v2: > - move the LayerManager out of Camera into the CameraManager > - remove hooks for generateConfiguration() and streams() > - Camera now passes itself into the layer hooks, as it is required for > the LayerManager to fetch the closure based on the camera to pass to > each layer > --- > include/libcamera/internal/camera.h | 4 ++++ > src/libcamera/camera.cpp | 32 ++++++++++++++++++++++++++--- > 2 files changed, 33 insertions(+), 3 deletions(-) > > diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h > index d28cd921a0f9..fdabc460a357 100644 > --- a/include/libcamera/internal/camera.h > +++ b/include/libcamera/internal/camera.h > @@ -19,6 +19,8 @@ > > #include <libcamera/camera.h> > > +#include "libcamera/internal/layer_manager.h" > + > namespace libcamera { > > class CameraControlValidator; > @@ -78,6 +80,8 @@ private: > std::atomic<State> state_; > > std::unique_ptr<CameraControlValidator> validator_; > + > + std::unique_ptr<LayerController> layers_; > }; > > } /* namespace libcamera */ > diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp > index a2132e61a7bd..4ed9a21726d9 100644 > --- a/src/libcamera/camera.cpp > +++ b/src/libcamera/camera.cpp > @@ -18,6 +18,7 @@ > #include <libcamera/base/log.h> > #include <libcamera/base/thread.h> > > +#include <libcamera/camera_manager.h> > #include <libcamera/color_space.h> > #include <libcamera/control_ids.h> > #include <libcamera/framebuffer_allocator.h> > @@ -27,6 +28,8 @@ > > #include "libcamera/internal/camera.h" > #include "libcamera/internal/camera_controls.h" > +#include "libcamera/internal/camera_manager.h" > +#include "libcamera/internal/layer_manager.h" > #include "libcamera/internal/pipeline_handler.h" > #include "libcamera/internal/request.h" > > @@ -774,18 +777,23 @@ void Camera::Private::setState(State state) > void Camera::Private::emitBufferCompleted(Request *request, FrameBuffer *buffer) > { > Camera *camera = _o<Camera>(); > + layers_->bufferCompleted(request, buffer); > camera->bufferCompleted.emit(request, buffer); > } > > void Camera::Private::emitRequestCompleted(Request *request) > { > Camera *camera = _o<Camera>(); > + ControlList metadata = layers_->requestCompleted(request); > + request->_d()->metadata().merge(metadata, > + ControlList::MergePolicy::OverwriteExisting); > camera->requestCompleted.emit(request); > } > > void Camera::Private::emitDisconnected() > { > Camera *camera = _o<Camera>(); > + layers_->disconnected(); > camera->disconnected.emit(); > } > > @@ -976,6 +984,10 @@ Camera::Camera(std::unique_ptr<Private> d, const std::string &id, > _d()->id_ = id; > _d()->streams_ = streams; > _d()->validator_ = std::make_unique<CameraControlValidator>(this); > + _d()->layers_ = > + _d()->pipe()->cameraManager()->_d()->layerManager()->createController(this, > + _d()->properties_, > + _d()->controlInfo_); Ah! I was about to ask what happens if there are no layers? But it seems I just needed to look closely-er. Looks good to me! Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com> Best wishes, Isaac > } > > Camera::~Camera() > @@ -1065,6 +1077,8 @@ int Camera::acquire() > return -EBUSY; > } > > + d->layers_->acquire(); > + > d->setState(Private::CameraAcquired); > > return 0; > @@ -1097,6 +1111,8 @@ int Camera::release() > d->pipe_->invokeMethod(&PipelineHandler::release, > ConnectionTypeBlocking, this); > > + d->layers_->release(); > + > d->setState(Private::CameraAvailable); > > return 0; > @@ -1114,7 +1130,7 @@ int Camera::release() > */ > const ControlInfoMap &Camera::controls() const > { > - return _d()->controlInfo_; > + return _d()->layers_->controls(); > } > > /** > @@ -1127,7 +1143,7 @@ const ControlInfoMap &Camera::controls() const > */ > const ControlList &Camera::properties() const > { > - return _d()->properties_; > + return _d()->layers_->properties(); > } > > /** > @@ -1276,6 +1292,8 @@ int Camera::configure(CameraConfiguration *config) > d->activeStreams_.insert(stream); > } > > + d->layers_->configure(config, d->controlInfo_); > + > d->setState(Private::CameraConfigured); > > return 0; > @@ -1316,6 +1334,8 @@ std::unique_ptr<Request> Camera::createRequest(uint64_t cookie) > /* Associate the request with the pipeline handler. */ > d->pipe_->registerRequest(request.get()); > > + d->layers_->createRequest(cookie, request.get()); > + > return request; > } > > @@ -1417,6 +1437,8 @@ int Camera::queueRequest(Request *request) > /* Pre-process AeEnable. */ > patchControlList(request->controls()); > > + d->layers_->queueRequest(request); > + > d->pipe_->invokeMethod(&PipelineHandler::queueRequest, > ConnectionTypeQueued, request); > > @@ -1453,8 +1475,10 @@ int Camera::start(const ControlList *controls) > > ASSERT(d->requestSequence_ == 0); > > + ControlList *newControls = d->layers_->start(controls); > + > if (controls) { > - ControlList copy(*controls); > + ControlList copy(*newControls); > patchControlList(copy); > ret = d->pipe_->invokeMethod(&PipelineHandler::start, > ConnectionTypeBlocking, this, ©); > @@ -1505,6 +1529,8 @@ int Camera::stop() > > d->setState(Private::CameraStopping); > > + d->layers_->stop(); > + > d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking, > this); > > -- > 2.47.2 >
diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index d28cd921a0f9..fdabc460a357 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -19,6 +19,8 @@ #include <libcamera/camera.h> +#include "libcamera/internal/layer_manager.h" + namespace libcamera { class CameraControlValidator; @@ -78,6 +80,8 @@ private: std::atomic<State> state_; std::unique_ptr<CameraControlValidator> validator_; + + std::unique_ptr<LayerController> layers_; }; } /* namespace libcamera */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index a2132e61a7bd..4ed9a21726d9 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -18,6 +18,7 @@ #include <libcamera/base/log.h> #include <libcamera/base/thread.h> +#include <libcamera/camera_manager.h> #include <libcamera/color_space.h> #include <libcamera/control_ids.h> #include <libcamera/framebuffer_allocator.h> @@ -27,6 +28,8 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_controls.h" +#include "libcamera/internal/camera_manager.h" +#include "libcamera/internal/layer_manager.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/request.h" @@ -774,18 +777,23 @@ void Camera::Private::setState(State state) void Camera::Private::emitBufferCompleted(Request *request, FrameBuffer *buffer) { Camera *camera = _o<Camera>(); + layers_->bufferCompleted(request, buffer); camera->bufferCompleted.emit(request, buffer); } void Camera::Private::emitRequestCompleted(Request *request) { Camera *camera = _o<Camera>(); + ControlList metadata = layers_->requestCompleted(request); + request->_d()->metadata().merge(metadata, + ControlList::MergePolicy::OverwriteExisting); camera->requestCompleted.emit(request); } void Camera::Private::emitDisconnected() { Camera *camera = _o<Camera>(); + layers_->disconnected(); camera->disconnected.emit(); } @@ -976,6 +984,10 @@ Camera::Camera(std::unique_ptr<Private> d, const std::string &id, _d()->id_ = id; _d()->streams_ = streams; _d()->validator_ = std::make_unique<CameraControlValidator>(this); + _d()->layers_ = + _d()->pipe()->cameraManager()->_d()->layerManager()->createController(this, + _d()->properties_, + _d()->controlInfo_); } Camera::~Camera() @@ -1065,6 +1077,8 @@ int Camera::acquire() return -EBUSY; } + d->layers_->acquire(); + d->setState(Private::CameraAcquired); return 0; @@ -1097,6 +1111,8 @@ int Camera::release() d->pipe_->invokeMethod(&PipelineHandler::release, ConnectionTypeBlocking, this); + d->layers_->release(); + d->setState(Private::CameraAvailable); return 0; @@ -1114,7 +1130,7 @@ int Camera::release() */ const ControlInfoMap &Camera::controls() const { - return _d()->controlInfo_; + return _d()->layers_->controls(); } /** @@ -1127,7 +1143,7 @@ const ControlInfoMap &Camera::controls() const */ const ControlList &Camera::properties() const { - return _d()->properties_; + return _d()->layers_->properties(); } /** @@ -1276,6 +1292,8 @@ int Camera::configure(CameraConfiguration *config) d->activeStreams_.insert(stream); } + d->layers_->configure(config, d->controlInfo_); + d->setState(Private::CameraConfigured); return 0; @@ -1316,6 +1334,8 @@ std::unique_ptr<Request> Camera::createRequest(uint64_t cookie) /* Associate the request with the pipeline handler. */ d->pipe_->registerRequest(request.get()); + d->layers_->createRequest(cookie, request.get()); + return request; } @@ -1417,6 +1437,8 @@ int Camera::queueRequest(Request *request) /* Pre-process AeEnable. */ patchControlList(request->controls()); + d->layers_->queueRequest(request); + d->pipe_->invokeMethod(&PipelineHandler::queueRequest, ConnectionTypeQueued, request); @@ -1453,8 +1475,10 @@ int Camera::start(const ControlList *controls) ASSERT(d->requestSequence_ == 0); + ControlList *newControls = d->layers_->start(controls); + if (controls) { - ControlList copy(*controls); + ControlList copy(*newControls); patchControlList(copy); ret = d->pipe_->invokeMethod(&PipelineHandler::start, ConnectionTypeBlocking, this, ©); @@ -1505,6 +1529,8 @@ int Camera::stop() d->setState(Private::CameraStopping); + d->layers_->stop(); + d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking, this);
Add hooks into the CameraManager to call into the LayerManager on all relevant public-facing interface of Camera. The entry point for each function into the LayerManager has been chosen based on the capabilities that we want to expose to Layer implementations. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> --- Changes in v6: - merge the metadata returned by the layers in requestCompleted into the request's metadata to forward it to the application No change in v5 No change in v4 Changes in v3: - send the copy of controls returned by LayerManager::start() - each Camera now has a LayerController that it can call into, shortening each hook call significantly Changes in v2: - move the LayerManager out of Camera into the CameraManager - remove hooks for generateConfiguration() and streams() - Camera now passes itself into the layer hooks, as it is required for the LayerManager to fetch the closure based on the camera to pass to each layer --- include/libcamera/internal/camera.h | 4 ++++ src/libcamera/camera.cpp | 32 ++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-)