tizen 2.0 init
[framework/multimedia/gst-plugins-base0.10.git] / tests / check / elements / playbin2.c
1 /* GStreamer unit tests for playbin2
2  *
3  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
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 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <gst/check/gstcheck.h>
26 #include <gst/base/gstpushsrc.h>
27 #include <unistd.h>
28
29 #ifndef GST_DISABLE_REGISTRY
30
31 static GType gst_red_video_src_get_type (void);
32 static GType gst_codec_src_get_type (void);
33
34 /* make sure the audio sink is not touched for video-only streams */
35 GST_START_TEST (test_sink_usage_video_only_stream)
36 {
37   GstElement *playbin, *fakevideosink, *fakeaudiosink;
38   GstState cur_state, pending_state;
39   GstElement *source;
40   GstBuffer *last_frame;
41   gint nstreams;
42
43   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
44           gst_red_video_src_get_type ()));
45
46   playbin = gst_element_factory_make ("playbin2", "playbin2");
47   fail_unless (playbin != NULL, "Failed to create playbin element");
48
49   fakevideosink = gst_element_factory_make ("fakesink", "fakevideosink");
50   fail_unless (fakevideosink != NULL, "Failed to create fakevideosink element");
51
52   fakeaudiosink = gst_element_factory_make ("fakesink", "fakeaudiosink");
53   fail_unless (fakeaudiosink != NULL, "Failed to create fakeaudiosink element");
54
55   /* video-only stream, audiosink will error out in null => ready if used */
56   g_object_set (fakeaudiosink, "state-error", 1, NULL);
57
58   g_object_set (playbin, "video-sink", fakevideosink, NULL);
59   g_object_set (playbin, "audio-sink", fakeaudiosink, NULL);
60
61   g_object_set (playbin, "uri", "redvideo://", NULL);
62
63   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
64       GST_STATE_CHANGE_SUCCESS);
65   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
66       GST_STATE_CHANGE_ASYNC);
67   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
68       GST_STATE_CHANGE_SUCCESS);
69
70   fail_unless_equals_int (gst_element_get_state (fakeaudiosink, &cur_state,
71           &pending_state, 0), GST_STATE_CHANGE_SUCCESS);
72   fail_unless_equals_int (cur_state, GST_STATE_NULL);
73   fail_unless_equals_int (pending_state, GST_STATE_VOID_PENDING);
74
75   g_object_get (playbin, "n-video", &nstreams, NULL);
76   fail_unless_equals_int (nstreams, 1);
77
78   g_object_get (playbin, "n-audio", &nstreams, NULL);
79   fail_unless_equals_int (nstreams, 0);
80
81   g_object_get (playbin, "n-text", &nstreams, NULL);
82   fail_unless_equals_int (nstreams, 0);
83
84   g_object_get (playbin, "source", &source, NULL);
85   fail_unless (G_TYPE_FROM_INSTANCE (source) == gst_red_video_src_get_type ());
86   gst_object_unref (source);
87
88   g_object_get (playbin, "frame", &last_frame, NULL);
89   fail_unless (GST_IS_BUFFER (last_frame));
90   gst_buffer_unref (last_frame);
91
92   gst_element_set_state (playbin, GST_STATE_NULL);
93   gst_object_unref (playbin);
94 }
95
96 GST_END_TEST;
97
98 /* this tests async error handling when setting up the subbin */
99 GST_START_TEST (test_suburi_error_unknowntype)
100 {
101   GstElement *playbin, *fakesink;
102
103   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
104           gst_red_video_src_get_type ()));
105
106   playbin = gst_element_factory_make ("playbin2", "playbin2");
107   fail_unless (playbin != NULL, "Failed to create playbin element");
108
109   fakesink = gst_element_factory_make ("fakesink", "fakesink");
110   fail_unless (fakesink != NULL, "Failed to create fakesink element");
111   ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1);
112
113   g_object_set (playbin, "video-sink", fakesink, NULL);
114
115   /* suburi file format unknown: playbin should just ignore the suburi and
116    * preroll normally (if /dev/zero does not exist, this test should behave
117    * the same as test_suburi_error_invalidfile() */
118   g_object_set (playbin, "uri", "redvideo://", NULL);
119   g_object_set (playbin, "suburi", "file:///dev/zero", NULL);
120   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
121       GST_STATE_CHANGE_SUCCESS);
122   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
123       GST_STATE_CHANGE_ASYNC);
124   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
125       GST_STATE_CHANGE_SUCCESS);
126
127   gst_element_set_state (playbin, GST_STATE_NULL);
128   gst_object_unref (playbin);
129 }
130
131 GST_END_TEST;
132
133 GST_START_TEST (test_suburi_error_invalidfile)
134 {
135   GstElement *playbin, *fakesink;
136
137   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
138           gst_red_video_src_get_type ()));
139
140   playbin = gst_element_factory_make ("playbin2", "playbin2");
141   fail_unless (playbin != NULL, "Failed to create playbin element");
142
143   fakesink = gst_element_factory_make ("fakesink", "fakesink");
144   fail_unless (fakesink != NULL, "Failed to create fakesink element");
145   ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1);
146
147   g_object_set (playbin, "video-sink", fakesink, NULL);
148
149   /* suburi file does not exist: playbin should just ignore the suburi and
150    * preroll normally */
151   g_object_set (playbin, "uri", "redvideo://", NULL);
152   g_object_set (playbin, "suburi", "file:///foo/bar/803129999/32x9ax1", NULL);
153   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
154       GST_STATE_CHANGE_SUCCESS);
155   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
156       GST_STATE_CHANGE_ASYNC);
157   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
158       GST_STATE_CHANGE_SUCCESS);
159
160   gst_element_set_state (playbin, GST_STATE_NULL);
161   gst_object_unref (playbin);
162 }
163
164 GST_END_TEST;
165
166 GST_START_TEST (test_suburi_error_wrongproto)
167 {
168   GstElement *playbin, *fakesink;
169
170   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
171           gst_red_video_src_get_type ()));
172
173   playbin = gst_element_factory_make ("playbin2", "playbin2");
174   fail_unless (playbin != NULL, "Failed to create playbin element");
175
176   fakesink = gst_element_factory_make ("fakesink", "fakesink");
177   fail_unless (fakesink != NULL, "Failed to create fakesink element");
178   ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1);
179
180   g_object_set (playbin, "video-sink", fakesink, NULL);
181
182   /* wrong protocol for suburi: playbin should just ignore the suburi and
183    * preroll normally */
184   g_object_set (playbin, "uri", "redvideo://", NULL);
185   g_object_set (playbin, "suburi", "nosuchproto://foo.bar:80", NULL);
186   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
187       GST_STATE_CHANGE_SUCCESS);
188   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
189       GST_STATE_CHANGE_ASYNC);
190   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
191       GST_STATE_CHANGE_SUCCESS);
192
193   gst_element_set_state (playbin, GST_STATE_NULL);
194   gst_object_unref (playbin);
195 }
196
197 GST_END_TEST;
198
199 static GstElement *
200 create_playbin (const gchar * uri)
201 {
202   GstElement *playbin, *fakesink1, *fakesink2;
203
204   playbin = gst_element_factory_make ("playbin2", "playbin2");
205   fail_unless (playbin != NULL, "Failed to create playbin element");
206
207   fakesink1 = gst_element_factory_make ("fakesink", NULL);
208   fail_unless (fakesink1 != NULL, "Failed to create fakesink element #1");
209
210   fakesink2 = gst_element_factory_make ("fakesink", NULL);
211   fail_unless (fakesink2 != NULL, "Failed to create fakesink element #2");
212
213   /* make them behave like normal sinks, even if not needed for the test */
214   g_object_set (fakesink1, "sync", TRUE, NULL);
215   g_object_set (fakesink2, "sync", TRUE, NULL);
216
217   g_object_set (playbin, "video-sink", fakesink1, NULL);
218   g_object_set (playbin, "audio-sink", fakesink2, NULL);
219
220   g_object_set (playbin, "uri", uri, NULL);
221
222   return playbin;
223 }
224
225 GST_START_TEST (test_missing_urisource_handler)
226 {
227   GstStructure *s;
228   GstMessage *msg;
229   GstElement *playbin;
230   GError *err = NULL;
231   GstBus *bus;
232
233   playbin = create_playbin ("chocchipcookie://withahint.of/cinnamon");
234
235   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
236       GST_STATE_CHANGE_SUCCESS);
237   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
238       GST_STATE_CHANGE_FAILURE);
239
240   /* there should be at least a missing-plugin message on the bus now and an
241    * error message; the missing-plugin message should be first */
242   bus = gst_element_get_bus (playbin);
243
244   msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
245   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
246   fail_unless (msg->structure != NULL);
247   s = msg->structure;
248   fail_unless (gst_structure_has_name (s, "missing-plugin"));
249   fail_unless (gst_structure_has_field_typed (s, "detail", G_TYPE_STRING));
250   fail_unless_equals_string (gst_structure_get_string (s, "detail"),
251       "chocchipcookie");
252   fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
253   fail_unless_equals_string (gst_structure_get_string (s, "type"), "urisource");
254   gst_message_unref (msg);
255
256   msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
257   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);
258
259   /* make sure the error is a CORE MISSING_PLUGIN one */
260   gst_message_parse_error (msg, &err, NULL);
261   fail_unless (err != NULL);
262   fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
263       "%s instead of core-error-quark", g_quark_to_string (err->domain));
264   fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
265       "code %u instead of GST_CORE_ERROR_MISSING_PLUGIN", err->code);
266   g_error_free (err);
267   gst_message_unref (msg);
268   gst_object_unref (bus);
269
270   gst_element_set_state (playbin, GST_STATE_NULL);
271   gst_object_unref (playbin);
272 }
273
274 GST_END_TEST;
275
276 GST_START_TEST (test_missing_suburisource_handler)
277 {
278   GstStructure *s;
279   GstMessage *msg;
280   GstElement *playbin;
281   GError *err = NULL;
282   GstBus *bus;
283
284   playbin = create_playbin ("file:///does/not/exis.t");
285
286   g_object_set (playbin, "suburi", "cookie://withahint.of/cinnamon", NULL);
287
288   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
289       GST_STATE_CHANGE_SUCCESS);
290   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
291       GST_STATE_CHANGE_FAILURE);
292
293   /* there should be at least a missing-plugin message on the bus now and an
294    * error message; the missing-plugin message should be first */
295   bus = gst_element_get_bus (playbin);
296
297   msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
298   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
299   fail_unless (msg->structure != NULL);
300   s = msg->structure;
301   fail_unless (gst_structure_has_name (s, "missing-plugin"));
302   fail_unless (gst_structure_has_field_typed (s, "detail", G_TYPE_STRING));
303   fail_unless_equals_string (gst_structure_get_string (s, "detail"), "cookie");
304   fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
305   fail_unless_equals_string (gst_structure_get_string (s, "type"), "urisource");
306   gst_message_unref (msg);
307
308   msg = gst_bus_poll (bus, GST_MESSAGE_WARNING, -1);
309   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_WARNING);
310
311   /* make sure the *warning* is a CORE MISSING_PLUGIN one */
312   gst_message_parse_warning (msg, &err, NULL);
313   fail_unless (err != NULL);
314   fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
315       "%s instead of core-error-quark", g_quark_to_string (err->domain));
316   fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
317       "code %u instead of GST_CORE_ERROR_MISSING_PLUGIN", err->code);
318   g_error_free (err);
319   gst_message_unref (msg);
320
321   msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
322   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);
323
324   /* make sure the error is a RESOURCE NOT_FOUND one */
325   gst_message_parse_error (msg, &err, NULL);
326   fail_unless (err != NULL);
327   fail_unless (err->domain == GST_RESOURCE_ERROR,
328       "error has wrong error domain " "%s instead of resource-error-quark",
329       g_quark_to_string (err->domain));
330   fail_unless (err->code == GST_RESOURCE_ERROR_NOT_FOUND,
331       "error has wrong " "code %u instead of GST_RESOURCE_ERROR_NOT_FOUND",
332       err->code);
333   g_error_free (err);
334   gst_message_unref (msg);
335
336   gst_object_unref (bus);
337
338   gst_element_set_state (playbin, GST_STATE_NULL);
339   gst_object_unref (playbin);
340 }
341
342 GST_END_TEST;
343
344 GST_START_TEST (test_missing_primary_decoder)
345 {
346   GstStructure *s;
347   GstMessage *msg;
348   GstElement *playbin;
349   GError *err = NULL;
350   GstBus *bus;
351
352   fail_unless (gst_element_register (NULL, "codecsrc", GST_RANK_PRIMARY,
353           gst_codec_src_get_type ()));
354
355   playbin = create_playbin ("codec://");
356
357   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
358       GST_STATE_CHANGE_SUCCESS);
359   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
360       GST_STATE_CHANGE_ASYNC);
361
362   /* there should soon be at least a missing-plugin message on the bus and an
363    * error message; the missing-plugin message should be first */
364   bus = gst_element_get_bus (playbin);
365
366   msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
367   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
368   fail_unless (msg->structure != NULL);
369   s = msg->structure;
370   fail_unless (gst_structure_has_name (s, "missing-plugin"));
371   fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
372   fail_unless_equals_string (gst_structure_get_string (s, "type"), "decoder");
373   fail_unless (gst_structure_has_field_typed (s, "detail", GST_TYPE_CAPS));
374   gst_message_unref (msg);
375
376   msg = gst_bus_poll (bus, GST_MESSAGE_WARNING, -1);
377   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_WARNING);
378
379   /* make sure the *warning* is a STREAM CODEC_NOT_FOUND one */
380   gst_message_parse_warning (msg, &err, NULL);
381   fail_unless (err != NULL);
382   fail_unless (err->domain == GST_STREAM_ERROR, "error has wrong error domain "
383       "%s instead of stream-error-quark", g_quark_to_string (err->domain));
384   fail_unless (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND, "error has wrong "
385       "code %u instead of GST_STREAM_ERROR_CODEC_NOT_FOUND", err->code);
386   g_error_free (err);
387   gst_message_unref (msg);
388
389   msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
390   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);
391
392   /* make sure the error is a CORE MISSING_PLUGIN one */
393   gst_message_parse_error (msg, &err, NULL);
394   fail_unless (err != NULL);
395   fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
396       "%s instead of core-error-quark", g_quark_to_string (err->domain));
397   fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
398       "code %u instead of GST_CORE_ERROR_MISSING_PLUGIN", err->code);
399   g_error_free (err);
400   gst_message_unref (msg);
401
402   gst_object_unref (bus);
403
404   gst_element_set_state (playbin, GST_STATE_NULL);
405   gst_object_unref (playbin);
406 }
407
408 GST_END_TEST;
409
410 GST_START_TEST (test_refcount)
411 {
412   GstElement *playbin, *audiosink, *videosink, *vis;
413
414   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
415           gst_red_video_src_get_type ()));
416
417   playbin = gst_element_factory_make ("playbin2", NULL);
418   audiosink = gst_element_factory_make ("fakesink", "myaudiosink");
419   videosink = gst_element_factory_make ("fakesink", "myvideosink");
420   vis = gst_element_factory_make ("identity", "myvis");
421
422   /* ref because we need them after we unref playbin2 */
423   gst_object_ref (audiosink);
424   gst_object_ref (videosink);
425   gst_object_ref (vis);
426
427   /* Sinks have floating ref only, setting the properties takes ownership. */
428   g_object_set (playbin,
429       "audio-sink", audiosink,
430       "video-sink", videosink,
431       "vis-plugin", vis, "flags", 0x01 | 0x02 | 0x08, NULL);
432
433   g_object_set (playbin, "uri", "redvideo://", NULL);
434   //"uri", "file:///home/wim/data/cdda.ogg", NULL);
435
436   ASSERT_OBJECT_REFCOUNT (playbin, "playbin", 1);
437
438   /* we have two refs now, one from ourselves and one from playbin2 */
439   ASSERT_OBJECT_REFCOUNT (audiosink, "myaudiosink", 2);
440   ASSERT_OBJECT_REFCOUNT (videosink, "myvideosink", 2);
441   ASSERT_OBJECT_REFCOUNT (vis, "myvis", 2);
442
443   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
444       GST_STATE_CHANGE_ASYNC);
445   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL,
446           GST_CLOCK_TIME_NONE), GST_STATE_CHANGE_SUCCESS);
447   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_NULL),
448       GST_STATE_CHANGE_SUCCESS);
449
450   ASSERT_OBJECT_REFCOUNT (playbin, "playbin", 1);
451   /* refcount of our elements is undefined, playbin2 might keep additional refs
452    * because it cached the elements in bins */
453   gst_object_unref (playbin);
454
455   /* now we are back to our refs */
456   ASSERT_OBJECT_REFCOUNT (audiosink, "myaudiosink", 1);
457   ASSERT_OBJECT_REFCOUNT (videosink, "myvideosink", 1);
458   ASSERT_OBJECT_REFCOUNT (vis, "myvis", 1);
459
460   gst_object_unref (audiosink);
461   gst_object_unref (videosink);
462   gst_object_unref (vis);
463 }
464
465 GST_END_TEST;
466
467 static void
468 source_setup (GstElement * playbin, GstElement * source, GstElement ** p_src)
469 {
470   GST_LOG ("source-setup called, source = %s", G_OBJECT_TYPE_NAME (source));
471   *p_src = gst_object_ref (source);
472   GST_LOG ("here");
473 }
474
475 GST_START_TEST (test_source_setup)
476 {
477   GstElement *playbin, *videosink;
478   GstElement *src = NULL;
479
480   if (!gst_default_registry_check_feature_version ("redvideosrc", 0, 10, 0)) {
481     fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
482             gst_red_video_src_get_type ()));
483   }
484
485   playbin = gst_element_factory_make ("playbin2", NULL);
486   g_object_set (playbin, "uri", "redvideo://", NULL);
487
488   videosink = gst_element_factory_make ("fakesink", "myvideosink");
489   g_object_set (playbin, "video-sink", videosink, NULL);
490
491   g_signal_connect (playbin, "source-setup", G_CALLBACK (source_setup), &src);
492
493   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
494       GST_STATE_CHANGE_ASYNC);
495   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL,
496           GST_CLOCK_TIME_NONE), GST_STATE_CHANGE_SUCCESS);
497
498   fail_unless (src != NULL);
499   fail_unless (G_OBJECT_TYPE (src) == gst_red_video_src_get_type ());
500
501   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_NULL),
502       GST_STATE_CHANGE_SUCCESS);
503
504   gst_object_unref (playbin);
505   gst_object_unref (src);
506 }
507
508 GST_END_TEST;
509
510 /*** redvideo:// source ***/
511
512 static GstURIType
513 gst_red_video_src_uri_get_type (void)
514 {
515   return GST_URI_SRC;
516 }
517
518 static gchar **
519 gst_red_video_src_uri_get_protocols (void)
520 {
521   static gchar *protocols[] = { (char *) "redvideo", NULL };
522
523   return protocols;
524 }
525
526 static const gchar *
527 gst_red_video_src_uri_get_uri (GstURIHandler * handler)
528 {
529   return "redvideo://";
530 }
531
532 static gboolean
533 gst_red_video_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
534 {
535   return (uri != NULL && g_str_has_prefix (uri, "redvideo:"));
536 }
537
538 static void
539 gst_red_video_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
540 {
541   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
542
543   iface->get_type = gst_red_video_src_uri_get_type;
544   iface->get_protocols = gst_red_video_src_uri_get_protocols;
545   iface->get_uri = gst_red_video_src_uri_get_uri;
546   iface->set_uri = gst_red_video_src_uri_set_uri;
547 }
548
549 static void
550 gst_red_video_src_init_type (GType type)
551 {
552   static const GInterfaceInfo uri_hdlr_info = {
553     gst_red_video_src_uri_handler_init, NULL, NULL
554   };
555
556   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &uri_hdlr_info);
557 }
558
559 typedef GstPushSrc GstRedVideoSrc;
560 typedef GstPushSrcClass GstRedVideoSrcClass;
561
562 GST_BOILERPLATE_FULL (GstRedVideoSrc, gst_red_video_src, GstPushSrc,
563     GST_TYPE_PUSH_SRC, gst_red_video_src_init_type);
564
565 static void
566 gst_red_video_src_base_init (gpointer klass)
567 {
568   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
569       GST_PAD_SRC, GST_PAD_ALWAYS,
570       GST_STATIC_CAPS ("video/x-raw-yuv, format=(fourcc)I420")
571       );
572   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
573
574   gst_element_class_add_static_pad_template (element_class, &src_templ);
575   gst_element_class_set_details_simple (element_class,
576       "Red Video Src", "Source/Video", "yep", "me");
577 }
578
579 static GstFlowReturn
580 gst_red_video_src_create (GstPushSrc * src, GstBuffer ** p_buf)
581 {
582   GstBuffer *buf;
583   GstCaps *caps;
584   guint8 *data;
585   guint w = 64, h = 64;
586   guint size;
587
588   size = w * h * 3 / 2;
589   buf = gst_buffer_new_and_alloc (size);
590   data = GST_BUFFER_DATA (buf);
591   memset (data, 76, w * h);
592   memset (data + (w * h), 85, (w * h) / 4);
593   memset (data + (w * h) + ((w * h) / 4), 255, (w * h) / 4);
594
595   caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC,
596       GST_MAKE_FOURCC ('I', '4', '2', '0'), "width", G_TYPE_INT, w, "height",
597       G_TYPE_INT, h, "framerate", GST_TYPE_FRACTION, 1, 1, NULL);
598   gst_buffer_set_caps (buf, caps);
599   gst_caps_unref (caps);
600
601   *p_buf = buf;
602   return GST_FLOW_OK;
603 }
604
605 static void
606 gst_red_video_src_class_init (GstRedVideoSrcClass * klass)
607 {
608   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
609
610   pushsrc_class->create = gst_red_video_src_create;
611 }
612
613 static void
614 gst_red_video_src_init (GstRedVideoSrc * src, GstRedVideoSrcClass * klass)
615 {
616 }
617
618 /*** codec:// source ***/
619
620 static GstURIType
621 gst_codec_src_uri_get_type (void)
622 {
623   return GST_URI_SRC;
624 }
625
626 static gchar **
627 gst_codec_src_uri_get_protocols (void)
628 {
629   static gchar *protocols[] = { (char *) "codec", NULL };
630
631   return protocols;
632 }
633
634 static const gchar *
635 gst_codec_src_uri_get_uri (GstURIHandler * handler)
636 {
637   return "codec://";
638 }
639
640 static gboolean
641 gst_codec_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
642 {
643   return (uri != NULL && g_str_has_prefix (uri, "codec:"));
644 }
645
646 static void
647 gst_codec_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
648 {
649   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
650
651   iface->get_type = gst_codec_src_uri_get_type;
652   iface->get_protocols = gst_codec_src_uri_get_protocols;
653   iface->get_uri = gst_codec_src_uri_get_uri;
654   iface->set_uri = gst_codec_src_uri_set_uri;
655 }
656
657 static void
658 gst_codec_src_init_type (GType type)
659 {
660   static const GInterfaceInfo uri_hdlr_info = {
661     gst_codec_src_uri_handler_init, NULL, NULL
662   };
663
664   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &uri_hdlr_info);
665 }
666
667 #undef parent_class
668 #define parent_class codec_src_parent_class
669
670 typedef GstPushSrc GstCodecSrc;
671 typedef GstPushSrcClass GstCodecSrcClass;
672
673 GST_BOILERPLATE_FULL (GstCodecSrc, gst_codec_src, GstPushSrc,
674     GST_TYPE_PUSH_SRC, gst_codec_src_init_type);
675
676 static void
677 gst_codec_src_base_init (gpointer klass)
678 {
679   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
680       GST_PAD_SRC, GST_PAD_ALWAYS,
681       GST_STATIC_CAPS ("application/x-codec")
682       );
683   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
684
685   gst_element_class_add_static_pad_template (element_class, &src_templ);
686   gst_element_class_set_details_simple (element_class,
687       "Codec Src", "Source/Video", "yep", "me");
688 }
689
690 static GstFlowReturn
691 gst_codec_src_create (GstPushSrc * src, GstBuffer ** p_buf)
692 {
693   GstBuffer *buf;
694   GstCaps *caps;
695
696   buf = gst_buffer_new_and_alloc (20);
697   memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
698
699   caps = gst_caps_new_simple ("application/x-codec", NULL);
700   gst_buffer_set_caps (buf, caps);
701   gst_caps_unref (caps);
702
703   *p_buf = buf;
704   return GST_FLOW_OK;
705 }
706
707 static void
708 gst_codec_src_class_init (GstCodecSrcClass * klass)
709 {
710   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
711
712   pushsrc_class->create = gst_codec_src_create;
713 }
714
715 static void
716 gst_codec_src_init (GstCodecSrc * src, GstCodecSrcClass * klass)
717 {
718 }
719
720 #endif /* GST_DISABLE_REGISTRY */
721
722
723 static Suite *
724 playbin2_suite (void)
725 {
726   Suite *s = suite_create ("playbin2");
727   TCase *tc_chain = tcase_create ("general");
728
729   suite_add_tcase (s, tc_chain);
730
731 #ifndef GST_DISABLE_REGISTRY
732   tcase_add_test (tc_chain, test_sink_usage_video_only_stream);
733   tcase_add_test (tc_chain, test_suburi_error_wrongproto);
734   tcase_add_test (tc_chain, test_suburi_error_invalidfile);
735   tcase_add_test (tc_chain, test_suburi_error_unknowntype);
736   tcase_add_test (tc_chain, test_missing_urisource_handler);
737   tcase_add_test (tc_chain, test_missing_suburisource_handler);
738   tcase_add_test (tc_chain, test_missing_primary_decoder);
739   tcase_add_test (tc_chain, test_refcount);
740   tcase_add_test (tc_chain, test_source_setup);
741
742   /* one day we might also want to have the following checks:
743    * tcase_add_test (tc_chain, test_missing_secondary_decoder_one_fatal);
744    * tcase_add_test (tc_chain, test_missing_secondary_decoder_two_fatal);
745    * tcase_add_test (tc_chain, test_missing_secondary_decoder_two_with_preroll);
746    */
747 #endif
748
749   return s;
750 }
751
752 GST_CHECK_MAIN (playbin2);