• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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