video device: use device id instead of friendly name

- Video settings, and APIs will now use a device id, which will be
  a path on platforms where everything is a file, and a DevicePath
  with a bonus ffmpeg-dshow compliant prefix on Windows.

- The device's friendly name is uniquified, and stored in the
  settings still, but only retrieved/translated for UI.

- MRLs are now constructed with the device id.

Change-Id: I092f08cc2cd31bd78aeec5c774c2cc33d75c1d4e
This commit is contained in:
Andreas Traczyk
2019-10-28 11:10:44 -04:00
parent ca26195f05
commit d6e2b8a332
17 changed files with 155 additions and 187 deletions

View File

@ -4,33 +4,33 @@
<!-- Video device methods -->
<method name="getDeviceList" tp:name-for-bindings="getDeviceList">
<tp:docstring>Returns a list of the detected v4l2 devices</tp:docstring>
<tp:docstring>Returns a list of ids for detected devices</tp:docstring>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
<arg type="as" name="list" direction="out">
</arg>
</method>
<method name="getCapabilities" tp:name-for-bindings="getCapabilities">
<tp:docstring>Returns a map of map of array of strings, containing the capabilities (channel, size, rate) of a device</tp:docstring>
<tp:docstring>Returns a map of map of array of strings, containing the capabilities (channel, size, rate) for a given device id</tp:docstring>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringMapStringVectorString"/>
<arg type="s" name="name" direction="in">
<arg type="s" name="deviceId" direction="in">
</arg>
<arg type="a{sa{sas}}" name="cap" direction="out">
</arg>
</method>
<method name="getSettings" tp:name-for-bindings="getSettings">
<tp:docstring>Returns a map of settings for the given device name</tp:docstring>
<tp:docstring>Returns a map of settings for the given device id</tp:docstring>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/>
<arg type="s" name="device" direction="in">
<arg type="s" name="deviceId" direction="in">
</arg>
<arg type="a{ss}" name="map" direction="out">
</arg>
</method>
<method name="applySettings" tp:name-for-bindings="applySettings">
<tp:docstring>Set the preferred settings for a given device name</tp:docstring>
<arg type="s" name="name" direction="in">
<tp:docstring>Set the preferred settings for a given device id</tp:docstring>
<arg type="s" name="deviceId" direction="in">
</arg>
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="MapStringString"/>
<arg type="a{ss}" name="settings" direction="in">
@ -38,12 +38,14 @@
</method>
<method name="getDefaultDevice" tp:name-for-bindings="getDefaultDevice">
<arg type="s" name="name" direction="out">
<tp:docstring>Returns the default device id</tp:docstring>
<arg type="s" name="deviceId" direction="out">
</arg>
</method>
<method name="setDefaultDevice" tp:name-for-bindings="setDefaultDevice">
<arg type="s" name="name" direction="in">
<tp:docstring>Sets the default device id</tp:docstring>
<arg type="s" name="deviceId" direction="in">
</arg>
</method>
@ -132,8 +134,8 @@
</method>
<method name="setDeviceOrientation" tp:name-for-bindings="setDeviceOrientation">
<arg type="s" name="name" direction="in">
<tp:docstring>Device name</tp:docstring>
<arg type="s" name="deviceId" direction="in">
<tp:docstring>Device id</tp:docstring>
</arg>
<arg type="i" name="angle" direction="in">
<tp:docstring>Angle of device in degrees (counterclockwise)</tp:docstring>

View File

