29#include <linux/videodev2.h>
30#if !defined(VIDIOC_ENUM_FRAMESIZES) || !defined(VIDIOC_ENUM_FRAMEINTERVALS)
31#error You need at least Linux 2.6.19
40#include "../video_device.h"
43#define ZEROVAR(x) std::memset(&(x), 0, sizeof(x))
83 std::vector<VideoV4l2Rate> rates_;
89 return a.height ==
b.height &&
a.width ==
b.width;
105 unsigned int readSizes(
int fd,
unsigned int pixel_format);
115 std::vector<VideoV4l2Size> sizes_;
131 std::vector<VideoSize>
getSizeList(
const std::string& channel)
const;
138 std::vector<VideoV4l2Channel> channels_;
246 rates.reserve(rates_.size());
247 for (
const auto& r : rates_)
248 rates.emplace_back(r.frame_rate);
259 frmival.pixel_format = pixel_format;
265 JAMI_ERR(
"Unable to query frame interval for size");
271 JAMI_ERR(
"Continuous and stepwise Frame Intervals are not supported");
276 addRate({
frmival.discrete.numerator,
frmival.discrete.denominator, pixel_format});
284 for (
const auto&
item : rates_) {
285 if (std::fabs((
item.frame_rate -
rate).real()) < 0.0001)
288 return rates_.back();
295 for (
auto&
item : rates_) {
315std::vector<VideoSize>
319 v.reserve(sizes_.size());
320 for (
const auto&
item : sizes_)
321 v.emplace_back(
item.width,
item.height);
341 throw std::runtime_error(
"Unable to get format");
344 size.readFrameRates(fd, fmt.fmt.pix.pixelformat);
345 sizes_.push_back(size);
347 return fmt.fmt.pix.pixelformat;
352 JAMI_ERR(
"Continuous Frame sizes not supported");
361 for (
auto&
item : sizes_) {
371 size.readFrameRates(fd,
frmsize.pixel_format);
372 sizes_.push_back(size);
384VideoV4l2Channel::putCIFFirst()
386 const auto iter = std::find_if(sizes_.begin(), sizes_.end(), [](
const VideoV4l2Size& size) {
387 return size.width == 352 and size.height == 258;
390 if (
iter != sizes_.end()
and iter != sizes_.begin())
391 std::swap(*
iter, *sizes_.begin());
398 throw std::runtime_error(
"VIDIOC_S_INPUT failed");
413 throw std::runtime_error(
"Unable to enumerate formats");
421 for (
const auto&
item : sizes_) {
422 if (
item.width == s.first &&
item.height == s.second)
427 return sizes_.front();
441 rate_.frame_rate = 30;
446 throw std::runtime_error(
"Unable to open device");
450 throw std::runtime_error(
"Unable to query capabilities");
453 throw std::runtime_error(
"Not a capture device");
456 throw std::runtime_error(
"Touch device, ignoring it");
458 name = string(
reinterpret_cast<const char*
>(
cap.card));
463 input.index =
idx = 0;
465 if (
idx != input.index)
469 VideoV4l2Channel channel(
idx, (
const char*) input.name);
470 channel.readFormats(fd);
471 if (
not channel.getSizeList().empty())
472 channels_.push_back(channel);
520 v.reserve(channels_.size());
521 for (
const auto&
itr : channels_)
522 v.push_back(
itr.name);
554const VideoV4l2Channel&
555VideoDeviceImpl::getChannel(
const string& name)
const
557 for (
const auto&
item : channels_)
562 return channels_.front();
573 const auto*
env = std::getenv(
"WAYLAND_DISPLAY");
575 params.format =
"x11grab";
578 params.input =
"pipewiregrab";
580 params.framerate = rate_.frame_rate;
583 params.format =
"video4linux2";
586 params.width = size_.width;
587 params.height = size_.height;
588 params.framerate = rate_.frame_rate;
589 params.pixel_format = rate_.libAvPixelformat();
597 rate_.frame_rate =
params.framerate;
601 channel_ = getChannel(
params.channel_name);
604 rate_ = size_.getRate(
params.framerate);
611 const std::vector<std::map<std::string, std::string>>&
devInfo)
614 deviceImpl_ = std::make_shared<VideoDeviceImpl>(
id,
616 :
devInfo.at(0).at(
"devPath"));
617 name = deviceImpl_->name;
623 auto params = deviceImpl_->getDeviceParams();
624 params.orientation = orientation_;
629VideoDevice::setDeviceParams(
const DeviceParams&
params)
631 return deviceImpl_->setDeviceParams(
params);
634std::vector<std::string>
637 return deviceImpl_->getChannelList();
640std::vector<VideoSize>
641VideoDevice::getSizeList(
const std::string& channel)
const
643 return deviceImpl_->getSizeList(channel);
646std::vector<FrameRate>
647VideoDevice::getRateList(
const std::string& channel,
VideoSize size)
const
649 return deviceImpl_->getRateList(channel, size);
VideoDeviceImpl(const std::string &id, const std::string &path)
std::vector< VideoSize > getSizeList() const
std::vector< std::string > getChannelList() const
VideoDeviceImpl(const std::string &path)
void setDeviceParams(const DeviceParams &)
DeviceParams getDeviceParams() const
std::vector< FrameRate > getRateList() const
std::vector< std::string > getChannelList() const
VideoDevice(const std::string &path, const std::vector< std::map< std::string, std::string > > &devInfo)
DeviceParams getDeviceParams() const
Returns the parameters needed for actual use of the device.
VideoV4l2Channel(unsigned idx, const char *s)
const VideoV4l2Size & getSize(VideoSize name) const
unsigned int readSizes(int fd, unsigned int pixel_format)
std::vector< VideoSize > getSizeList() const
VideoV4l2Rate(unsigned rate_numerator=0, unsigned rate_denominator=0, unsigned format=0)
std::string libAvPixelformat() const
VideoV4l2Rate getRate(const FrameRate &rate) const
std::vector< FrameRate > getRateList() const
void readFrameRates(int fd, unsigned int pixel_format)
VideoV4l2Size(const unsigned width, const unsigned height)
bool operator==(VideoV4l2Size &a, VideoV4l2Size &b)
static constexpr const char DEVICE_DESKTOP[]
static const unsigned pixelformats_supported[]
static unsigned int pixelformat_score(unsigned pixelformat)
std::pair< unsigned, unsigned > VideoSize
rational< double > FrameRate
void emitSignal(Args... args)
DeviceParams Parameters used by MediaDecoder and MediaEncoder to open a LibAV device/stream.