1 /* GStreamer unit test for gstprofile
3 * Copyright (C) <2009> Edward Hervey <edward.hervey@collabora.co.uk>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include <gst/pbutils/encoding-profile.h>
26 #include <gst/pbutils/missing-plugins.h>
27 #include <gst/check/gstcheck.h>
29 /* Helper functions to create profiles */
31 static GstEncodingProfile *
34 GstEncodingContainerProfile *prof;
37 ogg = gst_caps_new_empty_simple ("application/ogg");
38 prof = gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg,
41 return (GstEncodingProfile *) prof;
44 static GstEncodingProfile *
45 create_ogg_vorbis_profile (guint presence, gchar * preset)
47 GstEncodingContainerProfile *cprof;
48 GstCaps *ogg, *vorbis;
50 ogg = gst_caps_new_empty_simple ("application/ogg");
52 gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg,
56 vorbis = gst_caps_new_empty_simple ("audio/x-vorbis");
57 fail_unless (gst_encoding_container_profile_add_profile (cprof,
58 (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, preset,
60 gst_caps_unref (vorbis);
62 return (GstEncodingProfile *) cprof;
65 static GstEncodingProfile *
66 create_ogg_theora_vorbis_profile (guint theorapresence, guint vorbispresence)
68 GstEncodingContainerProfile *prof;
69 GstCaps *ogg, *vorbis, *theora;
71 ogg = gst_caps_new_empty_simple ("application/ogg");
73 gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg,
77 vorbis = gst_caps_new_empty_simple ("audio/x-vorbis");
78 fail_unless (gst_encoding_container_profile_add_profile (prof,
79 (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL,
80 NULL, vorbispresence)));
81 gst_caps_unref (vorbis);
83 theora = gst_caps_new_empty_simple ("video/x-theora");
84 fail_unless (gst_encoding_container_profile_add_profile (prof,
85 (GstEncodingProfile *) gst_encoding_video_profile_new (theora, NULL,
86 NULL, theorapresence)));
87 gst_caps_unref (theora);
89 return (GstEncodingProfile *) prof;
92 static GstEncodingProfile *
93 create_vorbis_only_profile (void)
95 GstEncodingProfile *prof;
98 vorbis = gst_caps_new_empty_simple ("audio/x-vorbis");
100 (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL, NULL,
102 gst_caps_unref (vorbis);
107 static GstEncodingProfile *
108 create_unsupported_profile (void)
110 GstEncodingProfile *prof;
113 caps = gst_caps_new_empty_simple ("audio/x-bogus");
115 (GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL, NULL,
117 gst_caps_unref (caps);
123 _caps_match (GstPad * sinkpad, const gchar * capsname)
125 GstCaps *caps, *sinkcaps;
128 caps = gst_caps_from_string (capsname);
129 sinkcaps = gst_pad_query_caps (sinkpad, NULL);
130 fail_unless (sinkcaps != NULL);
131 name = gst_caps_to_string (sinkcaps);
132 fail_unless (gst_caps_is_subset (sinkcaps, caps),
133 "caps ('%s') are not a subset of ('%s')", name, capsname);
135 gst_caps_unref (sinkcaps);
136 gst_caps_unref (caps);
140 set_profile (GstElement * ebin, GstEncodingProfile * prof)
142 g_object_set (ebin, "profile", prof, NULL);
143 gst_encoding_profile_unref (prof);
148 GST_START_TEST (test_encodebin_set_profile)
151 GstEncodingProfile *prof, *prof2;
153 /* Create an encodebin and check that it correctly changes states
154 * according to whether a profile is set or not */
156 ebin = gst_element_factory_make ("encodebin", NULL);
158 /* Set a profile on encodebin... */
159 prof = create_ogg_profile ();
160 g_object_set (ebin, "profile", prof, NULL);
162 /* ... and check the profile has been properly set */
163 g_object_get (ebin, "profile", &prof2, NULL);
165 fail_unless (gst_encoding_profile_is_equal (prof, prof2));
167 gst_encoding_profile_unref (prof);
168 gst_encoding_profile_unref (prof2);
170 gst_object_unref (ebin);
176 GST_START_TEST (test_encodebin_can_go_to_ready_without_profile)
182 /* Create an encodebin and check that it correctly changes states
183 * according to whether a profile is set or not */
185 ebin = gst_element_factory_make ("encodebin", NULL);
187 /* Check if the source pad was properly created */
188 srcpad = gst_element_get_static_pad (ebin, "src");
189 fail_unless (srcpad != NULL);
191 /* At this point, the ghostpad has *NO* target */
192 target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad));
193 fail_unless (target == NULL);
194 gst_object_unref (srcpad);
197 * switching to READY should succeed,
198 * but switching to PAUSED should fail
200 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY),
201 GST_STATE_CHANGE_SUCCESS);
202 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
203 GST_STATE_CHANGE_FAILURE);
205 /* Set back to NULL */
206 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
207 GST_STATE_CHANGE_SUCCESS);
209 gst_object_unref (ebin);
214 GST_START_TEST (test_encodebin_can_go_to_paused_with_profile)
220 /* Create an encodebin and check that it correctly changes states
221 * according to whether a profile is set or not */
223 ebin = gst_element_factory_make ("encodebin", NULL);
225 /* Set a profile on encodebin... */
226 set_profile (ebin, create_ogg_profile ());
228 /* Make sure we can go to PAUSED */
229 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
230 GST_STATE_CHANGE_SUCCESS);
232 /* At this point, the source pad *HAS* a target */
233 srcpad = gst_element_get_static_pad (ebin, "src");
234 fail_unless (srcpad != NULL);
235 target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad));
236 fail_unless (target != NULL);
237 gst_object_unref (target);
238 gst_object_unref (srcpad);
241 /* Set back to NULL */
242 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
243 GST_STATE_CHANGE_SUCCESS);
245 gst_object_unref (ebin);
251 GST_START_TEST (test_encodebin_sink_pads_static)
254 GstPad *srcpad, *sinkpad;
256 /* Create an encodebin and check that it properly creates the sink pads
257 * for a single-stream profile with fixed presence */
259 ebin = gst_element_factory_make ("encodebin", NULL);
261 /* streamprofile that has a forced presence of 1 */
262 set_profile (ebin, create_ogg_vorbis_profile (1, NULL));
264 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
265 GST_STATE_CHANGE_SUCCESS);
267 /* Check if the source pad was properly created */
268 srcpad = gst_element_get_static_pad (ebin, "src");
269 fail_unless (srcpad != NULL);
270 gst_object_unref (srcpad);
272 /* Check if the audio sink pad was properly created */
273 sinkpad = gst_element_get_static_pad (ebin, "audio_0");
274 fail_unless (sinkpad != NULL);
275 /* Check caps match */
276 _caps_match (sinkpad, "audio/x-raw;audio/x-vorbis");
277 gst_object_unref (sinkpad);
279 /* Set back to NULL */
280 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
281 GST_STATE_CHANGE_SUCCESS);
283 gst_object_unref (ebin);
288 GST_START_TEST (test_encodebin_preset)
291 GstEncodingProfile *prof;
292 guint64 max_delay = 0;
293 GstPreset *oggmuxpreset;
295 /* Create an encodebin with a bogus preset and check it fails switching states */
297 ebin = gst_element_factory_make ("encodebin", NULL);
298 oggmuxpreset = GST_PRESET (gst_element_factory_make ("oggmux", NULL));
300 /* We also set the name as the load_preset call will reset the element name to
301 * what is described in the preset... which might not be very smart tbh */
302 g_object_set (oggmuxpreset, "max-delay", (guint64) 12, "name",
303 "testingoggmux", NULL);
305 /* Give a name someone should never use outside of that test */
306 gst_preset_save_preset (oggmuxpreset, "test_encodebin_preset");
308 /* streamprofile that has a forced presence of 1 */
309 prof = create_ogg_vorbis_profile (1, NULL);
311 gst_encoding_profile_set_preset (prof, "test_encodebin_preset");
312 gst_encoding_profile_set_preset_name (prof, "oggmux");
314 set_profile (ebin, prof);
316 /* It will go to READY... */
317 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY),
318 GST_STATE_CHANGE_SUCCESS);
319 /* ... and to PAUSED */
320 fail_unless (gst_element_set_state (ebin, GST_STATE_PAUSED) !=
321 GST_STATE_CHANGE_FAILURE);
323 gst_child_proxy_get (GST_CHILD_PROXY (ebin), "testingoggmux::max-delay",
325 fail_unless_equals_uint64 (max_delay, 12);
327 gst_element_set_state (ebin, GST_STATE_NULL);
328 gst_preset_delete_preset (oggmuxpreset, "test_encodebin_preset");
330 gst_object_unref (ebin);
335 GST_START_TEST (test_encodebin_sink_pads_nopreset_static)
339 /* Create an encodebin with a bogus preset and check it fails switching states */
341 ebin = gst_element_factory_make ("encodebin", NULL);
343 /* streamprofile that has a forced presence of 1 */
345 create_ogg_vorbis_profile (1, (gchar *) "nowaythispresetexists"));
347 /* It will go to READY... */
348 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY),
349 GST_STATE_CHANGE_SUCCESS);
350 /* ... but to not PAUSED */
351 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
352 GST_STATE_CHANGE_FAILURE);
354 gst_element_set_state (ebin, GST_STATE_NULL);
356 gst_object_unref (ebin);
361 GST_START_TEST (test_encodebin_sink_pads_dynamic)
364 GstPad *srcpad, *sinkpad;
367 /* Create an encodebin and check that it properly creates the sink pads
368 * for a single-stream profile with a unfixed presence */
370 ebin = gst_element_factory_make ("encodebin", NULL);
372 /* streamprofile that has non-forced presence */
373 set_profile (ebin, create_ogg_vorbis_profile (0, NULL));
375 /* Check if the source pad was properly created */
376 srcpad = gst_element_get_static_pad (ebin, "src");
377 fail_unless (srcpad != NULL);
378 gst_object_unref (srcpad);
380 /* Check if the audio sink pad can be requested */
381 sinkpad = gst_element_get_request_pad (ebin, "audio_0");
382 fail_unless (sinkpad != NULL);
383 _caps_match (sinkpad, "audio/x-raw;audio/x-vorbis");
384 gst_element_release_request_pad (ebin, sinkpad);
385 gst_object_unref (sinkpad);
388 /* Check again with the 'request-pad' signal */
389 sinkcaps = gst_caps_new_empty_simple ("audio/x-raw");
390 g_signal_emit_by_name (ebin, "request-pad", sinkcaps, &sinkpad);
391 gst_caps_unref (sinkcaps);
392 fail_unless (sinkpad != NULL);
393 _caps_match (sinkpad, "audio/x-raw;audio/x-vorbis");
394 gst_element_release_request_pad (ebin, sinkpad);
395 gst_object_unref (sinkpad);
398 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
399 GST_STATE_CHANGE_SUCCESS);
401 /* Set back to NULL */
402 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
403 GST_STATE_CHANGE_SUCCESS);
405 gst_object_unref (ebin);
410 GST_START_TEST (test_encodebin_sink_pads_multiple_static)
413 GstPad *srcpad, *sinkpadvorbis, *sinkpadtheora;
415 /* Create an encodebin and check that it properly creates the sink pads */
417 ebin = gst_element_factory_make ("encodebin", NULL);
419 /* First try is with a streamprofile that has a forced presence of 1 */
420 set_profile (ebin, create_ogg_theora_vorbis_profile (1, 1));
422 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
423 GST_STATE_CHANGE_SUCCESS);
425 /* Check if the source pad was properly created */
426 srcpad = gst_element_get_static_pad (ebin, "src");
427 fail_unless (srcpad != NULL);
428 gst_object_unref (srcpad);
430 /* Check if the audio sink pad was properly created */
431 sinkpadvorbis = gst_element_get_static_pad (ebin, "audio_0");
432 fail_unless (sinkpadvorbis != NULL);
433 _caps_match (sinkpadvorbis, "audio/x-raw;audio/x-vorbis");
434 gst_object_unref (sinkpadvorbis);
436 /* Check if the video sink pad was properly created */
437 sinkpadtheora = gst_element_get_static_pad (ebin, "video_1");
438 fail_unless (sinkpadtheora != NULL);
439 _caps_match (sinkpadtheora, "video/x-raw;video/x-theora");
440 gst_object_unref (sinkpadtheora);
442 /* Set back to NULL */
443 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
444 GST_STATE_CHANGE_SUCCESS);
446 gst_object_unref (ebin);
451 GST_START_TEST (test_encodebin_sink_pads_multiple_dynamic)
454 GstPad *srcpad, *sinkpadvorbis, *sinkpadtheora;
456 /* Create an encodebin and check that it properly creates the sink pads
457 * for a multiple-stream with unfixed presence */
459 ebin = gst_element_factory_make ("encodebin", NULL);
461 /* multi-stream profile that has non-forced presence */
462 set_profile (ebin, create_ogg_theora_vorbis_profile (0, 0));
464 /* Check if the source pad was properly created */
465 srcpad = gst_element_get_static_pad (ebin, "src");
466 fail_unless (srcpad != NULL);
467 gst_object_unref (srcpad);
469 /* Check if the audio sink pad was properly created */
470 sinkpadvorbis = gst_element_get_request_pad (ebin, "audio_0");
471 _caps_match (sinkpadvorbis, "audio/x-raw;audio/x-vorbis");
472 fail_unless (sinkpadvorbis != NULL);
474 /* Check if the video sink pad was properly created */
475 sinkpadtheora = gst_element_get_request_pad (ebin, "video_1");
476 _caps_match (sinkpadtheora, "video/x-raw;video/x-theora");
477 fail_unless (sinkpadtheora != NULL);
479 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
480 GST_STATE_CHANGE_SUCCESS);
482 /* Set back to NULL */
483 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
484 GST_STATE_CHANGE_SUCCESS);
486 gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpadvorbis);
487 gst_object_unref (sinkpadvorbis);
488 gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpadtheora);
489 gst_object_unref (sinkpadtheora);
491 gst_object_unref (ebin);
496 GST_START_TEST (test_encodebin_sink_pads_dynamic_encoder)
499 GstPad *srcpad, *sinkpad = NULL;
502 /* Create an encodebin and check that it properly creates the sink pads
503 * for a single-stream profile with a unfixed presence */
505 ebin = gst_element_factory_make ("encodebin", NULL);
507 /* streamprofile that has non-forced presence */
508 set_profile (ebin, create_ogg_vorbis_profile (0, NULL));
510 /* Check if the source pad was properly created */
511 srcpad = gst_element_get_static_pad (ebin, "src");
512 fail_unless (srcpad != NULL);
513 gst_object_unref (srcpad);
515 /* Check if the audio sink pad was properly created */
516 vorbiscaps = gst_caps_from_string ("audio/x-vorbis,channels=2,rate=44100");
517 g_signal_emit_by_name (ebin, "request-pad", vorbiscaps, &sinkpad);
518 gst_caps_unref (vorbiscaps);
519 fail_unless (sinkpad != NULL);
520 _caps_match (sinkpad, "audio/x-raw;audio/x-vorbis");
521 gst_element_release_request_pad (ebin, sinkpad);
522 gst_object_unref (sinkpad);
524 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
525 GST_STATE_CHANGE_SUCCESS);
527 /* Set back to NULL */
528 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
529 GST_STATE_CHANGE_SUCCESS);
531 gst_object_unref (ebin);
536 GST_START_TEST (test_encodebin_render_audio_static)
538 GstElement *ebin, *pipeline, *audiotestsrc, *fakesink;
540 gboolean done = FALSE;
542 /* Create an encodebin and render 5s of vorbis/ogg */
544 pipeline = gst_pipeline_new ("encodebin-pipeline");
545 bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
546 audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
547 g_object_set (audiotestsrc, "num-buffers", 10, NULL);
548 fakesink = gst_element_factory_make ("fakesink", NULL);
550 ebin = gst_element_factory_make ("encodebin", NULL);
551 set_profile (ebin, create_ogg_vorbis_profile (1, NULL));
553 gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL);
555 fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL));
557 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
558 GST_STATE_CHANGE_ASYNC);
563 /* poll the bus until we get EOS without any errors */
564 msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
566 switch (GST_MESSAGE_TYPE (msg)) {
567 case GST_MESSAGE_ERROR:
568 fail ("GST_MESSAGE_ERROR");
570 case GST_MESSAGE_EOS:
576 gst_message_unref (msg);
580 /* Set back to NULL */
581 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
582 GST_STATE_CHANGE_SUCCESS);
584 gst_object_unref (bus);
586 gst_object_unref (pipeline);
591 GST_START_TEST (test_encodebin_render_audio_only_static)
593 GstElement *ebin, *pipeline, *audiotestsrc, *fakesink;
595 gboolean done = FALSE;
599 /* Create an encodebin and render 5s of vorbis only */
600 pipeline = gst_pipeline_new ("encodebin-pipeline");
601 bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
602 audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
603 g_object_set (audiotestsrc, "num-buffers", 10, NULL);
604 fakesink = gst_element_factory_make ("fakesink", NULL);
606 ebin = gst_element_factory_make ("encodebin", NULL);
607 set_profile (ebin, create_vorbis_only_profile ());
609 gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, ebin, fakesink, NULL);
611 GST_DEBUG ("linking encodebin");
612 fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL));
614 /* Requesting a new pad should fail */
615 ASSERT_CRITICAL (gst_element_get_request_pad (ebin, "audio_0"));
617 sinkcaps = gst_caps_new_empty_simple ("audio/x-raw");
618 g_signal_emit_by_name (ebin, "request-pad", sinkcaps, &sinkpad);
619 gst_caps_unref (sinkcaps);
620 fail_if (sinkpad != NULL);
622 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
623 GST_STATE_CHANGE_ASYNC);
628 /* poll the bus until we get EOS without any errors */
629 msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
631 switch (GST_MESSAGE_TYPE (msg)) {
632 case GST_MESSAGE_ERROR:
633 fail ("GST_MESSAGE_ERROR");
635 case GST_MESSAGE_EOS:
641 gst_message_unref (msg);
645 /* Set back to NULL */
646 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
647 GST_STATE_CHANGE_SUCCESS);
649 gst_object_unref (bus);
651 gst_object_unref (pipeline);
656 GST_START_TEST (test_encodebin_render_audio_dynamic)
658 GstElement *ebin, *pipeline, *audiotestsrc, *fakesink;
660 GstPad *sinkpad, *srcpad;
661 gboolean done = FALSE;
663 /* Create an encodebin and render 5s of vorbis/ogg */
665 pipeline = gst_pipeline_new ("encodebin-pipeline");
666 bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
667 audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
668 g_object_set (audiotestsrc, "num-buffers", 10, NULL);
669 fakesink = gst_element_factory_make ("fakesink", NULL);
671 ebin = gst_element_factory_make ("encodebin", NULL);
672 set_profile (ebin, create_ogg_vorbis_profile (0, NULL));
674 gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL);
676 srcpad = gst_element_get_static_pad (audiotestsrc, "src");
677 fail_unless (srcpad != NULL);
679 sinkpad = gst_element_get_request_pad (ebin, "audio_0");
680 fail_unless (sinkpad != NULL);
681 _caps_match (sinkpad, "audio/x-raw;audio/x-vorbis");
683 fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK);
685 gst_object_unref (srcpad);
687 fail_unless (gst_element_link (ebin, fakesink));
689 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
690 GST_STATE_CHANGE_ASYNC);
695 /* poll the bus until we get EOS without any errors */
696 msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
698 switch (GST_MESSAGE_TYPE (msg)) {
699 case GST_MESSAGE_ERROR:
700 fail ("GST_MESSAGE_ERROR");
702 case GST_MESSAGE_EOS:
708 gst_message_unref (msg);
712 /* Set back to NULL */
713 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
714 GST_STATE_CHANGE_SUCCESS);
716 gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad);
717 gst_object_unref (sinkpad);
719 gst_object_unref (bus);
721 gst_object_unref (pipeline);
726 GST_START_TEST (test_encodebin_render_audio_video_static)
728 GstElement *ebin, *pipeline, *audiotestsrc, *videotestsrc, *fakesink;
730 gboolean done = FALSE;
732 /* Create an encodebin and render 5s of vorbis/ogg */
734 pipeline = gst_pipeline_new ("encodebin-pipeline");
735 bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
736 audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
737 g_object_set (audiotestsrc, "num-buffers", 10, NULL);
738 videotestsrc = gst_element_factory_make ("videotestsrc", NULL);
739 g_object_set (videotestsrc, "num-buffers", 5, NULL);
740 fakesink = gst_element_factory_make ("fakesink", NULL);
742 ebin = gst_element_factory_make ("encodebin", NULL);
743 set_profile (ebin, create_ogg_theora_vorbis_profile (1, 1));
745 gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, videotestsrc, ebin,
748 fail_unless (gst_element_link (videotestsrc, ebin));
749 fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL));
751 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
752 GST_STATE_CHANGE_ASYNC);
757 /* poll the bus until we get EOS without any errors */
758 msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
760 switch (GST_MESSAGE_TYPE (msg)) {
761 case GST_MESSAGE_ERROR:
762 fail ("GST_MESSAGE_ERROR");
764 case GST_MESSAGE_EOS:
770 gst_message_unref (msg);
774 /* Set back to NULL */
775 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
776 GST_STATE_CHANGE_SUCCESS);
778 gst_object_unref (bus);
780 gst_object_unref (pipeline);
785 GST_START_TEST (test_encodebin_render_audio_video_dynamic)
787 GstElement *ebin, *pipeline, *audiotestsrc, *videotestsrc, *fakesink;
789 gboolean done = FALSE;
790 GstPad *sinkpad1, *sinkpad2, *srcpad;
792 /* Create an encodebin and render 5s of vorbis/ogg */
794 pipeline = gst_pipeline_new ("encodebin-pipeline");
795 bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
796 audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
797 g_object_set (audiotestsrc, "num-buffers", 10, NULL);
798 videotestsrc = gst_element_factory_make ("videotestsrc", NULL);
799 g_object_set (videotestsrc, "num-buffers", 5, NULL);
800 fakesink = gst_element_factory_make ("fakesink", NULL);
802 ebin = gst_element_factory_make ("encodebin", NULL);
803 set_profile (ebin, create_ogg_theora_vorbis_profile (0, 0));
805 gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, videotestsrc, ebin,
808 fail_unless (gst_element_link (ebin, fakesink));
810 srcpad = gst_element_get_static_pad (audiotestsrc, "src");
811 sinkpad1 = gst_element_get_request_pad (ebin, "audio_0");
812 fail_unless (srcpad != NULL);
813 fail_unless (sinkpad1 != NULL);
814 _caps_match (sinkpad1, "audio/x-raw;audio/x-vorbis");
815 fail_unless_equals_int (gst_pad_link (srcpad, sinkpad1), GST_PAD_LINK_OK);
816 gst_object_unref (srcpad);
818 srcpad = gst_element_get_static_pad (videotestsrc, "src");
819 sinkpad2 = gst_element_get_request_pad (ebin, "video_1");
820 _caps_match (sinkpad2, "video/x-raw;video/x-theora");
821 fail_unless_equals_int (gst_pad_link (srcpad, sinkpad2), GST_PAD_LINK_OK);
822 gst_object_unref (srcpad);
824 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
825 GST_STATE_CHANGE_ASYNC);
830 /* poll the bus until we get EOS without any errors */
831 msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
833 switch (GST_MESSAGE_TYPE (msg)) {
834 case GST_MESSAGE_ERROR:
835 fail ("GST_MESSAGE_ERROR");
837 case GST_MESSAGE_EOS:
843 gst_message_unref (msg);
847 /* Set back to NULL */
848 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
849 GST_STATE_CHANGE_SUCCESS);
851 gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad1);
852 gst_object_unref (sinkpad1);
853 gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad2);
854 gst_object_unref (sinkpad2);
856 gst_object_unref (bus);
858 gst_object_unref (pipeline);
863 GST_START_TEST (test_encodebin_impossible_element_combination)
866 GstEncodingProfile *prof;
869 ebin = gst_element_factory_make ("x264enc", NULL);
871 GST_DEBUG ("No available h264 encoder, skipping test");
874 gst_object_unref (ebin);
876 /* Make sure that impossible combinations of encoders and muxer
877 * properly fail. In this case we try putting h264 in ogg.
879 * To properly test we abort early, we use a presence of zero for the
880 * h264 stream profile. */
882 ebin = gst_element_factory_make ("encodebin", NULL);
884 ogg = gst_caps_new_empty_simple ("application/ogg");
885 prof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *)
886 "myprofile", NULL, ogg, NULL);
887 gst_caps_unref (ogg);
889 x264 = gst_caps_new_empty_simple ("video/x-h264");
890 fail_unless (gst_encoding_container_profile_add_profile
891 (GST_ENCODING_CONTAINER_PROFILE (prof),
892 (GstEncodingProfile *) gst_encoding_video_profile_new (x264, NULL,
894 gst_caps_unref (x264);
896 g_object_set (ebin, "profile", prof, NULL);
897 gst_encoding_profile_unref (prof);
899 /* It will go to READY... */
900 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY),
901 GST_STATE_CHANGE_SUCCESS);
902 /* ... but to not PAUSED */
903 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
904 GST_STATE_CHANGE_FAILURE);
906 gst_element_set_state (ebin, GST_STATE_NULL);
908 gst_object_unref (ebin);
914 _test_encodebin_reuse (GstEncodingProfile * prof1, GstEncodingProfile * prof2)
918 ebin = gst_element_factory_make ("encodebin", NULL);
920 /* Set a profile on encodebin... */
922 g_object_set (ebin, "profile", prof1, NULL);
924 /* Make sure we can go to PAUSED */
925 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
926 GST_STATE_CHANGE_SUCCESS);
928 /* Set back to NULL */
929 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
930 GST_STATE_CHANGE_SUCCESS);
933 g_object_set (ebin, "profile", prof2, NULL);
935 /* Make sure we can go to PLAYING */
936 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
937 GST_STATE_CHANGE_SUCCESS);
939 /* Set back to NULL */
940 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
941 GST_STATE_CHANGE_SUCCESS);
943 gst_object_unref (ebin);
946 GST_START_TEST (test_encodebin_reuse)
948 GstEncodingProfile *prof1;
949 GstEncodingProfile *prof2;
950 GstEncodingProfile *prof3;
953 caps = gst_caps_new_empty_simple ("application/ogg");
954 prof1 = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *)
955 "myprofile", NULL, caps, NULL);
956 gst_caps_unref (caps);
958 prof2 = create_ogg_theora_vorbis_profile (1, 1);
959 prof3 = create_vorbis_only_profile ();
961 _test_encodebin_reuse (prof1, NULL);
962 _test_encodebin_reuse (prof1, prof1);
964 _test_encodebin_reuse (prof1, prof2);
966 _test_encodebin_reuse (prof2, prof3);
968 gst_encoding_profile_unref (prof1);
969 gst_encoding_profile_unref (prof2);
970 gst_encoding_profile_unref (prof3);
975 GST_START_TEST (test_encodebin_named_requests)
978 GstEncodingContainerProfile *cprof;
979 GstCaps *ogg, *vorbis, *theora;
980 GstEncodingProfile *vorbisprof, *theoraprof;
981 GstPad *srcpad, *sinkpadvorbis, *sinkpadtheora;
983 /* Create a profile with vorbis/theora named profile */
984 ogg = gst_caps_new_empty_simple ("application/ogg");
986 gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg,
988 gst_caps_unref (ogg);
990 vorbis = gst_caps_new_empty_simple ("audio/x-vorbis");
992 (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL, NULL,
994 gst_encoding_profile_set_name (vorbisprof, "vorbisprofile");
995 fail_unless (gst_encoding_container_profile_add_profile (cprof, vorbisprof));
996 gst_caps_unref (vorbis);
998 theora = gst_caps_new_empty_simple ("video/x-theora");
1000 (GstEncodingProfile *) gst_encoding_video_profile_new (theora, NULL, NULL,
1002 gst_encoding_profile_set_name (theoraprof, "theoraprofile");
1003 fail_unless (gst_encoding_container_profile_add_profile (cprof, theoraprof));
1004 gst_caps_unref (theora);
1006 ebin = gst_element_factory_make ("encodebin", NULL);
1008 /* First try is with a streamprofile that has a forced presence of 1 */
1009 g_object_set (ebin, "profile", cprof, NULL);
1011 gst_encoding_profile_unref (cprof);
1013 /* Check if the source pad was properly created */
1014 srcpad = gst_element_get_static_pad (ebin, "src");
1015 fail_unless (srcpad != NULL);
1016 gst_object_unref (srcpad);
1018 /* Request a vorbis profile pad */
1019 g_signal_emit_by_name (ebin, "request-profile-pad", "vorbisprofile",
1021 fail_unless (sinkpadvorbis != NULL);
1022 _caps_match (sinkpadvorbis, "audio/x-raw;audio/x-vorbis");
1023 gst_object_unref (sinkpadvorbis);
1025 /* Request a theora profile pad */
1026 g_signal_emit_by_name (ebin, "request-profile-pad", "theoraprofile",
1028 fail_unless (sinkpadtheora != NULL);
1029 _caps_match (sinkpadtheora, "video/x-raw;video/x-theora");
1030 gst_object_unref (sinkpadtheora);
1032 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
1033 GST_STATE_CHANGE_SUCCESS);
1035 /* Set back to NULL */
1036 fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
1037 GST_STATE_CHANGE_SUCCESS);
1039 gst_object_unref (ebin);
1045 GST_START_TEST (test_encodebin_missing_plugin_messages)
1047 GstElement *pipeline = gst_pipeline_new ("test");
1048 GstBus *bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
1049 GstElement *ebin = gst_element_factory_make ("encodebin", NULL);
1050 GstMessage *message;
1052 /* first add to bin, then set profile */
1053 gst_bin_add ((GstBin *) pipeline, ebin);
1054 set_profile (ebin, create_unsupported_profile ());
1056 gst_element_set_state (pipeline, GST_STATE_READY);
1058 message = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT);
1059 fail_if (message == NULL);
1060 fail_if (!gst_is_missing_plugin_message (message));
1061 gst_message_unref (message);
1063 gst_element_set_state (pipeline, GST_STATE_NULL);
1064 gst_object_unref (bus);
1065 gst_object_unref (pipeline);
1071 encodebin_suite (void)
1073 Suite *s = suite_create ("encodebin element");
1074 TCase *tc_chain = tcase_create ("general");
1076 suite_add_tcase (s, tc_chain);
1077 tcase_add_test (tc_chain, test_encodebin_set_profile);
1078 tcase_add_test (tc_chain, test_encodebin_can_go_to_ready_without_profile);
1079 tcase_add_test (tc_chain, test_encodebin_can_go_to_paused_with_profile);
1080 tcase_add_test (tc_chain, test_encodebin_sink_pads_static);
1081 tcase_add_test (tc_chain, test_encodebin_sink_pads_nopreset_static);
1082 tcase_add_test (tc_chain, test_encodebin_preset);
1083 tcase_add_test (tc_chain, test_encodebin_sink_pads_dynamic);
1084 tcase_add_test (tc_chain, test_encodebin_sink_pads_multiple_static);
1085 tcase_add_test (tc_chain, test_encodebin_sink_pads_multiple_dynamic);
1086 tcase_add_test (tc_chain, test_encodebin_sink_pads_dynamic_encoder);
1087 tcase_add_test (tc_chain, test_encodebin_render_audio_static);
1088 tcase_add_test (tc_chain, test_encodebin_render_audio_only_static);
1089 tcase_add_test (tc_chain, test_encodebin_render_audio_dynamic);
1090 tcase_add_test (tc_chain, test_encodebin_render_audio_video_static);
1091 tcase_add_test (tc_chain, test_encodebin_render_audio_video_dynamic);
1092 tcase_add_test (tc_chain, test_encodebin_impossible_element_combination);
1093 tcase_add_test (tc_chain, test_encodebin_reuse);
1094 tcase_add_test (tc_chain, test_encodebin_named_requests);
1095 tcase_add_test (tc_chain, test_encodebin_missing_plugin_messages);
1100 GST_CHECK_MAIN (encodebin);