[v1] Documentation: guides: pipeline-handler: Refresh
diff mbox series

Message ID 20251217153808.3447066-1-barnabas.pocze@ideasonboard.com
State Superseded
Headers show
Series
  • [v1] Documentation: guides: pipeline-handler: Refresh
Related show

Commit Message

Barnabás Pőcze Dec. 17, 2025, 3:38 p.m. UTC
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(-)

Comments

Kieran Bingham Dec. 17, 2025, 3:54 p.m. UTC | #1
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
>

Patch
diff mbox series

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.