blob: b97100fad99b4ed62417a737449540c4f546d3e5 [file] [log] [blame]
/*
* Copyright (C) 2015-2020 Intel Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <vector>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <linux/v4l2-subdev.h>
#include <linux/media.h>
#include <expat.h>
#include <v4l2_device.h>
#include "CameraTypes.h"
#include "iutils/Thread.h"
#include "NodeInfo.h"
namespace icamera {
struct MediaEntity;
struct MediaPad;
struct MediaLink;
#define MEDIA_CTL_DEV_NAME "/dev/media"
#define MEDIA_DRIVER_NAME "intel-ipu"
#define MEDIA_DEVICE_MAX_NUM 256
enum {
FC_FORMAT = 0,
FC_SELECTION = 1,
};
enum ResolutionType {
RESOLUTION_MAX = 0,
RESOLUTION_COMPOSE,
RESOLUTION_CROP,
RESOLUTION_TARGET,
};
struct McFormat {
int entity;
int pad;
int stream;
int formatType;
int selCmd;
int top;
int left;
int width;
int height;
enum ResolutionType type;
std::string entityName;
unsigned int pixelCode;
McFormat() {
entity = 0;
pad = 0;
stream = 0;
formatType = 0;
selCmd = 0;
top = 0;
left = 0;
width = 0;
height = 0;
type = RESOLUTION_MAX;
pixelCode = 0;}
};
struct McOutput {
Port port;
unsigned int v4l2Format;
int width;
int height;
McOutput() { port = INVALID_PORT; v4l2Format = 0; width = 0; height = 0; }
};
struct McCtl {
int entity;
int ctlCmd;
int ctlValue;
std::string ctlName;
std::string entityName;
McCtl() { entity = 0; ctlCmd = 0; ctlValue= 0; }
};
struct McLink {
int srcEntity;
int srcPad;
int sinkEntity;
int sinkPad;
bool enable;
std::string srcEntityName;
std::string sinkEntityName;
McLink() { srcEntity = 0; srcPad = 0; sinkEntity = 0; sinkPad = 0; enable = false; }
};
struct McRoute {
int entity;
uint32_t sinkPad;
uint32_t sinkStream;
uint32_t srcPad;
uint32_t srcStream;
uint32_t flag;
std::string entityName;
McRoute() { entity = 0; sinkPad = 0; srcPad = 0; sinkStream = 0; srcStream = 0; flag = 0; entityName.clear(); }
};
struct McVideoNode {
std::string name;
VideoNodeType videoNodeType;
McVideoNode() { videoNodeType = VIDEO_GENERIC; }
};
struct MediaCtlConf {
std::vector <McCtl> ctls;
std::vector <McLink> links;
std::vector <McRoute> routes;
std::vector <McFormat> formats;
std::vector <McOutput> outputs;
std::vector <McVideoNode> videoNodes;
int mcId;
int outputWidth;
int outputHeight;
std::vector <ConfigMode> configMode;
int format;
/*
* The outputWidth or outputHeight is 0 if there isn't this setting
* in MediaCtlConf. It means the isys output size is dynamic, and
* we don't use stream size to select MC.
*/
MediaCtlConf() {
mcId = -1;
outputWidth = 0;
outputHeight = 0;
format = -1;
}
};
/**
* \class MediaController
*
* This class is used for discovering and configuring the internal topology
* of a media device. Devices are modelled as an oriented graph of building
* blocks called media entities. The media entities are connected to each other
* through pads.
*
* Each media entity corresponds to a V4L2 subdevice. This class is also used
* for configuring the V4L2 subdevices.
*/
class MediaControl {
public:
/**
* \brief Get the singleton instance of MediaControl
*/
static MediaControl* getInstance();
/**
* \brief Release the singleton instance of MediaControl.
*/
static void releaseInstance();
/**
* \brief Enum entities and link, and reset all links
*
* \return 0 if succeed, other value indicates failed
*/
int initEntities();
/**
* \brief Free all entities and links memory
*/
void clearEntities();
/**
* \brief Get the entity by name
*
* \return entity id if succeed or -1 if error
*/
int getEntityIdByName(const char *name);
/**
* \brief Get VCM I2C bus address
*
* \return 0 if succeed, other value indicates failed
*/
int getVCMI2CAddr(const char* vcmName, std::string* vcmI2CAddr);
/**
* \brief Set up media controller pipe
*
* \param cameraId: the current camera id
* \param mc: the MediaCtlConf got from platform data
* \param sensorName: the sensor name get from platform data
* \param width: The width of the request frame
* \param height: The height of the request frame
* \param format: The format of the request frame
* \param field: The field of the request frame
*
* \return OK if succeed, other value indicates failed
*/
int mediaCtlSetup(int cameraId, MediaCtlConf *mc, int width, int height, int field);
/**
* \brief Clear media controller pipe
*
*
* \param cameraId: the current camera id
* \param mc: the MediaCtlConf got from platform data
*/
void mediaCtlClear(int cameraId, MediaCtlConf *mc);
int resetAllLinks();
int getLensName(std::string *lensName);
bool checkAvailableSensor(const std::string &sensorEntityName,
const std::string &sinkEntityName);
/**
* Getting I2C bus address by the name of sensor entity and the name of sensor's sink entity.
*
* \sensorEntityName: the name of sensor entity.
* \sinkEntityName: the name of sensor's sink entity.
* \i2cBus: I2C bus address.
* \return OK if succeed, other value indicates failed
*/
int getI2CBusAddress(const std::string &sensorEntityName, const std::string &sinkEntityName,
std::string *i2cBus);
private:
MediaControl& operator=(const MediaControl&);
MediaControl(const char *devName);
~MediaControl();
static MediaControl* getMediaControlInstance();
int openDevice();
void closeDevice(int fd);
//enum MediaControl info.
int enumInfo();
int enumLinks(int fd);
int enumEntities(int fd, media_device_info& devInfo);
//get entity info.
int getDevnameFromSysfs(MediaEntity *entity);
MediaEntity *getEntityById(uint32_t id);
MediaEntity *getEntityByName(const char *name);
//set up entity link.
MediaLink *entityAddLink(MediaEntity *entity);
int setupLink(uint32_t srcEntity, uint32_t srcPad, uint32_t sinkEntity, uint32_t sinkPad, bool enable);
int setupLink(MediaPad *source, MediaPad *sink, uint32_t flags);
//set up MediaCtlConf info.
void setMediaMcCtl(int cameraId, std::vector <McCtl> ctls);
int setMediaMcLink(std::vector <McLink> links);
int setFormat(int cameraId, const McFormat *format,
int targetWidth, int targetHeight, int field);
int setSelection(int cameraId, const McFormat *format,
int targetWidth, int targetHeight);
/* Dump functions */
void dumpInfo(media_device_info& devInfo);
void dumpEntityDesc(media_entity_desc& desc, media_device_info& devInfo);
void dumpPadDesc(media_pad_desc *pads, const int padsCount = 1, const char *name = nullptr);
void dumpLinkDesc(media_link_desc *links, const int linksCount = 1);
const char *entitySubtype2String(unsigned type);
const char *padType2String(unsigned flag);
void dumpEntityTopology(bool dot = true);
void dumpTopologyDot();
void dumpTopologyText();
private:
std::string mDevName;
std::vector <MediaEntity> mEntities;
private:
static MediaControl *sInstance;
static Mutex sLock;
};
} //namespace icamera