summaryrefslogtreecommitdiff
path: root/tests/examples
diff options
context:
space:
mode:
authorNicola Murino <nicola.murino@gmail.com>2014-09-04 11:56:50 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-09-12 14:12:28 +0300
commit646352e9595dc7b1a42b60b6a7a6b29567ce2440 (patch)
tree6af08a4d20e69dc17357ad132618e474d411f23a /tests/examples
parent617f72b526087a21679a9d71af88259f65c2a1f6 (diff)
appsrc: Add example that shows gst_app_src_push_sample() usage
Diffstat (limited to 'tests/examples')
-rw-r--r--tests/examples/app/Makefile.am7
-rw-r--r--tests/examples/app/appsink-src2.c177
2 files changed, 183 insertions, 1 deletions
diff --git a/tests/examples/app/Makefile.am b/tests/examples/app/Makefile.am
index 3679e2819..689ee2fd3 100644
--- a/tests/examples/app/Makefile.am
+++ b/tests/examples/app/Makefile.am
@@ -1,6 +1,6 @@
noinst_PROGRAMS = appsrc_ex appsrc-stream appsrc-stream2 appsrc-ra \
- appsrc-seekable appsink-src
+ appsrc-seekable appsink-src appsink-src2
appsrc_ex_SOURCES = appsrc_ex.c
appsrc_ex_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
@@ -30,3 +30,8 @@ appsink_src_LDADD = \
$(top_builddir)/gst-libs/gst/app/libgstapp-@GST_API_VERSION@.la \
$(GST_BASE_LIBS) $(GST_LIBS)
+appsink_src2_SOURCES = appsink-src2.c
+appsink_src2_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
+appsink_src2_LDADD = \
+ $(top_builddir)/gst-libs/gst/app/libgstapp-@GST_API_VERSION@.la \
+ $(GST_BASE_LIBS) $(GST_LIBS)
diff --git a/tests/examples/app/appsink-src2.c b/tests/examples/app/appsink-src2.c
new file mode 100644
index 000000000..77ea4d4b6
--- /dev/null
+++ b/tests/examples/app/appsink-src2.c
@@ -0,0 +1,177 @@
+#include <gst/gst.h>
+
+#include <string.h>
+
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+
+/*
+ * In this sample we show the usage of gst_app_src_push_sample in push
+ * mode, this method set the appsrc caps based on the caps from the sample
+ *
+ */
+
+typedef struct
+{
+ GMainLoop *loop;
+ GstElement *source;
+ GstElement *sink;
+} ProgramData;
+
+/* called when the appsink notifies us that there is a new buffer ready for
+ * processing */
+
+static GstFlowReturn
+on_new_sample_from_sink (GstElement * elt, ProgramData * data)
+{
+ GstSample *sample;
+ GstElement *source;
+ GstFlowReturn ret;
+
+ /* get the sample from appsink */
+ sample = gst_app_sink_pull_sample (GST_APP_SINK (elt));
+
+ /* get source an push new sample */
+ source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
+ ret = gst_app_src_push_sample (GST_APP_SRC (source), sample);
+ gst_object_unref (source);
+
+ /* we don't need the appsink sample anymore */
+ gst_sample_unref (sample);
+
+ return ret;
+}
+
+/* called when we get a GstMessage from the source pipeline when we get EOS, we
+ * notify the appsrc of it. */
+static gboolean
+on_source_message (GstBus * bus, GstMessage * message, ProgramData * data)
+{
+ GstElement *source;
+
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ g_print ("The source got dry\n");
+ source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
+ gst_app_src_end_of_stream (GST_APP_SRC (source));
+ gst_object_unref (source);
+ break;
+ case GST_MESSAGE_ERROR:
+ g_print ("Received error\n");
+ g_main_loop_quit (data->loop);
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+/* called when we get a GstMessage from the sink pipeline when we get EOS, we
+ * exit the mainloop and this testapp. */
+static gboolean
+on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data)
+{
+ /* nil */
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ g_print ("Finished playback\n");
+ g_main_loop_quit (data->loop);
+ break;
+ case GST_MESSAGE_ERROR:
+ g_print ("Received error\n");
+ g_main_loop_quit (data->loop);
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ gchar *filename = NULL;
+ ProgramData *data = NULL;
+ gchar *string = NULL;
+ GstBus *bus = NULL;
+ GstElement *testsink = NULL;
+ GstElement *testsource = NULL;
+
+ gst_init (&argc, &argv);
+
+ data = g_new0 (ProgramData, 1);
+
+ data->loop = g_main_loop_new (NULL, FALSE);
+
+ /* setting up source pipeline, we read from a file and convert to our desired
+ * caps. */
+ string =
+ g_strdup_printf
+ ("audiotestsrc num-buffers=200 ! wavenc ! wavparse ! appsink name=testsink");
+ g_free (filename);
+ data->source = gst_parse_launch (string, NULL);
+ g_free (string);
+
+ if (data->source == NULL) {
+ g_print ("Bad source\n");
+ return -1;
+ }
+
+ /* to be notified of messages from this pipeline, mostly EOS */
+ bus = gst_element_get_bus (data->source);
+ gst_bus_add_watch (bus, (GstBusFunc) on_source_message, data);
+ gst_object_unref (bus);
+
+ /* we use appsink in push mode, it sends us a signal when data is available
+ * and we pull out the data in the signal callback. We want the appsink to
+ * push as fast as it can, hence the sync=false */
+ testsink = gst_bin_get_by_name (GST_BIN (data->source), "testsink");
+ g_object_set (G_OBJECT (testsink), "emit-signals", TRUE, "sync", FALSE, NULL);
+ g_signal_connect (testsink, "new-sample",
+ G_CALLBACK (on_new_sample_from_sink), data);
+ gst_object_unref (testsink);
+
+ /* setting up sink pipeline, we push audio data into this pipeline that will
+ * then play it back using the default audio sink. */
+ string =
+ g_strdup_printf
+ ("appsrc name=testsource ! audioconvert ! audioresample ! autoaudiosink");
+ data->sink = gst_parse_launch (string, NULL);
+ g_free (string);
+
+ if (data->sink == NULL) {
+ g_print ("Bad sink\n");
+ return -1;
+ }
+
+ testsource = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
+ /* configure for time-based format */
+ g_object_set (testsource, "format", GST_FORMAT_TIME, NULL);
+ /* uncomment the next line to block when appsrc has buffered enough */
+ /* g_object_set (testsource, "block", TRUE, NULL); */
+ gst_object_unref (testsource);
+
+ bus = gst_element_get_bus (data->sink);
+ gst_bus_add_watch (bus, (GstBusFunc) on_sink_message, data);
+ gst_object_unref (bus);
+
+ /* launching things */
+ gst_element_set_state (data->sink, GST_STATE_PLAYING);
+ gst_element_set_state (data->source, GST_STATE_PLAYING);
+
+ /* let's run !, this loop will quit when the sink pipeline goes EOS or when an
+ * error occurs in the source or sink pipelines. */
+ g_print ("Let's run!\n");
+ g_main_loop_run (data->loop);
+ g_print ("Going out\n");
+
+ gst_element_set_state (data->source, GST_STATE_NULL);
+ gst_element_set_state (data->sink, GST_STATE_NULL);
+
+ gst_object_unref (data->source);
+ gst_object_unref (data->sink);
+ g_main_loop_unref (data->loop);
+ g_free (data);
+
+ return 0;
+}