[{"id":35248,"web_url":"https://patchwork.libcamera.org/comment/35248/","msgid":"<175388375635.371358.17636377935124555395@localhost>","date":"2025-07-30T13:55:56","subject":"Re: [PATCH v3 4/3] Documentation: Replace links to Doxygen\n\tdocumentation with doxylink","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Laurent,\n\nQuoting Laurent Pinchart (2025-07-30 15:46:48)\n> Use the Sphinx doxylink extension to generate links to the\n> Doxygen-generated documentation automatically. Not only does this fix\n> currently broken links, but it also ensures that any removal or rename\n> of a class or function referenced to from the Sphinx documentation\n> without a corresponding documentation update will be caught by a\n> documentation build error.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nI didn't check the md5 sums. But I think the change is reasonable. So\n\nAcked-by: Stefan Klug <stefan.klug@ideasonboard.com> \n\nBest regards,\nStefan\n\n> ---\n>  Documentation/environment_variables.rst       |   2 +-\n>  .../guides/application-developer.rst          |  30 +-\n>  Documentation/guides/pipeline-handler.rst     | 312 +++++++-----------\n>  Documentation/libcamera_architecture.rst      |  13 +-\n>  4 files changed, 139 insertions(+), 218 deletions(-)\n> \n> diff --git a/Documentation/environment_variables.rst b/Documentation/environment_variables.rst\n> index 6f1235587a40..0cb4e27cd670 100644\n> --- a/Documentation/environment_variables.rst\n> +++ b/Documentation/environment_variables.rst\n> @@ -90,7 +90,7 @@ The optional `category <Log categories_>`__ is a string matching the categories\n>  defined by each file in the source base using the logging infrastructure. It\n>  can include a wildcard ('*') character at the end to match multiple categories.\n> \n> -For more information refer to the `API documentation <https://libcamera.org/api-html/log_8h.html#details>`__.\n> +For more information refer to the :doxy-int:`API documentation <log.h>`.\n> \n>  Examples:\n> \n> diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst\n> index 4a18ae3a1025..bccb54acc6d4 100644\n> --- a/Documentation/guides/application-developer.rst\n> +++ b/Documentation/guides/application-developer.rst\n> @@ -46,14 +46,13 @@ defined names and types without the need of prefixing them.\n>  Camera Manager\n>  --------------\n> \n> -Every libcamera-based application needs an instance of a `CameraManager`_ that\n> -runs for the life of the application. When the Camera Manager starts, it\n> +Every libcamera-based application needs an instance of a :doxy-pub:`CameraManager`\n> +that runs for the life of the application. When the Camera Manager starts, it\n>  enumerates all the cameras detected in the system. Behind the scenes, libcamera\n>  abstracts and manages the complex pipelines that kernel drivers expose through\n>  the `Linux Media Controller`_ and `Video for Linux`_ (V4L2) APIs, meaning that\n>  an application doesn't need to handle device or driver specific details.\n> \n> -.. _CameraManager: https://libcamera.org/api-html/classlibcamera_1_1CameraManager.html\n>  .. _Linux Media Controller: https://www.kernel.org/doc/html/latest/userspace-api/media/mediactl/media-controller.html\n>  .. _Video for Linux: https://www.linuxtv.org/docs.php\n> \n> @@ -210,10 +209,9 @@ function. If the new values are not supported by the ``Camera`` device, the\n>  validation process adjusts the parameters to what it considers to be the closest\n>  supported values.\n> \n> -The ``validate`` function returns a `Status`_ which applications shall check to\n> -see if the Pipeline Handler adjusted the configuration.\n> -\n> -.. _Status: https://libcamera.org/api-html/classlibcamera_1_1CameraConfiguration.html#a64163f21db2fe1ce0a6af5a6f6847744\n> +The ``validate`` function returns a :doxy-pub:`CameraConfiguration::Status`\n> +which applications shall check to see if the Pipeline Handler adjusted the\n> +configuration.\n> \n>  For example, the code above set the width and height to 640x480, but if the\n>  camera cannot produce an image that large, it might adjust the configuration to\n> @@ -348,10 +346,10 @@ camera device, and associate a buffer for each of them for the ``Stream``.\n>  Event handling and callbacks\n>  ----------------------------\n> \n> -The libcamera library uses the concept of `signals and slots` (similar to `Qt\n> -Signals and Slots`_) to connect events with callbacks to handle them.\n> +The libcamera library uses the concept of :doxy-pub:`signals and slots <Signal>`\n> +(similar to `Qt Signals and Slots`_) to connect events with callbacks to handle\n> +them.\n> \n> -.. _signals and slots: https://libcamera.org/api-html/classlibcamera_1_1Signal.html#details\n>  .. _Qt Signals and Slots: https://doc.qt.io/qt-6/signalsandslots.html\n> \n>  The ``Camera`` device emits two signals that applications can connect to in\n> @@ -400,9 +398,7 @@ Request completion events can be emitted for requests which have been canceled,\n>  for example, by unexpected application shutdown. To avoid an application\n>  processing invalid image data, it's worth checking that the request has\n>  completed successfully. The list of request completion statuses is available in\n> -the `Request::Status`_ class enum documentation.\n> -\n> -.. _Request::Status: https://www.libcamera.org/api-html/classlibcamera_1_1Request.html#a2209ba8d51af8167b25f6e3e94d5c45b\n> +the :doxy-pub:`Request::Status` class enum documentation.\n> \n>  .. code:: cpp\n> \n> @@ -422,9 +418,7 @@ Iterating through the map allows applications to inspect each completed buffer\n>  in this request, and access the metadata associated to each frame.\n> \n>  The metadata buffer contains information such the capture status, a timestamp,\n> -and the bytes used, as described in the `FrameMetadata`_ documentation.\n> -\n> -.. _FrameMetaData: https://libcamera.org/api-html/structlibcamera_1_1FrameMetadata.html\n> +and the bytes used, as described in the :doxy-pub:`FrameMetadata` documentation.\n> \n>  .. code:: cpp\n> \n> @@ -515,13 +509,11 @@ and queue all the previously created requests.\n>  Event processing\n>  ~~~~~~~~~~~~~~~~\n> \n> -libcamera creates an internal execution thread at `CameraManager::start()`_\n> +libcamera creates an internal execution thread at :doxy-pub:`CameraManager::start()`\n>  time to decouple its own event processing from the application's main thread.\n>  Applications are thus free to manage their own execution opportunely, and only\n>  need to respond to events generated by libcamera emitted through signals.\n> \n> -.. _CameraManager::start(): https://libcamera.org/api-html/classlibcamera_1_1CameraManager.html#a49e322880a2a26013bb0076788b298c5\n> -\n>  Real-world applications will likely either integrate with the event loop of the\n>  framework they use, or create their own event loop to respond to user events.\n>  For the simple application presented in this example, it is enough to prevent\n> diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst\n> index 0d5df7269e40..2b866d98059c 100644\n> --- a/Documentation/guides/pipeline-handler.rst\n> +++ b/Documentation/guides/pipeline-handler.rst\n> @@ -83,49 +83,49 @@ functionalities described above. Below is a brief overview of each of those:\n>  .. TODO: (MediaDevice) Reference to the Media Device API (possibly with versioning requirements)\n>  .. TODO: (IPAInterface) refer to the IPA guide\n> \n> --  `MediaDevice <https://libcamera.org/api-html/classlibcamera_1_1MediaDevice.html>`_:\n> +-  :doxy-int:`MediaDevice`:\n>     Instances of this class are associated with a kernel media controller\n>     device and its connected objects.\n> \n> --  `DeviceEnumerator <https://libcamera.org/api-html/classlibcamera_1_1DeviceEnumerator.html>`_:\n> +-  :doxy-int:`DeviceEnumerator`:\n>     Enumerates all media devices attached to the system and the media entities\n>     registered with it, by creating instances of the ``MediaDevice`` class and\n>     storing them.\n> \n> --  `DeviceMatch <https://libcamera.org/api-html/classlibcamera_1_1DeviceMatch.html>`_:\n> +-  :doxy-int:`DeviceMatch`:\n>     Describes a media device search pattern using entity names, or other\n>     properties.\n> \n> --  `V4L2VideoDevice <https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html>`_:\n> +-  :doxy-int:`V4L2VideoDevice`:\n>     Models an instance of a V4L2 video device constructed with the path to a V4L2\n>     video device node.\n> \n> --  `V4L2SubDevice <https://libcamera.org/api-html/classlibcamera_1_1V4L2Subdevice.html>`_:\n> +-  :doxy-int:`V4L2Subdevice`:\n>     Provides an API to the sub-devices that model the hardware components of a\n>     V4L2 device.\n> \n> --  `CameraSensor <https://libcamera.org/api-html/classlibcamera_1_1CameraSensor.html>`_:\n> +-  :doxy-int:`CameraSensor`:\n>     Abstracts camera sensor handling by hiding the details of the V4L2 subdevice\n>     kernel API and caching sensor information.\n> \n> --  `Camera::Private <https://libcamera.org/api-html/classlibcamera_1_1Camera_1_1Private.html>`_:\n> +-  :doxy-int:`Camera::Private`:\n>     Represents device-specific data a pipeline handler associates to each Camera\n>     instance.\n> \n> --  `StreamConfiguration <https://libcamera.org/api-html/structlibcamera_1_1StreamConfiguration.html>`_:\n> +-  :doxy-int:`StreamConfiguration`:\n>     Models the current configuration of an image stream produced by the camera by\n>     reporting its format and sizes.\n> \n> --  `CameraConfiguration <https://libcamera.org/api-html/classlibcamera_1_1CameraConfiguration.html>`_:\n> +-  :doxy-int:`CameraConfiguration`:\n>     Represents the current configuration of a camera, which includes a list of\n>     stream configurations for each active stream in a capture session. When\n>     validated, it is applied to the camera.\n> \n> --  `IPAInterface <https://libcamera.org/api-html/classlibcamera_1_1IPAInterface.html>`_:\n> +-  :doxy-int:`IPAInterface`:\n>     The interface to the Image Processing Algorithm (IPA) module which performs\n>     the computation of the image processing pipeline tuning parameters.\n> \n> --  `ControlList <https://libcamera.org/api-html/classlibcamera_1_1ControlList.html>`_:\n> +-  :doxy-int:`ControlList`:\n>     A list of control items, indexed by Control<> instances or by numerical index\n>     which contains values used by application and IPA to change parameters of\n>     image streams, used to return to applications and share with IPA the metadata\n> @@ -191,10 +191,8 @@ to the libcamera build options in the top level ``meson_options.txt``.\n> \n> \n>  In *vivid.cpp* add the pipeline handler to the ``libcamera`` namespace, defining\n> -a `PipelineHandler`_ derived class named PipelineHandlerVivid, and add stub\n> -implementations for the overridden class members.\n> -\n> -.. _PipelineHandler: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html\n> +a :doxy-int:`PipelineHandler` derived class named PipelineHandlerVivid, and add\n> +stub implementations for the overridden class members.\n> \n>  .. code-block:: cpp\n> \n> @@ -266,21 +264,17 @@ implementations for the overridden class members.\n>     } /* namespace libcamera */\n> \n>  Note that you must register the ``PipelineHandler`` subclass with the pipeline\n> -handler factory using the `REGISTER_PIPELINE_HANDLER`_ macro which\n> +handler factory using the :doxy-int:`REGISTER_PIPELINE_HANDLER` macro which\n>  registers it and creates a global symbol to reference the class and make it\n>  available to try and match devices.\n>  String \"vivid\" is the name assigned to the pipeline, matching the pipeline\n>  subdirectory name in the source tree.\n> \n> -.. _REGISTER_PIPELINE_HANDLER: https://libcamera.org/api-html/pipeline__handler_8h.html\n> -\n>  For debugging and testing a pipeline handler during development, you can define\n>  a log message category for the pipeline handler. The ``LOG_DEFINE_CATEGORY``\n>  macro and ``LIBCAMERA_LOG_LEVELS`` environment variable help you use the inbuilt\n> -libcamera `logging infrastructure`_ that allow for the inspection of internal\n> -operations in a user-configurable way.\n> -\n> -.. _logging infrastructure: https://libcamera.org/api-html/log_8h.html\n> +libcamera :doxy-int:`logging infrastructure <log.h>` that allow for the\n> +inspection of internal operations in a user-configurable way.\n> \n>  Add the following before the ``PipelineHandlerVivid`` class declaration:\n> \n> @@ -326,21 +320,18 @@ system configuration, by matching a ``DeviceMatch`` with the system\n>  have been registered in the system and allows the pipeline handler to be\n>  initialized.\n> \n> -The main entry point of a pipeline handler is the `match()`_ class member\n> -function. When the ``CameraManager`` is started (using the `start()`_ function),\n> -all the registered pipeline handlers are iterated and their ``match`` function\n> -called with an enumerator of all devices it found on a system.\n> +The main entry point of a pipeline handler is the :doxy-int:`PipelineHandler::match`\n> +class member function. When the ``CameraManager`` is started (using the\n> +:doxy-int:`CameraManager::start` function), all the registered pipeline\n> +handlers are iterated and their ``match`` function called with an enumerator of\n> +all devices it found on a system.\n> \n>  The match function should identify if there are suitable devices available in\n>  the ``DeviceEnumerator`` which the pipeline supports, returning ``true`` if it\n>  matches a device, and ``false`` if it does not. To do this, construct a\n> -`DeviceMatch`_ class with the name of the ``MediaController`` device to match.\n> -You can specify the search further by adding specific media entities to the\n> -search using the ``.add()`` function on the DeviceMatch.\n> -\n> -.. _match(): https://www.libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#a7cd5b652a2414b543ec20ba9dabf61b6\n> -.. _start(): https://libcamera.org/api-html/classlibcamera_1_1CameraManager.html#a49e322880a2a26013bb0076788b298c5\n> -.. _DeviceMatch: https://libcamera.org/api-html/classlibcamera_1_1DeviceMatch.html\n> +:doxy-int:`DeviceMatch` class with the name of the ``MediaController`` device\n> +to match. You can specify the search further by adding specific media entities\n> +to the search using the ``.add()`` function on the DeviceMatch.\n> \n>  This example uses search patterns that match vivid, but when developing a new\n>  pipeline handler, you should change this value to suit your device identifier.\n> @@ -355,11 +346,9 @@ following:\n>     return false; // Prevent infinite loops for now\n> \n>  With the device matching criteria defined, attempt to acquire exclusive access\n> -to the matching media controller device with the `acquireMediaDevice`_ function.\n> -If the function attempts to acquire a device it has already matched, it returns\n> -``false``.\n> -\n> -.. _acquireMediaDevice: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#a77e424fe704e7b26094164b9189e0f84\n> +to the matching media controller device with the :doxy-int:`PipelineHandler::acquireMediaDevice`\n> +function. If the function attempts to acquire a device it has already matched,\n> +it returns ``false``.\n> \n>  Add the following below ``dm.add(\"vivid-000-vid-cap\");``:\n> \n> @@ -421,12 +410,9 @@ receivers port output.\n>  The Pipeline Handler is responsible for defining the set of Streams associated\n>  with the Camera.\n> \n> -Each Camera has instance-specific data represented using the `Camera::Private`_\n> +Each Camera has instance-specific data represented using the :doxy-int:`Camera::Private`\n>  class, which can be extended for the specific needs of the pipeline handler.\n> \n> -.. _Camera::Private: https://libcamera.org/api-html/classlibcamera_1_1Camera_1_1Private.html\n> -\n> -\n>  To support the Camera we will later register, we need to create a Camera::Private\n>  class that we can implement for our specific Pipeline Handler.\n> \n> @@ -476,11 +462,9 @@ and is usually responsible for opening all Devices used in the capture pipeline.\n> \n>  We can now implement the ``init`` function for our example Pipeline Handler to\n>  create a new V4L2 video device from the media entity, which we can specify using\n> -the `MediaDevice::getEntityByName`_ function from the MediaDevice. As our\n> -example is based upon the simplistic Vivid test device, we only need to open a\n> -single capture device named 'vivid-000-vid-cap' by the device.\n> -\n> -.. _MediaDevice::getEntityByName: https://libcamera.org/api-html/classlibcamera_1_1MediaDevice.html#ad5d9279329ef4987ceece2694b33e230\n> +the :doxy-int:`MediaDevice::getEntityByName` function from the MediaDevice. As\n> +our example is based upon the simplistic Vivid test device, we only need to\n> +open a single capture device named 'vivid-000-vid-cap' by the device.\n> \n>  .. code-block:: cpp\n> \n> @@ -514,16 +498,13 @@ handler.\n>  Once the camera data has been initialized, the Camera device instances and the\n>  associated streams have to be registered. Create a set of streams for the\n>  camera, which for this device is only one. You create a camera using the static\n> -`Camera::create`_ function, passing the Camera::Private instance, the id of the\n> -camera, and the streams available. Then register the camera with the pipeline\n> -handler and camera manager using `registerCamera`_.\n> +:doxy-int:`Camera::create` function, passing the Camera::Private instance, the\n> +id of the camera, and the streams available. Then register the camera with the\n> +pipeline handler and camera manager using :doxy-int:`PipelineHandler::registerCamera`.\n> \n>  Finally with a successful construction, we return 'true' indicating that the\n>  PipelineHandler successfully matched and constructed a device.\n> \n> -.. _Camera::create: https://libcamera.org/internal-api-html/classlibcamera_1_1Camera.html#adf5e6c22411f953bfaa1ae21155d6c31\n> -.. _registerCamera: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#adf02a7f1bbd87aca73c0e8d8e0e6c98b\n> -\n>  .. code-block:: cpp\n> \n>     std::set<Stream *> streams{ &data->stream_ };\n> @@ -585,33 +566,26 @@ interface, and device interaction interfaces.\n>  Registering controls and properties\n>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n> \n> -The libcamera `controls framework`_ allows an application to configure the\n> -streams capture parameters on a per-frame basis and is also used to advertise\n> -immutable properties of the ``Camera`` device.\n> +The libcamera :doxy-int:`controls framework <controls.h>` allows an application\n> +to configure the streams capture parameters on a per-frame basis and is also\n> +used to advertise immutable properties of the ``Camera`` device.\n> \n>  The libcamera controls and properties are defined in YAML form which is\n>  processed to automatically generate documentation and interfaces. Controls are\n> -defined by the src/libcamera/`control_ids_core.yaml`_ file and camera properties\n> -are defined by src/libcamera/`property_ids_core.yaml`_.\n> -\n> -.. _controls framework: https://libcamera.org/api-html/controls_8h.html\n> -.. _control_ids_core.yaml: https://libcamera.org/api-html/control__ids_8h.html\n> -.. _property_ids_core.yaml: https://libcamera.org/api-html/property__ids_8h.html\n> +defined by the :doxy-int:`src/libcamera/control_ids_core.yaml <control_ids.h>`\n> +file and camera properties are defined by\n> +:doxy-int:`src/libcamera/property_ids_core.yaml <property_ids.h>`.\n> \n>  Pipeline handlers can optionally register the list of controls an application\n>  can set as well as a list of immutable camera properties. Being both\n>  Camera-specific values, they are represented in the ``Camera::Private`` base\n>  class, which provides two members for this purpose: the\n> -`Camera::Private::controlInfo_`_ and the `Camera::Private::properties_`_ fields.\n> -\n> -.. _Camera::Private::controlInfo_: https://libcamera.org/api-html/classlibcamera_1_1Camera_1_1Private.html#ab4e183eb4dabe929d1b2bbbb519b969f\n> -.. _Camera::Private::properties_: https://libcamera.org/api-html/classlibcamera_1_1Camera_1_1Private.html#ad31f12f5ed9c1fbe25750902f4791064\n> +:doxy-int:`Camera::Private::controlInfo_` and the\n> +:doxy-int:`Camera::Private::properties_` fields.\n> \n>  The ``controlInfo_`` field represents a map of ``ControlId`` instances\n>  associated with the limits of valid values supported for the control. More\n> -information can be found in the `ControlInfoMap`_ class documentation.\n> -\n> -.. _ControlInfoMap: https://libcamera.org/api-html/classlibcamera_1_1ControlInfoMap.html\n> +information can be found in the :doxy-int:`ControlInfoMap` class documentation.\n> \n>  Pipeline handlers register controls to expose the tunable device and IPA\n>  parameters to applications. Our example pipeline handler only exposes trivial\n> @@ -753,10 +727,8 @@ This configuration and validation process is managed with another Pipeline\n>  specific class derived from a common base implementation and interface.\n> \n>  To support validation in our example pipeline handler, Create a new class called\n> -``VividCameraConfiguration`` derived from the base `CameraConfiguration`_ class\n> -which we can implement and use within our ``PipelineHandlerVivid`` class.\n> -\n> -.. _CameraConfiguration: https://libcamera.org/api-html/classlibcamera_1_1CameraConfiguration.html\n> +``VividCameraConfiguration`` derived from the base :doxy-int:`CameraConfiguration`\n> +class which we can implement and use within our ``PipelineHandlerVivid`` class.\n> \n>  The derived ``CameraConfiguration`` class must override the base class\n>  ``validate()`` function, where the stream configuration inspection and\n> @@ -778,20 +750,16 @@ adjustment happens.\n>      }\n> \n>  Applications generate a ``CameraConfiguration`` instance by calling the\n> -`Camera::generateConfiguration()`_ function, which calls into the pipeline\n> -implementation of the overridden `PipelineHandler::generateConfiguration()`_\n> -function.\n> -\n> -.. _Camera::generateConfiguration(): https://libcamera.org/api-html/classlibcamera_1_1Camera.html#a25c80eb7fc9b1cf32692ce0c7f09991d\n> -.. _PipelineHandler::generateConfiguration(): https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#a7932e87735695500ce1f8c7ae449b65b\n> +:doxy-int:`Camera::generateConfiguration` function, which calls into the\n> +pipeline implementation of the overridden\n> +:doxy-int:`PipelineHandler::generateConfiguration` function.\n> \n>  Configurations are generated by receiving a list of ``StreamRole`` instances,\n>  which libcamera uses as predefined ways an application intends to use a camera\n> -(You can read the full list in the `StreamRole API`_ documentation). These are\n> -optional hints on how an application intends to use a stream, and a pipeline\n> -handler should return an ideal configuration for each role that is requested.\n> -\n> -.. _StreamRole API: https://libcamera.org/api-html/stream_8h.html#file_a295d1f5e7828d95c0b0aabc0a8baac03\n> +(You can read the full list in the :doxy-int:`StreamRole` API documentation).\n> +These are optional hints on how an application intends to use a stream, and a\n> +pipeline handler should return an ideal configuration for each role that is\n> +requested.\n> \n>  In the pipeline handler ``generateConfiguration`` implementation, remove the\n>  ``return nullptr;``, create a new instance of the ``CameraConfiguration``\n> @@ -844,11 +812,9 @@ implementation.\n>                     deviceFormats.try_emplace(pixelFormat, std::move(sizes));\n>     }\n> \n> -The `StreamFormats`_ class holds information about the pixel formats and frame\n> -sizes that a stream can support. The class groups size information by the pixel\n> -format, which can produce it.\n> -\n> -.. _StreamFormats: https://libcamera.org/api-html/classlibcamera_1_1StreamFormats.html\n> +The :doxy-int:`StreamFormats` class holds information about the pixel formats\n> +and frame sizes that a stream can support. The class groups size information by\n> +the pixel format, which can produce it.\n> \n>  The code below uses the ``StreamFormats`` class to represent all of the\n>  supported pixel formats, associated with a list of frame sizes. It then\n> @@ -893,16 +859,14 @@ Add the following code to complete the implementation of\n>     return config;\n> \n>  To validate a camera configuration, a pipeline handler must implement the\n> -`CameraConfiguration::validate()`_ function in its derived class to inspect all\n> -the stream configuration associated to it, make any adjustments required to make\n> -the configuration valid, and return the validation status.\n> +:doxy-int:`CameraConfiguration::validate` function in its derived class to\n> +inspect all the stream configuration associated to it, make any adjustments\n> +required to make the configuration valid, and return the validation status.\n> \n>  If changes are made, it marks the configuration as ``Adjusted``, however if the\n>  requested configuration is not supported and cannot be adjusted it shall be\n>  refused and marked as ``Invalid``.\n> \n> -.. _CameraConfiguration::validate(): https://libcamera.org/api-html/classlibcamera_1_1CameraConfiguration.html#a29f8f263384c6149775b6011c7397093\n> -\n>  The validation phase makes sure all the platform-specific constraints are\n>  respected by the requested configuration. The most trivial examples being making\n>  sure the requested image formats are supported and the image alignment\n> @@ -996,13 +960,10 @@ With the configuration generated, and optionally modified and re-validated, a\n>  pipeline handler needs a function that allows an application to apply a\n>  configuration to the hardware devices.\n> \n> -The `PipelineHandler::configure()`_ function receives a valid\n> -`CameraConfiguration`_ and applies the settings to hardware devices, using its\n> -parameters to prepare a device for a streaming session with the desired\n> -properties.\n> -\n> -.. _PipelineHandler::configure(): https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#a930f2a9cdfb51dfb4b9ca3824e84fc29\n> -.. _CameraConfiguration: https://libcamera.org/api-html/classlibcamera_1_1CameraConfiguration.html\n> +The :doxy-int:`PipelineHandler::configure` function receives a valid\n> +:doxy-int:`CameraConfiguration` and applies the settings to hardware devices,\n> +using its parameters to prepare a device for a streaming session with the\n> +desired properties.\n> \n>  Replace the contents of the stubbed ``PipelineHandlerVivid::configure`` function\n>  with the following to obtain the camera data and stream configuration. This\n> @@ -1017,16 +978,14 @@ system accordingly.\n>     StreamConfiguration &cfg = config->at(0);\n>     int ret;\n> \n> -The Vivid capture device is a V4L2 video device, so we use a `V4L2DeviceFormat`_\n> -with the fourcc and size attributes to apply directly to the capture device\n> -node. The fourcc attribute is a `V4L2PixelFormat`_ and differs from the\n> -``libcamera::PixelFormat``. Converting the format requires knowledge of the\n> -plane configuration for multiplanar formats, so you must explicitly convert it\n> -using the helper ``V4L2VideoDevice::toV4L2PixelFormat()`` provided by the\n> -V4L2VideoDevice instance that the format will be applied on.\n> -\n> -.. _V4L2DeviceFormat: https://libcamera.org/api-html/classlibcamera_1_1V4L2DeviceFormat.html\n> -.. _V4L2PixelFormat: https://libcamera.org/api-html/classlibcamera_1_1V4L2PixelFormat.html\n> +The Vivid capture device is a V4L2 video device, so we use a\n> +:doxy-int:`V4L2DeviceFormat` with the fourcc and size attributes to apply\n> +directly to the capture device node. The fourcc attribute is a\n> +:doxy-int:`V4L2PixelFormat` and differs from the ``libcamera::PixelFormat``.\n> +Converting the format requires knowledge of the plane configuration for\n> +multiplanar formats, so you must explicitly convert it using the helper\n> +``V4L2VideoDevice::toV4L2PixelFormat()`` provided by the V4L2VideoDevice\n> +instance that the format will be applied on.\n> \n>  Add the following code beneath the code from above:\n> \n> @@ -1037,12 +996,10 @@ Add the following code beneath the code from above:\n>     format.size = cfg.size;\n> \n>  Set the video device format defined above using the\n> -`V4L2VideoDevice::setFormat()`_ function. You should check if the kernel\n> -driver has adjusted the format, as this shows the pipeline handler has failed to\n> -handle the validation stages correctly, and the configure operation shall also\n> -fail.\n> -\n> -.. _V4L2VideoDevice::setFormat(): https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#ad67b47dd9327ce5df43350b80c083cca\n> +:doxy-int:`V4L2VideoDevice::setFormat` function. You should check if the kernel\n> +driver has adjusted the format, as this shows the pipeline handler has failed\n> +to handle the validation stages correctly, and the configure operation shall\n> +also fail.\n> \n>  Continue the implementation with the following code:\n> \n> @@ -1058,10 +1015,8 @@ Continue the implementation with the following code:\n> \n>  Finally, store and set stream-specific data reflecting the state of the stream.\n>  Associate the configuration with the stream by using the\n> -`StreamConfiguration::setStream`_ function, and set the values of individual\n> -stream configuration members as required.\n> -\n> -.. _StreamConfiguration::setStream: https://libcamera.org/api-html/structlibcamera_1_1StreamConfiguration.html#a74a0eb44dad1b00112c7c0443ae54a12\n> +:doxy-int:`StreamConfiguration::setStream` function, and set the values of\n> +individual stream configuration members as required.\n> \n>  .. NOTE: the cfg.setStream() call here associates the stream to the\n>     StreamConfiguration however that should quite likely be done as part of\n> @@ -1084,9 +1039,7 @@ Initializing device controls\n>  Pipeline handlers can optionally initialize the video devices and camera sensor\n>  controls at system configuration time, to make sure they are defaulted to sane\n>  values. Handling of device controls is again performed using the libcamera\n> -`controls framework`_.\n> -\n> -.. _Controls Framework: https://libcamera.org/api-html/controls_8h.html\n> +:doxy-int:`controls framework <controls.h>`.\n> \n>  This section is particularly specific to Vivid as it sets the initial values of\n>  controls to match `Vivid Controls`_ defined by the kernel driver. You won't need\n> @@ -1107,10 +1060,8 @@ come directly from the kernel sources:\n>     #define VIVID_CID_HOR_MOVEMENT          (VIVID_CID_VIVID_BASE  + 2)\n> \n>  We can now use the V4L2 control IDs to prepare a list of controls with the\n> -`ControlList`_ class, and set them using the `ControlList::set()`_ function.\n> -\n> -.. _ControlList: https://libcamera.org/api-html/classlibcamera_1_1ControlList.html\n> -.. _ControlList::set(): https://libcamera.org/api-html/classlibcamera_1_1ControlList.html#a74a1a29abff5243e6e37ace8e24eb4ba\n> +:doxy-int:`ControlList` class, and set them using the :doxy-int:`ControlList::set`\n> +function.\n> \n>  In our pipeline ``configure`` function, add the following code after the format\n>  has been set and checked to initialise the ControlList and apply it to the\n> @@ -1161,28 +1112,22 @@ provide application facing streams always act as memory importers which use,\n>  in V4L2 terminology, buffers of V4L2_MEMORY_DMABUF memory type.\n> \n>  libcamera also provides an API to allocate and export memory to applications\n> -realized through the `exportFrameBuffers`_ function and the\n> -`FrameBufferAllocator`_ class which will be presented later.\n> -\n> -.. _exportFrameBuffers: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#a6312a69da7129c2ed41f9d9f790adf7c\n> -.. _FrameBufferAllocator: https://libcamera.org/api-html/classlibcamera_1_1FrameBufferAllocator.html\n> +realized through the :doxy-int:`PipelineHandler::exportFrameBuffers` function\n> +and the :doxy-int:`FrameBufferAllocator` class which will be presented later.\n> \n>  Please refer to the V4L2VideoDevice API documentation, specifically the\n> -`allocateBuffers`_, `importBuffers`_ and `exportBuffers`_ functions for a\n> +:doxy-int:`allocateBuffers <V4L2VideoDevice::allocateBuffers>`,\n> +:doxy-int:`importBuffers <V4L2VideoDevice::importBuffers>` and\n> +:doxy-int:`exportBuffers <V4L2VideoDevice::exportBuffers>` functions for a\n>  detailed description of the video device memory management.\n> \n> -.. _allocateBuffers: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a3a1a77e5e6c220ea7878e89485864a1c\n> -.. _importBuffers: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a154f5283d16ebd5e15d63e212745cb64\n> -.. _exportBuffers: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#ae9c0b0a68f350725b63b73a6da5a2ecd\n> -\n> -Video memory buffers are represented in libcamera by the `FrameBuffer`_ class.\n> -A ``FrameBuffer`` instance has to be associated to each ``Stream`` which is part\n> -of a capture ``Request``. Pipeline handlers should prepare the capture devices\n> -by importing the dma-buf file descriptors it needs to operate on. This operation\n> -is performed by using the ``V4L2VideoDevice`` API, which provides an\n> -``importBuffers()`` function that prepares the video device accordingly.\n> -\n> -.. _FrameBuffer: https://libcamera.org/api-html/classlibcamera_1_1FrameBuffer.html\n> +Video memory buffers are represented in libcamera by the\n> +:doxy-int:`FrameBuffer` class.  A ``FrameBuffer`` instance has to be associated\n> +to each ``Stream`` which is part of a capture ``Request``. Pipeline handlers\n> +should prepare the capture devices by importing the dma-buf file descriptors it\n> +needs to operate on. This operation is performed by using the\n> +``V4L2VideoDevice`` API, which provides an ``importBuffers()`` function that\n> +prepares the video device accordingly.\n> \n>  Implement the pipeline handler ``start()`` function by replacing the stub\n>  version with the following code:\n> @@ -1206,20 +1151,17 @@ complex pipeline handlers in the libcamera code base.\n> \n>  Applications might want to use memory allocated in the video devices instead of\n>  allocating it from other parts of the system. libcamera provides an abstraction\n> -to assist with this task in the `FrameBufferAllocator`_ class. The\n> +to assist with this task in the :doxy-int:`FrameBufferAllocator` class. The\n>  ``FrameBufferAllocator`` reserves memory for a ``Stream`` in the video device\n>  and exports it as dma-buf file descriptors. From this point on, the allocated\n>  ``FrameBuffer`` are associated to ``Stream`` instances in a ``Request`` and then\n>  imported by the pipeline hander in exactly the same fashion as if they were\n>  allocated elsewhere.\n> \n> -.. _FrameBufferAllocator: https://libcamera.org/api-html/classlibcamera_1_1FrameBufferAllocator.html\n> -\n>  Pipeline handlers support the ``FrameBufferAllocator`` operations by\n> -implementing the `exportFrameBuffers`_ function, which will allocate memory in\n> -the video device associated with a stream and export it.\n> -\n> -.. _exportFrameBuffers: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#a6312a69da7129c2ed41f9d9f790adf7c\n> +implementing the :doxy-int:`PipelineHandler::exportFrameBuffers` function,\n> +which will allocate memory in the video device associated with a stream and\n> +export it.\n> \n>  Implement the ``exportFrameBuffers`` stub function with the following code to\n>  handle this:\n> @@ -1246,19 +1188,16 @@ with the following code:\n>     return 0;\n> \n>  The function starts the video device associated with the stream with the\n> -`streamOn`_ function. If the call fails, the error value is propagated to the\n> -caller and the `releaseBuffers`_ function releases any buffers to leave the\n> -device in a consistent state. If your pipeline handler uses any image processing\n> -algorithms, or other devices you should also stop them.\n> -\n> -.. _streamOn: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a588a5dc9d6f4c54c61136ac43ff9a8cc\n> -.. _releaseBuffers: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a191619c152f764e03bc461611f3fcd35\n> +:doxy-int:`V4L2VideoDevice::streamOn` function. If the call fails, the error\n> +value is propagated to the caller and the\n> +:doxy-int:`V4L2VideoDevice::releaseBuffers` function releases any buffers to\n> +leave the device in a consistent state. If your pipeline handler uses any image\n> +processing algorithms, or other devices you should also stop them.\n> \n>  Of course we also need to handle the corresponding actions to stop streaming on\n>  a device, Add the following to the ``stopDevice()`` function, to stop the\n> -stream with the `streamOff`_ function and release all buffers.\n> -\n> -.. _streamOff: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a61998710615bdf7aa25a046c8565ed66\n> +stream with the :doxy-int:`V4L2VideoDevice::streamOff` function and release\n> +all buffers.\n> \n>  .. code-block:: cpp\n> \n> @@ -1277,12 +1216,11 @@ When an application sends a capture request, the pipeline handler identifies\n>  which video devices have to be provided with buffers to generate a frame from\n>  the enabled streams.\n> \n> -This example pipeline handler identifies the buffer using the `findBuffer`_\n> -helper from the only supported stream and queues it to the capture device\n> -directly with the `queueBuffer`_ function provided by the V4L2VideoDevice.\n> -\n> -.. _findBuffer: https://libcamera.org/api-html/classlibcamera_1_1Request.html#ac66050aeb9b92c64218945158559c4d4\n> -.. _queueBuffer: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a594cd594686a8c1cf9ae8dba0b2a8a75\n> +This example pipeline handler identifies the buffer using the\n> +:doxy-int:`Request::findBuffer` helper from the only supported stream and\n> +queues it to the capture device directly with the\n> +:doxy-int:`V4L2VideoDevice::queueBuffer` function provided by the\n> +V4L2VideoDevice.\n> \n>  Replace the stubbed contents of ``queueRequestDevice`` with the following:\n> \n> @@ -1377,11 +1315,9 @@ where appropriate by setting controls on V4L2Subdevices directly. Each pipeline\n>  handler is responsible for understanding the correct procedure for applying\n>  controls to the device they support.\n> \n> -This example pipeline handler applies controls during the `queueRequestDevice`_\n> -function for each request, and applies them to the capture device through the\n> -capture node.\n> -\n> -.. _queueRequestDevice: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#a106914cca210640c9da9ee1f0419e83c\n> +This example pipeline handler applies controls during the\n> +:doxy-int:`PipelineHandler::queueRequestDevice` function for each request, and\n> +applies them to the capture device through the capture node.\n> \n>  In the ``queueRequestDevice`` function, replace the following:\n> \n> @@ -1418,11 +1354,10 @@ Slots`_) to connect event sources with callbacks to handle them.\n> \n>  As a general summary, a ``Slot`` can be connected to a ``Signal``, which when\n>  emitted triggers the execution of the connected slots.  A detailed description\n> -of the libcamera implementation is available in the `libcamera Signal and Slot`_\n> -classes documentation.\n> +of the libcamera implementation is available in the :doxy-int:`libcamera Signal\n> +and Slot <Signal>` classes documentation.\n> \n>  .. _Qt Signals and Slots: https://doc.qt.io/qt-6/signalsandslots.html\n> -.. _libcamera Signal and Slot: https://libcamera.org/api-html/classlibcamera_1_1Signal.html#details\n> \n>  In order to notify applications about the availability of new frames and data,\n>  the ``Camera`` device exposes two ``Signals`` to which applications can connect\n> @@ -1438,18 +1373,17 @@ The ``bufferComplete`` and ``requestComplete`` signals are emitted by the\n>  ``Camera`` device upon notifications received from the pipeline handler, which\n>  tracks the buffers and request completion status.\n> \n> -The single buffer completion notification is implemented by pipeline handlers by\n> -`connecting`_ the ``bufferReady`` signal of the capture devices they have queued\n> -buffers to, to a member function slot that handles processing of the completed\n> -frames. When a buffer is ready, the pipeline handler must propagate the\n> -completion of that buffer to the Camera by using the PipelineHandler base class\n> -``completeBuffer`` function. When all of the buffers referenced by a ``Request``\n> -have been completed, the pipeline handler must again notify the ``Camera`` using\n> -the PipelineHandler base class ``completeRequest`` function. The PipelineHandler\n> -class implementation makes sure the request completion notifications are\n> -delivered to applications in the same order as they have been submitted.\n> -\n> -.. _connecting: https://libcamera.org/api-html/classlibcamera_1_1Signal.html#aa04db72d5b3091ffbb4920565aeed382\n> +The single buffer completion notification is implemented by pipeline handlers\n> +by :doxy-int:`connecting <Signal::connect>` the ``bufferReady`` signal of the\n> +capture devices they have queued buffers to, to a member function slot that\n> +handles processing of the completed frames. When a buffer is ready, the\n> +pipeline handler must propagate the completion of that buffer to the Camera by\n> +using the PipelineHandler base class ``completeBuffer`` function. When all of\n> +the buffers referenced by a ``Request`` have been completed, the pipeline\n> +handler must again notify the ``Camera`` using the PipelineHandler base class\n> +``completeRequest`` function. The PipelineHandler class implementation makes\n> +sure the request completion notifications are delivered to applications in the\n> +same order as they have been submitted.\n> \n>  Returning to the ``int VividCameraData::init()`` function, add the following\n>  above the closing ``return 0;`` to connect the pipeline handler ``bufferReady``\n> diff --git a/Documentation/libcamera_architecture.rst b/Documentation/libcamera_architecture.rst\n> index abbb0d178cd8..d2bd13e1dc39 100644\n> --- a/Documentation/libcamera_architecture.rst\n> +++ b/Documentation/libcamera_architecture.rst\n> @@ -68,9 +68,7 @@ Camera Manager\n>    Each application's instance of the Camera Manager ensures that only a single\n>    application can take control of a camera device at once.\n> \n> -  Read the `Camera Manager API`_ documentation for more details.\n> -\n> -.. _Camera Manager API: https://libcamera.org/api-html/classlibcamera_1_1CameraManager.html\n> +  Read the :doxy-pub:`CameraManager` API documentation for more details.\n> \n>  Camera Device\n>    The Camera class represents a single item of camera hardware that is capable\n> @@ -85,9 +83,7 @@ Camera Device\n>    object that all other API operations interact with from configuration to\n>    capture.\n> \n> -  Read the `Camera API`_ documentation for more details.\n> -\n> -.. _Camera API: https://libcamera.org/api-html/classlibcamera_1_1Camera.html\n> +  Read the :doxy-pub:`Camera` API documentation for more details.\n> \n>  Pipeline Handler\n>    The Pipeline Handler manages the complex pipelines exposed by the kernel\n> @@ -107,11 +103,10 @@ Pipeline Handler\n>    they detect and support on the running system, and are responsible for\n>    managing the interactions with a camera device.\n> \n> -  More details can be found in the `PipelineHandler API`_ documentation, and the\n> +  More details can be found in the :doxy-int:`PipelineHandler` API\n> +  documentation, and the\n>    :doc:`Pipeline Handler Writers Guide <guides/pipeline-handler>`.\n> \n> -.. _PipelineHandler API: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html\n> -\n>  Image Processing Algorithms\n>    Together with the hardware image processing and hardware statistics\n>    collection, the Image Processing Algorithms (IPA) implement 3A (Auto-Exposure,\n> --\n> Regards,\n> \n> Laurent Pinchart\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 8EEC5BDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 30 Jul 2025 13:56:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AAF2E69203;\n\tWed, 30 Jul 2025 15:56:00 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D8C86691F8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 30 Jul 2025 15:55:58 +0200 (CEST)","from ideasonboard.com\n\t(p200300f89f4c84ba5ae71567ef55a21c.dip0.t-ipconnect.de\n\t[IPv6:2003:f8:9f4c:84ba:5ae7:1567:ef55:a21c])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 5D44B240A; \n\tWed, 30 Jul 2025 15:55:15 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Bszry2kN\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753883715;\n\tbh=+LwzeSjxtyKMggVNO5euTZSx+bypBQEt7NglzBn0VFo=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=Bszry2kNGaSeLo9bzEThPaSbyxkUa8jtatHkZB/zkRnCWFEdK/aJ6ba2IKXUqhY6U\n\todkNDWD42dx773r6g2F9mO79T1lQaIvGvHtJ6NY3xwG2P6m0L/a4RlVyKBog9n4pYm\n\tNidM88WXQKblNtSwjylTGlnsmhr9aLruPxeqqM48=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250730134648.19936-1-laurent.pinchart@ideasonboard.com>","References":"<20250730115045.3481-1-laurent.pinchart@ideasonboard.com>\n\t<20250730134648.19936-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [PATCH v3 4/3] Documentation: Replace links to Doxygen\n\tdocumentation with doxylink","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Wed, 30 Jul 2025 15:55:56 +0200","Message-ID":"<175388375635.371358.17636377935124555395@localhost>","User-Agent":"alot/0.12.dev8+g2c003385c862.d20250602","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>"}}]