[Bug 725187] Add new multiappsrc or dynappsrc element with multiple output streams

GStreamer (bugzilla.gnome.org) bugzilla at gnome.org
Fri Nov 7 02:43:10 PST 2014


https://bugzilla.gnome.org/show_bug.cgi?id=725187
  GStreamer | gst-plugins-bad | git

--- Comment #9 from Wonchul Lee <wonchul86.lee at lge.com> 2014-11-07 10:43:05 UTC ---
(From update of attachment 290145)
>From 15ba3c36f5aa60e8a4209b863583b088c9594321 Mon Sep 17 00:00:00 2001
>From: Wonchul Lee <wonchul86.lee at lge.com>
>Date: Fri, 7 Nov 2014 08:45:41 +0900
>Subject: [PATCH] dynappsrc: Add new element to handle multiple appsrc element
>
>---
> configure.ac                 |   2 +
> gst/dynappsrc/Makefile.am    |  13 ++
> gst/dynappsrc/gstdynappsrc.c | 526 +++++++++++++++++++++++++++++++++++++++++++
> gst/dynappsrc/gstdynappsrc.h |  79 +++++++
> gst/dynappsrc/plugins.c      |  45 ++++
> 5 files changed, 665 insertions(+)
> create mode 100644 gst/dynappsrc/Makefile.am
> create mode 100644 gst/dynappsrc/gstdynappsrc.c
> create mode 100644 gst/dynappsrc/gstdynappsrc.h
> create mode 100644 gst/dynappsrc/plugins.c
>
>diff --git a/configure.ac b/configure.ac
>index fdb6c88..63101a1 100644
>--- a/configure.ac
>+++ b/configure.ac
>@@ -445,6 +445,7 @@ AG_GST_CHECK_PLUGIN(dccp)
> AG_GST_CHECK_PLUGIN(debugutils)
> AG_GST_CHECK_PLUGIN(dvbsuboverlay)
> AG_GST_CHECK_PLUGIN(dvdspu)
>+AG_GST_CHECK_PLUGIN(dynappsrc)
> AG_GST_CHECK_PLUGIN(faceoverlay)
> AG_GST_CHECK_PLUGIN(festival)
> AG_GST_CHECK_PLUGIN(fieldanalysis)
>@@ -3253,6 +3254,7 @@ gst/dccp/Makefile
> gst/debugutils/Makefile
> gst/dvbsuboverlay/Makefile
> gst/dvdspu/Makefile
>+gst/dynappsrc/Makefile
> gst/faceoverlay/Makefile
> gst/festival/Makefile
> gst/fieldanalysis/Makefile
>diff --git a/gst/dynappsrc/Makefile.am b/gst/dynappsrc/Makefile.am
>new file mode 100644
>index 0000000..93abbae
>--- /dev/null
>+++ b/gst/dynappsrc/Makefile.am
>@@ -0,0 +1,13 @@
>+plugin_LTLIBRARIES = libgstdynappsrc.la
>+
>+# sources used to compile this plug-in
>+libgstdynappsrc_la_SOURCES = plugins.c gstdynappsrc.c
>+
>+# compiler and linker flags used to compile this plugin, set in configure.ac
>+libgstdynappsrc_la_CFLAGS = $(GST_CFLAGS)
>+libgstdynappsrc_la_LIBADD = $(GST_LIBS) -lgstvideo- at GST_API_VERSION@ -lgstaudio- at GST_API_VERSION@
>+libgstdynappsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
>+libgstdynappsrc_la_LIBTOOLFLAGS = --tag=disable-static
>+
>+# headers we need but don't want installed
>+noinst_HEADERS = gstdynappsrc.h
>diff --git a/gst/dynappsrc/gstdynappsrc.c b/gst/dynappsrc/gstdynappsrc.c
>new file mode 100644
>index 0000000..ade2527
>--- /dev/null
>+++ b/gst/dynappsrc/gstdynappsrc.c
>@@ -0,0 +1,526 @@
>+/* GStreamer Dynamic App Source element
>+ * Copyright (C) 2014 LG Electronics, Inc.
>+ *  Author : Wonchul Lee <wonchul86.lee at lge.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., 59 Temple Place - Suite 330,
>+ * Boston, MA 02111-1307, USA.
>+ */
>+
>+
>+/**
>+ * SECTION:element-dynappsrc
>+ *
>+ * Dynappsrc provides multiple appsrc elements inside a single source bin
>+ * for handling separated audio, video and text stream.
>+ *
>+ * <refsect2>
>+ * <title>Usage</title>
>+ * <para>
>+ * A dynappsrc element is created by pipeline based on "dynappsrc://" protocal URI.
>+ *
>+ * Dynappsrc is #GstBin. An appsrc element is created by new-appsrc signal action
>+ * to dynappsrc.
>+ *
>+ * When playback finished, received error or the application want to switch a
>+ * different track, dynappsrc should be set back to READY or NULL state.
>+ * Then appsrc elements in dynappsrc should be set to the NULL state and removed
>+ * from it.
>+ * </para>
>+ * </refsect2>
>+ * <refsect2>
>+ * <title>Examples</title>
>+ * |[
>+ * app->playbin = gst_element_factory_make ("playbin", NULL);
>+ * g_object_set (app->playbin, "uri", "dynappsrc://", NULL);
>+ * g_signal_connect (app->playbin, "deep-notify::source",
>+ *     (GCallback) found_source, app);
>+ * ]|
>+ * Create dynappsrc element in pipeline and watch source notify.
>+ * |[
>+ * gst_object_ref (appsrc1);
>+ * gst_object_ref (appsrc2);
>+ *
>+ * g_signal_emit_by_name (dynappsrc, "new-appsrc", &appsrc1);
>+ * g_signal_emit_by_name (dynappsrc, "new-appsrc", &appsrc2);
>+ *
>+ * g_signal_connect (app->appsrc1, "need-data", G_CALLBACK (start_feed), app);
>+ * g_signal_connect (app->appsrc1, "enough-data", G_CALLBACK (stop_feed), app);
>+ *
>+ * g_signal_connect (app->appsrc2, "need-data", G_CALLBACK (start_feed), app);
>+ * g_signal_connect (app->appsrc2, "enough-data", G_CALLBACK (stop_feed), app);
>+ * ]|
>+ * Create appsrc elements when called source notify handler.
>+ * </refsect2>
>+ */
>+
>+#ifdef HAVE_CONFIG_H
>+#include <config.h>
>+#endif
>+
>+#include <stdio.h>
>+#include <string.h>
>+#include <unistd.h>
>+
>+#include "gstdynappsrc.h"
>+
>+GST_DEBUG_CATEGORY_STATIC (dyn_appsrc_debug);
>+#define GST_CAT_DEFAULT dyn_appsrc_debug
>+
>+#define parent_class gst_dyn_appsrc_parent_class
>+
>+#define DEFAULT_PROP_URI NULL
>+
>+enum
>+{
>+  PROP_0,
>+  PROP_URI,
>+  PROP_N_SRC,
>+  PROP_LAST
>+};
>+
>+enum
>+{
>+  SIGNAL_NEW_APPSRC,
>+
>+  /* actions */
>+  SIGNAL_END_OF_STREAM,
>+  LAST_SIGNAL
>+};
>+
>+static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src_%u",
>+    GST_PAD_SRC,
>+    GST_PAD_SOMETIMES,
>+    GST_STATIC_CAPS_ANY);
>+
>+static guint gst_dyn_appsrc_signals[LAST_SIGNAL] = { 0 };
>+
>+static void gst_dyn_appsrc_set_property (GObject * object, guint prop_id,
>+    const GValue * value, GParamSpec * pspec);
>+static void gst_dyn_appsrc_get_property (GObject * object, guint prop_id,
>+    GValue * value, GParamSpec * pspec);
>+static void gst_dyn_appsrc_finalize (GObject * self);
>+static GstStateChangeReturn gst_dyn_appsrc_change_state (GstElement * element,
>+    GstStateChange transition);
>+static GstElement *gst_dyn_appsrc_new_appsrc (GstDynAppSrc * bin,
>+    const gchar * name);
>+static void gst_dyn_appsrc_uri_handler_init (gpointer g_iface,
>+    gpointer iface_data);
>+
>+G_DEFINE_TYPE_WITH_CODE (GstDynAppSrc, gst_dyn_appsrc, GST_TYPE_BIN,
>+    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
>+        gst_dyn_appsrc_uri_handler_init));
>+
>+
>+static void
>+gst_dyn_appsrc_class_init (GstDynAppSrcClass * klass)
>+{
>+  GObjectClass *gobject_class;
>+  GstElementClass *gstelement_class;
>+
>+  gobject_class = G_OBJECT_CLASS (klass);
>+  gstelement_class = GST_ELEMENT_CLASS (klass);
>+
>+  gobject_class->set_property = gst_dyn_appsrc_set_property;
>+  gobject_class->get_property = gst_dyn_appsrc_get_property;
>+  gobject_class->finalize = gst_dyn_appsrc_finalize;
>+
>+  gst_element_class_add_pad_template (gstelement_class,
>+      gst_static_pad_template_get (&src_template));
>+
>+  g_object_class_install_property (gobject_class, PROP_URI,
>+      g_param_spec_string ("uri", "URI",
>+          "URI to get protected content",
>+          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
>+
>+  /**
>+   * GstDynAppSrc:n-src
>+   *
>+   * Get the total number of available streams.
>+   */
>+  g_object_class_install_property (gobject_class, PROP_N_SRC,
>+      g_param_spec_int ("n-source", "Number Source",
>+          "Total number of source streams", 0, G_MAXINT, 0,
>+          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
>+
>+  /**
>+   * GstDynAppSrc::new-appsrc
>+   * @dynappsrc: a #GstDynAppSrc
>+   * @name : name of appsrc element
>+   *
>+   * Action signal to create a appsrc element.
>+   * This signal should be emitted before changing state READY to PAUSED.
>+   * The application emit this signal as soon as receiving source-setup signal from pipeline.
>+   *
>+   * Returns: a GstElement of appsrc element or NULL when element creation failed.
>+   */
>+  gst_dyn_appsrc_signals[SIGNAL_NEW_APPSRC] =
>+      g_signal_new ("new-appsrc", G_TYPE_FROM_CLASS (klass),
>+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
>+      G_STRUCT_OFFSET (GstDynAppSrcClass, new_appsrc), NULL, NULL,
>+      g_cclosure_marshal_generic, GST_TYPE_ELEMENT, 1, G_TYPE_STRING);
>+
>+  /**
>+    * GstDynAppSrc::end-of-stream:
>+    * @dynappsrc: the dynappsrc
>+    *
>+    * Notify all of @appsrc that no more buffer are available.
>+    */
>+  gst_dyn_appsrc_signals[SIGNAL_END_OF_STREAM] =
>+      g_signal_new ("end-of-stream", G_TYPE_FROM_CLASS (klass),
>+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstDynAppSrcClass,
>+          end_of_stream), NULL, NULL, g_cclosure_marshal_generic,
>+      GST_TYPE_FLOW_RETURN, 0, G_TYPE_NONE);
>+
>+  klass->new_appsrc = gst_dyn_appsrc_new_appsrc;
>+  klass->end_of_stream = gst_dyn_appsrc_end_of_stream;
>+
>+  gstelement_class->change_state =
>+      GST_DEBUG_FUNCPTR (gst_dyn_appsrc_change_state);
>+
>+  gst_element_class_set_static_metadata (gstelement_class,
>+      "Dynappsrc", "Source/Bin",
>+      "Dynamic App Source", "Wonchul Lee <wonchul86.lee at lge.com>");
>+
>+  GST_DEBUG_CATEGORY_INIT (dyn_appsrc_debug, "dynappsrc", 0,
>+      "Dynamic App Source");
>+}
>+
>+static void
>+gst_dyn_appsrc_init (GstDynAppSrc * bin)
>+{
>+  /* init member variable */
>+  bin->uri = g_strdup (DEFAULT_PROP_URI);
>+  bin->appsrc_list = NULL;
>+  bin->n_source = 0;
>+
>+  GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
>+}
>+
>+static void
>+gst_dyn_appsrc_set_property (GObject * object, guint prop_id,
>+    const GValue * value, GParamSpec * pspec)
>+{
>+  GstDynAppSrc *bin = GST_DYN_APPSRC (object);
>+
>+  switch (prop_id) {
>+    case PROP_URI:
>+    {
>+      GstURIHandler *handler;
>+      GstURIHandlerInterface *iface;
>+
>+      handler = GST_URI_HANDLER (bin);
>+      iface = GST_URI_HANDLER_GET_INTERFACE (handler);
>+      iface->set_uri (handler, g_value_get_string (value), NULL);
>+    }
>+      break;
>+    default:
>+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
>+      break;
>+  }
>+}
>+
>+static void
>+gst_dyn_appsrc_get_property (GObject * object, guint prop_id,
>+    GValue * value, GParamSpec * pspec)
>+{
>+  GstDynAppSrc *bin = GST_DYN_APPSRC (object);
>+
>+  switch (prop_id) {
>+    case PROP_URI:
>+      g_value_set_string (value, bin->uri);
>+      break;
>+    case PROP_N_SRC:
>+    {
>+      GST_OBJECT_LOCK (bin);
>+      g_value_set_int (value, bin->n_source);
>+      GST_OBJECT_UNLOCK (bin);
>+      break;
>+    }
>+    default:
>+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
>+      break;
>+  }
>+}
>+
>+static void
>+gst_dyn_appsrc_finalize (GObject * self)
>+{
>+  GstDynAppSrc *bin = GST_DYN_APPSRC (self);
>+
>+  g_free (bin->uri);
>+
>+  G_OBJECT_CLASS (parent_class)->finalize (self);
>+}
>+
>+static gboolean
>+gst_dyn_appsrc_handle_src_query (GstPad * pad, GstObject * parent,
>+    GstQuery * query)
>+{
>+  GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad));
>+  gboolean res = FALSE;
>+
>+  /* forward the query to the proxy target pad */
>+  if (target) {
>+    res = gst_pad_query (target, query);
>+    gst_object_unref (target);
>+  }
>+
>+  return res;
>+}
>+
>+static gboolean
>+gst_dyn_appsrc_handle_src_event (GstPad * pad, GstObject * parent,
>+    GstEvent * event)
>+{
>+  gboolean res = TRUE;
>+  GstPad *target;
>+  GstDynAppSrc *bin = GST_DYN_APPSRC (parent);
>+  GstIterator *it;
>+  GValue data = { 0, };
>+
>+  /*
>+   * dynappsrc handle a seek event that it send to all of linked appsrce elements.
>+   */
>+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
>+    it = gst_element_iterate_src_pads (GST_ELEMENT_CAST (bin));
>+    while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) {
>+      GstPad *srcpad = g_value_get_object (&data);
>+      target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (srcpad));
>+      res = gst_pad_send_event (target, gst_event_ref (event));
>+      gst_object_unref (target);
>+      g_value_reset (&data);
>+    }
>+    gst_event_unref (event);
>+    g_value_unset (&data);
>+    gst_iterator_free (it);
>+  } else if ((target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad)))) {
>+    res = gst_pad_send_event (target, event);
>+    gst_object_unref (target);
>+  } else
>+    gst_event_unref (event);
>+
>+  return res;
>+}
>+
>+static gboolean
>+setup_source (GstDynAppSrc * bin)
>+{
>+  GList *item;
>+  GstPadTemplate *pad_tmpl;
>+  gchar *padname;
>+  gboolean ret = FALSE;
>+
>+  pad_tmpl = gst_static_pad_template_get (&src_template);
>+
>+  for (item = bin->appsrc_list; item; item = g_list_next (item)) {
>+    GstAppSourceGroup *appsrc_group = (GstAppSourceGroup *) item->data;
>+    GstPad *srcpad = NULL;
>+
>+    gst_bin_add (GST_BIN_CAST (bin), appsrc_group->appsrc);
>+
>+    srcpad = gst_element_get_static_pad (appsrc_group->appsrc, "src");
>+    padname =
>+        g_strdup_printf ("src_%u", g_list_position (bin->appsrc_list, item));
>+    appsrc_group->srcpad =
>+        gst_ghost_pad_new_from_template (padname, srcpad, pad_tmpl);
>+    gst_pad_set_event_function (appsrc_group->srcpad,
>+        gst_dyn_appsrc_handle_src_event);
>+    gst_pad_set_query_function (appsrc_group->srcpad,
>+        gst_dyn_appsrc_handle_src_query);
>+
>+    gst_pad_set_active (appsrc_group->srcpad, TRUE);
>+    gst_element_add_pad (GST_ELEMENT_CAST (bin), appsrc_group->srcpad);
>+
>+    gst_object_unref (srcpad);
>+    g_free (padname);
>+
>+    ret = TRUE;
>+  }
>+  gst_object_unref (pad_tmpl);
>+
>+  if (ret) {
>+    GST_DEBUG_OBJECT (bin, "all appsrc elements are added");
>+    gst_element_no_more_pads (GST_ELEMENT_CAST (bin));
>+  }
>+
>+  return ret;
>+}
>+
>+static void
>+remove_source (GstDynAppSrc * bin)
>+{
>+  GList *item;
>+
>+  for (item = bin->appsrc_list; item; item = g_list_next (item)) {
>+    GstAppSourceGroup *appsrc_group = (GstAppSourceGroup *) item->data;
>+
>+    GST_DEBUG_OBJECT (bin, "removing appsrc element and ghostpad");
>+
>+    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (appsrc_group->srcpad), NULL);
>+    gst_element_remove_pad (GST_ELEMENT_CAST (bin), appsrc_group->srcpad);
>+    appsrc_group->srcpad = NULL;
>+
>+    gst_element_set_state (appsrc_group->appsrc, GST_STATE_NULL);
>+    gst_bin_remove (GST_BIN_CAST (bin), appsrc_group->appsrc);
>+    gst_object_unref (appsrc_group->appsrc);
>+    appsrc_group->appsrc = NULL;
>+  }
>+
>+  g_list_free_full (bin->appsrc_list, g_free);
>+  bin->appsrc_list = NULL;
>+
>+  bin->n_source = 0;
>+}
>+
>+static GstElement *
>+gst_dyn_appsrc_new_appsrc (GstDynAppSrc * bin, const gchar * name)
>+{
>+  GstAppSourceGroup *appsrc_group;
>+
>+  GST_OBJECT_LOCK (bin);
>+
>+  if (GST_STATE (bin) >= GST_STATE_PAUSED) {
>+    GST_WARNING_OBJECT (bin,
>+        "deny to create appsrc when state is in PAUSED or PLAYING state");
>+    GST_OBJECT_UNLOCK (bin);
>+    return NULL;
>+  }
>+  appsrc_group = g_malloc0 (sizeof (GstAppSourceGroup));
>+  appsrc_group->appsrc = gst_element_factory_make ("appsrc", name);
>+
>+  bin->appsrc_list = g_list_append (bin->appsrc_list, appsrc_group);
>+  bin->n_source++;
>+
>+  GST_INFO_OBJECT (bin, "appsrc %p is appended to a list",
>+      appsrc_group->appsrc);
>+  GST_INFO_OBJECT (bin, "source number = %d", bin->n_source);
>+
>+  GST_OBJECT_UNLOCK (bin);
>+
>+  return appsrc_group->appsrc;
>+}
>+
>+/**
>+ * gst_dyn_appsrc_end_of_stream:
>+ * @dynappsrc: a #GstDynAppSrc
>+ *
>+ * Indicates to all of appsrc elements that the last buffer queued in the
>+ * element is the last buffer of the stream.
>+ *
>+ * Returns: #GST_FLOW_OK when the EOS was successfuly queued.
>+ * #GST_FLOW_FLUSHING when @appsrc is not PAUSED or PLAYING.
>+ */
>+GstFlowReturn
>+gst_dyn_appsrc_end_of_stream (GstDynAppSrc * bin)
>+{
>+  GstFlowReturn ret = GST_FLOW_OK;
>+  GList *item;
>+
>+  for (item = bin->appsrc_list; item; item = g_list_next (item)) {
>+    GstAppSourceGroup *appsrc_group = (GstAppSourceGroup *) item->data;
>+
>+    GST_DEBUG_OBJECT (bin, "indicate to appsrc element for EOS");
>+    g_signal_emit_by_name (appsrc_group->appsrc, "end-of-stream", &ret);
>+    GST_DEBUG_OBJECT (bin, "%s[ret:%s]",
>+        GST_ELEMENT_NAME (appsrc_group->appsrc), gst_flow_get_name (ret));
>+    if (ret != GST_FLOW_OK)
>+      break;
>+  }
>+
>+  return ret;
>+}
>+
>+static GstStateChangeReturn
>+gst_dyn_appsrc_change_state (GstElement * element, GstStateChange transition)
>+{
>+  GstStateChangeReturn ret;
>+  GstDynAppSrc *bin = GST_DYN_APPSRC (element);
>+
>+  switch (transition) {
>+    case GST_STATE_CHANGE_READY_TO_PAUSED:
>+      if (!setup_source (bin))
>+        return GST_STATE_CHANGE_FAILURE;
>+      break;
>+    default:
>+      break;
>+  }
>+
>+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
>+
>+  switch (transition) {
>+    case GST_STATE_CHANGE_READY_TO_PAUSED:
>+      GST_DEBUG_OBJECT (bin, "ready to paused");
>+      if (ret == GST_STATE_CHANGE_FAILURE)
>+        goto setup_failed;
>+      break;
>+    case GST_STATE_CHANGE_PAUSED_TO_READY:
>+      GST_DEBUG_OBJECT (bin, "paused to ready");
>+      remove_source (bin);
>+      break;
>+    case GST_STATE_CHANGE_READY_TO_NULL:
>+      remove_source (bin);
>+      break;
>+    default:
>+      break;
>+  }
>+
>+  return ret;
>+
>+setup_failed:
>+  {
>+    /* clean up leftover groups */
>+    return GST_STATE_CHANGE_FAILURE;
>+  }
>+}
>+
>+static GstURIType
>+gst_dyn_appsrc_uri_get_type (GType type)
>+{
>+  return GST_URI_SRC;
>+}
>+
>+static const gchar *const *
>+gst_dyn_appsrc_uri_get_protocols (GType type)
>+{
>+  static const gchar *protocols[] = { "dynappsrc", NULL };
>+
>+  return protocols;
>+}
>+
>+static gchar *
>+gst_dyn_appsrc_uri_get_uri (GstURIHandler * handler)
>+{
>+  GstDynAppSrc *bin = GST_DYN_APPSRC (handler);
>+
>+  return bin->uri ? g_strdup (bin->uri) : NULL;
>+}
>+
>+static gboolean
>+gst_dyn_appsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri,
>+    GError ** error)
>+{
>+  return TRUE;
>+}
>+
>+static void
>+gst_dyn_appsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
>+{
>+  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
>+
>+  iface->get_type = gst_dyn_appsrc_uri_get_type;
>+  iface->get_protocols = gst_dyn_appsrc_uri_get_protocols;
>+  iface->get_uri = gst_dyn_appsrc_uri_get_uri;
>+  iface->set_uri = gst_dyn_appsrc_uri_set_uri;
>+}
>diff --git a/gst/dynappsrc/gstdynappsrc.h b/gst/dynappsrc/gstdynappsrc.h
>new file mode 100644
>index 0000000..7221bb4
>--- /dev/null
>+++ b/gst/dynappsrc/gstdynappsrc.h
>@@ -0,0 +1,79 @@
>+/* GStreamer Dynamic App Source element
>+ * Copyright (C) 2014 LG Electronics, Inc.
>+ *  Author : Wonchul Lee <wonchul86.lee at lge.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., 59 Temple Place - Suite 330,
>+ * Boston, MA 02111-1307, USA.
>+ */
>+
>+#ifndef __GST_DYN_APPSRC_H__
>+#define __GST_DYN_APPSRC_H__
>+
>+#include <gst/gst.h>
>+
>+G_BEGIN_DECLS
>+
>+#define GST_TYPE_DYN_APPSRC (gst_dyn_appsrc_get_type())
>+#define GST_DYN_APPSRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DYN_APPSRC,GstDynAppSrc))
>+#define GST_DYN_APPSRC_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj),GST_TYPE_DYN_APPSRC,GstDynAppSrcClass))
>+#define GST_IS_DYN_APPSRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DYN_APPSRC))
>+#define GST_IS_DYN_APPSRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj),GST_TYPE_DYN_APPSRC))
>+
>+typedef struct _GstDynAppSrc      GstDynAppSrc;
>+typedef struct _GstDynAppSrcClass GstDynAppSrcClass;
>+typedef struct _GstAppSourceGroup    GstAppSourceGroup;
>+
>+/**
>+ * GstDynAppSrc:
>+ *
>+ * dynappsrc element data structure
>+ */
>+struct _GstDynAppSrc
>+{
>+  GstBin parent;
>+
>+  GstPad* srcpad;
>+  gchar* uri;
>+
>+  GList *appsrc_list;
>+
>+  gint n_source;
>+
>+};
>+
>+struct _GstDynAppSrcClass
>+{
>+  GstBinClass parent_class;
>+
>+  /* create a appsrc element */
>+  GstElement *(*new_appsrc) (GstDynAppSrc * dynappsrc, const gchar * name);
>+
>+  /* actions */
>+    GstFlowReturn (*end_of_stream) (GstDynAppSrc * dynappsrc);
>+};
>+
>+struct _GstAppSourceGroup
>+{
>+  GstElement *appsrc;
>+  GstPad *srcpad;
>+};
>+
>+GType gst_dyn_appsrc_get_type (void);
>+
>+GstFlowReturn gst_dyn_appsrc_end_of_stream (GstDynAppSrc * dynappsrc);
>+
>+G_END_DECLS
>+#endif /* __GST_DYN_APPSRC_H__ */
>diff --git a/gst/dynappsrc/plugins.c b/gst/dynappsrc/plugins.c
>new file mode 100644
>index 0000000..cf0a386
>--- /dev/null
>+++ b/gst/dynappsrc/plugins.c
>@@ -0,0 +1,45 @@
>+/* GStreamer Dynamic App Source Plugins
>+ *
>+ * Copyright (C) 2014 LG Electronics, Inc.
>+ *	Author : Wonchul Lee <wonchul86.lee at lge.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., 59 Temple Place - Suite 330,
>+ * Boston, MA 02111-1307, USA.
>+ */
>+
>+#ifdef HAVE_CONFIG_H
>+#include <config.h>
>+#endif
>+
>+#include <string.h>
>+#include <gst/gst.h>
>+
>+#include "gstdynappsrc.h"
>+
>+static gboolean
>+plugin_init (GstPlugin * plugin)
>+{
>+  if (!gst_element_register (plugin, "dynappsrc", GST_RANK_PRIMARY,
>+          GST_TYPE_DYN_APPSRC))
>+    return FALSE;
>+
>+  return TRUE;
>+}
>+
>+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
>+    GST_VERSION_MINOR,
>+    dynappsrc,
>+    "Dynamic App Source",
>+    plugin_init, PACKAGE_VERSION, "LGPL", PACKAGE_NAME, PACKAGE_BUGREPORT)
>-- 
>1.9.1
>

-- 
Configure bugmail: https://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list