/tests/old/examples/seek/cdplayer.c

https://github.com/rikaunite/gst-opera_gst-plugins-base · C · 292 lines · 232 code · 56 blank · 4 comment · 20 complexity · f4127bf728e235a0c0592a3f22b82b28 MD5 · raw file

  1. #include <stdlib.h>
  2. #include <glib.h>
  3. #include <gtk/gtk.h>
  4. #include <gst/gst.h>
  5. #include <string.h>
  6. static GList *seekable_elements = NULL;
  7. static GstElement *pipeline;
  8. static GtkAdjustment *adjustment;
  9. static gboolean stats = FALSE;
  10. static guint64 duration;
  11. static guint update_id;
  12. #define UPDATE_INTERVAL 500
  13. static GstElement *
  14. make_cdaudio_pipeline (void)
  15. {
  16. GstElement *cdaudio;
  17. cdaudio = gst_element_factory_make ("cdaudio", "cdaudio");
  18. g_assert (cdaudio != NULL);
  19. seekable_elements = g_list_prepend (seekable_elements, cdaudio);
  20. return cdaudio;
  21. }
  22. static gchar *
  23. format_value (GtkScale * scale, gdouble value)
  24. {
  25. gint64 real;
  26. gint64 seconds;
  27. gint64 subseconds;
  28. real = value * duration / 100;
  29. seconds = (gint64) real / GST_SECOND;
  30. subseconds = (gint64) real / (GST_SECOND / 100);
  31. return g_strdup_printf ("%02" G_GINT64_FORMAT ":%02" G_GINT64_FORMAT ":%02"
  32. G_GINT64_FORMAT, seconds / 60, seconds % 60, subseconds % 100);
  33. }
  34. typedef struct
  35. {
  36. const gchar *name;
  37. const GstFormat format;
  38. }
  39. seek_format;
  40. static seek_format seek_formats[] = {
  41. {"tim", GST_FORMAT_TIME},
  42. {"byt", GST_FORMAT_BYTES},
  43. {"buf", GST_FORMAT_BUFFERS},
  44. {"def", GST_FORMAT_DEFAULT},
  45. {NULL, 0},
  46. };
  47. G_GNUC_UNUSED static void
  48. query_durations ()
  49. {
  50. GList *walk = seekable_elements;
  51. while (walk) {
  52. GstElement *element = GST_ELEMENT (walk->data);
  53. gint i = 0;
  54. g_print ("durations %8.8s: ", GST_ELEMENT_NAME (element));
  55. while (seek_formats[i].name) {
  56. gboolean res;
  57. gint64 value;
  58. GstFormat format;
  59. format = seek_formats[i].format;
  60. res = gst_element_query (element, GST_QUERY_TOTAL, &format, &value);
  61. if (res) {
  62. g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
  63. } else {
  64. g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
  65. }
  66. i++;
  67. }
  68. g_print (" %s\n", GST_ELEMENT_NAME (element));
  69. walk = g_list_next (walk);
  70. }
  71. }
  72. G_GNUC_UNUSED static void
  73. query_positions ()
  74. {
  75. GList *walk = seekable_elements;
  76. while (walk) {
  77. GstElement *element = GST_ELEMENT (walk->data);
  78. gint i = 0;
  79. g_print ("positions %8.8s: ", GST_ELEMENT_NAME (element));
  80. while (seek_formats[i].name) {
  81. gboolean res;
  82. gint64 value;
  83. GstFormat format;
  84. format = seek_formats[i].format;
  85. res = gst_element_query (element, GST_QUERY_POSITION, &format, &value);
  86. if (res) {
  87. g_print ("%s %13" G_GINT64_FORMAT " | ", seek_formats[i].name, value);
  88. } else {
  89. g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
  90. }
  91. i++;
  92. }
  93. g_print (" %s\n", GST_ELEMENT_NAME (element));
  94. walk = g_list_next (walk);
  95. }
  96. }
  97. static gboolean
  98. update_scale (gpointer data)
  99. {
  100. GstClock *clock;
  101. guint64 position = 0;
  102. GstFormat format = GST_FORMAT_TIME;
  103. duration = 0;
  104. clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline));
  105. if (seekable_elements) {
  106. GstElement *element = GST_ELEMENT (seekable_elements->data);
  107. gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
  108. gst_element_query (element, GST_QUERY_POSITION, &format, &position);
  109. }
  110. if (stats) {
  111. if (clock)
  112. g_print ("clock: %13" G_GUINT64_FORMAT " (%s)\n",
  113. position, gst_object_get_name (GST_OBJECT (clock)));
  114. query_durations ();
  115. query_positions ();
  116. }
  117. if (duration > 0) {
  118. gtk_adjustment_set_value (adjustment, position * 100.0 / duration);
  119. }
  120. return TRUE;
  121. }
  122. static gboolean
  123. start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
  124. {
  125. gst_element_set_state (pipeline, GST_STATE_PAUSED);
  126. g_timeout_remove (update_id);
  127. return FALSE;
  128. }
  129. static gboolean
  130. stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
  131. {
  132. gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
  133. gboolean res;
  134. GstEvent *s_event;
  135. GList *walk = seekable_elements;
  136. while (walk) {
  137. GstElement *seekable = GST_ELEMENT (walk->data);
  138. g_print ("seek to %" G_GINT64_FORMAT " on element %s\n", real,
  139. GST_ELEMENT_NAME (seekable));
  140. s_event =
  141. gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
  142. GST_SEEK_FLAG_FLUSH, real);
  143. res = gst_element_send_event (seekable, s_event);
  144. walk = g_list_next (walk);
  145. }
  146. gst_element_set_state (pipeline, GST_STATE_PLAYING);
  147. update_id =
  148. g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
  149. return FALSE;
  150. }
  151. static void
  152. play_cb (GtkButton * button, gpointer data)
  153. {
  154. GstState state;
  155. gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
  156. if (state != GST_STATE_PLAYING) {
  157. gst_element_set_state (pipeline, GST_STATE_PLAYING);
  158. update_id =
  159. g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
  160. }
  161. }
  162. static void
  163. pause_cb (GtkButton * button, gpointer data)
  164. {
  165. GstState state;
  166. gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
  167. if (state != GST_STATE_PAUSED) {
  168. gst_element_set_state (pipeline, GST_STATE_PAUSED);
  169. g_timeout_remove (update_id);
  170. }
  171. }
  172. static void
  173. stop_cb (GtkButton * button, gpointer data)
  174. {
  175. GstState state;
  176. gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
  177. if (state != GST_STATE_READY) {
  178. gst_element_set_state (pipeline, GST_STATE_READY);
  179. g_timeout_remove (update_id);
  180. }
  181. }
  182. int
  183. main (int argc, char **argv)
  184. {
  185. GtkWidget *window, *hbox, *vbox,
  186. *play_button, *pause_button, *stop_button, *hscale;
  187. struct poptOption options[] = {
  188. {"stats", 's', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &stats, 0,
  189. "Show element stats", NULL},
  190. POPT_TABLEEND
  191. };
  192. gst_init_with_popt_table (&argc, &argv, options);
  193. gtk_init (&argc, &argv);
  194. pipeline = make_cdaudio_pipeline ();
  195. g_signal_connect (pipeline, "deep_notify",
  196. G_CALLBACK (gst_object_default_deep_notify), NULL);
  197. /* initialize gui elements ... */
  198. window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  199. hbox = gtk_hbox_new (FALSE, 0);
  200. vbox = gtk_vbox_new (FALSE, 0);
  201. play_button = gtk_button_new_with_label ("play");
  202. pause_button = gtk_button_new_with_label ("pause");
  203. stop_button = gtk_button_new_with_label ("stop");
  204. adjustment =
  205. GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
  206. hscale = gtk_hscale_new (adjustment);
  207. gtk_scale_set_digits (GTK_SCALE (hscale), 2);
  208. gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
  209. g_signal_connect (GTK_OBJECT (hscale),
  210. "button_press_event", G_CALLBACK (start_seek), pipeline);
  211. g_signal_connect (GTK_OBJECT (hscale),
  212. "button_release_event", G_CALLBACK (stop_seek), pipeline);
  213. g_signal_connect (GTK_OBJECT (hscale),
  214. "format_value", G_CALLBACK (format_value), pipeline);
  215. /* do the packing stuff ... */
  216. gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
  217. gtk_container_add (GTK_CONTAINER (window), vbox);
  218. gtk_container_add (GTK_CONTAINER (vbox), hbox);
  219. gtk_box_pack_start (GTK_BOX (hbox), play_button, FALSE, FALSE, 2);
  220. gtk_box_pack_start (GTK_BOX (hbox), pause_button, FALSE, FALSE, 2);
  221. gtk_box_pack_start (GTK_BOX (hbox), stop_button, FALSE, FALSE, 2);
  222. gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
  223. /* connect things ... */
  224. g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
  225. pipeline);
  226. g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
  227. pipeline);
  228. g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
  229. pipeline);
  230. g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
  231. /* show the gui. */
  232. gtk_widget_show_all (window);
  233. gtk_main ();
  234. gst_element_set_state (pipeline, GST_STATE_NULL);
  235. return 0;
  236. }