[libcamera-devel] [PATCH v2 05/13] libcamera: ipu3: imgu: Move the ImgUDevice class to separate files
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sun Jun 28 08:59:11 CEST 2020
Hi Niklas,
Thank you for the patch.
On Sun, Jun 28, 2020 at 02:15:24AM +0200, Niklas Söderlund wrote:
> In preparation of refactoring the IPU3 pipeline handler breakout the
> ImgUDevice into its own .cpp and .h file, no functional change.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
> ---
> * Changes since v1
> - Remove stray newline
> ---
> src/libcamera/pipeline/ipu3/imgu.cpp | 355 +++++++++++++++++++++
> src/libcamera/pipeline/ipu3/imgu.h | 86 +++++
> src/libcamera/pipeline/ipu3/ipu3.cpp | 404 +-----------------------
> src/libcamera/pipeline/ipu3/meson.build | 1 +
> 4 files changed, 443 insertions(+), 403 deletions(-)
> create mode 100644 src/libcamera/pipeline/ipu3/imgu.cpp
> create mode 100644 src/libcamera/pipeline/ipu3/imgu.h
>
> diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp
> new file mode 100644
> index 0000000000000000..8965a51c5d26f8ae
> --- /dev/null
> +++ b/src/libcamera/pipeline/ipu3/imgu.cpp
> @@ -0,0 +1,355 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * imgu.cpp - Intel IPU3 ImgU
> + */
> +
> +#include "imgu.h"
> +
> +#include <linux/media-bus-format.h>
> +
> +#include <libcamera/formats.h>
> +#include <libcamera/stream.h>
> +
> +#include "libcamera/internal/log.h"
> +#include "libcamera/internal/media_device.h"
> +
> +namespace libcamera {
> +
> +LOG_DECLARE_CATEGORY(IPU3)
> +
> +/**
> + * \brief Initialize components of the ImgU instance
> + * \param[in] mediaDevice The ImgU instance media device
> + * \param[in] index The ImgU instance index
> + *
> + * Create and open the V4L2 devices and subdevices of the ImgU instance
> + * with \a index.
> + *
> + * In case of errors the created V4L2VideoDevice and V4L2Subdevice instances
> + * are destroyed at pipeline handler delete time.
> + *
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::init(MediaDevice *media, unsigned int index)
> +{
> + int ret;
> +
> + index_ = index;
> + name_ = "ipu3-imgu " + std::to_string(index_);
> + media_ = media;
> +
> + /*
> + * The media entities presence in the media device has been verified
> + * by the match() function: no need to check for newly created
> + * video devices and subdevice validity here.
> + */
> + imgu_ = V4L2Subdevice::fromEntityName(media, name_);
> + ret = imgu_->open();
> + if (ret)
> + return ret;
> +
> + input_ = V4L2VideoDevice::fromEntityName(media, name_ + " input");
> + ret = input_->open();
> + if (ret)
> + return ret;
> +
> + output_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " output");
> + ret = output_.dev->open();
> + if (ret)
> + return ret;
> +
> + output_.pad = PAD_OUTPUT;
> + output_.name = "output";
> +
> + viewfinder_.dev = V4L2VideoDevice::fromEntityName(media,
> + name_ + " viewfinder");
> + ret = viewfinder_.dev->open();
> + if (ret)
> + return ret;
> +
> + viewfinder_.pad = PAD_VF;
> + viewfinder_.name = "viewfinder";
> +
> + stat_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " 3a stat");
> + ret = stat_.dev->open();
> + if (ret)
> + return ret;
> +
> + stat_.pad = PAD_STAT;
> + stat_.name = "stat";
> +
> + return 0;
> +}
> +
> +/**
> + * \brief Configure the ImgU unit input
> + * \param[in] size The ImgU input frame size
> + * \param[in] inputFormat The format to be applied to ImgU input
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::configureInput(const Size &size,
> + V4L2DeviceFormat *inputFormat)
> +{
> + /* Configure the ImgU input video device with the requested sizes. */
> + int ret = input_->setFormat(inputFormat);
> + if (ret)
> + return ret;
> +
> + LOG(IPU3, Debug) << "ImgU input format = " << inputFormat->toString();
> +
> + /*
> + * \todo The IPU3 driver implementation shall be changed to use the
> + * input sizes as 'ImgU Input' subdevice sizes, and use the desired
> + * GDC output sizes to configure the crop/compose rectangles.
> + *
> + * The current IPU3 driver implementation uses GDC sizes as the
> + * 'ImgU Input' subdevice sizes, and the input video device sizes
> + * to configure the crop/compose rectangles, contradicting the
> + * V4L2 specification.
> + */
> + Rectangle rect = {
> + .x = 0,
> + .y = 0,
> + .width = inputFormat->size.width,
> + .height = inputFormat->size.height,
> + };
> + ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_CROP, &rect);
> + if (ret)
> + return ret;
> +
> + ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_COMPOSE, &rect);
> + if (ret)
> + return ret;
> +
> + LOG(IPU3, Debug) << "ImgU input feeder and BDS rectangle = "
> + << rect.toString();
> +
> + V4L2SubdeviceFormat imguFormat = {};
> + imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> + imguFormat.size = size;
> +
> + ret = imgu_->setFormat(PAD_INPUT, &imguFormat);
> + if (ret)
> + return ret;
> +
> + LOG(IPU3, Debug) << "ImgU GDC format = " << imguFormat.toString();
> +
> + return 0;
> +}
> +
> +/**
> + * \brief Configure the ImgU unit \a id video output
> + * \param[in] output The ImgU output device to configure
> + * \param[in] cfg The requested configuration
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::configureOutput(ImgUOutput *output,
> + const StreamConfiguration &cfg,
> + V4L2DeviceFormat *outputFormat)
> +{
> + V4L2VideoDevice *dev = output->dev;
> + unsigned int pad = output->pad;
> +
> + V4L2SubdeviceFormat imguFormat = {};
> + imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> + imguFormat.size = cfg.size;
> +
> + int ret = imgu_->setFormat(pad, &imguFormat);
> + if (ret)
> + return ret;
> +
> + /* No need to apply format to the stat node. */
> + if (output == &stat_)
> + return 0;
> +
> + *outputFormat = {};
> + outputFormat->fourcc = dev->toV4L2PixelFormat(formats::NV12);
> + outputFormat->size = cfg.size;
> + outputFormat->planesCount = 2;
> +
> + ret = dev->setFormat(outputFormat);
> + if (ret)
> + return ret;
> +
> + LOG(IPU3, Debug) << "ImgU " << output->name << " format = "
> + << outputFormat->toString();
> +
> + return 0;
> +}
> +
> +/**
> + * \brief Allocate buffers for all the ImgU video devices
> + */
> +int ImgUDevice::allocateBuffers(unsigned int bufferCount)
> +{
> + /* Share buffers between CIO2 output and ImgU input. */
> + int ret = input_->importBuffers(bufferCount);
> + if (ret) {
> + LOG(IPU3, Error) << "Failed to import ImgU input buffers";
> + return ret;
> + }
> +
> + /*
> + * The kernel fails to start if buffers are not either imported or
> + * allocated for the statisitcs video device. As statistics buffers are
> + * not yet used by the pipeline import buffers to save memory.
> + *
> + * \todo To be revised when we'll actually use the stat node.
> + */
> + ret = stat_.dev->importBuffers(bufferCount);
> + if (ret < 0) {
> + LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers";
> + goto error;
> + }
> +
> + /*
> + * Import buffers for all outputs, regardless of whether the
> + * corresponding stream is active or inactive, as the driver needs
> + * buffers to be requested on the V4L2 devices in order to operate.
> + */
> + ret = output_.dev->importBuffers(bufferCount);
> + if (ret < 0) {
> + LOG(IPU3, Error) << "Failed to import ImgU output buffers";
> + goto error;
> + }
> +
> + ret = viewfinder_.dev->importBuffers(bufferCount);
> + if (ret < 0) {
> + LOG(IPU3, Error) << "Failed to import ImgU viewfinder buffers";
> + goto error;
> + }
> +
> + return 0;
> +
> +error:
> + freeBuffers();
> +
> + return ret;
> +}
> +
> +/**
> + * \brief Release buffers for all the ImgU video devices
> + */
> +void ImgUDevice::freeBuffers()
> +{
> + int ret;
> +
> + ret = output_.dev->releaseBuffers();
> + if (ret)
> + LOG(IPU3, Error) << "Failed to release ImgU output buffers";
> +
> + ret = stat_.dev->releaseBuffers();
> + if (ret)
> + LOG(IPU3, Error) << "Failed to release ImgU stat buffers";
> +
> + ret = viewfinder_.dev->releaseBuffers();
> + if (ret)
> + LOG(IPU3, Error) << "Failed to release ImgU viewfinder buffers";
> +
> + ret = input_->releaseBuffers();
> + if (ret)
> + LOG(IPU3, Error) << "Failed to release ImgU input buffers";
> +}
> +
> +int ImgUDevice::start()
> +{
> + int ret;
> +
> + /* Start the ImgU video devices. */
> + ret = output_.dev->streamOn();
> + if (ret) {
> + LOG(IPU3, Error) << "Failed to start ImgU output";
> + return ret;
> + }
> +
> + ret = viewfinder_.dev->streamOn();
> + if (ret) {
> + LOG(IPU3, Error) << "Failed to start ImgU viewfinder";
> + return ret;
> + }
> +
> + ret = stat_.dev->streamOn();
> + if (ret) {
> + LOG(IPU3, Error) << "Failed to start ImgU stat";
> + return ret;
> + }
> +
> + ret = input_->streamOn();
> + if (ret) {
> + LOG(IPU3, Error) << "Failed to start ImgU input";
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +int ImgUDevice::stop()
> +{
> + int ret;
> +
> + ret = output_.dev->streamOff();
> + ret |= viewfinder_.dev->streamOff();
> + ret |= stat_.dev->streamOff();
> + ret |= input_->streamOff();
> +
> + return ret;
> +}
> +
> +/**
> + * \brief Enable or disable a single link on the ImgU instance
> + *
> + * This method assumes the media device associated with the ImgU instance
> + * is open.
> + *
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::linkSetup(const std::string &source, unsigned int sourcePad,
> + const std::string &sink, unsigned int sinkPad,
> + bool enable)
> +{
> + MediaLink *link = media_->link(source, sourcePad, sink, sinkPad);
> + if (!link) {
> + LOG(IPU3, Error)
> + << "Failed to get link: '" << source << "':"
> + << sourcePad << " -> '" << sink << "':" << sinkPad;
> + return -ENODEV;
> + }
> +
> + return link->setEnabled(enable);
> +}
> +
> +/**
> + * \brief Enable or disable all media links in the ImgU instance to prepare
> + * for capture operations
> + *
> + * \todo This method will probably be removed or changed once links will be
> + * enabled or disabled selectively.
> + *
> + * \return 0 on success or a negative error code otherwise
> + */
> +int ImgUDevice::enableLinks(bool enable)
> +{
> + std::string viewfinderName = name_ + " viewfinder";
> + std::string outputName = name_ + " output";
> + std::string statName = name_ + " 3a stat";
> + std::string inputName = name_ + " input";
> + int ret;
> +
> + ret = linkSetup(inputName, 0, name_, PAD_INPUT, enable);
> + if (ret)
> + return ret;
> +
> + ret = linkSetup(name_, PAD_OUTPUT, outputName, 0, enable);
> + if (ret)
> + return ret;
> +
> + ret = linkSetup(name_, PAD_VF, viewfinderName, 0, enable);
> + if (ret)
> + return ret;
> +
> + return linkSetup(name_, PAD_STAT, statName, 0, enable);
> +}
> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h
> new file mode 100644
> index 0000000000000000..9bb1b88e2ca8ea2d
> --- /dev/null
> +++ b/src/libcamera/pipeline/ipu3/imgu.h
> @@ -0,0 +1,86 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * imgu.h - Intel IPU3 ImgU
> + */
> +#ifndef __LIBCAMERA_PIPELINE_IPU3_IMGU_H__
> +#define __LIBCAMERA_PIPELINE_IPU3_IMGU_H__
> +
> +#include <memory>
> +#include <string>
> +#include <vector>
I think memory and vector are not needed here (don't forget then to
include memory in patch 13/13).
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> +
> +#include "libcamera/internal/v4l2_subdevice.h"
> +#include "libcamera/internal/v4l2_videodevice.h"
> +
> +namespace libcamera {
> +
> +class FrameBuffer;
> +class MediaDevice;
> +struct Size;
> +struct StreamConfiguration;
> +
> +class ImgUDevice
> +{
> +public:
> + static constexpr unsigned int PAD_INPUT = 0;
> + static constexpr unsigned int PAD_OUTPUT = 2;
> + static constexpr unsigned int PAD_VF = 3;
> + static constexpr unsigned int PAD_STAT = 4;
> +
> + /* ImgU output descriptor: group data specific to an ImgU output. */
> + struct ImgUOutput {
> + V4L2VideoDevice *dev;
> + unsigned int pad;
> + std::string name;
> + };
> +
> + ImgUDevice()
> + : imgu_(nullptr), input_(nullptr)
> + {
> + output_.dev = nullptr;
> + viewfinder_.dev = nullptr;
> + stat_.dev = nullptr;
> + }
> +
> + ~ImgUDevice()
> + {
> + delete imgu_;
> + delete input_;
> + delete output_.dev;
> + delete viewfinder_.dev;
> + delete stat_.dev;
> + }
> +
> + int init(MediaDevice *media, unsigned int index);
> + int configureInput(const Size &size, V4L2DeviceFormat *inputFormat);
> + int configureOutput(ImgUOutput *output, const StreamConfiguration &cfg,
> + V4L2DeviceFormat *outputFormat);
> +
> + int allocateBuffers(unsigned int bufferCount);
> + void freeBuffers();
> +
> + int start();
> + int stop();
> +
> + int linkSetup(const std::string &source, unsigned int sourcePad,
> + const std::string &sink, unsigned int sinkPad,
> + bool enable);
> + int enableLinks(bool enable);
> +
> + unsigned int index_;
> + std::string name_;
> + MediaDevice *media_;
> +
> + V4L2Subdevice *imgu_;
> + V4L2VideoDevice *input_;
> + ImgUOutput output_;
> + ImgUOutput viewfinder_;
> + ImgUOutput stat_;
> + /* \todo Add param video device for 3A tuning */
> +};
> +
> +} /* namespace libcamera */
> +
> +#endif /* __LIBCAMERA_PIPELINE_IPU3_IMGU_H__ */
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index fd2725c7bd0c144b..b41a789e8dc2a7b2 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -11,8 +11,6 @@
> #include <queue>
> #include <vector>
>
> -#include <linux/media-bus-format.h>
> -
> #include <libcamera/camera.h>
> #include <libcamera/formats.h>
> #include <libcamera/request.h>
> @@ -25,77 +23,14 @@
> #include "libcamera/internal/pipeline_handler.h"
> #include "libcamera/internal/utils.h"
> #include "libcamera/internal/v4l2_controls.h"
> -#include "libcamera/internal/v4l2_subdevice.h"
> -#include "libcamera/internal/v4l2_videodevice.h"
>
> #include "cio2.h"
> +#include "imgu.h"
>
> namespace libcamera {
>
> LOG_DEFINE_CATEGORY(IPU3)
>
> -class ImgUDevice
> -{
> -public:
> - static constexpr unsigned int PAD_INPUT = 0;
> - static constexpr unsigned int PAD_OUTPUT = 2;
> - static constexpr unsigned int PAD_VF = 3;
> - static constexpr unsigned int PAD_STAT = 4;
> -
> - /* ImgU output descriptor: group data specific to an ImgU output. */
> - struct ImgUOutput {
> - V4L2VideoDevice *dev;
> - unsigned int pad;
> - std::string name;
> - };
> -
> - ImgUDevice()
> - : imgu_(nullptr), input_(nullptr)
> - {
> - output_.dev = nullptr;
> - viewfinder_.dev = nullptr;
> - stat_.dev = nullptr;
> - }
> -
> - ~ImgUDevice()
> - {
> - delete imgu_;
> - delete input_;
> - delete output_.dev;
> - delete viewfinder_.dev;
> - delete stat_.dev;
> - }
> -
> - int init(MediaDevice *media, unsigned int index);
> - int configureInput(const Size &size,
> - V4L2DeviceFormat *inputFormat);
> - int configureOutput(ImgUOutput *output,
> - const StreamConfiguration &cfg,
> - V4L2DeviceFormat *outputFormat);
> -
> - int allocateBuffers(unsigned int bufferCount);
> - void freeBuffers();
> -
> - int start();
> - int stop();
> -
> - int linkSetup(const std::string &source, unsigned int sourcePad,
> - const std::string &sink, unsigned int sinkPad,
> - bool enable);
> - int enableLinks(bool enable);
> -
> - unsigned int index_;
> - std::string name_;
> - MediaDevice *media_;
> -
> - V4L2Subdevice *imgu_;
> - V4L2VideoDevice *input_;
> - ImgUOutput output_;
> - ImgUOutput viewfinder_;
> - ImgUOutput stat_;
> - /* \todo Add param video device for 3A tuning */
> -};
> -
> class IPU3Stream : public Stream
> {
> public:
> @@ -952,343 +887,6 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
> imgu_->input_->queueBuffer(buffer);
> }
>
> -/* -----------------------------------------------------------------------------
> - * ImgU Device
> - */
> -
> -/**
> - * \brief Initialize components of the ImgU instance
> - * \param[in] mediaDevice The ImgU instance media device
> - * \param[in] index The ImgU instance index
> - *
> - * Create and open the V4L2 devices and subdevices of the ImgU instance
> - * with \a index.
> - *
> - * In case of errors the created V4L2VideoDevice and V4L2Subdevice instances
> - * are destroyed at pipeline handler delete time.
> - *
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::init(MediaDevice *media, unsigned int index)
> -{
> - int ret;
> -
> - index_ = index;
> - name_ = "ipu3-imgu " + std::to_string(index_);
> - media_ = media;
> -
> - /*
> - * The media entities presence in the media device has been verified
> - * by the match() function: no need to check for newly created
> - * video devices and subdevice validity here.
> - */
> - imgu_ = V4L2Subdevice::fromEntityName(media, name_);
> - ret = imgu_->open();
> - if (ret)
> - return ret;
> -
> - input_ = V4L2VideoDevice::fromEntityName(media, name_ + " input");
> - ret = input_->open();
> - if (ret)
> - return ret;
> -
> - output_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " output");
> - ret = output_.dev->open();
> - if (ret)
> - return ret;
> -
> - output_.pad = PAD_OUTPUT;
> - output_.name = "output";
> -
> - viewfinder_.dev = V4L2VideoDevice::fromEntityName(media,
> - name_ + " viewfinder");
> - ret = viewfinder_.dev->open();
> - if (ret)
> - return ret;
> -
> - viewfinder_.pad = PAD_VF;
> - viewfinder_.name = "viewfinder";
> -
> - stat_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " 3a stat");
> - ret = stat_.dev->open();
> - if (ret)
> - return ret;
> -
> - stat_.pad = PAD_STAT;
> - stat_.name = "stat";
> -
> - return 0;
> -}
> -
> -/**
> - * \brief Configure the ImgU unit input
> - * \param[in] size The ImgU input frame size
> - * \param[in] inputFormat The format to be applied to ImgU input
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::configureInput(const Size &size,
> - V4L2DeviceFormat *inputFormat)
> -{
> - /* Configure the ImgU input video device with the requested sizes. */
> - int ret = input_->setFormat(inputFormat);
> - if (ret)
> - return ret;
> -
> - LOG(IPU3, Debug) << "ImgU input format = " << inputFormat->toString();
> -
> - /*
> - * \todo The IPU3 driver implementation shall be changed to use the
> - * input sizes as 'ImgU Input' subdevice sizes, and use the desired
> - * GDC output sizes to configure the crop/compose rectangles.
> - *
> - * The current IPU3 driver implementation uses GDC sizes as the
> - * 'ImgU Input' subdevice sizes, and the input video device sizes
> - * to configure the crop/compose rectangles, contradicting the
> - * V4L2 specification.
> - */
> - Rectangle rect = {
> - .x = 0,
> - .y = 0,
> - .width = inputFormat->size.width,
> - .height = inputFormat->size.height,
> - };
> - ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_CROP, &rect);
> - if (ret)
> - return ret;
> -
> - ret = imgu_->setSelection(PAD_INPUT, V4L2_SEL_TGT_COMPOSE, &rect);
> - if (ret)
> - return ret;
> -
> - LOG(IPU3, Debug) << "ImgU input feeder and BDS rectangle = "
> - << rect.toString();
> -
> - V4L2SubdeviceFormat imguFormat = {};
> - imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> - imguFormat.size = size;
> -
> - ret = imgu_->setFormat(PAD_INPUT, &imguFormat);
> - if (ret)
> - return ret;
> -
> - LOG(IPU3, Debug) << "ImgU GDC format = " << imguFormat.toString();
> -
> - return 0;
> -}
> -
> -/**
> - * \brief Configure the ImgU unit \a id video output
> - * \param[in] output The ImgU output device to configure
> - * \param[in] cfg The requested configuration
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::configureOutput(ImgUOutput *output,
> - const StreamConfiguration &cfg,
> - V4L2DeviceFormat *outputFormat)
> -{
> - V4L2VideoDevice *dev = output->dev;
> - unsigned int pad = output->pad;
> -
> - V4L2SubdeviceFormat imguFormat = {};
> - imguFormat.mbus_code = MEDIA_BUS_FMT_FIXED;
> - imguFormat.size = cfg.size;
> -
> - int ret = imgu_->setFormat(pad, &imguFormat);
> - if (ret)
> - return ret;
> -
> - /* No need to apply format to the stat node. */
> - if (output == &stat_)
> - return 0;
> -
> - *outputFormat = {};
> - outputFormat->fourcc = dev->toV4L2PixelFormat(formats::NV12);
> - outputFormat->size = cfg.size;
> - outputFormat->planesCount = 2;
> -
> - ret = dev->setFormat(outputFormat);
> - if (ret)
> - return ret;
> -
> - LOG(IPU3, Debug) << "ImgU " << output->name << " format = "
> - << outputFormat->toString();
> -
> - return 0;
> -}
> -
> -/**
> - * \brief Allocate buffers for all the ImgU video devices
> - */
> -int ImgUDevice::allocateBuffers(unsigned int bufferCount)
> -{
> - /* Share buffers between CIO2 output and ImgU input. */
> - int ret = input_->importBuffers(bufferCount);
> - if (ret) {
> - LOG(IPU3, Error) << "Failed to import ImgU input buffers";
> - return ret;
> - }
> -
> - /*
> - * The kernel fails to start if buffers are not either imported or
> - * allocated for the statisitcs video device. As statistics buffers are
> - * not yet used by the pipeline import buffers to save memory.
> - *
> - * \todo To be revised when we'll actually use the stat node.
> - */
> - ret = stat_.dev->importBuffers(bufferCount);
> - if (ret < 0) {
> - LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers";
> - goto error;
> - }
> -
> - /*
> - * Import buffers for all outputs, regardless of whether the
> - * corresponding stream is active or inactive, as the driver needs
> - * buffers to be requested on the V4L2 devices in order to operate.
> - */
> - ret = output_.dev->importBuffers(bufferCount);
> - if (ret < 0) {
> - LOG(IPU3, Error) << "Failed to import ImgU output buffers";
> - goto error;
> - }
> -
> - ret = viewfinder_.dev->importBuffers(bufferCount);
> - if (ret < 0) {
> - LOG(IPU3, Error) << "Failed to import ImgU viewfinder buffers";
> - goto error;
> - }
> -
> - return 0;
> -
> -error:
> - freeBuffers();
> -
> - return ret;
> -}
> -
> -/**
> - * \brief Release buffers for all the ImgU video devices
> - */
> -void ImgUDevice::freeBuffers()
> -{
> - int ret;
> -
> - ret = output_.dev->releaseBuffers();
> - if (ret)
> - LOG(IPU3, Error) << "Failed to release ImgU output buffers";
> -
> - ret = stat_.dev->releaseBuffers();
> - if (ret)
> - LOG(IPU3, Error) << "Failed to release ImgU stat buffers";
> -
> - ret = viewfinder_.dev->releaseBuffers();
> - if (ret)
> - LOG(IPU3, Error) << "Failed to release ImgU viewfinder buffers";
> -
> - ret = input_->releaseBuffers();
> - if (ret)
> - LOG(IPU3, Error) << "Failed to release ImgU input buffers";
> -}
> -
> -int ImgUDevice::start()
> -{
> - int ret;
> -
> - /* Start the ImgU video devices. */
> - ret = output_.dev->streamOn();
> - if (ret) {
> - LOG(IPU3, Error) << "Failed to start ImgU output";
> - return ret;
> - }
> -
> - ret = viewfinder_.dev->streamOn();
> - if (ret) {
> - LOG(IPU3, Error) << "Failed to start ImgU viewfinder";
> - return ret;
> - }
> -
> - ret = stat_.dev->streamOn();
> - if (ret) {
> - LOG(IPU3, Error) << "Failed to start ImgU stat";
> - return ret;
> - }
> -
> - ret = input_->streamOn();
> - if (ret) {
> - LOG(IPU3, Error) << "Failed to start ImgU input";
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> -int ImgUDevice::stop()
> -{
> - int ret;
> -
> - ret = output_.dev->streamOff();
> - ret |= viewfinder_.dev->streamOff();
> - ret |= stat_.dev->streamOff();
> - ret |= input_->streamOff();
> -
> - return ret;
> -}
> -
> -/**
> - * \brief Enable or disable a single link on the ImgU instance
> - *
> - * This method assumes the media device associated with the ImgU instance
> - * is open.
> - *
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::linkSetup(const std::string &source, unsigned int sourcePad,
> - const std::string &sink, unsigned int sinkPad,
> - bool enable)
> -{
> - MediaLink *link = media_->link(source, sourcePad, sink, sinkPad);
> - if (!link) {
> - LOG(IPU3, Error)
> - << "Failed to get link: '" << source << "':"
> - << sourcePad << " -> '" << sink << "':" << sinkPad;
> - return -ENODEV;
> - }
> -
> - return link->setEnabled(enable);
> -}
> -
> -/**
> - * \brief Enable or disable all media links in the ImgU instance to prepare
> - * for capture operations
> - *
> - * \todo This method will probably be removed or changed once links will be
> - * enabled or disabled selectively.
> - *
> - * \return 0 on success or a negative error code otherwise
> - */
> -int ImgUDevice::enableLinks(bool enable)
> -{
> - std::string viewfinderName = name_ + " viewfinder";
> - std::string outputName = name_ + " output";
> - std::string statName = name_ + " 3a stat";
> - std::string inputName = name_ + " input";
> - int ret;
> -
> - ret = linkSetup(inputName, 0, name_, PAD_INPUT, enable);
> - if (ret)
> - return ret;
> -
> - ret = linkSetup(name_, PAD_OUTPUT, outputName, 0, enable);
> - if (ret)
> - return ret;
> -
> - ret = linkSetup(name_, PAD_VF, viewfinderName, 0, enable);
> - if (ret)
> - return ret;
> -
> - return linkSetup(name_, PAD_STAT, statName, 0, enable);
> -}
> -
> REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3);
>
> } /* namespace libcamera */
> diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build
> index b2602d30123f908d..d60e07ae6ccac2bc 100644
> --- a/src/libcamera/pipeline/ipu3/meson.build
> +++ b/src/libcamera/pipeline/ipu3/meson.build
> @@ -2,5 +2,6 @@
>
> libcamera_sources += files([
> 'cio2.cpp',
> + 'imgu.cpp',
> 'ipu3.cpp',
> ])
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list