From 3b393bd1d2f4d52b6eab7e10f4f5af51a6875f1c Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 11 Jun 2012 15:07:54 +0200 Subject: [PATCH 01/26] Use default toolset instead of forcing WinDDK's (This shouldn't have been committed). --- .../vs2010/basic-tutorial-12/basic-tutorial-12.vcxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst-sdk/tutorials/vs2010/basic-tutorial-12/basic-tutorial-12.vcxproj b/gst-sdk/tutorials/vs2010/basic-tutorial-12/basic-tutorial-12.vcxproj index 7d51383db7..bb5a388cfe 100644 --- a/gst-sdk/tutorials/vs2010/basic-tutorial-12/basic-tutorial-12.vcxproj +++ b/gst-sdk/tutorials/vs2010/basic-tutorial-12/basic-tutorial-12.vcxproj @@ -31,16 +31,12 @@ Application true Unicode - Windows7.1SDK - Windows7.1SDK Application false true Unicode - Windows7.1SDK - Windows7.1SDK From 63177bf882d3b28f184876fc8b2d8f05046abcd0 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 18 Jun 2012 10:34:24 +0200 Subject: [PATCH 02/26] Fix warnings shown with -Wall --- gst-sdk/tutorials/playback-tutorial-1.c | 2 ++ gst-sdk/tutorials/playback-tutorial-2.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/gst-sdk/tutorials/playback-tutorial-1.c b/gst-sdk/tutorials/playback-tutorial-1.c index 196edad6ac..e457de68ee 100644 --- a/gst-sdk/tutorials/playback-tutorial-1.c +++ b/gst-sdk/tutorials/playback-tutorial-1.c @@ -193,6 +193,8 @@ static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data) } } } break; + default: + break; } /* We want to keep receiving messages */ diff --git a/gst-sdk/tutorials/playback-tutorial-2.c b/gst-sdk/tutorials/playback-tutorial-2.c index 8e5ee15f8d..bd11fbb23d 100644 --- a/gst-sdk/tutorials/playback-tutorial-2.c +++ b/gst-sdk/tutorials/playback-tutorial-2.c @@ -195,6 +195,8 @@ static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data) } } } break; + default: + break; } /* We want to keep receiving messages */ From b4f718acfd4150ed8ac4689020ae2ac1df531288 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 18 Jun 2012 12:19:06 +0200 Subject: [PATCH 03/26] 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 0000000000..c170eccc9e --- /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 0000000000..34c5ea5ce3 --- /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 0000000000..97cf2797d4 --- /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 afa1ea7c62..f8227e920d 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 From 279e01a1589332280db154d6cff7bddf3ba7297a Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 18 Jun 2012 16:11:57 +0200 Subject: [PATCH 04/26] Print temp-location. --- gst-sdk/tutorials/playback-tutorial-3.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-3.c b/gst-sdk/tutorials/playback-tutorial-3.c index c170eccc9e..dfdb64c0d7 100644 --- a/gst-sdk/tutorials/playback-tutorial-3.c +++ b/gst-sdk/tutorials/playback-tutorial-3.c @@ -5,7 +5,7 @@ /* playbin2 flags */ typedef enum { - GST_PLAY_FLAG_DOWNLOAD = (1 << 7) /* Enable progressive download buffering for selected formats. */ + GST_PLAY_FLAG_DOWNLOAD = (1 << 7) /* Enable progressive download (on selected formats) */ } GstPlayFlags; typedef struct _CustomData { @@ -14,6 +14,14 @@ typedef struct _CustomData { GMainLoop *loop; gint buffering_level; } CustomData; + +static void got_location (GstObject *gstobject, GstObject *prop_object, GParamSpec *prop, gpointer data) { + gchar *location; + g_object_get (G_OBJECT (prop_object), "temp-location", &location, NULL); + g_print ("Temporary file: %s\n", location); + /* Uncomment this line to keep the temporary file after the program exits */ + /* g_object_set (G_OBJECT (prop_object), "temp-remove", FALSE, NULL); */ +} static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data) { @@ -120,7 +128,6 @@ int main(int argc, char *argv[]) { /* 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 */ @@ -143,7 +150,8 @@ int main(int argc, char *argv[]) { data.pipeline = pipeline; gst_bus_add_signal_watch (bus); - g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data); + g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data); + g_signal_connect (pipeline, "deep-notify::temp-location", G_CALLBACK (got_location), NULL); /* Register a function that GLib will call every second */ g_timeout_add_seconds (1, (GSourceFunc)refresh_ui, &data); From e7a0bcbb6e3e88f8887ccdff993a36e8a2bc2aef Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 18 Jun 2012 17:39:05 +0200 Subject: [PATCH 05/26] Add commented-out ring-buffer size limitation (for pedagogic purposes) --- gst-sdk/tutorials/playback-tutorial-3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-sdk/tutorials/playback-tutorial-3.c b/gst-sdk/tutorials/playback-tutorial-3.c index dfdb64c0d7..a59390a71e 100644 --- a/gst-sdk/tutorials/playback-tutorial-3.c +++ b/gst-sdk/tutorials/playback-tutorial-3.c @@ -135,6 +135,9 @@ int main(int argc, char *argv[]) { flags |= GST_PLAY_FLAG_DOWNLOAD; g_object_set (pipeline, "flags", flags, NULL); + /* Uncomment this line to limit the amount of downloaded data */ + /* g_object_set (pipeline, "ring-buffer-max-size", (guint64)4000000, NULL); */ + /* Start playing */ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { From 490eb9b40ef5659f18e36d11e5d43c58840cdf43 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 19 Jun 2012 12:31:06 +0200 Subject: [PATCH 06/26] Carriage returns --- gst-sdk/tutorials/playback-tutorial-3.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-3.c b/gst-sdk/tutorials/playback-tutorial-3.c index a59390a71e..e0bfd50e85 100644 --- a/gst-sdk/tutorials/playback-tutorial-3.c +++ b/gst-sdk/tutorials/playback-tutorial-3.c @@ -14,14 +14,14 @@ typedef struct _CustomData { GMainLoop *loop; gint buffering_level; } CustomData; - -static void got_location (GstObject *gstobject, GstObject *prop_object, GParamSpec *prop, gpointer data) { - gchar *location; - g_object_get (G_OBJECT (prop_object), "temp-location", &location, NULL); - g_print ("Temporary file: %s\n", location); - /* Uncomment this line to keep the temporary file after the program exits */ - /* g_object_set (G_OBJECT (prop_object), "temp-remove", FALSE, NULL); */ -} + +static void got_location (GstObject *gstobject, GstObject *prop_object, GParamSpec *prop, gpointer data) { + gchar *location; + g_object_get (G_OBJECT (prop_object), "temp-location", &location, NULL); + g_print ("Temporary file: %s\n", location); + /* Uncomment this line to keep the temporary file after the program exits */ + /* g_object_set (G_OBJECT (prop_object), "temp-remove", FALSE, NULL); */ +} static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data) { @@ -153,7 +153,7 @@ int main(int argc, char *argv[]) { data.pipeline = pipeline; gst_bus_add_signal_watch (bus); - g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data); + g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data); g_signal_connect (pipeline, "deep-notify::temp-location", G_CALLBACK (got_location), NULL); /* Register a function that GLib will call every second */ From 9b52a33ccfde4ea7fb569bc4fd156cf59ac48d87 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 19 Jun 2012 12:51:27 +0200 Subject: [PATCH 07/26] Whitespace --- gst-sdk/tutorials/playback-tutorial-3.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-3.c b/gst-sdk/tutorials/playback-tutorial-3.c index e0bfd50e85..a5829d6eeb 100644 --- a/gst-sdk/tutorials/playback-tutorial-3.c +++ b/gst-sdk/tutorials/playback-tutorial-3.c @@ -1,8 +1,8 @@ #include #include - + #define GRAPH_LENGTH 80 - + /* playbin2 flags */ typedef enum { GST_PLAY_FLAG_DOWNLOAD = (1 << 7) /* Enable progressive download (on selected formats) */ @@ -70,7 +70,7 @@ static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data) { 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) { @@ -78,10 +78,10 @@ static gboolean refresh_ui (CustomData *data) { 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; @@ -106,9 +106,9 @@ static gboolean refresh_ui (CustomData *data) { } g_print ("\r"); } - + return TRUE; - + } int main(int argc, char *argv[]) { From 082beeeb6a092669828dd896d1e3482affad762a Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 19 Jun 2012 13:01:05 +0200 Subject: [PATCH 08/26] Corrected tutorial number (should be 4, not 3) --- .../tutorials/{playback-tutorial-3.c => playback-tutorial-4.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename gst-sdk/tutorials/{playback-tutorial-3.c => playback-tutorial-4.c} (100%) diff --git a/gst-sdk/tutorials/playback-tutorial-3.c b/gst-sdk/tutorials/playback-tutorial-4.c similarity index 100% rename from gst-sdk/tutorials/playback-tutorial-3.c rename to gst-sdk/tutorials/playback-tutorial-4.c From 6a3594ea4ae5915751e1c6e57968302a0257d5c2 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 19 Jun 2012 13:07:20 +0200 Subject: [PATCH 09/26] Fix tutorial number in VS files --- .../playback-tutorial-4.vcxproj} | 2 +- .../playback-tutorial-4.vcxproj.filters} | 2 +- gst-sdk/tutorials/vs2010/tutorials.sln | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename gst-sdk/tutorials/vs2010/{playback-tutorial-3/playback-tutorial-3.vcxproj => playback-tutorial-4/playback-tutorial-4.vcxproj} (96%) rename gst-sdk/tutorials/vs2010/{playback-tutorial-3/playback-tutorial-3.vcxproj.filters => playback-tutorial-4/playback-tutorial-4.vcxproj.filters} (69%) diff --git a/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj b/gst-sdk/tutorials/vs2010/playback-tutorial-4/playback-tutorial-4.vcxproj similarity index 96% rename from gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj rename to gst-sdk/tutorials/vs2010/playback-tutorial-4/playback-tutorial-4.vcxproj index 34c5ea5ce3..2da5fbcbcb 100644 --- a/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-4/playback-tutorial-4.vcxproj @@ -19,7 +19,7 @@ - + Win32Proj diff --git a/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj.filters b/gst-sdk/tutorials/vs2010/playback-tutorial-4/playback-tutorial-4.vcxproj.filters similarity index 69% rename from gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj.filters rename to gst-sdk/tutorials/vs2010/playback-tutorial-4/playback-tutorial-4.vcxproj.filters index 97cf2797d4..9e1c365ec4 100644 --- a/gst-sdk/tutorials/vs2010/playback-tutorial-3/playback-tutorial-3.vcxproj.filters +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-4/playback-tutorial-4.vcxproj.filters @@ -1,6 +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 f8227e920d..39690ca60d 100644 --- a/gst-sdk/tutorials/vs2010/tutorials.sln +++ b/gst-sdk/tutorials/vs2010/tutorials.sln @@ -25,7 +25,7 @@ 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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-4", "playback-tutorial-4\playback-tutorial-4.vcxproj", "{0342A79A-3522-416B-A4F8-58F5664B8415}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 80d6b6e476b231ade274a84f0dec2c3c3f464de6 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 19 Jun 2012 14:01:48 +0200 Subject: [PATCH 10/26] Whitespacey --- gst-sdk/tutorials/basic-tutorial-8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-sdk/tutorials/basic-tutorial-8.c b/gst-sdk/tutorials/basic-tutorial-8.c index d74aad80d3..0e94840714 100644 --- a/gst-sdk/tutorials/basic-tutorial-8.c +++ b/gst-sdk/tutorials/basic-tutorial-8.c @@ -21,7 +21,7 @@ typedef struct _CustomData { /* This method is called by the idle GSource in the mainloop, to feed CHUNK_SIZE bytes into appsrc. * The ide handler is added to the mainloop when appsrc requests us to start sending data (need-data signal) - * and is removed when appsrc has enough data (enough-data signal). + * and is removed when appsrc has enough data (enough-data signal). */ static gboolean push_data (CustomData *data) { GstBuffer *buffer; From 482bff1ce4f603930be401dbe470d86b6615972b Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 19 Jun 2012 17:59:37 +0200 Subject: [PATCH 11/26] Added playback tutorial 3 --- gst-sdk/tutorials/playback-tutorial-3.c | 153 ++++++++++++++++++ .../playback-tutorial-3.vcxproj | 95 +++++++++++ .../playback-tutorial-3.vcxproj.filters | 6 + gst-sdk/tutorials/vs2010/tutorials.sln | 10 ++ 4 files changed, 264 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 0000000000..f48bca3c25 --- /dev/null +++ b/gst-sdk/tutorials/playback-tutorial-3.c @@ -0,0 +1,153 @@ +#include +#include + +#define CHUNK_SIZE 1024 /* Amount of bytes we are sending in each buffer */ +#define SAMPLE_RATE 44100 /* Samples per second we are sending */ +#define AUDIO_CAPS "audio/x-raw-int,channels=1,rate=%d,signed=(boolean)true,width=16,depth=16,endianness=BYTE_ORDER" + +/* Structure to contain all our information, so we can pass it to callbacks */ +typedef struct _CustomData { + GstElement *pipeline; + GstElement *app_source; + + guint64 num_samples; /* Number of samples generated so far (for timestamp generation) */ + gfloat a, b, c, d; /* For waveform generation */ + + guint sourceid; /* To control the GSource */ + + GMainLoop *main_loop; /* GLib's Main Loop */ +} CustomData; + +/* This method is called by the idle GSource in the mainloop, to feed CHUNK_SIZE bytes into appsrc. + * The ide handler is added to the mainloop when appsrc requests us to start sending data (need-data signal) + * and is removed when appsrc has enough data (enough-data signal). + */ +static gboolean push_data (CustomData *data) { + GstBuffer *buffer; + GstFlowReturn ret; + int i; + gint16 *raw; + gint num_samples = CHUNK_SIZE / 2; /* Because each sample is 16 bits */ + gfloat freq; + + /* Create a new empty buffer */ + buffer = gst_buffer_new_and_alloc (CHUNK_SIZE); + + /* Set its timestamp and duration */ + GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale (data->num_samples, GST_SECOND, SAMPLE_RATE); + GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale (CHUNK_SIZE, GST_SECOND, SAMPLE_RATE); + + /* Generate some psychodelic waveforms */ + raw = (gint16 *)GST_BUFFER_DATA (buffer); + data->c += data->d; + data->d -= data->c / 1000; + freq = 1100 + 1000 * data->d; + for (i = 0; i < num_samples; i++) { + data->a += data->b; + data->b -= data->a / freq; + raw[i] = (gint16)(500 * data->a); + } + data->num_samples += num_samples; + + /* Push the buffer into the appsrc */ + g_signal_emit_by_name (data->app_source, "push-buffer", buffer, &ret); + + /* Free the buffer now that we are done with it */ + gst_buffer_unref (buffer); + + if (ret != GST_FLOW_OK) { + /* We got some error, stop sending data */ + return FALSE; + } + + return TRUE; +} + +/* This signal callback triggers when appsrc needs data. Here, we add an idle handler + * to the mainloop to start pushing data into the appsrc */ +static void start_feed (GstElement *source, guint size, CustomData *data) { + if (data->sourceid == 0) { + g_print ("Start feeding\n"); + data->sourceid = g_idle_add ((GSourceFunc) push_data, data); + } +} + +/* This callback triggers when appsrc has enough data and we can stop sending. + * We remove the idle handler from the mainloop */ +static void stop_feed (GstElement *source, CustomData *data) { + if (data->sourceid != 0) { + g_print ("Stop feeding\n"); + g_source_remove (data->sourceid); + data->sourceid = 0; + } +} + +/* This function is called when an error message is posted on the bus */ +static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) { + GError *err; + gchar *debug_info; + + /* Print error details on the screen */ + gst_message_parse_error (msg, &err, &debug_info); + g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); + g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); + g_clear_error (&err); + g_free (debug_info); + + g_main_loop_quit (data->main_loop); +} + +/* This function is called when playbin2 has created the appsrc element, so we have + * a chance to configure it. */ +static void source_setup (GstElement *pipeline, GstElement *source, CustomData *data) { + gchar *audio_caps_text; + GstCaps *audio_caps; + + g_print ("Source has been created. Configuring.\n"); + data->app_source = source; + + /* Configure appsrc */ + audio_caps_text = g_strdup_printf (AUDIO_CAPS, SAMPLE_RATE); + audio_caps = gst_caps_from_string (audio_caps_text); + g_object_set (source, "caps", audio_caps, NULL); + g_signal_connect (source, "need-data", G_CALLBACK (start_feed), data); + g_signal_connect (source, "enough-data", G_CALLBACK (stop_feed), data); + gst_caps_unref (audio_caps); + g_free (audio_caps_text); +} + +int main(int argc, char *argv[]) { + CustomData data; + GstBus *bus; + guint flags; + + /* Initialize cumstom data structure */ + memset (&data, 0, sizeof (data)); + data.b = 1; /* For waveform generation */ + data.d = 1; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Create the playbin2 element */ + data.pipeline = gst_parse_launch ("playbin2 uri=appsrc://", NULL); + g_signal_connect (data.pipeline, "source-setup", G_CALLBACK (source_setup), &data); + + /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */ + bus = gst_element_get_bus (data.pipeline); + gst_bus_add_signal_watch (bus); + g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, &data); + gst_object_unref (bus); + + /* Start playing the pipeline */ + gst_element_set_state (data.pipeline, GST_STATE_PLAYING); + + /* Create a GLib Main Loop and set it to run */ + data.main_loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (data.main_loop); + + /* Free resources */ + gst_element_set_state (data.pipeline, GST_STATE_NULL); + gst_object_unref (data.pipeline); + return 0; +} 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 0000000000..41f16d0021 --- /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 + {B84F4F87-E804-456C-874E-AC76E0116268} + 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 0000000000..97cf2797d4 --- /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 39690ca60d..224fb254f1 100644 --- a/gst-sdk/tutorials/vs2010/tutorials.sln +++ b/gst-sdk/tutorials/vs2010/tutorials.sln @@ -27,6 +27,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic-tutorial-12", "basic- EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-4", "playback-tutorial-4\playback-tutorial-4.vcxproj", "{0342A79A-3522-416B-A4F8-58F5664B8415}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-3", "playback-tutorial-3\playback-tutorial-3.vcxproj", "{B84F4F87-E804-456C-874E-AC76E0116268}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -139,6 +141,14 @@ Global {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 + {B84F4F87-E804-456C-874E-AC76E0116268}.Debug|Win32.ActiveCfg = Debug|Win32 + {B84F4F87-E804-456C-874E-AC76E0116268}.Debug|Win32.Build.0 = Debug|Win32 + {B84F4F87-E804-456C-874E-AC76E0116268}.Debug|x64.ActiveCfg = Debug|x64 + {B84F4F87-E804-456C-874E-AC76E0116268}.Debug|x64.Build.0 = Debug|x64 + {B84F4F87-E804-456C-874E-AC76E0116268}.Release|Win32.ActiveCfg = Release|Win32 + {B84F4F87-E804-456C-874E-AC76E0116268}.Release|Win32.Build.0 = Release|Win32 + {B84F4F87-E804-456C-874E-AC76E0116268}.Release|x64.ActiveCfg = Release|x64 + {B84F4F87-E804-456C-874E-AC76E0116268}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 69b6590d03cb6f83d0052190ccf53baa41ba5901 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 19 Jun 2012 17:55:21 +0200 Subject: [PATCH 12/26] Remove unused variable --- gst-sdk/tutorials/playback-tutorial-3.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-sdk/tutorials/playback-tutorial-3.c b/gst-sdk/tutorials/playback-tutorial-3.c index f48bca3c25..de6d40fdf5 100644 --- a/gst-sdk/tutorials/playback-tutorial-3.c +++ b/gst-sdk/tutorials/playback-tutorial-3.c @@ -119,7 +119,6 @@ static void source_setup (GstElement *pipeline, GstElement *source, CustomData * int main(int argc, char *argv[]) { CustomData data; GstBus *bus; - guint flags; /* Initialize cumstom data structure */ memset (&data, 0, sizeof (data)); From b2fb2d10ccfb240e82bd8f4147cf6844d2e251fa Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Thu, 21 Jun 2012 16:08:19 +0200 Subject: [PATCH 13/26] Add playback tutorial 5 --- gst-sdk/tutorials/playback-tutorial-5.c | 182 ++++++++++++++++++ .../playback-tutorial-5.vcxproj | 97 ++++++++++ .../playback-tutorial-5.vcxproj.filters | 6 + gst-sdk/tutorials/vs2010/tutorials.sln | 10 + 4 files changed, 295 insertions(+) create mode 100644 gst-sdk/tutorials/playback-tutorial-5.c create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-5/playback-tutorial-5.vcxproj create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-5/playback-tutorial-5.vcxproj.filters diff --git a/gst-sdk/tutorials/playback-tutorial-5.c b/gst-sdk/tutorials/playback-tutorial-5.c new file mode 100644 index 0000000000..ce04f81a1b --- /dev/null +++ b/gst-sdk/tutorials/playback-tutorial-5.c @@ -0,0 +1,182 @@ +#include +#include +#include + +typedef struct _CustomData { + GstElement *pipeline; + GMainLoop *loop; +} CustomData; + +/* playbin2 flags */ +typedef enum { + GST_PLAY_FLAG_DEINTERLACE = (1 << 9) +} GstPlayFlags; + +/* Process a color balance command */ +static void update_color_channel (const gchar *channel_name, gboolean increase, GstColorBalance *cb) { + gdouble step; + gint value; + GstColorBalanceChannel *channel = NULL; + const GList *channels, *l; + + /* Retrieve the list of channels and locate the requested one */ + channels = gst_color_balance_list_channels (cb); + for (l = channels; l != NULL; l = l->next) { + GstColorBalanceChannel *tmp = (GstColorBalanceChannel *)l->data; + + if (g_strrstr (tmp->label, channel_name)) { + channel = tmp; + break; + } + } + if (!channel) + return; + + /* Change the channel's value */ + step = 0.1 * (channel->max_value - channel->min_value); + value = gst_color_balance_get_value (cb, channel); + if (increase) { + value += step; + if (value > channel->max_value) + value = channel->max_value; + } else { + value -= step; + if (value < channel->min_value) + value = channel->min_value; + } + gst_color_balance_set_value (cb, channel, value); +} + +/* Toggle the deinterlacing flag */ +static void toggle_deinterlace (GstElement *pipeline) { + gint flags; + gint64 current_position = GST_CLOCK_TIME_NONE; + GstFormat format = GST_FORMAT_TIME; + + /* Find current position, since it will be lost when we stop */ + gst_element_query_position (pipeline, &format, ¤t_position); + /* Stop */ + gst_element_set_state (pipeline, GST_STATE_READY); + /* Toggle deinterlacing flag (it will be ignored while PLAYING) */ + g_object_get (pipeline, "flags", &flags, NULL); + flags ^= GST_PLAY_FLAG_DEINTERLACE; + g_object_set (pipeline, "flags", flags, NULL); + /* Resume */ + gst_element_set_state (pipeline, GST_STATE_PLAYING); + /* Wait until the state change takes effect */ + gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + /* Set current position, if we were able to recover it previously */ + if (GST_CLOCK_TIME_IS_VALID (current_position)) { + gst_element_seek_simple (pipeline, format, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, current_position); + } +} + +/* Output the current values of all Color Balance channels and the Deinterlace flag */ +static void print_current_values (GstElement *pipeline) { + gint flags; + const GList *channels, *l; + + /* Output Color Balance values */ + channels = gst_color_balance_list_channels (GST_COLOR_BALANCE (pipeline)); + for (l = channels; l != NULL; l = l->next) { + GstColorBalanceChannel *channel = (GstColorBalanceChannel *)l->data; + gint value = gst_color_balance_get_value (GST_COLOR_BALANCE (pipeline), channel); + g_print ("%s: %3d%% ", channel->label, + 100 * (value - channel->min_value) / (channel->max_value - channel->min_value)); + } + + /* Output Deinterlace flag value */ + g_object_get (pipeline, "flags", &flags, NULL); + g_print ("Deinterlacing: %s\n", flags & GST_PLAY_FLAG_DEINTERLACE ? "ON" : "OFF"); +} + +/* Process keyboard input */ +static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) { + gchar *str = NULL; + + if (!g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { + return TRUE; + } + + switch (g_ascii_tolower (str[0])) { + case 'c': + update_color_channel ("CONTRAST", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 'b': + update_color_channel ("BRIGHTNESS", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 'h': + update_color_channel ("HUE", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 's': + update_color_channel ("SATURATION", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 'd': + toggle_deinterlace (data->pipeline); + break; + case 'q': + g_main_loop_quit (data->loop); + break; + default: + break; + } + + g_free (str); + + print_current_values (data->pipeline); + + return TRUE; +} + +int main(int argc, char *argv[]) { + CustomData data; + GstStateChangeReturn ret; + GIOChannel *io_stdin; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Initialize our data structure */ + memset (&data, 0, sizeof (data)); + + /* Print usage map */ + g_print ( + "USAGE: Choose one of the following options, then press enter:\n" + " 'C' to increase contrast, 'c' to decrease contrast\n" + " 'B' to increase brightness, 'b' to decrease brightness\n" + " 'H' to increase hue, 'h' to decrease hue\n" + " 'S' to increase saturation, 's' to decrease saturation\n" + " 'D' to toggle deinterlacing ON and OFF\n" + " 'Q' to quit\n"); + + /* Build the pipeline */ + data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480i.avi", NULL); + + /* Add a keyboard watch so we get notified of keystrokes */ +#ifdef _WIN32 + io_stdin = g_io_channel_win32_new_fd (fileno (stdin)); +#else + io_stdin = g_io_channel_unix_new (fileno (stdin)); +#endif + g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data); + + /* Start playing */ + ret = gst_element_set_state (data.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 (data.pipeline); + return -1; + } + print_current_values (data.pipeline); + + /* Create a GLib Main Loop and set it to run */ + data.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (data.loop); + + /* Free resources */ + g_main_loop_unref (data.loop); + g_io_channel_unref (io_stdin); + gst_element_set_state (data.pipeline, GST_STATE_NULL); + gst_object_unref (data.pipeline); + return 0; +} diff --git a/gst-sdk/tutorials/vs2010/playback-tutorial-5/playback-tutorial-5.vcxproj b/gst-sdk/tutorials/vs2010/playback-tutorial-5/playback-tutorial-5.vcxproj new file mode 100644 index 0000000000..3bfe49f9ba --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-5/playback-tutorial-5.vcxproj @@ -0,0 +1,97 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + Win32Proj + {57F94395-E9A1-430E-AF28-165FD9BE0872} + 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-5/playback-tutorial-5.vcxproj.filters b/gst-sdk/tutorials/vs2010/playback-tutorial-5/playback-tutorial-5.vcxproj.filters new file mode 100644 index 0000000000..d11ad27c8d --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-5/playback-tutorial-5.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 224fb254f1..34d0e6ec0e 100644 --- a/gst-sdk/tutorials/vs2010/tutorials.sln +++ b/gst-sdk/tutorials/vs2010/tutorials.sln @@ -29,6 +29,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-4", "play EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-3", "playback-tutorial-3\playback-tutorial-3.vcxproj", "{B84F4F87-E804-456C-874E-AC76E0116268}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-5", "playback-tutorial-5\playback-tutorial-5.vcxproj", "{57F94395-E9A1-430E-AF28-165FD9BE0872}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -149,6 +151,14 @@ Global {B84F4F87-E804-456C-874E-AC76E0116268}.Release|Win32.Build.0 = Release|Win32 {B84F4F87-E804-456C-874E-AC76E0116268}.Release|x64.ActiveCfg = Release|x64 {B84F4F87-E804-456C-874E-AC76E0116268}.Release|x64.Build.0 = Release|x64 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Debug|Win32.ActiveCfg = Debug|Win32 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Debug|Win32.Build.0 = Debug|Win32 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Debug|x64.ActiveCfg = Debug|x64 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Debug|x64.Build.0 = Debug|x64 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Release|Win32.ActiveCfg = Release|Win32 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Release|Win32.Build.0 = Release|Win32 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Release|x64.ActiveCfg = Release|x64 + {57F94395-E9A1-430E-AF28-165FD9BE0872}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From e6e3719d25a75bd0b8fb164fbef8f747d2124709 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Fri, 22 Jun 2012 12:57:24 +0200 Subject: [PATCH 14/26] Fix Carriage Returns --- gst-sdk/tutorials/playback-tutorial-5.c | 353 ++++++++++++------------ 1 file changed, 178 insertions(+), 175 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-5.c b/gst-sdk/tutorials/playback-tutorial-5.c index ce04f81a1b..1fc58d41da 100644 --- a/gst-sdk/tutorials/playback-tutorial-5.c +++ b/gst-sdk/tutorials/playback-tutorial-5.c @@ -1,182 +1,185 @@ -#include -#include -#include - +#include +#include +#include + typedef struct _CustomData { GstElement *pipeline; GMainLoop *loop; -} CustomData; - +} CustomData; + /* playbin2 flags */ typedef enum { GST_PLAY_FLAG_DEINTERLACE = (1 << 9) -} GstPlayFlags; - -/* Process a color balance command */ -static void update_color_channel (const gchar *channel_name, gboolean increase, GstColorBalance *cb) { - gdouble step; - gint value; - GstColorBalanceChannel *channel = NULL; - const GList *channels, *l; - - /* Retrieve the list of channels and locate the requested one */ - channels = gst_color_balance_list_channels (cb); - for (l = channels; l != NULL; l = l->next) { - GstColorBalanceChannel *tmp = (GstColorBalanceChannel *)l->data; - - if (g_strrstr (tmp->label, channel_name)) { - channel = tmp; - break; - } - } - if (!channel) - return; - - /* Change the channel's value */ - step = 0.1 * (channel->max_value - channel->min_value); - value = gst_color_balance_get_value (cb, channel); - if (increase) { - value += step; - if (value > channel->max_value) - value = channel->max_value; - } else { - value -= step; - if (value < channel->min_value) - value = channel->min_value; - } - gst_color_balance_set_value (cb, channel, value); -} - -/* Toggle the deinterlacing flag */ -static void toggle_deinterlace (GstElement *pipeline) { - gint flags; - gint64 current_position = GST_CLOCK_TIME_NONE; - GstFormat format = GST_FORMAT_TIME; - - /* Find current position, since it will be lost when we stop */ - gst_element_query_position (pipeline, &format, ¤t_position); - /* Stop */ - gst_element_set_state (pipeline, GST_STATE_READY); - /* Toggle deinterlacing flag (it will be ignored while PLAYING) */ - g_object_get (pipeline, "flags", &flags, NULL); - flags ^= GST_PLAY_FLAG_DEINTERLACE; - g_object_set (pipeline, "flags", flags, NULL); - /* Resume */ - gst_element_set_state (pipeline, GST_STATE_PLAYING); - /* Wait until the state change takes effect */ - gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); - /* Set current position, if we were able to recover it previously */ - if (GST_CLOCK_TIME_IS_VALID (current_position)) { - gst_element_seek_simple (pipeline, format, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, current_position); - } -} - -/* Output the current values of all Color Balance channels and the Deinterlace flag */ -static void print_current_values (GstElement *pipeline) { - gint flags; - const GList *channels, *l; - - /* Output Color Balance values */ - channels = gst_color_balance_list_channels (GST_COLOR_BALANCE (pipeline)); - for (l = channels; l != NULL; l = l->next) { - GstColorBalanceChannel *channel = (GstColorBalanceChannel *)l->data; - gint value = gst_color_balance_get_value (GST_COLOR_BALANCE (pipeline), channel); - g_print ("%s: %3d%% ", channel->label, - 100 * (value - channel->min_value) / (channel->max_value - channel->min_value)); - } - - /* Output Deinterlace flag value */ - g_object_get (pipeline, "flags", &flags, NULL); - g_print ("Deinterlacing: %s\n", flags & GST_PLAY_FLAG_DEINTERLACE ? "ON" : "OFF"); -} - -/* Process keyboard input */ -static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) { - gchar *str = NULL; - - if (!g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { - return TRUE; - } - - switch (g_ascii_tolower (str[0])) { - case 'c': - update_color_channel ("CONTRAST", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); - break; - case 'b': - update_color_channel ("BRIGHTNESS", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); - break; - case 'h': - update_color_channel ("HUE", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); - break; - case 's': - update_color_channel ("SATURATION", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); - break; - case 'd': - toggle_deinterlace (data->pipeline); - break; - case 'q': - g_main_loop_quit (data->loop); - break; - default: - break; - } - - g_free (str); - - print_current_values (data->pipeline); - - return TRUE; -} - -int main(int argc, char *argv[]) { - CustomData data; - GstStateChangeReturn ret; - GIOChannel *io_stdin; - - /* Initialize GStreamer */ - gst_init (&argc, &argv); +} GstPlayFlags; - /* Initialize our data structure */ - memset (&data, 0, sizeof (data)); - - /* Print usage map */ - g_print ( - "USAGE: Choose one of the following options, then press enter:\n" - " 'C' to increase contrast, 'c' to decrease contrast\n" - " 'B' to increase brightness, 'b' to decrease brightness\n" - " 'H' to increase hue, 'h' to decrease hue\n" - " 'S' to increase saturation, 's' to decrease saturation\n" - " 'D' to toggle deinterlacing ON and OFF\n" - " 'Q' to quit\n"); - - /* Build the pipeline */ - data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480i.avi", NULL); - - /* Add a keyboard watch so we get notified of keystrokes */ -#ifdef _WIN32 - io_stdin = g_io_channel_win32_new_fd (fileno (stdin)); -#else - io_stdin = g_io_channel_unix_new (fileno (stdin)); -#endif - g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data); - - /* Start playing */ - ret = gst_element_set_state (data.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 (data.pipeline); - return -1; - } - print_current_values (data.pipeline); - - /* Create a GLib Main Loop and set it to run */ - data.loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (data.loop); - - /* Free resources */ - g_main_loop_unref (data.loop); - g_io_channel_unref (io_stdin); - gst_element_set_state (data.pipeline, GST_STATE_NULL); - gst_object_unref (data.pipeline); - return 0; -} +/* Process a color balance command */ +static void update_color_channel (const gchar *channel_name, gboolean increase, GstColorBalance *cb) { + gdouble step; + gint value; + GstColorBalanceChannel *channel = NULL; + const GList *channels, *l; + + /* Retrieve the list of channels and locate the requested one */ + channels = gst_color_balance_list_channels (cb); + for (l = channels; l != NULL; l = l->next) { + GstColorBalanceChannel *tmp = (GstColorBalanceChannel *)l->data; + + if (g_strrstr (tmp->label, channel_name)) { + channel = tmp; + break; + } + } + if (!channel) + return; + + /* Change the channel's value */ + step = 0.1 * (channel->max_value - channel->min_value); + value = gst_color_balance_get_value (cb, channel); + if (increase) { + value += step; + if (value > channel->max_value) + value = channel->max_value; + } else { + value -= step; + if (value < channel->min_value) + value = channel->min_value; + } + gst_color_balance_set_value (cb, channel, value); +} + +/* Toggle the deinterlacing flag */ +static void toggle_deinterlace (GstElement *pipeline) { + gint flags; + gint64 current_position = GST_CLOCK_TIME_NONE; + GstFormat format = GST_FORMAT_TIME; + + /* Find current position, since it will be lost when we stop */ + gst_element_query_position (pipeline, &format, ¤t_position); + /* Stop */ + GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "before.dot"); + gst_element_set_state (pipeline, GST_STATE_READY); + /* Toggle deinterlacing flag (it will be ignored while PLAYING) */ + g_object_get (pipeline, "flags", &flags, NULL); + flags ^= GST_PLAY_FLAG_DEINTERLACE; + g_object_set (pipeline, "flags", flags, NULL); + /* Resume */ + gst_element_set_state (pipeline, GST_STATE_PLAYING); + /* Wait until the state change takes effect */ + gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "after.dot"); + /* Set current position, if we were able to recover it previously */ + if (GST_CLOCK_TIME_IS_VALID (current_position)) { + gst_element_seek_simple (pipeline, format, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, current_position); + } +} + +/* Output the current values of all Color Balance channels and the Deinterlace flag */ +static void print_current_values (GstElement *pipeline) { + gint flags; + const GList *channels, *l; + + /* Output Color Balance values */ + channels = gst_color_balance_list_channels (GST_COLOR_BALANCE (pipeline)); + for (l = channels; l != NULL; l = l->next) { + GstColorBalanceChannel *channel = (GstColorBalanceChannel *)l->data; + gint value = gst_color_balance_get_value (GST_COLOR_BALANCE (pipeline), channel); + g_print ("%s: %3d%% ", channel->label, + 100 * (value - channel->min_value) / (channel->max_value - channel->min_value)); + } + + /* Output Deinterlace flag value */ + g_object_get (pipeline, "flags", &flags, NULL); + g_print ("Deinterlacing: %s\n", flags & GST_PLAY_FLAG_DEINTERLACE ? "ON" : "OFF"); +} + +/* Process keyboard input */ +static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) { + gchar *str = NULL; + + if (!g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { + return TRUE; + } + + switch (g_ascii_tolower (str[0])) { + case 'c': + update_color_channel ("CONTRAST", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 'b': + update_color_channel ("BRIGHTNESS", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 'h': + update_color_channel ("HUE", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 's': + update_color_channel ("SATURATION", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); + break; + case 'd': + toggle_deinterlace (data->pipeline); + break; + case 'q': + g_main_loop_quit (data->loop); + break; + default: + break; + } + + g_free (str); + + print_current_values (data->pipeline); + + return TRUE; +} + +int main(int argc, char *argv[]) { + CustomData data; + GstStateChangeReturn ret; + GIOChannel *io_stdin; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Initialize our data structure */ + memset (&data, 0, sizeof (data)); + + /* Print usage map */ + g_print ( + "USAGE: Choose one of the following options, then press enter:\n" + " 'C' to increase contrast, 'c' to decrease contrast\n" + " 'B' to increase brightness, 'b' to decrease brightness\n" + " 'H' to increase hue, 'h' to decrease hue\n" + " 'S' to increase saturation, 's' to decrease saturation\n" + " 'D' to toggle deinterlacing ON and OFF\n" + " 'Q' to quit\n"); + + /* Build the pipeline */ + data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480i.avi", NULL); + g_object_set (data.pipeline, "flags", (gint)0x0417, NULL); + + /* Add a keyboard watch so we get notified of keystrokes */ +#ifdef _WIN32 + io_stdin = g_io_channel_win32_new_fd (fileno (stdin)); +#else + io_stdin = g_io_channel_unix_new (fileno (stdin)); +#endif + g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data); + + /* Start playing */ + ret = gst_element_set_state (data.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 (data.pipeline); + return -1; + } + print_current_values (data.pipeline); + + /* Create a GLib Main Loop and set it to run */ + data.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (data.loop); + + /* Free resources */ + g_main_loop_unref (data.loop); + g_io_channel_unref (io_stdin); + gst_element_set_state (data.pipeline, GST_STATE_NULL); + gst_object_unref (data.pipeline); + return 0; +} From ef0bd3ef083dcfddea7438579dca98240ddf375c Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Fri, 22 Jun 2012 13:55:37 +0200 Subject: [PATCH 15/26] Remove unneeded debug info. --- gst-sdk/tutorials/playback-tutorial-5.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-5.c b/gst-sdk/tutorials/playback-tutorial-5.c index 1fc58d41da..0e2682ac13 100644 --- a/gst-sdk/tutorials/playback-tutorial-5.c +++ b/gst-sdk/tutorials/playback-tutorial-5.c @@ -56,7 +56,6 @@ static void toggle_deinterlace (GstElement *pipeline) { /* Find current position, since it will be lost when we stop */ gst_element_query_position (pipeline, &format, ¤t_position); /* Stop */ - GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "before.dot"); gst_element_set_state (pipeline, GST_STATE_READY); /* Toggle deinterlacing flag (it will be ignored while PLAYING) */ g_object_get (pipeline, "flags", &flags, NULL); @@ -66,7 +65,6 @@ static void toggle_deinterlace (GstElement *pipeline) { gst_element_set_state (pipeline, GST_STATE_PLAYING); /* Wait until the state change takes effect */ gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); - GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "after.dot"); /* Set current position, if we were able to recover it previously */ if (GST_CLOCK_TIME_IS_VALID (current_position)) { gst_element_seek_simple (pipeline, format, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, current_position); From d9b9e9bf11368ea4a41b0fa0929370b881456645 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 25 Jun 2012 10:25:17 +0200 Subject: [PATCH 16/26] Remove unnecessary playbin2 flags. --- gst-sdk/tutorials/playback-tutorial-5.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gst-sdk/tutorials/playback-tutorial-5.c b/gst-sdk/tutorials/playback-tutorial-5.c index 0e2682ac13..11ddd6ba96 100644 --- a/gst-sdk/tutorials/playback-tutorial-5.c +++ b/gst-sdk/tutorials/playback-tutorial-5.c @@ -151,7 +151,6 @@ int main(int argc, char *argv[]) { /* Build the pipeline */ data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480i.avi", NULL); - g_object_set (data.pipeline, "flags", (gint)0x0417, NULL); /* Add a keyboard watch so we get notified of keystrokes */ #ifdef _WIN32 From 17d3c4557d18105eaea07b4af973619bca28499b Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 25 Jun 2012 11:07:24 +0200 Subject: [PATCH 17/26] Clarify comparison. --- gst-sdk/tutorials/playback-tutorial-5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-sdk/tutorials/playback-tutorial-5.c b/gst-sdk/tutorials/playback-tutorial-5.c index 11ddd6ba96..1bb6597d3f 100644 --- a/gst-sdk/tutorials/playback-tutorial-5.c +++ b/gst-sdk/tutorials/playback-tutorial-5.c @@ -94,7 +94,7 @@ static void print_current_values (GstElement *pipeline) { static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) { gchar *str = NULL; - if (!g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { + if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) { return TRUE; } From 87b9d58e953a6e9a1edb9b2f3274d1976f2bb75e Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 25 Jun 2012 15:53:28 +0200 Subject: [PATCH 18/26] Fix precision warning. --- gst-sdk/tutorials/playback-tutorial-5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-5.c b/gst-sdk/tutorials/playback-tutorial-5.c index 1bb6597d3f..d89c7f289c 100644 --- a/gst-sdk/tutorials/playback-tutorial-5.c +++ b/gst-sdk/tutorials/playback-tutorial-5.c @@ -36,11 +36,11 @@ static void update_color_channel (const gchar *channel_name, gboolean increase, step = 0.1 * (channel->max_value - channel->min_value); value = gst_color_balance_get_value (cb, channel); if (increase) { - value += step; + value = (gint)(value + step); if (value > channel->max_value) value = channel->max_value; } else { - value -= step; + value = (gint)(value - step); if (value < channel->min_value) value = channel->min_value; } From 989e16d36651c9ceea578ee27feb63c0d5b8cae7 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Mon, 25 Jun 2012 17:31:35 +0200 Subject: [PATCH 19/26] Remove deinterlacing stuff. This is a Color Balance tutorial from now on. --- gst-sdk/tutorials/playback-tutorial-5.c | 47 +++---------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-5.c b/gst-sdk/tutorials/playback-tutorial-5.c index d89c7f289c..a09f6ab089 100644 --- a/gst-sdk/tutorials/playback-tutorial-5.c +++ b/gst-sdk/tutorials/playback-tutorial-5.c @@ -7,11 +7,6 @@ typedef struct _CustomData { GMainLoop *loop; } CustomData; -/* playbin2 flags */ -typedef enum { - GST_PLAY_FLAG_DEINTERLACE = (1 << 9) -} GstPlayFlags; - /* Process a color balance command */ static void update_color_channel (const gchar *channel_name, gboolean increase, GstColorBalance *cb) { gdouble step; @@ -38,42 +33,17 @@ static void update_color_channel (const gchar *channel_name, gboolean increase, if (increase) { value = (gint)(value + step); if (value > channel->max_value) - value = channel->max_value; + value = channel->max_value; } else { value = (gint)(value - step); if (value < channel->min_value) - value = channel->min_value; + value = channel->min_value; } gst_color_balance_set_value (cb, channel, value); } -/* Toggle the deinterlacing flag */ -static void toggle_deinterlace (GstElement *pipeline) { - gint flags; - gint64 current_position = GST_CLOCK_TIME_NONE; - GstFormat format = GST_FORMAT_TIME; - - /* Find current position, since it will be lost when we stop */ - gst_element_query_position (pipeline, &format, ¤t_position); - /* Stop */ - gst_element_set_state (pipeline, GST_STATE_READY); - /* Toggle deinterlacing flag (it will be ignored while PLAYING) */ - g_object_get (pipeline, "flags", &flags, NULL); - flags ^= GST_PLAY_FLAG_DEINTERLACE; - g_object_set (pipeline, "flags", flags, NULL); - /* Resume */ - gst_element_set_state (pipeline, GST_STATE_PLAYING); - /* Wait until the state change takes effect */ - gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); - /* Set current position, if we were able to recover it previously */ - if (GST_CLOCK_TIME_IS_VALID (current_position)) { - gst_element_seek_simple (pipeline, format, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, current_position); - } -} - -/* Output the current values of all Color Balance channels and the Deinterlace flag */ +/* Output the current values of all Color Balance channels */ static void print_current_values (GstElement *pipeline) { - gint flags; const GList *channels, *l; /* Output Color Balance values */ @@ -84,10 +54,7 @@ static void print_current_values (GstElement *pipeline) { g_print ("%s: %3d%% ", channel->label, 100 * (value - channel->min_value) / (channel->max_value - channel->min_value)); } - - /* Output Deinterlace flag value */ - g_object_get (pipeline, "flags", &flags, NULL); - g_print ("Deinterlacing: %s\n", flags & GST_PLAY_FLAG_DEINTERLACE ? "ON" : "OFF"); + g_print ("\n"); } /* Process keyboard input */ @@ -111,9 +78,6 @@ static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomDa case 's': update_color_channel ("SATURATION", g_ascii_isupper (str[0]), GST_COLOR_BALANCE (data->pipeline)); break; - case 'd': - toggle_deinterlace (data->pipeline); - break; case 'q': g_main_loop_quit (data->loop); break; @@ -146,11 +110,10 @@ int main(int argc, char *argv[]) { " 'B' to increase brightness, 'b' to decrease brightness\n" " 'H' to increase hue, 'h' to decrease hue\n" " 'S' to increase saturation, 's' to decrease saturation\n" - " 'D' to toggle deinterlacing ON and OFF\n" " 'Q' to quit\n"); /* Build the pipeline */ - data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480i.avi", NULL); + data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL); /* Add a keyboard watch so we get notified of keystrokes */ #ifdef _WIN32 From 9e05d50a5f74adbb49face3553971f58318efaa8 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 26 Jun 2012 10:50:08 +0200 Subject: [PATCH 20/26] Added playback-tutorial-6. --- gst-sdk/tutorials/playback-tutorial-6.c | 84 ++++++++++++++++ .../playback-tutorial-6.vcxproj | 95 +++++++++++++++++++ .../playback-tutorial-6.vcxproj.filters | 6 ++ gst-sdk/tutorials/vs2010/tutorials.sln | 10 ++ 4 files changed, 195 insertions(+) create mode 100644 gst-sdk/tutorials/playback-tutorial-6.c create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-6/playback-tutorial-6.vcxproj create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-6/playback-tutorial-6.vcxproj.filters diff --git a/gst-sdk/tutorials/playback-tutorial-6.c b/gst-sdk/tutorials/playback-tutorial-6.c new file mode 100644 index 0000000000..59e1405335 --- /dev/null +++ b/gst-sdk/tutorials/playback-tutorial-6.c @@ -0,0 +1,84 @@ +#include + +/* playbin2 flags */ +typedef enum { + GST_PLAY_FLAG_VIS = (1 << 3) /* Enable rendering of visualisations when there is no video stream. */ +} GstPlayFlags; + +/* Return TRUE if this is a Visualization element */ +static gboolean filter_vis_features (GstPluginFeature *feature, gpointer data) { + GstElementFactory *factory; + + if (!GST_IS_ELEMENT_FACTORY (feature)) + return FALSE; + factory = GST_ELEMENT_FACTORY (feature); + if (!g_strrstr (gst_element_factory_get_klass (factory), "Visualization")) + return FALSE; + + return TRUE; +} + +int main(int argc, char *argv[]) { + GstElement *pipeline, *vis_plugin; + GstBus *bus; + GstMessage *msg; + GList *list, *walk; + GstElementFactory *factory = NULL; + guint flags; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Get a list of all visualization plugins */ + list = gst_registry_feature_filter (gst_registry_get_default (), filter_vis_features, FALSE, NULL); + + /* Print their names */ + g_print("Available visualization plugins:\n"); + for (walk = list; walk != NULL; walk = g_list_next (walk)) { + const gchar *name; + + factory = GST_ELEMENT_FACTORY (walk->data); + name = gst_element_factory_get_longname (factory); + + g_print(" %s\n", name); + } + + /* Don't use the factory if it's still empty */ + /* e.g. no visualization plugins found */ + if (!factory) { + g_print ("No visualization plugins found!\n"); + return -1; + } + + /* We now have factory pointing to the last Visualization plugin found */ + vis_plugin = gst_element_factory_create (factory, NULL); + if (!vis_plugin) + return -1; + + /* Build the pipeline */ + pipeline = gst_parse_launch ("playbin2 uri=http://radio.goha.ru:8000/grindfm.ogg", NULL); + + /* Set the visualization flag */ + g_object_get (pipeline, "flags", &flags, NULL); + flags |= GST_PLAY_FLAG_VIS; + g_object_set (pipeline, "flags", flags, NULL); + + /* set vis plugin for playbin2 */ + g_object_set (pipeline, "vis-plugin", vis_plugin, NULL); + + /* Start playing */ + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + /* Wait until error or EOS */ + bus = gst_element_get_bus (pipeline); + msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS); + + /* Free resources */ + if (msg != NULL) + gst_message_unref (msg); + gst_plugin_feature_list_free (list); + gst_object_unref (bus); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); + return 0; +} diff --git a/gst-sdk/tutorials/vs2010/playback-tutorial-6/playback-tutorial-6.vcxproj b/gst-sdk/tutorials/vs2010/playback-tutorial-6/playback-tutorial-6.vcxproj new file mode 100644 index 0000000000..e168038c59 --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-6/playback-tutorial-6.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + Win32Proj + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC} + 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-6/playback-tutorial-6.vcxproj.filters b/gst-sdk/tutorials/vs2010/playback-tutorial-6/playback-tutorial-6.vcxproj.filters new file mode 100644 index 0000000000..44ffbcdab4 --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-6/playback-tutorial-6.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 34d0e6ec0e..cb04202399 100644 --- a/gst-sdk/tutorials/vs2010/tutorials.sln +++ b/gst-sdk/tutorials/vs2010/tutorials.sln @@ -31,6 +31,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-3", "play EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-5", "playback-tutorial-5\playback-tutorial-5.vcxproj", "{57F94395-E9A1-430E-AF28-165FD9BE0872}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-6", "playback-tutorial-6\playback-tutorial-6.vcxproj", "{D6293AFD-41DA-44B6-AE57-F1EEE74338AC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -159,6 +161,14 @@ Global {57F94395-E9A1-430E-AF28-165FD9BE0872}.Release|Win32.Build.0 = Release|Win32 {57F94395-E9A1-430E-AF28-165FD9BE0872}.Release|x64.ActiveCfg = Release|x64 {57F94395-E9A1-430E-AF28-165FD9BE0872}.Release|x64.Build.0 = Release|x64 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Debug|Win32.ActiveCfg = Debug|Win32 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Debug|Win32.Build.0 = Debug|Win32 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Debug|x64.ActiveCfg = Debug|x64 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Debug|x64.Build.0 = Debug|x64 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Release|Win32.ActiveCfg = Release|Win32 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Release|Win32.Build.0 = Release|Win32 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Release|x64.ActiveCfg = Release|x64 + {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From a4ca0d8c0c90643e5a5f8b0793e11763b8d0148a Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 26 Jun 2012 13:25:16 +0200 Subject: [PATCH 21/26] Prefer GOOM over other visuals. Radio station that does not use chained-ogg files. --- gst-sdk/tutorials/playback-tutorial-6.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-6.c b/gst-sdk/tutorials/playback-tutorial-6.c index 59e1405335..31a3a42862 100644 --- a/gst-sdk/tutorials/playback-tutorial-6.c +++ b/gst-sdk/tutorials/playback-tutorial-6.c @@ -2,7 +2,7 @@ /* playbin2 flags */ typedef enum { - GST_PLAY_FLAG_VIS = (1 << 3) /* Enable rendering of visualisations when there is no video stream. */ + GST_PLAY_FLAG_VIS = (1 << 3) /* Enable rendering of visualizations when there is no video stream. */ } GstPlayFlags; /* Return TRUE if this is a Visualization element */ @@ -23,7 +23,7 @@ int main(int argc, char *argv[]) { GstBus *bus; GstMessage *msg; GList *list, *walk; - GstElementFactory *factory = NULL; + GstElementFactory *selected_factory = NULL; guint flags; /* Initialize GStreamer */ @@ -36,27 +36,32 @@ int main(int argc, char *argv[]) { g_print("Available visualization plugins:\n"); for (walk = list; walk != NULL; walk = g_list_next (walk)) { const gchar *name; + GstElementFactory *factory; factory = GST_ELEMENT_FACTORY (walk->data); name = gst_element_factory_get_longname (factory); - g_print(" %s\n", name); + + if (selected_factory == NULL || g_str_has_prefix (name, "GOOM")) { + selected_factory = factory; + } } /* Don't use the factory if it's still empty */ /* e.g. no visualization plugins found */ - if (!factory) { + if (!selected_factory) { g_print ("No visualization plugins found!\n"); return -1; } - /* We now have factory pointing to the last Visualization plugin found */ - vis_plugin = gst_element_factory_create (factory, NULL); + /* We have now selected a factory for the visualization element */ + g_print ("Selected '%s'\n", gst_element_factory_get_longname (selected_factory)); + vis_plugin = gst_element_factory_create (selected_factory, NULL); if (!vis_plugin) return -1; /* Build the pipeline */ - pipeline = gst_parse_launch ("playbin2 uri=http://radio.goha.ru:8000/grindfm.ogg", NULL); + pipeline = gst_parse_launch ("playbin2 uri=http://radio.hbr1.com:19800/ambient.ogg", NULL); /* Set the visualization flag */ g_object_get (pipeline, "flags", &flags, NULL); From bdc179a654023eae3cc7f2aac6bd4dbdd9e0de48 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 26 Jun 2012 18:19:10 +0200 Subject: [PATCH 22/26] Whitespace --- gst-sdk/tutorials/basic-tutorial-3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-sdk/tutorials/basic-tutorial-3.c b/gst-sdk/tutorials/basic-tutorial-3.c index 204b930a83..c4ac241f92 100644 --- a/gst-sdk/tutorials/basic-tutorial-3.c +++ b/gst-sdk/tutorials/basic-tutorial-3.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { /* Create the empty pipeline */ data.pipeline = gst_pipeline_new ("test-pipeline"); - + if (!data.pipeline || !data.source || !data.convert || !data.sink) { g_printerr ("Not all elements could be created.\n"); return -1; From 5b0195b360a84a39f321b338d8089acfd5cd6763 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 26 Jun 2012 18:21:52 +0200 Subject: [PATCH 23/26] Initial version. --- gst-sdk/tutorials/playback-tutorial-7.c | 54 +++++++++++ .../playback-tutorial-7.vcxproj | 95 +++++++++++++++++++ .../playback-tutorial-7.vcxproj.filters | 6 ++ gst-sdk/tutorials/vs2010/tutorials.sln | 10 ++ 4 files changed, 165 insertions(+) create mode 100644 gst-sdk/tutorials/playback-tutorial-7.c create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-7/playback-tutorial-7.vcxproj create mode 100644 gst-sdk/tutorials/vs2010/playback-tutorial-7/playback-tutorial-7.vcxproj.filters diff --git a/gst-sdk/tutorials/playback-tutorial-7.c b/gst-sdk/tutorials/playback-tutorial-7.c new file mode 100644 index 0000000000..da0570b003 --- /dev/null +++ b/gst-sdk/tutorials/playback-tutorial-7.c @@ -0,0 +1,54 @@ +#include + +int main(int argc, char *argv[]) { + GstElement *pipeline, *bin, *equalizer, *sink; + GstPad *pad, *ghost_pad; + GstBus *bus; + GstMessage *msg; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Build the pipeline */ + pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL); + + /* Create the elements inside the sink bin */ + equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer"); + sink = gst_element_factory_make ("autoaudiosink", "audio_sink"); + if (!equalizer || !sink) { + g_printerr ("Not all elements could be created.\n"); + return -1; + } + + /* Create the sink bin, add the elements and link them */ + bin = gst_bin_new ("audio_sink_bin"); + gst_bin_add_many (GST_BIN (bin), equalizer, sink, NULL); + gst_element_link (equalizer, sink); + pad = gst_element_get_static_pad (equalizer, "sink"); + ghost_pad = gst_ghost_pad_new ("sink", pad); + gst_pad_set_active (ghost_pad, TRUE); + gst_element_add_pad (bin, ghost_pad); + gst_object_unref (pad); + + /* Configure the equalizer */ + g_object_set (G_OBJECT (equalizer), "band1", (gdouble)-24.0, NULL); + g_object_set (G_OBJECT (equalizer), "band2", (gdouble)-24.0, NULL); + + /* Set playbin2's audio sink to be our sink bin */ + g_object_set (GST_OBJECT (pipeline), "audio-sink", bin, NULL); + + /* Start playing */ + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + /* Wait until error or EOS */ + bus = gst_element_get_bus (pipeline); + msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS); + + /* Free resources */ + if (msg != NULL) + gst_message_unref (msg); + gst_object_unref (bus); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); + return 0; +} \ No newline at end of file diff --git a/gst-sdk/tutorials/vs2010/playback-tutorial-7/playback-tutorial-7.vcxproj b/gst-sdk/tutorials/vs2010/playback-tutorial-7/playback-tutorial-7.vcxproj new file mode 100644 index 0000000000..b36543375a --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-7/playback-tutorial-7.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + Win32Proj + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A} + 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-7/playback-tutorial-7.vcxproj.filters b/gst-sdk/tutorials/vs2010/playback-tutorial-7/playback-tutorial-7.vcxproj.filters new file mode 100644 index 0000000000..46528cc431 --- /dev/null +++ b/gst-sdk/tutorials/vs2010/playback-tutorial-7/playback-tutorial-7.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 cb04202399..249a539e89 100644 --- a/gst-sdk/tutorials/vs2010/tutorials.sln +++ b/gst-sdk/tutorials/vs2010/tutorials.sln @@ -33,6 +33,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-5", "play EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-6", "playback-tutorial-6\playback-tutorial-6.vcxproj", "{D6293AFD-41DA-44B6-AE57-F1EEE74338AC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-7", "playback-tutorial-7\playback-tutorial-7.vcxproj", "{9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -169,6 +171,14 @@ Global {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Release|Win32.Build.0 = Release|Win32 {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Release|x64.ActiveCfg = Release|x64 {D6293AFD-41DA-44B6-AE57-F1EEE74338AC}.Release|x64.Build.0 = Release|x64 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Debug|Win32.ActiveCfg = Debug|Win32 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Debug|Win32.Build.0 = Debug|Win32 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Debug|x64.ActiveCfg = Debug|x64 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Debug|x64.Build.0 = Debug|x64 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Release|Win32.ActiveCfg = Release|Win32 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Release|Win32.Build.0 = Release|Win32 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Release|x64.ActiveCfg = Release|x64 + {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 3b6437cbcf78311fe5b014c7a0a9e39d2908eb47 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Wed, 27 Jun 2012 11:05:27 +0200 Subject: [PATCH 24/26] Add an audioconvert, just in case... --- gst-sdk/tutorials/playback-tutorial-7.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst-sdk/tutorials/playback-tutorial-7.c b/gst-sdk/tutorials/playback-tutorial-7.c index da0570b003..2ccd06940e 100644 --- a/gst-sdk/tutorials/playback-tutorial-7.c +++ b/gst-sdk/tutorials/playback-tutorial-7.c @@ -1,7 +1,7 @@ #include int main(int argc, char *argv[]) { - GstElement *pipeline, *bin, *equalizer, *sink; + GstElement *pipeline, *bin, *equalizer, *convert, *sink; GstPad *pad, *ghost_pad; GstBus *bus; GstMessage *msg; @@ -14,16 +14,17 @@ int main(int argc, char *argv[]) { /* Create the elements inside the sink bin */ equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer"); + convert = gst_element_factory_make ("audioconvert", "convert"); sink = gst_element_factory_make ("autoaudiosink", "audio_sink"); - if (!equalizer || !sink) { + if (!equalizer || !convert || !sink) { g_printerr ("Not all elements could be created.\n"); return -1; } /* Create the sink bin, add the elements and link them */ bin = gst_bin_new ("audio_sink_bin"); - gst_bin_add_many (GST_BIN (bin), equalizer, sink, NULL); - gst_element_link (equalizer, sink); + gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL); + gst_element_link_many (equalizer, convert, sink, NULL); pad = gst_element_get_static_pad (equalizer, "sink"); ghost_pad = gst_ghost_pad_new ("sink", pad); gst_pad_set_active (ghost_pad, TRUE); From ecff617bf350517be03d2826a9c01e5660879aec Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 3 Jul 2012 17:42:00 +0200 Subject: [PATCH 25/26] Added basic tutorial 13. --- gst-sdk/tutorials/basic-tutorial-13.c | 112 ++++++++++++++++++ .../basic-tutorial-13.vcxproj | 95 +++++++++++++++ .../basic-tutorial-13.vcxproj.filters | 6 + gst-sdk/tutorials/vs2010/tutorials.sln | 10 ++ 4 files changed, 223 insertions(+) create mode 100644 gst-sdk/tutorials/basic-tutorial-13.c create mode 100644 gst-sdk/tutorials/vs2010/basic-tutorial-13/basic-tutorial-13.vcxproj create mode 100644 gst-sdk/tutorials/vs2010/basic-tutorial-13/basic-tutorial-13.vcxproj.filters diff --git a/gst-sdk/tutorials/basic-tutorial-13.c b/gst-sdk/tutorials/basic-tutorial-13.c new file mode 100644 index 0000000000..bd9846b69e --- /dev/null +++ b/gst-sdk/tutorials/basic-tutorial-13.c @@ -0,0 +1,112 @@ +#include +#include + +typedef struct _CustomData { + GstElement *pipeline; + GMainLoop *loop; + + gboolean playing; /* Playing or Paused */ + gdouble rate; /* Current playback rate */ + gboolean backward; /* Forward or backwards */ +} CustomData; + +/* Process keyboard input */ +static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) { + gchar *str = NULL; + + if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) { + return TRUE; + } + + switch (g_ascii_tolower (str[0])) { + case 'p': + data->playing = !data->playing; + gst_element_set_state (data->pipeline, data->playing ? GST_STATE_PLAYING : GST_STATE_PAUSED); + g_print ("Setting state to %s\n", data->playing ? "PLAYING" : "PAUSE"); + break; + case 's': + if (g_ascii_isupper (str[0])) { + data->rate *= 2.0; + } else { + data->rate /= 2.0; + } + gst_element_send_event (data->pipeline, + gst_event_new_step (GST_FORMAT_TIME, -1, data->rate, TRUE, FALSE)); + g_print ("Current rate: %g\n", data->rate); + break; + case 'd': + data->backward = !data->backward; + gst_element_send_event (data->pipeline, + gst_event_new_seek (data->backward ? -data->rate : data->rate, + GST_FORMAT_TIME, GST_SEEK_FLAG_NONE, GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0)); + g_print ("Going %s\n", data->backward ? "backwards" : "forward"); + break; + case 'n': + gst_element_send_event (data->pipeline, + gst_event_new_step (GST_FORMAT_BUFFERS, 1, data->rate, TRUE, FALSE)); + g_print ("Stepping one frame\n"); + break; + case 'q': + g_main_loop_quit (data->loop); + break; + default: + break; + } + + g_free (str); + + return TRUE; +} + +int main(int argc, char *argv[]) { + CustomData data; + GstStateChangeReturn ret; + GIOChannel *io_stdin; + + /* Initialize GStreamer */ + gst_init (&argc, &argv); + + /* Initialize our data structure */ + memset (&data, 0, sizeof (data)); + + /* Print usage map */ + g_print ( + "USAGE: Choose one of the following options, then press enter:\n" + " 'P' to toggle between PAUSE and PLAY\n" + " 'S' to increase playback speed, 's' to decrease playback speed\n" + " 'D' to toggle playback direction\n" + " 'N' to move to next frame (in the current direction, better in PAUSE)\n" + " 'Q' to quit\n"); + + /* Build the pipeline */ + data.pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL); + + /* Add a keyboard watch so we get notified of keystrokes */ +#ifdef _WIN32 + io_stdin = g_io_channel_win32_new_fd (fileno (stdin)); +#else + io_stdin = g_io_channel_unix_new (fileno (stdin)); +#endif + g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data); + + /* Start playing */ + ret = gst_element_set_state (data.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 (data.pipeline); + return -1; + } + data.playing = TRUE; + data.rate = 1.0; + + /* Create a GLib Main Loop and set it to run */ + data.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (data.loop); + + /* Free resources */ + g_main_loop_unref (data.loop); + g_io_channel_unref (io_stdin); + gst_element_set_state (data.pipeline, GST_STATE_NULL); + gst_object_unref (data.pipeline); + return 0; +} diff --git a/gst-sdk/tutorials/vs2010/basic-tutorial-13/basic-tutorial-13.vcxproj b/gst-sdk/tutorials/vs2010/basic-tutorial-13/basic-tutorial-13.vcxproj new file mode 100644 index 0000000000..f0ae7c64c7 --- /dev/null +++ b/gst-sdk/tutorials/vs2010/basic-tutorial-13/basic-tutorial-13.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + Win32Proj + {6D962544-E7A2-450B-998B-6D09B17ACCB3} + 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/basic-tutorial-13/basic-tutorial-13.vcxproj.filters b/gst-sdk/tutorials/vs2010/basic-tutorial-13/basic-tutorial-13.vcxproj.filters new file mode 100644 index 0000000000..910fa0532a --- /dev/null +++ b/gst-sdk/tutorials/vs2010/basic-tutorial-13/basic-tutorial-13.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 249a539e89..17529d26b1 100644 --- a/gst-sdk/tutorials/vs2010/tutorials.sln +++ b/gst-sdk/tutorials/vs2010/tutorials.sln @@ -35,6 +35,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-6", "play EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "playback-tutorial-7", "playback-tutorial-7\playback-tutorial-7.vcxproj", "{9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic-tutorial-13", "basic-tutorial-13\basic-tutorial-13.vcxproj", "{6D962544-E7A2-450B-998B-6D09B17ACCB3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -179,6 +181,14 @@ Global {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Release|Win32.Build.0 = Release|Win32 {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Release|x64.ActiveCfg = Release|x64 {9C06FA1E-E571-42EA-B4AA-B91F9DA77D5A}.Release|x64.Build.0 = Release|x64 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Debug|Win32.Build.0 = Debug|Win32 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Debug|x64.ActiveCfg = Debug|x64 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Debug|x64.Build.0 = Debug|x64 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Release|Win32.ActiveCfg = Release|Win32 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Release|Win32.Build.0 = Release|Win32 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Release|x64.ActiveCfg = Release|x64 + {6D962544-E7A2-450B-998B-6D09B17ACCB3}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 7fa1aede37ab70af58094397305b918aec90a049 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Tue, 3 Jul 2012 18:31:49 +0200 Subject: [PATCH 26/26] Fix rate changes by using seeks instead of steps. --- gst-sdk/tutorials/basic-tutorial-13.c | 49 +++++++++++++++++++++------ 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/gst-sdk/tutorials/basic-tutorial-13.c b/gst-sdk/tutorials/basic-tutorial-13.c index bd9846b69e..710562fbf9 100644 --- a/gst-sdk/tutorials/basic-tutorial-13.c +++ b/gst-sdk/tutorials/basic-tutorial-13.c @@ -3,13 +3,45 @@ typedef struct _CustomData { GstElement *pipeline; + GstElement *video_sink; GMainLoop *loop; gboolean playing; /* Playing or Paused */ - gdouble rate; /* Current playback rate */ - gboolean backward; /* Forward or backwards */ + gdouble rate; /* Current playback rate (can be negative) */ } CustomData; +/* Send seek event to change rate */ +static void send_seek_event (CustomData *data) { + gint64 position; + GstFormat format = GST_FORMAT_TIME; + GstEvent *seek_event; + + /* Obtain the current position, needed for the seek event */ + if (!gst_element_query_position (data->pipeline, &format, &position)) { + g_printerr ("Unable to retrieve current position.\n"); + return; + } + + /* Create the seek event */ + if (data->rate > 0) { + seek_event = gst_event_new_seek (data->rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, + GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE, 0); + } else { + seek_event = gst_event_new_seek (data->rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, + GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_SET, position); + } + + if (data->video_sink == NULL) { + /* If we have not done so, obtain the sink through which we will send the seek events */ + g_object_get (data->pipeline, "video_sink", &data->video_sink, NULL); + } + + /* Send the event */ + gst_element_send_event (data->video_sink, seek_event); + + g_print ("Current rate: %g\n", data->rate); +} + /* Process keyboard input */ static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) { gchar *str = NULL; @@ -30,16 +62,11 @@ static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomDa } else { data->rate /= 2.0; } - gst_element_send_event (data->pipeline, - gst_event_new_step (GST_FORMAT_TIME, -1, data->rate, TRUE, FALSE)); - g_print ("Current rate: %g\n", data->rate); + send_seek_event (data); break; case 'd': - data->backward = !data->backward; - gst_element_send_event (data->pipeline, - gst_event_new_seek (data->backward ? -data->rate : data->rate, - GST_FORMAT_TIME, GST_SEEK_FLAG_NONE, GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0)); - g_print ("Going %s\n", data->backward ? "backwards" : "forward"); + data->rate *= -1.0; + send_seek_event (data); break; case 'n': gst_element_send_event (data->pipeline, @@ -107,6 +134,8 @@ int main(int argc, char *argv[]) { g_main_loop_unref (data.loop); g_io_channel_unref (io_stdin); gst_element_set_state (data.pipeline, GST_STATE_NULL); + if (data.video_sink != NULL) + gst_object_unref (data.video_sink); gst_object_unref (data.pipeline); return 0; }