mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
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:
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>();
|
||||
|
@ -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 {};
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user