Added little test apps for cdplayer and cdparanoia
Original commit message from CVS: Added little test apps for cdplayer and cdparanoia
This commit is contained in:
		
							parent
							
								
									4af324deb5
								
							
						
					
					
						commit
						6e78110edf
					
				| @ -1,4 +1,4 @@ | ||||
| examples = seek spider_seek | ||||
| examples = seek spider_seek cdplayer cdparanoia | ||||
| 
 | ||||
| noinst_PROGRAMS = $(examples) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										168
									
								
								examples/seeking/cdparanoia.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								examples/seeking/cdparanoia.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,168 @@ | ||||
| #include <stdlib.h> | ||||
| #include <gst/gst.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| static void | ||||
| get_track_info (GstElement *cdparanoia) | ||||
| { | ||||
|   GstFormat track_format; | ||||
|   gint64 total_tracks, total_time; | ||||
|   GstPad *pad; | ||||
|   const GstFormat *formats; | ||||
|   gint i; | ||||
|   gint64 time_count = 0; | ||||
|    | ||||
|   track_format = gst_format_get_by_nick ("track"); | ||||
|   g_assert (track_format != 0); | ||||
| 
 | ||||
|   pad = gst_element_get_pad (cdparanoia, "src"); | ||||
|   formats = gst_pad_get_formats (pad); | ||||
| 
 | ||||
|   /* we loop over all supported formats and report the total
 | ||||
|    * number of them */ | ||||
|   while (*formats) { | ||||
|     const GstFormatDefinition *definition; | ||||
|     gint64 total; | ||||
|     gboolean res; | ||||
|      | ||||
|     definition = gst_format_get_details (*formats); | ||||
| 
 | ||||
|     res = gst_pad_query (pad, GST_PAD_QUERY_TOTAL, | ||||
| 		         (GstFormat *)formats, &total); | ||||
|     if (res) { | ||||
|       if (*formats == GST_FORMAT_TIME) | ||||
|         g_print ("%s total: %lld:%lld\n", definition->nick, total/60, total%60); | ||||
|       else | ||||
|         g_print ("%s total: %lld\n", definition->nick, total); | ||||
| 
 | ||||
|       if (*formats == track_format) | ||||
| 	total_tracks = total; | ||||
|       else if (*formats == GST_FORMAT_TIME) | ||||
| 	total_time = total; | ||||
|     } | ||||
|     else | ||||
|       g_print ("failed to get %s total\n", definition->nick); | ||||
| 
 | ||||
|     formats++; | ||||
|   } | ||||
| 
 | ||||
|   /* then we loop over all the tracks to get more info.
 | ||||
|    * since pad_convert always works from 0, the time from track 1 needs | ||||
|    * to be substracted from track 2 */ | ||||
|   for (i = 0; i <= total_tracks; i++) { | ||||
|     gint64 time; | ||||
|     gboolean res; | ||||
| 
 | ||||
|     if (i < total_tracks) { | ||||
|       GstFormat format; | ||||
| 
 | ||||
|       format = GST_FORMAT_TIME; | ||||
|       res = gst_pad_convert (pad, track_format, i, | ||||
| 		             &format, &time); | ||||
|     } | ||||
|     else { | ||||
|       time = total_time; | ||||
|       res = TRUE; | ||||
|     } | ||||
| 
 | ||||
|     if (res) { | ||||
|       /* for the first track (i==0) we wait until we have the 
 | ||||
|        * time of the next track */ | ||||
|       if (i > 0) { | ||||
| 	gint64 length = time - time_count; | ||||
| 
 | ||||
|         g_print ("track %d: %lld:%02lld -> %lld:%02lld, length: %lld:%02lld\n", i-1,  | ||||
| 			time_count/60, time_count%60, | ||||
| 			time/60, time%60, | ||||
| 			length/60, length%60); | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       g_print ("could not get time for track %d\n", i); | ||||
|     } | ||||
| 
 | ||||
|     time_count = time; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main (int argc, char **argv) | ||||
| { | ||||
|   GstElement *pipeline; | ||||
|   GstElement *cdparanoia; | ||||
|   GstElement *osssink; | ||||
|   GstPad *pad; | ||||
|   GstFormat track_format; | ||||
|   GstEvent *event; | ||||
|   gint count; | ||||
|    | ||||
|   gst_init (&argc, &argv); | ||||
| 
 | ||||
|   pipeline = gst_pipeline_new ("pipeline"); | ||||
| 
 | ||||
|   cdparanoia = gst_element_factory_make ("cdparanoia", "cdparanoia"); | ||||
|   g_assert (cdparanoia); | ||||
|   g_object_set (G_OBJECT (cdparanoia), "paranoia_mode", 0, NULL); | ||||
| 
 | ||||
|   osssink = gst_element_factory_make ("osssink", "osssink"); | ||||
|   g_assert (osssink); | ||||
| 
 | ||||
|   gst_bin_add (GST_BIN (pipeline), cdparanoia); | ||||
|   gst_bin_add (GST_BIN (pipeline), osssink); | ||||
| 
 | ||||
|   gst_element_connect_pads (cdparanoia, "src", osssink, "sink"); | ||||
| 
 | ||||
|   g_signal_connect (G_OBJECT (pipeline), "deep_notify",  | ||||
| 		  G_CALLBACK (gst_element_default_deep_notify), NULL); | ||||
|    | ||||
|   gst_element_set_state (pipeline, GST_STATE_PAUSED); | ||||
| 
 | ||||
|   /* now we go into probe mode */ | ||||
|   get_track_info (cdparanoia); | ||||
| 
 | ||||
|   track_format = gst_format_get_by_nick ("track"); | ||||
|   g_assert (track_format != 0); | ||||
| 
 | ||||
|   pad = gst_element_get_pad (cdparanoia, "src"); | ||||
|   g_assert (pad); | ||||
| 
 | ||||
|   g_print ("playing from track 3\n"); | ||||
|   /* seek to track3 */ | ||||
|   event = gst_event_new_seek (track_format | | ||||
| 		              GST_SEEK_METHOD_SET | | ||||
| 		  	      GST_SEEK_FLAG_FLUSH, | ||||
| 			      3); | ||||
| 
 | ||||
|   gst_pad_send_event (pad, event); | ||||
|   gst_element_set_state (pipeline, GST_STATE_PLAYING); | ||||
| 
 | ||||
|   count = 0; | ||||
|   while (gst_bin_iterate (GST_BIN (pipeline))) { | ||||
|     if (count++ > 500) | ||||
|       break; | ||||
|   } | ||||
|   gst_element_set_state (pipeline, GST_STATE_PAUSED); | ||||
| 
 | ||||
|   g_print ("playing track 3 only\n"); | ||||
|   /* seek to track3 */ | ||||
|   event = gst_event_new_segment_seek (track_format | | ||||
| 		                      GST_SEEK_METHOD_SET | | ||||
| 		  	              GST_SEEK_FLAG_FLUSH, | ||||
| 			              3, 4); | ||||
|   gst_pad_send_event (pad, event); | ||||
|   gst_element_set_state (pipeline, GST_STATE_PLAYING); | ||||
| 
 | ||||
|   count = 0; | ||||
|   while (gst_bin_iterate (GST_BIN (pipeline))) { | ||||
|     if (count++ > 500) | ||||
|       break; | ||||
|   } | ||||
| 
 | ||||
|   /* shutdown everything again */ | ||||
|   gst_element_set_state (pipeline, GST_STATE_NULL); | ||||
| 
 | ||||
|   gst_buffer_print_stats(); | ||||
|   gst_event_print_stats(); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										310
									
								
								examples/seeking/cdplayer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								examples/seeking/cdplayer.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,310 @@ | ||||
| #include <stdlib.h> | ||||
| #include <glib.h> | ||||
| #include <gtk/gtk.h> | ||||
| #include <gst/gst.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| static GList *seekable_elements = NULL; | ||||
| 
 | ||||
| static GstElement *pipeline; | ||||
| static GtkAdjustment *adjustment; | ||||
| static gboolean stats = FALSE; | ||||
| static guint64 duration; | ||||
| 
 | ||||
| static guint update_id; | ||||
| 
 | ||||
| //#define SOURCE "gnomevfssrc"
 | ||||
| #define SOURCE "filesrc" | ||||
| 
 | ||||
| #define UPDATE_INTERVAL 500 | ||||
| 
 | ||||
| static GstElement* | ||||
| make_cdaudio_pipeline (gboolean thread)  | ||||
| { | ||||
|   GstElement *pipeline; | ||||
|   GstElement *cdaudio; | ||||
|    | ||||
|   if (thread) { | ||||
|     pipeline = gst_thread_new ("app"); | ||||
|   } | ||||
|   else { | ||||
|     pipeline = gst_pipeline_new ("app"); | ||||
|   } | ||||
|    | ||||
|   cdaudio = gst_element_factory_make ("cdaudio", "cdaudio"); | ||||
| 
 | ||||
|   gst_bin_add (GST_BIN (pipeline), cdaudio); | ||||
| 
 | ||||
|   seekable_elements = g_list_prepend (seekable_elements, cdaudio); | ||||
| 
 | ||||
|   return pipeline; | ||||
| } | ||||
| 
 | ||||
| static gchar* | ||||
| format_value (GtkScale *scale, | ||||
| 	      gdouble   value) | ||||
| { | ||||
|   gint64 real; | ||||
|   gint64 seconds; | ||||
|   gint64 subseconds; | ||||
| 
 | ||||
|   real = value * duration / 100; | ||||
|   seconds = (gint64) real / GST_SECOND; | ||||
|   subseconds = (gint64) real / (GST_SECOND / 100); | ||||
| 
 | ||||
|   return g_strdup_printf ("%02lld:%02lld:%02lld", | ||||
|                           seconds/60,  | ||||
| 			  seconds%60,  | ||||
| 			  subseconds%100); | ||||
| } | ||||
| 
 | ||||
| typedef struct | ||||
| { | ||||
|   const gchar *name; | ||||
|   const GstFormat format; | ||||
| } seek_format; | ||||
| 
 | ||||
| static seek_format seek_formats[] =  | ||||
| { | ||||
|   { "tim",  GST_FORMAT_TIME    }, | ||||
|   { "byt",  GST_FORMAT_BYTES   }, | ||||
|   { "unt",  GST_FORMAT_UNITS   }, | ||||
|   { "buf",  GST_FORMAT_BUFFERS }, | ||||
|   { "def",  GST_FORMAT_DEFAULT }, | ||||
|   { NULL, 0 },  | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| G_GNUC_UNUSED static void | ||||
| query_durations () | ||||
| { | ||||
|   GList *walk = seekable_elements; | ||||
| 
 | ||||
|   while (walk) { | ||||
|     GstElement *element = GST_ELEMENT (walk->data); | ||||
|     gint i = 0; | ||||
| 
 | ||||
|     g_print ("durations %8.8s: ", GST_ELEMENT_NAME (element)); | ||||
|     while (seek_formats[i].name) { | ||||
|       gboolean res; | ||||
|       gint64 value; | ||||
|       GstFormat format; | ||||
| 
 | ||||
|       format = seek_formats[i].format; | ||||
|       res = gst_element_query (element, GST_PAD_QUERY_TOTAL, &format, &value); | ||||
|       if (res) { | ||||
|         g_print ("%s %13lld | ", seek_formats[i].name, value); | ||||
|       } | ||||
|       else { | ||||
|         g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*"); | ||||
|       } | ||||
|       i++; | ||||
|     } | ||||
|     g_print (" %s\n", GST_ELEMENT_NAME (element)); | ||||
|     walk = g_list_next (walk); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| G_GNUC_UNUSED static void | ||||
| query_positions () | ||||
| { | ||||
|   GList *walk = seekable_elements; | ||||
| 
 | ||||
|   while (walk) { | ||||
|     GstElement *element = GST_ELEMENT (walk->data); | ||||
|     gint i = 0; | ||||
| 
 | ||||
|     g_print ("positions %8.8s: ", GST_ELEMENT_NAME (element)); | ||||
|     while (seek_formats[i].name) { | ||||
|       gboolean res; | ||||
|       gint64 value; | ||||
|       GstFormat format; | ||||
| 
 | ||||
|       format = seek_formats[i].format; | ||||
|       res = gst_element_query (element, GST_PAD_QUERY_POSITION, &format, &value); | ||||
|       if (res) { | ||||
|         g_print ("%s %13lld | ", seek_formats[i].name, value); | ||||
|       } | ||||
|       else { | ||||
|         g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*"); | ||||
|       } | ||||
|       i++; | ||||
|     } | ||||
|     g_print (" %s\n", GST_ELEMENT_NAME (element)); | ||||
|     walk = g_list_next (walk); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| static gboolean | ||||
| update_scale (gpointer data)  | ||||
| { | ||||
|   GstClock *clock; | ||||
|   guint64 position; | ||||
|   GstFormat format = GST_FORMAT_TIME; | ||||
| 
 | ||||
|   duration = 0; | ||||
|   clock = gst_bin_get_clock (GST_BIN (pipeline)); | ||||
| 
 | ||||
|   if (seekable_elements) { | ||||
|     GstElement *element = GST_ELEMENT (seekable_elements->data); | ||||
|     gst_element_query (element, GST_PAD_QUERY_TOTAL, &format, &duration); | ||||
|   } | ||||
|   position = gst_clock_get_time (clock); | ||||
| 
 | ||||
|   if (stats) { | ||||
|     g_print ("clock:                  %13llu  (%s)\n", position, gst_object_get_name (GST_OBJECT (clock))); | ||||
|     query_durations (); | ||||
|     query_positions (); | ||||
|   } | ||||
|   if (duration > 0) { | ||||
|     gtk_adjustment_set_value (adjustment, position * 100.0 / duration); | ||||
|   } | ||||
| 
 | ||||
|   return TRUE; | ||||
| } | ||||
| 
 | ||||
| static gboolean | ||||
| iterate (gpointer data) | ||||
| { | ||||
|   gboolean res = TRUE; | ||||
| 
 | ||||
|   res = gst_bin_iterate (GST_BIN (data)); | ||||
|   if (!res) { | ||||
|     gtk_timeout_remove (update_id); | ||||
|     g_print ("stopping iterations\n"); | ||||
|   } | ||||
|   return res; | ||||
| } | ||||
| 
 | ||||
| static gboolean | ||||
| start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data) | ||||
| { | ||||
|   gst_element_set_state (pipeline, GST_STATE_PAUSED); | ||||
|   gtk_timeout_remove (update_id); | ||||
| 
 | ||||
|   return FALSE; | ||||
| } | ||||
| 
 | ||||
| static gboolean | ||||
| stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data) | ||||
| { | ||||
|   gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100; | ||||
|   gboolean res; | ||||
|   GstEvent *s_event; | ||||
|   GList *walk = seekable_elements; | ||||
| 
 | ||||
|   while (walk) { | ||||
|     GstElement *seekable = GST_ELEMENT (walk->data); | ||||
| 
 | ||||
|     g_print ("seek to %lld on element %s\n", real, GST_ELEMENT_NAME (seekable)); | ||||
|     s_event = gst_event_new_seek (GST_FORMAT_TIME | | ||||
| 			   	  GST_SEEK_METHOD_SET | | ||||
| 				  GST_SEEK_FLAG_FLUSH, real); | ||||
| 
 | ||||
|     res = gst_element_send_event (seekable, s_event); | ||||
| 
 | ||||
|     walk = g_list_next (walk); | ||||
|   } | ||||
| 
 | ||||
|   gst_element_set_state (pipeline, GST_STATE_PLAYING); | ||||
|   if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE)) | ||||
|     gtk_idle_add ((GtkFunction) iterate, pipeline); | ||||
|   update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); | ||||
| 
 | ||||
|   return FALSE; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| play_cb (GtkButton * button, gpointer data) | ||||
| { | ||||
|   if (gst_element_get_state (pipeline) != GST_STATE_PLAYING) { | ||||
|     gst_element_set_state (pipeline, GST_STATE_PLAYING); | ||||
|     if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE)) | ||||
|       gtk_idle_add ((GtkFunction) iterate, pipeline); | ||||
|     update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| pause_cb (GtkButton * button, gpointer data) | ||||
| { | ||||
|   if (gst_element_get_state (pipeline) != GST_STATE_PAUSED) { | ||||
|     gst_element_set_state (pipeline, GST_STATE_PAUSED); | ||||
|     gtk_timeout_remove (update_id); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| stop_cb (GtkButton * button, gpointer data) | ||||
| { | ||||
|   if (gst_element_get_state (pipeline) != GST_STATE_READY) { | ||||
|     gst_element_set_state (pipeline, GST_STATE_READY); | ||||
|     gtk_timeout_remove (update_id); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main (int argc, char **argv) | ||||
| { | ||||
|   GtkWidget *window, *hbox, *vbox,  | ||||
|             *play_button, *pause_button, *stop_button,  | ||||
| 	    *hscale; | ||||
|   gboolean threaded = FALSE; | ||||
|   struct poptOption options[] = { | ||||
|     {"threaded",  't',  POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   &threaded,   0, | ||||
|          "Run the pipeline in a toplevel thread", NULL}, | ||||
|     {"stats",  's',  POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   &stats,   0, | ||||
|          "Show element stats", NULL}, | ||||
|      POPT_TABLEEND | ||||
|     }; | ||||
| 
 | ||||
|   gst_init_with_popt_table (&argc, &argv, options); | ||||
|   gtk_init (&argc, &argv); | ||||
| 
 | ||||
|   pipeline = make_cdaudio_pipeline (threaded); | ||||
| 
 | ||||
|   /* initialize gui elements ... */ | ||||
|   window = gtk_window_new (GTK_WINDOW_TOPLEVEL); | ||||
|   hbox = gtk_hbox_new (FALSE, 0); | ||||
|   vbox = gtk_vbox_new (FALSE, 0); | ||||
|   play_button = gtk_button_new_with_label ("play"); | ||||
|   pause_button = gtk_button_new_with_label ("pause"); | ||||
|   stop_button = gtk_button_new_with_label ("stop"); | ||||
| 
 | ||||
|   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0)); | ||||
|   hscale = gtk_hscale_new (adjustment); | ||||
|   gtk_scale_set_digits (GTK_SCALE (hscale), 2); | ||||
|   gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS); | ||||
| 
 | ||||
|   gtk_signal_connect(GTK_OBJECT(hscale), | ||||
|                              "button_press_event", G_CALLBACK (start_seek), pipeline); | ||||
|   gtk_signal_connect(GTK_OBJECT(hscale), | ||||
|                              "button_release_event", G_CALLBACK (stop_seek), pipeline); | ||||
|   gtk_signal_connect(GTK_OBJECT(hscale), | ||||
|                              "format_value", G_CALLBACK (format_value), pipeline); | ||||
| 
 | ||||
|   /* do the packing stuff ... */ | ||||
|   gtk_window_set_default_size (GTK_WINDOW (window), 96, 96); | ||||
|   gtk_container_add (GTK_CONTAINER (window), vbox); | ||||
|   gtk_container_add (GTK_CONTAINER (vbox), hbox); | ||||
|   gtk_box_pack_start (GTK_BOX (hbox), play_button, FALSE, FALSE, 2); | ||||
|   gtk_box_pack_start (GTK_BOX (hbox), pause_button, FALSE, FALSE, 2); | ||||
|   gtk_box_pack_start (GTK_BOX (hbox), stop_button, FALSE, FALSE, 2); | ||||
|   gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2); | ||||
| 
 | ||||
|   /* connect things ... */ | ||||
|   g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline); | ||||
|   g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline); | ||||
|   g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline); | ||||
|   g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL); | ||||
| 
 | ||||
|   /* show the gui. */ | ||||
|   gtk_widget_show_all (window); | ||||
| 
 | ||||
|   gtk_main (); | ||||
| 
 | ||||
|   gst_buffer_print_stats(); | ||||
|   gst_event_print_stats(); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user