From 646352e9595dc7b1a42b60b6a7a6b29567ce2440 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Thu, 4 Sep 2014 11:56:50 +0200 Subject: appsrc: Add example that shows gst_app_src_push_sample() usage --- tests/examples/app/Makefile.am | 7 +- tests/examples/app/appsink-src2.c | 177 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 tests/examples/app/appsink-src2.c (limited to 'tests/examples') 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 + +#include + +#include +#include + +/* + * 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; +} -- cgit v1.2.3