#pragma once #include #include #include #include #ifndef V4L2_PIX_FMT_VP8 #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') #endif #ifndef V4L2_PIX_FMT_VP9 #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') #endif #ifndef V4L2_PIX_FMT_HEVC #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') #endif namespace Video { namespace V4L2 { enum V4l2IoType { IOTYPE_READWRITE, IOTYPE_MMAP }; struct DeviceParameters { DeviceParameters(const char* devname, const std::list& formatList, unsigned int width, unsigned int height, int fps, V4l2IoType ioType = IOTYPE_MMAP, int verbose = 0, int openFlags = O_RDWR | O_NONBLOCK) : m_devName(devname), m_formatList(formatList), m_width(width), m_height(height), m_fps(fps), m_iotype(ioType), m_verbose(verbose), m_openFlags(openFlags) { } DeviceParameters(const char* devname, unsigned int format, unsigned int width, unsigned int height, int fps, V4l2IoType ioType = IOTYPE_MMAP, int verbose = 0, int openFlags = O_RDWR | O_NONBLOCK) : m_devName(devname), m_width(width), m_height(height), m_fps(fps), m_iotype(ioType), m_verbose(verbose), m_openFlags(openFlags) { if (format) { m_formatList.push_back(format); } } std::string m_devName; std::list m_formatList; unsigned int m_width; unsigned int m_height; int m_fps; V4l2IoType m_iotype; int m_verbose; int m_openFlags; }; class Device { friend class Capture; friend class Output; protected: void close(); int initdevice(const char* dev_name, unsigned int mandatoryCapabilities); int checkCapabilities(int fd, unsigned int mandatoryCapabilities); int configureFormat(int fd); int configureFormat(int fd, unsigned int format, unsigned int width, unsigned int height); int configureParam(int fd, int fps); virtual bool init(unsigned int mandatoryCapabilities); virtual size_t writeInternal(char*, size_t) { return -1; } virtual bool startPartialWrite() { return false; } virtual size_t writePartialInternal(char*, size_t) { return -1; } virtual bool endPartialWrite() { return false; } virtual size_t readInternal(char*, size_t) { return -1; } public: Device(const DeviceParameters& params, v4l2_buf_type deviceType); virtual ~Device(); virtual bool isReady() { return (m_fd != -1); } virtual bool start() { return true; } virtual bool stop() { return true; } std::string getName() { return m_name; } unsigned int getBufferSize() { return m_bufferSize; } unsigned int getFormat() { return m_format; } unsigned int getWidth() { return m_width; } unsigned int getHeight() { return m_height; } int getFd() { return m_fd; } void queryFormat(); int setFormat(unsigned int format, unsigned int width, unsigned int height) { return this->configureFormat(m_fd, format, width, height); } int setFps(int fps) { return this->configureParam(m_fd, fps); } static std::string fourcc(unsigned int format); static unsigned int fourcc(const char* format); protected: DeviceParameters m_params; int m_fd; v4l2_buf_type m_deviceType; unsigned int m_bufferSize; unsigned int m_format; unsigned int m_width; unsigned int m_height; struct v4l2_buffer m_partialWriteBuf; bool m_partialWriteInProgress; std::string m_name; }; } }