From b4f718acfd4150ed8ac4689020ae2ac1df531288 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 18 Jun 2012 12:19:06 +0200 Subject: [PATCH] Added Playback tutorial 3. --- gst-sdk/tutorials/playback-tutorial-3.c | 161 +++++++++++++++++++++ .../playback-tutorial-3.vcxproj | 95 ++++++++++++ .../playback-tutorial-3.vcxproj.filters | 6 + gst-sdk/tutorials/vs2010/tutorials.sln | 10 ++ 4 files changed, 272 insertions(+) create mode 100644 gst-sdk/tutorials/playback-tutorial-3.c create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj.filters diff --git a/gst-sdk/tutorials/playback-tutorial-3.c b/gst-sdk/tutorials/playback-tutorial-3.c new file mode 100644 index 0000000..c170ecc --- /dev/null +++ b/gst-sdk/tutorials/playback-tutorial-3.c @@ -0,0 +1,161 @@ +#include +#include + +#define GRAPH_LENGTH 80 + +/* playbin2 flags */ +typedef enum { + GST_PLAY_FLAG_DOWNLOAD = (1 << 7) /* Enable progressive download buffering for selected formats. */ +} GstPlayFlags; + +typedef struct _CustomData { + gboolean is_live; + GstElement *pipeline; + GMainLoop *loop; + gint buffering_level; +} CustomData; + +static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data) { + + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: { + GError *err; + gchar *debug; + + gst_message_parse_error (msg, &err, &debug); + g_print ("Error: %s\n", err->message); + g_error_free (err); + g_free (debug); + + gst_element_set_state (data->pipeline, GST_STATE_READY); + g_main_loop_quit (data->loop); + break; + } + case GST_MESSAGE_EOS: + /* end-of-stream */ + gst_element_set_state (data->pipeline, GST_STATE_READY); + g_main_loop_quit (data->loop); + break; + case GST_MESSAGE_BUFFERING: + /* If the stream is live, we do not care about buffering. */ + if (data->is_live) break; + + gst_message_parse_buffering (msg, &data->buffering_level); + + /* Wait until buffering is complete before start/resume playing */ + if (data->buffering_level < 100) + gst_element_set_state (data->pipeline, GST_STATE_PAUSED); + else + gst_element_set_state (data->pipeline, GST_STATE_PLAYING); + break; + case GST_MESSAGE_CLOCK_LOST: + /* Get a new clock */ + gst_element_set_state (data->pipeline, GST_STATE_PAUSED); + gst_element_set_state (data->pipeline, GST_STATE_PLAYING); + break; + default: + /* Unhandled message */ + break; + } +} + +static gboolean refresh_ui (CustomData *data) { + GstQuery *query; + gboolean result; + + query = gst_query_new_buffering (GST_FORMAT_PERCENT); + result = gst_element_query (data->pipeline, query); + if (result) { + gint n_ranges, range, i; + gchar graph[GRAPH_LENGTH + 1]; + GstFormat format = GST_FORMAT_TIME; + gint64 position = 0, duration = 0; + + memset (graph, ' ', GRAPH_LENGTH); + graph[GRAPH_LENGTH] = '\0'; + + n_ranges = gst_query_get_n_buffering_ranges (query); + for (range = 0; range < n_ranges; range++) { + gint64 start, stop; + gst_query_parse_nth_buffering_range (query, range, &start, &stop); + start = start * GRAPH_LENGTH / 100; + stop = stop * GRAPH_LENGTH / 100; + for (i = (gint)start; i < stop; i++) + graph [i] = '-'; + } + if (gst_element_query_position (data->pipeline, &format, &position) && + GST_CLOCK_TIME_IS_VALID (position) && + gst_element_query_duration (data->pipeline, &format, &duration) && + GST_CLOCK_TIME_IS_VALID (duration)) { + i = (gint)(GRAPH_LENGTH * (double)position / (double)(duration + 1)); + graph [i] = data->buffering_level < 100 ? 'X' : '>'; + } + g_print ("[%s]", graph); + if (data->buffering_level < 100) { + g_print (" Buffering: %3d%%", data->buffering_level); + } else { + g_print (" "); + } + g_print ("\r"); + } + + return TRUE; + +} + +int main(int argc, char *argv[]) { + GstElement *pipeline; + GstBus *bus; + GstStateChangeReturn ret; + GMainLoop *main_loop; + CustomData data; + guint flags; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Initialize our data structure */ + memset (&data, 0, sizeof (data)); + data.buffering_level = 100; + + /* Build the pipeline */ + pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL); +// pipeline = gst_parse_launch ("playbin2 uri=http://micro.autom.teithe.gr/~vivia/oldmovies/peta.mp4", NULL); + bus = gst_element_get_bus (pipeline); + + /* Set the download flag */ + g_object_get (pipeline, "flags", &flags, NULL); + flags |= GST_PLAY_FLAG_DOWNLOAD; + g_object_set (pipeline, "flags", flags, NULL); + + /* Start playing */ + ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + g_printerr ("Unable to set the pipeline to the playing state.\n"); + gst_object_unref (pipeline); + return -1; + } else if (ret == GST_STATE_CHANGE_NO_PREROLL) { + data.is_live = TRUE; + } + + main_loop = g_main_loop_new (NULL, FALSE); + data.loop = main_loop; + data.pipeline = pipeline; + + gst_bus_add_signal_watch (bus); + g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data); + + /* Register a function that GLib will call every second */ + g_timeout_add_seconds (1, (GSourceFunc)refresh_ui, &data); + + g_main_loop_run (main_loop); + + /* Free resources */ + g_main_loop_unref (main_loop); + gst_object_unref (bus); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); + + g_print ("\n"); + return 0; +} \ No newline at end of file diff --git a/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj b/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj new file mode 100644 index 0000000..34c5ea5 --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + Win32Proj + {0342A79A-3522-416B-A4F8-58F5664B8415} + v4.0 + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + false + true + + + + + + \ No newline at end of file diff --git a/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj.filters b/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj.filters new file mode 100644 index 0000000..97cf279 --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj.filters @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/gst-sdk/tutorials/vs2010/tutorials.sln b/gst-sdk/tutorials/vs2010/tutorials.sln index afa1ea7..f8227e9 100644 --- a/gst-sdk/tutorials/vs2010/tutorials.sln +++ b/gst-sdk/tutorials/vs2010/tutorials.sln @@ -25,6 +25,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic-tutorial-9", "basic-t EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic-tutorial-12", "basic-tutorial-12\basic-tutorial-12.vcxproj", "{A2E63C29-3375-4930-B7D3-2F23EC824EAF}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-3", "playback-tutorial-3\playback-tutorial-3.vcxproj", "{0342A79A-3522-416B-A4F8-58F5664B8415}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -129,6 +131,14 @@ Global {A2E63C29-3375-4930-B7D3-2F23EC824EAF}.Release|Win32.Build.0 = Release|Win32 {A2E63C29-3375-4930-B7D3-2F23EC824EAF}.Release|x64.ActiveCfg = Release|x64 {A2E63C29-3375-4930-B7D3-2F23EC824EAF}.Release|x64.Build.0 = Release|x64 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Debug|Win32.ActiveCfg = Debug|Win32 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Debug|Win32.Build.0 = Debug|Win32 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Debug|x64.ActiveCfg = Debug|x64 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Debug|x64.Build.0 = Debug|x64 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Release|Win32.ActiveCfg = Release|Win32 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Release|Win32.Build.0 = Release|Win32 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Release|x64.ActiveCfg = Release|x64 + {0342A79A-3522-416B-A4F8-58F5664B8415}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE -- 2.7.4