0f6549be3e7ccba8e142e2068866232ea2351214
[platform/upstream/gstreamer.git] / tests / check / elements / filesrc.c
1 /* GStreamer
2  *
3  * Copyright (C) 2006 Thomas Vander Stichele <thomas at apestaart dot org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25
26 #include <gst/check/gstcheck.h>
27
28 gboolean have_eos = FALSE;
29
30 GstPad *mysinkpad;
31
32 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
33     GST_PAD_SINK,
34     GST_PAD_ALWAYS,
35     GST_STATIC_CAPS_ANY);
36
37 gboolean
38 event_func (GstPad * pad, GstEvent * event)
39 {
40   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
41     have_eos = TRUE;
42     gst_event_unref (event);
43     return TRUE;
44   }
45
46   gst_event_unref (event);
47   return FALSE;
48 }
49
50 GstElement *
51 setup_filesrc ()
52 {
53   GstElement *filesrc;
54
55   GST_DEBUG ("setup_filesrc");
56   filesrc = gst_check_setup_element ("filesrc");
57   mysinkpad = gst_check_setup_sink_pad (filesrc, &sinktemplate, NULL);
58   gst_pad_set_event_function (mysinkpad, event_func);
59   gst_pad_set_active (mysinkpad, TRUE);
60   return filesrc;
61 }
62
63 void
64 cleanup_filesrc (GstElement * filesrc)
65 {
66   gst_pad_set_active (mysinkpad, FALSE);
67   gst_check_teardown_sink_pad (filesrc);
68   gst_check_teardown_element (filesrc);
69 }
70
71 GST_START_TEST (test_seeking)
72 {
73   GstElement *src;
74   GstQuery *seeking_query;
75   gboolean seekable;
76
77 #ifndef TESTFILE
78 #error TESTFILE not defined
79 #endif
80   src = setup_filesrc ();
81
82   g_object_set (G_OBJECT (src), "location", TESTFILE, NULL);
83   fail_unless (gst_element_set_state (src,
84           GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS,
85       "could not set to paused");
86
87   /* Test that filesrc is seekable with a file fd */
88   fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES))
89       != NULL);
90   fail_unless (gst_element_query (src, seeking_query) == TRUE);
91   gst_query_parse_seeking (seeking_query, NULL, &seekable, NULL, NULL);
92   fail_unless (seekable == TRUE);
93   gst_query_unref (seeking_query);
94
95   fail_unless (gst_element_set_state (src,
96           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
97
98   /* cleanup */
99   cleanup_filesrc (src);
100 }
101
102 GST_END_TEST;
103
104 GST_START_TEST (test_pull)
105 {
106   GstElement *src;
107   GstQuery *seeking_query;
108   gboolean res, seekable;
109   gint64 start, stop;
110   GstPad *pad;
111   GstFlowReturn ret;
112   GstBuffer *buffer1, *buffer2;
113
114   src = setup_filesrc ();
115
116   g_object_set (G_OBJECT (src), "location", TESTFILE, NULL);
117   fail_unless (gst_element_set_state (src,
118           GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
119       "could not set to ready");
120
121   /* get the source pad */
122   pad = gst_element_get_pad (src, "src");
123   fail_unless (pad != NULL);
124
125   /* activate the pad in pull mode */
126   res = gst_pad_activate_pull (pad, TRUE);
127   fail_unless (res == TRUE);
128
129   /* not start playing */
130   fail_unless (gst_element_set_state (src,
131           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
132       "could not set to paused");
133
134   /* Test that filesrc is seekable with a file fd */
135   fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES))
136       != NULL);
137   fail_unless (gst_element_query (src, seeking_query) == TRUE);
138
139   /* get the seeking capabilities */
140   gst_query_parse_seeking (seeking_query, NULL, &seekable, &start, &stop);
141   fail_unless (seekable == TRUE);
142   fail_unless (start == 0);
143   fail_unless (start != -1);
144   gst_query_unref (seeking_query);
145
146   /* do some pulls */
147   ret = gst_pad_get_range (pad, 0, 100, &buffer1);
148   fail_unless (ret == GST_FLOW_OK);
149   fail_unless (buffer1 != NULL);
150   fail_unless (GST_BUFFER_SIZE (buffer1) == 100);
151
152   ret = gst_pad_get_range (pad, 0, 50, &buffer2);
153   fail_unless (ret == GST_FLOW_OK);
154   fail_unless (buffer2 != NULL);
155   fail_unless (GST_BUFFER_SIZE (buffer2) == 50);
156
157   /* this should be the same */
158   fail_unless (memcmp (GST_BUFFER_DATA (buffer1), GST_BUFFER_DATA (buffer2),
159           50) == 0);
160
161   gst_buffer_unref (buffer2);
162
163   /* read next 50 bytes */
164   ret = gst_pad_get_range (pad, 50, 50, &buffer2);
165   fail_unless (ret == GST_FLOW_OK);
166   fail_unless (buffer2 != NULL);
167   fail_unless (GST_BUFFER_SIZE (buffer2) == 50);
168
169   /* compare with previously read data */
170   fail_unless (memcmp (GST_BUFFER_DATA (buffer1) + 50,
171           GST_BUFFER_DATA (buffer2), 50) == 0);
172
173   gst_buffer_unref (buffer1);
174   gst_buffer_unref (buffer2);
175
176   /* read 10 bytes at end-10 should give exactly 10 bytes */
177   ret = gst_pad_get_range (pad, stop - 10, 10, &buffer1);
178   fail_unless (ret == GST_FLOW_OK);
179   fail_unless (buffer1 != NULL);
180   fail_unless (GST_BUFFER_SIZE (buffer1) == 10);
181   gst_buffer_unref (buffer1);
182
183   /* read 20 bytes at end-10 should give exactly 10 bytes */
184   ret = gst_pad_get_range (pad, stop - 10, 20, &buffer1);
185   fail_unless (ret == GST_FLOW_OK);
186   fail_unless (buffer1 != NULL);
187   fail_unless (GST_BUFFER_SIZE (buffer1) == 10);
188   gst_buffer_unref (buffer1);
189
190   /* read 0 bytes at end-1 should return 0 bytes */
191   ret = gst_pad_get_range (pad, stop - 1, 0, &buffer1);
192   fail_unless (ret == GST_FLOW_OK);
193   fail_unless (buffer1 != NULL);
194   fail_unless (GST_BUFFER_SIZE (buffer1) == 0);
195   gst_buffer_unref (buffer1);
196
197   /* read 10 bytes at end-1 should return 1 byte */
198   ret = gst_pad_get_range (pad, stop - 1, 10, &buffer1);
199   fail_unless (ret == GST_FLOW_OK);
200   fail_unless (buffer1 != NULL);
201   fail_unless (GST_BUFFER_SIZE (buffer1) == 1);
202   gst_buffer_unref (buffer1);
203
204   /* read 0 bytes at end should EOS */
205   ret = gst_pad_get_range (pad, stop, 0, &buffer1);
206   fail_unless (ret == GST_FLOW_UNEXPECTED);
207
208   /* read 10 bytes before end should EOS */
209   ret = gst_pad_get_range (pad, stop, 10, &buffer1);
210   fail_unless (ret == GST_FLOW_UNEXPECTED);
211
212   /* read 0 bytes after end should EOS */
213   ret = gst_pad_get_range (pad, stop + 10, 0, &buffer1);
214   fail_unless (ret == GST_FLOW_UNEXPECTED);
215
216   /* read 10 bytes after end should EOS too */
217   ret = gst_pad_get_range (pad, stop + 10, 10, &buffer1);
218   fail_unless (ret == GST_FLOW_UNEXPECTED);
219
220   fail_unless (gst_element_set_state (src,
221           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
222
223   /* cleanup */
224   gst_object_unref (pad);
225   cleanup_filesrc (src);
226 }
227
228 GST_END_TEST;
229
230 GST_START_TEST (test_coverage)
231 {
232   GstElement *src;
233   gchar *location;
234   GstBus *bus;
235   GstMessage *message;
236
237   src = setup_filesrc ();
238   bus = gst_bus_new ();
239
240   gst_element_set_bus (src, bus);
241
242   g_object_set (G_OBJECT (src), "location", "/i/do/not/exist", NULL);
243   g_object_get (G_OBJECT (src), "location", &location, NULL);
244   fail_unless_equals_string (location, "/i/do/not/exist");
245   g_free (location);
246   fail_unless (gst_element_set_state (src,
247           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE,
248       "could set to playing with wrong location");
249
250   /* a state change and an error */
251   fail_if ((message = gst_bus_pop (bus)) == NULL);
252   gst_message_unref (message);
253   fail_if ((message = gst_bus_pop (bus)) == NULL);
254   fail_unless_message_error (message, RESOURCE, NOT_FOUND);
255   gst_message_unref (message);
256
257   g_object_set (G_OBJECT (src), "location", NULL, NULL);
258   g_object_get (G_OBJECT (src), "location", &location, NULL);
259   fail_if (location);
260
261   /* cleanup */
262   gst_element_set_bus (src, NULL);
263   gst_object_unref (GST_OBJECT (bus));
264   cleanup_filesrc (src);
265 }
266
267 GST_END_TEST;
268
269 GST_START_TEST (test_uri_interface)
270 {
271   GstElement *src;
272   gchar *location;
273   GstBus *bus;
274
275   src = setup_filesrc ();
276   bus = gst_bus_new ();
277
278   gst_element_set_bus (src, bus);
279
280   g_object_set (G_OBJECT (src), "location", "/i/do/not/exist", NULL);
281   g_object_get (G_OBJECT (src), "location", &location, NULL);
282   fail_unless_equals_string (location, "/i/do/not/exist");
283   g_free (location);
284
285   location = (gchar *) gst_uri_handler_get_uri (GST_URI_HANDLER (src));
286   fail_unless_equals_string (location, "file://%2Fi%2Fdo%2Fnot%2Fexist");
287
288   /* should accept file:///foo/bar URIs */
289   fail_unless (gst_uri_handler_set_uri (GST_URI_HANDLER (src),
290           "file:///foo/bar"));
291   location = (gchar *) gst_uri_handler_get_uri (GST_URI_HANDLER (src));
292   fail_unless_equals_string (location, "file://%2Ffoo%2Fbar");
293   g_object_get (G_OBJECT (src), "location", &location, NULL);
294   fail_unless_equals_string (location, "/foo/bar");
295   g_free (location);
296
297   /* should accept file://localhost/foo/bar URIs */
298   fail_unless (gst_uri_handler_set_uri (GST_URI_HANDLER (src),
299           "file://localhost/foo/baz"));
300   location = (gchar *) gst_uri_handler_get_uri (GST_URI_HANDLER (src));
301   fail_unless_equals_string (location, "file://%2Ffoo%2Fbaz");
302   g_object_get (G_OBJECT (src), "location", &location, NULL);
303   fail_unless_equals_string (location, "/foo/baz");
304   g_free (location);
305
306   /* should fail with other hostnames */
307   fail_if (gst_uri_handler_set_uri (GST_URI_HANDLER (src),
308           "file://hostname/foo/foo"));
309
310   /* cleanup */
311   gst_element_set_bus (src, NULL);
312   gst_object_unref (GST_OBJECT (bus));
313   cleanup_filesrc (src);
314 }
315
316 GST_END_TEST;
317
318 Suite *
319 filesrc_suite (void)
320 {
321   Suite *s = suite_create ("filesrc");
322   TCase *tc_chain = tcase_create ("general");
323
324   suite_add_tcase (s, tc_chain);
325   tcase_add_test (tc_chain, test_seeking);
326   tcase_add_test (tc_chain, test_pull);
327   tcase_add_test (tc_chain, test_coverage);
328   tcase_add_test (tc_chain, test_uri_interface);
329
330   return s;
331 }
332
333 GST_CHECK_MAIN (filesrc);