|
|
@ -169,6 +169,30 @@ createAnswer(GstPromise *promise, gpointer webrtc) |
|
|
|
g_signal_emit_by_name(webrtc, "create-answer", nullptr, promise); |
|
|
|
g_signal_emit_by_name(webrtc, "create-answer", nullptr, promise); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if GST_CHECK_VERSION(1, 17, 0) |
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
iceGatheringStateChanged(GstElement *webrtc, |
|
|
|
|
|
|
|
GParamSpec *pspec G_GNUC_UNUSED, |
|
|
|
|
|
|
|
gpointer user_data G_GNUC_UNUSED) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
GstWebRTCICEGatheringState newState; |
|
|
|
|
|
|
|
g_object_get(webrtc, "ice-gathering-state", &newState, nullptr); |
|
|
|
|
|
|
|
if (newState == GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE) { |
|
|
|
|
|
|
|
nhlog::ui()->debug("WebRTC: GstWebRTCICEGatheringState -> Complete"); |
|
|
|
|
|
|
|
if (isoffering_) { |
|
|
|
|
|
|
|
emit WebRTCSession::instance().offerCreated(localsdp_, localcandidates_); |
|
|
|
|
|
|
|
emit WebRTCSession::instance().stateChanged( |
|
|
|
|
|
|
|
WebRTCSession::State::OFFERSENT); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
emit WebRTCSession::instance().answerCreated(localsdp_, localcandidates_); |
|
|
|
|
|
|
|
emit WebRTCSession::instance().stateChanged( |
|
|
|
|
|
|
|
WebRTCSession::State::ANSWERSENT); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
|
|
|
|
gboolean |
|
|
|
gboolean |
|
|
|
onICEGatheringCompletion(gpointer timerid) |
|
|
|
onICEGatheringCompletion(gpointer timerid) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -182,6 +206,7 @@ onICEGatheringCompletion(gpointer timerid) |
|
|
|
} |
|
|
|
} |
|
|
|
return FALSE; |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
void |
|
|
|
addLocalICECandidate(GstElement *webrtc G_GNUC_UNUSED, |
|
|
|
addLocalICECandidate(GstElement *webrtc G_GNUC_UNUSED, |
|
|
@ -200,13 +225,15 @@ addLocalICECandidate(GstElement *webrtc G_GNUC_UNUSED, |
|
|
|
localcandidates_.push_back({"audio", (uint16_t)mlineIndex, candidate}); |
|
|
|
localcandidates_.push_back({"audio", (uint16_t)mlineIndex, candidate}); |
|
|
|
|
|
|
|
|
|
|
|
// GStreamer v1.16: webrtcbin's notify::ice-gathering-state triggers
|
|
|
|
// GStreamer v1.16: webrtcbin's notify::ice-gathering-state triggers
|
|
|
|
// GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE too early. Fixed in v1.18. Use a 100ms timeout in
|
|
|
|
// GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE too early. Fixed in v1.17.
|
|
|
|
// the meantime
|
|
|
|
// Use a 100ms timeout in the meantime
|
|
|
|
|
|
|
|
#if !GST_CHECK_VERSION(1, 17, 0) |
|
|
|
static guint timerid = 0; |
|
|
|
static guint timerid = 0; |
|
|
|
if (timerid) |
|
|
|
if (timerid) |
|
|
|
g_source_remove(timerid); |
|
|
|
g_source_remove(timerid); |
|
|
|
|
|
|
|
|
|
|
|
timerid = g_timeout_add(100, onICEGatheringCompletion, &timerid); |
|
|
|
timerid = g_timeout_add(100, onICEGatheringCompletion, &timerid); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
void |
|
|
@ -437,6 +464,11 @@ WebRTCSession::startPipeline(int opusPayloadType) |
|
|
|
gst_element_set_state(pipe_, GST_STATE_READY); |
|
|
|
gst_element_set_state(pipe_, GST_STATE_READY); |
|
|
|
g_signal_connect(webrtc_, "pad-added", G_CALLBACK(addDecodeBin), pipe_); |
|
|
|
g_signal_connect(webrtc_, "pad-added", G_CALLBACK(addDecodeBin), pipe_); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if GST_CHECK_VERSION(1, 17, 0) |
|
|
|
|
|
|
|
// capture ICE gathering completion
|
|
|
|
|
|
|
|
g_signal_connect( |
|
|
|
|
|
|
|
webrtc_, "notify::ice-gathering-state", G_CALLBACK(iceGatheringStateChanged), nullptr); |
|
|
|
|
|
|
|
#endif |
|
|
|
// webrtcbin lifetime is the same as that of the pipeline
|
|
|
|
// webrtcbin lifetime is the same as that of the pipeline
|
|
|
|
gst_object_unref(webrtc_); |
|
|
|
gst_object_unref(webrtc_); |
|
|
|
|
|
|
|
|
|
|
|