1 /* GStreamer
2  *
3  * unit test for shm elements
4  * Copyright (C) 2013 Collabora Ltd
5  *   @author: Olivier Crete <olivier.crete@collabora.com>
6  *
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.
11  *
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.
16  *
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.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <gst/gst.h>
28 #include <gst/check/gstcheck.h>
29 
30 
31 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
32     GST_PAD_SINK,
33     GST_PAD_ALWAYS,
34     GST_STATIC_CAPS_ANY);
35 
36 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
37     GST_PAD_SRC,
38     GST_PAD_ALWAYS,
39     GST_STATIC_CAPS_ANY);
40 
41 GstElement *src, *sink;
42 GstPad *sinkpad, *srcpad;
43 
44 static void
setup_shm(void)45 setup_shm (void)
46 {
47   gchar *socket_path = NULL;
48 
49   sink = gst_check_setup_element ("shmsink");
50   src = gst_check_setup_element ("shmsrc");
51 
52   srcpad = gst_check_setup_src_pad (sink, &src_template);
53   sinkpad = gst_check_setup_sink_pad (src, &sink_template);
54 
55   g_object_set (sink, "socket-path", "shm-unit-test", NULL);
56 
57   fail_unless (gst_element_set_state (sink, GST_STATE_PLAYING) ==
58       GST_STATE_CHANGE_ASYNC);
59 
60   g_object_get (sink, "socket-path", &socket_path, NULL);
61   fail_unless (socket_path != NULL);
62   g_object_set (src, "socket-path", socket_path, NULL);
63   g_free (socket_path);
64 
65   gst_pad_set_active (srcpad, TRUE);
66   gst_pad_set_active (sinkpad, TRUE);
67 
68   fail_unless (gst_element_set_state (src, GST_STATE_PLAYING) ==
69       GST_STATE_CHANGE_SUCCESS);
70 }
71 
72 static void
teardown_shm(void)73 teardown_shm (void)
74 {
75   fail_unless (gst_element_set_state (src, GST_STATE_NULL) ==
76       GST_STATE_CHANGE_SUCCESS);
77   gst_check_teardown_sink_pad (src);
78   gst_check_teardown_src_pad (sink);
79   gst_check_teardown_element (src);
80   gst_check_teardown_element (sink);
81 }
82 
GST_START_TEST(test_shm_sysmem_alloc)83 GST_START_TEST (test_shm_sysmem_alloc)
84 {
85   GstBuffer *buf;
86   GstState state, pending;
87   GstSegment segment;
88 
89   gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
90   gst_segment_init (&segment, GST_FORMAT_BYTES);
91   gst_pad_push_event (srcpad, gst_event_new_segment (&segment));
92 
93   buf = gst_buffer_new_allocate (NULL, 1000, NULL);
94 
95   fail_unless (gst_pad_push (srcpad, buf) == GST_FLOW_OK);
96 
97   fail_unless (gst_element_get_state (sink, &state, &pending,
98           GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_SUCCESS);
99   fail_unless (state == GST_STATE_PLAYING);
100   fail_unless (pending == GST_STATE_VOID_PENDING);
101 
102   g_mutex_lock (&check_mutex);
103   while (buffers == NULL)
104     g_cond_wait (&check_cond, &check_mutex);
105   g_mutex_unlock (&check_mutex);
106   fail_unless (g_list_length (buffers) == 1);
107 
108   buf = buffers->data;
109   fail_unless (gst_buffer_get_size (buf) == 1000);
110 
111   gst_check_drop_buffers ();
112   teardown_shm ();
113 }
114 
115 GST_END_TEST;
116 
117 
GST_START_TEST(test_shm_alloc)118 GST_START_TEST (test_shm_alloc)
119 {
120   GstBuffer *buf;
121   GstQuery *query;
122   GstCaps *caps = gst_caps_new_empty_simple ("application/x-test");
123   GstAllocator *alloc;
124   GstAllocationParams params;
125   guint size;
126   GstSegment segment;
127 
128   gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
129   gst_pad_push_event (srcpad, gst_event_new_caps (caps));
130   gst_segment_init (&segment, GST_FORMAT_BYTES);
131   gst_pad_push_event (srcpad, gst_event_new_segment (&segment));
132 
133   query = gst_query_new_allocation (caps, FALSE);
134   gst_caps_unref (caps);
135 
136   fail_unless (gst_pad_peer_query (srcpad, query));
137 
138   fail_unless (gst_query_get_n_allocation_params (query) == 1);
139 
140   gst_query_parse_nth_allocation_param (query, 0, &alloc, &params);
141   fail_unless (alloc != NULL);
142   gst_query_unref (query);
143 
144   g_object_get (sink, "shm-size", &size, NULL);
145 
146   size -= params.align | gst_memory_alignment;
147 
148   /* alloc buffer of max size, this way, it will block forever it a copy
149    * is made inside shmsink*/
150   buf = gst_buffer_new_allocate (alloc, size, &params);
151 
152   gst_object_unref (alloc);
153 
154   fail_unless (gst_pad_push (srcpad, buf) == GST_FLOW_OK);
155 
156 
157   g_mutex_lock (&check_mutex);
158   while (buffers == NULL)
159     g_cond_wait (&check_cond, &check_mutex);
160   g_mutex_unlock (&check_mutex);
161   fail_unless (g_list_length (buffers) == 1);
162 
163   buf = buffers->data;
164   fail_unless (gst_buffer_get_size (buf) == size);
165 
166   gst_check_drop_buffers ();
167   teardown_shm ();
168 }
169 
170 GST_END_TEST;
171 
GST_START_TEST(test_shm_live)172 GST_START_TEST (test_shm_live)
173 {
174   GstElement *producer, *consumer;
175   GstElement *src, *sink;
176   gchar *socket_path = NULL;
177   GstStateChangeReturn state_res;
178   GstSample *sample = NULL;
179 
180   src = gst_element_factory_make ("fakesrc", NULL);
181   g_object_set (src, "sizetype", 2, NULL);
182 
183   sink = gst_element_factory_make ("shmsink", NULL);
184   g_object_set (sink, "socket-path", "shm-unit-test", "wait-for-connection",
185       FALSE, NULL);
186 
187   producer = gst_pipeline_new ("producer-pipeline");
188   gst_bin_add_many (GST_BIN (producer), src, sink, NULL);
189   fail_unless (gst_element_link (src, sink));
190 
191   state_res = gst_element_set_state (producer, GST_STATE_PLAYING);
192   fail_unless (state_res != GST_STATE_CHANGE_FAILURE);
193 
194   g_object_get (sink, "socket-path", &socket_path, NULL);
195   fail_unless (socket_path != NULL);
196 
197   src = gst_element_factory_make ("shmsrc", NULL);
198   sink = gst_element_factory_make ("appsink", NULL);
199   g_object_set (src, "is-live", TRUE, NULL);
200   g_object_set (sink, "async", FALSE, "enable-last-sample", FALSE, NULL);
201 
202   consumer = gst_pipeline_new ("consumer-pipeline");
203   gst_bin_add_many (GST_BIN (consumer), src, sink, NULL);
204   fail_unless (gst_element_link (src, sink));
205 
206   g_object_set (src, "socket-path", socket_path, NULL);
207 
208   state_res = gst_element_set_state (consumer, GST_STATE_PLAYING);
209   fail_unless (state_res != GST_STATE_CHANGE_FAILURE);
210 
211   /* wait for preroll */
212   state_res = gst_element_get_state (consumer, NULL, NULL, GST_CLOCK_TIME_NONE);
213   fail_unless (state_res == GST_STATE_CHANGE_SUCCESS);
214 
215   g_signal_emit_by_name (sink, "pull-sample", &sample);
216   gst_sample_unref (sample);
217 
218   state_res = gst_element_set_state (consumer, GST_STATE_NULL);
219   fail_unless (state_res != GST_STATE_CHANGE_FAILURE);
220 
221   state_res = gst_element_set_state (producer, GST_STATE_NULL);
222   fail_unless (state_res != GST_STATE_CHANGE_FAILURE);
223 
224   gst_object_unref (consumer);
225   gst_object_unref (producer);
226 
227   g_free (socket_path);
228 }
229 
230 GST_END_TEST;
231 
232 static Suite *
shm_suite(void)233 shm_suite (void)
234 {
235   Suite *s = suite_create ("shm");
236   TCase *tc;
237 
238   tc = tcase_create ("shm");
239   tcase_add_checked_fixture (tc, setup_shm, NULL);
240   tcase_add_test (tc, test_shm_sysmem_alloc);
241   tcase_add_test (tc, test_shm_alloc);
242   suite_add_tcase (s, tc);
243 
244   tc = tcase_create ("shm2");
245   tcase_add_test (tc, test_shm_live);
246   suite_add_tcase (s, tc);
247 
248   return s;
249 }
250 
251 
252 GST_CHECK_MAIN (shm);
253