webrtc: Expose RTCError enum
authorPhilippe Normand <philn@igalia.com>
Fri, 28 Jan 2022 17:11:41 +0000 (17:11 +0000)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Sat, 29 Jan 2022 14:42:22 +0000 (14:42 +0000)
The error codes not complying with the spec are now notified with the
GST_WEBRTC_ERROR_INTERNAL_FAILURE code.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1485>

subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c
subprojects/gst-plugins-bad/ext/webrtc/utils.c
subprojects/gst-plugins-bad/ext/webrtc/utils.h
subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.c
subprojects/gst-plugins-bad/ext/webrtc/webrtcsdp.c
subprojects/gst-plugins-bad/gst-libs/gst/webrtc/meson.build
subprojects/gst-plugins-bad/gst-libs/gst/webrtc/webrtc.c [new file with mode: 0644]
subprojects/gst-plugins-bad/gst-libs/gst/webrtc/webrtc_fwd.h
subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c

index 9d5b263..9986657 100644 (file)
@@ -926,7 +926,7 @@ _execute_op (GstWebRTCBinTask * op)
 
     if (op->promise) {
       GError *error =
-          g_error_new (GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_CLOSED,
+          g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INVALID_STATE,
           "webrtcbin is closed. aborting execution.");
       GstStructure *s = gst_structure_new ("application/x-gst-promise",
           "error", G_TYPE_ERROR, error, NULL);
@@ -1704,8 +1704,8 @@ _query_pad_caps (GstWebRTCBin * webrtc, GstWebRTCRTPTransceiver * rtp_trans,
 
   /* Only return an error if actual empty caps were returned from the query. */
   if (gst_caps_is_empty (caps)) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_CAPS_NEGOTIATION_FAILED,
+    g_set_error (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_INTERNAL_FAILURE,
         "Caps negotiation on pad %s failed", GST_PAD_NAME (pad));
     gst_clear_caps (&caps);
     gst_caps_unref (filter);
@@ -1840,9 +1840,9 @@ _find_codec_preferences (GstWebRTCBin * webrtc,
       gst_clear_caps (&caps);
 
       if (gst_caps_is_empty (intersection)) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR,
-            GST_WEBRTC_BIN_ERROR_CAPS_NEGOTIATION_FAILED,
-            "Caps negotiation on pad %s failed againt codec preferences",
+        g_set_error (error, GST_WEBRTC_ERROR,
+            GST_WEBRTC_ERROR_INTERNAL_FAILURE,
+            "Caps negotiation on pad %s failed against codec preferences",
             GST_PAD_NAME (pad));
         gst_clear_caps (&intersection);
       } else {
@@ -2841,8 +2841,8 @@ _parse_extmap (GQuark field_id, const GValue * value, GError ** error)
   if (!ret && error) {
     gchar *val_str = gst_value_serialize (value);
 
-    g_set_error (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_CAPS_NEGOTIATION_FAILED,
+    g_set_error (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_INTERNAL_FAILURE,
         "Invalid value for %s: %s", g_quark_to_string (field_id), val_str);
     g_free (val_str);
   }
@@ -2886,8 +2886,8 @@ _dedup_extmap_field (GQuark field_id, const GValue * value, ExtmapData * data)
         GST_ERROR
             ("extmap contains different values for id %s (%s != %s)",
             g_quark_to_string (field_id), old_value, new_value);
-        g_set_error (data->error, GST_WEBRTC_BIN_ERROR,
-            GST_WEBRTC_BIN_ERROR_CAPS_NEGOTIATION_FAILED,
+        g_set_error (data->error, GST_WEBRTC_ERROR,
+            GST_WEBRTC_ERROR_INTERNAL_FAILURE,
             "extmap contains different values for id %s (%s != %s)",
             g_quark_to_string (field_id), old_value, new_value);
         data->ret = FALSE;
@@ -3392,8 +3392,8 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options,
             g_assert (!g_list_find (seen_transceivers, trans));
 
             if (wtrans->mline_locked && trans->mline != media_idx) {
-              g_set_error (error, GST_WEBRTC_BIN_ERROR,
-                  GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION,
+              g_set_error (error, GST_WEBRTC_ERROR,
+                  GST_WEBRTC_ERROR_INTERNAL_FAILURE,
                   "Previous negotiatied transceiver %"
                   GST_PTR_FORMAT " with mid %s was in mline %d but transceiver"
                   " has locked mline %u", trans, trans->mid, media_idx,
@@ -3414,8 +3414,8 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options,
 
             if (g_hash_table_contains (all_mids, mid)) {
               gst_sdp_media_free (media);
-              g_set_error (error, GST_WEBRTC_BIN_ERROR,
-                  GST_WEBRTC_BIN_ERROR_FAILED,
+              g_set_error (error, GST_WEBRTC_ERROR,
+                  GST_WEBRTC_ERROR_INTERNAL_FAILURE,
                   "Duplicate mid %s when creating offer", mid);
               goto cancel_offer;
             }
@@ -3459,7 +3459,7 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options,
 
     if (trans->mid) {
       if (g_hash_table_contains (all_mids, trans->mid)) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_FAILED,
+        g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE,
             "Duplicate mid %s when creating offer", trans->mid);
         goto cancel_offer;
       }
@@ -3539,8 +3539,8 @@ _create_offer_task (GstWebRTCBin * webrtc, const GstStructure * options,
             continue;
           g_assert (wtrans->mline_locked);
 
-          g_set_error (error, GST_WEBRTC_BIN_ERROR,
-              GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION,
+          g_set_error (error, GST_WEBRTC_ERROR,
+              GST_WEBRTC_ERROR_INTERNAL_FAILURE,
               "Tranceiver %" GST_PTR_FORMAT " with mid %s has locked mline %d"
               " but the whole offer only has %u sections", trans, trans->mid,
               trans->mline, media_idx);
@@ -3779,8 +3779,8 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options,
   GstSDPMessage *last_answer = _get_latest_self_generated_sdp (webrtc);
 
   if (!webrtc->pending_remote_description) {
-    g_set_error_literal (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_INVALID_STATE,
+    g_set_error_literal (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_INVALID_STATE,
         "Asked to create an answer without a remote description");
     return NULL;
   }
@@ -3793,7 +3793,7 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options,
     guint bundle_media_index;
 
     if (!_get_bundle_index (pending_remote->sdp, bundled, &bundle_idx)) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "Bundle tag is %s but no media found matching", bundled[0]);
       goto out;
     }
@@ -4289,7 +4289,7 @@ gst_webrtc_bin_create_offer (GstWebRTCBin * webrtc,
   if (!gst_webrtc_bin_enqueue_task (webrtc, (GstWebRTCBinFunc) _create_sdp_task,
           data, (GDestroyNotify) _free_create_sdp_data, promise)) {
     GError *error =
-        g_error_new (GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_CLOSED,
+        g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INVALID_STATE,
         "Could not create offer. webrtcbin is closed");
     GstStructure *s = gst_structure_new ("application/x-gst-promise",
         "error", G_TYPE_ERROR, error, NULL);
@@ -4313,7 +4313,7 @@ gst_webrtc_bin_create_answer (GstWebRTCBin * webrtc,
   if (!gst_webrtc_bin_enqueue_task (webrtc, (GstWebRTCBinFunc) _create_sdp_task,
           data, (GDestroyNotify) _free_create_sdp_data, promise)) {
     GError *error =
-        g_error_new (GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_CLOSED,
+        g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INVALID_STATE,
         "Could not create answer. webrtcbin is closed.");
     GstStructure *s = gst_structure_new ("application/x-gst-promise",
         "error", G_TYPE_ERROR, error, NULL);
@@ -4876,7 +4876,7 @@ _update_transceiver_from_sdp_media (GstWebRTCBin * webrtc,
     remote_setup = _get_dtls_setup_from_media (remote_media);
     new_setup = _get_final_setup (local_setup, remote_setup);
     if (new_setup == GST_WEBRTC_DTLS_SETUP_NONE) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "Cannot intersect direction attributes for media %u", media_idx);
       return;
     }
@@ -4885,7 +4885,7 @@ _update_transceiver_from_sdp_media (GstWebRTCBin * webrtc,
     remote_dir = _get_direction_from_media (remote_media);
     new_dir = _get_final_direction (local_dir, remote_dir);
     if (new_dir == GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "Cannot intersect dtls setup attributes for media %u", media_idx);
       return;
     }
@@ -4893,8 +4893,8 @@ _update_transceiver_from_sdp_media (GstWebRTCBin * webrtc,
     if (prev_dir != GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE
         && new_dir != GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE
         && prev_dir != new_dir) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_NOT_IMPLEMENTED,
+      g_set_error (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_INTERNAL_FAILURE,
           "transceiver direction changes are not implemented. Media %u",
           media_idx);
       return;
@@ -5107,7 +5107,7 @@ _update_data_channel_from_sdp_media (GstWebRTCBin * webrtc,
   remote_setup = _get_dtls_setup_from_media (remote_media);
   new_setup = _get_final_setup (local_setup, remote_setup);
   if (new_setup == GST_WEBRTC_DTLS_SETUP_NONE) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "Cannot intersect dtls setup for media %u", media_idx);
     return;
   }
@@ -5120,7 +5120,7 @@ _update_data_channel_from_sdp_media (GstWebRTCBin * webrtc,
   local_port = _get_sctp_port_from_media (local_media);
   remote_port = _get_sctp_port_from_media (local_media);
   if (local_port == -1 || remote_port == -1) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "Could not find sctp port for media %u (local %i, remote %i)",
         media_idx, local_port, remote_port);
     return;
@@ -5260,7 +5260,7 @@ _update_transceivers_from_sdp (GstWebRTCBin * webrtc, SDPSource source,
   if (bundled) {
 
     if (!_get_bundle_index (sdp->sdp, bundled, &bundle_idx)) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "Bundle tag is %s but no media found matching", bundled[0]);
       goto done;
     }
@@ -5312,7 +5312,7 @@ _update_transceivers_from_sdp (GstWebRTCBin * webrtc, SDPSource source,
       webrtc_transceiver_set_transport ((WebRTCTransceiver *) trans, stream);
 
     if (source == SDP_LOCAL && sdp->type == GST_WEBRTC_SDP_TYPE_OFFER && !trans) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "State mismatch.  Could not find local transceiver by mline %u", i);
       goto done;
     } else {
@@ -5415,8 +5415,8 @@ check_locked_mlines (GstWebRTCBin * webrtc, GstWebRTCSessionDescription * sdp,
       continue;
 
     if (rtp_trans->mline != i) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION,
+      g_set_error (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_INTERNAL_FAILURE,
           "m-line with mid %s is at position %d, but was locked to %d, "
           "rejecting", rtp_trans->mid, i, rtp_trans->mline);
       return FALSE;
@@ -5425,8 +5425,8 @@ check_locked_mlines (GstWebRTCBin * webrtc, GstWebRTCSessionDescription * sdp,
     if (rtp_trans->kind != GST_WEBRTC_KIND_UNKNOWN) {
       if (!g_strcmp0 (gst_sdp_media_get_media (media), "audio") &&
           rtp_trans->kind != GST_WEBRTC_KIND_AUDIO) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR,
-            GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION,
+        g_set_error (error, GST_WEBRTC_ERROR,
+            GST_WEBRTC_ERROR_INTERNAL_FAILURE,
             "m-line %d was locked to audio, but SDP has %s media", i,
             gst_sdp_media_get_media (media));
         return FALSE;
@@ -5434,8 +5434,8 @@ check_locked_mlines (GstWebRTCBin * webrtc, GstWebRTCSessionDescription * sdp,
 
       if (!g_strcmp0 (gst_sdp_media_get_media (media), "video") &&
           rtp_trans->kind != GST_WEBRTC_KIND_VIDEO) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR,
-            GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION,
+        g_set_error (error, GST_WEBRTC_ERROR,
+            GST_WEBRTC_ERROR_INTERNAL_FAILURE,
             "m-line %d was locked to video, but SDP has %s media", i,
             gst_sdp_media_get_media (media));
         return FALSE;
@@ -5511,7 +5511,7 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd)
 
   if (bundled) {
     if (!_get_bundle_index (sd->sdp->sdp, bundled, &bundle_idx)) {
-      g_set_error (&error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (&error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "Bundle tag is %s but no matching media found", bundled[0]);
       goto out;
     }
@@ -5520,8 +5520,8 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd)
   if (!check_transceivers_not_removed (webrtc,
           get_previous_description (webrtc, sd->source, sd->sdp->type),
           sd->sdp)) {
-    g_set_error_literal (&error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error_literal (&error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "m=lines removed from the SDP. Processing a completely new connection "
         "is not currently supported.");
     goto out;
@@ -5889,7 +5889,7 @@ gst_webrtc_bin_set_remote_description (GstWebRTCBin * webrtc,
           (GstWebRTCBinFunc) _set_description_task, sd,
           (GDestroyNotify) _free_set_description_data, promise)) {
     GError *error =
-        g_error_new (GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_CLOSED,
+        g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INVALID_STATE,
         "Could not set remote description. webrtcbin is closed.");
     GstStructure *s = gst_structure_new ("application/x-gst-promise",
         "error", G_TYPE_ERROR, error, NULL);
@@ -5927,7 +5927,7 @@ gst_webrtc_bin_set_local_description (GstWebRTCBin * webrtc,
           (GstWebRTCBinFunc) _set_description_task, sd,
           (GDestroyNotify) _free_set_description_data, promise)) {
     GError *error =
-        g_error_new (GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_CLOSED,
+        g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INVALID_STATE,
         "Could not set local description. webrtcbin is closed");
     GstStructure *s = gst_structure_new ("application/x-gst-promise",
         "error", G_TYPE_ERROR, error, NULL);
@@ -6122,7 +6122,7 @@ gst_webrtc_bin_get_stats (GstWebRTCBin * webrtc, GstPad * pad,
   if (!gst_webrtc_bin_enqueue_task (webrtc, (GstWebRTCBinFunc) _get_stats_task,
           stats, (GDestroyNotify) _free_get_stats, promise)) {
     GError *error =
-        g_error_new (GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_CLOSED,
+        g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INVALID_STATE,
         "Could not retrieve statistics. webrtcbin is closed.");
     GstStructure *s = gst_structure_new ("application/x-gst-promise",
         "error", G_TYPE_ERROR, error, NULL);
index 70a5e12..78849f0 100644 (file)
 #include "utils.h"
 #include "gstwebrtcbin.h"
 
-GQuark
-gst_webrtc_bin_error_quark (void)
-{
-  return g_quark_from_static_string ("gst-webrtc-bin-error-quark");
-}
-
 GstPadTemplate *
 _find_pad_template (GstElement * element, GstPadDirection direction,
     GstPadPresence presence, const gchar * name)
index 7cc608e..41d37ec 100644 (file)
 
 G_BEGIN_DECLS
 
-#define GST_WEBRTC_BIN_ERROR gst_webrtc_bin_error_quark ()
-GQuark gst_webrtc_bin_error_quark (void);
-
-typedef enum
-{
-  GST_WEBRTC_BIN_ERROR_FAILED,
-  GST_WEBRTC_BIN_ERROR_INVALID_SYNTAX,
-  GST_WEBRTC_BIN_ERROR_INVALID_MODIFICATION,
-  GST_WEBRTC_BIN_ERROR_INVALID_STATE,
-  GST_WEBRTC_BIN_ERROR_BAD_SDP,
-  GST_WEBRTC_BIN_ERROR_FINGERPRINT,
-  GST_WEBRTC_BIN_ERROR_SCTP_FAILURE,
-  GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
-  GST_WEBRTC_BIN_ERROR_CLOSED,
-  GST_WEBRTC_BIN_ERROR_NOT_IMPLEMENTED,
-  GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION,
-  GST_WEBRTC_BIN_ERROR_CAPS_NEGOTIATION_FAILED
-} GstWebRTCError;
-
 GstPadTemplate *        _find_pad_template          (GstElement * element,
                                                      GstPadDirection direction,
                                                      GstPadPresence presence,
index e0fef6d..403c1c6 100644 (file)
@@ -413,8 +413,8 @@ _parse_control_packet (WebRTCDataChannel * channel, guint8 * data,
     GST_INFO_OBJECT (channel, "Received channel open");
 
     if (channel->parent.negotiated) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+      g_set_error (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
           "Data channel was signalled as negotiated already");
       g_return_val_if_reached (GST_FLOW_ERROR);
     }
@@ -479,16 +479,15 @@ _parse_control_packet (WebRTCDataChannel * channel, guint8 * data,
 
     ret = gst_app_src_push_buffer (GST_APP_SRC (channel->appsrc), buffer);
     if (ret != GST_FLOW_OK) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
-          "Could not send ack packet");
+      g_set_error (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE, "Could not send ack packet");
       return ret;
     }
 
     return ret;
   } else {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+    g_set_error (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
         "Unknown message type in control protocol");
     return GST_FLOW_ERROR;
   }
@@ -497,8 +496,8 @@ parse_error:
   {
     g_free (label);
     g_free (proto);
-    g_set_error (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE, "Failed to parse packet");
+    g_set_error (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE, "Failed to parse packet");
     g_return_val_if_reached (GST_FLOW_ERROR);
   }
 }
@@ -550,14 +549,14 @@ _data_channel_have_sample (WebRTCDataChannel * channel, GstSample * sample,
 
   buffer = gst_sample_get_buffer (sample);
   if (!buffer) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE, "No buffer to handle");
+    g_set_error (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE, "No buffer to handle");
     return GST_FLOW_ERROR;
   }
   receive = gst_sctp_buffer_get_receive_meta (buffer);
   if (!receive) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+    g_set_error (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
         "No SCTP Receive meta on the buffer");
     return GST_FLOW_ERROR;
   }
@@ -566,8 +565,8 @@ _data_channel_have_sample (WebRTCDataChannel * channel, GstSample * sample,
     case DATA_CHANNEL_PPID_WEBRTC_CONTROL:{
       GstMapInfo info = GST_MAP_INFO_INIT;
       if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR,
-            GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+        g_set_error (error, GST_WEBRTC_ERROR,
+            GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
             "Failed to map received buffer");
         ret = GST_FLOW_ERROR;
       } else {
@@ -580,8 +579,8 @@ _data_channel_have_sample (WebRTCDataChannel * channel, GstSample * sample,
     case DATA_CHANNEL_PPID_WEBRTC_STRING_PARTIAL:{
       GstMapInfo info = GST_MAP_INFO_INIT;
       if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR,
-            GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+        g_set_error (error, GST_WEBRTC_ERROR,
+            GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
             "Failed to map received buffer");
         ret = GST_FLOW_ERROR;
       } else {
@@ -596,8 +595,8 @@ _data_channel_have_sample (WebRTCDataChannel * channel, GstSample * sample,
     case DATA_CHANNEL_PPID_WEBRTC_BINARY_PARTIAL:{
       struct map_info *info = g_new0 (struct map_info, 1);
       if (!gst_buffer_map (buffer, &info->map_info, GST_MAP_READ)) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR,
-            GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+        g_set_error (error, GST_WEBRTC_ERROR,
+            GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
             "Failed to map received buffer");
         ret = GST_FLOW_ERROR;
       } else {
@@ -618,8 +617,8 @@ _data_channel_have_sample (WebRTCDataChannel * channel, GstSample * sample,
           NULL);
       break;
     default:
-      g_set_error (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+      g_set_error (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
           "Unknown SCTP PPID %u received", receive->ppid);
       ret = GST_FLOW_ERROR;
       break;
@@ -713,8 +712,8 @@ webrtc_data_channel_start_negotiation (WebRTCDataChannel * channel)
     _channel_enqueue_task (channel, (ChannelTask) _emit_on_open, NULL, NULL);
   } else {
     GError *error = NULL;
-    g_set_error (&error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+    g_set_error (&error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
         "Failed to send DCEP open packet");
     _channel_store_error (channel, error);
     _channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL, NULL);
@@ -765,8 +764,8 @@ webrtc_data_channel_send_data (GstWebRTCDataChannel * base_channel,
     g_return_if_fail (data != NULL);
     if (!_is_within_max_message_size (channel, size)) {
       GError *error = NULL;
-      g_set_error (&error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+      g_set_error (&error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
           "Requested to send data that is too large");
       _channel_store_error (channel, error);
       _channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL,
@@ -795,8 +794,8 @@ webrtc_data_channel_send_data (GstWebRTCDataChannel * base_channel,
 
   if (ret != GST_FLOW_OK) {
     GError *error = NULL;
-    g_set_error (&error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE, "Failed to send data");
+    g_set_error (&error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE, "Failed to send data");
     _channel_store_error (channel, error);
     _channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL, NULL);
   }
@@ -826,8 +825,8 @@ webrtc_data_channel_send_string (GstWebRTCDataChannel * base_channel,
 
     if (!_is_within_max_message_size (channel, size)) {
       GError *error = NULL;
-      g_set_error (&error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE,
+      g_set_error (&error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
           "Requested to send a string that is too large");
       _channel_store_error (channel, error);
       _channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL,
@@ -858,8 +857,8 @@ webrtc_data_channel_send_string (GstWebRTCDataChannel * base_channel,
 
   if (ret != GST_FLOW_OK) {
     GError *error = NULL;
-    g_set_error (&error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_DATA_CHANNEL_FAILURE, "Failed to send string");
+    g_set_error (&error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE, "Failed to send string");
     _channel_store_error (channel, error);
     _channel_enqueue_task (channel, (ChannelTask) _close_procedure, NULL, NULL);
   }
index 4c033b4..a166094 100644 (file)
@@ -84,8 +84,8 @@ _check_valid_state_for_sdp_change (GstWebRTCSignalingState state,
     gchar *state_str = _enum_value_to_string (GST_TYPE_WEBRTC_SIGNALING_STATE,
         state);
     gchar *type_str = _enum_value_to_string (GST_TYPE_WEBRTC_SDP_TYPE, type);
-    g_set_error (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_INVALID_STATE,
+    g_set_error (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_INVALID_STATE,
         "Not in the correct state (%s) for setting %s %s description",
         state_str, _sdp_source_to_string (source), type_str);
     g_free (state_str);
@@ -108,8 +108,8 @@ _check_sdp_crypto (SDPSource source, GstWebRTCSessionDescription * sdp,
 
   key = gst_sdp_message_get_key (sdp->sdp);
   if (!IS_EMPTY_SDP_ATTRIBUTE (key->data)) {
-    g_set_error_literal (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_BAD_SDP, "sdp contains a k line");
+    g_set_error_literal (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR, "sdp contains a k line");
     return FALSE;
   }
 
@@ -122,8 +122,8 @@ _check_sdp_crypto (SDPSource source, GstWebRTCSessionDescription * sdp,
 
     if (!IS_EMPTY_SDP_ATTRIBUTE (message_fingerprint)
         && !IS_EMPTY_SDP_ATTRIBUTE (media_fingerprint)) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_FINGERPRINT,
+      g_set_error (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_FINGERPRINT_FAILURE,
           "No fingerprint lines in sdp for media %u", i);
       return FALSE;
     }
@@ -132,8 +132,8 @@ _check_sdp_crypto (SDPSource source, GstWebRTCSessionDescription * sdp,
     }
     if (!IS_EMPTY_SDP_ATTRIBUTE (media_fingerprint)
         && g_strcmp0 (fingerprint, media_fingerprint) != 0) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_FINGERPRINT,
+      g_set_error (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_FINGERPRINT_FAILURE,
           "Fingerprint in media %u differs from %s fingerprint. "
           "\'%s\' != \'%s\'", i, message_fingerprint ? "global" : "previous",
           fingerprint, media_fingerprint);
@@ -178,8 +178,8 @@ static gboolean
 _check_trickle_ice (GstSDPMessage * msg, GError ** error)
 {
   if (!_session_has_attribute_key_value (msg, "ice-options", "trickle")) {
-    g_set_error_literal (error, GST_WEBRTC_BIN_ERROR,
-        GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error_literal (error, GST_WEBRTC_ERROR,
+        GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "No required \'a=ice-options:trickle\' line in sdp");
   }
   return TRUE;
@@ -204,7 +204,7 @@ _media_has_mid (const GstSDPMedia * media, guint media_idx, GError ** error)
 {
   const gchar *mid = gst_sdp_media_get_attribute_val (media, "mid");
   if (IS_EMPTY_SDP_ATTRIBUTE (mid)) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "media %u is missing or contains an empty \'mid\' attribute",
         media_idx);
     return FALSE;
@@ -248,13 +248,13 @@ _media_has_setup (const GstSDPMedia * media, guint media_idx, GError ** error)
   static const gchar *valid_setups[] = { "actpass", "active", "passive", NULL };
   const gchar *setup = gst_sdp_media_get_attribute_val (media, "setup");
   if (IS_EMPTY_SDP_ATTRIBUTE (setup)) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "media %u is missing or contains an empty \'setup\' attribute",
         media_idx);
     return FALSE;
   }
   if (!g_strv_contains (valid_setups, setup)) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "media %u contains unknown \'setup\' attribute, \'%s\'", media_idx,
         setup);
     return FALSE;
@@ -268,7 +268,7 @@ _media_has_dtls_id (const GstSDPMedia * media, guint media_idx, GError ** error)
 {
   const gchar *dtls_id = gst_sdp_media_get_attribute_val (media, "ice-pwd");
   if (IS_EMPTY_SDP_ATTRIBUTE (dtls_id)) {
-    g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+    g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
         "media %u is missing or contains an empty \'dtls-id\' attribute",
         media_idx);
     return FALSE;
@@ -307,13 +307,13 @@ validate_sdp (GstWebRTCSignalingState state, SDPSource source,
     media_in_bundle = is_bundle
         && g_strv_contains ((const gchar **) group_members, mid);
     if (!_media_get_ice_ufrag (sdp->sdp, i)) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "media %u is missing or contains an empty \'ice-ufrag\' attribute",
           i);
       goto fail;
     }
     if (!_media_get_ice_pwd (sdp->sdp, i)) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "media %u is missing or contains an empty \'ice-pwd\' attribute", i);
       goto fail;
     }
@@ -327,7 +327,7 @@ validate_sdp (GstWebRTCSignalingState state, SDPSource source,
       if (!bundle_ice_ufrag)
         bundle_ice_ufrag = ice_ufrag;
       else if (g_strcmp0 (bundle_ice_ufrag, ice_ufrag) != 0) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+        g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
             "media %u has different ice-ufrag values in bundle. "
             "%s != %s", i, bundle_ice_ufrag, ice_ufrag);
         goto fail;
@@ -335,7 +335,7 @@ validate_sdp (GstWebRTCSignalingState state, SDPSource source,
       if (!bundle_ice_pwd) {
         bundle_ice_pwd = ice_pwd;
       } else if (g_strcmp0 (bundle_ice_pwd, ice_pwd) != 0) {
-        g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+        g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
             "media %u has different ice-pwd values in bundle. "
             "%s != %s", i, bundle_ice_pwd, ice_pwd);
         goto fail;
@@ -884,7 +884,7 @@ _parse_bundle (GstSDPMessage * sdp, GStrv * bundled, GError ** error)
     *bundled = g_strsplit (group + strlen ("BUNDLE "), " ", 0);
 
     if (!(*bundled)[0]) {
-      g_set_error (error, GST_WEBRTC_BIN_ERROR, GST_WEBRTC_BIN_ERROR_BAD_SDP,
+      g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
           "Invalid format for BUNDLE group, expected at least one mid (%s)",
           group);
       g_strfreev (*bundled);
index 473102d..6708f05 100644 (file)
@@ -7,6 +7,7 @@ webrtc_sources = files([
   'rtptransceiver.c',
   'datachannel.c',
   'sctptransport.c',
+  'webrtc.c',
 ])
 
 webrtc_headers = files([
diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/webrtc/webrtc.c b/subprojects/gst-plugins-bad/gst-libs/gst/webrtc/webrtc.c
new file mode 100644 (file)
index 0000000..8040e38
--- /dev/null
@@ -0,0 +1,35 @@
+/* GStreamer
+ * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/webrtc/webrtc_fwd.h>
+
+/**
+ * gst_webrtc_error_quark:
+ *
+ * Since: 1.20
+ */
+GQuark
+gst_webrtc_error_quark (void)
+{
+  return g_quark_from_static_string ("gst-webrtc-error-quark");
+}
index 189e7b3..d181873 100644 (file)
@@ -423,4 +423,45 @@ typedef enum /*<underscore_name=gst_webrtc_kind>*/
   GST_WEBRTC_KIND_VIDEO,
 } GstWebRTCKind;
 
+
+GST_WEBRTC_API
+GQuark gst_webrtc_error_quark (void);
+
+/**
+ * GST_WEBRTC_ERROR:
+ *
+ * Since: 1.20
+ */
+#define GST_WEBRTC_ERROR gst_webrtc_error_quark ()
+
+/**
+ * GstWebRTCError:
+ * @GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE: data-channel-failure
+ * @GST_WEBRTC_ERROR_DTLS_FAILURE: dtls-failure
+ * @GST_WEBRTC_ERROR_FINGERPRINT_FAILURE: fingerprint-failure
+ * @GST_WEBRTC_ERROR_SCTP_FAILURE: sctp-failure
+ * @GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR: sdp-syntax-error
+ * @GST_WEBRTC_ERROR_HARDWARE_ENCODER_NOT_AVAILABLE: hardware-encoder-not-available
+ * @GST_WEBRTC_ERROR_ENCODER_ERROR: encoder-error
+ * @GST_WEBRTC_ERROR_INVALID_STATE: invalid-state (part of WebIDL specification)
+ * @GST_WEBRTC_ERROR_INTERNAL_FAILURE: GStreamer-specific failure, not matching any other value from the specification
+ *
+ * See <https://www.w3.org/TR/webrtc/#dom-rtcerrordetailtype> for more information.
+ *
+ * Since: 1.20
+ */
+typedef enum /*<underscore_name=gst_webrtc_error>*/
+{
+  GST_WEBRTC_ERROR_DATA_CHANNEL_FAILURE,
+  GST_WEBRTC_ERROR_DTLS_FAILURE,
+  GST_WEBRTC_ERROR_FINGERPRINT_FAILURE,
+  GST_WEBRTC_ERROR_SCTP_FAILURE,
+  GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
+  GST_WEBRTC_ERROR_HARDWARE_ENCODER_NOT_AVAILABLE,
+  GST_WEBRTC_ERROR_ENCODER_ERROR,
+  GST_WEBRTC_ERROR_INVALID_STATE,
+  GST_WEBRTC_ERROR_INTERNAL_FAILURE
+} GstWebRTCError;
+
+
 #endif /* __GST_WEBRTC_FWD_H__ */
index c53b158..9ed6937 100644 (file)
@@ -3862,8 +3862,11 @@ GST_START_TEST (test_reject_create_offer)
   s = gst_promise_get_reply (promise);
   fail_unless (s != NULL);
   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
-  fail_unless (g_error_matches (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION));
+  fail_unless (g_error_matches (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_INTERNAL_FAILURE));
+  fail_unless (g_str_match_string
+      ("has locked mline 1 but the whole offer only has 0 sections",
+          error->message, FALSE));
   g_clear_error (&error);
   gst_promise_unref (promise);
 
@@ -3933,8 +3936,12 @@ GST_START_TEST (test_reject_set_description)
   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
   s = gst_promise_get_reply (promise);
   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
-  fail_unless (g_error_matches (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION));
+  fail_unless (g_error_matches (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_INTERNAL_FAILURE));
+  fail_unless (g_str_match_string
+      ("m-line 0 was locked to audio, but SDP has audio media", error->message,
+          FALSE));
+
   g_clear_error (&error);
   fail_unless (s != NULL);
   gst_promise_unref (promise);
@@ -4129,8 +4136,11 @@ GST_START_TEST (test_codec_preferences_negotiation_sinkpad)
   s = gst_promise_get_reply (promise);
   fail_unless (s != NULL);
   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
-  fail_unless (g_error_matches (error, GST_WEBRTC_BIN_ERROR,
-          GST_WEBRTC_BIN_ERROR_CAPS_NEGOTIATION_FAILED));
+  fail_unless (g_error_matches (error, GST_WEBRTC_ERROR,
+          GST_WEBRTC_ERROR_INTERNAL_FAILURE));
+  fail_unless (g_str_match_string
+      ("Caps negotiation on pad sink_0 failed against codec preferences",
+          error->message, FALSE));
   g_clear_error (&error);
   gst_promise_unref (promise);