blob: 9f2b6655feca086db3508d59d650513317c23774 [file] [log] [blame]
/*
* Copyright (C) 2015-2019 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.
*/
#ifndef _CAMERA3_GRAPHCONFIG_H_
#define _CAMERA3_GRAPHCONFIG_H_
#include <string>
#include <memory>
#include <vector>
#include <set>
#include <utils/Errors.h>
#include <hardware/camera3.h>
#include <gcss.h>
#include <ia_aiq.h>
#include <linux/media.h>
#include "MediaCtlPipeConfig.h"
#include "LogHelper.h"
#include "MediaController.h"
#include "IPU3CameraCapInfo.h"
namespace GCSS {
class GraphConfigNode;
}
#define NODE_NAME(x) (getNodeName(x).c_str())
namespace cros {
namespace intel {
class GraphConfigManager;
#define MAX_OUTPUT_NUM_IN_PIPE 2
#define CSI_BE_OUTPUT "csi_be:output"
const int32_t ACTIVE_ISA_OUTPUT_BUFFER = 2;
const int32_t MAX_STREAMS = 4; // max number of streams
const uint32_t MAX_KERNEL_COUNT = 30; // max number of kernels in the kernel list
// Declare string consts
const std::string CSI_BE = "ipu3-cio2 ";
const std::string GC_INPUT = "input";
const std::string GC_MAIN = "main";
const std::string GC_VF = "vf";
const std::string GC_RAW = "raw";
// pipe index, video pipe: "ipu3-imgu 0", still pipe: "ipu3-imgu 1"
#define VIDEO_PIPE_INDEX 0
#define STILL_PIPE_INDEX 1
/**
* Stream id associated with the ISA PG that runs on Psys.
*/
static const int32_t PSYS_ISA_STREAM_ID = 60002;
/**
* Stream id associated with the ISA PG that runs on Isys.
*/
static const int32_t ISYS_ISA_STREAM_ID = 0;
/**
* \struct SinkDependency
*
* This structure stores dependency information for each virtual sink.
* This information is useful to determine the connections that preceded the
* virtual sink.
* We do not go all the way up to the sensor (we could), we just store the
* terminal id of the input port of the pipeline that serves a particular sink
* (i.e. the input port of the video pipe or still pipe)
*/
struct SinkDependency {
uid_t sinkGCKey; /**< GCSS_KEY that represents a sink, like GCSS_KEY_VIDEO1 */
int32_t streamId; /**< (a.k.a pipeline id) linked to this sink (ex 60000) */
uid_t streamInputPortId; /**< 4CC code of that terminal */
SinkDependency():
sinkGCKey(0),
streamId(-1),
streamInputPortId(0) {};
};
/**
* \class GraphConfig
*
* Reference and accessor to pipe configuration for specific request.
*
* In general case, at sream-config time there are multiple possible graphs.
* Per each request there is additional intent that can narrow down the
* possibilities to single graph settings: the GraphConfig object.
*
* This class is instantiated by \class GraphConfigManager for each request,
* and passed around HAL (control unit, capture unit, processing unit) via
* shared pointers. The objects are read-only and owned by GCM.
*/
class GraphConfig {
public:
typedef GCSS::GraphConfigNode Node;
typedef std::vector<Node*> NodesPtrVector;
typedef std::vector<int32_t> StreamsVector;
typedef std::map<camera3_stream_t*, uid_t> StreamToSinkMap;
static const int32_t PORT_DIRECTION_INPUT = 0;
static const int32_t PORT_DIRECTION_OUTPUT = 1;
public:
GraphConfig();
~GraphConfig();
/*
* Convert Node to GraphConfig interface
*/
const GCSS::IGraphConfig* getInterface(Node *node) const;
const GCSS::IGraphConfig* getInterface() const;
/*
* Graph Interrogation methods
*/
status_t graphGetSinksByName(const std::string &name, NodesPtrVector &sinks);
status_t graphGetDimensionsByName(const std::string &name,
int &widht, int &height);
status_t graphGetDimensionsByName(const std::string &name,
unsigned short &widht, unsigned short &height);
/*
* Find distinct stream ids from the graph
*/
status_t graphGetStreamIds(std::vector<int32_t> &streamIds);
/*
* Sink Interrogation methods
*/
int32_t sinkGetStreamId(Node *sink);
/*
* Stream Interrogation methods
*/
status_t streamGetInputPort(int32_t streamId, Node **port);
/*
* Port Interrogation methods
*/
status_t portGetFullName(Node *port, std::string &fullName);
status_t portGetPeer(Node *port, Node **peer);
int32_t portGetDirection(Node *port);
bool portIsVirtual(Node *port);
status_t portGetPeerIdByName(std::string name,
uid_t &terminalId);
status_t getDimensions(const Node *node, int &w, int &h) const;
status_t getDimensions(const Node *node, int &w, int &h, int &l,int &t) const;
/*
* re-cycler static method
*/
static void reset(GraphConfig *me);
void fullReset();
/*
* Debugging support
*/
std::string getNodeName(Node *node);
status_t getValue(string &nodeName, uint32_t id, int &value);
bool doesNodeExist(string nodeName);
enum PipeType {
PIPE_STILL = 0,
PIPE_VIDEO,
PIPE_MAX
};
PipeType getPipeType() const { return mPipeType; }
void setPipeType(PipeType type) { mPipeType = type; }
bool isStillPipe() { return mPipeType == PIPE_STILL; }
public:
void setMediaCtlConfig(std::shared_ptr<MediaController> mediaCtl,
bool enableStill);
private:
/* Helper structures to access Sensor Node information easily */
class Rectangle {
public:
Rectangle();
int32_t w; /*<! width */
int32_t h; /*<! height */
int32_t t; /*<! top */
int32_t l; /*<! left */
};
struct MediaCtlLut {
string uidStr;
uint32_t uid;
int pad;
string nodeName;
int ipuNodeName;
};
class SubdevPad: public Rectangle {
public:
SubdevPad();
int32_t mbusFormat;
};
struct BinFactor {
int32_t h;
int32_t v;
};
struct ScaleFactor {
int32_t num;
int32_t denom;
};
union RcFactor { // Resolution Changing factor
BinFactor bin;
ScaleFactor scale;
};
struct SubdevInfo {
string name;
SubdevPad in;
SubdevPad out;
RcFactor factor;
};
class SourceNodeInfo {
public:
SourceNodeInfo();
string name;
string i2cAddress;
string modeId;
bool metadataEnabled;
string csiPort;
string nativeBayer;
SubdevInfo tpg;
SubdevInfo pa;
SubdevPad output;
int32_t interlaced;
string verticalFlip;
string horizontalFlip;
string link_freq;
};
friend class GraphConfigManager;
// Private initializer: only used by our friend GraphConfigManager.
void init(int32_t reqId);
status_t prepare(Node *settings,
StreamToSinkMap &streamToSinkIdMap);
status_t analyzeSourceType();
void calculateSinkDependencies();
void storeTuningModes();
/*
* Helpers for constructing mediaCtlConfigs from graph config
*/
status_t parseSensorNodeInfo(Node* sensorNode, SourceNodeInfo &info);
status_t getCio2MediaCtlData(int *cio2Format, MediaCtlConfig* mediaCtlConfig);
status_t getImguMediaCtlData(int32_t cameraId,
int cio2Format,
int32_t testPatternMode,
bool enableStill,
MediaCtlConfig* mediaCtlConfig);
status_t addControls(const Node *sensorNode,
const SourceNodeInfo &sensorInfo,
MediaCtlConfig* config);
void addVideoNodes(MediaCtlConfig *config);
void addImguVideoNode(int ipuNodeName, const string& nodeName, MediaCtlConfig* config);
status_t getBinningFactor(const Node *node,
int32_t &hBin, int32_t &vBin) const;
status_t getScalingFactor(const Node *node,
int32_t &scalingNum,
int32_t &scalingDenom) const;
void addCtlParams(const string &entityName,
uint32_t controlName,
int controlId,
const string &strValue,
MediaCtlConfig* config);
void addFormatParams(const string &entityName,
int width,
int height,
int pad,
int formatCode,
int field,
MediaCtlConfig* config);
void addLinkParams(const string &srcName,
int srcPad,
const string &sinkName,
int sinkPad,
int enable,
int flags,
MediaCtlConfig* config);
void addSelectionParams(const string &entityName,
int width,
int height,
int left,
int top,
int target,
int pad,
MediaCtlConfig* config);
void addSelectionVideoParams(const string &entityName,
const struct v4l2_subdev_selection &select,
MediaCtlConfig* config);
status_t getNodeInfo(const ia_uid uid, const Node &parent, int *width, int *height);
void dumpMediaCtlConfig(const MediaCtlConfig &config) const;
// Private helpers for port nodes
status_t portGetFourCCInfo(Node &portNode,
uint32_t &stageId, uint32_t &terminalId);
// Format options methods
status_t getActiveOutputPorts(
const StreamToSinkMap &streamToSinkIdMap);
Node *getOutputPortForSink(const std::string &sinkName);
public:
// Imgu used from ParameterWorker
status_t getSensorFrameParams(ia_aiq_frame_params &sensorFrameParams);
private:
// Disable copy constructor and assignment operator
GraphConfig(const GraphConfig &);
GraphConfig& operator=(const GraphConfig &);
private:
GCSS::GraphConfigNode *mSettings;
int32_t mReqId;
std::map<int32_t, size_t> mKernelCountsMap; // key is stream id
PipeType mPipeType;
enum SourceType {
SRC_NONE = 0,
SRC_SENSOR,
SRC_TPG,
};
SourceType mSourceType;
/**
* pre-computed state done *per request*.
* This map holds the terminal id's of the ISA's peer ports (this is
* the terminal id's of the input port of the video or still pipe)
* that are required to fulfill a request.
* Ideally this gets initialized during init() call.
* But for now the GcManager will set it via a private method.
* we use a map so that we can handle the case when a request has 2 buffers
* that are generated from the same pipe.
*/
std::map<uid_t, uid_t> mIsaActiveDestinations;
/**
* vector holding the peers to the sink nodes. Map contains pairs of
* {sink, peer}.
* This map is filled at stream config time.
*/
std::map<Node*, Node*> mSinkPeerPort;
/**
*copy of the map provided from GraphConfigManager to be used internally.
*/
StreamToSinkMap mStreamToSinkIdMap;
/**
* Map of tuning modes per stream id
* Key: stream id
* Value: tuning mode
*/
std::map<int32_t, int32_t> mStream2TuningMap;
std::string mCSIBE;
std::shared_ptr<MediaController> mMediaCtl;
std::vector<MediaCtlLut> mLut;
};
} // namespace intel
} // namespace cros
#endif