/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2019, Google Inc.
*
* ipu3.cpp - Pipeline handler for Intel IPU3
*/
#include <algorithm>
#include <iomanip>
#include <memory>
#include <vector>
#include <linux/media-bus-format.h>
#include <libcamera/camera.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
#include "camera_sensor.h"
#include "device_enumerator.h"
#include "log.h"
#include "media_device.h"
#include "pipeline_handler.h"
#include "utils.h"
#include "v4l2_device.h"
#include "v4l2_subdevice.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 {
V4L2Device *dev;
unsigned int pad;
std::string name;
BufferPool *pool;
};
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 &config);
int importBuffers(BufferPool *pool);
int exportBuffers(ImgUOutput *output, BufferPool *pool);
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_;
V4L2Device *input_;
ImgUOutput output_;
ImgUOutput viewfinder_;
ImgUOutput stat_;
/* \todo Add param video device for 3A tuning */
BufferPool vfPool_;
BufferPool statPool_;
};
class CIO2Device
{
public:
static constexpr unsigned int CIO2_BUFFER_COUNT = 4;
CIO2Device()
: output_(nullptr), csi2_(nullptr), sensor_(nullptr)
{
}
~CIO2Device()
{
delete output_;
delete csi2_;
delete sensor_;
}
int init(const MediaDevice *media, unsigned int index);
int configure(const Size &size,
V4L2DeviceFormat *outputFormat);
BufferPool *exportBuffers();
void freeBuffers();
int start();
int stop();
static int mediaBusToFormat(unsigned int code);
V4L2Device *output_;
V4L2Subdevice *csi2_;
CameraSensor *sensor_;
BufferPool pool_;
};
class IPU3Stream : public Stream
{
public:
IPU3Stream()
: active_(false), device_(nullptr)
{
}
bool active_;
std::string name_;
ImgUDevice::ImgUOutput *device_;
};
class PipelineHandlerIPU3 : public PipelineHandler
{
public:
PipelineHandlerIPU3(CameraManager *manager);
~PipelineHandlerIPU3();
CameraConfiguration
streamConfiguration(Camera *camera,
const std::vector<StreamUsage> &usages) override;
int configureStreams(Camera *camera,
|