nice: Add gstreamer plugins from libnice (0.1.17) 47/270847/3
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 10 Feb 2022 05:29:21 +0000 (14:29 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 10 Feb 2022 06:56:51 +0000 (15:56 +0900)
Change-Id: I30b4590d3e767ccff11a385ebfa5597935bc0db8
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
12 files changed:
packaging/gstreamer.spec
subprojects/gst-plugins-bad/ext/meson.build
subprojects/gst-plugins-bad/ext/nice/Makefile.am [new file with mode: 0644]
subprojects/gst-plugins-bad/ext/nice/gstnice.c [new file with mode: 0644]
subprojects/gst-plugins-bad/ext/nice/gstnice.h [new file with mode: 0644]
subprojects/gst-plugins-bad/ext/nice/gstnicesink.c [new file with mode: 0644]
subprojects/gst-plugins-bad/ext/nice/gstnicesink.h [new file with mode: 0644]
subprojects/gst-plugins-bad/ext/nice/gstnicesrc.c [new file with mode: 0644]
subprojects/gst-plugins-bad/ext/nice/gstnicesrc.h [new file with mode: 0644]
subprojects/gst-plugins-bad/ext/nice/meson.build [new file with mode: 0644]
subprojects/gst-plugins-bad/meson.build
subprojects/gst-plugins-bad/meson_options.txt

index be06162..9f177c6 100644 (file)
@@ -1051,6 +1051,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_lib_gstreamer_dir}/libgstaudiolatency.so
 %{_lib_gstreamer_dir}/libgstipcpipeline.so
 %{_lib_gstreamer_dir}/libgstproxy.so
+%{_lib_gstreamer_dir}/libgstnice.so
 %{_lib_gstreamer_dir}/libgstwebrtc.so
 %{_lib_gstreamer_dir}/libgstdtls.so
 %{_lib_gstreamer_dir}/libgstrtpmanagerbad.so
@@ -1075,6 +1076,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/libgstwayland-%{gst_branch}.so.0*
 %endif
 %exclude %{_bindir}/gst-transcoder-1.0
