Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / tests / examples / stepping / framestep1.c
1 #include <stdlib.h>
2 #include <gst/gst.h>
3
4 static void
5 event_loop (GstElement * pipe)
6 {
7   GstBus *bus;
8   GstMessage *message = NULL;
9   gboolean running = TRUE;
10
11   bus = gst_element_get_bus (GST_ELEMENT (pipe));
12
13   while (running) {
14     message = gst_bus_timed_pop_filtered (bus, -1, GST_MESSAGE_ANY);
15
16     g_assert (message != NULL);
17
18     switch (message->type) {
19       case GST_MESSAGE_EOS:
20         g_message ("got EOS");
21         running = FALSE;
22         break;
23       case GST_MESSAGE_WARNING:{
24         GError *gerror;
25         gchar *debug;
26
27         gst_message_parse_warning (message, &gerror, &debug);
28         gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
29         g_error_free (gerror);
30         g_free (debug);
31         break;
32       }
33       case GST_MESSAGE_ERROR:
34       {
35         GError *gerror;
36         gchar *debug;
37
38         gst_message_parse_error (message, &gerror, &debug);
39         gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
40         g_error_free (gerror);
41         g_free (debug);
42         running = FALSE;
43         break;
44       }
45       case GST_MESSAGE_STEP_DONE:
46       {
47         GstFormat format;
48         guint64 amount;
49         gdouble rate;
50         gboolean flush, intermediate;
51         guint64 duration;
52         gboolean eos;
53
54         gst_message_parse_step_done (message, &format, &amount, &rate,
55             &flush, &intermediate, &duration, &eos);
56
57         if (format == GST_FORMAT_DEFAULT) {
58           g_message ("step done: %" GST_TIME_FORMAT " skipped in %"
59               G_GUINT64_FORMAT " frames", GST_TIME_ARGS (duration), amount);
60         } else {
61           g_message ("step done: %" GST_TIME_FORMAT " skipped",
62               GST_TIME_ARGS (duration));
63         }
64         break;
65       }
66       default:
67         break;
68     }
69     gst_message_unref (message);
70   }
71   gst_object_unref (bus);
72 }
73
74 /* signalled when a new preroll buffer is available */
75 static void
76 new_preroll (GstElement * appsink, gpointer user_data)
77 {
78   GstBuffer *buffer;
79
80   g_signal_emit_by_name (appsink, "pull-preroll", &buffer);
81
82   g_message ("have new-preroll buffer %p, timestamp %" GST_TIME_FORMAT, buffer,
83       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
84
85   gst_buffer_unref (buffer);
86 }
87
88 int
89 main (int argc, char *argv[])
90 {
91   GstElement *bin, *videotestsrc, *appsink;
92   gint64 pos;
93
94   gst_init (&argc, &argv);
95
96   /* create a new bin to hold the elements */
97   bin = gst_pipeline_new ("pipeline");
98   g_assert (bin);
99
100   /* create a fake source */
101   videotestsrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
102   g_assert (videotestsrc);
103   g_object_set (videotestsrc, "num-buffers", 10, NULL);
104
105   /* and a fake sink */
106   appsink = gst_element_factory_make ("appsink", "appsink");
107   g_assert (appsink);
108   g_object_set (appsink, "emit-signals", TRUE, NULL);
109   g_object_set (appsink, "sync", TRUE, NULL);
110   g_signal_connect (appsink, "new-preroll", (GCallback) new_preroll, NULL);
111
112   /* add objects to the main pipeline */
113   gst_bin_add (GST_BIN (bin), videotestsrc);
114   gst_bin_add (GST_BIN (bin), appsink);
115
116   /* link the elements */
117   gst_element_link_many (videotestsrc, appsink, NULL);
118
119   /* go to the PAUSED state and wait for preroll */
120   g_message ("prerolling first frame");
121   gst_element_set_state (bin, GST_STATE_PAUSED);
122   gst_element_get_state (bin, NULL, NULL, -1);
123
124   /* step two frames, flush so that new preroll is queued */
125   g_message ("stepping three frames");
126   g_assert (gst_element_send_event (bin,
127           gst_event_new_step (GST_FORMAT_BUFFERS, 2, 1.0, TRUE, FALSE)));
128
129   /* blocks and returns when we received the step done message */
130   event_loop (bin);
131
132   /* wait for step to really complete */
133   gst_element_get_state (bin, NULL, NULL, -1);
134
135   gst_element_query_position (bin, GST_FORMAT_TIME, &pos);
136   g_message ("stepped two frames, now at %" GST_TIME_FORMAT,
137       GST_TIME_ARGS (pos));
138
139   /* step 3 frames, flush so that new preroll is queued */
140   g_message ("stepping 120 milliseconds ");
141   g_assert (gst_element_send_event (bin,
142           gst_event_new_step (GST_FORMAT_TIME, 120 * GST_MSECOND, 1.0, TRUE,
143               FALSE)));
144
145   /* blocks and returns when we received the step done message */
146   event_loop (bin);
147
148   /* wait for step to really complete */
149   gst_element_get_state (bin, NULL, NULL, -1);
150
151   gst_element_query_position (bin, GST_FORMAT_TIME, &pos);
152   g_message ("stepped 120ms frames, now at %" GST_TIME_FORMAT,
153       GST_TIME_ARGS (pos));
154
155   g_message ("playing until EOS");
156   gst_element_set_state (bin, GST_STATE_PLAYING);
157   /* Run event loop listening for bus messages until EOS or ERROR */
158   event_loop (bin);
159   g_message ("finished");
160
161   /* stop the bin */
162   gst_element_set_state (bin, GST_STATE_NULL);
163
164   exit (0);
165 }