[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