3 * unit test for videorate
5 * Copyright (C) 2006 Thomas Vander Stichele <thomas at apestaart dot org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
25 #include <gst/check/gstcheck.h>
27 /* For ease of programming we use globals to keep refs for our floating
28 * src and sink pads we create; otherwise we always have to do get_pad,
29 * get_peer, and then remove references in every test function */
30 static GstPad *mysrcpad, *mysinkpad;
33 #define VIDEO_CAPS_TEMPLATE_STRING \
36 #define VIDEO_CAPS_STRING \
38 "width = (int) 320, " \
39 "height = (int) 240, " \
40 "framerate = (fraction) 25/1 , " \
41 "format = (string) I420"
43 #define VIDEO_CAPS_NO_FRAMERATE_STRING \
45 "width = (int) 320, " \
46 "height = (int) 240, " \
47 "format = (string) I420"
49 #define VIDEO_CAPS_NEWSIZE_STRING \
51 "width = (int) 240, " \
52 "height = (int) 120, " \
53 "framerate = (fraction) 25/1 , " \
54 "format = (string) I420"
56 #define VIDEO_CAPS_UNUSUAL_FRAMERATE \
58 "width = (int) 240, " \
59 "height = (int) 120, " \
60 "framerate = (fraction) 999/7 , " \
61 "format = (string) I420"
63 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
66 GST_STATIC_CAPS (VIDEO_CAPS_TEMPLATE_STRING)
68 static GstStaticPadTemplate downstreamsinktemplate =
69 GST_STATIC_PAD_TEMPLATE ("sink",
72 GST_STATIC_CAPS (VIDEO_CAPS_STRING)
74 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
77 GST_STATIC_CAPS (VIDEO_CAPS_TEMPLATE_STRING)
81 assert_videorate_stats (GstElement * videorate, const gchar * reason,
82 guint64 xin, guint64 xout, guint64 xdropped, guint64 xduplicated)
84 guint64 in, out, dropped, duplicated;
86 g_object_get (videorate, "in", &in, "out", &out, "drop", &dropped,
87 "duplicate", &duplicated, NULL);
88 #define _assert_equals_uint64(a, b) \
92 fail_unless(first == second, \
93 "%s: '" #a "' (%" G_GUINT64_FORMAT ") is not equal to " \
94 "expected '" #a"' (%" G_GUINT64_FORMAT ")", reason, first, second); \
98 _assert_equals_uint64 (in, xin);
99 _assert_equals_uint64 (out, xout);
100 _assert_equals_uint64 (dropped, xdropped);
101 _assert_equals_uint64 (duplicated, xduplicated);
105 setup_videorate_full (GstStaticPadTemplate * srctemplate,
106 GstStaticPadTemplate * sinktemplate)
108 GstElement *videorate;
110 GST_DEBUG ("setup_videorate");
111 videorate = gst_check_setup_element ("videorate");
112 mysrcpad = gst_check_setup_src_pad (videorate, srctemplate);
113 mysinkpad = gst_check_setup_sink_pad (videorate, sinktemplate);
114 gst_pad_set_active (mysrcpad, TRUE);
115 gst_pad_set_active (mysinkpad, TRUE);
121 setup_videorate (void)
123 return setup_videorate_full (&srctemplate, &sinktemplate);
127 cleanup_videorate (GstElement * videorate)
129 GST_DEBUG ("cleanup_videorate");
131 g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
132 g_list_free (buffers);
135 gst_element_set_state (videorate, GST_STATE_NULL);
136 gst_element_get_state (videorate, NULL, NULL, GST_CLOCK_TIME_NONE);
137 gst_pad_set_active (mysrcpad, FALSE);
138 gst_pad_set_active (mysinkpad, FALSE);
139 gst_check_teardown_src_pad (videorate);
140 gst_check_teardown_sink_pad (videorate);
141 gst_check_teardown_element (videorate);
145 buffer_get_byte (GstBuffer * buffer, gint offset)
149 gst_buffer_extract (buffer, offset, &res, 1);
154 GST_START_TEST (test_one)
156 GstElement *videorate;
160 videorate = setup_videorate ();
161 fail_unless (gst_element_set_state (videorate,
162 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
163 "could not set to playing");
165 inbuffer = gst_buffer_new_and_alloc (4);
166 gst_buffer_memset (inbuffer, 0, 0, 4);
167 caps = gst_caps_from_string (VIDEO_CAPS_STRING);
168 gst_pad_set_caps (mysrcpad, caps);
169 GST_BUFFER_TIMESTAMP (inbuffer) = 0;
170 gst_caps_unref (caps);
171 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
173 /* pushing gives away my reference ... */
174 fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
175 /* ... and it is now stuck inside videorate */
176 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
177 fail_unless_equals_int (g_list_length (buffers), 0);
180 cleanup_videorate (videorate);
185 GST_START_TEST (test_more)
187 GstElement *videorate;
188 GstBuffer *first, *second, *third, *outbuffer;
193 videorate = setup_videorate ();
194 fail_unless (gst_element_set_state (videorate,
195 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
196 "could not set to playing");
197 assert_videorate_stats (videorate, "creation", 0, 0, 0, 0);
199 rand = g_rand_new ();
202 first = gst_buffer_new_and_alloc (4);
203 GST_BUFFER_TIMESTAMP (first) = 0;
204 /* it shouldn't matter what the offsets are, videorate produces perfect
206 GST_BUFFER_OFFSET (first) = g_rand_int (rand);
207 GST_BUFFER_OFFSET_END (first) = g_rand_int (rand);
208 gst_buffer_memset (first, 0, 1, 4);
209 caps = gst_caps_from_string (VIDEO_CAPS_STRING);
210 gst_pad_set_caps (mysrcpad, caps);
211 gst_caps_unref (caps);
212 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
213 gst_buffer_ref (first);
215 /* pushing gives away my reference ... */
216 fail_unless (gst_pad_push (mysrcpad, first) == GST_FLOW_OK);
217 /* ... and a copy is now stuck inside videorate */
218 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
219 fail_unless_equals_int (g_list_length (buffers), 0);
220 assert_videorate_stats (videorate, "first buffer", 1, 0, 0, 0);
222 /* second buffer; inbetween second and third output frame's timestamp */
223 second = gst_buffer_new_and_alloc (4);
224 GST_BUFFER_TIMESTAMP (second) = GST_SECOND * 3 / 50;
225 GST_BUFFER_OFFSET (second) = g_rand_int (rand);
226 GST_BUFFER_OFFSET_END (second) = g_rand_int (rand);
227 gst_buffer_memset (second, 0, 2, 4);
228 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
229 gst_buffer_ref (second);
231 /* pushing gives away one of my references ... */
232 fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK);
233 /* ... and a copy is now stuck inside videorate */
234 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
236 /* ... and the first one is pushed out, with timestamp 0 */
237 fail_unless_equals_int (g_list_length (buffers), 1);
238 assert_videorate_stats (videorate, "second buffer", 2, 1, 0, 0);
239 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
241 outbuffer = buffers->data;
242 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer), 0);
245 third = gst_buffer_new_and_alloc (4);
246 GST_BUFFER_TIMESTAMP (third) = GST_SECOND * 12 / 50;
247 GST_BUFFER_OFFSET (third) = g_rand_int (rand);
248 GST_BUFFER_OFFSET_END (third) = g_rand_int (rand);
249 gst_buffer_memset (third, 0, 3, 4);
250 ASSERT_BUFFER_REFCOUNT (third, "third", 1);
251 gst_buffer_ref (third);
253 /* pushing gives away my reference ... */
254 fail_unless (gst_pad_push (mysrcpad, third) == GST_FLOW_OK);
255 /* ... and a copy is now stuck inside videorate */
256 ASSERT_BUFFER_REFCOUNT (third, "third", 1);
258 /* submitting the third buffer has triggered flushing of three more frames */
259 assert_videorate_stats (videorate, "third buffer", 3, 4, 0, 2);
261 /* check timestamp and source correctness */
263 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), 0);
264 fail_unless_equals_int (buffer_get_byte (l->data, 0), 1);
265 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 0);
266 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 1);
269 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), GST_SECOND / 25);
270 fail_unless_equals_int (buffer_get_byte (l->data, 0), 2);
271 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 1);
272 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 2);
275 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data),
276 GST_SECOND * 2 / 25);
277 fail_unless_equals_int (buffer_get_byte (l->data, 0), 2);
278 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 2);
279 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 3);
282 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data),
283 GST_SECOND * 3 / 25);
284 fail_unless_equals_int (buffer_get_byte (l->data, 0), 2);
285 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 3);
286 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 4);
288 fail_unless_equals_int (g_list_length (buffers), 4);
289 /* one held by us, three held by each output frame taken from the second */
290 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
293 fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
295 /* submitting eos should flush out two more frames for tick 8 and 10 */
296 /* FIXME: right now it only flushes out one, so out is 5 instead of 6 ! */
297 assert_videorate_stats (videorate, "eos", 3, 5, 0, 2);
298 fail_unless_equals_int (g_list_length (buffers), 5);
302 gst_buffer_unref (first);
303 gst_buffer_unref (second);
304 gst_buffer_unref (third);
305 cleanup_videorate (videorate);
310 /* frames at 1, 0, 2 -> second one should be ignored */
311 GST_START_TEST (test_wrong_order_from_zero)
313 GstElement *videorate;
314 GstBuffer *first, *second, *third, *outbuffer;
317 videorate = setup_videorate ();
318 fail_unless (gst_element_set_state (videorate,
319 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
320 "could not set to playing");
321 assert_videorate_stats (videorate, "start", 0, 0, 0, 0);
324 first = gst_buffer_new_and_alloc (4);
325 GST_BUFFER_TIMESTAMP (first) = GST_SECOND;
326 gst_buffer_memset (first, 0, 0, 4);
327 caps = gst_caps_from_string (VIDEO_CAPS_STRING);
328 gst_pad_set_caps (mysrcpad, caps);
329 gst_caps_unref (caps);
330 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
331 gst_buffer_ref (first);
333 GST_DEBUG ("pushing first buffer");
334 /* pushing gives away my reference ... */
335 fail_unless (gst_pad_push (mysrcpad, first) == GST_FLOW_OK);
336 /* ... and a copy is now stuck inside videorate */
337 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
338 fail_unless_equals_int (g_list_length (buffers), 0);
339 assert_videorate_stats (videorate, "first", 1, 0, 0, 0);
342 second = gst_buffer_new_and_alloc (4);
343 GST_BUFFER_TIMESTAMP (second) = 0;
344 gst_buffer_memset (second, 0, 0, 4);
345 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
346 gst_buffer_ref (second);
348 /* pushing gives away my reference ... */
349 fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK);
350 /* ... and it is now dropped because it is too old */
351 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
352 fail_unless_equals_int (g_list_length (buffers), 0);
354 /* ... and the first one is still there */
355 assert_videorate_stats (videorate, "second", 2, 0, 1, 0);
356 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
359 third = gst_buffer_new_and_alloc (4);
360 GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND;
361 gst_buffer_memset (third, 0, 0, 4);
362 ASSERT_BUFFER_REFCOUNT (third, "third", 1);
363 gst_buffer_ref (third);
365 /* pushing gives away my reference ... */
366 fail_unless (gst_pad_push (mysrcpad, third) == GST_FLOW_OK);
367 /* ... and a copy is now stuck inside videorate */
368 ASSERT_BUFFER_REFCOUNT (third, "third", 1);
370 /* and now the first one should be pushed once and dupped 24 + 13 times, to
371 * reach the half point between 1 s (first) and 2 s (third) */
372 fail_unless_equals_int (g_list_length (buffers), 38);
373 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
374 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
375 ASSERT_BUFFER_REFCOUNT (third, "third", 1);
376 assert_videorate_stats (videorate, "third", 3, 38, 1, 37);
378 /* verify last buffer */
379 outbuffer = g_list_last (buffers)->data;
380 fail_unless (GST_IS_BUFFER (outbuffer));
381 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer),
382 GST_SECOND * 37 / 25);
385 gst_buffer_unref (first);
386 gst_buffer_unref (second);
387 gst_buffer_unref (third);
388 cleanup_videorate (videorate);
393 /* send frames with 0, 1, 2, 0 seconds */
394 GST_START_TEST (test_wrong_order)
396 GstElement *videorate;
397 GstBuffer *first, *second, *third, *fourth, *outbuffer;
400 videorate = setup_videorate ();
401 fail_unless (gst_element_set_state (videorate,
402 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
403 "could not set to playing");
404 assert_videorate_stats (videorate, "start", 0, 0, 0, 0);
407 first = gst_buffer_new_and_alloc (4);
408 GST_BUFFER_TIMESTAMP (first) = 0;
409 gst_buffer_memset (first, 0, 0, 4);
410 caps = gst_caps_from_string (VIDEO_CAPS_STRING);
411 gst_pad_set_caps (mysrcpad, caps);
412 gst_caps_unref (caps);
413 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
414 gst_buffer_ref (first);
416 GST_DEBUG ("pushing first buffer");
417 /* pushing gives away my reference ... */
418 fail_unless (gst_pad_push (mysrcpad, first) == GST_FLOW_OK);
419 /* ... and a copy is now stuck inside videorate */
420 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
421 fail_unless_equals_int (g_list_length (buffers), 0);
422 assert_videorate_stats (videorate, "first", 1, 0, 0, 0);
425 second = gst_buffer_new_and_alloc (4);
426 GST_BUFFER_TIMESTAMP (second) = GST_SECOND;
427 gst_buffer_memset (second, 0, 0, 4);
428 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
429 gst_buffer_ref (second);
431 /* pushing gives away my reference ... */
432 fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK);
433 /* ... and a copy is now stuck inside videorate */
434 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
435 /* and it created 13 output buffers as copies of the first frame */
436 fail_unless_equals_int (g_list_length (buffers), 13);
437 assert_videorate_stats (videorate, "second", 2, 13, 0, 12);
438 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
441 third = gst_buffer_new_and_alloc (4);
442 GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND;
443 gst_buffer_memset (third, 0, 0, 4);
444 ASSERT_BUFFER_REFCOUNT (third, "third", 1);
445 gst_buffer_ref (third);
447 /* pushing gives away my reference ... */
448 fail_unless (gst_pad_push (mysrcpad, third) == GST_FLOW_OK);
449 /* ... and a copy is now stuck inside videorate */
450 ASSERT_BUFFER_REFCOUNT (third, "third", 1);
452 /* submitting a frame with 2 seconds triggers output of 25 more frames */
453 fail_unless_equals_int (g_list_length (buffers), 38);
454 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
455 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
456 /* three frames submitted; two of them output as is, and 36 duplicated */
457 assert_videorate_stats (videorate, "third", 3, 38, 0, 36);
460 fourth = gst_buffer_new_and_alloc (4);
461 GST_BUFFER_TIMESTAMP (fourth) = 0;
462 gst_buffer_memset (fourth, 0, 0, 4);
463 ASSERT_BUFFER_REFCOUNT (fourth, "fourth", 1);
464 gst_buffer_ref (fourth);
466 /* pushing gives away my reference ... */
467 fail_unless (gst_pad_push (mysrcpad, fourth) == GST_FLOW_OK);
468 /* ... and it is dropped */
469 ASSERT_BUFFER_REFCOUNT (fourth, "fourth", 1);
471 fail_unless_equals_int (g_list_length (buffers), 38);
472 ASSERT_BUFFER_REFCOUNT (first, "first", 1);
473 ASSERT_BUFFER_REFCOUNT (second, "second", 1);
474 assert_videorate_stats (videorate, "fourth", 4, 38, 1, 36);
476 /* verify last buffer */
477 outbuffer = g_list_last (buffers)->data;
478 fail_unless (GST_IS_BUFFER (outbuffer));
479 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer),
480 GST_SECOND * 37 / 25);
484 gst_buffer_unref (first);
485 gst_buffer_unref (second);
486 gst_buffer_unref (third);
487 gst_buffer_unref (fourth);
488 cleanup_videorate (videorate);
494 /* if no framerate is negotiated, we should not be able to push a buffer */
495 GST_START_TEST (test_no_framerate)
497 GstElement *videorate;
501 videorate = setup_videorate ();
502 fail_unless (gst_element_set_state (videorate,
503 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
504 "could not set to playing");
506 inbuffer = gst_buffer_new_and_alloc (4);
507 gst_buffer_memset (inbuffer, 0, 0, 4);
508 caps = gst_caps_from_string (VIDEO_CAPS_NO_FRAMERATE_STRING);
509 gst_pad_set_caps (mysrcpad, caps);
510 gst_caps_unref (caps);
511 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
513 /* take a ref so we can later check refcount */
514 gst_buffer_ref (inbuffer);
516 /* no framerate is negotiated so pushing should fail */
517 fail_if (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
518 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
519 gst_buffer_unref (inbuffer);
520 fail_unless_equals_int (g_list_length (buffers), 0);
523 cleanup_videorate (videorate);
528 /* This test outputs 2 buffers of same dimensions (320x240), then 1 buffer of
529 * differing dimensions (240x120), and then another buffer of previous
530 * dimensions (320x240) and checks that the 3 buffers output as a result have
531 * correct caps (first 2 with 320x240 and 3rd with 240x120).
533 GST_START_TEST (test_changing_size)
535 GstElement *videorate;
542 GstEvent *newsegment;
543 GstCaps *caps, *caps_newsize;
546 videorate = setup_videorate ();
547 fail_unless (gst_element_set_state (videorate,
548 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
549 "could not set to playing");
551 gst_segment_init (&segment, GST_FORMAT_TIME);
552 newsegment = gst_event_new_segment (&segment);
553 fail_unless (gst_pad_push_event (mysrcpad, newsegment) == TRUE);
555 first = gst_buffer_new_and_alloc (4);
556 gst_buffer_memset (first, 0, 0, 4);
557 caps = gst_caps_from_string (VIDEO_CAPS_STRING);
558 GST_BUFFER_TIMESTAMP (first) = 0;
559 gst_pad_set_caps (mysrcpad, caps);
561 GST_DEBUG ("pushing first buffer");
562 fail_unless (gst_pad_push (mysrcpad, first) == GST_FLOW_OK);
565 second = gst_buffer_new_and_alloc (4);
566 GST_BUFFER_TIMESTAMP (second) = GST_SECOND / 25;
567 gst_buffer_memset (second, 0, 0, 4);
569 fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK);
570 fail_unless_equals_int (g_list_length (buffers), 1);
571 outbuf = buffers->data;
572 /* first buffer should be output here */
573 fail_unless (GST_BUFFER_TIMESTAMP (outbuf) == 0);
575 /* third buffer with new size */
576 third = gst_buffer_new_and_alloc (4);
577 GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND / 25;
578 gst_buffer_memset (third, 0, 0, 4);
579 caps_newsize = gst_caps_from_string (VIDEO_CAPS_NEWSIZE_STRING);
580 gst_pad_set_caps (mysrcpad, caps_newsize);
582 fail_unless (gst_pad_push (mysrcpad, third) == GST_FLOW_OK);
583 /* new caps flushed the internal state, no new output yet */
584 fail_unless_equals_int (g_list_length (buffers), 1);
585 outbuf = g_list_last (buffers)->data;
586 /* first buffer should be output here */
587 //fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (outbuf), caps));
588 fail_unless (GST_BUFFER_TIMESTAMP (outbuf) == 0);
590 /* fourth buffer with original size */
591 fourth = gst_buffer_new_and_alloc (4);
592 GST_BUFFER_TIMESTAMP (fourth) = 3 * GST_SECOND / 25;
593 gst_buffer_memset (fourth, 0, 0, 4);
594 gst_pad_set_caps (mysrcpad, caps);
596 fail_unless (gst_pad_push (mysrcpad, fourth) == GST_FLOW_OK);
597 fail_unless_equals_int (g_list_length (buffers), 1);
599 /* fifth buffer with original size */
600 fifth = gst_buffer_new_and_alloc (4);
601 GST_BUFFER_TIMESTAMP (fifth) = 4 * GST_SECOND / 25;
602 gst_buffer_memset (fifth, 0, 0, 4);
604 fail_unless (gst_pad_push (mysrcpad, fifth) == GST_FLOW_OK);
605 /* all four missing buffers here, dups of fourth buffer */
606 fail_unless_equals_int (g_list_length (buffers), 4);
607 outbuf = g_list_last (buffers)->data;
608 /* third buffer should be output here */
609 fail_unless (GST_BUFFER_TIMESTAMP (outbuf) == 3 * GST_SECOND / 25);
610 //fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (outbuf), caps));
612 gst_caps_unref (caps);
613 gst_caps_unref (caps_newsize);
614 cleanup_videorate (videorate);
619 GST_START_TEST (test_non_ok_flow)
621 GstElement *videorate;
626 videorate = setup_videorate ();
627 fail_unless (gst_element_set_state (videorate,
628 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
629 "could not set to playing");
631 buf = gst_buffer_new_and_alloc (4);
632 gst_buffer_memset (buf, 0, 0, 4);
633 caps = gst_caps_from_string (VIDEO_CAPS_STRING);
634 gst_pad_set_caps (mysrcpad, caps);
635 gst_caps_unref (caps);
636 ASSERT_BUFFER_REFCOUNT (buf, "inbuffer", 1);
638 /* push a few 'normal' buffers */
639 for (ts = 0; ts < 100 * GST_SECOND; ts += GST_SECOND / 33) {
642 inbuf = gst_buffer_copy (buf);
643 GST_BUFFER_TIMESTAMP (inbuf) = ts;
645 fail_unless_equals_int (gst_pad_push (mysrcpad, inbuf), GST_FLOW_OK);
648 /* we should have buffers according to the output framerate of 25/1 */
649 fail_unless_equals_int (g_list_length (buffers), 100 * 25);
651 /* now deactivate pad so we get a WRONG_STATE flow return */
652 gst_pad_set_active (mysinkpad, FALSE);
654 /* push buffer on deactivated pad */
655 fail_unless (gst_buffer_is_writable (buf));
656 GST_BUFFER_TIMESTAMP (buf) = ts;
658 /* pushing gives away our reference */
659 fail_unless_equals_int (gst_pad_push (mysrcpad, buf), GST_FLOW_FLUSHING);
662 cleanup_videorate (videorate);
667 GST_START_TEST (test_upstream_caps_nego)
669 GstElement *videorate;
670 GstPad *videorate_pad;
671 GstCaps *expected_caps;
673 GstStructure *structure;
675 videorate = setup_videorate_full (&srctemplate, &downstreamsinktemplate);
676 fail_unless (gst_element_set_state (videorate,
677 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
678 "could not set to playing");
680 videorate_pad = gst_element_get_static_pad (videorate, "sink");
681 caps = gst_pad_query_caps (videorate_pad, NULL);
683 /* assemble the expected caps */
684 structure = gst_structure_from_string (VIDEO_CAPS_STRING, NULL);
685 expected_caps = gst_caps_new_empty ();
686 gst_caps_append_structure (expected_caps, structure);
687 structure = gst_structure_copy (structure);
688 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION_RANGE,
689 0, 1, G_MAXINT, 1, NULL);
690 gst_caps_append_structure (expected_caps, structure);
692 fail_unless (gst_caps_is_equal (expected_caps, caps));
693 gst_caps_unref (caps);
694 gst_caps_unref (expected_caps);
695 gst_object_unref (videorate_pad);
698 cleanup_videorate (videorate);
704 GST_START_TEST (test_selected_caps)
706 GstElement *videorate;
707 GstElement *pipeline;
711 pipeline = gst_parse_launch ("videotestsrc num-buffers=1"
712 " ! identity ! videorate name=videorate0 ! " VIDEO_CAPS_UNUSUAL_FRAMERATE
713 " ! fakesink", NULL);
714 fail_if (pipeline == NULL);
715 videorate = gst_bin_get_by_name (GST_BIN (pipeline), "videorate0");
716 fail_if (videorate == NULL);
717 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
719 fail_if (gst_element_set_state (pipeline,
720 GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE,
721 "could not set to playing");
723 msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
724 GST_MESSAGE_EOS | GST_MESSAGE_ERROR);
725 fail_if (msg == NULL || GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
727 /* make sure upstream nego works right and videotestsrc has selected the
728 * caps we want downstream of videorate */
732 GstCaps *caps = NULL;
733 GstPad *videorate_pad;
735 videorate_pad = gst_element_get_static_pad (videorate, "sink");
736 g_object_get (videorate_pad, "caps", &caps, NULL);
737 fail_unless (caps != NULL);
739 GST_DEBUG ("negotiated caps: %" GST_PTR_FORMAT, caps);
741 s = gst_caps_get_structure (caps, 0);
742 val = gst_structure_get_value (s, "framerate");
743 fail_unless (val != NULL, "no framerate field in negotiated caps");
744 fail_unless (GST_VALUE_HOLDS_FRACTION (val));
745 fail_unless_equals_int (gst_value_get_fraction_numerator (val), 999);
746 fail_unless_equals_int (gst_value_get_fraction_denominator (val), 7);
748 gst_caps_unref (caps);
749 gst_object_unref (videorate_pad);
753 gst_object_unref (bus);
754 gst_message_unref (msg);
755 gst_element_set_state (pipeline, GST_STATE_NULL);
756 gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
757 gst_object_unref (videorate);
758 gst_object_unref (pipeline);
764 /* Caps negotiation tests */
770 /* Result of the videomaxrate caps after transforming */
771 const gchar *expected_sink_caps;
772 const gchar *expected_src_caps;
775 static TestInfo caps_negotiation_tests[] = {
777 .caps = "video/x-raw",
779 .expected_sink_caps = "video/x-raw",
780 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]"},
782 .caps = "video/x-raw",
785 .expected_sink_caps = "video/x-raw",
786 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, 15]"},
788 .caps = "video/x-raw",
790 .expected_sink_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
791 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]"},
793 .caps = "video/x-raw",
796 .expected_sink_caps =
797 "video/x-raw, framerate=(fraction)[0/1, 15];"
798 "video/x-raw, framerate=(fraction)[0/1, MAX]",
799 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, 15]"},
803 .caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
805 .expected_sink_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
806 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]"},
808 .caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
811 .expected_sink_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
812 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, 15]"},
814 .caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
816 .expected_sink_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
817 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, MAX]"},
819 .caps = "video/x-raw, framerate=(fraction)[0/1, MAX]",
822 .expected_sink_caps =
823 "video/x-raw, framerate=(fraction)[0/1, 15];"
824 "video/x-raw, framerate=(fraction)[0/1, MAX]",
825 .expected_src_caps = "video/x-raw, framerate=(fraction)[0/1, 15]"},
827 .caps = "video/x-raw, framerate=15/1",
829 .expected_sink_caps =
830 "video/x-raw, framerate=(fraction)15/1;"
831 "video/x-raw, framerate=(fraction)[0/1, MAX]",
833 "video/x-raw, framerate=(fraction)15/1;"
834 "video/x-raw, framerate=(fraction)[0/1, MAX]"},
836 .caps = "video/x-raw, framerate=15/1",
839 .expected_sink_caps =
840 "video/x-raw, framerate=(fraction)15/1;"
841 "video/x-raw, framerate=(fraction)[0/1, MAX]",
843 "video/x-raw, framerate=(fraction)15/1;"
844 "video/x-raw, framerate=(fraction)[0/1, 20/1]"},
846 .caps = "video/x-raw, framerate=15/1",
848 .expected_sink_caps =
849 "video/x-raw, framerate=(fraction)15/1;"
850 "video/x-raw, framerate=(fraction)[15/1, MAX];"
851 "video/x-raw, framerate=(fraction)0/1",
853 "video/x-raw, framerate=(fraction)15/1;"
854 "video/x-raw, framerate=(fraction)[0/1, 15/1]"},
856 .caps = "video/x-raw, framerate=15/1",
859 .expected_sink_caps =
860 "video/x-raw, framerate=(fraction)15/1;"
861 "video/x-raw, framerate=(fraction)[15/1, MAX];"
862 "video/x-raw, framerate=(fraction)0/1",
864 "video/x-raw, framerate=(fraction)15/1;"
865 "video/x-raw, framerate=(fraction)[0/1, 15/1];"},
867 .caps = "video/x-raw, framerate=[15/1, 30/1]",
869 .expected_sink_caps =
870 "video/x-raw, framerate=(fraction)[15/1, 30/1];"
871 "video/x-raw, framerate=(fraction)[0/1, MAX];",
873 "video/x-raw, framerate=(fraction)[15/1, 30/1];"
874 "video/x-raw, framerate=(fraction)[0/1, MAX];"},
876 .caps = "video/x-raw, framerate=[15/1, 30/1]",
879 .expected_sink_caps =
880 "video/x-raw, framerate=(fraction)[15/1, 30/1];"
881 "video/x-raw, framerate=(fraction)[0/1, MAX];",
883 "video/x-raw, framerate=(fraction)[15/1, 20/1];"
884 "video/x-raw, framerate=(fraction)[0/1, 20/1];"},
886 .caps = "video/x-raw, framerate=[15/1, 30/1]",
888 .expected_sink_caps =
889 "video/x-raw, framerate=(fraction)[15/1, 30/1];"
890 "video/x-raw, framerate=(fraction)[15/1, MAX];"
891 "video/x-raw, framerate=(fraction)0/1",
893 "video/x-raw, framerate=(fraction)[15/1, 30/1];"
894 "video/x-raw, framerate=(fraction)[0/1, 30/1]"},
896 .caps = "video/x-raw, framerate=[15/1, 30/1]",
899 .expected_sink_caps =
900 "video/x-raw, framerate=(fraction)[15/1, 20/1];"
901 "video/x-raw, framerate=(fraction)[15/1, 30/1];"
902 "video/x-raw, framerate=(fraction)[15/1, MAX];"
903 "video/x-raw, framerate=(fraction)0/1",
905 "video/x-raw, framerate=(fraction)[15/1, 20/1];"
906 "video/x-raw, framerate=(fraction)[0/1, 20/1]"},
908 .caps = "video/x-raw, framerate={15/1, 30/1}",
910 .expected_sink_caps =
911 "video/x-raw, framerate=(fraction){15/1, 30/1};"
912 "video/x-raw, framerate=(fraction)[0/1, MAX];",
914 "video/x-raw, framerate=(fraction){15/1, 30/1};"
915 "video/x-raw, framerate=(fraction)[0/1, MAX]"},
917 .caps = "video/x-raw, framerate={15/1, 30/1}",
920 .expected_sink_caps =
921 "video/x-raw, framerate=(fraction){15/1, 30/1};"
922 "video/x-raw, framerate=(fraction)[0/1, MAX];",
924 "video/x-raw, framerate=(fraction)15/1;"
925 "video/x-raw, framerate=(fraction)[0/1, 20/1];"},
927 .caps = "video/x-raw, framerate={15/1, 30/1}",
929 .expected_sink_caps =
930 "video/x-raw, framerate=(fraction){15/1, 30/1};"
931 "video/x-raw, framerate=(fraction)[15/1, MAX];"
932 "video/x-raw, framerate=(fraction)0/1",
934 "video/x-raw, framerate=(fraction){15/1, 30/1};"
935 "video/x-raw, framerate=(fraction)[0/1, 30/1];"},
937 .caps = "video/x-raw, framerate={15/1, 30/1}",
940 .expected_sink_caps =
941 "video/x-raw, framerate=(fraction)15/1;"
942 "video/x-raw, framerate=(fraction){15/1, 30/1};"
943 "video/x-raw, framerate=(fraction)[15/1, MAX];"
944 "video/x-raw, framerate=(fraction)0/1",
946 "video/x-raw, framerate=(fraction)15/1;"
947 "video/x-raw, framerate=(fraction)[0/1, 20/1]"},
951 _query_function (GstPad * pad, GstObject * parent, GstQuery * query)
955 switch (GST_QUERY_TYPE (query)) {
956 case GST_QUERY_CAPS:{
957 GstCaps *caps = g_object_get_data (G_OBJECT (pad), "caps");
959 fail_unless (caps != NULL);
961 gst_query_set_caps_result (query, caps);
966 res = gst_pad_query_default (pad, parent, query);
973 check_caps_identical (GstCaps * a, GstCaps * b, const char *name)
977 if (gst_caps_get_size (a) != gst_caps_get_size (b))
980 for (i = 0; i < gst_caps_get_size (a); i++) {
981 GstStructure *sa, *sb;
983 sa = gst_caps_get_structure (a, i);
984 sb = gst_caps_get_structure (b, i);
986 if (!gst_structure_is_equal (sa, sb))
993 fail ("%s caps (%s) is not equal to caps (%s)",
994 name, gst_caps_to_string (a), gst_caps_to_string (b));
998 check_peer_caps (GstPad * pad, const char *expected, const char *name)
1001 GstCaps *expected_caps;
1003 caps = gst_pad_peer_query_caps (pad, NULL);
1004 fail_unless (caps != NULL);
1006 expected_caps = gst_caps_from_string (expected);
1007 fail_unless (expected_caps != NULL);
1009 check_caps_identical (caps, expected_caps, name);
1011 gst_caps_unref (caps);
1012 gst_caps_unref (expected_caps);
1015 GST_START_TEST (test_caps_negotiation)
1017 GstElement *videorate;
1019 TestInfo *test = &caps_negotiation_tests[__i__];
1021 videorate = setup_videorate_full (&srctemplate, &sinktemplate);
1023 caps = gst_caps_from_string (test->caps);
1024 g_object_set_data_full (G_OBJECT (mysrcpad), "caps",
1025 gst_caps_ref (caps), (GDestroyNotify) gst_caps_unref);
1026 g_object_set_data_full (G_OBJECT (mysinkpad), "caps",
1027 gst_caps_ref (caps), (GDestroyNotify) gst_caps_unref);
1028 gst_caps_unref (caps);
1030 g_object_set (videorate, "drop-only", test->drop_only, NULL);
1031 if (test->max_rate != 0)
1032 g_object_set (videorate, "max-rate", test->max_rate, NULL);
1034 gst_pad_set_query_function (mysrcpad, _query_function);
1035 gst_pad_set_query_function (mysinkpad, _query_function);
1037 check_peer_caps (mysrcpad, test->expected_sink_caps, "sink");
1038 check_peer_caps (mysinkpad, test->expected_src_caps, "src");
1040 gst_object_unref (videorate);
1046 videorate_suite (void)
1048 Suite *s = suite_create ("videorate");
1049 TCase *tc_chain = tcase_create ("general");
1051 suite_add_tcase (s, tc_chain);
1052 tcase_add_test (tc_chain, test_one);
1053 tcase_add_test (tc_chain, test_more);
1054 tcase_add_test (tc_chain, test_wrong_order_from_zero);
1055 tcase_add_test (tc_chain, test_wrong_order);
1056 tcase_add_test (tc_chain, test_no_framerate);
1057 tcase_add_test (tc_chain, test_changing_size);
1058 tcase_add_test (tc_chain, test_non_ok_flow);
1059 tcase_add_test (tc_chain, test_upstream_caps_nego);
1060 tcase_add_test (tc_chain, test_selected_caps);
1061 tcase_add_loop_test (tc_chain, test_caps_negotiation,
1062 0, G_N_ELEMENTS (caps_negotiation_tests));
1067 GST_CHECK_MAIN (videorate)