bb4a3fd32bc91b8201ee844b4d55fc9fa604687a
[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_check_teardown_sink_pad (filesrc);
67   gst_check_teardown_element (filesrc);
68 }
69
70 GST_START_TEST (test_seeking)
71 {
72   GstElement *src;
73   GstQuery *seeking_query;
74   gboolean seekable;
75
76 #ifndef TESTFILE
77 #error TESTFILE not defined
78 #endif
79   src = setup_filesrc ();
80
81   g_object_set (G_OBJECT (src), "location", TESTFILE, NULL);
82   fail_unless (gst_element_set_state (src,
83           GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS,
84       "could not set to paused");
85
86   /* Test that filesrc is seekable with a file fd */
87   fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES))
88       != NULL);
89   fail_unless (gst_element_query (src, seeking_query) == TRUE);
90   gst_query_parse_seeking (seeking_query, NULL, &seekable, NULL, NULL);
91   fail_unless (seekable == TRUE);
92   gst_query_unref (seeking_query);
93
94   fail_unless (gst_element_set_state (src,
95           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
96
97   /* cleanup */
98   cleanup_filesrc (src);
99 }
100
101 GST_END_TEST;
102
103 GST_START_TEST (test_pull)
104 {
105   GstElement *src;
106   GstQuery *seeking_query;
107   gboolean res, seekable;
108   gint64 start, stop;
109   GstPad *pad;
110   GstFlowReturn ret;
111   GstBuffer *buffer1, *buffer2;
112
113   src = setup_filesrc ();
114
115   g_object_set (G_OBJECT (src), "location", TESTFILE, NULL);
116   fail_unless (gst_element_set_state (src,
117           GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
118       "could not set to ready");
119
120   /* get the source pad */
121   pad = gst_element_get_pad (src, "src");
122   fail_unless (pad != NULL);
123
124   /* activate the pad in pull mode */
125   res = gst_pad_activate_pull (pad, TRUE);
126   fail_unless (res == TRUE);
127
128   /* not start playing */
129   fail_unless (gst_element_set_state (src,
130           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
131       "could not set to paused");
132
133   /* Test that filesrc is seekable with a file fd */
134   fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES))
135       != NULL);
136   fail_unless (gst_element_query (src, seeking_query) == TRUE);
137
138   /* get the seeking capabilities */
139   gst_query_parse_seeking (seeking_query, NULL, &seekable, &start, &stop);
140   fail_unless (seekable == TRUE);
141   fail_unless (start == 0);
142   fail_unless (start != -1);
143   gst_query_unref (seeking_query);
144
145   /* do some pulls */
146   ret = gst_pad_get_range (pad, 0, 100, &buffer1);
147   fail_unless (ret == GST_FLOW_OK);
148   fail_unless (buffer1 != NULL);
149   fail_unless (GST_BUFFER_SIZE (buffer1) == 100);
150
151   ret = gst_pad_get_range (pad, 0, 50, &buffer2);
152   fail_unless (ret == GST_FLOW_OK);
153   fail_unless (buffer2 != NULL);
154   fail_unless (GST_BUFFER_SIZE (buffer2) == 50);
155
156   /* this should be the same */
157   fail_unless (memcmp (GST_BUFFER_DATA (buffer1), GST_BUFFER_DATA (buffer2),
158           50) == 0);
159
160   gst_buffer_unref (buffer2);
161
162   /* read next 50 bytes */
163   ret = gst_pad_get_range (pad, 50, 50, &buffer2);
164   fail_unless (ret == GST_FLOW_OK);
165   fail_unless (buffer2 != NULL);
166   fail_unless (GST_BUFFER_SIZE (buffer2) == 50);
167
168   /* compare with previously read data */
169   fail_unless (memcmp (GST_BUFFER_DATA (buffer1) + 50,
170           GST_BUFFER_DATA (buffer2), 50) == 0);
171
172   gst_buffer_unref (buffer1);
173   gst_buffer_unref (buffer2);
174
175   /* read 10 bytes at end-10 should give exactly 10 bytes */
176   ret = gst_pad_get_range (pad, stop - 10, 10, &buffer1);
177   fail_unless (ret == GST_FLOW_OK);
178   fail_unless (buffer1 != NULL);
179   fail_unless (GST_BUFFER_SIZE (buffer1) == 10);
180   gst_buffer_unref (buffer1);
181
182   /* read 20 bytes at end-10 should give exactly 10 bytes */
183   ret = gst_pad_get_range (pad, stop - 10, 20, &buffer1);
184   fail_unless (ret == GST_FLOW_OK);
185   fail_unless (buffer1 != NULL);
186   fail_unless (GST_BUFFER_SIZE (buffer1) == 10);
187   gst_buffer_unref (buffer1);
188
189   /* read 0 bytes at end-1 should return 0 bytes */
190   ret = gst_pad_get_range (pad, stop - 1, 0, &buffer1);
191   fail_unless (ret == GST_FLOW_OK);
192   fail_unless (buffer1 != NULL);
193   fail_unless (GST_BUFFER_SIZE (buffer1) == 0);
194   gst_buffer_unref (buffer1);
195
196   /* read 10 bytes at end-1 should return 1 byte */
197   ret = gst_pad_get_range (pad, stop - 1, 10, &buffer1);
198   fail_unless (ret == GST_FLOW_OK);
199   fail_unless (buffer1 != NULL);
200   fail_unless (GST_BUFFER_SIZE (buffer1) == 1);
201   gst_buffer_unref (buffer1);
202
203   /* read 0 bytes at end should EOS */
204   ret = gst_pad_get_range (pad, stop, 0, &buffer1);
205   fail_unless (ret == GST_FLOW_UNEXPECTED);
206
207   /* read 10 bytes before end should EOS */
208   ret = gst_pad_get_range (pad, stop, 10, &buffer1);
209   fail_unless (ret == GST_FLOW_UNEXPECTED);
210
211   /* read 0 bytes after end should EOS */
212   ret = gst_pad_get_range (pad, stop + 10, 0, &buffer1);
213   fail_unless (ret == GST_FLOW_UNEXPECTED);
214
215   /* read 10 bytes after end should EOS too */
216   ret = gst_pad_get_range (pad, stop + 10, 10, &buffer1);
217   fail_unless (ret == GST_FLOW_UNEXPECTED);
218
219   fail_unless (gst_element_set_state (src,
220           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
221
222   /* cleanup */
223   gst_object_unref (pad);
224   cleanup_filesrc (src);
225 }
226
227 GST_END_TEST;
228
229 GST_START_TEST (test_coverage)
230 {
231   GstElement *src;
232   gchar *location;
233   GstBus *bus;
234   GstMessage *message;
235
236   src = setup_filesrc ();
237   bus = gst_bus_new ();
238
239   gst_element_set_bus (src, bus);
240
241   g_object_set (G_OBJECT (src), "location", "/i/do/not/exist", NULL);
242   g_object_get (G_OBJECT (src), "location", &location, NULL);
243   fail_unless_equals_string (location, "/i/do/not/exist");
244   g_free (location);
245   fail_unless (gst_element_set_state (src,
246           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE,
247       "could set to playing with wrong location");
248
249   /* a state change and an error */
250   fail_if ((message = gst_bus_pop (bus)) == NULL);
251   gst_message_unref (message);
252   fail_if ((message = gst_bus_pop (bus)) == NULL);
253   fail_unless_message_error (message, RESOURCE, NOT_FOUND);
254   gst_message_unref (message);
255
256   g_object_set (G_OBJECT (src), "location", NULL, NULL);
257   g_object_get (G_OBJECT (src), "location", &location, NULL);
258   fail_if (location);
259
260   /* cleanup */
261   gst_element_set_bus (src, NULL);
262   gst_object_unref (GST_OBJECT (bus));
263   cleanup_filesrc (src);
264 }
265
266 GST_END_TEST;
267
268 Suite *
269 filesrc_suite (void)
270 {
271   Suite *s = suite_create ("filesrc");
272   TCase *tc_chain = tcase_create ("general");
273
274   suite_add_tcase (s, tc_chain);
275   tcase_add_test (tc_chain, test_seeking);
276   tcase_add_test (tc_chain, test_pull);
277   tcase_add_test (tc_chain, test_coverage);
278
279   return s;
280 }
281
282 GST_CHECK_MAIN (filesrc);