1 /* GStreamer unit tests for playbin complex stream support
2  *
3  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
4  * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25 
26 #include <gst/check/gstcheck.h>
27 #include <gst/base/gstpushsrc.h>
28 #include <gst/base/gstbasesink.h>
29 #include <gst/audio/audio.h>
30 #include <gst/video/gstvideodecoder.h>
31 
32 #ifndef GST_DISABLE_REGISTRY
33 
34 #define NBUFFERS 100
35 
36 static GType gst_caps_src_get_type (void);
37 static GType gst_codec_demuxer_get_type (void);
38 static GType gst_codec_sink_get_type (void);
39 static GType gst_audio_codec_sink_get_type (void);
40 static GType gst_video_codec_sink_get_type (void);
41 static GType gst_video_decoder1_get_type (void);
42 static GType gst_video_decoder2_get_type (void);
43 static GType gst_video_sink1_get_type (void);
44 static GType gst_video_sink2_get_type (void);
45 
46 typedef struct _GstCapsSrc GstCapsSrc;
47 typedef GstPushSrcClass GstCapsSrcClass;
48 
49 struct _GstCapsSrc
50 {
51   GstPushSrc parent;
52 
53   GstCaps *caps;
54   gchar *uri;
55   gint nbuffers;
56 };
57 
58 static GstURIType
gst_caps_src_uri_get_type(GType type)59 gst_caps_src_uri_get_type (GType type)
60 {
61   return GST_URI_SRC;
62 }
63 
64 static const gchar *const *
gst_caps_src_uri_get_protocols(GType type)65 gst_caps_src_uri_get_protocols (GType type)
66 {
67   static const gchar *protocols[] = { "caps", NULL };
68 
69   return protocols;
70 }
71 
72 static gchar *
gst_caps_src_uri_get_uri(GstURIHandler * handler)73 gst_caps_src_uri_get_uri (GstURIHandler * handler)
74 {
75   GstCapsSrc *src = (GstCapsSrc *) handler;
76 
77   return g_strdup (src->uri);
78 }
79 
80 static gboolean
gst_caps_src_uri_set_uri(GstURIHandler * handler,const gchar * uri,GError ** error)81 gst_caps_src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
82     GError ** error)
83 {
84   GstCapsSrc *src = (GstCapsSrc *) handler;
85 
86   if (uri == NULL || !g_str_has_prefix (uri, "caps:"))
87     return FALSE;
88 
89   g_free (src->uri);
90   src->uri = g_strdup (uri);
91 
92   if (src->caps)
93     gst_caps_unref (src->caps);
94   src->caps = NULL;
95 
96   return TRUE;
97 }
98 
99 static void
gst_caps_src_uri_handler_init(gpointer g_iface,gpointer iface_data)100 gst_caps_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
101 {
102   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
103 
104   iface->get_type = gst_caps_src_uri_get_type;
105   iface->get_protocols = gst_caps_src_uri_get_protocols;
106   iface->get_uri = gst_caps_src_uri_get_uri;
107   iface->set_uri = gst_caps_src_uri_set_uri;
108 }
109 
110 G_DEFINE_TYPE_WITH_CODE (GstCapsSrc, gst_caps_src, GST_TYPE_PUSH_SRC,
111     G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
112         gst_caps_src_uri_handler_init));
113 
114 static void
gst_caps_src_finalize(GObject * object)115 gst_caps_src_finalize (GObject * object)
116 {
117   GstCapsSrc *src = (GstCapsSrc *) object;
118 
119   if (src->caps)
120     gst_caps_unref (src->caps);
121   src->caps = NULL;
122   g_free (src->uri);
123 
124   G_OBJECT_CLASS (gst_caps_src_parent_class)->finalize (object);
125 }
126 
127 static GstFlowReturn
gst_caps_src_create(GstPushSrc * psrc,GstBuffer ** p_buf)128 gst_caps_src_create (GstPushSrc * psrc, GstBuffer ** p_buf)
129 {
130   GstCapsSrc *src = (GstCapsSrc *) psrc;
131   GstBuffer *buf;
132 
133   if (src->nbuffers >= NBUFFERS) {
134     return GST_FLOW_EOS;
135   }
136 
137   if (!src->caps) {
138     if (!src->uri) {
139       return GST_FLOW_ERROR;
140     }
141 
142     src->caps = gst_caps_from_string (src->uri + sizeof ("caps"));
143     if (!src->caps) {
144       return GST_FLOW_ERROR;
145     }
146   }
147 
148   if (src->nbuffers == 0) {
149     gst_pad_push_event (GST_BASE_SRC_PAD (psrc),
150         gst_event_new_stream_start ("test"));
151     gst_pad_set_caps (GST_BASE_SRC_PAD (psrc), src->caps);
152   }
153 
154   buf = gst_buffer_new_wrapped (g_malloc0 (4), 4);
155   GST_BUFFER_TIMESTAMP (buf) =
156       gst_util_uint64_scale (src->nbuffers, GST_SECOND, 25);
157   src->nbuffers++;
158 
159   *p_buf = buf;
160   return GST_FLOW_OK;
161 }
162 
163 static void
gst_caps_src_class_init(GstCapsSrcClass * klass)164 gst_caps_src_class_init (GstCapsSrcClass * klass)
165 {
166   GObjectClass *gobject_class = (GObjectClass *) klass;
167   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
168   GstPushSrcClass *pushsrc_class = (GstPushSrcClass *) klass;
169   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
170       GST_PAD_SRC, GST_PAD_ALWAYS,
171       GST_STATIC_CAPS_ANY);
172 
173   gst_element_class_add_static_pad_template (element_class, &src_templ);
174   gst_element_class_set_metadata (element_class,
175       "CapsSource", "Source/Generic", "yep", "me");
176 
177   gobject_class->finalize = gst_caps_src_finalize;
178   pushsrc_class->create = gst_caps_src_create;
179 }
180 
181 static void
gst_caps_src_init(GstCapsSrc * src)182 gst_caps_src_init (GstCapsSrc * src)
183 {
184   gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
185 }
186 
187 typedef struct _GstCodecSink GstCodecSink;
188 typedef GstBaseSinkClass GstCodecSinkClass;
189 
190 struct _GstCodecSink
191 {
192   GstBaseSink parent;
193 
194   gboolean audio;
195   gboolean raw;
196   gint n_raw, n_compressed;
197 };
198 
199 G_DEFINE_TYPE (GstCodecSink, gst_codec_sink, GST_TYPE_BASE_SINK);
200 
201 static gboolean
gst_codec_sink_start(GstBaseSink * bsink)202 gst_codec_sink_start (GstBaseSink * bsink)
203 {
204   GstCodecSink *sink = (GstCodecSink *) bsink;
205 
206   sink->n_raw = 0;
207   sink->n_compressed = 0;
208 
209   return TRUE;
210 }
211 
212 static GstFlowReturn
gst_codec_sink_render(GstBaseSink * bsink,GstBuffer * buffer)213 gst_codec_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
214 {
215   GstCodecSink *sink = (GstCodecSink *) bsink;
216 
217   if (sink->raw)
218     sink->n_raw++;
219   else
220     sink->n_compressed++;
221 
222   return GST_FLOW_OK;
223 }
224 
225 static void
gst_codec_sink_class_init(GstCodecSinkClass * klass)226 gst_codec_sink_class_init (GstCodecSinkClass * klass)
227 {
228   GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
229 
230   basesink_class->start = gst_codec_sink_start;
231   basesink_class->render = gst_codec_sink_render;
232 }
233 
234 static void
gst_codec_sink_init(GstCodecSink * sink)235 gst_codec_sink_init (GstCodecSink * sink)
236 {
237 }
238 
239 typedef GstCodecSink GstAudioCodecSink;
240 typedef GstCodecSinkClass GstAudioCodecSinkClass;
241 
242 G_DEFINE_TYPE_WITH_CODE (GstAudioCodecSink, gst_audio_codec_sink,
243     gst_codec_sink_get_type (),
244     G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL));
245 
246 static void
gst_audio_codec_sink_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)247 gst_audio_codec_sink_set_property (GObject * object,
248     guint prop_id, const GValue * value, GParamSpec * pspec)
249 {
250   switch (prop_id) {
251     case 1:
252     case 2:
253       break;
254     default:
255       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
256       break;
257   }
258 }
259 
260 static void
gst_audio_codec_sink_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)261 gst_audio_codec_sink_get_property (GObject * object,
262     guint prop_id, GValue * value, GParamSpec * pspec)
263 {
264 
265   switch (prop_id) {
266     case 1:
267       g_value_set_double (value, 1.0);
268       break;
269     case 2:
270       g_value_set_boolean (value, FALSE);
271       break;
272     default:
273       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
274       break;
275   }
276 }
277 
278 static gboolean
gst_audio_codec_sink_set_caps(GstBaseSink * bsink,GstCaps * caps)279 gst_audio_codec_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
280 {
281   GstAudioCodecSink *sink = (GstAudioCodecSink *) bsink;
282   GstStructure *s;
283 
284   s = gst_caps_get_structure (caps, 0);
285 
286   if (gst_structure_has_name (s, "audio/x-raw")) {
287     sink->raw = TRUE;
288   } else if (gst_structure_has_name (s, "audio/x-compressed")) {
289     sink->raw = FALSE;
290   } else {
291     fail_unless (gst_structure_has_name (s, "audio/x-raw")
292         || gst_structure_has_name (s, "audio/x-compressed"));
293     return FALSE;
294   }
295 
296   return TRUE;
297 }
298 
299 static void
gst_audio_codec_sink_class_init(GstAudioCodecSinkClass * klass)300 gst_audio_codec_sink_class_init (GstAudioCodecSinkClass * klass)
301 {
302   GObjectClass *gobject_class = (GObjectClass *) klass;
303   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
304   GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
305   static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
306       GST_PAD_SINK, GST_PAD_ALWAYS,
307       GST_STATIC_CAPS ("audio/x-raw; audio/x-compressed")
308       );
309 
310   gobject_class->set_property = gst_audio_codec_sink_set_property;
311   gobject_class->get_property = gst_audio_codec_sink_get_property;
312 
313   g_object_class_install_property (gobject_class,
314       1,
315       g_param_spec_double ("volume", "Volume",
316           "Linear volume of this stream, 1.0=100%", 0.0, 10.0,
317           1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
318   g_object_class_install_property (gobject_class,
319       2,
320       g_param_spec_boolean ("mute", "Mute",
321           "Mute", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
322 
323   gst_element_class_add_static_pad_template (element_class, &sink_templ);
324   gst_element_class_set_metadata (element_class,
325       "AudioCodecSink", "Sink/Audio", "yep", "me");
326 
327   basesink_class->set_caps = gst_audio_codec_sink_set_caps;
328 }
329 
330 static void
gst_audio_codec_sink_init(GstAudioCodecSink * sink)331 gst_audio_codec_sink_init (GstAudioCodecSink * sink)
332 {
333   sink->audio = TRUE;
334 }
335 
336 typedef GstCodecSink GstVideoCodecSink;
337 typedef GstCodecSinkClass GstVideoCodecSinkClass;
338 
339 G_DEFINE_TYPE (GstVideoCodecSink, gst_video_codec_sink,
340     gst_codec_sink_get_type ());
341 
342 static gboolean
gst_video_codec_sink_set_caps(GstBaseSink * bsink,GstCaps * caps)343 gst_video_codec_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
344 {
345   GstVideoCodecSink *sink = (GstVideoCodecSink *) bsink;
346   GstStructure *s;
347 
348   s = gst_caps_get_structure (caps, 0);
349 
350   if (gst_structure_has_name (s, "video/x-raw")) {
351     sink->raw = TRUE;
352   } else if (gst_structure_has_name (s, "video/x-compressed")) {
353     sink->raw = FALSE;
354   } else {
355     fail_unless (gst_structure_has_name (s, "video/x-raw")
356         || gst_structure_has_name (s, "video/x-compressed"));
357     return FALSE;
358   }
359 
360   return TRUE;
361 }
362 
363 static void
gst_video_codec_sink_class_init(GstVideoCodecSinkClass * klass)364 gst_video_codec_sink_class_init (GstVideoCodecSinkClass * klass)
365 {
366   GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
367   static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
368       GST_PAD_SINK, GST_PAD_ALWAYS,
369       GST_STATIC_CAPS ("video/x-raw; video/x-compressed")
370       );
371   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
372 
373   gst_element_class_add_static_pad_template (element_class, &sink_templ);
374   gst_element_class_set_metadata (element_class,
375       "VideoCodecSink", "Sink/Video", "yep", "me");
376 
377   basesink_class->set_caps = gst_video_codec_sink_set_caps;
378 }
379 
380 static void
gst_video_codec_sink_init(GstVideoCodecSink * sink)381 gst_video_codec_sink_init (GstVideoCodecSink * sink)
382 {
383   sink->audio = FALSE;
384 }
385 
386 typedef struct _GstCodecDemuxer GstCodecDemuxer;
387 typedef GstElementClass GstCodecDemuxerClass;
388 
389 struct _GstCodecDemuxer
390 {
391   GstElement parent;
392 
393   GstPad *sinkpad;
394   GstPad *srcpad0, *srcpad1;
395 
396   GstEvent *newseg_event;
397 };
398 
399 #define STREAM_TYPES "{ " \
400     "none, " \
401     "raw-audio, " \
402     "compressed-audio, " \
403     "raw-video, " \
404     "compressed-video " \
405     "}"
406 
407 static GstStaticPadTemplate cd_sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
408     GST_PAD_SINK, GST_PAD_ALWAYS,
409     GST_STATIC_CAPS ("application/x-container,"
410         " stream0 = (string)" STREAM_TYPES " ,"
411         " stream1 = (string)" STREAM_TYPES)
412     );
413 static GstStaticPadTemplate cd_src_templ = GST_STATIC_PAD_TEMPLATE ("src_%u",
414     GST_PAD_SRC, GST_PAD_SOMETIMES,
415     GST_STATIC_CAPS ("audio/x-raw; audio/x-compressed; "
416         "video/x-raw; video/x-compressed")
417     );
418 
419 G_DEFINE_TYPE (GstCodecDemuxer, gst_codec_demuxer, GST_TYPE_ELEMENT);
420 
421 static void
gst_codec_demuxer_finalize(GObject * object)422 gst_codec_demuxer_finalize (GObject * object)
423 {
424   GstCodecDemuxer *demux = (GstCodecDemuxer *) object;
425 
426   if (demux->newseg_event)
427     gst_event_unref (demux->newseg_event);
428   demux->newseg_event = NULL;
429 
430   G_OBJECT_CLASS (gst_codec_demuxer_parent_class)->finalize (object);
431 }
432 
433 static void
gst_codec_demuxer_class_init(GstCodecDemuxerClass * klass)434 gst_codec_demuxer_class_init (GstCodecDemuxerClass * klass)
435 {
436   GObjectClass *gobject_class = (GObjectClass *) klass;
437   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
438 
439   gobject_class->finalize = gst_codec_demuxer_finalize;
440 
441   gst_element_class_add_static_pad_template (element_class, &cd_sink_templ);
442   gst_element_class_add_static_pad_template (element_class, &cd_src_templ);
443   gst_element_class_set_metadata (element_class,
444       "CodecDemuxer", "Codec/Demuxer", "yep", "me");
445 }
446 
447 static GstFlowReturn
gst_codec_demuxer_chain(GstPad * pad,GstObject * parent,GstBuffer * buf)448 gst_codec_demuxer_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
449 {
450   GstCodecDemuxer *demux = (GstCodecDemuxer *) parent;
451   GstFlowReturn ret0 = GST_FLOW_OK, ret1 = GST_FLOW_OK;
452 
453   if (demux->newseg_event) {
454     if (demux->srcpad0)
455       gst_pad_push_event (demux->srcpad0, gst_event_ref (demux->newseg_event));
456     if (demux->srcpad1)
457       gst_pad_push_event (demux->srcpad1, gst_event_ref (demux->newseg_event));
458     gst_event_unref (demux->newseg_event);
459     demux->newseg_event = NULL;
460   }
461 
462   if (demux->srcpad0) {
463     GstBuffer *outbuf = gst_buffer_copy (buf);
464     ret0 = gst_pad_push (demux->srcpad0, outbuf);
465   }
466   if (demux->srcpad1) {
467     GstBuffer *outbuf = gst_buffer_copy (buf);
468     ret1 = gst_pad_push (demux->srcpad1, outbuf);
469   }
470   gst_buffer_unref (buf);
471 
472   if (ret0 == GST_FLOW_NOT_LINKED && ret1 == GST_FLOW_NOT_LINKED)
473     return GST_FLOW_NOT_LINKED;
474   if (ret0 == GST_FLOW_OK && ret1 == GST_FLOW_OK)
475     return GST_FLOW_OK;
476 
477   return MIN (ret0, ret1);
478 }
479 
480 static void
gst_codec_demuxer_setup_pad(GstCodecDemuxer * demux,GstPad ** pad,const gchar * streaminfo)481 gst_codec_demuxer_setup_pad (GstCodecDemuxer * demux, GstPad ** pad,
482     const gchar * streaminfo)
483 {
484   if (g_str_equal (streaminfo, "none")) {
485     if (*pad) {
486       gst_pad_set_active (*pad, FALSE);
487       gst_element_remove_pad (GST_ELEMENT (demux), *pad);
488       *pad = NULL;
489     }
490   } else {
491     GstCaps *caps;
492 
493     if (!*pad) {
494       GstPadTemplate *templ;
495 
496       templ =
497           gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (demux),
498           "src_%u");
499       if (pad == &demux->srcpad0)
500         *pad = gst_pad_new_from_template (templ, "src_0");
501       else
502         *pad = gst_pad_new_from_template (templ, "src_1");
503       gst_pad_set_active (*pad, TRUE);
504       gst_pad_use_fixed_caps (*pad);
505       gst_element_add_pad (GST_ELEMENT (demux), *pad);
506     }
507 
508     if (g_str_equal (streaminfo, "raw-video")) {
509       caps = gst_caps_new_simple ("video/x-raw",
510           "format", G_TYPE_STRING, "I420",
511           "width", G_TYPE_INT, 320,
512           "height", G_TYPE_INT, 240,
513           "framerate", GST_TYPE_FRACTION, 25, 1,
514           "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL);
515     } else if (g_str_equal (streaminfo, "compressed-video")) {
516       caps = gst_caps_new_empty_simple ("video/x-compressed");
517     } else if (g_str_equal (streaminfo, "raw-audio")) {
518       caps = gst_caps_new_simple ("audio/x-raw",
519           "format", G_TYPE_STRING, GST_AUDIO_NE (S16),
520           "layout", G_TYPE_STRING, "interleaved",
521           "rate", G_TYPE_INT, 48000, "channels", G_TYPE_INT, 2, NULL);
522     } else {
523       caps = gst_caps_new_empty_simple ("audio/x-compressed");
524     }
525 
526     gst_pad_push_event (*pad, gst_event_new_stream_start ("test"));
527 
528     gst_pad_set_caps (*pad, caps);
529     gst_caps_unref (caps);
530   }
531 }
532 
533 static gboolean
gst_codec_demuxer_setcaps(GstPad * pad,GstObject * parent,GstCaps * caps)534 gst_codec_demuxer_setcaps (GstPad * pad, GstObject * parent, GstCaps * caps)
535 {
536   GstCodecDemuxer *demux = (GstCodecDemuxer *) parent;
537   GstStructure *s;
538   const gchar *streaminfo;
539 
540   s = gst_caps_get_structure (caps, 0);
541 
542   streaminfo = gst_structure_get_string (s, "stream0");
543   gst_codec_demuxer_setup_pad (demux, &demux->srcpad0, streaminfo);
544 
545   streaminfo = gst_structure_get_string (s, "stream1");
546   gst_codec_demuxer_setup_pad (demux, &demux->srcpad1, streaminfo);
547 
548   return TRUE;
549 }
550 
551 static gboolean
gst_codec_demuxer_event(GstPad * pad,GstObject * parent,GstEvent * event)552 gst_codec_demuxer_event (GstPad * pad, GstObject * parent, GstEvent * event)
553 {
554   GstCodecDemuxer *demux = (GstCodecDemuxer *) parent;
555   gboolean ret = TRUE;
556 
557   /* The single newsegment event is pushed when the pads are created */
558   switch (GST_EVENT_TYPE (event)) {
559     case GST_EVENT_CAPS:
560     {
561       GstCaps *caps;
562 
563       gst_event_parse_caps (event, &caps);
564       ret = gst_codec_demuxer_setcaps (pad, parent, caps);
565       break;
566     }
567     case GST_EVENT_SEGMENT:
568       gst_event_replace (&demux->newseg_event, event);
569       break;
570     default:
571       if (demux->srcpad0)
572         ret = ret && gst_pad_push_event (demux->srcpad0, gst_event_ref (event));
573       if (demux->srcpad1)
574         ret = ret && gst_pad_push_event (demux->srcpad1, gst_event_ref (event));
575       break;
576   }
577   gst_event_unref (event);
578 
579   return ret;
580 }
581 
582 static void
gst_codec_demuxer_init(GstCodecDemuxer * demux)583 gst_codec_demuxer_init (GstCodecDemuxer * demux)
584 {
585   demux->sinkpad = gst_pad_new_from_static_template (&cd_sink_templ, "sink");
586   gst_pad_set_chain_function (demux->sinkpad,
587       GST_DEBUG_FUNCPTR (gst_codec_demuxer_chain));
588   gst_pad_set_event_function (demux->sinkpad,
589       GST_DEBUG_FUNCPTR (gst_codec_demuxer_event));
590   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
591 }
592 
593 typedef struct _GstVideoDecoder1 GstVideoDecoder1;
594 typedef GstVideoDecoderClass GstVideoDecoder1Class;
595 
596 typedef struct _GstVideoDecoder2 GstVideoDecoder2;
597 typedef GstVideoDecoderClass GstVideoDecoder2Class;
598 
599 typedef struct _GstVideoSink1 GstVideoSink1;
600 typedef GstBaseSinkClass GstVideoSink1Class;
601 
602 typedef struct _GstVideoSink2 GstVideoSink2;
603 typedef GstBaseSinkClass GstVideoSink2Class;
604 
605 struct _GstVideoDecoder1
606 {
607   GstVideoDecoder parent;
608 };
609 
610 struct _GstVideoDecoder2
611 {
612   GstVideoDecoder parent;
613 };
614 
615 struct _GstVideoSink1
616 {
617   GstBaseSink parent;
618 };
619 
620 struct _GstVideoSink2
621 {
622   GstBaseSink parent;
623 };
624 
625 #define GST_CAPS_FEATURE_MEMORY_FAKE "memory:FakeMem"
626 
627 G_DEFINE_TYPE (GstVideoDecoder1, gst_video_decoder1, GST_TYPE_VIDEO_DECODER);
628 G_DEFINE_TYPE (GstVideoDecoder2, gst_video_decoder2, GST_TYPE_VIDEO_DECODER);
629 G_DEFINE_TYPE (GstVideoSink1, gst_video_sink1, GST_TYPE_BASE_SINK);
630 G_DEFINE_TYPE (GstVideoSink2, gst_video_sink2, GST_TYPE_BASE_SINK);
631 
632 static void
gst_video_sink1_class_init(GstVideoSink1Class * klass)633 gst_video_sink1_class_init (GstVideoSink1Class * klass)
634 {
635   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
636 
637   static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
638       GST_PAD_SINK, GST_PAD_ALWAYS,
639       GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
640           (GST_CAPS_FEATURE_MEMORY_FAKE,
641               GST_VIDEO_FORMATS_ALL) ";"
642           GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL))
643       );
644 
645   gst_element_class_add_static_pad_template (element_class, &sink_templ);
646 
647   gst_element_class_set_static_metadata (element_class,
648       "Fake Video Sink1", "Sink/Video",
649       "fake sink1", "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
650 }
651 
652 static void
gst_video_sink1_init(GstVideoSink1 * sink)653 gst_video_sink1_init (GstVideoSink1 * sink)
654 {
655 }
656 
657 static void
gst_video_sink2_class_init(GstVideoSink2Class * klass)658 gst_video_sink2_class_init (GstVideoSink2Class * klass)
659 {
660   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
661 
662   static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
663       GST_PAD_SINK, GST_PAD_ALWAYS,
664       GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)));
665 
666   gst_element_class_add_static_pad_template (element_class, &sink_templ);
667 
668   gst_element_class_set_static_metadata (element_class,
669       "Fake Video Sink2", "Sink/Video",
670       "fake sink2", "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
671 }
672 
673 static void
gst_video_sink2_init(GstVideoSink2 * sink)674 gst_video_sink2_init (GstVideoSink2 * sink)
675 {
676 }
677 
678 static GstFlowReturn
fake_theora_dec_handle_frame(GstVideoDecoder * bdec,GstVideoCodecFrame * frame)679 fake_theora_dec_handle_frame (GstVideoDecoder * bdec,
680     GstVideoCodecFrame * frame)
681 {
682   /* the width and height are hard-coded for ../../files/theora-vorbis.ogg */
683   gst_video_codec_state_unref (gst_video_decoder_set_output_state (bdec,
684           GST_VIDEO_FORMAT_NV12, 320, 240, NULL));
685   gst_video_decoder_allocate_output_frame (bdec, frame);
686   return gst_video_decoder_finish_frame (bdec, frame);
687 }
688 
689 static void
gst_video_decoder1_class_init(GstVideoDecoder1Class * klass)690 gst_video_decoder1_class_init (GstVideoDecoder1Class * klass)
691 {
692   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
693   GstVideoDecoderClass *vd_class = GST_VIDEO_DECODER_CLASS (klass);
694 
695   static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
696       GST_PAD_SINK, GST_PAD_ALWAYS,
697       GST_STATIC_CAPS ("video/x-theora"));
698 
699   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
700       GST_PAD_SRC, GST_PAD_ALWAYS,
701       GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
702           (GST_CAPS_FEATURE_MEMORY_FAKE,
703               GST_VIDEO_FORMATS_ALL) ";"
704           GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)));
705 
706   gst_element_class_add_static_pad_template (element_class, &sink_templ);
707   gst_element_class_add_static_pad_template (element_class, &src_templ);
708   gst_element_class_set_static_metadata (element_class,
709       "Fake theora video decoder1", "Codec/Decoder/Video",
710       "decode theora stream",
711       "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
712 
713   vd_class->handle_frame = fake_theora_dec_handle_frame;
714 }
715 
716 static void
gst_video_decoder1_init(GstVideoDecoder1 * dec1)717 gst_video_decoder1_init (GstVideoDecoder1 * dec1)
718 {
719 }
720 
721 static void
gst_video_decoder2_class_init(GstVideoDecoder2Class * klass)722 gst_video_decoder2_class_init (GstVideoDecoder2Class * klass)
723 {
724   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
725   GstVideoDecoderClass *vd_class = GST_VIDEO_DECODER_CLASS (klass);
726 
727   static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
728       GST_PAD_SINK, GST_PAD_ALWAYS,
729       GST_STATIC_CAPS ("video/x-theora"));
730 
731   static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
732       GST_PAD_SRC, GST_PAD_ALWAYS,
733       GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)));
734 
735   gst_element_class_add_static_pad_template (element_class, &sink_templ);
736   gst_element_class_add_static_pad_template (element_class, &src_templ);
737   gst_element_class_set_static_metadata (element_class,
738       "Fake theora video decoder2", "Codec/Decoder/Video",
739       "decode theora stream",
740       "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
741 
742   vd_class->handle_frame = fake_theora_dec_handle_frame;
743 }
744 
745 static void
gst_video_decoder2_init(GstVideoDecoder2 * dec2)746 gst_video_decoder2_init (GstVideoDecoder2 * dec2)
747 {
748 }
749 
750 /****
751  * Start of the tests
752  ***/
753 
754 static void
pipeline_deep_notify_caps_cb(GstObject * pipeline,GstObject * object,GParamSpec * pspec,GstElement ** dec)755 pipeline_deep_notify_caps_cb (GstObject * pipeline,
756     GstObject * object, GParamSpec * pspec, GstElement ** dec)
757 {
758   GstObject *pad_parent;
759 
760   if (!GST_IS_PAD (object))
761     return;
762 
763   pad_parent = gst_object_get_parent (object);
764 
765   if (GST_IS_ELEMENT (pad_parent) && *dec == NULL) {
766     GstElementFactory *factory;
767     GstElement *element;
768     const gchar *klass;
769 
770     element = GST_ELEMENT_CAST (pad_parent);
771     if ((factory = gst_element_get_factory (element)) &&
772         (klass =
773             gst_element_factory_get_metadata (factory,
774                 GST_ELEMENT_METADATA_KLASS)) && strstr (klass, "Video")
775         && strstr (klass, "Decoder")) {
776       *dec = gst_object_ref (element);
777     }
778   }
779   if (pad_parent)
780     gst_object_unref (pad_parent);
781 }
782 
783 static GstElement *
create_playbin(const gchar * uri,gboolean set_sink)784 create_playbin (const gchar * uri, gboolean set_sink)
785 {
786   GstElement *playbin, *sink;
787 
788   playbin = gst_element_factory_make ("playbin", "playbin");
789   fail_unless (playbin != NULL, "Failed to create playbin element");
790 
791   if (set_sink) {
792     sink = gst_element_factory_make ("videocodecsink", NULL);
793     fail_unless (sink != NULL, "Failed to create videocodecsink element");
794 
795     /* Set sync to FALSE to prevent buffers from being dropped because
796      * they're too late */
797     g_object_set (sink, "sync", FALSE, NULL);
798 
799     g_object_set (playbin, "video-sink", sink, NULL);
800 
801     sink = gst_element_factory_make ("audiocodecsink", NULL);
802     fail_unless (sink != NULL, "Failed to create audiocodecsink");
803 
804     /* Set sync to FALSE to prevent buffers from being dropped because
805      * they're too late */
806     g_object_set (sink, "sync", FALSE, NULL);
807 
808     g_object_set (playbin, "audio-sink", sink, NULL);
809   }
810 
811   g_object_set (playbin, "uri", uri, NULL);
812 
813   return playbin;
814 }
815 
GST_START_TEST(test_autoplug_decoder_sink_combination)816 GST_START_TEST (test_autoplug_decoder_sink_combination)
817 {
818   GstElement *playbin;
819   GstElement *decoder = NULL;
820   GstElement *sink, *asink;
821   gchar *path, *uri;
822 
823   fail_unless (gst_element_register (NULL, "faketheoradec1",
824           GST_RANK_PRIMARY + 1, gst_video_decoder1_get_type ()));
825   fail_unless (gst_element_register (NULL, "faketheoradec2",
826           GST_RANK_PRIMARY + 1, gst_video_decoder2_get_type ()));
827   fail_unless (gst_element_register (NULL, "fakevideosink1",
828           GST_RANK_PRIMARY + 1, gst_video_sink1_get_type ()));
829   fail_unless (gst_element_register (NULL, "fakevideosink2",
830           GST_RANK_PRIMARY + 1, gst_video_sink2_get_type ()));
831 
832   path = g_build_filename (GST_TEST_FILES_PATH, "theora-vorbis.ogg", NULL);
833   uri = gst_filename_to_uri (path, NULL);
834   g_free (path);
835 
836   playbin = create_playbin (uri, FALSE);
837   g_free (uri);
838 
839   asink = gst_element_factory_make ("fakesink", NULL);
840   g_object_set (asink, "sync", TRUE, NULL);
841   g_object_set (playbin, "audio-sink", asink, NULL);
842 
843   g_signal_connect (playbin, "deep-notify::caps",
844       G_CALLBACK (pipeline_deep_notify_caps_cb), &decoder);
845 
846   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
847       GST_STATE_CHANGE_SUCCESS);
848   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
849       GST_STATE_CHANGE_ASYNC);
850   fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, -1),
851       GST_STATE_CHANGE_SUCCESS);
852 
853   /* there shouldn't be any errors */
854   fail_if (gst_bus_poll (GST_ELEMENT_BUS (playbin), GST_MESSAGE_ERROR,
855           0) != NULL);
856 
857   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
858   fail_unless (sink != NULL);
859   {
860     fail_unless (G_TYPE_FROM_INSTANCE (sink) == gst_video_sink1_get_type ());
861     gst_object_unref (sink);
862   }
863 
864   fail_unless (decoder != NULL);
865   {
866     fail_unless (G_TYPE_FROM_INSTANCE (decoder) ==
867         gst_video_decoder1_get_type ());
868     gst_object_unref (decoder);
869   }
870 
871   gst_element_set_state (playbin, GST_STATE_NULL);
872   gst_object_unref (playbin);
873 }
874 
875 GST_END_TEST;
GST_START_TEST(test_raw_single_video_stream_manual_sink)876 GST_START_TEST (test_raw_single_video_stream_manual_sink)
877 {
878   GstMessage *msg;
879   GstElement *playbin;
880   GstElement *sink;
881   GstBus *bus;
882   gboolean done = FALSE;
883 
884   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
885           gst_caps_src_get_type ()));
886   fail_unless (gst_element_register (NULL, "audiocodecsink",
887           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
888   fail_unless (gst_element_register (NULL, "videocodecsink",
889           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
890 
891   playbin =
892       create_playbin
893       ("caps:video/x-raw, "
894       "format=(string)I420, "
895       "width=(int)320, "
896       "height=(int)240, "
897       "framerate=(fraction)0/1, " "pixel-aspect-ratio=(fraction)1/1", TRUE);
898 
899   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
900       GST_STATE_CHANGE_SUCCESS);
901   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
902       GST_STATE_CHANGE_ASYNC);
903 
904   bus = gst_element_get_bus (playbin);
905 
906   while (!done) {
907     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
908 
909     switch (GST_MESSAGE_TYPE (msg)) {
910       case GST_MESSAGE_EOS:
911         done = TRUE;
912         break;
913       case GST_MESSAGE_ERROR:
914         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
915         break;
916       default:
917         break;
918     }
919     gst_message_unref (msg);
920   }
921   gst_object_unref (bus);
922 
923   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
924   fail_unless (sink != NULL);
925   {
926     GstVideoCodecSink *csink;
927 
928     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
929         gst_video_codec_sink_get_type ());
930     csink = (GstVideoCodecSink *) sink;
931     fail_unless (csink->audio == FALSE);
932     fail_unless (csink->raw == TRUE);
933     fail_unless_equals_int (csink->n_raw, NBUFFERS);
934     fail_unless_equals_int (csink->n_compressed, 0);
935     gst_object_unref (sink);
936   }
937 
938   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
939   fail_unless (sink != NULL);
940   {
941     GstAudioCodecSink *csink;
942 
943     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
944         gst_audio_codec_sink_get_type ());
945     csink = (GstAudioCodecSink *) sink;
946     fail_unless (csink->audio == TRUE);
947     fail_unless (csink->raw == FALSE);
948     fail_unless_equals_int (csink->n_raw, 0);
949     fail_unless_equals_int (csink->n_compressed, 0);
950     gst_object_unref (sink);
951   }
952 
953   gst_element_set_state (playbin, GST_STATE_NULL);
954   gst_object_unref (playbin);
955 }
956 
957 GST_END_TEST;
958 
GST_START_TEST(test_compressed_single_video_stream_manual_sink)959 GST_START_TEST (test_compressed_single_video_stream_manual_sink)
960 {
961   GstMessage *msg;
962   GstElement *playbin;
963   GstElement *sink;
964   GstBus *bus;
965   gboolean done = FALSE;
966 
967   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
968           gst_caps_src_get_type ()));
969   fail_unless (gst_element_register (NULL, "audiocodecsink",
970           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
971   fail_unless (gst_element_register (NULL, "videocodecsink",
972           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
973 
974   playbin = create_playbin ("caps:video/x-compressed", TRUE);
975 
976   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
977       GST_STATE_CHANGE_SUCCESS);
978   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
979       GST_STATE_CHANGE_ASYNC);
980 
981   bus = gst_element_get_bus (playbin);
982 
983   while (!done) {
984     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
985 
986     switch (GST_MESSAGE_TYPE (msg)) {
987       case GST_MESSAGE_EOS:
988         done = TRUE;
989         break;
990       case GST_MESSAGE_ERROR:
991         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
992         break;
993       default:
994         break;
995     }
996     gst_message_unref (msg);
997   }
998   gst_object_unref (bus);
999 
1000   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1001   fail_unless (sink != NULL);
1002   {
1003     GstVideoCodecSink *csink;
1004 
1005     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1006         gst_video_codec_sink_get_type ());
1007     csink = (GstVideoCodecSink *) sink;
1008     fail_unless (csink->audio == FALSE);
1009     fail_unless (csink->raw == FALSE);
1010     fail_unless_equals_int (csink->n_raw, 0);
1011     fail_unless_equals_int (csink->n_compressed, NBUFFERS);
1012     gst_object_unref (sink);
1013   }
1014 
1015   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1016   fail_unless (sink != NULL);
1017   {
1018     GstAudioCodecSink *csink;
1019 
1020     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1021         gst_audio_codec_sink_get_type ());
1022     csink = (GstAudioCodecSink *) sink;
1023     fail_unless (csink->audio == TRUE);
1024     fail_unless (csink->raw == FALSE);
1025     fail_unless_equals_int (csink->n_raw, 0);
1026     fail_unless_equals_int (csink->n_compressed, 0);
1027     gst_object_unref (sink);
1028   }
1029 
1030   gst_element_set_state (playbin, GST_STATE_NULL);
1031   gst_object_unref (playbin);
1032 }
1033 
1034 GST_END_TEST;
1035 
GST_START_TEST(test_raw_single_video_stream_demuxer_manual_sink)1036 GST_START_TEST (test_raw_single_video_stream_demuxer_manual_sink)
1037 {
1038   GstMessage *msg;
1039   GstElement *playbin;
1040   GstElement *sink;
1041   GstBus *bus;
1042   gboolean done = FALSE;
1043 
1044   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1045           gst_caps_src_get_type ()));
1046   fail_unless (gst_element_register (NULL, "codecdemuxer",
1047           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1048   fail_unless (gst_element_register (NULL, "audiocodecsink",
1049           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1050   fail_unless (gst_element_register (NULL, "videocodecsink",
1051           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1052 
1053   playbin = create_playbin ("caps:application/x-container, "
1054       "stream0=(string)raw-video, " "stream1=(string)none", TRUE);
1055 
1056   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1057       GST_STATE_CHANGE_SUCCESS);
1058   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1059       GST_STATE_CHANGE_ASYNC);
1060 
1061   bus = gst_element_get_bus (playbin);
1062 
1063   while (!done) {
1064     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1065 
1066     switch (GST_MESSAGE_TYPE (msg)) {
1067       case GST_MESSAGE_EOS:
1068         done = TRUE;
1069         break;
1070       case GST_MESSAGE_ERROR:
1071         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1072         break;
1073       default:
1074         break;
1075     }
1076     gst_message_unref (msg);
1077   }
1078   gst_object_unref (bus);
1079 
1080   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1081   fail_unless (sink != NULL);
1082   {
1083     GstVideoCodecSink *csink;
1084 
1085     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1086         gst_video_codec_sink_get_type ());
1087     csink = (GstVideoCodecSink *) sink;
1088     fail_unless (csink->audio == FALSE);
1089     fail_unless (csink->raw == TRUE);
1090     fail_unless_equals_int (csink->n_raw, NBUFFERS);
1091     fail_unless_equals_int (csink->n_compressed, 0);
1092     gst_object_unref (sink);
1093   }
1094 
1095   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1096   fail_unless (sink != NULL);
1097   {
1098     GstAudioCodecSink *csink;
1099 
1100     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1101         gst_audio_codec_sink_get_type ());
1102     csink = (GstAudioCodecSink *) sink;
1103     fail_unless (csink->audio == TRUE);
1104     fail_unless (csink->raw == FALSE);
1105     fail_unless_equals_int (csink->n_raw, 0);
1106     fail_unless_equals_int (csink->n_compressed, 0);
1107     gst_object_unref (sink);
1108   }
1109 
1110   gst_element_set_state (playbin, GST_STATE_NULL);
1111   gst_object_unref (playbin);
1112 }
1113 
1114 GST_END_TEST;
1115 
GST_START_TEST(test_compressed_single_video_stream_demuxer_manual_sink)1116 GST_START_TEST (test_compressed_single_video_stream_demuxer_manual_sink)
1117 {
1118   GstMessage *msg;
1119   GstElement *playbin;
1120   GstElement *sink;
1121   GstBus *bus;
1122   gboolean done = FALSE;
1123 
1124   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1125           gst_caps_src_get_type ()));
1126   fail_unless (gst_element_register (NULL, "codecdemuxer",
1127           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1128   fail_unless (gst_element_register (NULL, "audiocodecsink",
1129           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1130   fail_unless (gst_element_register (NULL, "videocodecsink",
1131           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1132 
1133   playbin = create_playbin ("caps:application/x-container, "
1134       "stream0=(string)compressed-video, " "stream1=(string)none", TRUE);
1135 
1136   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1137       GST_STATE_CHANGE_SUCCESS);
1138   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1139       GST_STATE_CHANGE_ASYNC);
1140 
1141   bus = gst_element_get_bus (playbin);
1142 
1143   while (!done) {
1144     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1145 
1146     switch (GST_MESSAGE_TYPE (msg)) {
1147       case GST_MESSAGE_EOS:
1148         done = TRUE;
1149         break;
1150       case GST_MESSAGE_ERROR:
1151         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1152         break;
1153       default:
1154         break;
1155     }
1156     gst_message_unref (msg);
1157   }
1158   gst_object_unref (bus);
1159 
1160   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1161   fail_unless (sink != NULL);
1162   {
1163     GstVideoCodecSink *csink;
1164 
1165     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1166         gst_video_codec_sink_get_type ());
1167     csink = (GstVideoCodecSink *) sink;
1168     fail_unless (csink->audio == FALSE);
1169     fail_unless (csink->raw == FALSE);
1170     fail_unless_equals_int (csink->n_raw, 0);
1171     fail_unless_equals_int (csink->n_compressed, NBUFFERS);
1172     gst_object_unref (sink);
1173   }
1174 
1175   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1176   fail_unless (sink != NULL);
1177   {
1178     GstAudioCodecSink *csink;
1179 
1180     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1181         gst_audio_codec_sink_get_type ());
1182     csink = (GstAudioCodecSink *) sink;
1183     fail_unless (csink->audio == TRUE);
1184     fail_unless (csink->raw == FALSE);
1185     fail_unless_equals_int (csink->n_raw, 0);
1186     fail_unless_equals_int (csink->n_compressed, 0);
1187     gst_object_unref (sink);
1188   }
1189 
1190   gst_element_set_state (playbin, GST_STATE_NULL);
1191   gst_object_unref (playbin);
1192 }
1193 
1194 GST_END_TEST;
1195 
GST_START_TEST(test_raw_single_audio_stream_manual_sink)1196 GST_START_TEST (test_raw_single_audio_stream_manual_sink)
1197 {
1198   GstMessage *msg;
1199   GstElement *playbin;
1200   GstElement *sink;
1201   GstBus *bus;
1202   gboolean done = FALSE;
1203 
1204   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1205           gst_caps_src_get_type ()));
1206   fail_unless (gst_element_register (NULL, "audiocodecsink",
1207           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1208   fail_unless (gst_element_register (NULL, "videocodecsink",
1209           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1210 
1211   playbin =
1212       create_playbin
1213       ("caps:audio/x-raw,"
1214       " format=(string)" GST_AUDIO_NE (S16) ", " "layout=(string)interleaved, "
1215       " rate=(int)48000, " " channels=(int)2", TRUE);
1216 
1217   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1218       GST_STATE_CHANGE_SUCCESS);
1219   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1220       GST_STATE_CHANGE_ASYNC);
1221 
1222   bus = gst_element_get_bus (playbin);
1223 
1224   while (!done) {
1225     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1226 
1227     switch (GST_MESSAGE_TYPE (msg)) {
1228       case GST_MESSAGE_EOS:
1229         done = TRUE;
1230         break;
1231       case GST_MESSAGE_ERROR:
1232         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1233         break;
1234       default:
1235         break;
1236     }
1237     gst_message_unref (msg);
1238   }
1239   gst_object_unref (bus);
1240 
1241   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1242   fail_unless (sink != NULL);
1243   {
1244     GstVideoCodecSink *csink;
1245 
1246     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1247         gst_video_codec_sink_get_type ());
1248     csink = (GstVideoCodecSink *) sink;
1249     fail_unless (csink->audio == FALSE);
1250     fail_unless (csink->raw == FALSE);
1251     fail_unless_equals_int (csink->n_raw, 0);
1252     fail_unless_equals_int (csink->n_compressed, 0);
1253     gst_object_unref (sink);
1254   }
1255 
1256   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1257   fail_unless (sink != NULL);
1258   {
1259     GstAudioCodecSink *csink;
1260 
1261     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1262         gst_audio_codec_sink_get_type ());
1263     csink = (GstAudioCodecSink *) sink;
1264     fail_unless (csink->audio == TRUE);
1265     fail_unless (csink->raw == TRUE);
1266     fail_unless_equals_int (csink->n_raw, NBUFFERS);
1267     fail_unless_equals_int (csink->n_compressed, 0);
1268     gst_object_unref (sink);
1269   }
1270 
1271   gst_element_set_state (playbin, GST_STATE_NULL);
1272   gst_object_unref (playbin);
1273 }
1274 
1275 GST_END_TEST;
1276 
GST_START_TEST(test_compressed_single_audio_stream_manual_sink)1277 GST_START_TEST (test_compressed_single_audio_stream_manual_sink)
1278 {
1279   GstMessage *msg;
1280   GstElement *playbin;
1281   GstElement *sink;
1282   GstBus *bus;
1283   gboolean done = FALSE;
1284 
1285   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1286           gst_caps_src_get_type ()));
1287   fail_unless (gst_element_register (NULL, "audiocodecsink",
1288           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1289   fail_unless (gst_element_register (NULL, "videocodecsink",
1290           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1291 
1292   playbin = create_playbin ("caps:audio/x-compressed", TRUE);
1293 
1294   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1295       GST_STATE_CHANGE_SUCCESS);
1296   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1297       GST_STATE_CHANGE_ASYNC);
1298 
1299   bus = gst_element_get_bus (playbin);
1300 
1301   while (!done) {
1302     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1303 
1304     switch (GST_MESSAGE_TYPE (msg)) {
1305       case GST_MESSAGE_EOS:
1306         done = TRUE;
1307         break;
1308       case GST_MESSAGE_ERROR:
1309         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1310         break;
1311       default:
1312         break;
1313     }
1314     gst_message_unref (msg);
1315   }
1316   gst_object_unref (bus);
1317 
1318   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1319   fail_unless (sink != NULL);
1320   {
1321     GstVideoCodecSink *csink;
1322 
1323     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1324         gst_video_codec_sink_get_type ());
1325     csink = (GstVideoCodecSink *) sink;
1326     fail_unless (csink->audio == FALSE);
1327     fail_unless (csink->raw == FALSE);
1328     fail_unless_equals_int (csink->n_raw, 0);
1329     fail_unless_equals_int (csink->n_compressed, 0);
1330     gst_object_unref (sink);
1331   }
1332 
1333   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1334   fail_unless (sink != NULL);
1335   {
1336     GstAudioCodecSink *csink;
1337 
1338     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1339         gst_audio_codec_sink_get_type ());
1340     csink = (GstAudioCodecSink *) sink;
1341     fail_unless (csink->audio == TRUE);
1342     fail_unless (csink->raw == FALSE);
1343     fail_unless_equals_int (csink->n_raw, 0);
1344     fail_unless_equals_int (csink->n_compressed, NBUFFERS);
1345     gst_object_unref (sink);
1346   }
1347 
1348   gst_element_set_state (playbin, GST_STATE_NULL);
1349   gst_object_unref (playbin);
1350 }
1351 
1352 GST_END_TEST;
1353 
GST_START_TEST(test_raw_single_audio_stream_demuxer_manual_sink)1354 GST_START_TEST (test_raw_single_audio_stream_demuxer_manual_sink)
1355 {
1356   GstMessage *msg;
1357   GstElement *playbin;
1358   GstElement *sink;
1359   GstBus *bus;
1360   gboolean done = FALSE;
1361 
1362   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1363           gst_caps_src_get_type ()));
1364   fail_unless (gst_element_register (NULL, "codecdemuxer",
1365           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1366   fail_unless (gst_element_register (NULL, "audiocodecsink",
1367           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1368   fail_unless (gst_element_register (NULL, "videocodecsink",
1369           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1370 
1371   playbin = create_playbin ("caps:application/x-container, "
1372       "stream0=(string)raw-audio, " "stream1=(string)none", TRUE);
1373 
1374   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1375       GST_STATE_CHANGE_SUCCESS);
1376   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1377       GST_STATE_CHANGE_ASYNC);
1378 
1379   bus = gst_element_get_bus (playbin);
1380 
1381   while (!done) {
1382     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1383 
1384     switch (GST_MESSAGE_TYPE (msg)) {
1385       case GST_MESSAGE_EOS:
1386         done = TRUE;
1387         break;
1388       case GST_MESSAGE_ERROR:
1389         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1390         break;
1391       default:
1392         break;
1393     }
1394     gst_message_unref (msg);
1395   }
1396   gst_object_unref (bus);
1397 
1398   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1399   fail_unless (sink != NULL);
1400   {
1401     GstVideoCodecSink *csink;
1402 
1403     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1404         gst_video_codec_sink_get_type ());
1405     csink = (GstVideoCodecSink *) sink;
1406     fail_unless (csink->audio == FALSE);
1407     fail_unless (csink->raw == FALSE);
1408     fail_unless_equals_int (csink->n_raw, 0);
1409     fail_unless_equals_int (csink->n_compressed, 0);
1410     gst_object_unref (sink);
1411   }
1412 
1413   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1414   fail_unless (sink != NULL);
1415   {
1416     GstAudioCodecSink *csink;
1417 
1418     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1419         gst_audio_codec_sink_get_type ());
1420     csink = (GstAudioCodecSink *) sink;
1421     fail_unless (csink->audio == TRUE);
1422     fail_unless (csink->raw == TRUE);
1423     fail_unless_equals_int (csink->n_raw, NBUFFERS);
1424     fail_unless_equals_int (csink->n_compressed, 0);
1425     gst_object_unref (sink);
1426   }
1427 
1428   gst_element_set_state (playbin, GST_STATE_NULL);
1429   gst_object_unref (playbin);
1430 }
1431 
1432 GST_END_TEST;
1433 
GST_START_TEST(test_compressed_single_audio_stream_demuxer_manual_sink)1434 GST_START_TEST (test_compressed_single_audio_stream_demuxer_manual_sink)
1435 {
1436   GstMessage *msg;
1437   GstElement *playbin;
1438   GstElement *sink;
1439   GstBus *bus;
1440   gboolean done = FALSE;
1441 
1442   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1443           gst_caps_src_get_type ()));
1444   fail_unless (gst_element_register (NULL, "codecdemuxer",
1445           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1446   fail_unless (gst_element_register (NULL, "audiocodecsink",
1447           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1448   fail_unless (gst_element_register (NULL, "videocodecsink",
1449           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1450 
1451   playbin = create_playbin ("caps:application/x-container, "
1452       "stream0=(string)compressed-audio, " "stream1=(string)none", TRUE);
1453 
1454   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1455       GST_STATE_CHANGE_SUCCESS);
1456   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1457       GST_STATE_CHANGE_ASYNC);
1458 
1459   bus = gst_element_get_bus (playbin);
1460 
1461   while (!done) {
1462     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1463 
1464     switch (GST_MESSAGE_TYPE (msg)) {
1465       case GST_MESSAGE_EOS:
1466         done = TRUE;
1467         break;
1468       case GST_MESSAGE_ERROR:
1469         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1470         break;
1471       default:
1472         break;
1473     }
1474     gst_message_unref (msg);
1475   }
1476   gst_object_unref (bus);
1477 
1478   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1479   fail_unless (sink != NULL);
1480   {
1481     GstVideoCodecSink *csink;
1482 
1483     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1484         gst_video_codec_sink_get_type ());
1485     csink = (GstVideoCodecSink *) sink;
1486     fail_unless (csink->audio == FALSE);
1487     fail_unless (csink->raw == FALSE);
1488     fail_unless_equals_int (csink->n_raw, 0);
1489     fail_unless_equals_int (csink->n_compressed, 0);
1490     gst_object_unref (sink);
1491   }
1492 
1493   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1494   fail_unless (sink != NULL);
1495   {
1496     GstAudioCodecSink *csink;
1497 
1498     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1499         gst_audio_codec_sink_get_type ());
1500     csink = (GstAudioCodecSink *) sink;
1501     fail_unless (csink->audio == TRUE);
1502     fail_unless (csink->raw == FALSE);
1503     fail_unless_equals_int (csink->n_raw, 0);
1504     fail_unless_equals_int (csink->n_compressed, NBUFFERS);
1505     gst_object_unref (sink);
1506   }
1507 
1508   gst_element_set_state (playbin, GST_STATE_NULL);
1509   gst_object_unref (playbin);
1510 }
1511 
1512 GST_END_TEST;
1513 
GST_START_TEST(test_raw_audio_video_stream_demuxer_manual_sink)1514 GST_START_TEST (test_raw_audio_video_stream_demuxer_manual_sink)
1515 {
1516   GstMessage *msg;
1517   GstElement *playbin;
1518   GstElement *sink;
1519   GstBus *bus;
1520   gboolean done = FALSE;
1521 
1522   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1523           gst_caps_src_get_type ()));
1524   fail_unless (gst_element_register (NULL, "codecdemuxer",
1525           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1526   fail_unless (gst_element_register (NULL, "audiocodecsink",
1527           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1528   fail_unless (gst_element_register (NULL, "videocodecsink",
1529           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1530 
1531   playbin = create_playbin ("caps:application/x-container, "
1532       "stream0=(string)raw-audio, " "stream1=(string)raw-video", TRUE);
1533 
1534   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1535       GST_STATE_CHANGE_SUCCESS);
1536   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1537       GST_STATE_CHANGE_ASYNC);
1538 
1539   bus = gst_element_get_bus (playbin);
1540 
1541   while (!done) {
1542     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1543 
1544     switch (GST_MESSAGE_TYPE (msg)) {
1545       case GST_MESSAGE_EOS:
1546         done = TRUE;
1547         break;
1548       case GST_MESSAGE_ERROR:
1549         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1550         break;
1551       default:
1552         break;
1553     }
1554     gst_message_unref (msg);
1555   }
1556   gst_object_unref (bus);
1557 
1558   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1559   fail_unless (sink != NULL);
1560   {
1561     GstVideoCodecSink *csink;
1562 
1563     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1564         gst_video_codec_sink_get_type ());
1565     csink = (GstVideoCodecSink *) sink;
1566     fail_unless (csink->audio == FALSE);
1567     fail_unless (csink->raw == TRUE);
1568     fail_unless_equals_int (csink->n_raw, NBUFFERS);
1569     fail_unless_equals_int (csink->n_compressed, 0);
1570     gst_object_unref (sink);
1571   }
1572 
1573   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1574   fail_unless (sink != NULL);
1575   {
1576     GstAudioCodecSink *csink;
1577 
1578     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1579         gst_audio_codec_sink_get_type ());
1580     csink = (GstAudioCodecSink *) sink;
1581     fail_unless (csink->audio == TRUE);
1582     fail_unless (csink->raw == TRUE);
1583     fail_unless_equals_int (csink->n_raw, NBUFFERS);
1584     fail_unless_equals_int (csink->n_compressed, 0);
1585     gst_object_unref (sink);
1586   }
1587 
1588   gst_element_set_state (playbin, GST_STATE_NULL);
1589   gst_object_unref (playbin);
1590 }
1591 
1592 GST_END_TEST;
1593 
GST_START_TEST(test_compressed_audio_video_stream_demuxer_manual_sink)1594 GST_START_TEST (test_compressed_audio_video_stream_demuxer_manual_sink)
1595 {
1596   GstMessage *msg;
1597   GstElement *playbin;
1598   GstElement *sink;
1599   GstBus *bus;
1600   gboolean done = FALSE;
1601 
1602   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1603           gst_caps_src_get_type ()));
1604   fail_unless (gst_element_register (NULL, "codecdemuxer",
1605           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1606   fail_unless (gst_element_register (NULL, "audiocodecsink",
1607           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1608   fail_unless (gst_element_register (NULL, "videocodecsink",
1609           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1610 
1611   playbin = create_playbin ("caps:application/x-container, "
1612       "stream0=(string)compressed-audio, " "stream1=(string)compressed-video",
1613       TRUE);
1614 
1615   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1616       GST_STATE_CHANGE_SUCCESS);
1617   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1618       GST_STATE_CHANGE_ASYNC);
1619 
1620   bus = gst_element_get_bus (playbin);
1621 
1622   while (!done) {
1623     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1624 
1625     switch (GST_MESSAGE_TYPE (msg)) {
1626       case GST_MESSAGE_EOS:
1627         done = TRUE;
1628         break;
1629       case GST_MESSAGE_ERROR:
1630         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1631         break;
1632       default:
1633         break;
1634     }
1635     gst_message_unref (msg);
1636   }
1637   gst_object_unref (bus);
1638 
1639   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1640   fail_unless (sink != NULL);
1641   {
1642     GstVideoCodecSink *csink;
1643 
1644     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1645         gst_video_codec_sink_get_type ());
1646     csink = (GstVideoCodecSink *) sink;
1647     fail_unless (csink->audio == FALSE);
1648     fail_unless (csink->raw == FALSE);
1649     fail_unless_equals_int (csink->n_raw, 0);
1650     fail_unless_equals_int (csink->n_compressed, NBUFFERS);
1651     gst_object_unref (sink);
1652   }
1653 
1654   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1655   fail_unless (sink != NULL);
1656   {
1657     GstAudioCodecSink *csink;
1658 
1659     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1660         gst_audio_codec_sink_get_type ());
1661     csink = (GstAudioCodecSink *) sink;
1662     fail_unless (csink->audio == TRUE);
1663     fail_unless (csink->raw == FALSE);
1664     fail_unless_equals_int (csink->n_raw, 0);
1665     fail_unless_equals_int (csink->n_compressed, NBUFFERS);
1666     gst_object_unref (sink);
1667   }
1668 
1669   gst_element_set_state (playbin, GST_STATE_NULL);
1670   gst_object_unref (playbin);
1671 }
1672 
1673 GST_END_TEST;
1674 
GST_START_TEST(test_raw_compressed_video_stream_demuxer_manual_sink)1675 GST_START_TEST (test_raw_compressed_video_stream_demuxer_manual_sink)
1676 {
1677   GstMessage *msg;
1678   GstElement *playbin;
1679   GstElement *sink;
1680   GstBus *bus;
1681   gboolean done = FALSE;
1682 
1683   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1684           gst_caps_src_get_type ()));
1685   fail_unless (gst_element_register (NULL, "codecdemuxer",
1686           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1687   fail_unless (gst_element_register (NULL, "audiocodecsink",
1688           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1689   fail_unless (gst_element_register (NULL, "videocodecsink",
1690           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1691 
1692   playbin = create_playbin ("caps:application/x-container, "
1693       "stream0=(string)raw-video, " "stream1=(string)compressed-video", TRUE);
1694 
1695   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1696       GST_STATE_CHANGE_SUCCESS);
1697   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1698       GST_STATE_CHANGE_ASYNC);
1699 
1700   bus = gst_element_get_bus (playbin);
1701 
1702   while (!done) {
1703     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1704 
1705     switch (GST_MESSAGE_TYPE (msg)) {
1706       case GST_MESSAGE_EOS:
1707         done = TRUE;
1708         break;
1709       case GST_MESSAGE_ERROR:
1710         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1711         break;
1712       default:
1713         break;
1714     }
1715     gst_message_unref (msg);
1716   }
1717   gst_object_unref (bus);
1718 
1719   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1720   fail_unless (sink != NULL);
1721   {
1722     GstVideoCodecSink *csink;
1723 
1724     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1725         gst_video_codec_sink_get_type ());
1726     csink = (GstVideoCodecSink *) sink;
1727     fail_unless (csink->audio == FALSE);
1728     fail_unless_equals_int (csink->n_raw + csink->n_compressed, NBUFFERS);
1729     gst_object_unref (sink);
1730   }
1731 
1732   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1733   fail_unless (sink != NULL);
1734   {
1735     GstAudioCodecSink *csink;
1736 
1737     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1738         gst_audio_codec_sink_get_type ());
1739     csink = (GstAudioCodecSink *) sink;
1740     fail_unless (csink->audio == TRUE);
1741     fail_unless_equals_int (csink->n_raw, 0);
1742     fail_unless_equals_int (csink->n_compressed, 0);
1743     gst_object_unref (sink);
1744   }
1745 
1746   gst_element_set_state (playbin, GST_STATE_NULL);
1747   gst_object_unref (playbin);
1748 }
1749 
1750 GST_END_TEST;
1751 
GST_START_TEST(test_raw_compressed_audio_stream_demuxer_manual_sink)1752 GST_START_TEST (test_raw_compressed_audio_stream_demuxer_manual_sink)
1753 {
1754   GstMessage *msg;
1755   GstElement *playbin;
1756   GstElement *sink;
1757   GstBus *bus;
1758   gboolean done = FALSE;
1759 
1760   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1761           gst_caps_src_get_type ()));
1762   fail_unless (gst_element_register (NULL, "codecdemuxer",
1763           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1764   fail_unless (gst_element_register (NULL, "audiocodecsink",
1765           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1766   fail_unless (gst_element_register (NULL, "videocodecsink",
1767           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1768 
1769   playbin = create_playbin ("caps:application/x-container, "
1770       "stream0=(string)raw-audio, " "stream1=(string)compressed-audio", TRUE);
1771 
1772   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1773       GST_STATE_CHANGE_SUCCESS);
1774   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1775       GST_STATE_CHANGE_ASYNC);
1776 
1777   bus = gst_element_get_bus (playbin);
1778 
1779   while (!done) {
1780     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1781 
1782     switch (GST_MESSAGE_TYPE (msg)) {
1783       case GST_MESSAGE_EOS:
1784         done = TRUE;
1785         break;
1786       case GST_MESSAGE_ERROR:
1787         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1788         break;
1789       default:
1790         break;
1791     }
1792     gst_message_unref (msg);
1793   }
1794   gst_object_unref (bus);
1795 
1796   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1797   fail_unless (sink != NULL);
1798   {
1799     GstVideoCodecSink *csink;
1800 
1801     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1802         gst_video_codec_sink_get_type ());
1803     csink = (GstVideoCodecSink *) sink;
1804     fail_unless (csink->audio == FALSE);
1805     fail_unless_equals_int (csink->n_raw, 0);
1806     fail_unless_equals_int (csink->n_compressed, 0);
1807     gst_object_unref (sink);
1808   }
1809 
1810   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1811   fail_unless (sink != NULL);
1812   {
1813     GstAudioCodecSink *csink;
1814 
1815     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1816         gst_audio_codec_sink_get_type ());
1817     csink = (GstAudioCodecSink *) sink;
1818     fail_unless (csink->audio == TRUE);
1819     fail_unless_equals_int (csink->n_raw + csink->n_compressed, NBUFFERS);
1820     gst_object_unref (sink);
1821   }
1822 
1823   gst_element_set_state (playbin, GST_STATE_NULL);
1824   gst_object_unref (playbin);
1825 }
1826 
1827 GST_END_TEST;
1828 
GST_START_TEST(test_raw_raw_audio_stream_adder_manual_sink)1829 GST_START_TEST (test_raw_raw_audio_stream_adder_manual_sink)
1830 {
1831   GstMessage *msg;
1832   GstElement *adder;
1833   GstElement *playbin_combiner;
1834   GstElement *playbin;
1835   GstElement *sink;
1836   GstBus *bus;
1837   gboolean adder_used = FALSE;
1838   gboolean done = FALSE;
1839 
1840   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1841           gst_caps_src_get_type ()));
1842   fail_unless (gst_element_register (NULL, "codecdemuxer",
1843           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1844   fail_unless (gst_element_register (NULL, "audiocodecsink",
1845           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1846   fail_unless (gst_element_register (NULL, "videocodecsink",
1847           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1848 
1849   playbin = create_playbin ("caps:application/x-container, "
1850       "stream0=(string)raw-audio, " "stream1=(string)raw-audio", TRUE);
1851 
1852   /* before playback starts, and with no custom combiner, these should all be NULL */
1853   g_object_get (G_OBJECT (playbin), "audio-stream-combiner", &playbin_combiner,
1854       NULL);
1855   fail_unless (playbin_combiner == NULL);
1856   g_object_get (G_OBJECT (playbin), "text-stream-combiner", &playbin_combiner,
1857       NULL);
1858   fail_unless (playbin_combiner == NULL);
1859   g_object_get (G_OBJECT (playbin), "video-stream-combiner", &playbin_combiner,
1860       NULL);
1861   fail_unless (playbin_combiner == NULL);
1862 
1863   /* set audio combiner */
1864   adder = gst_element_factory_make ("adder", NULL);
1865   fail_unless (adder != NULL);
1866   g_object_set (G_OBJECT (playbin), "audio-stream-combiner", adder, NULL);
1867 
1868   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1869       GST_STATE_CHANGE_SUCCESS);
1870   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
1871       GST_STATE_CHANGE_ASYNC);
1872 
1873   /* audio combiner should still be there */
1874   g_object_get (G_OBJECT (playbin), "audio-stream-combiner", &playbin_combiner,
1875       NULL);
1876   fail_unless (playbin_combiner == adder);
1877   gst_object_unref (playbin_combiner);
1878 
1879   /* text and video combiners should still be NULL */
1880   g_object_get (G_OBJECT (playbin), "text-stream-combiner", &playbin_combiner,
1881       NULL);
1882   fail_unless (playbin_combiner == NULL);
1883   g_object_get (G_OBJECT (playbin), "video-stream-combiner", &playbin_combiner,
1884       NULL);
1885   fail_unless (playbin_combiner == NULL);
1886 
1887   bus = gst_element_get_bus (playbin);
1888 
1889   while (!done) {
1890     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
1891 
1892     switch (GST_MESSAGE_TYPE (msg)) {
1893       case GST_MESSAGE_EOS:
1894         done = TRUE;
1895         break;
1896       case GST_MESSAGE_ERROR:
1897         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
1898         break;
1899       case GST_MESSAGE_STATE_CHANGED:
1900         if (GST_MESSAGE_SRC (msg) == GST_OBJECT (adder)) {
1901           GstState state;
1902           gst_message_parse_state_changed (msg, &state, NULL, NULL);
1903           if (state == GST_STATE_PAUSED)
1904             adder_used = TRUE;
1905         }
1906       default:
1907         break;
1908     }
1909     gst_message_unref (msg);
1910   }
1911   gst_object_unref (bus);
1912   fail_unless (adder_used);
1913 
1914   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1915   fail_unless (sink != NULL);
1916   {
1917     GstVideoCodecSink *csink;
1918 
1919     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1920         gst_video_codec_sink_get_type ());
1921     csink = (GstVideoCodecSink *) sink;
1922     fail_unless (csink->audio == FALSE);
1923     fail_unless_equals_int (csink->n_raw, 0);
1924     fail_unless_equals_int (csink->n_compressed, 0);
1925     gst_object_unref (sink);
1926   }
1927 
1928   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
1929   fail_unless (sink != NULL);
1930   {
1931     GstAudioCodecSink *csink;
1932 
1933     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
1934         gst_audio_codec_sink_get_type ());
1935     csink = (GstAudioCodecSink *) sink;
1936     fail_unless (csink->audio == TRUE);
1937     fail_unless_equals_int (csink->n_raw, NBUFFERS);
1938     fail_unless_equals_int (csink->n_compressed, 0);
1939     gst_object_unref (sink);
1940   }
1941 
1942   gst_element_set_state (playbin, GST_STATE_NULL);
1943   gst_object_unref (playbin);
1944 }
1945 
1946 GST_END_TEST;
1947 
1948 #if 0
1949 typedef struct
1950 {
1951   GstElement *playbin;
1952   GstElement *sink;
1953 } SwitchBufferProbeCtx;
1954 
1955 static gboolean
1956 switch_video_buffer_probe (GstPad * pad, GstBuffer * buffer,
1957     SwitchBufferProbeCtx * ctx)
1958 {
1959   GstElement *playbin = ctx->playbin;
1960   GstVideoCodecSink *sink = (GstVideoCodecSink *) ctx->sink;
1961 
1962   if (sink->n_raw + sink->n_compressed == NBUFFERS / 2) {
1963     gint cur_video;
1964 
1965     g_object_get (G_OBJECT (playbin), "current-video", &cur_video, NULL);
1966     cur_video = (cur_video == 0) ? 1 : 0;
1967     g_object_set (G_OBJECT (playbin), "current-video", cur_video, NULL);
1968   }
1969 
1970   return TRUE;
1971 }
1972 
1973 GST_START_TEST (test_raw_compressed_video_stream_demuxer_switch_manual_sink)
1974 {
1975   GstMessage *msg;
1976   GstElement *playbin;
1977   GstElement *sink;
1978   GstBus *bus;
1979   gboolean done = FALSE;
1980   GstPad *pad;
1981   SwitchBufferProbeCtx switch_ctx;
1982 
1983   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
1984           gst_caps_src_get_type ()));
1985   fail_unless (gst_element_register (NULL, "codecdemuxer",
1986           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
1987   fail_unless (gst_element_register (NULL, "audiocodecsink",
1988           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
1989   fail_unless (gst_element_register (NULL, "videocodecsink",
1990           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
1991 
1992   playbin = create_playbin ("caps:application/x-container, "
1993       "stream0=(string)raw-video, " "stream1=(string)compressed-video", TRUE);
1994 
1995   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
1996       GST_STATE_CHANGE_SUCCESS);
1997 
1998   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
1999   fail_unless (sink != NULL);
2000   pad = gst_element_get_static_pad (sink, "sink");
2001   fail_unless (pad != NULL);
2002   switch_ctx.playbin = playbin;
2003   switch_ctx.sink = sink;
2004   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_video_buffer_probe),
2005       &switch_ctx);
2006   gst_object_unref (pad);
2007   gst_object_unref (sink);
2008 
2009   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2010       GST_STATE_CHANGE_ASYNC);
2011 
2012   bus = gst_element_get_bus (playbin);
2013 
2014   while (!done) {
2015     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2016 
2017     switch (GST_MESSAGE_TYPE (msg)) {
2018       case GST_MESSAGE_EOS:
2019         done = TRUE;
2020         break;
2021       case GST_MESSAGE_ERROR:
2022         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2023         break;
2024       default:
2025         break;
2026     }
2027     gst_message_unref (msg);
2028   }
2029   gst_object_unref (bus);
2030 
2031   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2032   fail_unless (sink != NULL);
2033   {
2034     GstVideoCodecSink *csink;
2035 
2036     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2037         gst_video_codec_sink_get_type ());
2038     csink = (GstVideoCodecSink *) sink;
2039     fail_unless (csink->audio == FALSE);
2040     fail_unless (csink->n_raw > 0);
2041     fail_unless (csink->n_compressed > 0);
2042     gst_object_unref (sink);
2043   }
2044 
2045   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2046   fail_unless (sink != NULL);
2047   {
2048     GstAudioCodecSink *csink;
2049 
2050     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2051         gst_audio_codec_sink_get_type ());
2052     csink = (GstAudioCodecSink *) sink;
2053     fail_unless (csink->audio == TRUE);
2054     fail_unless_equals_int (csink->n_raw, 0);
2055     fail_unless_equals_int (csink->n_compressed, 0);
2056     gst_object_unref (sink);
2057   }
2058 
2059   gst_element_set_state (playbin, GST_STATE_NULL);
2060   gst_object_unref (playbin);
2061 }
2062 
2063 GST_END_TEST;
2064 
2065 GST_START_TEST (test_compressed_raw_video_stream_demuxer_switch_manual_sink)
2066 {
2067   GstMessage *msg;
2068   GstElement *playbin;
2069   GstElement *sink;
2070   GstBus *bus;
2071   gboolean done = FALSE;
2072   GstPad *pad;
2073   SwitchBufferProbeCtx switch_ctx;
2074 
2075   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
2076           gst_caps_src_get_type ()));
2077   fail_unless (gst_element_register (NULL, "codecdemuxer",
2078           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
2079   fail_unless (gst_element_register (NULL, "audiocodecsink",
2080           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
2081   fail_unless (gst_element_register (NULL, "videocodecsink",
2082           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
2083 
2084   playbin = create_playbin ("caps:application/x-container, "
2085       "stream0=(string)compressed-video, " "stream1=(string)raw-video", TRUE);
2086 
2087   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
2088       GST_STATE_CHANGE_SUCCESS);
2089 
2090   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2091   fail_unless (sink != NULL);
2092   pad = gst_element_get_static_pad (sink, "sink");
2093   fail_unless (pad != NULL);
2094   switch_ctx.playbin = playbin;
2095   switch_ctx.sink = sink;
2096   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_video_buffer_probe),
2097       &switch_ctx);
2098   gst_object_unref (pad);
2099   gst_object_unref (sink);
2100 
2101   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2102       GST_STATE_CHANGE_ASYNC);
2103 
2104   bus = gst_element_get_bus (playbin);
2105 
2106   while (!done) {
2107     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2108 
2109     switch (GST_MESSAGE_TYPE (msg)) {
2110       case GST_MESSAGE_EOS:
2111         done = TRUE;
2112         break;
2113       case GST_MESSAGE_ERROR:
2114         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2115         break;
2116       default:
2117         break;
2118     }
2119     gst_message_unref (msg);
2120   }
2121   gst_object_unref (bus);
2122 
2123   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2124   fail_unless (sink != NULL);
2125   {
2126     GstVideoCodecSink *csink;
2127 
2128     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2129         gst_video_codec_sink_get_type ());
2130     csink = (GstVideoCodecSink *) sink;
2131     fail_unless (csink->audio == FALSE);
2132     fail_unless (csink->n_raw > 0);
2133     fail_unless (csink->n_compressed > 0);
2134     gst_object_unref (sink);
2135   }
2136 
2137   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2138   fail_unless (sink != NULL);
2139   {
2140     GstAudioCodecSink *csink;
2141 
2142     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2143         gst_audio_codec_sink_get_type ());
2144     csink = (GstAudioCodecSink *) sink;
2145     fail_unless (csink->audio == TRUE);
2146     fail_unless_equals_int (csink->n_raw, 0);
2147     fail_unless_equals_int (csink->n_compressed, 0);
2148     gst_object_unref (sink);
2149   }
2150 
2151   gst_element_set_state (playbin, GST_STATE_NULL);
2152   gst_object_unref (playbin);
2153 }
2154 
2155 GST_END_TEST;
2156 
2157 GST_START_TEST (test_raw_raw_video_stream_demuxer_switch_manual_sink)
2158 {
2159   GstMessage *msg;
2160   GstElement *playbin;
2161   GstElement *sink;
2162   GstBus *bus;
2163   gboolean done = FALSE;
2164   GstPad *pad;
2165   SwitchBufferProbeCtx switch_ctx;
2166 
2167   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
2168           gst_caps_src_get_type ()));
2169   fail_unless (gst_element_register (NULL, "codecdemuxer",
2170           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
2171   fail_unless (gst_element_register (NULL, "audiocodecsink",
2172           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
2173   fail_unless (gst_element_register (NULL, "videocodecsink",
2174           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
2175 
2176   playbin = create_playbin ("caps:application/x-container, "
2177       "stream0=(string)raw-video, " "stream1=(string)raw-video", TRUE);
2178 
2179   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
2180       GST_STATE_CHANGE_SUCCESS);
2181 
2182   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2183   fail_unless (sink != NULL);
2184   pad = gst_element_get_static_pad (sink, "sink");
2185   fail_unless (pad != NULL);
2186   switch_ctx.playbin = playbin;
2187   switch_ctx.sink = sink;
2188   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_video_buffer_probe),
2189       &switch_ctx);
2190   gst_object_unref (pad);
2191   gst_object_unref (sink);
2192 
2193   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2194       GST_STATE_CHANGE_ASYNC);
2195 
2196   bus = gst_element_get_bus (playbin);
2197 
2198   while (!done) {
2199     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2200 
2201     switch (GST_MESSAGE_TYPE (msg)) {
2202       case GST_MESSAGE_EOS:
2203         done = TRUE;
2204         break;
2205       case GST_MESSAGE_ERROR:
2206         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2207         break;
2208       default:
2209         break;
2210     }
2211     gst_message_unref (msg);
2212   }
2213   gst_object_unref (bus);
2214 
2215   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2216   fail_unless (sink != NULL);
2217   {
2218     GstVideoCodecSink *csink;
2219 
2220     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2221         gst_video_codec_sink_get_type ());
2222     csink = (GstVideoCodecSink *) sink;
2223     fail_unless (csink->audio == FALSE);
2224     fail_unless (csink->n_raw > 0);
2225     fail_unless_equals_int (csink->n_compressed, 0);
2226     gst_object_unref (sink);
2227   }
2228 
2229   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2230   fail_unless (sink != NULL);
2231   {
2232     GstAudioCodecSink *csink;
2233 
2234     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2235         gst_audio_codec_sink_get_type ());
2236     csink = (GstAudioCodecSink *) sink;
2237     fail_unless (csink->audio == TRUE);
2238     fail_unless_equals_int (csink->n_raw, 0);
2239     fail_unless_equals_int (csink->n_compressed, 0);
2240     gst_object_unref (sink);
2241   }
2242 
2243   gst_element_set_state (playbin, GST_STATE_NULL);
2244   gst_object_unref (playbin);
2245 }
2246 
2247 GST_END_TEST;
2248 
2249 GST_START_TEST
2250     (test_compressed_compressed_video_stream_demuxer_switch_manual_sink) {
2251   GstMessage *msg;
2252   GstElement *playbin;
2253   GstElement *sink;
2254   GstBus *bus;
2255   gboolean done = FALSE;
2256   GstPad *pad;
2257   SwitchBufferProbeCtx switch_ctx;
2258 
2259   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
2260           gst_caps_src_get_type ()));
2261   fail_unless (gst_element_register (NULL, "codecdemuxer",
2262           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
2263   fail_unless (gst_element_register (NULL, "audiocodecsink",
2264           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
2265   fail_unless (gst_element_register (NULL, "videocodecsink",
2266           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
2267 
2268   playbin = create_playbin ("caps:application/x-container, "
2269       "stream0=(string)compressed-video, " "stream1=(string)compressed-video",
2270       TRUE);
2271 
2272   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
2273       GST_STATE_CHANGE_SUCCESS);
2274 
2275   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2276   fail_unless (sink != NULL);
2277   pad = gst_element_get_static_pad (sink, "sink");
2278   fail_unless (pad != NULL);
2279   switch_ctx.playbin = playbin;
2280   switch_ctx.sink = sink;
2281   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_video_buffer_probe),
2282       &switch_ctx);
2283   gst_object_unref (pad);
2284   gst_object_unref (sink);
2285 
2286   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2287       GST_STATE_CHANGE_ASYNC);
2288 
2289   bus = gst_element_get_bus (playbin);
2290 
2291   while (!done) {
2292     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2293 
2294     switch (GST_MESSAGE_TYPE (msg)) {
2295       case GST_MESSAGE_EOS:
2296         done = TRUE;
2297         break;
2298       case GST_MESSAGE_ERROR:
2299         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2300         break;
2301       default:
2302         break;
2303     }
2304     gst_message_unref (msg);
2305   }
2306   gst_object_unref (bus);
2307 
2308   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2309   fail_unless (sink != NULL);
2310   {
2311     GstVideoCodecSink *csink;
2312 
2313     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2314         gst_video_codec_sink_get_type ());
2315     csink = (GstVideoCodecSink *) sink;
2316     fail_unless (csink->audio == FALSE);
2317     fail_unless_equals_int (csink->n_raw, 0);
2318     fail_unless (csink->n_compressed > 0);
2319     gst_object_unref (sink);
2320   }
2321 
2322   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2323   fail_unless (sink != NULL);
2324   {
2325     GstAudioCodecSink *csink;
2326 
2327     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2328         gst_audio_codec_sink_get_type ());
2329     csink = (GstAudioCodecSink *) sink;
2330     fail_unless (csink->audio == TRUE);
2331     fail_unless_equals_int (csink->n_raw, 0);
2332     fail_unless_equals_int (csink->n_compressed, 0);
2333     gst_object_unref (sink);
2334   }
2335 
2336   gst_element_set_state (playbin, GST_STATE_NULL);
2337   gst_object_unref (playbin);
2338 }
2339 
2340 GST_END_TEST;
2341 
2342 static gboolean
2343 switch_audio_buffer_probe (GstPad * pad, GstBuffer * buffer,
2344     SwitchBufferProbeCtx * ctx)
2345 {
2346   GstElement *playbin = ctx->playbin;
2347   GstAudioCodecSink *sink = (GstAudioCodecSink *) ctx->sink;
2348 
2349   if (sink->n_raw + sink->n_compressed == NBUFFERS / 3) {
2350     gint cur_audio;
2351 
2352     g_object_get (G_OBJECT (playbin), "current-audio", &cur_audio, NULL);
2353     cur_audio = (cur_audio == 0) ? 1 : 0;
2354     g_object_set (G_OBJECT (playbin), "current-audio", cur_audio, NULL);
2355   }
2356 
2357   return TRUE;
2358 }
2359 
2360 GST_START_TEST (test_raw_compressed_audio_stream_demuxer_switch_manual_sink)
2361 {
2362   GstMessage *msg;
2363   GstElement *playbin;
2364   GstElement *sink;
2365   GstBus *bus;
2366   gboolean done = FALSE;
2367   GstPad *pad;
2368   SwitchBufferProbeCtx switch_ctx;
2369 
2370   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
2371           gst_caps_src_get_type ()));
2372   fail_unless (gst_element_register (NULL, "codecdemuxer",
2373           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
2374   fail_unless (gst_element_register (NULL, "audiocodecsink",
2375           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
2376   fail_unless (gst_element_register (NULL, "videocodecsink",
2377           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
2378 
2379   playbin = create_playbin ("caps:application/x-container, "
2380       "stream0=(string)raw-audio, " "stream1=(string)compressed-audio", TRUE);
2381 
2382   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
2383       GST_STATE_CHANGE_SUCCESS);
2384 
2385   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2386   fail_unless (sink != NULL);
2387   pad = gst_element_get_static_pad (sink, "sink");
2388   fail_unless (pad != NULL);
2389   switch_ctx.playbin = playbin;
2390   switch_ctx.sink = sink;
2391   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_audio_buffer_probe),
2392       &switch_ctx);
2393   gst_object_unref (pad);
2394   gst_object_unref (sink);
2395 
2396   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2397       GST_STATE_CHANGE_ASYNC);
2398 
2399   bus = gst_element_get_bus (playbin);
2400 
2401   while (!done) {
2402     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2403 
2404     switch (GST_MESSAGE_TYPE (msg)) {
2405       case GST_MESSAGE_EOS:
2406         done = TRUE;
2407         break;
2408       case GST_MESSAGE_ERROR:
2409         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2410         break;
2411       default:
2412         break;
2413     }
2414     gst_message_unref (msg);
2415   }
2416   gst_object_unref (bus);
2417 
2418   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2419   fail_unless (sink != NULL);
2420   {
2421     GstVideoCodecSink *csink;
2422 
2423     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2424         gst_video_codec_sink_get_type ());
2425     csink = (GstVideoCodecSink *) sink;
2426     fail_unless (csink->audio == FALSE);
2427     fail_unless_equals_int (csink->n_raw, 0);
2428     fail_unless_equals_int (csink->n_compressed, 0);
2429     gst_object_unref (sink);
2430   }
2431 
2432   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2433   fail_unless (sink != NULL);
2434   {
2435     GstAudioCodecSink *csink;
2436 
2437     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2438         gst_audio_codec_sink_get_type ());
2439     csink = (GstAudioCodecSink *) sink;
2440     fail_unless (csink->audio == TRUE);
2441     fail_unless (csink->n_raw > 0);
2442     fail_unless (csink->n_compressed > 0);
2443     gst_object_unref (sink);
2444   }
2445 
2446   gst_element_set_state (playbin, GST_STATE_NULL);
2447   gst_object_unref (playbin);
2448 }
2449 
2450 GST_END_TEST;
2451 
2452 GST_START_TEST (test_compressed_raw_audio_stream_demuxer_switch_manual_sink)
2453 {
2454   GstMessage *msg;
2455   GstElement *playbin;
2456   GstElement *sink;
2457   GstBus *bus;
2458   gboolean done = FALSE;
2459   GstPad *pad;
2460   SwitchBufferProbeCtx switch_ctx;
2461 
2462   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
2463           gst_caps_src_get_type ()));
2464   fail_unless (gst_element_register (NULL, "codecdemuxer",
2465           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
2466   fail_unless (gst_element_register (NULL, "audiocodecsink",
2467           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
2468   fail_unless (gst_element_register (NULL, "videocodecsink",
2469           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
2470 
2471   playbin = create_playbin ("caps:application/x-container, "
2472       "stream0=(string)compressed-audio, " "stream1=(string)raw-audio", TRUE);
2473 
2474   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
2475       GST_STATE_CHANGE_SUCCESS);
2476 
2477   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2478   fail_unless (sink != NULL);
2479   pad = gst_element_get_static_pad (sink, "sink");
2480   fail_unless (pad != NULL);
2481   switch_ctx.playbin = playbin;
2482   switch_ctx.sink = sink;
2483   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_audio_buffer_probe),
2484       &switch_ctx);
2485   gst_object_unref (pad);
2486   gst_object_unref (sink);
2487 
2488   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2489       GST_STATE_CHANGE_ASYNC);
2490 
2491   bus = gst_element_get_bus (playbin);
2492 
2493   while (!done) {
2494     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2495 
2496     switch (GST_MESSAGE_TYPE (msg)) {
2497       case GST_MESSAGE_EOS:
2498         done = TRUE;
2499         break;
2500       case GST_MESSAGE_ERROR:
2501         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2502         break;
2503       default:
2504         break;
2505     }
2506     gst_message_unref (msg);
2507   }
2508   gst_object_unref (bus);
2509 
2510   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2511   fail_unless (sink != NULL);
2512   {
2513     GstVideoCodecSink *csink;
2514 
2515     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2516         gst_video_codec_sink_get_type ());
2517     csink = (GstVideoCodecSink *) sink;
2518     fail_unless (csink->audio == FALSE);
2519     fail_unless_equals_int (csink->n_raw, 0);
2520     fail_unless_equals_int (csink->n_compressed, 0);
2521     gst_object_unref (sink);
2522   }
2523 
2524   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2525   fail_unless (sink != NULL);
2526   {
2527     GstAudioCodecSink *csink;
2528 
2529     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2530         gst_audio_codec_sink_get_type ());
2531     csink = (GstAudioCodecSink *) sink;
2532     fail_unless (csink->audio == TRUE);
2533     fail_unless (csink->n_raw > 0);
2534     fail_unless (csink->n_compressed > 0);
2535     gst_object_unref (sink);
2536   }
2537 
2538   gst_element_set_state (playbin, GST_STATE_NULL);
2539   gst_object_unref (playbin);
2540 }
2541 
2542 GST_END_TEST;
2543 
2544 GST_START_TEST (test_raw_raw_audio_stream_demuxer_switch_manual_sink)
2545 {
2546   GstMessage *msg;
2547   GstElement *playbin;
2548   GstElement *sink;
2549   GstBus *bus;
2550   gboolean done = FALSE;
2551   GstPad *pad;
2552   SwitchBufferProbeCtx switch_ctx;
2553 
2554   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
2555           gst_caps_src_get_type ()));
2556   fail_unless (gst_element_register (NULL, "codecdemuxer",
2557           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
2558   fail_unless (gst_element_register (NULL, "audiocodecsink",
2559           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
2560   fail_unless (gst_element_register (NULL, "videocodecsink",
2561           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
2562 
2563   playbin = create_playbin ("caps:application/x-container, "
2564       "stream0=(string)raw-audio, " "stream1=(string)raw-audio", TRUE);
2565 
2566   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
2567       GST_STATE_CHANGE_SUCCESS);
2568 
2569   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2570   fail_unless (sink != NULL);
2571   pad = gst_element_get_static_pad (sink, "sink");
2572   fail_unless (pad != NULL);
2573   switch_ctx.playbin = playbin;
2574   switch_ctx.sink = sink;
2575   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_audio_buffer_probe),
2576       &switch_ctx);
2577   gst_object_unref (pad);
2578   gst_object_unref (sink);
2579 
2580   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2581       GST_STATE_CHANGE_ASYNC);
2582 
2583   bus = gst_element_get_bus (playbin);
2584 
2585   while (!done) {
2586     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2587 
2588     switch (GST_MESSAGE_TYPE (msg)) {
2589       case GST_MESSAGE_EOS:
2590         done = TRUE;
2591         break;
2592       case GST_MESSAGE_ERROR:
2593         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2594         break;
2595       default:
2596         break;
2597     }
2598     gst_message_unref (msg);
2599   }
2600   gst_object_unref (bus);
2601 
2602   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2603   fail_unless (sink != NULL);
2604   {
2605     GstVideoCodecSink *csink;
2606 
2607     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2608         gst_video_codec_sink_get_type ());
2609     csink = (GstVideoCodecSink *) sink;
2610     fail_unless (csink->audio == FALSE);
2611     fail_unless_equals_int (csink->n_raw, 0);
2612     fail_unless_equals_int (csink->n_compressed, 0);
2613     gst_object_unref (sink);
2614   }
2615 
2616   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2617   fail_unless (sink != NULL);
2618   {
2619     GstAudioCodecSink *csink;
2620 
2621     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2622         gst_audio_codec_sink_get_type ());
2623     csink = (GstAudioCodecSink *) sink;
2624     fail_unless (csink->audio == TRUE);
2625     fail_unless (csink->n_raw > 0);
2626     fail_unless_equals_int (csink->n_compressed, 0);
2627     gst_object_unref (sink);
2628   }
2629 
2630   gst_element_set_state (playbin, GST_STATE_NULL);
2631   gst_object_unref (playbin);
2632 }
2633 
2634 GST_END_TEST;
2635 
2636 GST_START_TEST
2637     (test_compressed_compressed_audio_stream_demuxer_switch_manual_sink) {
2638   GstMessage *msg;
2639   GstElement *playbin;
2640   GstElement *sink;
2641   GstBus *bus;
2642   gboolean done = FALSE;
2643   GstPad *pad;
2644   SwitchBufferProbeCtx switch_ctx;
2645 
2646   fail_unless (gst_element_register (NULL, "capssrc", GST_RANK_PRIMARY,
2647           gst_caps_src_get_type ()));
2648   fail_unless (gst_element_register (NULL, "codecdemuxer",
2649           GST_RANK_PRIMARY + 100, gst_codec_demuxer_get_type ()));
2650   fail_unless (gst_element_register (NULL, "audiocodecsink",
2651           GST_RANK_PRIMARY + 100, gst_audio_codec_sink_get_type ()));
2652   fail_unless (gst_element_register (NULL, "videocodecsink",
2653           GST_RANK_PRIMARY + 100, gst_video_codec_sink_get_type ()));
2654 
2655   playbin = create_playbin ("caps:application/x-container, "
2656       "stream0=(string)compressed-audio, " "stream1=(string)compressed-audio",
2657       TRUE);
2658 
2659   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
2660       GST_STATE_CHANGE_SUCCESS);
2661 
2662   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2663   fail_unless (sink != NULL);
2664   pad = gst_element_get_static_pad (sink, "sink");
2665   fail_unless (pad != NULL);
2666   switch_ctx.playbin = playbin;
2667   switch_ctx.sink = sink;
2668   gst_pad_add_buffer_probe (pad, G_CALLBACK (switch_audio_buffer_probe),
2669       &switch_ctx);
2670   gst_object_unref (pad);
2671   gst_object_unref (sink);
2672 
2673   fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PLAYING),
2674       GST_STATE_CHANGE_ASYNC);
2675 
2676   bus = gst_element_get_bus (playbin);
2677 
2678   while (!done) {
2679     msg = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
2680 
2681     switch (GST_MESSAGE_TYPE (msg)) {
2682       case GST_MESSAGE_EOS:
2683         done = TRUE;
2684         break;
2685       case GST_MESSAGE_ERROR:
2686         fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
2687         break;
2688       default:
2689         break;
2690     }
2691     gst_message_unref (msg);
2692   }
2693   gst_object_unref (bus);
2694 
2695   g_object_get (G_OBJECT (playbin), "video-sink", &sink, NULL);
2696   fail_unless (sink != NULL);
2697   {
2698     GstVideoCodecSink *csink;
2699 
2700     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2701         gst_video_codec_sink_get_type ());
2702     csink = (GstVideoCodecSink *) sink;
2703     fail_unless (csink->audio == FALSE);
2704     fail_unless_equals_int (csink->n_raw, 0);
2705     fail_unless_equals_int (csink->n_compressed, 0);
2706     gst_object_unref (sink);
2707   }
2708 
2709   g_object_get (G_OBJECT (playbin), "audio-sink", &sink, NULL);
2710   fail_unless (sink != NULL);
2711   {
2712     GstAudioCodecSink *csink;
2713 
2714     fail_unless (G_TYPE_FROM_INSTANCE (sink) ==
2715         gst_audio_codec_sink_get_type ());
2716     csink = (GstAudioCodecSink *) sink;
2717     fail_unless (csink->audio == TRUE);
2718     fail_unless_equals_int (csink->n_raw, 0);
2719     fail_unless (csink->n_compressed > 0);
2720     gst_object_unref (sink);
2721   }
2722 
2723   gst_element_set_state (playbin, GST_STATE_NULL);
2724   gst_object_unref (playbin);
2725 }
2726 
2727 GST_END_TEST;
2728 #endif
2729 #endif
2730 
2731 static Suite *
playbin_complex_suite(void)2732 playbin_complex_suite (void)
2733 {
2734   Suite *s = suite_create ("playbin_complex");
2735   TCase *tc_chain = tcase_create ("general");
2736 
2737   suite_add_tcase (s, tc_chain);
2738 
2739 #ifndef GST_DISABLE_REGISTRY
2740   tcase_add_test (tc_chain, test_raw_single_video_stream_manual_sink);
2741   tcase_add_test (tc_chain, test_raw_single_audio_stream_manual_sink);
2742   tcase_add_test (tc_chain, test_compressed_single_video_stream_manual_sink);
2743   tcase_add_test (tc_chain, test_compressed_single_audio_stream_manual_sink);
2744 
2745   tcase_add_test (tc_chain, test_raw_single_video_stream_demuxer_manual_sink);
2746   tcase_add_test (tc_chain, test_raw_single_audio_stream_demuxer_manual_sink);
2747   tcase_add_test (tc_chain,
2748       test_compressed_single_video_stream_demuxer_manual_sink);
2749   tcase_add_test (tc_chain,
2750       test_compressed_single_audio_stream_demuxer_manual_sink);
2751 
2752   tcase_add_test (tc_chain, test_raw_audio_video_stream_demuxer_manual_sink);
2753   tcase_add_test (tc_chain,
2754       test_compressed_audio_video_stream_demuxer_manual_sink);
2755 
2756   tcase_add_test (tc_chain,
2757       test_raw_compressed_audio_stream_demuxer_manual_sink);
2758   tcase_add_test (tc_chain,
2759       test_raw_compressed_video_stream_demuxer_manual_sink);
2760 
2761   tcase_add_test (tc_chain, test_raw_raw_audio_stream_adder_manual_sink);
2762 
2763   if (gst_registry_check_feature_version (gst_registry_get (),
2764           "oggdemux", GST_VERSION_MAJOR, GST_VERSION_MINOR, 0)) {
2765     tcase_add_test (tc_chain, test_autoplug_decoder_sink_combination);
2766   }
2767   /* These tests need something like the stream-activate event
2768    * and are racy otherwise */
2769 #if 0
2770   tcase_add_test (tc_chain,
2771       test_raw_raw_audio_stream_demuxer_switch_manual_sink);
2772   tcase_add_test (tc_chain,
2773       test_raw_compressed_audio_stream_demuxer_switch_manual_sink);
2774   tcase_add_test (tc_chain,
2775       test_compressed_raw_audio_stream_demuxer_switch_manual_sink);
2776   tcase_add_test (tc_chain,
2777       test_compressed_compressed_audio_stream_demuxer_switch_manual_sink);
2778   tcase_add_test (tc_chain,
2779       test_raw_raw_video_stream_demuxer_switch_manual_sink);
2780   tcase_add_test (tc_chain,
2781       test_raw_compressed_video_stream_demuxer_switch_manual_sink);
2782   tcase_add_test (tc_chain,
2783       test_compressed_raw_video_stream_demuxer_switch_manual_sink);
2784   tcase_add_test (tc_chain,
2785       test_compressed_compressed_video_stream_demuxer_switch_manual_sink);
2786 #endif
2787 #endif
2788 
2789   return s;
2790 }
2791 
2792 GST_CHECK_MAIN (playbin_complex);
2793