@ -32,27 +32,27 @@ DBusVideoManager::getDeviceList() -> decltype(DRing::getDeviceList())
}
auto
DBusVideoManager::getCapabilities(const std::string& name) -> decltype(DRing::getCapabilities(name))
DBusVideoManager::getCapabilities(const std::string& deviceId) -> decltype(DRing::getCapabilities(deviceId))
{
return DRing::getCapabilities(name);
return DRing::getCapabilities(deviceId);
}
auto
DBusVideoManager::getSettings(const std::string& name) -> decltype(DRing::getSettings(name))
DBusVideoManager::getSettings(const std::string& deviceId) -> decltype(DRing::getSettings(deviceId))
{
return DRing::getSettings(name);
return DRing::getSettings(deviceId);
}
void
DBusVideoManager::applySettings(const std::string& name, const std::map<std::string, std::string>& settings)
DBusVideoManager::applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings)
{
DRing::applySettings(name, settings);
DRing::applySettings(deviceId, settings);
}
void
DBusVideoManager::setDefaultDevice(const std::string& dev)
DBusVideoManager::setDefaultDevice(const std::string& deviceId)
{
DRing::setDefaultDevice(dev);
DRing::setDefaultDevice(deviceId);
}
auto
@ -122,9 +122,9 @@ DBusVideoManager::setEncodingAccelerated(const bool& state)
}
void
DBusVideoManager::setDeviceOrientation(const std::string& name, const int& angle)
DBusVideoManager::setDeviceOrientation(const std::string& deviceId, const int& angle)
{
DRing::setDeviceOrientation(name, angle);
DRing::setDeviceOrientation(deviceId, angle);
}
std::map<std::string, std::string>

View File

@ -52,10 +52,10 @@ class DRING_PUBLIC DBusVideoManager :
// Methods
std::vector<std::string> getDeviceList();
std::map<std::string, std::map<std::string, std::vector<std::string>>> getCapabilities(const std::string& name);
std::map<std::string, std::string> getSettings(const std::string& name);
void applySettings(const std::string& name, const std::map<std::string, std::string>& settings);
void setDefaultDevice(const std::string& dev);
std::map<std::string, std::map<std::string, std::vector<std::string>>> getCapabilities(const std::string& deviceId);
std::map<std::string, std::string> getSettings(const std::string& deviceId);
void applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings);
void setDefaultDevice(const std::string& deviceId);
std::string getDefaultDevice();
void startCamera();
void stopCamera();
@ -67,7 +67,7 @@ class DRING_PUBLIC DBusVideoManager :
void setDecodingAccelerated(const bool& state);
bool getEncodingAccelerated();
void setEncodingAccelerated(const bool& state);
void setDeviceOrientation(const std::string& name, const int& angle);
void setDeviceOrientation(const std::string& deviceId, const int& angle);
std::map<std::string, std::string> getRenderer(const std::string& callId);
std::string startLocalRecorder(const bool& audioOnly, const std::string& filepath);
void stopLocalRecorder(const std::string& filepath);

View File

@ -329,9 +329,9 @@ getDeviceList()
}
VideoCapabilities
getCapabilities(const std::string& name)
getCapabilities(const std::string& deviceId)
{
return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getCapabilities(name);
return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getCapabilities(deviceId);
}
std::string
@ -341,23 +341,23 @@ getDefaultDevice()
}
void
setDefaultDevice(const std::string& name)
setDefaultDevice(const std::string& deviceId)
{
JAMI_DBG("Setting default device to %s", name.c_str());
jami::Manager::instance().getVideoManager().videoDeviceMonitor.setDefaultDevice(name);
JAMI_DBG("Setting default device to %s", deviceId.c_str());
jami::Manager::instance().getVideoManager().videoDeviceMonitor.setDefaultDevice(deviceId);
jami::Manager::instance().saveConfig();
}
void
setDeviceOrientation(const std::string& name, int angle)
setDeviceOrientation(const std::string& deviceId, int angle)
{
jami::Manager::instance().getVideoManager().setDeviceOrientation(name, angle);
jami::Manager::instance().getVideoManager().setDeviceOrientation(deviceId, angle);
}
std::map<std::string, std::string>
getDeviceParams(const std::string& name)
getDeviceParams(const std::string& deviceId)
{
auto params = jami::Manager::instance().getVideoManager().videoDeviceMonitor.getDeviceParams(name);
auto params = jami::Manager::instance().getVideoManager().videoDeviceMonitor.getDeviceParams(deviceId);
std::stringstream width, height, rate;
width << params.width;
height << params.height;
@ -371,16 +371,16 @@ getDeviceParams(const std::string& name)
}
std::map<std::string, std::string>
getSettings(const std::string& name)
getSettings(const std::string& deviceId)
{
return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getSettings(name).to_map();
return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getSettings(deviceId).to_map();
}
void
applySettings(const std::string& name,
applySettings(const std::string& deviceId,
const std::map<std::string, std::string>& settings)
{
jami::Manager::instance().getVideoManager().videoDeviceMonitor.applySettings(name, settings);
jami::Manager::instance().getVideoManager().videoDeviceMonitor.applySettings(deviceId, settings);
jami::Manager::instance().saveConfig();
}
@ -650,9 +650,9 @@ getAudioInput(const std::string& id)
}
void
VideoManager::setDeviceOrientation(const std::string& name, int angle)
VideoManager::setDeviceOrientation(const std::string& deviceId, int angle)
{
videoDeviceMonitor.setDeviceOrientation(name, angle);
videoDeviceMonitor.setDeviceOrientation(deviceId, angle);
}
} // namespace jami

