mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-16 19:25:18 +00:00
webrtcbin: Relay add-ice-candidate errors from Ice implementation to Application
The `add_candidate` vfunc of the GstWebRTCICE interface gained a GstPromise argument, which is an ABI break. We're not aware of any external user of this interface yet so we think it's OK. This change is useful in cases where the application needs to bubble up errors from the underlying ICE agent, for instance when the agent was given an invalid ICE candidate. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3960>
This commit is contained in:
parent
cf96d96f6a
commit
906b90287c
5 changed files with 84 additions and 18 deletions
|
@ -28,10 +28,10 @@ customice_agent_find_transport (GstWebRTCICE * ice,
|
|||
|
||||
void
|
||||
customice_agent_add_candidate (GstWebRTCICE * ice,
|
||||
GstWebRTCICEStream * stream, const gchar * candidate)
|
||||
GstWebRTCICEStream * stream, const gchar * candidate, GstPromise * promise)
|
||||
{
|
||||
GstWebRTCICE *c_ice = GST_WEBRTC_ICE (CUSTOMICE_AGENT (ice)->nice_agent);
|
||||
gst_webrtc_ice_add_candidate (c_ice, stream, candidate);
|
||||
gst_webrtc_ice_add_candidate (c_ice, stream, candidate, promise);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
@ -5303,12 +5303,15 @@ typedef struct
|
|||
{
|
||||
guint mlineindex;
|
||||
gchar *candidate;
|
||||
GstPromise *promise;
|
||||
} IceCandidateItem;
|
||||
|
||||
static void
|
||||
_clear_ice_candidate_item (IceCandidateItem * item)
|
||||
{
|
||||
g_free (item->candidate);
|
||||
if (item->promise)
|
||||
gst_promise_unref (item->promise);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5320,12 +5323,23 @@ _add_ice_candidate (GstWebRTCBin * webrtc, IceCandidateItem * item,
|
|||
stream = _find_ice_stream_for_session (webrtc, item->mlineindex);
|
||||
if (stream == NULL) {
|
||||
if (drop_invalid) {
|
||||
GST_WARNING_OBJECT (webrtc, "Unknown mline %u, dropping",
|
||||
item->mlineindex);
|
||||
if (item->promise) {
|
||||
GError *error =
|
||||
g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE,
|
||||
"Unknown mline %u, dropping", item->mlineindex);
|
||||
GstStructure *s = gst_structure_new ("application/x-gst-promise",
|
||||
"error", G_TYPE_ERROR, error, NULL);
|
||||
gst_promise_reply (item->promise, s);
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (webrtc, "Unknown mline %u, dropping",
|
||||
item->mlineindex);
|
||||
}
|
||||
} else {
|
||||
IceCandidateItem new;
|
||||
new.mlineindex = item->mlineindex;
|
||||
new.candidate = g_strdup (item->candidate);
|
||||
new.promise = NULL;
|
||||
GST_INFO_OBJECT (webrtc, "Unknown mline %u, deferring", item->mlineindex);
|
||||
|
||||
ICE_LOCK (webrtc);
|
||||
|
@ -5338,7 +5352,8 @@ _add_ice_candidate (GstWebRTCBin * webrtc, IceCandidateItem * item,
|
|||
GST_LOG_OBJECT (webrtc, "adding ICE candidate with mline:%u, %s",
|
||||
item->mlineindex, item->candidate);
|
||||
|
||||
gst_webrtc_ice_add_candidate (webrtc->priv->ice, stream, item->candidate);
|
||||
gst_webrtc_ice_add_candidate (webrtc->priv->ice, stream, item->candidate,
|
||||
item->promise);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5364,7 +5379,7 @@ _add_ice_candidates_from_sdp (GstWebRTCBin * webrtc, gint mlineindex,
|
|||
candidate = g_strdup_printf ("a=candidate:%s", attr->value);
|
||||
GST_LOG_OBJECT (webrtc, "adding ICE candidate with mline:%u, %s",
|
||||
mlineindex, candidate);
|
||||
gst_webrtc_ice_add_candidate (webrtc->priv->ice, stream, candidate);
|
||||
gst_webrtc_ice_add_candidate (webrtc->priv->ice, stream, candidate, NULL);
|
||||
g_free (candidate);
|
||||
}
|
||||
}
|
||||
|
@ -6768,6 +6783,7 @@ _add_ice_candidate_task (GstWebRTCBin * webrtc, IceCandidateItem * item)
|
|||
IceCandidateItem new;
|
||||
new.mlineindex = item->mlineindex;
|
||||
new.candidate = g_steal_pointer (&item->candidate);
|
||||
new.promise = NULL;
|
||||
|
||||
ICE_LOCK (webrtc);
|
||||
g_array_append_val (webrtc->priv->pending_remote_ice_candidates, new);
|
||||
|
@ -6794,6 +6810,7 @@ gst_webrtc_bin_add_ice_candidate (GstWebRTCBin * webrtc, guint mline,
|
|||
|
||||
item = g_new0 (IceCandidateItem, 1);
|
||||
item->mlineindex = mline;
|
||||
item->promise = promise ? gst_promise_ref (promise) : NULL;
|
||||
if (attr && attr[0] != 0) {
|
||||
if (!g_ascii_strncasecmp (attr, "a=candidate:", 12))
|
||||
item->candidate = g_strdup (attr);
|
||||
|
@ -6885,6 +6902,7 @@ _on_local_ice_candidate_cb (GstWebRTCICE * ice, guint session_id,
|
|||
|
||||
item.mlineindex = session_id;
|
||||
item.candidate = g_strdup (candidate);
|
||||
item.promise = NULL;
|
||||
|
||||
ICE_LOCK (webrtc);
|
||||
g_array_append_val (webrtc->priv->pending_local_ice_candidates, item);
|
||||
|
|
|
@ -101,17 +101,19 @@ gst_webrtc_ice_find_transport (GstWebRTCICE * ice,
|
|||
* @ice: The #GstWebRTCICE
|
||||
* @stream: The #GstWebRTCICEStream
|
||||
* @candidate: The ICE candidate
|
||||
* @promise: (allow none): A #GstPromise for task notifications (Since: 1.24)
|
||||
*
|
||||
* Since: 1.22
|
||||
*/
|
||||
void
|
||||
gst_webrtc_ice_add_candidate (GstWebRTCICE * ice,
|
||||
GstWebRTCICEStream * stream, const gchar * candidate)
|
||||
GstWebRTCICEStream * stream, const gchar * candidate, GstPromise * promise)
|
||||
{
|
||||
g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
|
||||
g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate);
|
||||
|
||||
GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate (ice, stream, candidate);
|
||||
GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate (ice, stream, candidate,
|
||||
promise);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,7 +84,8 @@ struct _GstWebRTCICEClass {
|
|||
GstWebRTCICEStream * stream);
|
||||
void (*add_candidate) (GstWebRTCICE * ice,
|
||||
GstWebRTCICEStream * stream,
|
||||
const gchar * candidate);
|
||||
const gchar * candidate,
|
||||
GstPromise * promise);
|
||||
gboolean (*set_local_credentials) (GstWebRTCICE * ice,
|
||||
GstWebRTCICEStream * stream,
|
||||
const gchar * ufrag,
|
||||
|
@ -169,7 +170,8 @@ gboolean gst_webrtc_ice_gather_candidates (GstWebRTCIC
|
|||
GST_WEBRTC_API
|
||||
void gst_webrtc_ice_add_candidate (GstWebRTCICE * ice,
|
||||
GstWebRTCICEStream * stream,
|
||||
const gchar * candidate);
|
||||
const gchar * candidate,
|
||||
GstPromise * promise);
|
||||
|
||||
GST_WEBRTC_API
|
||||
gboolean gst_webrtc_ice_set_local_credentials (GstWebRTCICE * ice,
|
||||
|
|
|
@ -699,6 +699,7 @@ struct resolve_candidate_data
|
|||
guint nice_stream_id;
|
||||
char *prefix;
|
||||
char *postfix;
|
||||
GstPromise *promise;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -706,6 +707,8 @@ free_resolve_candidate_data (struct resolve_candidate_data *rc)
|
|||
{
|
||||
g_free (rc->prefix);
|
||||
g_free (rc->postfix);
|
||||
if (rc->promise)
|
||||
gst_promise_unref (rc->promise);
|
||||
g_free (rc);
|
||||
}
|
||||
|
||||
|
@ -743,8 +746,14 @@ on_candidate_resolved (GstWebRTCICE * ice, GAsyncResult * res,
|
|||
GstWebRTCNice *nice = GST_WEBRTC_NICE (ice);
|
||||
|
||||
if (!(addresses = resolve_host_finish (nice, res, &error))) {
|
||||
GST_WARNING_OBJECT (ice, "Could not resolve candidate address: %s",
|
||||
error->message);
|
||||
if (rc->promise) {
|
||||
GstStructure *s = gst_structure_new ("application/x-gst-promise", "error",
|
||||
G_TYPE_ERROR, error, NULL);
|
||||
gst_promise_reply (rc->promise, s);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (ice, "Could not resolve candidate address: %s",
|
||||
error->message);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
@ -764,7 +773,18 @@ on_candidate_resolved (GstWebRTCICE * ice, GAsyncResult * res,
|
|||
rc->nice_stream_id, new_candidate);
|
||||
g_free (new_candidate);
|
||||
if (!cand) {
|
||||
GST_WARNING_OBJECT (ice, "Could not parse candidate \'%s\'", new_candidate);
|
||||
if (rc->promise) {
|
||||
GError *error =
|
||||
g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE,
|
||||
"Could not parse candidate \'%s\'", new_candidate);
|
||||
GstStructure *s = gst_structure_new ("application/x-gst-promise", "error",
|
||||
G_TYPE_ERROR, error, NULL);
|
||||
gst_promise_reply (rc->promise, s);
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (ice, "Could not parse candidate \'%s\'",
|
||||
new_candidate);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -777,7 +797,7 @@ on_candidate_resolved (GstWebRTCICE * ice, GAsyncResult * res,
|
|||
/* candidate must start with "a=candidate:" or be NULL*/
|
||||
static void
|
||||
gst_webrtc_nice_add_candidate (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
|
||||
const gchar * candidate)
|
||||
const gchar * candidate, GstPromise * promise)
|
||||
{
|
||||
struct NiceStreamItem *item;
|
||||
NiceCandidate *cand;
|
||||
|
@ -801,14 +821,37 @@ gst_webrtc_nice_add_candidate (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
|
|||
struct resolve_candidate_data *rc;
|
||||
|
||||
if (!get_candidate_address (candidate, &prefix, &address, &postfix)) {
|
||||
GST_WARNING_OBJECT (nice, "Failed to retrieve address from candidate %s",
|
||||
candidate);
|
||||
if (promise) {
|
||||
GError *error =
|
||||
g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE,
|
||||
"Failed to retrieve address from candidate %s",
|
||||
candidate);
|
||||
GstStructure *s = gst_structure_new ("application/x-gst-promise",
|
||||
"error", G_TYPE_ERROR, error, NULL);
|
||||
gst_promise_reply (promise, s);
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (nice,
|
||||
"Failed to retrieve address from candidate %s", candidate);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!g_str_has_suffix (address, ".local")) {
|
||||
GST_WARNING_OBJECT (nice, "candidate address \'%s\' does not end "
|
||||
"with \'.local\'", address);
|
||||
if (promise) {
|
||||
GError *error =
|
||||
g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE,
|
||||
"candidate address \'%s\' does not end " "with \'.local\'",
|
||||
address);
|
||||
GstStructure *s = gst_structure_new ("application/x-gst-promise",
|
||||
"error", G_TYPE_ERROR, error, NULL);
|
||||
gst_promise_reply (promise, s);
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (nice,
|
||||
"candidate address \'%s\' does not end "
|
||||
"with \'.local\'", address);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -816,6 +859,7 @@ gst_webrtc_nice_add_candidate (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
|
|||
rc->nice_stream_id = item->nice_stream_id;
|
||||
rc->prefix = prefix;
|
||||
rc->postfix = postfix;
|
||||
rc->promise = promise ? gst_promise_ref (promise) : NULL;
|
||||
resolve_host_async (nice, address,
|
||||
(GAsyncReadyCallback) on_candidate_resolved, rc,
|
||||
(GDestroyNotify) free_resolve_candidate_data);
|
||||
|
|
Loading…
Reference in a new issue