diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index 85d9cc87..083cdb74 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -154,7 +154,7 @@ In the *meson.build* file, add the *vivid.cpp* file as a build source for libcamera by adding it to the global meson ``libcamera_internal_sources`` variable: -.. code-block:: none +.. code-block:: meson # SPDX-License-Identifier: CC0-1.0 @@ -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. @@ -180,7 +180,7 @@ configuring a build directory. To add the new pipeline handler to this list of options, add its directory name to the libcamera build options in the top level ``meson_options.txt``. -.. code-block:: none +.. code-block:: meson option('pipelines', type : 'array', @@ -201,12 +201,12 @@ stub implementations for the overridden class members. public: PipelineHandlerVivid(CameraManager *manager); - CameraConfiguration *generateConfiguration(Camera *camera, - Span roles) override; + std::unique_ptr + generateConfiguration(Camera *camera, Span roles) override; int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) override; + std::vector> *buffers) override; int start(Camera *camera, const ControlList *controls) override; void stopDevice(Camera *camera) override; @@ -221,8 +221,9 @@ stub implementations for the overridden class members. { } - CameraConfiguration *PipelineHandlerVivid::generateConfiguration(Camera *camera, - Span roles) + std::unique_ptr + PipelineHandlerVivid::generateConfiguration(Camera *camera, + Span roles) { return nullptr; } @@ -293,8 +294,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: @@ -305,9 +305,9 @@ new pipeline handler by running: And you should see output like the below: -.. code-block:: shell +.. code-block:: text - 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 +352,7 @@ Add the following below ``dm.add("vivid-000-vid-cap");``: .. code-block:: cpp - MediaDevice *media = acquireMediaDevice(enumerator, dm); + std::shared_ptr media = acquireMediaDevice(enumerator, dm); if (!media) return false; @@ -382,7 +382,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 +423,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 video_; Stream stream_; }; @@ -466,9 +460,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(media->getEntityByName("vivid-000-vid-cap")); if (video_->open()) return -ENODEV; @@ -487,9 +481,9 @@ handler. .. code-block:: cpp - std::unique_ptr data = std::make_unique(this, media); + std::unique_ptr data = std::make_unique(this); - if (data->init()) + if (data->init(media.get())) return false; @@ -506,7 +500,8 @@ PipelineHandler successfully matched and constructed a device. .. code-block:: cpp std::set streams{ &data->stream_ }; - std::shared_ptr camera = Camera::create(std::move(data), data->video_->deviceName(), streams); + const char *id = data->video_->deviceName(); + std::shared_ptr camera = Camera::create(std::move(data), id, streams); registerCamera(std::move(camera)); return true; @@ -521,19 +516,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 media = acquireMediaDevice(enumerator, dm); if (!media) return false; - std::unique_ptr data = std::make_unique(this, media); + std::unique_ptr data = std::make_unique(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 streams{ &data->stream_ }; - std::shared_ptr camera = Camera::create(std::move(data), data->video_->deviceName(), streams); + const char *id = data->video_->deviceName(); + std::shared_ptr camera = Camera::create(std::move(data), id, streams); registerCamera(std::move(camera)); return true; @@ -897,7 +893,7 @@ Add the following function implementation to your file: const std::vector &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,13 +908,13 @@ 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 handler, and showing that our configurations have been generated: -.. code-block:: shell +.. code-block:: text Using camera vivid 0: 1280x720-BGR888 @@ -989,8 +985,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 +1004,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. @@ -1130,7 +1126,7 @@ prepares the video device accordingly. Implement the pipeline handler ``start()`` function by replacing the stub version with the following code: -.. code-block:: c++ +.. code-block:: cpp VividCameraData *data = cameraData(camera); unsigned int count = data->stream_.configuration().bufferCount; @@ -1262,8 +1258,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 +1275,7 @@ before being set. continue; } - int32_t value = std::lround(it.second.get() * 128 + offset); + int32_t value = std::lround(v.get() * 128 + offset); controls.set(cid, std::clamp(value, 0, 255)); } @@ -1421,7 +1416,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. @@ -1430,7 +1425,7 @@ Running the command above outputs (a lot of) information about pixel formats, and then starts capturing frame data, and should provide an output such as the following: -.. code-block:: none +.. code-block:: text user@dev:/home/libcamera$ ./build/src/cam/cam -c vivid -C5 [42:34:08.573066847] [186470] INFO IPAManager ipa_manager.cpp:136 libcamera is not installed. Adding '/home/libcamera/build/src/ipa' to the IPA search path