tizen 2.3 release
[framework/multimedia/gst-plugins-base0.10.git] / tests / check / elements / playbin.c
1 /* GStreamer unit tests for playbin
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 #define DEFINE_TEST(func) \
35     static void func (void);                            \
36     \
37     GST_START_TEST(func ## _decodebin1)                  \
38     { g_unsetenv("USE_DECODEBIN2"); func(); }            \
39     GST_END_TEST;                                        \
40     \
41     GST_START_TEST(func ## _decodebin2)                  \
42     { g_setenv("USE_DECODEBIN2", "1", TRUE); func(); }   \
43     GST_END_TEST;
44
45 DEFINE_TEST (test_sink_usage_video_only_stream);
46
47 /* make sure the audio sink is not touched for video-only streams */
48 static void
49 test_sink_usage_video_only_stream (void)
50 {
51   GstElement *playbin, *fakevideosink, *fakeaudiosink;
52   GstState cur_state, pending_state;
53
54   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
55           gst_red_video_src_get_type ()));
56
57   playbin = gst_element_factory_make ("playbin", "playbin");
58   fail_unless (playbin != NULL, "Failed to create playbin element");
59
60   fakevideosink = gst_element_factory_make ("fakesink", "fakevideosink");
61   fail_unless (fakevideosink != NULL, "Failed to create fakevideosink element");
62
63   fakeaudiosink = gst_element_factory_make ("fakesink", "fakeaudiosink");
64   fail_unless (fakeaudiosink != NULL, "Failed to create fakeaudiosink element");
65
66   /* video-only stream, audiosink will error out in null => ready if used */
67   g_object_set (fakeaudiosink, "state-error", 1, NULL);
68
69   g_object_set (playbin, "video-sink", fakevideosink, NULL);
70   g_object_set (playbin, "audio-sink", fakeaudiosink, NULL);
71
72   g_object_set (playbin, "uri", "redvideo://", NULL);
73
74   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
75       GST_STATE_CHANGE_SUCCESS);
76   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
77       GST_STATE_CHANGE_ASYNC);
78   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
79       GST_STATE_CHANGE_SUCCESS);
80
81   fail_unless_equals_int (gst_element_get_state (fakeaudiosink, &cur_state,
82           &pending_state, 0), GST_STATE_CHANGE_SUCCESS);
83   fail_unless_equals_int (cur_state, GST_STATE_NULL);
84   fail_unless_equals_int (pending_state, GST_STATE_VOID_PENDING);
85
86   {
87     GValueArray *stream_info = NULL;
88
89     g_object_get (playbin, "stream-info-value-array", &stream_info, NULL);
90     fail_unless (stream_info != NULL);
91     fail_unless_equals_int (stream_info->n_values, 1);
92     g_value_array_free (stream_info);
93   }
94
95   gst_element_set_state (playbin, GST_STATE_NULL);
96   gst_object_unref (playbin);
97 }
98
99 /* this tests async error handling when setting up the subbin */
100 DEFINE_TEST (test_suburi_error_unknowntype);
101
102 static void
103 test_suburi_error_unknowntype (void)
104 {
105   GstElement *playbin, *fakesink;
106
107   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
108           gst_red_video_src_get_type ()));
109
110   playbin = gst_element_factory_make ("playbin", "playbin");
111   fail_unless (playbin != NULL, "Failed to create playbin element");
112
113   fakesink = gst_element_factory_make ("fakesink", "fakesink");
114   fail_unless (fakesink != NULL, "Failed to create fakesink element");
115   ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1);
116
117   g_object_set (playbin, "video-sink", fakesink, NULL);
118
119   /* suburi file format unknown: playbin should just ignore the suburi and
120    * preroll normally (if /dev/zero does not exist, this test should behave
121    * the same as test_suburi_error_invalidfile() */
122   g_object_set (playbin, "uri", "redvideo://", NULL);
123   g_object_set (playbin, "suburi", "file:///dev/zero", NULL);
124   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
125       GST_STATE_CHANGE_SUCCESS);
126   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
127       GST_STATE_CHANGE_ASYNC);
128   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
129       GST_STATE_CHANGE_SUCCESS);
130
131   gst_element_set_state (playbin, GST_STATE_NULL);
132   gst_object_unref (playbin);
133 }
134
135 DEFINE_TEST (test_suburi_error_invalidfile);
136
137 static void
138 test_suburi_error_invalidfile (void)
139 {
140   GstElement *playbin, *fakesink;
141
142   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
143           gst_red_video_src_get_type ()));
144
145   playbin = gst_element_factory_make ("playbin", "playbin");
146   fail_unless (playbin != NULL, "Failed to create playbin element");
147
148   fakesink = gst_element_factory_make ("fakesink", "fakesink");
149   fail_unless (fakesink != NULL, "Failed to create fakesink element");
150   ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1);
151
152   g_object_set (playbin, "video-sink", fakesink, NULL);
153
154   /* suburi file does not exist: playbin should just ignore the suburi and
155    * preroll normally */
156   g_object_set (playbin, "uri", "redvideo://", NULL);
157   g_object_set (playbin, "suburi", "file:///foo/bar/803129999/32x9ax1", NULL);
158   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
159       GST_STATE_CHANGE_SUCCESS);
160   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
161       GST_STATE_CHANGE_ASYNC);
162   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
163       GST_STATE_CHANGE_SUCCESS);
164
165   gst_element_set_state (playbin, GST_STATE_NULL);
166   gst_object_unref (playbin);
167 }
168
169 DEFINE_TEST (test_suburi_error_wrongproto);
170
171 static void
172 test_suburi_error_wrongproto (void)
173 {
174   GstElement *playbin, *fakesink;
175
176   fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
177           gst_red_video_src_get_type ()));
178
179   playbin = gst_element_factory_make ("playbin", "playbin");
180   fail_unless (playbin != NULL, "Failed to create playbin element");
181
182   fakesink = gst_element_factory_make ("fakesink", "fakesink");
183   fail_unless (fakesink != NULL, "Failed to create fakesink element");
184   ASSERT_OBJECT_REFCOUNT (fakesink, "fakesink after creation", 1);
185
186   g_object_set (playbin, "video-sink", fakesink, NULL);
187
188   /* wrong protocol for suburi: playbin should just ignore the suburi and
189    * preroll normally */
190   g_object_set (playbin, "uri", "redvideo://", NULL);
191   g_object_set (playbin, "suburi", "nosuchproto://foo.bar:80", NULL);
192   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
193       GST_STATE_CHANGE_SUCCESS);
194   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
195       GST_STATE_CHANGE_ASYNC);
196   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
197       GST_STATE_CHANGE_SUCCESS);
198
199   gst_element_set_state (playbin, GST_STATE_NULL);
200   gst_object_unref (playbin);
201 }
202
203 static GstElement *
204 create_playbin (const gchar * uri)
205 {
206   GstElement *playbin, *fakesink1, *fakesink2;
207
208   playbin = gst_element_factory_make ("playbin", "playbin");
209   fail_unless (playbin != NULL, "Failed to create playbin element");
210
211   fakesink1 = gst_element_factory_make ("fakesink", NULL);
212   fail_unless (fakesink1 != NULL, "Failed to create fakesink element #1");
213
214   fakesink2 = gst_element_factory_make ("fakesink", NULL);
215   fail_unless (fakesink2 != NULL, "Failed to create fakesink element #2");
216
217   /* make them behave like normal sinks, even if not needed for the test */
218   g_object_set (fakesink1, "sync", TRUE, NULL);
219   g_object_set (fakesink2, "sync", TRUE, NULL);
220
221   g_object_set (playbin, "video-sink", fakesink1, NULL);
222   g_object_set (playbin, "audio-sink", fakesink2, NULL);
223
224   g_object_set (playbin, "uri", uri, NULL);
225
226   return playbin;
227 }
228
229 DEFINE_TEST (test_missing_urisource_handler);
230
231 static void
232 test_missing_urisource_handler (void)
233 {
234   GstStructure *s;
235   GstMessage *msg;
236   GstElement *playbin;
237   GError *err = NULL;
238   GstBus *bus;
239
240   playbin = create_playbin ("chocchipcookie://withahint.of/cinnamon");
241
242   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
243       GST_STATE_CHANGE_SUCCESS);
244   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
245       GST_STATE_CHANGE_FAILURE);
246
247   /* there should be at least a missing-plugin message on the bus now and an
248    * error message; the missing-plugin message should be first */
249   bus = gst_element_get_bus (playbin);
250
251   msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
252   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
253   fail_unless (msg->structure != NULL);
254   s = msg->structure;
255   fail_unless (gst_structure_has_name (s, "missing-plugin"));
256   fail_unless (gst_structure_has_field_typed (s, "detail", G_TYPE_STRING));
257   fail_unless_equals_string (gst_structure_get_string (s, "detail"),
258       "chocchipcookie");
259   fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
260   fail_unless_equals_string (gst_structure_get_string (s, "type"), "urisource");
261   gst_message_unref (msg);
262
263   msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
264   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);
265
266   /* make sure the error is a CORE MISSING_PLUGIN one */
267   gst_message_parse_error (msg, &err, NULL);
268   fail_unless (err != NULL);
269   fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
270       "%s instead of core-error-quark", g_quark_to_string (err->domain));
271   fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
272       "code %u instead of GST_CORE_ERROR_MISSING_PLUGIN", err->code);
273   g_error_free (err);
274   gst_message_unref (msg);
275   gst_object_unref (bus);
276
277   gst_element_set_state (playbin, GST_STATE_NULL);
278   gst_object_unref (playbin);
279 }
280
281 DEFINE_TEST (test_missing_suburisource_handler);
282
283 static void
284 test_missing_suburisource_handler (void)
285 {
286   GstStructure *s;
287   GstMessage *msg;
288   GstElement *playbin;
289   GError *err = NULL;
290   GstBus *bus;
291
292   playbin = create_playbin ("file:///does/not/exis.t");
293
294   g_object_set (playbin, "suburi", "cookie://withahint.of/cinnamon", NULL);
295
296   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
297       GST_STATE_CHANGE_SUCCESS);
298   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
299       GST_STATE_CHANGE_FAILURE);
300
301   /* there should be at least a missing-plugin message on the bus now and an
302    * error message; the missing-plugin message should be first */
303   bus = gst_element_get_bus (playbin);
304
305   msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
306   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
307   fail_unless (msg->structure != NULL);
308   s = msg->structure;
309   fail_unless (gst_structure_has_name (s, "missing-plugin"));
310   fail_unless (gst_structure_has_field_typed (s, "detail", G_TYPE_STRING));
311   fail_unless_equals_string (gst_structure_get_string (s, "detail"), "cookie");
312   fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
313   fail_unless_equals_string (gst_structure_get_string (s, "type"), "urisource");
314   gst_message_unref (msg);
315
316   msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
317   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);
318
319   /* make sure the error is a CORE MISSING_PLUGIN one */
320   gst_message_parse_error (msg, &err, NULL);
321   fail_unless (err != NULL);
322   fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
323       "%s instead of core-error-quark", g_quark_to_string (err->domain));
324   fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
325       "code %u instead of GST_CORE_ERROR_MISSING_PLUGIN", err->code);
326   g_error_free (err);
327   gst_message_unref (msg);
328   gst_object_unref (bus);
329
330   gst_element_set_state (playbin, GST_STATE_NULL);
331   gst_object_unref (playbin);
332 }
333
334 DEFINE_TEST (test_missing_primary_decoder);
335
336 static void
337 test_missing_primary_decoder (void)
338 {
339   GstStructure *s;
340   GstMessage *msg;
341   GstElement *playbin;
342   GError *err = NULL;
343   GstBus *bus;
344   gchar *use_decodebin2 = getenv ("USE_DECODEBIN2");
345   gboolean decodebin2 = use_decodebin2 != NULL && *use_decodebin2 == '1';
346
347   fail_unless (gst_element_register (NULL, "codecsrc", GST_RANK_PRIMARY,
348           gst_codec_src_get_type ()));
349
350   playbin = create_playbin ("codec://");
351
352   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
353       GST_STATE_CHANGE_SUCCESS);
354   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
355       GST_STATE_CHANGE_ASYNC);
356
357   /* there should soon be at least a missing-plugin message on the bus and an
358    * error message; the missing-plugin message should be first */
359   bus = gst_element_get_bus (playbin);
360
361   msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
362   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
363   fail_unless (msg->structure != NULL);
364   s = msg->structure;
365   fail_unless (gst_structure_has_name (s, "missing-plugin"));
366   fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
367   fail_unless_equals_string (gst_structure_get_string (s, "type"), "decoder");
368   fail_unless (gst_structure_has_field_typed (s, "detail", GST_TYPE_CAPS));
369   gst_message_unref (msg);
370
371   msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
372   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);
373
374   /* make sure the error is a STREAM CODEC_NOT_FOUND one */
375   gst_message_parse_error (msg, &err, NULL);
376   fail_unless (err != NULL);
377   if (decodebin2) {
378     fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
379         "%s instead of core-error-quark", g_quark_to_string (err->domain));
380     fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
381         "code %u instead of GST_RESOURCE_ERROR_MISSING_PLUGIN", err->code);
382   } else {
383     fail_unless (err->domain == GST_STREAM_ERROR,
384         "error has wrong error domain " "%s instead of stream-error-quark",
385         g_quark_to_string (err->domain));
386     fail_unless (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND,
387         "error has wrong "
388         "code %u instead of GST_STREAM_ERROR_CODEC_NOT_FOUND", err->code);
389   }
390   g_error_free (err);
391   gst_message_unref (msg);
392   gst_object_unref (bus);
393
394   gst_element_set_state (playbin, GST_STATE_NULL);
395   gst_object_unref (playbin);
396 }
397
398 /*** redvideo:// source ***/
399
400 static GstURIType
401 gst_red_video_src_uri_get_type (void)
402 {
403   return GST_URI_SRC;
404 }
405
406 static gchar **
407 gst_red_video_src_uri_get_protocols (void)
408 {
409   static gchar *protocols[] = { (char *) "redvideo", NULL };
410
411   return protocols;
412 }
413
414 static const gchar *
415 gst_red_video_src_uri_get_uri (GstURIHandler * handler)
416 {
417   return "redvideo://";
418 }
419
420 static gboolean
421 gst_red_video_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
422 {
423   return (uri != NULL && g_str_has_prefix (uri, "redvideo:"));
424 }
425
426 static void
427 gst_red_video_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
428 {
429   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
430
431   iface->get_type = gst_red_video_src_uri_get_type;
432   iface->get_protocols = gst_red_video_src_uri_get_protocols;
433   iface->get_uri = gst_red_video_src_uri_get_uri;
434   iface->set_uri = gst_red_video_src_uri_set_uri;
435 }
436
437 static void
438 gst_red_video_src_init_type (GType type)
439 {
440   static const GInterfaceInfo uri_hdlr_info = {
441     gst_red_video_src_uri_handler_init, NULL, NULL
442   };
443
444   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &uri_hdlr_info);
445 }
446
447 typedef GstPushSrc GstRedVideoSrc;
448 typedef GstPushSrcClass GstRedVideoSrcClass;
449
450 GST_BOILERPLATE_FULL (GstRedVideoSrc, gst_red_video_src, GstPushSrc,
451     GST_TYPE_PUSH_SRC, gst_red_video_src_init_type);
452
453 static void
454 gst_red_video_src_base_init (gpointer klass)
455 {
456   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
457       GST_PAD_SRC, GST_PAD_ALWAYS,
458       GST_STATIC_CAPS ("video/x-raw-yuv, format=(fourcc)I420")
459       );
460   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
461
462   gst_element_class_add_static_pad_template (element_class, &src_templ);
463   gst_element_class_set_details_simple (element_class,
464       "Red Video Src", "Source/Video", "yep", "me");
465 }
466
467 static GstFlowReturn
468 gst_red_video_src_create (GstPushSrc * src, GstBuffer ** p_buf)
469 {
470   GstBuffer *buf;
471   GstCaps *caps;
472   guint8 *data;
473   guint w = 64, h = 64;
474   guint size;
475
476   size = w * h * 3 / 2;
477   buf = gst_buffer_new_and_alloc (size);
478   data = GST_BUFFER_DATA (buf);
479   memset (data, 76, w * h);
480   memset (data + (w * h), 85, (w * h) / 4);
481   memset (data + (w * h) + ((w * h) / 4), 255, (w * h) / 4);
482
483   caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC,
484       GST_MAKE_FOURCC ('I', '4', '2', '0'), "width", G_TYPE_INT, w, "height",
485       G_TYPE_INT, h, "framerate", GST_TYPE_FRACTION, 1, 1, NULL);
486   gst_buffer_set_caps (buf, caps);
487   gst_caps_unref (caps);
488
489   *p_buf = buf;
490   return GST_FLOW_OK;
491 }
492
493 static void
494 gst_red_video_src_class_init (GstRedVideoSrcClass * klass)
495 {
496   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
497
498   pushsrc_class->create = gst_red_video_src_create;
499 }
500
501 static void
502 gst_red_video_src_init (GstRedVideoSrc * src, GstRedVideoSrcClass * klass)
503 {
504 }
505
506 /*** codec:// source ***/
507
508 static GstURIType
509 gst_codec_src_uri_get_type (void)
510 {
511   return GST_URI_SRC;
512 }
513
514 static gchar **
515 gst_codec_src_uri_get_protocols (void)
516 {
517   static gchar *protocols[] = { (char *) "codec", NULL };
518
519   return protocols;
520 }
521
522 static const gchar *
523 gst_codec_src_uri_get_uri (GstURIHandler * handler)
524 {
525   return "codec://";
526 }
527
528 static gboolean
529 gst_codec_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
530 {
531   return (uri != NULL && g_str_has_prefix (uri, "codec:"));
532 }
533
534 static void
535 gst_codec_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
536 {
537   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
538
539   iface->get_type = gst_codec_src_uri_get_type;
540   iface->get_protocols = gst_codec_src_uri_get_protocols;
541   iface->get_uri = gst_codec_src_uri_get_uri;
542   iface->set_uri = gst_codec_src_uri_set_uri;
543 }
544
545 static void
546 gst_codec_src_init_type (GType type)
547 {
548   static const GInterfaceInfo uri_hdlr_info = {
549     gst_codec_src_uri_handler_init, NULL, NULL
550   };
551
552   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &uri_hdlr_info);
553 }
554
555 #undef parent_class
556 #define parent_class codec_src_parent_class
557
558 typedef GstPushSrc GstCodecSrc;
559 typedef GstPushSrcClass GstCodecSrcClass;
560
561 GST_BOILERPLATE_FULL (GstCodecSrc, gst_codec_src, GstPushSrc,
562     GST_TYPE_PUSH_SRC, gst_codec_src_init_type);
563
564 static void
565 gst_codec_src_base_init (gpointer klass)
566 {
567   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
568       GST_PAD_SRC, GST_PAD_ALWAYS,
569       GST_STATIC_CAPS ("application/x-codec")
570       );
571   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
572
573   gst_element_class_add_static_pad_template (element_class, &src_templ);
574   gst_element_class_set_details_simple (element_class,
575       "Codec Src", "Source/Video", "yep", "me");
576 }
577
578 static GstFlowReturn
579 gst_codec_src_create (GstPushSrc * src, GstBuffer ** p_buf)
580 {
581   GstBuffer *buf;
582   GstCaps *caps;
583
584   buf = gst_buffer_new_and_alloc (20);
585   memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
586
587   caps = gst_caps_new_simple ("application/x-codec", NULL);
588   gst_buffer_set_caps (buf, caps);
589   gst_caps_unref (caps);
590
591   *p_buf = buf;
592   return GST_FLOW_OK;
593 }
594
595 static void
596 gst_codec_src_class_init (GstCodecSrcClass * klass)
597 {
598   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
599
600   pushsrc_class->create = gst_codec_src_create;
601 }
602
603 static void
604 gst_codec_src_init (GstCodecSrc * src, GstCodecSrcClass * klass)
605 {
606 }
607
608 #endif /* GST_DISABLE_REGISTRY */
609
610
611 static Suite *
612 playbin_suite (void)
613 {
614   Suite *s = suite_create ("playbin");
615   TCase *tc_chain = tcase_create ("general");
616
617   suite_add_tcase (s, tc_chain);
618
619 #ifndef GST_DISABLE_REGISTRY
620   /* with the old decodebin */
621   tcase_add_test (tc_chain, test_sink_usage_video_only_stream_decodebin1);
622   tcase_add_test (tc_chain, test_suburi_error_wrongproto_decodebin1);
623   tcase_add_test (tc_chain, test_suburi_error_invalidfile_decodebin1);
624   tcase_add_test (tc_chain, test_suburi_error_unknowntype_decodebin1);
625   tcase_add_test (tc_chain, test_missing_urisource_handler_decodebin1);
626   tcase_add_test (tc_chain, test_missing_suburisource_handler_decodebin1);
627   tcase_add_test (tc_chain, test_missing_primary_decoder_decodebin1);
628
629   /* and again with decodebin2 */
630   tcase_add_test (tc_chain, test_missing_primary_decoder_decodebin2);
631   tcase_add_test (tc_chain, test_sink_usage_video_only_stream_decodebin2);
632   tcase_add_test (tc_chain, test_suburi_error_wrongproto_decodebin2);
633   tcase_add_test (tc_chain, test_suburi_error_invalidfile_decodebin2);
634   tcase_add_test (tc_chain, test_suburi_error_unknowntype_decodebin2);
635   tcase_add_test (tc_chain, test_missing_urisource_handler_decodebin2);
636   tcase_add_test (tc_chain, test_missing_suburisource_handler_decodebin2);
637
638   /* one day we might also want to have the following checks:
639    * tcase_add_test (tc_chain, test_missing_secondary_decoder_one_fatal);
640    * tcase_add_test (tc_chain, test_missing_secondary_decoder_two_fatal);
641    * tcase_add_test (tc_chain, test_missing_secondary_decoder_two_with_preroll);
642    */
643 #endif
644
645   return s;
646 }
647
648 GST_CHECK_MAIN (playbin);