[{"id":37428,"web_url":"https://patchwork.libcamera.org/comment/37428/","msgid":"<176598687280.3937789.8994626741445111547@ping.linuxembedded.co.uk>","date":"2025-12-17T15:54:32","subject":"Re: [PATCH v1] Documentation: guides: pipeline-handler: Refresh","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2025-12-17 15:38:08)\n> Update the guide to be compatible with the current version of\n> libcamera, as well as sync the code snippets with [0].\n> \n> Apart from libcamera related changes, `meson build` is replaced with\n> `meson setup build`, and direct `ninja` calls are replaced with\n> `meson compile -C build`.\n> \n> [0]: https://git.libcamera.org/libcamera/vivid.git\n> \n\nThanks,\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\n>  Documentation/guides/pipeline-handler.rst | 68 +++++++++++------------\n>  1 file changed, 31 insertions(+), 37 deletions(-)\n> \n> diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst\n> index 85d9cc870..deca75376 100644\n> --- a/Documentation/guides/pipeline-handler.rst\n> +++ b/Documentation/guides/pipeline-handler.rst\n> @@ -170,7 +170,7 @@ a comma separated list with ``-Dpipelines`` when generating a build directory:\n>  \n>  .. code-block:: shell\n>  \n> -    meson build -Dpipelines=ipu3,uvcvideo,vivid\n> +    meson setup build -Dpipelines=ipu3,uvcvideo,vivid\n>  \n>  Read the `Meson build configuration`_ documentation for more information on\n>  configuring a build directory.\n> @@ -201,12 +201,12 @@ stub implementations for the overridden class members.\n>     public:\n>            PipelineHandlerVivid(CameraManager *manager);\n>  \n> -          CameraConfiguration *generateConfiguration(Camera *camera,\n> -          Span<const StreamRole> roles) override;\n> +          std::unique_ptr<CameraConfiguration>\n> +                  generateConfiguration(Camera *camera, Span<const StreamRole> roles) override;\n>            int configure(Camera *camera, CameraConfiguration *config) override;\n>  \n>            int exportFrameBuffers(Camera *camera, Stream *stream,\n> -          std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n> +                                 std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n>  \n>            int start(Camera *camera, const ControlList *controls) override;\n>            void stopDevice(Camera *camera) override;\n> @@ -293,8 +293,7 @@ Run the following commands:\n>  \n>  .. code-block:: shell\n>  \n> -   meson build\n> -   ninja -C build\n> +   meson compile -C build\n>  \n>  To build the libcamera code base, and confirm that the build system found the\n>  new pipeline handler by running:\n> @@ -307,7 +306,7 @@ And you should see output like the below:\n>  \n>  .. code-block:: shell\n>  \n> -    DEBUG Camera camera_manager.cpp:148 Found registered pipeline handler 'PipelineHandlerVivid'\n> +    DEBUG Camera camera_manager.cpp:143 Found registered pipeline handler 'vivid\n>  \n>  Matching devices\n>  ~~~~~~~~~~~~~~~~\n> @@ -352,7 +351,7 @@ Add the following below ``dm.add(\"vivid-000-vid-cap\");``:\n>  \n>  .. code-block:: cpp\n>  \n> -   MediaDevice *media = acquireMediaDevice(enumerator, dm);\n> +   std::shared_ptr<MediaDevice> media = acquireMediaDevice(enumerator, dm);\n>     if (!media)\n>             return false;\n>  \n> @@ -382,7 +381,7 @@ running\n>  \n>  .. code-block:: shell\n>  \n> -   ninja -C build\n> +   meson compile -C build\n>     LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./build/src/cam/cam -l\n>  \n>  And you should see output like the below:\n> @@ -423,21 +422,15 @@ it will be used:\n>     class VividCameraData : public Camera::Private\n>     {\n>     public:\n> -          VividCameraData(PipelineHandler *pipe, MediaDevice *media)\n> -                : Camera::Private(pipe), media_(media), video_(nullptr)\n> +          VividCameraData(PipelineHandler *pipe)\n> +                : Camera::Private(pipe)\n>            {\n>            }\n>  \n> -          ~VividCameraData()\n> -          {\n> -                delete video_;\n> -          }\n> -\n> -          int init();\n> +          int init(const MediaDevice *media);\n>            void bufferReady(FrameBuffer *buffer);\n>  \n> -          MediaDevice *media_;\n> -          V4L2VideoDevice *video_;\n> +          std::unique_ptr<V4L2VideoDevice> video_;\n>            Stream stream_;\n>     };\n>  \n> @@ -466,9 +459,9 @@ open a single capture device named 'vivid-000-vid-cap' by the device.\n>  \n>  .. code-block:: cpp\n>  \n> -   int VividCameraData::init()\n> +   int VividCameraData::init(const MediaDevice *media)\n>     {\n> -          video_ = new V4L2VideoDevice(media_->getEntityByName(\"vivid-000-vid-cap\"));\n> +          video_ = std::make_unique<V4L2VideoDevice>(media->getEntityByName(\"vivid-000-vid-cap\"));\n>            if (video_->open())\n>                  return -ENODEV;\n>  \n> @@ -487,9 +480,9 @@ handler.\n>  \n>  .. code-block:: cpp\n>  \n> -   std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this, media);\n> +   std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this);\n>  \n> -   if (data->init())\n> +   if (data->init(media.get()))\n>             return false;\n>  \n>  \n> @@ -506,7 +499,8 @@ PipelineHandler successfully matched and constructed a device.\n>  .. code-block:: cpp\n>  \n>     std::set<Stream *> streams{ &data->stream_ };\n> -   std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams);\n> +   const char *id = data->video_->deviceName();\n> +   std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams);\n>     registerCamera(std::move(camera));\n>  \n>     return true;\n> @@ -521,19 +515,20 @@ Our match function should now look like the following:\n>         DeviceMatch dm(\"vivid\");\n>         dm.add(\"vivid-000-vid-cap\");\n>  \n> -       MediaDevice *media = acquireMediaDevice(enumerator, dm);\n> +       std::shared_ptr<MediaDevice> media = acquireMediaDevice(enumerator, dm);\n>         if (!media)\n>                 return false;\n>  \n> -       std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this, media);\n> +       std::unique_ptr<VividCameraData> data = std::make_unique<VividCameraData>(this);\n>  \n>         /* Locate and open the capture video node. */\n> -       if (data->init())\n> +       if (data->init(media.get()))\n>                 return false;\n>  \n>         /* Create and register the camera. */\n>         std::set<Stream *> streams{ &data->stream_ };\n> -       std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams);\n> +       const char *id = data->video_->deviceName();\n> +       std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams);\n>         registerCamera(std::move(camera));\n>  \n>         return true;\n> @@ -897,7 +892,7 @@ Add the following function implementation to your file:\n>             const std::vector<libcamera::PixelFormat> &formats = cfg.formats().pixelformats();\n>             if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) {\n>                    cfg.pixelFormat = formats[0];\n> -                  LOG(VIVID, Debug) << \"Adjusting format to \" << cfg.pixelFormat.toString();\n> +                  LOG(VIVID, Debug) << \"Adjusting format to \" << cfg.pixelFormat;\n>                    status = Adjusted;\n>             }\n>  \n> @@ -912,7 +907,7 @@ codebase, and test:\n>  \n>  .. code-block:: shell\n>  \n> -   ninja -C build\n> +   meson compile -C build\n>     LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./build/src/cam/cam -c vivid -I\n>  \n>  You should see the following output showing the capabilites of our new pipeline\n> @@ -989,8 +984,9 @@ Add the following code beneath the code from above:\n>  \n>  .. code-block:: cpp\n>  \n> +   const V4L2PixelFormat fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat);\n>     V4L2DeviceFormat format = {};\n> -   format.fourcc = data->video_->toV4L2PixelFormat(cfg.pixelFormat);\n> +   format.fourcc = fourcc;\n>     format.size = cfg.size;\n>  \n>  Set the video device format defined above using the\n> @@ -1007,8 +1003,7 @@ Continue the implementation with the following code:\n>     if (ret)\n>            return ret;\n>  \n> -   if (format.size != cfg.size ||\n> -          format.fourcc != data->video_->toV4L2PixelFormat(cfg.pixelFormat))\n> +   if (format.size != cfg.size || format.fourcc != fourcc)\n>            return -EINVAL;\n>  \n>  Finally, store and set stream-specific data reflecting the state of the stream.\n> @@ -1262,8 +1257,7 @@ before being set.\n>     {\n>            ControlList controls(data->video_->controls());\n>  \n> -          for (auto it : request->controls()) {\n> -                 unsigned int id = it.first;\n> +          for (const auto &[id, v] : request->controls()) {\n>                   unsigned int offset;\n>                   uint32_t cid;\n>  \n> @@ -1280,7 +1274,7 @@ before being set.\n>                          continue;\n>                   }\n>  \n> -                 int32_t value = std::lround(it.second.get<float>() * 128 + offset);\n> +                 int32_t value = std::lround(v.get<float>() * 128 + offset);\n>                   controls.set(cid, std::clamp(value, 0, 255));\n>            }\n>  \n> @@ -1421,7 +1415,7 @@ capture through the pipeline through both of the cam and qcam utilities.\n>  \n>  .. code-block:: shell\n>  \n> -   ninja -C build\n> +   meson compile -C build\n>     ./build/src/cam/cam -c vivid -C5\n>  \n>  To test that the pipeline handler can detect a device, and capture input.\n> -- \n> 2.52.0\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B7E4ABD7D8\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 17 Dec 2025 15:54:38 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BA13461AA4;\n\tWed, 17 Dec 2025 16:54:37 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7724961A35\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 17 Dec 2025 16:54:36 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id DB6FDB3;\n\tWed, 17 Dec 2025 16:54:29 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"spm7ppbf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1765986870;\n\tbh=iwRk/JrQ7j12HbE0vEV44xb6gRlFy4a0bv/V9EDMYJM=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=spm7ppbfToCuFjF3TO+/3F0GZ1oSQC4JLeDl3Ox75nUWwy04/icRcv8bQmxSyNF2m\n\tcmRwDJiAh44yg6kagLXuTK331qZqPWhdWtUFgfyHbom7YCExCOussq6+b82iCx5On0\n\t7HC9IAH+iYNRwCFYb8McR9GtuipJj+KwiamV+EME=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20251217153808.3447066-1-barnabas.pocze@ideasonboard.com>","References":"<20251217153808.3447066-1-barnabas.pocze@ideasonboard.com>","Subject":"Re: [PATCH v1] Documentation: guides: pipeline-handler: Refresh","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Wed, 17 Dec 2025 15:54:32 +0000","Message-ID":"<176598687280.3937789.8994626741445111547@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]