| Message ID | 20251217153808.3447066-1-barnabas.pocze@ideasonboard.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
Quoting Barnabás Pőcze (2025-12-17 15:38:08) > Update the guide to be compatible with the current version of > libcamera, as well as sync the code snippets with [0]. > > Apart from libcamera related changes, `meson build` is replaced with > `meson setup build`, and direct `ninja` calls are replaced with > `meson compile -C build`. > > [0]: https://git.libcamera.org/libcamera/vivid.git > Thanks, Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > --- > Documentation/guides/pipeline-handler.rst | 68 +++++++++++------------ > 1 file changed, 31 insertions(+), 37 deletions(-) > > diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst > index 85d9cc870..deca75376 100644 > --- a/Documentation/guides/pipeline-handler.rst > +++ b/Documentation/guides/pipeline-handler.rst > @@ -170,7 +170,7 @@ a comma separated list with ``-Dpipelines`` when generating a build directory: > > .. code-block:: shell > > - meson build -Dpipelines=ipu3,uvcvideo,vivid > + meson setup build -Dpipelines=ipu3,uvcvideo,vivid > > Read the `Meson build configuration`_ documentation for more information on > configuring a build directory. > @@ -201,12 +201,12 @@ stub implementations for the overridden class members. > public: > PipelineHandlerVivid(CameraManager *manager); > > - CameraConfiguration *generateConfiguration(Camera *camera, > - Span<const StreamRole> roles) override; > + std::unique_ptr<CameraConfiguration> > + generateConfiguration(Camera *camera, Span<const StreamRole> roles) override; > int configure(Camera *camera, CameraConfiguration *config) override; > > int exportFrameBuffers(Camera *camera, Stream *stream, > - std::vector<std::unique_ptr<FrameBuffer>> *buffers) override; > + std::vector<std::unique_ptr<FrameBuffer>> *buffers) override; > > int start(Camera *camera, const ControlList *controls) override; > void stopDevice(Camera *camera) override; > @@ -293,8 +293,7 @@ Run the following commands: > > .. code-block:: shell > > - meson build > - ninja -C build > + meson compile -C build > > To build the libcamera code base, and confirm that the build system found the > new pipeline handler by running: > @@ -307,7 +306,7 @@ And you should see output like the below: > > .. code-block:: shell > > - DEBUG Camera camera_manager.cpp:148 Found registered pipeline handler 'PipelineHandlerVivid' > + DEBUG Camera camera_manager.cpp:143 Found registered pipeline handler 'vivid > > Matching devices > ~~~~~~~~~~~~~~~~ > @@ -352,7 +351,7 @@ Add the following below ``dm.add("vivid-000-vid-cap");``: > > .. code-block:: cpp > > - MediaDevice *media = acquireMediaDevice(enumerator, dm); > + std::shared_ptr<MediaDevice> media = acquireMediaDevice(enumerator, dm); > if (!media) > return false; > > @@ -382,7 +381,7 @@ running > > .. code-block:: shell > > - ninja -C build > + meson compile -C build > LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./build/src/cam/cam -l > > And you should see output like the below: > @@ -423,21 +422,15 @@ it will be used: > class VividCameraData : public Camera::Private > { > public: > - VividCameraData(PipelineHandler *pipe, MediaDevice *media) > - : Camera::Private(pipe), media_(media), video_(nullptr) > + VividCameraData(PipelineHandler *pipe) > + : Camera::Private(pipe) > { > } > > - ~VividCameraData() > - { > - delete video_; > - } > - > - int init(); > + int init(const MediaDevice *media); > void bufferReady(FrameBuffer *buffer); > > - MediaDevice *media_; > - V4L2VideoDevice *video_; > + std::unique_ptr<V4L2VideoDevice> video_; > Stream stream_; > }; > > @@ -466,9 +459,9 @@ open a single capture device named 'vivid-000-vid-cap' by the device. > > .. code-block:: cpp > > - int VividCameraData::init() > + int VividCameraData::init(const MediaDevice *media) > { > - video_ = new V4L2VideoDevice(media_->getEntityByName("vivid-000-vid-cap")); > + video_ = std::make_unique<V4L2VideoDevice>(media->getEntityByName("vivid-000-vid-cap")); > if (video_->open()) > return -ENODEV; > > @@ -487,9 +480,9 @@ handler. > > .. code-block:: cpp > > - std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this, media); > + std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this); > > - if (data->init()) > + if (data->init(media.get())) > return false; > > > @@ -506,7 +499,8 @@ PipelineHandler successfully matched and constructed a device. > .. code-block:: cpp > > std::set<Stream *> streams{ &data->stream_ }; > - std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams); > + const char *id = data->video_->deviceName(); > + std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams); > registerCamera(std::move(camera)); > > return true; > @@ -521,19 +515,20 @@ Our match function should now look like the following: > DeviceMatch dm("vivid"); > dm.add("vivid-000-vid-cap"); > > - MediaDevice *media = acquireMediaDevice(enumerator, dm); > + std::shared_ptr<MediaDevice> media = acquireMediaDevice(enumerator, dm); > if (!media) > return false; > > - std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this, media); > + std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this); > > /* Locate and open the capture video node. */ > - if (data->init()) > + if (data->init(media.get())) > return false; > > /* Create and register the camera. */ > std::set<Stream *> streams{ &data->stream_ }; > - std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams); > + const char *id = data->video_->deviceName(); > + std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams); > registerCamera(std::move(camera)); > > return true; > @@ -897,7 +892,7 @@ Add the following function implementation to your file: > const std::vector<libcamera::PixelFormat> &formats = cfg.formats().pixelformats(); > if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) { > cfg.pixelFormat = formats[0]; > - LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat.toString(); > + LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat; > status = Adjusted; > } > > @@ -912,7 +907,7 @@ codebase, and test: > > .. code-block:: shell > > - ninja -C build > + meson compile -C build > LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./build/src/cam/cam -c vivid -I > > You should see the following output showing the capabilites of our new pipeline > @@ -989,8 +984,9 @@ Add the following code beneath the code from above: > > .. code-block:: cpp > > + const V4L2PixelFormat fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat); > V4L2DeviceFormat format = {}; > - format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat); > + format.fourcc = fourcc; > format.size = cfg.size; > > Set the video device format defined above using the > @@ -1007,8 +1003,7 @@ Continue the implementation with the following code: > if (ret) > return ret; > > - if (format.size != cfg.size || > - format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat)) > + if (format.size != cfg.size || format.fourcc != fourcc) > return -EINVAL; > > Finally, store and set stream-specific data reflecting the state of the stream. > @@ -1262,8 +1257,7 @@ before being set. > { > ControlList controls(data->video_->controls()); > > - for (auto it : request->controls()) { > - unsigned int id = it.first; > + for (const auto &[id, v] : request->controls()) { > unsigned int offset; > uint32_t cid; > > @@ -1280,7 +1274,7 @@ before being set. > continue; > } > > - int32_t value = std::lround(it.second.get<float>() * 128 + offset); > + int32_t value = std::lround(v.get<float>() * 128 + offset); > controls.set(cid, std::clamp(value, 0, 255)); > } > > @@ -1421,7 +1415,7 @@ capture through the pipeline through both of the cam and qcam utilities. > > .. code-block:: shell > > - ninja -C build > + meson compile -C build > ./build/src/cam/cam -c vivid -C5 > > To test that the pipeline handler can detect a device, and capture input. > -- > 2.52.0 >
diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index 85d9cc870..deca75376 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -170,7 +170,7 @@ a comma separated list with ``-Dpipelines`` when generating a build directory: .. code-block:: shell - meson build -Dpipelines=ipu3,uvcvideo,vivid + meson setup build -Dpipelines=ipu3,uvcvideo,vivid Read the `Meson build configuration`_ documentation for more information on configuring a build directory. @@ -201,12 +201,12 @@ stub implementations for the overridden class members. public: PipelineHandlerVivid(CameraManager *manager); - CameraConfiguration *generateConfiguration(Camera *camera, - Span<const StreamRole> roles) override; + std::unique_ptr<CameraConfiguration> + generateConfiguration(Camera *camera, Span<const StreamRole> roles) override; int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector<std::unique_ptr<FrameBuffer>> *buffers) override; + std::vector<std::unique_ptr<FrameBuffer>> *buffers) override; int start(Camera *camera, const ControlList *controls) override; void stopDevice(Camera *camera) override; @@ -293,8 +293,7 @@ Run the following commands: .. code-block:: shell - meson build - ninja -C build + meson compile -C build To build the libcamera code base, and confirm that the build system found the new pipeline handler by running: @@ -307,7 +306,7 @@ And you should see output like the below: .. code-block:: shell - DEBUG Camera camera_manager.cpp:148 Found registered pipeline handler 'PipelineHandlerVivid' + DEBUG Camera camera_manager.cpp:143 Found registered pipeline handler 'vivid Matching devices ~~~~~~~~~~~~~~~~ @@ -352,7 +351,7 @@ Add the following below ``dm.add("vivid-000-vid-cap");``: .. code-block:: cpp - MediaDevice *media = acquireMediaDevice(enumerator, dm); + std::shared_ptr<MediaDevice> media = acquireMediaDevice(enumerator, dm); if (!media) return false; @@ -382,7 +381,7 @@ running .. code-block:: shell - ninja -C build + meson compile -C build LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./build/src/cam/cam -l And you should see output like the below: @@ -423,21 +422,15 @@ it will be used: class VividCameraData : public Camera::Private { public: - VividCameraData(PipelineHandler *pipe, MediaDevice *media) - : Camera::Private(pipe), media_(media), video_(nullptr) + VividCameraData(PipelineHandler *pipe) + : Camera::Private(pipe) { } - ~VividCameraData() - { - delete video_; - } - - int init(); + int init(const MediaDevice *media); void bufferReady(FrameBuffer *buffer); - MediaDevice *media_; - V4L2VideoDevice *video_; + std::unique_ptr<V4L2VideoDevice> video_; Stream stream_; }; @@ -466,9 +459,9 @@ open a single capture device named 'vivid-000-vid-cap' by the device. .. code-block:: cpp - int VividCameraData::init() + int VividCameraData::init(const MediaDevice *media) { - video_ = new V4L2VideoDevice(media_->getEntityByName("vivid-000-vid-cap")); + video_ = std::make_unique<V4L2VideoDevice>(media->getEntityByName("vivid-000-vid-cap")); if (video_->open()) return -ENODEV; @@ -487,9 +480,9 @@ handler. .. code-block:: cpp - std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this, media); + std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this); - if (data->init()) + if (data->init(media.get())) return false; @@ -506,7 +499,8 @@ PipelineHandler successfully matched and constructed a device. .. code-block:: cpp std::set<Stream *> streams{ &data->stream_ }; - std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams); + const char *id = data->video_->deviceName(); + std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams); registerCamera(std::move(camera)); return true; @@ -521,19 +515,20 @@ Our match function should now look like the following: DeviceMatch dm("vivid"); dm.add("vivid-000-vid-cap"); - MediaDevice *media = acquireMediaDevice(enumerator, dm); + std::shared_ptr<MediaDevice> media = acquireMediaDevice(enumerator, dm); if (!media) return false; - std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this, media); + std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this); /* Locate and open the capture video node. */ - if (data->init()) + if (data->init(media.get())) return false; /* Create and register the camera. */ std::set<Stream *> streams{ &data->stream_ }; - std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams); + const char *id = data->video_->deviceName(); + std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams); registerCamera(std::move(camera)); return true; @@ -897,7 +892,7 @@ Add the following function implementation to your file: const std::vector<libcamera::PixelFormat> &formats = cfg.formats().pixelformats(); if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) { cfg.pixelFormat = formats[0]; - LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat.toString(); + LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat; status = Adjusted; } @@ -912,7 +907,7 @@ codebase, and test: .. code-block:: shell - ninja -C build + meson compile -C build LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./build/src/cam/cam -c vivid -I You should see the following output showing the capabilites of our new pipeline @@ -989,8 +984,9 @@ Add the following code beneath the code from above: .. code-block:: cpp + const V4L2PixelFormat fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat); V4L2DeviceFormat format = {}; - format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat); + format.fourcc = fourcc; format.size = cfg.size; Set the video device format defined above using the @@ -1007,8 +1003,7 @@ Continue the implementation with the following code: if (ret) return ret; - if (format.size != cfg.size || - format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat)) + if (format.size != cfg.size || format.fourcc != fourcc) return -EINVAL; Finally, store and set stream-specific data reflecting the state of the stream. @@ -1262,8 +1257,7 @@ before being set. { ControlList controls(data->video_->controls()); - for (auto it : request->controls()) { - unsigned int id = it.first; + for (const auto &[id, v] : request->controls()) { unsigned int offset; uint32_t cid; @@ -1280,7 +1274,7 @@ before being set. continue; } - int32_t value = std::lround(it.second.get<float>() * 128 + offset); + int32_t value = std::lround(v.get<float>() * 128 + offset); controls.set(cid, std::clamp(value, 0, 255)); } @@ -1421,7 +1415,7 @@ capture through the pipeline through both of the cam and qcam utilities. .. code-block:: shell - ninja -C build + meson compile -C build ./build/src/cam/cam -c vivid -C5 To test that the pipeline handler can detect a device, and capture input.
Update the guide to be compatible with the current version of libcamera, as well as sync the code snippets with [0]. Apart from libcamera related changes, `meson build` is replaced with `meson setup build`, and direct `ninja` calls are replaced with `meson compile -C build`. [0]: https://git.libcamera.org/libcamera/vivid.git Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> --- Documentation/guides/pipeline-handler.rst | 68 +++++++++++------------ 1 file changed, 31 insertions(+), 37 deletions(-)