1 /* GStreamer
2 *
3 * unit test for identity
4 *
5 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
6 * Copyright (C) <2015> Havard Graff <havard@pexip.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gst/check/gstcheck.h>
28 #include <gst/check/gstharness.h>
29
GST_START_TEST(test_one_buffer)30 GST_START_TEST (test_one_buffer)
31 {
32 GstHarness *h = gst_harness_new ("identity");
33 GstBuffer *buffer_in;
34 GstBuffer *buffer_out;
35
36 gst_harness_set_src_caps_str (h, "mycaps");
37
38 buffer_in = gst_buffer_new_and_alloc (4);
39 ASSERT_BUFFER_REFCOUNT (buffer_in, "buffer", 1);
40
41 gst_buffer_fill (buffer_in, 0, "data", 4);
42
43 /* pushing gives away my reference ... */
44 fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));
45
46 /* ... but it should end up being collected on GstHarness queue */
47 fail_unless_equals_int (1, gst_harness_buffers_in_queue (h));
48 buffer_out = gst_harness_pull (h);
49
50 fail_unless (buffer_in == buffer_out);
51 ASSERT_BUFFER_REFCOUNT (buffer_out, "buffer", 1);
52
53 /* cleanup */
54 gst_buffer_unref (buffer_out);
55 gst_harness_teardown (h);
56 }
57
58 GST_END_TEST;
59
60 static void
handoff_func(GstElement * identity,GstBuffer * buf,GstBuffer ** ret)61 handoff_func (GstElement * identity, GstBuffer * buf, GstBuffer ** ret)
62 {
63 (void) identity;
64 *ret = buf;
65 }
66
GST_START_TEST(test_signal_handoffs)67 GST_START_TEST (test_signal_handoffs)
68 {
69 GstHarness *h = gst_harness_new ("identity");
70 GstBuffer *buffer_in;
71 GstBuffer *buffer_signaled = NULL;
72 gst_harness_set_src_caps_str (h, "mycaps");
73
74 /* connect to the handoff signal */
75 g_signal_connect (h->element, "handoff",
76 G_CALLBACK (handoff_func), &buffer_signaled);
77
78 /* first, turn off signal-handoffs */
79 g_object_set (h->element, "signal-handoffs", FALSE, NULL);
80
81 /* then push a buffer */
82 buffer_in = gst_buffer_new_and_alloc (4);
83 fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));
84
85 /* verify that we got no buffer signaled */
86 fail_unless (buffer_signaled == NULL);
87
88 /* now turn on signal-handoffs */
89 g_object_set (h->element, "signal-handoffs", TRUE, NULL);
90
91 /* then push another buffer */
92 buffer_in = gst_buffer_new_and_alloc (4);
93 fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));
94
95 /* verify the buffer signaled is equal to the one pushed in */
96 fail_unless (buffer_signaled == buffer_in);
97 ASSERT_BUFFER_REFCOUNT (buffer_signaled, "buffer", 1);
98
99 /* cleanup */
100 gst_harness_teardown (h);
101 }
102
103 GST_END_TEST;
104
GST_START_TEST(test_sync_on_timestamp)105 GST_START_TEST (test_sync_on_timestamp)
106 {
107 /* the reason to use the queue in front of the identity element
108 is to effectively make gst_harness_push asynchronous, not locking
109 up the test, waiting for gst_clock_id_wait */
110 GstHarness *h = gst_harness_new_parse ("queue ! identity sync=1");
111 GstBuffer *buf;
112 GstClock *clock;
113 GstClockTime timestamp = 123456789;
114
115 /* use testclock */
116 gst_harness_use_testclock (h);
117 gst_harness_set_src_caps_str (h, "mycaps");
118
119 /* make a buffer and set the timestamp */
120 buf = gst_buffer_new ();
121 GST_BUFFER_PTS (buf) = timestamp;
122
123 /* push the buffer, and verify it does *not* make it through */
124 gst_harness_push (h, buf);
125 fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
126
127 /* verify the identity element has registered exactly one GstClockID */
128 fail_unless (gst_harness_wait_for_clock_id_waits (h, 1, 42));
129
130 /* crank the clock and pull the buffer */
131 gst_harness_crank_single_clock_wait (h);
132 buf = gst_harness_pull (h);
133
134 /* verify that the buffer has the right timestamp, and that the time on
135 the clock is equal to the timestamp */
136 fail_unless_equals_int64 (timestamp, GST_BUFFER_PTS (buf));
137 clock = gst_element_get_clock (h->element);
138 fail_unless_equals_int64 (timestamp, gst_clock_get_time (clock));
139
140 /* cleanup */
141 gst_object_unref (clock);
142 gst_buffer_unref (buf);
143 gst_harness_teardown (h);
144 }
145
146 GST_END_TEST;
147
GST_START_TEST(test_stopping_element_unschedules_sync)148 GST_START_TEST (test_stopping_element_unschedules_sync)
149 {
150 /* the reason to use the queue in front of the identity element
151 is to effectively make gst_harness_push asynchronous, not locking
152 up the test, waiting for gst_clock_id_wait */
153 GstHarness *h = gst_harness_new_parse ("queue ! identity sync=1");
154 GstBuffer *buf;
155 GstClockTime timestamp = 123456789;
156
157 /* use testclock */
158 gst_harness_use_testclock (h);
159 gst_harness_set_src_caps_str (h, "mycaps");
160
161 /* make a buffer and set the timestamp */
162 buf = gst_buffer_new ();
163 GST_BUFFER_PTS (buf) = timestamp;
164
165 /* push the buffer, and verify it does *not* make it through */
166 gst_harness_push (h, buf);
167 fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
168
169 /* verify the identity element has registered exactly one GstClockID */
170 fail_unless (gst_harness_wait_for_clock_id_waits (h, 1, 42));
171
172 /* setting identity to READY should unschedule the sync */
173 gst_element_set_state (h->element, GST_STATE_READY);
174
175 /* verify the identity element no longer waits on the clock */
176 fail_unless (gst_harness_wait_for_clock_id_waits (h, 0, 42));
177
178 /* and that the waiting buffer was dropped */
179 fail_unless_equals_int (0, gst_harness_buffers_received (h));
180
181 gst_harness_teardown (h);
182 }
183
184 GST_END_TEST;
185
186 static Suite *
identity_suite(void)187 identity_suite (void)
188 {
189 Suite *s = suite_create ("identity");
190 TCase *tc_chain = tcase_create ("general");
191
192 suite_add_tcase (s, tc_chain);
193 tcase_add_test (tc_chain, test_one_buffer);
194 tcase_add_test (tc_chain, test_signal_handoffs);
195 tcase_add_test (tc_chain, test_sync_on_timestamp);
196 tcase_add_test (tc_chain, test_stopping_element_unschedules_sync);
197
198
199 return s;
200 }
201
202 GST_CHECK_MAIN (identity);
203