diff --git a/src/voip/CallManager.cpp b/src/voip/CallManager.cpp
index 3d795fc1..135d0b6a 100644
--- a/src/voip/CallManager.cpp
+++ b/src/voip/CallManager.cpp
@@ -193,9 +193,8 @@ CallManager::sendInvite(const QString &roomid, CallType callType, unsigned int w
auto roomInfo = cache::singleRoomInfo(roomid.toStdString());
std::string errorMessage;
- if (!session_.havePlugins(false, &errorMessage) ||
- ((callType == CallType::VIDEO || callType == CallType::SCREEN) &&
- !session_.havePlugins(true, &errorMessage))) {
+ if (!session_.havePlugins(
+ callType != CallType::VOICE, callType == CallType::SCREEN, &errorMessage)) {
emit ChatPage::instance()->showNotification(QString::fromStdString(errorMessage));
return;
}
@@ -469,8 +468,8 @@ CallManager::acceptInvite()
stopRingtone();
std::string errorMessage;
- if (!session_.havePlugins(false, &errorMessage) ||
- (callType_ == CallType::VIDEO && !session_.havePlugins(true, &errorMessage))) {
+ if (!session_.havePlugins(
+ callType_ != CallType::VOICE, callType_ == CallType::SCREEN, &errorMessage)) {
emit ChatPage::instance()->showNotification(QString::fromStdString(errorMessage));
hangUp(CallHangUp::Reason::UserMediaFailed);
return;
diff --git a/src/voip/WebRTCSession.cpp b/src/voip/WebRTCSession.cpp
index 7760e2ea..001781e4 100644
--- a/src/voip/WebRTCSession.cpp
+++ b/src/voip/WebRTCSession.cpp
@@ -580,53 +580,81 @@ getMediaAttributes(const GstSDPMessage *sdp,
}
bool
-WebRTCSession::havePlugins(bool isVideo, std::string *errorMessage)
+WebRTCSession::havePlugins(bool isVideo, bool isX11Screenshare, std::string *errorMessage)
{
if (!initialised_ && !init(errorMessage))
return false;
- if (!isVideo && haveVoicePlugins_)
- return true;
- if (isVideo && haveVideoPlugins_)
+ if (haveVoicePlugins_ && (!isVideo || haveVideoPlugins_) &&
+ (!isX11Screenshare || haveX11ScreensharePlugins_))
return true;
- const gchar *voicePlugins[] = {"audioconvert",
- "audioresample",
- "autodetect",
- "dtls",
- "nice",
- "opus",
- "playback",
- "rtpmanager",
- "srtp",
- "volume",
- "webrtc",
- nullptr};
+ static constexpr std::initializer_list<const char *> audio_elements = {
+ "audioconvert",
+ "audioresample",
+ "autoaudiosink",
+ "capsfilter",
+ "decodebin",
+ "opusenc",
+ "queue",
+ "rtpopuspay",
+ "volume",
+ "webrtcbin",
+ };
- const gchar *videoPlugins[] = {
- "compositor", "opengl", "qmlgl", "rtp", "videoconvert", "vpx", nullptr};
+ static constexpr std::initializer_list<const char *> video_elements = {
+ "compositor",
+ "glcolorconvert",
+ "glsinkbin",
+ "glupload",
+ "qmlglsink",
+ "rtpvp8pay",
+ "tee",
+ "videoconvert",
+ "videoscale",
+ "vp8enc",
+ };
+ static constexpr std::initializer_list<const char *> screenshare_elements = {
+ "ximagesink",
+ "ximagesrc",
+ };
- std::string strError("Missing GStreamer plugins: ");
- const gchar **needed = isVideo ? videoPlugins : voicePlugins;
- bool &havePlugins = isVideo ? haveVideoPlugins_ : haveVoicePlugins_;
- havePlugins = true;
+ std::string strError("Missing GStreamer elements: ");
GstRegistry *registry = gst_registry_get();
- for (guint i = 0; i < g_strv_length((gchar **)needed); i++) {
- GstPlugin *plugin = gst_registry_find_plugin(registry, needed[i]);
- if (!plugin) {
- havePlugins = false;
- strError += std::string(needed[i]) + " ";
- continue;
+
+ auto check_plugins = [&strError,
+ registry](const std::initializer_list<const char *> &elements) {
+ bool havePlugins = true;
+ for (const auto &element : elements) {
+ GstPluginFeature *plugin =
+ gst_registry_find_feature(registry, element, GST_TYPE_ELEMENT_FACTORY);
+ if (!plugin) {
+ havePlugins = false;
+ strError += std::string(element) + " ";
+ continue;
+ }
+ gst_object_unref(plugin);
}
- gst_object_unref(plugin);
- }
- if (!havePlugins) {
+
+ return havePlugins;
+ };
+
+ haveVoicePlugins_ = check_plugins(audio_elements);
+
+ // check both elements at once
+ if (isVideo)
+ haveVideoPlugins_ = check_plugins(video_elements);
+ if (isX11Screenshare)
+ haveX11ScreensharePlugins_ = check_plugins(screenshare_elements);
+
+ if (!haveVoicePlugins_ || (isVideo && !haveVideoPlugins_) ||
+ (isX11Screenshare && !haveX11ScreensharePlugins_)) {
nhlog::ui()->error(strError);
if (errorMessage)
*errorMessage = strError;
return false;
}
- if (isVideo) {
+ if (isVideo || isX11Screenshare) {
// load qmlglsink to register GStreamer's GstGLVideoItem QML type
GstElement *qmlglsink = gst_element_factory_make("qmlglsink", nullptr);
gst_object_unref(qmlglsink);
diff --git a/src/voip/WebRTCSession.h b/src/voip/WebRTCSession.h
index da13e356..911a9b6c 100644
--- a/src/voip/WebRTCSession.h
+++ b/src/voip/WebRTCSession.h
@@ -54,7 +54,7 @@ public:
return instance;
}
- bool havePlugins(bool isVideo, std::string *errorMessage = nullptr);
+ bool havePlugins(bool isVideo, bool isX11Screenshare, std::string *errorMessage = nullptr);
webrtc::CallType callType() const { return callType_; }
webrtc::State state() const { return state_; }
bool haveLocalPiP() const;
@@ -93,18 +93,19 @@ private:
WebRTCSession();
CallDevices &devices_;
- bool initialised_ = false;
- bool haveVoicePlugins_ = false;
- bool haveVideoPlugins_ = false;
- webrtc::CallType callType_ = webrtc::CallType::VOICE;
- webrtc::State state_ = webrtc::State::DISCONNECTED;
- bool isOffering_ = false;
- bool isRemoteVideoRecvOnly_ = false;
- bool isRemoteVideoSendOnly_ = false;
- QQuickItem *videoItem_ = nullptr;
- GstElement *pipe_ = nullptr;
- GstElement *webrtc_ = nullptr;
- unsigned int busWatchId_ = 0;
+ bool initialised_ = false;
+ bool haveVoicePlugins_ = false;
+ bool haveVideoPlugins_ = false;
+ bool haveX11ScreensharePlugins_ = false;
+ webrtc::CallType callType_ = webrtc::CallType::VOICE;
+ webrtc::State state_ = webrtc::State::DISCONNECTED;
+ bool isOffering_ = false;
+ bool isRemoteVideoRecvOnly_ = false;
+ bool isRemoteVideoSendOnly_ = false;
+ QQuickItem *videoItem_ = nullptr;
+ GstElement *pipe_ = nullptr;
+ GstElement *webrtc_ = nullptr;
+ unsigned int busWatchId_ = 0;
std::vector<std::string> turnServers_;
uint32_t shareWindowId_ = 0;
|