646c121c10359c0f29c93eaf7763a7741b1a762e
[platform/upstream/gst-plugins-good.git] / examples / seeking / cdparanoia.c
1 #include <stdlib.h>
2 #include <gst/gst.h>
3 #include <string.h>
4
5 static void
6 get_position_info (GstElement *cdparanoia)
7 {
8   GstFormat track_format;
9   const GstFormat *formats;
10   GstPad *pad;
11
12   track_format = gst_format_get_by_nick ("track");
13   g_assert (track_format != 0);
14
15   pad = gst_element_get_pad (cdparanoia, "src");
16   formats = gst_pad_get_formats (pad);
17
18   while (*formats) {
19     const GstFormatDefinition *definition;
20     GstFormat format;
21     gint64 position;
22     gboolean res;
23
24     definition = gst_format_get_details (*formats);
25
26     format = *formats;
27     res = gst_pad_query (pad, GST_QUERY_POSITION,
28                          &format, &position);
29
30     if (format == GST_FORMAT_TIME) {
31       position /= GST_SECOND;
32       g_print ("%s: %lld:%02lld", definition->nick, position/60, position%60);
33     }
34     else {
35       g_print ("%s: %lld", definition->nick, position);
36     }
37
38     formats++;
39     if (*formats) {
40       g_print (", ");
41     }
42   }
43   g_print ("\r");
44 }
45
46 static void
47 get_track_info (GstElement *cdparanoia)
48 {
49   GstFormat track_format;
50   gint64 total_tracks = 0, total_time = 0;
51   GstPad *pad;
52   const GstFormat *formats;
53   gint i;
54   gint64 time_count = 0;
55   
56   track_format = gst_format_get_by_nick ("track");
57   g_assert (track_format != 0);
58
59   pad = gst_element_get_pad (cdparanoia, "src");
60   formats = gst_pad_get_formats (pad);
61
62   /* we loop over all supported formats and report the total
63    * number of them */
64   while (*formats) {
65     const GstFormatDefinition *definition;
66     gint64 total;
67     GstFormat format;
68     gboolean res;
69     
70     definition = gst_format_get_details (*formats);
71
72     format = *formats;
73     res = gst_pad_query (pad, GST_QUERY_TOTAL,
74                          &format, &total);
75     if (res) {
76       if (format == GST_FORMAT_TIME) {
77         total /= GST_SECOND;
78         g_print ("%s total: %lld:%02lld\n", definition->nick, total/60, total%60);
79       }
80       else
81         g_print ("%s total: %lld\n", definition->nick, total);
82
83       if (format == track_format)
84         total_tracks = total;
85       else if (format == GST_FORMAT_TIME)
86         total_time = total;
87     }
88     else
89       g_print ("failed to get %s total\n", definition->nick);
90
91     formats++;
92   }
93
94   /* then we loop over all the tracks to get more info.
95    * since pad_convert always works from 0, the time from track 1 needs
96    * to be substracted from track 2 */
97   for (i = 0; i <= total_tracks; i++) {
98     gint64 time;
99     gboolean res;
100
101     if (i < total_tracks) {
102       GstFormat format;
103
104       format = GST_FORMAT_TIME;
105       res = gst_pad_convert (pad, track_format, i,
106                              &format, &time);
107       time /= GST_SECOND;
108     }
109     else {
110       time = total_time;
111       res = TRUE;
112     }
113
114     if (res) {
115       /* for the first track (i==0) we wait until we have the
116        * time of the next track */
117       if (i > 0) {
118         gint64 length = time - time_count;
119
120         g_print ("track %d: %lld:%02lld -> %lld:%02lld, length: %lld:%02lld\n",
121                  i-1,
122                  time_count / 60, time_count % 60,
123                  time / 60, time % 60,
124                  length / 60, length % 60);
125       }
126     }
127     else {
128       g_print ("could not get time for track %d\n", i);
129     }
130
131     time_count = time;
132   }
133 }
134
135 int
136 main (int argc, char **argv)
137 {
138   GstElement *pipeline;
139   GstElement *cdparanoia;
140   GstElement *osssink;
141   GstPad *pad;
142   GstFormat track_format;
143   GstEvent *event;
144   gint count;
145   gboolean res;
146
147   gst_init (&argc, &argv);
148
149   pipeline = gst_pipeline_new ("pipeline");
150
151   cdparanoia = gst_element_factory_make ("cdparanoia", "cdparanoia");
152   g_assert (cdparanoia);
153   g_object_set (G_OBJECT (cdparanoia), "paranoia_mode", 0, NULL);
154
155   osssink = gst_element_factory_make ("osssink", "osssink");
156   g_assert (osssink);
157
158   gst_bin_add (GST_BIN (pipeline), cdparanoia);
159   gst_bin_add (GST_BIN (pipeline), osssink);
160
161   gst_element_link_pads (cdparanoia, "src", osssink, "sink");
162
163   g_signal_connect (G_OBJECT (pipeline), "deep_notify",
164                   G_CALLBACK (gst_element_default_deep_notify), NULL);
165
166   gst_element_set_state (pipeline, GST_STATE_PAUSED);
167
168   /* now we go into probe mode */
169   get_track_info (cdparanoia);
170
171   track_format = gst_format_get_by_nick ("track");
172   g_assert (track_format != 0);
173
174   pad = gst_element_get_pad (cdparanoia, "src");
175   g_assert (pad);
176
177   g_print ("playing from track 3\n");
178   /* seek to track3 */
179   event = gst_event_new_seek (track_format |
180                               GST_SEEK_METHOD_SET |
181                               GST_SEEK_FLAG_FLUSH,
182                               3);
183
184   res = gst_pad_send_event (pad, event);
185   if (!res)
186     g_warning ("seek failed");
187
188   gst_element_set_state (pipeline, GST_STATE_PLAYING);
189
190   count = 0;
191   while (gst_bin_iterate (GST_BIN (pipeline))) {
192     get_position_info (cdparanoia);
193     if (count++ > 500)
194       break;
195   }
196   gst_element_set_state (pipeline, GST_STATE_PAUSED);
197
198   g_print ("\nplaying from second 25 to second 29\n");
199   /* seek to some seconds */
200   event = gst_event_new_segment_seek (GST_FORMAT_TIME |
201                                       GST_SEEK_METHOD_SET |
202                                       GST_SEEK_FLAG_FLUSH,
203                                       25 * GST_SECOND, 29 * GST_SECOND);
204   res = gst_pad_send_event (pad, event);
205   if (!res)
206     g_warning ("seek failed");
207
208   gst_element_set_state (pipeline, GST_STATE_PLAYING);
209
210   while (gst_bin_iterate (GST_BIN (pipeline))) {
211     get_position_info (cdparanoia);
212   }
213   g_print ("\n");
214
215   /* shutdown everything again */
216   gst_element_set_state (pipeline, GST_STATE_NULL);
217
218   return 0;
219 }