+%exclude %{_libdir}/debug/*
 
 %files -n gst-plugins-bad-devel
 %manifest gst-plugins-bad.manifest
index 1e40ace..5ae13b9 100644 (file)
@@ -72,3 +72,4 @@ subdir('wpe')
 subdir('x265')
 subdir('zxing')
 subdir('zbar')
+subdir('nice')
diff --git a/subprojects/gst-plugins-bad/ext/nice/Makefile.am b/subprojects/gst-plugins-bad/ext/nice/Makefile.am
new file mode 100644 (file)
index 0000000..8776780
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# Makefile.am for the Nice Glib ICE library
+#
+# (C) 2006, 2007 Collabora Ltd.
+# (C) 2006, 2007 Nokia Corporation. All rights reserved.
+#
+# Licensed under MPL 1.1/LGPL 2.1. See file COPYING.
+
+AM_CFLAGS = $(LIBNICE_CFLAGS) \
+       -I $(top_srcdir) \
+       -I $(top_srcdir)/socket \
+       -I $(top_srcdir)/agent \
+       -I $(top_srcdir)/random \
+       -I $(top_srcdir)/stun
+
+COMMON_LIBADD = \
+       $(top_builddir)/nice/libnice.la
+
+# libgstnice
+
+if WITH_GSTREAMER
+gstplugin_LTLIBRARIES = libgstnice.la
+
+libgstnice_la_CFLAGS = $(AM_CFLAGS) $(GST_CFLAGS) -DGST_USE_UNSTABLE_API
+
+libgstnice_la_SOURCES = \
+       gstnicesrc.h \
+       gstnicesrc.c \
+       gstnicesink.h \
+       gstnicesink.c \
+       gstnice.h \
+       gstnice.c
+
+libgstnice_la_LIBADD =         $(COMMON_LIBADD) $(GST_LIBS)
+
+libgstnice_la_LDFLAGS = -module -avoid-version -no-undefined
+endif
+
+
+if WITH_GSTREAMER010
+gstplugin010_LTLIBRARIES = libgstnice010.la
+
+libgstnice010_la_CFLAGS = $(AM_CFLAGS) $(GST010_CFLAGS)
+
+libgstnice010_la_SOURCES = \
+       gstnicesrc.h \
+       gstnicesrc.c \
+       gstnicesink.h \
+       gstnicesink.c \
+       gstnice.h \
+       gstnice.c
+
+libgstnice010_la_LIBADD = $(COMMON_LIBADD) $(GST010_LIBS)
+
+libgstnice010_la_LDFLAGS = -module -avoid-version -no-undefined
+endif
+
+EXTRA_DIST = meson.build
diff --git a/subprojects/gst-plugins-bad/ext/nice/gstnice.c b/subprojects/gst-plugins-bad/ext/nice/gstnice.c
new file mode 100644 (file)
index 0000000..1f0d1e7
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2006, 2007 Collabora Ltd.
+ *  Contact: Dafydd Harries
+ * (C) 2006, 2007 Nokia Corporation. All rights reserved.
+ *  Contact: Kai Vehmanen
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ *   Dafydd Harries, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "gstnicesrc.h"
+#include "gstnicesink.h"
+
+static gboolean
+plugin_init (GstPlugin *plugin)
+{
+  if (!gst_element_register (plugin, "nicesrc",
+        GST_RANK_NONE, GST_TYPE_NICE_SRC))
+    return FALSE;
+
+  if (!gst_element_register (plugin, "nicesink",
+        GST_RANK_NONE, GST_TYPE_NICE_SINK))
+    return FALSE;
+
+  return TRUE;
+}
+
+#if GST_CHECK_VERSION (1,0,0)
+#define PLUGIN_NAME nice
+#else
+#define PLUGIN_NAME "nice"
+#endif
+
+GST_PLUGIN_DEFINE (
+    GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    PLUGIN_NAME,
+    "Interactive UDP connectivity establishment",
+    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
+    "https://nice.freedesktop.org/");
+
diff --git a/subprojects/gst-plugins-bad/ext/nice/gstnice.h b/subprojects/gst-plugins-bad/ext/nice/gstnice.h
new file mode 100644 (file)
index 0000000..b90939a
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2006, 2007 Collabora Ltd.
+ *  Contact: Dafydd Harries
+ * (C) 2006, 2007 Nokia Corporation. All rights reserved.
+ *  Contact: Kai Vehmanen
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ *   Dafydd Harries, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+
+#include "gstnicesrc.h"
+#include "gstnicesink.h"
+
diff --git a/subprojects/gst-plugins-bad/ext/nice/gstnicesink.c b/subprojects/gst-plugins-bad/ext/nice/gstnicesink.c
new file mode 100644 (file)
index 0000000..be46665
--- /dev/null
@@ -0,0 +1,584 @@
+
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2006, 2007 Collabora Ltd.
+ *  Contact: Dafydd Harries
+ * (C) 2006, 2007 Nokia Corporation. All rights reserved.
+ *  Contact: Kai Vehmanen
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ *   Dafydd Harries, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "gstnicesink.h"
+
+
+GST_DEBUG_CATEGORY_STATIC (nicesink_debug);
+#define GST_CAT_DEFAULT nicesink_debug
+
+static GstFlowReturn
+gst_nice_sink_render (
+  GstBaseSink *basesink,
+  GstBuffer *buffer);
+#if GST_CHECK_VERSION (1,0,0)
+static GstFlowReturn
+gst_nice_sink_render_list (
+  GstBaseSink *basesink,
+  GstBufferList *buffer_list);
+#endif
+
+static gboolean
+gst_nice_sink_unlock (GstBaseSink *basesink);
+
+static gboolean
+gst_nice_sink_unlock_stop (GstBaseSink *basesink);
+
+static void
+_reliable_transport_writable (
+    NiceAgent *agent,
+    guint stream_id,
+    guint component_id,
+    GstNiceSink *sink);
+
+static void
+gst_nice_sink_set_property (
+  GObject *object,
+  guint prop_id,
+  const GValue *value,
+  GParamSpec *pspec);
+
+static void
+gst_nice_sink_get_property (
+  GObject *object,
+  guint prop_id,
+  GValue *value,
+  GParamSpec *pspec);
+
+static void
+gst_nice_sink_dispose (GObject *object);
+#if GST_CHECK_VERSION (1,0,0)
+static void
+gst_nice_sink_finalize (GObject *object);
+#endif
+
+static GstStateChangeReturn
+gst_nice_sink_change_state (
+    GstElement * element,
+    GstStateChange transition);
+
+static GstStaticPadTemplate gst_nice_sink_sink_template =
+GST_STATIC_PAD_TEMPLATE (
+    "sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS_ANY);
+
+G_DEFINE_TYPE (GstNiceSink, gst_nice_sink, GST_TYPE_BASE_SINK);
+
+enum
+{
+  PROP_AGENT = 1,
+  PROP_STREAM,
+  PROP_COMPONENT
+};
+
+static void
+gst_nice_sink_class_init (GstNiceSinkClass *klass)
+{
+  GstBaseSinkClass *gstbasesink_class;
+  GstElementClass *gstelement_class;
+  GObjectClass *gobject_class;
+
+  GST_DEBUG_CATEGORY_INIT (nicesink_debug, "nicesink",
+      0, "libnice sink");
+
+  gstbasesink_class = (GstBaseSinkClass *) klass;
+  gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_nice_sink_render);
+#if GST_CHECK_VERSION (1,0,0)
+  gstbasesink_class->render_list = GST_DEBUG_FUNCPTR (gst_nice_sink_render_list);
+#endif
+  gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_nice_sink_unlock);
+  gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_nice_sink_unlock_stop);
+
+  gobject_class = (GObjectClass *) klass;
+  gobject_class->set_property = gst_nice_sink_set_property;
+  gobject_class->get_property = gst_nice_sink_get_property;
+  gobject_class->dispose = gst_nice_sink_dispose;
+#if GST_CHECK_VERSION (1,0,0)
+  gobject_class->finalize = gst_nice_sink_finalize;
+#endif
+
+  gstelement_class = (GstElementClass *) klass;
+  gstelement_class->change_state = gst_nice_sink_change_state;
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_nice_sink_sink_template));
+#if GST_CHECK_VERSION (1,0,0)
+  gst_element_class_set_metadata (gstelement_class,
+#else
+  gst_element_class_set_details_simple (gstelement_class,
+#endif
+    "ICE sink",
+    "Sink",
+    "Interactive UDP connectivity establishment",
+    "Dafydd Harries <dafydd.harries@collabora.co.uk>");
+
+
+  g_object_class_install_property (gobject_class, PROP_AGENT,
+      g_param_spec_object (
+         "agent",
+         "Agent",
+         "The NiceAgent this source is bound to",
+         NICE_TYPE_AGENT,
+         G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_STREAM,
+      g_param_spec_uint (
+         "stream",
+         "Stream ID",
+         "The ID of the stream to read from",
+         0,
+         G_MAXUINT,
+         0,
+         G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_COMPONENT,
+      g_param_spec_uint (
+         "component",
+         "Component ID",
+         "The ID of the component to read from",
+         0,
+         G_MAXUINT,
+         0,
+         G_PARAM_READWRITE));
+}
+
+static void
+gst_nice_sink_init (GstNiceSink *sink)
+{
+#if GST_CHECK_VERSION (1,0,0)
+  guint max_mem;
+#endif
+
+  g_cond_init (&sink->writable_cond);
+
+#if GST_CHECK_VERSION (1,0,0)
+  /* pre-allocate OutputVector, MapInfo and OutputMessage arrays
+   * for use in the render and render_list functions */
+  max_mem = gst_buffer_get_max_memory ();
+
+  sink->n_vecs = max_mem;
+  sink->vecs = g_new (GOutputVector, sink->n_vecs);
+
+  sink->n_maps = max_mem;
+  sink->maps = g_new (GstMapInfo, sink->n_maps);
+
+  sink->n_messages = 1;
+  sink->messages = g_new (NiceOutputMessage, sink->n_messages);
+#endif
+}
+
+static void
+_reliable_transport_writable (NiceAgent *agent, guint stream_id,
+    guint component_id, GstNiceSink *sink)
+{
+  GST_OBJECT_LOCK (sink);
+  if (stream_id == sink->stream_id && component_id == sink->component_id) {
+    g_cond_broadcast (&sink->writable_cond);
+  }
+  GST_OBJECT_UNLOCK (sink);
+}
+
+#if GST_CHECK_VERSION (1,0,0)
+static gsize
+fill_vectors (GOutputVector * vecs, GstMapInfo * maps, guint n, GstBuffer * buf)
+{
+  GstMemory *mem;
+  gsize size = 0;
+  guint i;
+
+  g_assert_cmpuint (gst_buffer_n_memory (buf), ==, n);
+
+  for (i = 0; i < n; ++i) {
+    mem = gst_buffer_peek_memory (buf, i);
+    if (gst_memory_map (mem, &maps[i], GST_MAP_READ)) {
+      vecs[i].buffer = maps[i].data;
+      vecs[i].size = maps[i].size;
+    } else {
+      GST_WARNING ("Failed to map memory %p for reading", mem);
+      vecs[i].buffer = "";
+      vecs[i].size = 0;
+    }
+    size += vecs[i].size;
+  }
+
+  return size;
+}
+
+/* Buffer list code written by
+ *   Tim-Philipp Müller <tim@centricular.com>
+ * taken from
+ *   gst-plugins-good/gst/udp/gstmultiudpsink.c
+ */
+static GstFlowReturn
+gst_nice_sink_render_buffers (GstNiceSink * sink, GstBuffer ** buffers,
+    guint num_buffers, guint8 * mem_nums, guint total_mem_num)
+{
+  NiceOutputMessage *msgs;
+  GOutputVector *vecs;
+  GstMapInfo *map_infos;
+  guint i, mem;
+  guint written = 0;
+  gint ret;
+  GstFlowReturn flow_ret = GST_FLOW_OK;
+
+  GST_LOG_OBJECT (sink, "%u buffers, %u memories -> to be sent",
+      num_buffers, total_mem_num);
+
+  if (sink->n_vecs < total_mem_num) {
+    sink->n_vecs = GST_ROUND_UP_16 (total_mem_num);
+    g_free (sink->vecs);
+    sink->vecs = g_new (GOutputVector, sink->n_vecs);
+  }
+  vecs = sink->vecs;
+
+  if (sink->n_maps < total_mem_num) {
+    sink->n_maps = GST_ROUND_UP_16 (total_mem_num);
+    g_free (sink->maps);
+    sink->maps = g_new (GstMapInfo, sink->n_maps);
+  }
+  map_infos = sink->maps;
+
+  if (sink->n_messages < num_buffers) {
+    sink->n_messages = GST_ROUND_UP_16 (num_buffers);
+    g_free (sink->messages);
+    sink->messages = g_new (NiceOutputMessage, sink->n_messages);
+  }
+  msgs = sink->messages;
+
+  for (i = 0, mem = 0; i < num_buffers; ++i) {
+    fill_vectors (&vecs[mem], &map_infos[mem], mem_nums[i], buffers[i]);
+    msgs[i].buffers = &vecs[mem];
+    msgs[i].n_buffers = mem_nums[i];
+    mem += mem_nums[i];
+  }
+
+  GST_OBJECT_LOCK (sink);
+  do {
+    ret = nice_agent_send_messages_nonblocking(sink->agent, sink->stream_id,
+        sink->component_id, msgs + written, num_buffers - written, NULL, NULL);
+
+    if (ret > 0)
+      written += ret;
+
+    if (sink->reliable && written < num_buffers)
+      g_cond_wait (&sink->writable_cond, GST_OBJECT_GET_LOCK (sink));
+
+    if (sink->flushing) {
+      flow_ret = GST_FLOW_FLUSHING;
+      break;
+    }
+  } while (sink->reliable && written < num_buffers);
+  GST_OBJECT_UNLOCK (sink);
+
+  for (i = 0; i < mem; ++i)
+    gst_memory_unmap (map_infos[i].memory, &map_infos[i]);
+
+  return flow_ret;
+}
+#endif
+
+static GstFlowReturn
+gst_nice_sink_render (GstBaseSink *basesink, GstBuffer *buffer)
+{
+  GstNiceSink *nicesink = GST_NICE_SINK (basesink);
+  GstFlowReturn flow_ret = GST_FLOW_OK;
+#if GST_CHECK_VERSION (1,0,0)
+  guint8 n_mem;
+
+  n_mem = gst_buffer_n_memory (buffer);
+
+  if (n_mem > 0) {
+    flow_ret = gst_nice_sink_render_buffers (nicesink, &buffer, 1, &n_mem,
+        n_mem);
+  }
+
+#else
+  guint written = 0;
+  gint ret;
+  gchar *data = NULL;
+  guint size = 0;
+
+  data = (gchar *) GST_BUFFER_DATA (buffer);
+  size = GST_BUFFER_SIZE (buffer);
+
+  GST_OBJECT_LOCK (nicesink);
+  do {
+    ret = nice_agent_send (nicesink->agent, nicesink->stream_id,
+        nicesink->component_id, size - written, data + written);
+    if (ret > 0)
+      written += ret;
+
+    if (nicesink->reliable && written < size)
+      g_cond_wait (&nicesink->writable_cond, GST_OBJECT_GET_LOCK (nicesink));
+    if (nicesink->flushing) {
+      flow_ret = GST_FLOW_WRONG_STATE;
+      break;
+    }
+  } while (nicesink->reliable && written < size);
+  GST_OBJECT_UNLOCK (nicesink);
+
+#endif
+  return flow_ret;
+}
+
+#if GST_CHECK_VERSION (1,0,0)
+static GstFlowReturn
+gst_nice_sink_render_list (GstBaseSink *basesink, GstBufferList *buffer_list)
+{
+  GstNiceSink *nicesink = GST_NICE_SINK (basesink);
+  GstBuffer **buffers;
+  GstFlowReturn flow_ret = GST_FLOW_OK;
+  guint8 *mem_nums;
+  guint total_mems;
+  guint i, num_buffers;
+
+  num_buffers = gst_buffer_list_length (buffer_list);
+  if (num_buffers == 0)
+    goto no_data;
+
+  buffers = g_newa (GstBuffer *, num_buffers);
+  mem_nums = g_newa (guint8, num_buffers);
+  for (i = 0, total_mems = 0; i < num_buffers; ++i) {
+    buffers[i] = gst_buffer_list_get (buffer_list, i);
+    mem_nums[i] = gst_buffer_n_memory (buffers[i]);
+    total_mems += mem_nums[i];
+  }
+
+  flow_ret = gst_nice_sink_render_buffers (nicesink, buffers, num_buffers,
+      mem_nums, total_mems);
+
+  return flow_ret;
+
+no_data:
+  {
+    GST_LOG_OBJECT (nicesink, "empty buffer");
+    return GST_FLOW_OK;
+  }
+
+  return flow_ret;
+}
+#endif
+
+static gboolean gst_nice_sink_unlock (GstBaseSink *basesink)
+{
+  GstNiceSink *nicesink = GST_NICE_SINK (basesink);
+
+  GST_OBJECT_LOCK (nicesink);
+  nicesink->flushing = TRUE;
+  g_cond_broadcast (&nicesink->writable_cond);
+  GST_OBJECT_UNLOCK (nicesink);
+
+  return TRUE;
+}
+
+static gboolean gst_nice_sink_unlock_stop (GstBaseSink *basesink)
+{
+  GstNiceSink *nicesink = GST_NICE_SINK (basesink);
+
+  GST_OBJECT_LOCK (nicesink);
+  nicesink->flushing = FALSE;
+  GST_OBJECT_UNLOCK (nicesink);
+
+  return TRUE;
+}
+
+static void
+gst_nice_sink_dispose (GObject *object)
+{
+  GstNiceSink *sink = GST_NICE_SINK (object);
+
+  if (sink->agent && sink->writable_id)
+    g_signal_handler_disconnect (sink->agent, sink->writable_id);
+  sink->writable_id = 0;
+  g_clear_object (&sink->agent);
+
+  g_cond_clear (&sink->writable_cond);
+
+  G_OBJECT_CLASS (gst_nice_sink_parent_class)->dispose (object);
+}
+
+#if GST_CHECK_VERSION (1,0,0)
+static void
+gst_nice_sink_finalize (GObject *object)
+{
+  GstNiceSink *sink = GST_NICE_SINK (object);
+
+  g_free (sink->vecs);
+  sink->vecs = NULL;
+  sink->n_vecs = 0;
+  g_free (sink->maps);
+  sink->maps = NULL;
+  sink->n_maps = 0;
+  g_free (sink->messages);
+  sink->messages = NULL;
+  sink->n_messages = 0;
+
+  G_OBJECT_CLASS (gst_nice_sink_parent_class)->finalize (object);
+}
+#endif
+
+static void
+gst_nice_sink_set_property (
+  GObject *object,
+  guint prop_id,
+  const GValue *value,
+  GParamSpec *pspec)
+{
+  GstNiceSink *sink = GST_NICE_SINK (object);
+
+  switch (prop_id)
+    {
+    case PROP_AGENT:
+      if (sink->agent) {
+        GST_ERROR_OBJECT (object,
+            "Changing the agent on a nice sink not allowed");
+      } else {
+        sink->agent = g_value_dup_object (value);
+        g_object_get (sink->agent, "reliable", &sink->reliable, NULL);
+        if (sink->reliable)
+          sink->writable_id = g_signal_connect (sink->agent,
+              "reliable-transport-writable",
+              (GCallback) _reliable_transport_writable, sink);
+      }
+      break;
+
+    case PROP_STREAM:
+      GST_OBJECT_LOCK (sink);
+      sink->stream_id = g_value_get_uint (value);
+      GST_OBJECT_UNLOCK (sink);
+      break;
+
+    case PROP_COMPONENT:
+      {
+        guint new_component_id = g_value_get_uint (value);
+        GST_OBJECT_LOCK (sink);
+        if (sink->component_id != new_component_id) {
+          sink->component_id = new_component_id;
+          g_cond_broadcast (&sink->writable_cond);
+        }
+        GST_OBJECT_UNLOCK (sink);
+      }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gst_nice_sink_get_property (
+  GObject *object,
+  guint prop_id,
+  GValue *value,
+  GParamSpec *pspec)
+{
+  GstNiceSink *sink = GST_NICE_SINK (object);
+
+  switch (prop_id)
+    {
+    case PROP_AGENT:
+      g_value_set_object (value, sink->agent);
+      break;
+
+    case PROP_STREAM:
+      GST_OBJECT_LOCK (sink);
+      g_value_set_uint (value, sink->stream_id);
+      GST_OBJECT_UNLOCK (sink);
+      break;
+
+    case PROP_COMPONENT:
+      GST_OBJECT_LOCK (sink);
+      g_value_set_uint (value, sink->component_id);
+      GST_OBJECT_UNLOCK (sink);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static GstStateChangeReturn
+gst_nice_sink_change_state (GstElement * element, GstStateChange transition)
+{
+  GstNiceSink *sink;
+  GstStateChangeReturn ret;
+
+  sink = GST_NICE_SINK (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      if (sink->agent == NULL)
+        {
+          GST_ERROR_OBJECT (element,
+              "Trying to start Nice sink without an agent set");
+          return GST_STATE_CHANGE_FAILURE;
+        }
+      else if (sink->stream_id == 0)
+          {
+            GST_ERROR_OBJECT (element,
+                "Trying to start Nice sink without a stream set");
+            return GST_STATE_CHANGE_FAILURE;
+          }
+      else if (sink->component_id == 0)
+          {
+            GST_ERROR_OBJECT (element,
+                "Trying to start Nice sink without a component set");
+            return GST_STATE_CHANGE_FAILURE;
+          }
+      break;
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+    case GST_STATE_CHANGE_READY_TO_NULL:
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (gst_nice_sink_parent_class)->change_state (element,
+      transition);
+
+  return ret;
+}
diff --git a/subprojects/gst-plugins-bad/ext/nice/gstnicesink.h b/subprojects/gst-plugins-bad/ext/nice/gstnicesink.h
new file mode 100644 (file)
index 0000000..3c8edbb
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2006, 2007 Collabora Ltd.
+ *  Contact: Dafydd Harries
+ * (C) 2006, 2007 Nokia Corporation. All rights reserved.
+ *  Contact: Kai Vehmanen
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ *   Dafydd Harries, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+
+#ifndef _GST_NICE_SINK_H
+#define _GST_NICE_SINK_H
+
+#include <gst/gst.h>
+#include <gst/base/gstbasesink.h>
+
+#include <nice/nice.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_NICE_SINK \
+  (gst_nice_sink_get_type())
+#define GST_NICE_SINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NICE_SINK,GstNiceSink))
+#define GST_NICE_SINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NICE_SINK,GstNiceSinkClass))
+#define GST_IS_NICE_SINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NICE_SINK))
+#define GST_IS_NICE_SINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NICE_SINK))
+
+typedef struct _GstNiceSink GstNiceSink;
+
+struct _GstNiceSink
+{
+  GstBaseSink parent;
+  GstPad *sinkpad;
+  NiceAgent *agent;
+  guint stream_id;
+  guint component_id;
+  gboolean reliable;
+  GCond writable_cond;
+  gulong writable_id;
+  gboolean flushing;
+
+#if GST_CHECK_VERSION (1,0,0)
+  /* pre-allocated scrap space for render function */
+  GOutputVector *vecs;
+  guint n_vecs;
+  GstMapInfo *maps;
+  guint n_maps;
+  NiceOutputMessage *messages;
+  guint n_messages;
+#endif
+};
+
+typedef struct _GstNiceSinkClass GstNiceSinkClass;
+
+struct _GstNiceSinkClass
+{
+  GstBaseSinkClass parent_class;
+};
+
+GType gst_nice_sink_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/subprojects/gst-plugins-bad/ext/nice/gstnicesrc.c b/subprojects/gst-plugins-bad/ext/nice/gstnicesrc.c
new file mode 100644 (file)
index 0000000..424f449
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2006, 2007 Collabora Ltd.
+ *  Contact: Dafydd Harries
+ * (C) 2006, 2007 Nokia Corporation. All rights reserved.
+ *  Contact: Kai Vehmanen
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ *   Dafydd Harries, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "gstnicesrc.h"
+
+GST_DEBUG_CATEGORY_STATIC (nicesrc_debug);
+#define GST_CAT_DEFAULT nicesrc_debug
+
+
+#define BUFFER_SIZE (65536)
+
+static GstFlowReturn
+gst_nice_src_create (
+  GstPushSrc *basesrc,
+  GstBuffer **buffer);
+
+static gboolean
+gst_nice_src_unlock (
+    GstBaseSrc *basesrc);
+
+static gboolean
+gst_nice_src_unlock_stop (
+    GstBaseSrc *basesrc);
+
+static void
+gst_nice_src_set_property (
+  GObject *object,
+  guint prop_id,
+  const GValue *value,
+  GParamSpec *pspec);
+
+static void
+gst_nice_src_get_property (
+  GObject *object,
+  guint prop_id,
+  GValue *value,
+  GParamSpec *pspec);
+
+
+static void
+gst_nice_src_dispose (GObject *object);
+
+static GstStateChangeReturn
+gst_nice_src_change_state (
+    GstElement * element,
+    GstStateChange transition);
+
+static GstStaticPadTemplate gst_nice_src_src_template =
+GST_STATIC_PAD_TEMPLATE (
+    "src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS_ANY);
+
+G_DEFINE_TYPE (GstNiceSrc, gst_nice_src, GST_TYPE_PUSH_SRC);
+
+enum
+{
+  PROP_AGENT = 1,
+  PROP_STREAM,
+  PROP_COMPONENT
+};
+
+
+static void
+gst_nice_src_class_init (GstNiceSrcClass *klass)
+{
+  GstPushSrcClass *gstpushsrc_class;
+  GstBaseSrcClass *gstbasesrc_class;
+  GstElementClass *gstelement_class;
+  GObjectClass *gobject_class;
+
+  GST_DEBUG_CATEGORY_INIT (nicesrc_debug, "nicesrc",
+      0, "libnice source");
+
+  gstpushsrc_class = (GstPushSrcClass *) klass;
+  gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_nice_src_create);
+
+  gstbasesrc_class = (GstBaseSrcClass *) klass;
+  gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_nice_src_unlock);
+  gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_nice_src_unlock_stop);
+
+  gobject_class = (GObjectClass *) klass;
+  gobject_class->set_property = gst_nice_src_set_property;
+  gobject_class->get_property = gst_nice_src_get_property;
+  gobject_class->dispose = gst_nice_src_dispose;
+
+  gstelement_class = (GstElementClass *) klass;
+  gstelement_class->change_state = gst_nice_src_change_state;
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_nice_src_src_template));
+#if GST_CHECK_VERSION (1,0,0)
+  gst_element_class_set_metadata (gstelement_class,
+#else
+  gst_element_class_set_details_simple (gstelement_class,
+#endif
+      "ICE source",
+      "Source",
+      "Interactive UDP connectivity establishment",
+      "Dafydd Harries <dafydd.harries@collabora.co.uk>");
+
+  g_object_class_install_property (gobject_class, PROP_AGENT,
+      g_param_spec_object (
+         "agent",
+         "Agent",
+         "The NiceAgent this source is bound to",
+         NICE_TYPE_AGENT,
+         G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_STREAM,
+      g_param_spec_uint (
+         "stream",
+         "Stream ID",
+         "The ID of the stream to read from",
+         0,
+         G_MAXUINT,
+         0,
+         G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_COMPONENT,
+      g_param_spec_uint (
+         "component",
+         "Component ID",
+         "The ID of the component to read from",
+         0,
+         G_MAXUINT,
+         0,
+         G_PARAM_READWRITE));
+}
+
+static void
+gst_nice_src_init (GstNiceSrc *src)
+{
+  gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
+  gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
+  gst_base_src_set_do_timestamp (GST_BASE_SRC (src), TRUE);
+  src->agent = NULL;
+  src->stream_id = 0;
+  src->component_id = 0;
+  src->mainctx = g_main_context_new ();
+  src->mainloop = g_main_loop_new (src->mainctx, FALSE);
+  src->unlocked = FALSE;
+  src->idle_source = NULL;
+  src->outbufs = g_queue_new ();
+}
+
+static void
+gst_nice_src_read_callback (NiceAgent *agent,
+    guint stream_id,
+    guint component_id,
+    guint len,
+    gchar *buf,
+    gpointer data)
+{
+  GstBaseSrc *basesrc = GST_BASE_SRC (data);
+  GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc);
+  GstBuffer *buffer = NULL;
+
+  GST_LOG_OBJECT (agent, "Got buffer, getting out of the main loop");
+
+#if GST_CHECK_VERSION (1,0,0)
+  buffer = gst_buffer_new_allocate (NULL, len, NULL);
+  gst_buffer_fill (buffer, 0, buf, len);
+#else
+  buffer = gst_buffer_new_and_alloc (len);
+  memcpy (GST_BUFFER_DATA (buffer), buf, len);
+#endif
+  GST_OBJECT_LOCK (nicesrc);
+  g_queue_push_tail (nicesrc->outbufs, buffer);
+  g_main_loop_quit (nicesrc->mainloop);
+  GST_OBJECT_UNLOCK (nicesrc);
+}
+
+static gboolean
+gst_nice_src_unlock_idler (gpointer data)
+{
+  GstNiceSrc *nicesrc = GST_NICE_SRC (data);
+
+  GST_OBJECT_LOCK (nicesrc);
+  if (nicesrc->unlocked)
+    g_main_loop_quit (nicesrc->mainloop);
+
+  if (nicesrc->idle_source) {
+    g_source_destroy (nicesrc->idle_source);
+    g_source_unref (nicesrc->idle_source);
+    nicesrc->idle_source = NULL;
+  }
+  GST_OBJECT_UNLOCK (nicesrc);
+
+  return FALSE;
+}
+
+static gboolean
+gst_nice_src_unlock (GstBaseSrc *src)
+{
+  GstNiceSrc *nicesrc = GST_NICE_SRC (src);
+
+  GST_OBJECT_LOCK (src);
+  nicesrc->unlocked = TRUE;
+
+  g_main_loop_quit (nicesrc->mainloop);
+
+  if (!nicesrc->idle_source) {
+    nicesrc->idle_source = g_idle_source_new ();
+    g_source_set_priority (nicesrc->idle_source, G_PRIORITY_HIGH);
+    g_source_set_callback (nicesrc->idle_source, gst_nice_src_unlock_idler, src, NULL);
+    g_source_attach (nicesrc->idle_source, g_main_loop_get_context (nicesrc->mainloop));
+  }
+  GST_OBJECT_UNLOCK (src);
+
+  return TRUE;
+}
+
+static gboolean
+gst_nice_src_unlock_stop (GstBaseSrc *src)
+{
+  GstNiceSrc *nicesrc = GST_NICE_SRC (src);
+
+  GST_OBJECT_LOCK (src);
+  nicesrc->unlocked = FALSE;
+  if (nicesrc->idle_source) {
+    g_source_destroy (nicesrc->idle_source);
+    g_source_unref(nicesrc->idle_source);
+  }
+  nicesrc->idle_source = NULL;
+  GST_OBJECT_UNLOCK (src);
+
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_nice_src_create (
+  GstPushSrc *basesrc,
+  GstBuffer **buffer)
+{
+  GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc);
+
+  GST_LOG_OBJECT (nicesrc, "create called");
+
+  GST_OBJECT_LOCK (basesrc);
+  if (nicesrc->unlocked) {
+    GST_OBJECT_UNLOCK (basesrc);
+#if GST_CHECK_VERSION (1,0,0)
+    return GST_FLOW_FLUSHING;
+#else
+    return GST_FLOW_WRONG_STATE;
+#endif
+  }
+  if (g_queue_is_empty (nicesrc->outbufs)) {
+    GST_OBJECT_UNLOCK (basesrc);
+    g_main_loop_run (nicesrc->mainloop);
+    GST_OBJECT_LOCK (basesrc);
+  }
+
+  *buffer = g_queue_pop_head (nicesrc->outbufs);
+  GST_OBJECT_UNLOCK (basesrc);
+
+  if (*buffer != NULL) {
+    GST_LOG_OBJECT (nicesrc, "Got buffer, pushing");
+    return GST_FLOW_OK;
+  } else {
+    GST_LOG_OBJECT (nicesrc, "Got interrupting, returning wrong-state");
+#if GST_CHECK_VERSION (1,0,0)
+    return GST_FLOW_FLUSHING;
+#else
+    return GST_FLOW_WRONG_STATE;
+#endif
+  }
+
+}
+
+static void
+gst_nice_src_dispose (GObject *object)
+{
+  GstNiceSrc *src = GST_NICE_SRC (object);
+
+  if (src->agent)
+    g_object_unref (src->agent);
+  src->agent = NULL;
+
+  if (src->mainloop)
+    g_main_loop_unref (src->mainloop);
+  src->mainloop = NULL;
+
+  if (src->mainctx)
+    g_main_context_unref (src->mainctx);
+  src->mainctx = NULL;
+
+  if (src->outbufs) {
+    g_queue_free_full (src->outbufs, (GDestroyNotify) gst_buffer_unref);
+  }
+  src->outbufs = NULL;
+
+  if (src->idle_source) {
+    g_source_destroy (src->idle_source);
+    g_source_unref(src->idle_source);
+  }
+  src->idle_source = NULL;
+
+  G_OBJECT_CLASS (gst_nice_src_parent_class)->dispose (object);
+}
+
+static void
+gst_nice_src_set_property (
+  GObject *object,
+  guint prop_id,
+  const GValue *value,
+  GParamSpec *pspec)
+{
+  GstNiceSrc *src = GST_NICE_SRC (object);
+
+  switch (prop_id)
+    {
+    case PROP_AGENT:
+      if (src->agent)
+        GST_ERROR_OBJECT (object,
+            "Changing the agent on a nice src not allowed");
+      else
+        src->agent = g_value_dup_object (value);
+      break;
+
+    case PROP_STREAM:
+      src->stream_id = g_value_get_uint (value);
+      break;
+
+    case PROP_COMPONENT:
+      src->component_id = g_value_get_uint (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gst_nice_src_get_property (
+  GObject *object,
+  guint prop_id,
+  GValue *value,
+  GParamSpec *pspec)
+{
+  GstNiceSrc *src = GST_NICE_SRC (object);
+
+  switch (prop_id)
+    {
+    case PROP_AGENT:
+      g_value_set_object (value, src->agent);
+      break;
+
+    case PROP_STREAM:
+      g_value_set_uint (value, src->stream_id);
+      break;
+
+    case PROP_COMPONENT:
+      g_value_set_uint (value, src->component_id);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static GstStateChangeReturn
+gst_nice_src_change_state (GstElement * element, GstStateChange transition)
+{
+  GstNiceSrc *src;
+  GstStateChangeReturn ret;
+
+  src = GST_NICE_SRC (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      if (src->agent == NULL)
+        {
+          GST_ERROR_OBJECT (element,
+              "Trying to start Nice source without an agent set");
+          return GST_STATE_CHANGE_FAILURE;
+        }
+      else if (src->stream_id == 0)
+          {
+            GST_ERROR_OBJECT (element,
+                "Trying to start Nice source without a stream set");
+            return GST_STATE_CHANGE_FAILURE;
+          }
+      else if (src->component_id == 0)
+          {
+            GST_ERROR_OBJECT (element,
+                "Trying to start Nice source without a component set");
+            return GST_STATE_CHANGE_FAILURE;
+          }
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      nice_agent_attach_recv (src->agent, src->stream_id, src->component_id,
+          src->mainctx, NULL, NULL);
+      GST_OBJECT_LOCK (src);
+      g_list_free_full (src->outbufs->head, (GDestroyNotify) gst_buffer_unref);
+      g_queue_init (src->outbufs);
+      GST_OBJECT_UNLOCK (src);
+      break;
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+    case GST_STATE_CHANGE_READY_TO_NULL:
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (gst_nice_src_parent_class)->change_state (element,
+      transition);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      nice_agent_attach_recv (src->agent, src->stream_id, src->component_id,
+          src->mainctx, gst_nice_src_read_callback, (gpointer) src);
+      break;
+    case GST_STATE_CHANGE_NULL_TO_READY:
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+    case GST_STATE_CHANGE_READY_TO_NULL:
+    default:
+      break;
+  }
+
+  return ret;
+}
+
+
diff --git a/subprojects/gst-plugins-bad/ext/nice/gstnicesrc.h b/subprojects/gst-plugins-bad/ext/nice/gstnicesrc.h
new file mode 100644 (file)
index 0000000..5d3f554
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2006, 2007 Collabora Ltd.
+ *  Contact: Dafydd Harries
+ * (C) 2006, 2007 Nokia Corporation. All rights reserved.
+ *  Contact: Kai Vehmanen
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ *   Dafydd Harries, Collabora Ltd.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+
+#ifndef _GSTNICESRC_H
+#define _GSTNICESRC_H
+
+#include <gst/gst.h>
+#include <gst/base/gstpushsrc.h>
+
+#include <nice/nice.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_NICE_SRC \
+  (gst_nice_src_get_type())
+#define GST_NICE_SRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NICE_SRC,GstNiceSrc))
+#define GST_NICE_SRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NICE_SRC,GstNiceSrcClass))
+#define GST_IS_NICE_SRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NICE_SRC))
+#define GST_IS_NICE_SRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NICE_SRC))
+
+typedef struct _GstNiceSrc GstNiceSrc;
+
+struct _GstNiceSrc
+{
+  GstPushSrc parent;
+  GstPad *srcpad;
+  NiceAgent *agent;
+  guint stream_id;
+  guint component_id;
+  GMainContext *mainctx;
+  GMainLoop *mainloop;
+  GQueue *outbufs;
+  gboolean unlocked;
+  GSource *idle_source;
+};
+
+typedef struct _GstNiceSrcClass GstNiceSrcClass;
+
+struct _GstNiceSrcClass
+{
+  GstPushSrcClass parent_class;
+};
+
+GType gst_nice_src_get_type (void);
+
+G_END_DECLS
+
+#endif // _GSTNICESRC_H
+
diff --git a/subprojects/gst-plugins-bad/ext/nice/meson.build b/subprojects/gst-plugins-bad/ext/nice/meson.build
new file mode 100644 (file)
index 0000000..b5fc742
--- /dev/null
@@ -0,0 +1,20 @@
+gst_nice_sources = [
+  'gstnicesrc.c',
+  'gstnicesink.c',
+  'gstnice.c',
+]
+
+gst_plugins_install_dir = join_paths(get_option('libdir'), 'gstreamer-1.0')
+
+libgstnice = library('gstnice',
+  gst_nice_sources,
+  c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API'],
+  include_directories: [configinc],
+  dependencies: [libnice_dep, gst_dep, gstbase_dep],
+  install_dir: gst_plugins_install_dir,
+  install: true)
+
+# Generate pc files for static plugins if we build static plugins
+if get_option('default_library') != 'shared'
+  pkg.generate(libgstnice, install_dir: join_paths(gst_plugins_install_dir, 'pkgconfig'))
+endif
index 6834bda..3b72173 100644 (file)
@@ -456,6 +456,9 @@ cdata.set('TIZEN_FEATURE_WEBRTC_MODIFICATION', true)
 cdata.set('TIZEN_FEATURE_WEBRTC_IMPORT_NETSIM', true)
 cdata.set('TIZEN_FEATURE_PITCH_AUDIO_META', true)
 
+# For plugins from libnice
+libnice_dep = dependency('nice', version : '>=0.1.17', required : get_option('nice'))
+
 # TIZEN BUILD OPTION end
 
 # Disable compiler warnings for unused variables and args if gst debug system is disabled
index 513e048..7fa60e1 100644 (file)
@@ -220,3 +220,7 @@ option('doc', type : 'feature', value : 'auto', yield: true,
 # Tizen Options
 option('tv-profile', type : 'boolean', value : false,
        description : 'tv-profile')
+
+# nice plugins from libnice
+option('nice', type : 'feature', value : 'auto', description : 'Interactive UDP connectivity establishment')
+