View File

@ -40,7 +40,7 @@ struct VideoManager
{
public:
void setDeviceOrientation(const std::string& name, int angle);
void setDeviceOrientation(const std::string& deviceId, int angle);
/**
* VideoManager acts as a cache of the active VideoInput.

View File

@ -163,14 +163,12 @@ struct DRING_PUBLIC AVSinkTarget {
using VideoCapabilities = std::map<std::string, std::map<std::string, std::vector<std::string>>>;
DRING_PUBLIC std::vector<std::string> getDeviceList();
DRING_PUBLIC VideoCapabilities getCapabilities(const std::string& name);
DRING_PUBLIC std::map<std::string, std::string> getSettings(const std::string& name);
DRING_PUBLIC void applySettings(const std::string& name, const std::map<std::string, std::string>& settings);
DRING_PUBLIC void setDefaultDevice(const std::string& name);
DRING_PUBLIC void setDeviceOrientation(const std::string& name, int angle);
DRING_PUBLIC std::map<std::string, std::string> getDeviceParams(const std::string& name);
DRING_PUBLIC VideoCapabilities getCapabilities(const std::string& deviceId);
DRING_PUBLIC std::map<std::string, std::string> getSettings(const std::string& deviceId);
DRING_PUBLIC void applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings);
DRING_PUBLIC void setDefaultDevice(const std::string& deviceId);
DRING_PUBLIC void setDeviceOrientation(const std::string& deviceId, int angle);
DRING_PUBLIC std::map<std::string, std::string> getDeviceParams(const std::string& deviceId);
DRING_PUBLIC std::string getDefaultDevice();
DRING_PUBLIC std::string getCurrentCodecName(const std::string& callID);
DRING_PUBLIC void startCamera();

View File

@ -189,6 +189,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&) :
deviceImpl_(new VideoDeviceImpl(path))
{
id_ = path;
name = deviceImpl_->name;
}

View File

@ -179,7 +179,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>& devInfo)
: deviceImpl_(new VideoDeviceImpl(path, devInfo))
{
node_ = path;
id_ = path;
name = deviceImpl_->name;
}

View File

@ -42,7 +42,7 @@ class VideoDeviceImpl {
*/
VideoDeviceImpl(const std::string& path);
std::string device;
std::string id;
std::string name;
std::vector<std::string> getChannelList() const;
@ -64,7 +64,7 @@ class VideoDeviceImpl {
};
VideoDeviceImpl::VideoDeviceImpl(const std::string& uniqueID)
: device(uniqueID)
: id(uniqueID)
, current_size_(-1, -1)
, avDevice_([AVCaptureDevice deviceWithUniqueID:
[NSString stringWithCString:uniqueID.c_str() encoding:[NSString defaultCStringEncoding]]])
@ -112,7 +112,7 @@ VideoDeviceImpl::getDeviceParams() const
{
DeviceParams params;
params.name = [[avDevice_ localizedName] UTF8String];
params.input = params.name;
params.input = [[avDevice_ localizedName] UTF8String];
params.framerate = rate_;
params.format = "avfoundation";
params.pixel_format = "nv12";
@ -155,7 +155,7 @@ VideoDeviceImpl::getChannelList() const
VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&) :
deviceImpl_(new VideoDeviceImpl(path))
{
node_ = path;
id_ = path;
name = deviceImpl_->name;
}

View File

@ -125,7 +125,7 @@ public:
*/
VideoDeviceImpl(const std::string& path);
std::string device;
std::string id;
std::string name;
std::vector<std::string> getChannelList() const;
@ -431,14 +431,14 @@ VideoV4l2Channel::getSize(VideoSize s) const
}
VideoDeviceImpl::VideoDeviceImpl(const string& path)
: device(path)
: id(path)
, name()
, channels_()
, channel_(-1, "")
, size_(-1, -1)
, rate_(-1, 1, 0)
{
int fd = open(device.c_str(), O_RDWR);
int fd = open(id.c_str(), O_RDWR);
if (fd == -1)
throw std::runtime_error("could not open device");
@ -544,7 +544,7 @@ VideoDeviceImpl::getDeviceParams() const
{
DeviceParams params;
params.name = name;
params.input = device;
params.input = id;
params.format = "video4linux2";
params.channel_name = channel_.name;
params.channel = channel_.idx;
@ -571,7 +571,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&)
: deviceImpl_(new VideoDeviceImpl(path))
{
node_ = path;
id_ = path;
name = deviceImpl_->name;
}

View File

@ -83,6 +83,7 @@ extractString(const std::map<std::string, std::string>& settings, const std::str
VideoSettings::VideoSettings(const std::map<std::string, std::string>& settings)
{
name = extractString(settings, "name");
id = extractString(settings, "id");
channel = extractString(settings, "channel");
video_size = extractString(settings, "size");
framerate = extractString(settings, "rate");
@ -93,6 +94,7 @@ VideoSettings::to_map() const
{
return {
{"name", name},
{"id", id},
{"size", video_size},
{"channel", channel},
{"rate", framerate}
@ -107,6 +109,7 @@ Node
convert<jami::video::VideoSettings>::encode(const jami::video::VideoSettings& rhs) {
Node node;
node["name"] = rhs.name;
node["id"] = rhs.id;
node["video_size"] = rhs.video_size;
node["channel"] = rhs.channel;
node["framerate"] = rhs.framerate;
@ -120,6 +123,7 @@ convert<jami::video::VideoSettings>::decode(const Node& node, jami::video::Video
return false;
}
rhs.name = node["name"].as<std::string>();
rhs.id = node["id"].as<std::string>();
rhs.video_size = node["video_size"].as<std::string>();
rhs.channel = node["channel"].as<std::string>();
rhs.framerate = node["framerate"].as<std::string>();

View File

@ -96,6 +96,7 @@ struct VideoSettings
std::map<std::string, std::string> to_map() const;
std::string id {};
std::string name {};
std::string channel {};
std::string video_size {};

View File

@ -56,7 +56,7 @@ public:
*/
std::string name {};
const std::string& getNode() const { return node_; }
const std::string& getDeviceId() const { return id_; }
/*
* Get the 3 level deep tree of possible settings for the device.
@ -138,7 +138,8 @@ public:
VideoSettings getSettings() const {
auto params = getDeviceParams();
VideoSettings settings;
settings.name = params.name;
settings.name = name.empty() ? params.name : name;
settings.id = params.input;
settings.channel = params.channel_name;
settings.video_size = sizeToString(params.width, params.height);
settings.framerate = jami::to_string(params.framerate.real());
@ -155,6 +156,7 @@ public:
void applySettings(VideoSettings settings) {
DeviceParams params {};
params.name = settings.name;
params.input = settings.id;
params.channel_name = settings.channel;
auto size = sizeFromString(settings.channel, settings.video_size);
params.width = size.first;
@ -222,7 +224,7 @@ private:
/*
* The device node, e.g. "/dev/video0".
*/
std::string node_ {};
std::string id_ {};
int orientation_ {0};

View File

@ -3,6 +3,7 @@
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -49,18 +50,18 @@ vector<string>
VideoDeviceMonitor::getDeviceList() const
{
std::lock_guard<std::mutex> l(lock_);
vector<string> names;
names.reserve(devices_.size());
vector<string> ids;
ids.reserve(devices_.size());
for (const auto& dev : devices_)
names.emplace_back(dev.name);
return names;
ids.emplace_back(dev.getDeviceId());
return ids;
}
DRing::VideoCapabilities
VideoDeviceMonitor::getCapabilities(const string& name) const
VideoDeviceMonitor::getCapabilities(const string& id) const
{
std::lock_guard<std::mutex> l(lock_);
const auto iter = findDeviceByName(name);
const auto iter = findDeviceById(id);
if (iter == devices_.end())
return DRing::VideoCapabilities();
@ -68,28 +69,28 @@ VideoDeviceMonitor::getCapabilities(const string& name) const
}
VideoSettings
VideoDeviceMonitor::getSettings(const string& name)
VideoDeviceMonitor::getSettings(const string& id)
{
std::lock_guard<std::mutex> l(lock_);
const auto itd = findPreferencesByName(name);
if (itd == preferences_.end())
const auto prefIter = findPreferencesById(id);
if (prefIter == preferences_.end())
return VideoSettings();
return *itd;
return *prefIter;
}
void
VideoDeviceMonitor::applySettings(const string& name, const VideoSettings& settings)
VideoDeviceMonitor::applySettings(const string& id, const VideoSettings& settings)
{
std::lock_guard<std::mutex> l(lock_);
const auto iter = findDeviceByName(name);
const auto iter = findDeviceById(id);
if (iter == devices_.end())
return;
iter->applySettings(settings);
auto it = findPreferencesByName(settings.name);
auto it = findPreferencesById(settings.id);
if (it != preferences_.end())
(*it) = settings;
}
@ -98,30 +99,33 @@ string
VideoDeviceMonitor::getDefaultDevice() const
{
std::lock_guard<std::mutex> l(lock_);
return defaultDevice_;
const auto it = findDeviceById(defaultDevice_);
if (it == std::end(devices_))
return {};
return it->getDeviceId();
}
std::string
VideoDeviceMonitor::getMRLForDefaultDevice() const
{
std::lock_guard<std::mutex> l(lock_);
const auto it = findDeviceByName(defaultDevice_);
const auto it = findDeviceById(defaultDevice_);
if(it == std::end(devices_))
return {};
static const std::string sep = DRing::Media::VideoProtocolPrefix::SEPARATOR;
return DRing::Media::VideoProtocolPrefix::CAMERA + sep + it->getSettings().name;
return DRing::Media::VideoProtocolPrefix::CAMERA + sep + it->getDeviceId();
}
void
VideoDeviceMonitor::setDefaultDevice(const std::string& name)
VideoDeviceMonitor::setDefaultDevice(const std::string& id)
{
std::lock_guard<std::mutex> l(lock_);
const auto itDev = findDeviceByName(name);
const auto itDev = findDeviceById(id);
if (itDev != devices_.end()) {
defaultDevice_ = itDev->name;
defaultDevice_ = itDev->getDeviceId();
// place it at the begining of the prefs
auto itPref = findPreferencesByName(name);
auto itPref = findPreferencesById(itDev->getDeviceId());
if (itPref != preferences_.end()) {
auto settings = *itPref;
preferences_.erase(itPref);
@ -133,64 +137,38 @@ VideoDeviceMonitor::setDefaultDevice(const std::string& name)
}
void
VideoDeviceMonitor::setDeviceOrientation(const std::string& name, int angle)
VideoDeviceMonitor::setDeviceOrientation(const std::string& id, int angle)
{
const auto itd = findDeviceByName(name);
const auto itd = findDeviceById(id);
if (itd != devices_.cend()) {
itd->setOrientation(angle);
} else {
JAMI_WARN("Can't find device %s to set orientation %d", name.c_str(), angle);
JAMI_WARN("Can't find device %s to set orientation %d", id.c_str(), angle);
}
}
DeviceParams
VideoDeviceMonitor::getDeviceParams(const std::string& name) const
VideoDeviceMonitor::getDeviceParams(const std::string& id) const
{
std::lock_guard<std::mutex> l(lock_);
const auto itd = findDeviceByName(name);
const auto itd = findDeviceById(id);
if (itd == devices_.cend())
return DeviceParams();
return itd->getDeviceParams();
}
static int
getNumber(const string &name, size_t *sharp)
{
size_t len = name.length();
// name is too short to be numbered
if (len < 3)
return -1;
for (size_t c = len; c; --c) {
if (name[c] == '#') {
unsigned i;
if (sscanf(name.substr(c).c_str(), "#%u", &i) != 1)
return -1;
*sharp = c;
return i;
}
}
return -1;
}
static void
giveUniqueName(VideoDevice &dev, const vector<VideoDevice> &devices)
{
start:
for (auto &item : devices) {
if (dev.name == item.name) {
size_t sharp;
int num = getNumber(dev.name, &sharp);
if (num < 0) // not numbered
dev.name += " #0";
else {
stringstream ss;
ss << num + 1;
dev.name.replace(sharp + 1, ss.str().length(), ss.str());
}
goto start; // we changed the name, let's look again if it is unique
}
std::string suffix;
uint64_t number = 2;
auto unique = true;
for (;; unique = static_cast<bool>(++number)) {
for (const auto& s : devices)
unique &= static_cast<bool>(s.name.compare(dev.name + suffix));
if (unique)
return (void)(dev.name += suffix);
suffix = " (" + std::to_string(number) + ")";
}
}
@ -203,15 +181,15 @@ notify()
}
void
VideoDeviceMonitor::addDevice(const string& node, const std::vector<std::map<std::string, std::string>>* devInfo)
VideoDeviceMonitor::addDevice(const string& id, const std::vector<std::map<std::string, std::string>>* devInfo)
{
try {
std::lock_guard<std::mutex> l(lock_);
if (findDeviceByNode(node) != devices_.end())
if (findDeviceById(id) != devices_.end())
return;
// instantiate a new unique device
VideoDevice dev {node, *devInfo};
VideoDevice dev { id, *devInfo};
if (dev.getChannelList().empty())
return;
@ -219,43 +197,42 @@ VideoDeviceMonitor::addDevice(const string& node, const std::vector<std::map<std
giveUniqueName(dev, devices_);
// restore its preferences if any, or store the defaults
auto it = findPreferencesByName(dev.name);
if (it != preferences_.end())
auto it = findPreferencesById(id);
if (it != preferences_.end()) {
dev.applySettings(*it);
else {
} else {
dev.applySettings(dev.getDefaultSettings());
preferences_.emplace_back(dev.getSettings());
}
// in case there is no default device on a fresh run
if (defaultDevice_.empty())
defaultDevice_ = dev.name;
defaultDevice_ = dev.getDeviceId();
devices_.emplace_back(std::move(dev));
} catch (const std::exception& e) {
JAMI_ERR("Failed to add device %s: %s", node.c_str(), e.what());
JAMI_ERR("Failed to add device %s: %s", id.c_str(), e.what());
return;
}
notify();
}
void
VideoDeviceMonitor::removeDevice(const string& node)
VideoDeviceMonitor::removeDevice(const string& id)
{
{
std::lock_guard<std::mutex> l(lock_);
const auto it = findDeviceByNode(node);
const auto it = findDeviceById(id);
if (it == devices_.end())
return;
auto removedDeviceName = it->name;
devices_.erase(it);
if (defaultDevice_ == removedDeviceName) {
if (defaultDevice_.find(id) != std::string::npos) {
if (devices_.size() == 0) {
defaultDevice_.clear();
} else {
defaultDevice_ = devices_[0].name;
defaultDevice_ = devices_[0].getDeviceId();
}
}
}
@ -263,53 +240,36 @@ VideoDeviceMonitor::removeDevice(const string& node)
}
vector<VideoDevice>::iterator
VideoDeviceMonitor::findDeviceByName(const string& name)
VideoDeviceMonitor::findDeviceById(const string& id)
{
for (auto it = devices_.begin(); it != devices_.end(); ++it)
if (it->name == name)
if (it->getDeviceId().find(id) != std::string::npos)
return it;
return devices_.end();
}
vector<VideoDevice>::const_iterator
VideoDeviceMonitor::findDeviceByName(const string& name) const
VideoDeviceMonitor::findDeviceById(const string& id) const
{
for (auto it = devices_.cbegin(); it != devices_.cend(); ++it)
if (it->name == name)
return it;
return devices_.cend();
}
vector<VideoDevice>::iterator
VideoDeviceMonitor::findDeviceByNode(const string& node)
{
for (auto it = devices_.begin(); it != devices_.end(); ++it)
if (it->getNode().find(node) != std::string::npos)
return it;
return devices_.end();
}
vector<VideoDevice>::const_iterator
VideoDeviceMonitor::findDeviceByNode(const string& node) const
{
for (auto it = devices_.cbegin(); it != devices_.cend(); ++it)
if (it->getNode().find(node) != std::string::npos)
if (it->getDeviceId().find(id) != std::string::npos)
return it;
return devices_.end();
}
vector<VideoSettings>::iterator
VideoDeviceMonitor::findPreferencesByName(const string& name)
VideoDeviceMonitor::findPreferencesById(const string& id)
{
for (auto it = preferences_.begin(); it != preferences_.end(); ++it)
if (it->name == name) return it;
if (it->id.find(id) != std::string::npos)
return it;
return preferences_.end();
}
void
VideoDeviceMonitor::overwritePreferences(const VideoSettings& settings)
{
auto it = findPreferencesByName(settings.name);
auto it = findPreferencesById(settings.id);
if (it != preferences_.end())
preferences_.erase(it);
preferences_.emplace_back(settings);
@ -332,21 +292,23 @@ VideoDeviceMonitor::unserialize(const YAML::Node &in)
const auto& devices = node["devices"];
for (const auto& dev : devices) {
VideoSettings pref = dev.as<VideoSettings>();
if (pref.name.empty())
if (pref.id.empty())
continue; // discard malformed section
overwritePreferences(pref);
auto itd = findDeviceByName(pref.name);
auto itd = findDeviceById(pref.id);
if (itd != devices_.end())
itd->applySettings(pref);
}
// Restore the default device if present, or select the first one
const string pref = preferences_.empty() ? "" : preferences_[0].name;
const string first = devices_.empty() ? "" : devices_[0].name;
if (findDeviceByName(pref) != devices_.end())
defaultDevice_ = pref;
else
defaultDevice_ = first;
const string prefId = preferences_.empty() ? "" : preferences_[0].id;
const string firstId = devices_.empty() ? "" : devices_[0].getDeviceId();
const auto devIter = findDeviceById(prefId);
if (devIter != devices_.end()) {
defaultDevice_ = devIter->getDeviceId();
} else {
defaultDevice_ = firstId;
}
}
#pragma optimize("", on)
}} // namespace jami::video

View File

@ -56,7 +56,7 @@ class VideoDeviceMonitor : public Serializable
std::string getDefaultDevice() const;
std::string getMRLForDefaultDevice() const;
void setDefaultDevice(const std::string& name);
void setDeviceOrientation(const std::string& name, int angle);
void setDeviceOrientation(const std::string& id, int angle);
void addDevice(const std::string &node, const std::vector<std::map<std::string, std::string>>* devInfo=nullptr);
void removeDevice(const std::string &node);
@ -83,7 +83,7 @@ class VideoDeviceMonitor : public Serializable
std::vector<VideoSettings> preferences_;
void overwritePreferences(const VideoSettings& settings);
std::vector<VideoSettings>::iterator findPreferencesByName(const std::string& name);
std::vector<VideoSettings>::iterator findPreferencesById(const std::string& id);
/*
* Vector containing the video devices.
@ -91,10 +91,8 @@ class VideoDeviceMonitor : public Serializable
std::vector<VideoDevice> devices_;
std::string defaultDevice_ = "";
std::vector<VideoDevice>::iterator findDeviceByName(const std::string& name);
std::vector<VideoDevice>::const_iterator findDeviceByName(const std::string& name) const;
std::vector<VideoDevice>::iterator findDeviceByNode(const std::string& node);
std::vector<VideoDevice>::const_iterator findDeviceByNode(const std::string& node) const;
std::vector<VideoDevice>::iterator findDeviceById(const std::string& id);
std::vector<VideoDevice>::const_iterator findDeviceById(const std::string& id) const;
std::unique_ptr<VideoDeviceMonitorImpl> monitorImpl_;

View File

@ -43,8 +43,8 @@ class VideoDeviceImpl {
/**
* @throw std::runtime_error
*/
VideoDeviceImpl(const std::string& path);
std::string device;
VideoDeviceImpl(const std::string& id);
std::string id;
std::string name;
std::vector<std::string> getChannelList() const;
@ -66,8 +66,8 @@ class VideoDeviceImpl {
void fail(const std::string& error);
};
VideoDeviceImpl::VideoDeviceImpl(const std::string& path)
: device(path)
VideoDeviceImpl::VideoDeviceImpl(const std::string& id)
: id(id)
, name()
, cInterface(new CaptureGraphInterfaces())
{
@ -148,11 +148,11 @@ VideoDeviceImpl::setup()
// We want to get the capabilities of a device with the unique_name
// that corresponds to what was enumerated by the video device monitor.
if (unique_name.find(this->device) == std::string::npos) {
if (unique_name.find(this->id) == std::string::npos) {
continue;
}
this->device = unique_name;
this->id = unique_name;
// get friendly name
VARIANT var;
@ -257,7 +257,7 @@ VideoDeviceImpl::getDeviceParams() const
DeviceParams params;
params.name = name;
params.input = device;
params.input = id;
params.format = "dshow";
AM_MEDIA_TYPE *pmt;
@ -316,7 +316,7 @@ VideoDeviceImpl::getChannelList() const
VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&)
: deviceImpl_(new VideoDeviceImpl(path))
{
node_ = path;
id_ = path;
name = deviceImpl_->name;
}

View File

@ -166,9 +166,9 @@ VideoDeviceMonitorImpl::WinProcCallback(HWND hWnd, UINT message, WPARAM wParam,
if (pThis = reinterpret_cast<VideoDeviceMonitorImpl*>(GetWindowLongPtr(hWnd, GWLP_USERDATA))) {
if (wParam == DBT_DEVICEARRIVAL) {
auto captureDeviceList = pThis->enumerateVideoInputDevices();
for (auto node : captureDeviceList) {
if (node.find(unique_name) != std::string::npos)
pThis->monitor_->addDevice(node);
for (auto id : captureDeviceList) {
if (id.find(unique_name) != std::string::npos)
pThis->monitor_->addDevice(id);
}
} else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
pThis->monitor_->removeDevice(unique_name);