diff --git a/src/media/video/v4l2/video_device_impl.cpp b/src/media/video/v4l2/video_device_impl.cpp index eeb4d0363a15fdda5f72e4834cf167c1a997a66f..2741282d02792a5b153e202128a5cb76cf2dc358 100644 --- a/src/media/video/v4l2/video_device_impl.cpp +++ b/src/media/video/v4l2/video_device_impl.cpp @@ -441,6 +441,11 @@ VideoDeviceImpl::VideoDeviceImpl(const string& id, const std::string& path) , size_(-1, -1) , rate_(-1, 1, 0) { + if (id == DEVICE_DESKTOP) { + name = DEVICE_DESKTOP; + rate_.frame_rate = 30; + return; + } int fd = open(path.c_str(), O_RDWR); if (fd == -1) throw std::runtime_error("could not open device"); @@ -514,6 +519,8 @@ VideoV4l2Rate::libAvPixelformat() const vector<string> VideoDeviceImpl::getChannelList() const { + if (unique_id == DEVICE_DESKTOP) + return {"default"}; vector<string> v; v.reserve(channels_.size()); for (const auto& itr : channels_) @@ -525,12 +532,26 @@ VideoDeviceImpl::getChannelList() const vector<VideoSize> VideoDeviceImpl::getSizeList(const string& channel) const { + if (unique_id == DEVICE_DESKTOP) { + return {VideoSize(0, 0)}; + } return getChannel(channel).getSizeList(); } vector<FrameRate> VideoDeviceImpl::getRateList(const string& channel, VideoSize size) const { + if (unique_id == DEVICE_DESKTOP) { + return {FrameRate(5), + FrameRate(10), + FrameRate(15), + FrameRate(20), + FrameRate(25), + FrameRate(30), + FrameRate(60), + FrameRate(120), + FrameRate(144)}; + } return getChannel(channel).getSize(size).getRateList(); } @@ -552,6 +573,11 @@ VideoDeviceImpl::getDeviceParams() const params.name = name; params.unique_id = unique_id; params.input = path; + if (unique_id == DEVICE_DESKTOP) { + params.format = "x11grab"; + params.framerate = rate_.frame_rate; + return params; + } params.format = "video4linux2"; params.channel_name = channel_.name; params.channel = channel_.idx; @@ -565,6 +591,10 @@ VideoDeviceImpl::getDeviceParams() const void VideoDeviceImpl::setDeviceParams(const DeviceParams& params) { + if (unique_id == DEVICE_DESKTOP) { + rate_.frame_rate = params.framerate; + return; + } // Set preferences or fallback to defaults. channel_ = getChannel(params.channel_name); size_ = channel_.getSize({params.width, params.height}); diff --git a/src/media/video/v4l2/video_device_monitor_impl.cpp b/src/media/video/v4l2/video_device_monitor_impl.cpp index 5e02b3d0339d835985edccf073898eb3ef5a14a8..2d9daf662857c3f852907029402d37b4632c59ec 100644 --- a/src/media/video/v4l2/video_device_monitor_impl.cpp +++ b/src/media/video/v4l2/video_device_monitor_impl.cpp @@ -279,6 +279,7 @@ VideoDeviceMonitor::VideoDeviceMonitor() , monitorImpl_(new VideoDeviceMonitorImpl(this)) { monitorImpl_->start(); + addDevice(DEVICE_DESKTOP, {}); } VideoDeviceMonitor::~VideoDeviceMonitor() {} diff --git a/src/media/video/video_device.h b/src/media/video/video_device.h index 46386af941df10628668e048eeb1f9dc97b9b47b..4f2dec6e05a50ab12700c6cc96da81ab61f2374e 100644 --- a/src/media/video/video_device.h +++ b/src/media/video/video_device.h @@ -44,6 +44,7 @@ namespace video { using VideoSize = std::pair<unsigned, unsigned>; using FrameRate = rational<double>; +static constexpr const char DEVICE_DESKTOP[] = "desktop"; class VideoDeviceImpl; diff --git a/src/media/video/video_device_monitor.cpp b/src/media/video/video_device_monitor.cpp index 75a291b1ceeec1f61b9ab8601ac3ab39f04d7b3b..8542bd69eda7f62444494db4f999167263f97f6b 100644 --- a/src/media/video/video_device_monitor.cpp +++ b/src/media/video/video_device_monitor.cpp @@ -53,7 +53,8 @@ VideoDeviceMonitor::getDeviceList() const vector<string> ids; ids.reserve(devices_.size()); for (const auto& dev : devices_) { - ids.emplace_back(dev.getDeviceId()); + if (dev.name != DEVICE_DESKTOP) + ids.emplace_back(dev.getDeviceId()); } return ids; } @@ -213,7 +214,7 @@ VideoDeviceMonitor::addDevice(const string& id, } // in case there is no default device on a fresh run - if (defaultDevice_.empty()) + if (defaultDevice_.empty() && id != DEVICE_DESKTOP) defaultDevice_ = dev.getDeviceId(); devices_.emplace_back(std::move(dev)); @@ -235,13 +236,13 @@ VideoDeviceMonitor::removeDevice(const string& id) return; devices_.erase(it); - if (defaultDevice_.find(id) != std::string::npos) { - if (devices_.size() == 0) { - defaultDevice_.clear(); - } else { - defaultDevice_ = devices_[0].getDeviceId(); - } + defaultDevice_.clear(); + for (const auto& dev : devices_) + if (dev.name != DEVICE_DESKTOP) { + defaultDevice_ = dev.getDeviceId(); + break; + } } } notify(); @@ -310,12 +311,16 @@ VideoDeviceMonitor::unserialize(const YAML::Node& in) // Restore the default device if present, or select the first one const string prefId = preferences_.empty() ? "" : preferences_[0].unique_id; - const string firstId = devices_.empty() ? "" : devices_[0].getDeviceId(); const auto devIter = findDeviceById(prefId); - if (devIter != devices_.end()) { + if (devIter != devices_.end() && prefId != DEVICE_DESKTOP) { defaultDevice_ = devIter->getDeviceId(); } else { - defaultDevice_ = firstId; + defaultDevice_.clear(); + for (const auto& dev : devices_) + if (dev.name != DEVICE_DESKTOP) { + defaultDevice_ = dev.getDeviceId(); + break; + } } } diff --git a/src/media/video/video_input.cpp b/src/media/video/video_input.cpp index d91f1b6bcc42240ff10b4dadfc38ebe2b62c8097..f4af01384253b20017f342dab8d3c81139bb4809 100644 --- a/src/media/video/video_input.cpp +++ b/src/media/video/video_input.cpp @@ -396,8 +396,7 @@ VideoInput::initX11(std::string display) size_t space = display.find(' '); clearOptions(); - decOpts_.format = "x11grab"; - decOpts_.framerate = 25; + decOpts_ = jami::getVideoDeviceMonitor().getDeviceParams(DEVICE_DESKTOP); if (space != std::string::npos) { std::istringstream iss(display.substr(space + 1)); @@ -428,7 +427,7 @@ VideoInput::initAVFoundation(const std::string& display) decOpts_.pixel_format = "nv12"; decOpts_.name = "Capture screen 0"; decOpts_.input = "Capture screen 0"; - decOpts_.framerate = 30; + decOpts_.framerate = jami::getVideoDeviceMonitor().getDeviceParams(DEVICE_DESKTOP).framerate; if (space != std::string::npos) { std::istringstream iss(display.substr(space + 1)); @@ -449,9 +448,7 @@ VideoInput::initGdiGrab(const std::string& params) { size_t space = params.find(' '); clearOptions(); - decOpts_.format = "gdigrab"; - decOpts_.input = "desktop"; - decOpts_.framerate = 30; + decOpts_ = jami::getVideoDeviceMonitor().getDeviceParams(DEVICE_DESKTOP); if (space != std::string::npos) { std::istringstream iss(params.substr(space + 1)); diff --git a/src/media/video/winvideo/video_device_impl.cpp b/src/media/video/winvideo/video_device_impl.cpp index e244d40079f75916d60bc63daf04e39d5d1efe89..9af9dc8ce3dea5dfe2e2d6c1ba82f43dff828ef3 100644 --- a/src/media/video/winvideo/video_device_impl.cpp +++ b/src/media/video/winvideo/video_device_impl.cpp @@ -64,6 +64,7 @@ private: std::vector<VideoSize> sizeList_; std::map<VideoSize, std::vector<FrameRate>> rateList_; std::map<VideoSize, AM_MEDIA_TYPE*> capMap_; + FrameRate desktopFrameRate_ = {30}; void fail(const std::string& error); }; @@ -79,6 +80,21 @@ VideoDeviceImpl::VideoDeviceImpl(const std::string& id) void VideoDeviceImpl::setup() { + if (id == DEVICE_DESKTOP) { + name = DEVICE_DESKTOP; + VideoSize size {0, 0}; + sizeList_.emplace_back(size); + rateList_[size] = {FrameRate(5), + FrameRate(10), + FrameRate(15), + FrameRate(20), + FrameRate(25), + FrameRate(30), + FrameRate(60), + FrameRate(120), + FrameRate(144)}; + return; + } HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, nullptr, CLSCTX_INPROC_SERVER, @@ -264,6 +280,12 @@ VideoDeviceImpl::getDeviceParams() const params.name = name; params.unique_id = id; params.input = id; + if (id == DEVICE_DESKTOP) { + params.format = "gdigrab"; + params.framerate = desktopFrameRate_; + return params; + } + params.format = "dshow"; AM_MEDIA_TYPE* pmt; @@ -282,6 +304,10 @@ VideoDeviceImpl::getDeviceParams() const void VideoDeviceImpl::setDeviceParams(const DeviceParams& params) { + if (id == DEVICE_DESKTOP) { + desktopFrameRate_ = params.framerate; + return; + } if (params.width and params.height) { auto pmt = capMap_.at(std::make_pair(params.width, params.height)); if (pmt != nullptr) { diff --git a/src/media/video/winvideo/video_device_monitor_impl.cpp b/src/media/video/winvideo/video_device_monitor_impl.cpp index c4abebbfdd90b3ceeed902b453db80c79ce437e9..cc23a92b646897bbd999c3b414e76c9f7f39d6a4 100644 --- a/src/media/video/winvideo/video_device_monitor_impl.cpp +++ b/src/media/video/winvideo/video_device_monitor_impl.cpp @@ -293,6 +293,7 @@ VideoDeviceMonitor::VideoDeviceMonitor() , monitorImpl_(new VideoDeviceMonitorImpl(this)) { monitorImpl_->start(); + addDevice(DEVICE_DESKTOP, {}); } VideoDeviceMonitor::~VideoDeviceMonitor() {}