1 /* GStreamer
2  * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #include <string.h>
21 
22 #include <gst/check/gstcheck.h>
23 #include <gst/video/video.h>
24 
25 static gboolean
bus_handler(GstBus * bus,GstMessage * message,gpointer data)26 bus_handler (GstBus * bus, GstMessage * message, gpointer data)
27 {
28   GMainLoop *loop = (GMainLoop *) data;
29 
30   switch (message->type) {
31     case GST_MESSAGE_EOS:
32       g_main_loop_quit (loop);
33       break;
34     case GST_MESSAGE_WARNING:
35     case GST_MESSAGE_ERROR:{
36       GError *gerror;
37       gchar *debug;
38 
39       if (message->type == GST_MESSAGE_WARNING)
40         gst_message_parse_warning (message, &gerror, &debug);
41       else
42         gst_message_parse_error (message, &gerror, &debug);
43       g_error ("error from %s: %s (%s)\n",
44           GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)), gerror->message,
45           GST_STR_NULL (debug));
46       g_error_free (gerror);
47       g_free (debug);
48       g_main_loop_quit (loop);
49       break;
50     }
51     default:
52       break;
53   }
54 
55   return TRUE;
56 }
57 
58 static GstElement *
setup_imagefreeze(const GstCaps * caps1,const GstCaps * caps2,GCallback sink_handoff,gpointer sink_handoff_data)59 setup_imagefreeze (const GstCaps * caps1, const GstCaps * caps2,
60     GCallback sink_handoff, gpointer sink_handoff_data)
61 {
62   GstElement *pipeline;
63   GstElement *videotestsrc, *capsfilter1, *imagefreeze, *capsfilter2, *fakesink;
64 
65   pipeline = gst_pipeline_new ("pipeline");
66   fail_unless (pipeline != NULL);
67 
68   videotestsrc = gst_element_factory_make ("videotestsrc", "src");
69   fail_unless (videotestsrc != NULL);
70   g_object_set (videotestsrc, "num-buffers", 1, NULL);
71 
72   capsfilter1 = gst_element_factory_make ("capsfilter", "filter1");
73   fail_unless (capsfilter1 != NULL);
74   g_object_set (capsfilter1, "caps", caps1, NULL);
75 
76   imagefreeze = gst_element_factory_make ("imagefreeze", "freeze");
77   fail_unless (imagefreeze != NULL);
78 
79   capsfilter2 = gst_element_factory_make ("capsfilter", "filter2");
80   fail_unless (capsfilter2 != NULL);
81   g_object_set (capsfilter2, "caps", caps2, NULL);
82 
83   fakesink = gst_element_factory_make ("fakesink", "sink");
84   fail_unless (fakesink != NULL);
85   g_object_set (fakesink, "signal-handoffs", TRUE, "async", FALSE, NULL);
86 
87   if (sink_handoff)
88     g_signal_connect (fakesink, "handoff", sink_handoff, sink_handoff_data);
89 
90   gst_bin_add_many (GST_BIN (pipeline), videotestsrc, capsfilter1, imagefreeze,
91       capsfilter2, fakesink, NULL);
92 
93   fail_unless (gst_element_link_pads (videotestsrc, "src", capsfilter1,
94           "sink"));
95   fail_unless (gst_element_link_pads (capsfilter1, "src", imagefreeze, "sink"));
96   fail_unless (gst_element_link_pads (imagefreeze, "src", capsfilter2, "sink"));
97   fail_unless (gst_element_link_pads (capsfilter2, "src", fakesink, "sink"));
98 
99   return pipeline;
100 }
101 
102 static void
sink_handoff_cb_0_1(GstElement * object,GstBuffer * buffer,GstPad * pad,gpointer user_data)103 sink_handoff_cb_0_1 (GstElement * object, GstBuffer * buffer, GstPad * pad,
104     gpointer user_data)
105 {
106   guint *n_buffers = (guint *) user_data;
107 
108   if (*n_buffers == G_MAXUINT)
109     return;
110 
111   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer), 0);
112   fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), GST_CLOCK_TIME_NONE);
113   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 0);
114   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer), 1);
115 
116   *n_buffers = *n_buffers + 1;
117 }
118 
GST_START_TEST(test_imagefreeze_0_1)119 GST_START_TEST (test_imagefreeze_0_1)
120 {
121   GstElement *pipeline;
122   GstCaps *caps1, *caps2;
123   GstBus *bus;
124   GMainLoop *loop;
125   guint n_buffers = G_MAXUINT;
126   guint bus_watch = 0;
127   GstVideoInfo i1, i2;
128 
129   gst_video_info_init (&i1);
130   gst_video_info_set_format (&i1, GST_VIDEO_FORMAT_xRGB, 640, 480);
131   i1.fps_n = 25;
132   i1.fps_d = 1;
133   caps1 = gst_video_info_to_caps (&i1);
134 
135   gst_video_info_init (&i2);
136   gst_video_info_set_format (&i2, GST_VIDEO_FORMAT_xRGB, 640, 480);
137   caps2 = gst_video_info_to_caps (&i2);
138 
139   pipeline =
140       setup_imagefreeze (caps1, caps2, G_CALLBACK (sink_handoff_cb_0_1),
141       &n_buffers);
142 
143   loop = g_main_loop_new (NULL, TRUE);
144   fail_unless (loop != NULL);
145 
146   bus = gst_element_get_bus (pipeline);
147   fail_unless (bus != NULL);
148   bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
149   gst_object_unref (bus);
150 
151   n_buffers = 0;
152   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
153       GST_STATE_CHANGE_SUCCESS);
154 
155   g_main_loop_run (loop);
156 
157   fail_unless_equals_int (n_buffers, 1);
158 
159   gst_element_set_state (pipeline, GST_STATE_NULL);
160 
161   gst_object_unref (pipeline);
162   g_main_loop_unref (loop);
163   gst_caps_unref (caps1);
164   gst_caps_unref (caps2);
165   g_source_remove (bus_watch);
166 }
167 
168 GST_END_TEST;
169 
170 static void
sink_handoff_cb_25_1_0ms_400ms(GstElement * object,GstBuffer * buffer,GstPad * pad,gpointer user_data)171 sink_handoff_cb_25_1_0ms_400ms (GstElement * object, GstBuffer * buffer,
172     GstPad * pad, gpointer user_data)
173 {
174   guint *n_buffers = (guint *) user_data;
175 
176   if (*n_buffers == G_MAXUINT)
177     return;
178 
179   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
180       *n_buffers * 40 * GST_MSECOND);
181   fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
182   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), *n_buffers);
183   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer), *n_buffers + 1);
184 
185   *n_buffers = *n_buffers + 1;
186 }
187 
GST_START_TEST(test_imagefreeze_25_1_0ms_400ms)188 GST_START_TEST (test_imagefreeze_25_1_0ms_400ms)
189 {
190   GstElement *pipeline;
191   GstCaps *caps1, *caps2;
192   GstBus *bus;
193   GMainLoop *loop;
194   guint n_buffers = G_MAXUINT;
195   guint bus_watch = 0;
196   GstVideoInfo i1, i2;
197 
198   gst_video_info_init (&i1);
199   gst_video_info_set_format (&i1, GST_VIDEO_FORMAT_xRGB, 640, 480);
200   i1.fps_n = 25;
201   i1.fps_d = 1;
202   caps1 = gst_video_info_to_caps (&i1);
203 
204   gst_video_info_init (&i2);
205   gst_video_info_set_format (&i2, GST_VIDEO_FORMAT_xRGB, 640, 480);
206   i2.fps_n = 25;
207   i2.fps_d = 1;
208   caps2 = gst_video_info_to_caps (&i2);
209 
210   pipeline =
211       setup_imagefreeze (caps1, caps2,
212       G_CALLBACK (sink_handoff_cb_25_1_0ms_400ms), &n_buffers);
213 
214   loop = g_main_loop_new (NULL, TRUE);
215   fail_unless (loop != NULL);
216 
217   bus = gst_element_get_bus (pipeline);
218   fail_unless (bus != NULL);
219   bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
220   gst_object_unref (bus);
221 
222   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
223       GST_STATE_CHANGE_SUCCESS);
224 
225   fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
226           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
227           400 * GST_MSECOND));
228 
229   n_buffers = 0;
230 
231   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
232       GST_STATE_CHANGE_SUCCESS);
233 
234   g_main_loop_run (loop);
235 
236   fail_unless_equals_int (n_buffers, 10);
237 
238   gst_element_set_state (pipeline, GST_STATE_NULL);
239 
240   gst_object_unref (pipeline);
241   g_main_loop_unref (loop);
242   gst_caps_unref (caps1);
243   gst_caps_unref (caps2);
244   g_source_remove (bus_watch);
245 }
246 
247 GST_END_TEST;
248 
249 static void
sink_handoff_cb_25_1_200ms_400ms(GstElement * object,GstBuffer * buffer,GstPad * pad,gpointer user_data)250 sink_handoff_cb_25_1_200ms_400ms (GstElement * object, GstBuffer * buffer,
251     GstPad * pad, gpointer user_data)
252 {
253   guint *n_buffers = (guint *) user_data;
254 
255   if (*n_buffers == G_MAXUINT)
256     return;
257 
258   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
259       200 * GST_MSECOND + *n_buffers * 40 * GST_MSECOND);
260   fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
261   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 5 + *n_buffers);
262   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer),
263       5 + *n_buffers + 1);
264 
265   *n_buffers = *n_buffers + 1;
266 }
267 
GST_START_TEST(test_imagefreeze_25_1_200ms_400ms)268 GST_START_TEST (test_imagefreeze_25_1_200ms_400ms)
269 {
270   GstElement *pipeline;
271   GstCaps *caps1, *caps2;
272   GstBus *bus;
273   GMainLoop *loop;
274   guint n_buffers = G_MAXUINT;
275   guint bus_watch = 0;
276   GstVideoInfo i1, i2;
277 
278   gst_video_info_init (&i1);
279   gst_video_info_set_format (&i1, GST_VIDEO_FORMAT_xRGB, 640, 480);
280   i1.fps_n = 25;
281   i1.fps_d = 1;
282   caps1 = gst_video_info_to_caps (&i1);
283 
284   gst_video_info_init (&i2);
285   gst_video_info_set_format (&i2, GST_VIDEO_FORMAT_xRGB, 640, 480);
286   i2.fps_n = 25;
287   i2.fps_d = 1;
288   caps2 = gst_video_info_to_caps (&i2);
289 
290   pipeline =
291       setup_imagefreeze (caps1, caps2,
292       G_CALLBACK (sink_handoff_cb_25_1_200ms_400ms), &n_buffers);
293 
294   loop = g_main_loop_new (NULL, TRUE);
295   fail_unless (loop != NULL);
296 
297   bus = gst_element_get_bus (pipeline);
298   fail_unless (bus != NULL);
299   bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
300   gst_object_unref (bus);
301 
302   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
303       GST_STATE_CHANGE_SUCCESS);
304 
305   fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
306           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 200 * GST_MSECOND,
307           GST_SEEK_TYPE_SET, 400 * GST_MSECOND));
308 
309   n_buffers = 0;
310 
311   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
312       GST_STATE_CHANGE_SUCCESS);
313 
314   g_main_loop_run (loop);
315 
316   fail_unless_equals_int (n_buffers, 5);
317 
318   gst_element_set_state (pipeline, GST_STATE_NULL);
319 
320   gst_object_unref (pipeline);
321   g_main_loop_unref (loop);
322   gst_caps_unref (caps1);
323   gst_caps_unref (caps2);
324   g_source_remove (bus_watch);
325 }
326 
327 GST_END_TEST;
328 
329 static void
sink_handoff_cb_25_1_400ms_0ms(GstElement * object,GstBuffer * buffer,GstPad * pad,gpointer user_data)330 sink_handoff_cb_25_1_400ms_0ms (GstElement * object, GstBuffer * buffer,
331     GstPad * pad, gpointer user_data)
332 {
333   guint *n_buffers = (guint *) user_data;
334 
335   if (*n_buffers == G_MAXUINT)
336     return;
337 
338   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
339       400 * GST_MSECOND - (*n_buffers + 1) * 40 * GST_MSECOND);
340   fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
341   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 10 - (*n_buffers + 1));
342   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer),
343       10 - (*n_buffers + 1) + 1);
344 
345   *n_buffers = *n_buffers + 1;
346 }
347 
GST_START_TEST(test_imagefreeze_25_1_400ms_0ms)348 GST_START_TEST (test_imagefreeze_25_1_400ms_0ms)
349 {
350   GstElement *pipeline;
351   GstCaps *caps1, *caps2;
352   GstBus *bus;
353   GMainLoop *loop;
354   guint n_buffers = G_MAXUINT;
355   guint bus_watch = 0;
356   GstVideoInfo i1, i2;
357 
358   gst_video_info_init (&i1);
359   gst_video_info_set_format (&i1, GST_VIDEO_FORMAT_xRGB, 640, 480);
360   i1.fps_n = 25;
361   i1.fps_d = 1;
362   caps1 = gst_video_info_to_caps (&i1);
363 
364   gst_video_info_init (&i2);
365   gst_video_info_set_format (&i2, GST_VIDEO_FORMAT_xRGB, 640, 480);
366   i2.fps_n = 25;
367   i2.fps_d = 1;
368   caps2 = gst_video_info_to_caps (&i2);
369 
370   pipeline =
371       setup_imagefreeze (caps1, caps2,
372       G_CALLBACK (sink_handoff_cb_25_1_400ms_0ms), &n_buffers);
373 
374   loop = g_main_loop_new (NULL, TRUE);
375   fail_unless (loop != NULL);
376 
377   bus = gst_element_get_bus (pipeline);
378   fail_unless (bus != NULL);
379   bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
380   gst_object_unref (bus);
381 
382   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
383       GST_STATE_CHANGE_SUCCESS);
384 
385   fail_unless (gst_element_seek (pipeline, -1.0, GST_FORMAT_TIME,
386           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
387           400 * GST_MSECOND));
388 
389   n_buffers = 0;
390 
391   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
392       GST_STATE_CHANGE_SUCCESS);
393 
394   g_main_loop_run (loop);
395 
396   fail_unless_equals_int (n_buffers, 10);
397 
398   gst_element_set_state (pipeline, GST_STATE_NULL);
399 
400   gst_object_unref (pipeline);
401   g_main_loop_unref (loop);
402   gst_caps_unref (caps1);
403   gst_caps_unref (caps2);
404   g_source_remove (bus_watch);
405 }
406 
407 GST_END_TEST;
408 
409 static void
sink_handoff_cb_25_1_220ms_380ms(GstElement * object,GstBuffer * buffer,GstPad * pad,gpointer user_data)410 sink_handoff_cb_25_1_220ms_380ms (GstElement * object, GstBuffer * buffer,
411     GstPad * pad, gpointer user_data)
412 {
413   guint *n_buffers = (guint *) user_data;
414 
415   if (*n_buffers == G_MAXUINT)
416     return;
417 
418   if (*n_buffers == 0) {
419     fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
420         220 * GST_MSECOND);
421     fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 20 * GST_MSECOND);
422   } else if (*n_buffers == 4) {
423     fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
424         360 * GST_MSECOND);
425     fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 20 * GST_MSECOND);
426   } else {
427     fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
428         200 * GST_MSECOND + *n_buffers * 40 * GST_MSECOND);
429     fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
430   }
431 
432   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 5 + *n_buffers);
433   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer),
434       5 + *n_buffers + 1);
435 
436   *n_buffers = *n_buffers + 1;
437 }
438 
GST_START_TEST(test_imagefreeze_25_1_220ms_380ms)439 GST_START_TEST (test_imagefreeze_25_1_220ms_380ms)
440 {
441   GstElement *pipeline;
442   GstCaps *caps1, *caps2;
443   GstBus *bus;
444   GMainLoop *loop;
445   guint n_buffers = G_MAXUINT;
446   guint bus_watch = 0;
447   GstVideoInfo i1, i2;
448 
449   gst_video_info_init (&i1);
450   gst_video_info_set_format (&i1, GST_VIDEO_FORMAT_xRGB, 640, 480);
451   i1.fps_n = 25;
452   i1.fps_d = 1;
453   caps1 = gst_video_info_to_caps (&i1);
454 
455   gst_video_info_init (&i2);
456   gst_video_info_set_format (&i2, GST_VIDEO_FORMAT_xRGB, 640, 480);
457   i2.fps_n = 25;
458   i2.fps_d = 1;
459   caps2 = gst_video_info_to_caps (&i2);
460 
461   pipeline =
462       setup_imagefreeze (caps1, caps2,
463       G_CALLBACK (sink_handoff_cb_25_1_220ms_380ms), &n_buffers);
464 
465   loop = g_main_loop_new (NULL, TRUE);
466   fail_unless (loop != NULL);
467 
468   bus = gst_element_get_bus (pipeline);
469   fail_unless (bus != NULL);
470   bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
471   gst_object_unref (bus);
472 
473   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
474       GST_STATE_CHANGE_SUCCESS);
475 
476   fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
477           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 220 * GST_MSECOND,
478           GST_SEEK_TYPE_SET, 380 * GST_MSECOND));
479 
480   n_buffers = 0;
481 
482   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
483       GST_STATE_CHANGE_SUCCESS);
484 
485   g_main_loop_run (loop);
486 
487   fail_unless_equals_int (n_buffers, 5);
488 
489   gst_element_set_state (pipeline, GST_STATE_NULL);
490 
491   gst_object_unref (pipeline);
492   g_main_loop_unref (loop);
493   gst_caps_unref (caps1);
494   gst_caps_unref (caps2);
495   g_source_remove (bus_watch);
496 }
497 
498 GST_END_TEST;
499 
500 static void
sink_handoff_cb_count_buffers(GstElement * object,GstBuffer * buffer,GstPad * pad,gpointer user_data)501 sink_handoff_cb_count_buffers (GstElement * object, GstBuffer * buffer,
502     GstPad * pad, gpointer user_data)
503 {
504   guint *n_buffers = (guint *) user_data;
505 
506   if (*n_buffers == G_MAXUINT)
507     return;
508 
509   *n_buffers = *n_buffers + 1;
510 }
511 
GST_START_TEST(test_imagefreeze_num_buffers)512 GST_START_TEST (test_imagefreeze_num_buffers)
513 {
514   GstElement *pipeline;
515   GstElement *imagefreeze;
516   GstCaps *caps1, *caps2;
517   GstBus *bus;
518   GMainLoop *loop;
519   guint n_buffers = G_MAXUINT;
520   guint bus_watch = 0;
521   GstVideoInfo i1, i2;
522 
523   gst_video_info_init (&i1);
524   gst_video_info_set_format (&i1, GST_VIDEO_FORMAT_xRGB, 640, 480);
525   i1.fps_n = 25;
526   i1.fps_d = 1;
527   caps1 = gst_video_info_to_caps (&i1);
528 
529   gst_video_info_init (&i2);
530   gst_video_info_set_format (&i2, GST_VIDEO_FORMAT_xRGB, 640, 480);
531   i2.fps_n = 25;
532   i2.fps_d = 1;
533   caps2 = gst_video_info_to_caps (&i2);
534 
535   pipeline =
536       setup_imagefreeze (caps1, caps2,
537       G_CALLBACK (sink_handoff_cb_count_buffers), &n_buffers);
538 
539   imagefreeze = gst_bin_get_by_name (GST_BIN (pipeline), "freeze");
540   fail_unless (imagefreeze != NULL);
541 
542   loop = g_main_loop_new (NULL, TRUE);
543   fail_unless (loop != NULL);
544 
545   bus = gst_element_get_bus (pipeline);
546   fail_unless (bus != NULL);
547   bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
548   gst_object_unref (bus);
549 
550   /* Check that 0 buffers have been pushed */
551   g_object_set (imagefreeze, "num-buffers", 0, NULL);
552   n_buffers = 0;
553 
554   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
555       GST_STATE_CHANGE_SUCCESS);
556 
557   g_main_loop_run (loop);
558 
559   fail_unless_equals_int (n_buffers, 0);
560 
561   gst_element_set_state (pipeline, GST_STATE_NULL);
562 
563   /* Check that the exact number of buffers have been pushed */
564   g_object_set (imagefreeze, "num-buffers", 100, NULL);
565   n_buffers = 0;
566 
567   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
568       GST_STATE_CHANGE_SUCCESS);
569 
570   g_main_loop_run (loop);
571 
572   fail_unless_equals_int (n_buffers, 100);
573 
574   gst_element_set_state (pipeline, GST_STATE_NULL);
575 
576   gst_object_unref (imagefreeze);
577   gst_object_unref (pipeline);
578   g_main_loop_unref (loop);
579   gst_caps_unref (caps1);
580   gst_caps_unref (caps2);
581   g_source_remove (bus_watch);
582 }
583 
584 GST_END_TEST;
585 
GST_START_TEST(test_imagefreeze_eos)586 GST_START_TEST (test_imagefreeze_eos)
587 {
588   GstElement *pipeline;
589   GstElement *src;
590   GstCaps *caps1, *caps2;
591   GstBus *bus;
592   GMainLoop *loop;
593   GstFormat fmt = GST_FORMAT_TIME;
594   gint64 position;
595   guint bus_watch = 0;
596   GstVideoInfo i1, i2;
597 
598   gst_video_info_init (&i1);
599   gst_video_info_set_format (&i1, GST_VIDEO_FORMAT_xRGB, 640, 480);
600   i1.fps_n = 25;
601   i1.fps_d = 1;
602   caps1 = gst_video_info_to_caps (&i1);
603 
604   gst_video_info_init (&i2);
605   gst_video_info_set_format (&i2, GST_VIDEO_FORMAT_xRGB, 640, 480);
606   i2.fps_n = 25;
607   i2.fps_d = 1;
608   caps2 = gst_video_info_to_caps (&i2);
609 
610   pipeline = setup_imagefreeze (caps1, caps2, NULL, NULL);
611 
612   src = gst_bin_get_by_name (GST_BIN (pipeline), "src");
613   fail_unless (src != NULL);
614   g_object_set (src, "num-buffers", 100, NULL);
615 
616   loop = g_main_loop_new (NULL, TRUE);
617   fail_unless (loop != NULL);
618 
619   bus = gst_element_get_bus (pipeline);
620   fail_unless (bus != NULL);
621   bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
622   gst_object_unref (bus);
623 
624   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
625       GST_STATE_CHANGE_SUCCESS);
626 
627   fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
628           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
629           400 * GST_MSECOND));
630 
631   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
632       GST_STATE_CHANGE_SUCCESS);
633 
634   g_main_loop_run (loop);
635 
636   fail_unless (gst_element_query_position (src, fmt, &position));
637   fail_unless_equals_uint64 (position, 40 * GST_MSECOND);
638 
639   gst_element_set_state (pipeline, GST_STATE_NULL);
640 
641   gst_object_unref (src);
642   gst_object_unref (pipeline);
643   g_main_loop_unref (loop);
644   gst_caps_unref (caps1);
645   gst_caps_unref (caps2);
646   g_source_remove (bus_watch);
647 }
648 
649 GST_END_TEST;
650 
651 static Suite *
imagefreeze_suite(void)652 imagefreeze_suite (void)
653 {
654   Suite *s = suite_create ("imagefreeze");
655   TCase *tc_chain = tcase_create ("linear");
656 
657   /* time out after 120s, not the default 3 */
658   tcase_set_timeout (tc_chain, 120);
659 
660   suite_add_tcase (s, tc_chain);
661   tcase_add_test (tc_chain, test_imagefreeze_0_1);
662   tcase_add_test (tc_chain, test_imagefreeze_25_1_0ms_400ms);
663   tcase_add_test (tc_chain, test_imagefreeze_25_1_200ms_400ms);
664   tcase_add_test (tc_chain, test_imagefreeze_25_1_400ms_0ms);
665   tcase_add_test (tc_chain, test_imagefreeze_25_1_220ms_380ms);
666 
667   tcase_add_test (tc_chain, test_imagefreeze_num_buffers);
668   tcase_add_test (tc_chain, test_imagefreeze_eos);
669 
670   return s;
671 }
672 
673 GST_CHECK_MAIN (imagefreeze);
674