Macro qtTrIdx() replaced by tr() and QT_TRANSLATE_NOOP()
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / tests / check / elements / encodebin.c
1 /* GStreamer unit test for gstprofile
2  *
3  * Copyright (C) <2009> Edward Hervey <edward.hervey@collabora.co.uk>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gst/pbutils/encoding-profile.h>
26 #include <gst/check/gstcheck.h>
27
28 /* Helper functions to create profiles */
29
30 static GstEncodingProfile *
31 create_ogg_vorbis_profile (guint presence, gchar * preset)
32 {
33   GstEncodingContainerProfile *cprof;
34   GstCaps *ogg, *vorbis;
35
36   ogg = gst_caps_new_simple ("application/ogg", NULL);
37   cprof =
38       gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg,
39       NULL);
40   gst_caps_unref (ogg);
41
42   vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL);
43   fail_unless (gst_encoding_container_profile_add_profile (cprof,
44           (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, preset,
45               NULL, presence)));
46   gst_caps_unref (vorbis);
47
48   return (GstEncodingProfile *) cprof;
49 }
50
51 static GstEncodingProfile *
52 create_ogg_theora_vorbis_profile (guint theorapresence, guint vorbispresence)
53 {
54   GstEncodingContainerProfile *prof;
55   GstCaps *ogg, *vorbis, *theora;
56
57   ogg = gst_caps_new_simple ("application/ogg", NULL);
58   prof =
59       gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg,
60       NULL);
61   gst_caps_unref (ogg);
62
63   vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL);
64   fail_unless (gst_encoding_container_profile_add_profile (prof,
65           (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL,
66               NULL, vorbispresence)));
67   gst_caps_unref (vorbis);
68
69   theora = gst_caps_new_simple ("video/x-theora", NULL);
70   fail_unless (gst_encoding_container_profile_add_profile (prof,
71           (GstEncodingProfile *) gst_encoding_video_profile_new (theora, NULL,
72               NULL, theorapresence)));
73   gst_caps_unref (theora);
74
75   return (GstEncodingProfile *) prof;
76 }
77
78 static GstEncodingProfile *
79 create_vorbis_only_profile (void)
80 {
81   GstEncodingProfile *prof;
82   GstCaps *vorbis;
83
84   vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL);
85   prof =
86       (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL, NULL,
87       0);
88   gst_caps_unref (vorbis);
89
90   return prof;
91 }
92
93 GST_START_TEST (test_encodebin_states)
94 {
95   GstElement *ebin;
96   GstEncodingProfile *prof, *prof2;
97   GstCaps *ogg;
98   GstPad *srcpad;
99   GstPad *target;
100
101   /* Create an encodebin and check that it correctly changes states
102    * according to whether a profile is set or not */
103
104   ebin = gst_element_factory_make ("encodebin", NULL);
105
106   /* Check if the source pad was properly created */
107   srcpad = gst_element_get_static_pad (ebin, "src");
108   fail_unless (srcpad != NULL);
109
110   /* At this point, the ghostpad has *NO* target */
111   target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad));
112   fail_unless (target == NULL);
113   gst_object_unref (srcpad);
114
115   /* No profile,
116    * switching to READY should succeed,
117    * but switching to PAUSED should fail
118    */
119   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY),
120       GST_STATE_CHANGE_SUCCESS);
121   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
122       GST_STATE_CHANGE_FAILURE);
123
124   /* Set a profile on encodebin... */
125   ogg = gst_caps_new_simple ("application/ogg", NULL);
126   prof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *)
127       "myprofile", NULL, ogg, NULL);
128   gst_caps_unref (ogg);
129
130   g_object_set (ebin, "profile", prof, NULL);
131
132   /* ... and check the profile has been properly set */
133   g_object_get (ebin, "profile", &prof2, NULL);
134
135   fail_unless (gst_encoding_profile_is_equal (prof, prof2));
136
137   gst_encoding_profile_unref (prof);
138   gst_encoding_profile_unref (prof2);
139
140   /* Make sure we can go to PAUSED */
141   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
142       GST_STATE_CHANGE_SUCCESS);
143
144   /* At this point, the source pad *HAS* a target */
145   srcpad = gst_element_get_static_pad (ebin, "src");
146   fail_unless (srcpad != NULL);
147   target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad));
148   fail_unless (target != NULL);
149   gst_object_unref (target);
150   gst_object_unref (srcpad);
151
152
153   /* Set back to NULL */
154   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
155       GST_STATE_CHANGE_SUCCESS);
156
157   gst_object_unref (ebin);
158 };
159
160 GST_END_TEST;
161
162 GST_START_TEST (test_encodebin_sink_pads_static)
163 {
164   GstElement *ebin;
165   GstEncodingProfile *prof;
166   GstPad *srcpad, *sinkpad;
167
168   /* Create an encodebin and check that it properly creates the sink pads
169    * for a single-stream profile with fixed presence */
170
171   ebin = gst_element_factory_make ("encodebin", NULL);
172
173   /* streamprofile that has a forced presence of 1 */
174   prof = create_ogg_vorbis_profile (1, NULL);
175
176   g_object_set (ebin, "profile", prof, NULL);
177
178   gst_encoding_profile_unref (prof);
179
180   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
181       GST_STATE_CHANGE_SUCCESS);
182
183   /* Check if the source pad was properly created */
184   srcpad = gst_element_get_static_pad (ebin, "src");
185   fail_unless (srcpad != NULL);
186   gst_object_unref (srcpad);
187
188   /* Check if the audio sink pad was properly created */
189   sinkpad = gst_element_get_static_pad (ebin, "audio_0");
190   fail_unless (sinkpad != NULL);
191   gst_object_unref (sinkpad);
192
193   /* Set back to NULL */
194   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
195       GST_STATE_CHANGE_SUCCESS);
196
197   gst_object_unref (ebin);
198 };
199
200 GST_END_TEST;
201
202 GST_START_TEST (test_encodebin_sink_pads_nopreset_static)
203 {
204   GstElement *ebin;
205   GstEncodingProfile *prof;
206
207   /* Create an encodebin with a bogus preset and check it fails switching states */
208
209   ebin = gst_element_factory_make ("encodebin", NULL);
210
211   /* streamprofile that has a forced presence of 1 */
212   prof = create_ogg_vorbis_profile (1, (gchar *) "nowaythispresetexists");
213
214   g_object_set (ebin, "profile", prof, NULL);
215
216   gst_encoding_profile_unref (prof);
217
218   /* It will go to READY... */
219   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY),
220       GST_STATE_CHANGE_SUCCESS);
221   /* ... but to not PAUSED */
222   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
223       GST_STATE_CHANGE_FAILURE);
224
225   gst_element_set_state (ebin, GST_STATE_NULL);
226
227   gst_object_unref (ebin);
228 };
229
230 GST_END_TEST;
231
232 GST_START_TEST (test_encodebin_sink_pads_dynamic)
233 {
234   GstElement *ebin;
235   GstEncodingProfile *prof;
236   GstPad *srcpad, *sinkpad;
237   GstCaps *sinkcaps;
238
239   /* Create an encodebin and check that it properly creates the sink pads
240    * for a single-stream profile with a unfixed presence */
241
242   ebin = gst_element_factory_make ("encodebin", NULL);
243
244   /* streamprofile that has non-forced presence */
245   prof = create_ogg_vorbis_profile (0, NULL);
246
247   g_object_set (ebin, "profile", prof, NULL);
248
249   gst_encoding_profile_unref (prof);
250
251   /* Check if the source pad was properly created */
252   srcpad = gst_element_get_static_pad (ebin, "src");
253   fail_unless (srcpad != NULL);
254   gst_object_unref (srcpad);
255
256   /* Check if the audio sink pad can be requested */
257   sinkpad = gst_element_get_request_pad (ebin, "audio_0");
258   fail_unless (sinkpad != NULL);
259   gst_element_release_request_pad (ebin, sinkpad);
260   gst_object_unref (sinkpad);
261   sinkpad = NULL;
262
263   /* Check again with the 'request-pad' signal */
264   sinkcaps = gst_caps_new_simple ("audio/x-raw-int", NULL);
265   g_signal_emit_by_name (ebin, "request-pad", sinkcaps, &sinkpad);
266   gst_caps_unref (sinkcaps);
267   fail_unless (sinkpad != NULL);
268   gst_element_release_request_pad (ebin, sinkpad);
269   gst_object_unref (sinkpad);
270   sinkpad = NULL;
271
272   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
273       GST_STATE_CHANGE_SUCCESS);
274
275   /* Set back to NULL */
276   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
277       GST_STATE_CHANGE_SUCCESS);
278
279   gst_object_unref (ebin);
280 };
281
282 GST_END_TEST;
283
284 GST_START_TEST (test_encodebin_sink_pads_multiple_static)
285 {
286   GstElement *ebin;
287   GstEncodingProfile *prof;
288   GstPad *srcpad, *sinkpadvorbis, *sinkpadtheora;
289
290   /* Create an encodebin and check that it properly creates the sink pads */
291
292   ebin = gst_element_factory_make ("encodebin", NULL);
293
294   /* First try is with a streamprofile that has a forced presence of 1 */
295   prof = create_ogg_theora_vorbis_profile (1, 1);
296
297   g_object_set (ebin, "profile", prof, NULL);
298
299   gst_encoding_profile_unref (prof);
300
301   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
302       GST_STATE_CHANGE_SUCCESS);
303
304   /* Check if the source pad was properly created */
305   srcpad = gst_element_get_static_pad (ebin, "src");
306   fail_unless (srcpad != NULL);
307   gst_object_unref (srcpad);
308
309   /* Check if the audio sink pad was properly created */
310   sinkpadvorbis = gst_element_get_static_pad (ebin, "audio_0");
311   fail_unless (sinkpadvorbis != NULL);
312   gst_object_unref (sinkpadvorbis);
313
314   /* Check if the video sink pad was properly created */
315   sinkpadtheora = gst_element_get_static_pad (ebin, "video_1");
316   fail_unless (sinkpadtheora != NULL);
317   gst_object_unref (sinkpadtheora);
318
319   /* Set back to NULL */
320   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
321       GST_STATE_CHANGE_SUCCESS);
322
323   gst_object_unref (ebin);
324 };
325
326 GST_END_TEST;
327
328 GST_START_TEST (test_encodebin_sink_pads_multiple_dynamic)
329 {
330   GstElement *ebin;
331   GstEncodingProfile *prof;
332   GstPad *srcpad, *sinkpadvorbis, *sinkpadtheora;
333
334   /* Create an encodebin and check that it properly creates the sink pads
335    * for a multiple-stream with unfixed presence */
336
337   ebin = gst_element_factory_make ("encodebin", NULL);
338
339   /* multi-stream profile that has non-forced presence */
340   prof = create_ogg_theora_vorbis_profile (0, 0);
341
342   g_object_set (ebin, "profile", prof, NULL);
343
344   gst_encoding_profile_unref (prof);
345
346   /* Check if the source pad was properly created */
347   srcpad = gst_element_get_static_pad (ebin, "src");
348   fail_unless (srcpad != NULL);
349   gst_object_unref (srcpad);
350
351   /* Check if the audio sink pad was properly created */
352   sinkpadvorbis = gst_element_get_request_pad (ebin, "audio_0");
353   fail_unless (sinkpadvorbis != NULL);
354
355   /* Check if the video sink pad was properly created */
356   sinkpadtheora = gst_element_get_request_pad (ebin, "video_1");
357   fail_unless (sinkpadtheora != NULL);
358
359   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
360       GST_STATE_CHANGE_SUCCESS);
361
362   /* Set back to NULL */
363   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
364       GST_STATE_CHANGE_SUCCESS);
365
366   gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpadvorbis);
367   gst_object_unref (sinkpadvorbis);
368   gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpadtheora);
369   gst_object_unref (sinkpadtheora);
370
371   gst_object_unref (ebin);
372 };
373
374 GST_END_TEST;
375
376 GST_START_TEST (test_encodebin_sink_pads_dynamic_encoder)
377 {
378   GstElement *ebin;
379   GstEncodingProfile *prof;
380   GstPad *srcpad, *sinkpad = NULL;
381   GstCaps *vorbiscaps;
382
383   /* Create an encodebin and check that it properly creates the sink pads
384    * for a single-stream profile with a unfixed presence */
385
386   ebin = gst_element_factory_make ("encodebin", NULL);
387
388   /* streamprofile that has non-forced presence */
389   prof = create_ogg_vorbis_profile (0, NULL);
390
391   g_object_set (ebin, "profile", prof, NULL);
392
393   gst_encoding_profile_unref (prof);
394
395   /* Check if the source pad was properly created */
396   srcpad = gst_element_get_static_pad (ebin, "src");
397   fail_unless (srcpad != NULL);
398   gst_object_unref (srcpad);
399
400   /* Check if the audio sink pad was properly created */
401   vorbiscaps = gst_caps_from_string ("audio/x-vorbis,channels=2,rate=44100");
402   g_signal_emit_by_name (ebin, "request-pad", vorbiscaps, &sinkpad);
403   gst_caps_unref (vorbiscaps);
404   fail_unless (sinkpad != NULL);
405   gst_element_release_request_pad (ebin, sinkpad);
406   gst_object_unref (sinkpad);
407
408   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
409       GST_STATE_CHANGE_SUCCESS);
410
411   /* Set back to NULL */
412   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
413       GST_STATE_CHANGE_SUCCESS);
414
415   gst_object_unref (ebin);
416 };
417
418 GST_END_TEST;
419
420 GST_START_TEST (test_encodebin_render_audio_static)
421 {
422   GstElement *ebin, *pipeline, *audiotestsrc, *fakesink;
423   GstEncodingProfile *prof;
424   GstBus *bus;
425   gboolean done = FALSE;
426
427   /* Create an encodebin and render 5s of vorbis/ogg */
428
429   pipeline = gst_pipeline_new ("encodebin-pipeline");
430   bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
431   audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
432   g_object_set (audiotestsrc, "num-buffers", 10, NULL);
433   fakesink = gst_element_factory_make ("fakesink", NULL);
434
435   ebin = gst_element_factory_make ("encodebin", NULL);
436
437   prof = create_ogg_vorbis_profile (1, NULL);
438   g_object_set (ebin, "profile", prof, NULL);
439   gst_encoding_profile_unref (prof);
440
441   gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL);
442
443   fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL));
444
445   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
446       GST_STATE_CHANGE_ASYNC);
447
448   while (!done) {
449     GstMessage *msg;
450
451     /* poll the bus until we get EOS without any errors */
452     msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
453     if (msg) {
454       switch (GST_MESSAGE_TYPE (msg)) {
455         case GST_MESSAGE_ERROR:
456           fail ("GST_MESSAGE_ERROR");
457           break;
458         case GST_MESSAGE_EOS:
459           done = TRUE;
460           break;
461         default:
462           break;
463       }
464       gst_message_unref (msg);
465     }
466   }
467
468   /* Set back to NULL */
469   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
470       GST_STATE_CHANGE_SUCCESS);
471
472   gst_object_unref (bus);
473
474   gst_object_unref (pipeline);
475 }
476
477 GST_END_TEST;
478
479 GST_START_TEST (test_encodebin_render_audio_only_static)
480 {
481   GstElement *ebin, *pipeline, *audiotestsrc, *fakesink;
482   GstEncodingProfile *prof;
483   GstBus *bus;
484   gboolean done = FALSE;
485   GstPad *sinkpad;
486   GstCaps *sinkcaps;
487
488   /* Create an encodebin and render 5s of vorbis only */
489
490   pipeline = gst_pipeline_new ("encodebin-pipeline");
491   bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
492   audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
493   g_object_set (audiotestsrc, "num-buffers", 10, NULL);
494   fakesink = gst_element_factory_make ("fakesink", NULL);
495
496   ebin = gst_element_factory_make ("encodebin", NULL);
497
498   prof = create_vorbis_only_profile ();
499   g_object_set (ebin, "profile", prof, NULL);
500   gst_encoding_profile_unref (prof);
501
502   gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL);
503
504   fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL));
505
506   /* Requesting a new pad should fail */
507   ASSERT_CRITICAL (gst_element_get_request_pad (ebin, "audio_0"));
508
509   sinkcaps = gst_caps_new_simple ("audio/x-raw-int", NULL);
510   g_signal_emit_by_name (ebin, "request-pad", sinkcaps, &sinkpad);
511   gst_caps_unref (sinkcaps);
512   fail_if (sinkpad != NULL);
513
514   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
515       GST_STATE_CHANGE_ASYNC);
516
517   while (!done) {
518     GstMessage *msg;
519
520     /* poll the bus until we get EOS without any errors */
521     msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
522     if (msg) {
523       switch (GST_MESSAGE_TYPE (msg)) {
524         case GST_MESSAGE_ERROR:
525           fail ("GST_MESSAGE_ERROR");
526           break;
527         case GST_MESSAGE_EOS:
528           done = TRUE;
529           break;
530         default:
531           break;
532       }
533       gst_message_unref (msg);
534     }
535   }
536
537   /* Set back to NULL */
538   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
539       GST_STATE_CHANGE_SUCCESS);
540
541   gst_object_unref (bus);
542
543   gst_object_unref (pipeline);
544 }
545
546 GST_END_TEST;
547
548 GST_START_TEST (test_encodebin_render_audio_dynamic)
549 {
550   GstElement *ebin, *pipeline, *audiotestsrc, *fakesink;
551   GstEncodingProfile *prof;
552   GstBus *bus;
553   GstPad *sinkpad, *srcpad;
554   gboolean done = FALSE;
555
556   /* Create an encodebin and render 5s of vorbis/ogg */
557
558   pipeline = gst_pipeline_new ("encodebin-pipeline");
559   bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
560   audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
561   g_object_set (audiotestsrc, "num-buffers", 10, NULL);
562   fakesink = gst_element_factory_make ("fakesink", NULL);
563
564   ebin = gst_element_factory_make ("encodebin", NULL);
565
566   prof = create_ogg_vorbis_profile (0, NULL);
567   g_object_set (ebin, "profile", prof, NULL);
568   gst_encoding_profile_unref (prof);
569
570   gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL);
571
572   srcpad = gst_element_get_static_pad (audiotestsrc, "src");
573   fail_unless (srcpad != NULL);
574
575   sinkpad = gst_element_get_request_pad (ebin, "audio_0");
576   fail_unless (sinkpad != NULL);
577
578   fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK);
579
580   gst_object_unref (srcpad);
581
582   fail_unless (gst_element_link (ebin, fakesink));
583
584   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
585       GST_STATE_CHANGE_ASYNC);
586
587   while (!done) {
588     GstMessage *msg;
589
590     /* poll the bus until we get EOS without any errors */
591     msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
592     if (msg) {
593       switch (GST_MESSAGE_TYPE (msg)) {
594         case GST_MESSAGE_ERROR:
595           fail ("GST_MESSAGE_ERROR");
596           break;
597         case GST_MESSAGE_EOS:
598           done = TRUE;
599           break;
600         default:
601           break;
602       }
603       gst_message_unref (msg);
604     }
605   }
606
607   /* Set back to NULL */
608   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
609       GST_STATE_CHANGE_SUCCESS);
610
611   gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad);
612   gst_object_unref (sinkpad);
613
614   gst_object_unref (bus);
615
616   gst_object_unref (pipeline);
617 }
618
619 GST_END_TEST;
620
621 GST_START_TEST (test_encodebin_render_audio_video_static)
622 {
623   GstElement *ebin, *pipeline, *audiotestsrc, *videotestsrc, *fakesink;
624   GstEncodingProfile *prof;
625   GstBus *bus;
626   gboolean done = FALSE;
627
628   /* Create an encodebin and render 5s of vorbis/ogg */
629
630   pipeline = gst_pipeline_new ("encodebin-pipeline");
631   bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
632   audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
633   g_object_set (audiotestsrc, "num-buffers", 10, NULL);
634   videotestsrc = gst_element_factory_make ("videotestsrc", NULL);
635   g_object_set (videotestsrc, "num-buffers", 5, NULL);
636   fakesink = gst_element_factory_make ("fakesink", NULL);
637
638   ebin = gst_element_factory_make ("encodebin", NULL);
639
640   prof = create_ogg_theora_vorbis_profile (1, 1);
641   g_object_set (ebin, "profile", prof, NULL);
642   gst_encoding_profile_unref (prof);
643
644   gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, videotestsrc, ebin,
645       fakesink, NULL);
646
647   fail_unless (gst_element_link (videotestsrc, ebin));
648   fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL));
649
650   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
651       GST_STATE_CHANGE_ASYNC);
652
653   while (!done) {
654     GstMessage *msg;
655
656     /* poll the bus until we get EOS without any errors */
657     msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
658     if (msg) {
659       switch (GST_MESSAGE_TYPE (msg)) {
660         case GST_MESSAGE_ERROR:
661           fail ("GST_MESSAGE_ERROR");
662           break;
663         case GST_MESSAGE_EOS:
664           done = TRUE;
665           break;
666         default:
667           break;
668       }
669       gst_message_unref (msg);
670     }
671   }
672
673   /* Set back to NULL */
674   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
675       GST_STATE_CHANGE_SUCCESS);
676
677   gst_object_unref (bus);
678
679   gst_object_unref (pipeline);
680 }
681
682 GST_END_TEST;
683
684 GST_START_TEST (test_encodebin_render_audio_video_dynamic)
685 {
686   GstElement *ebin, *pipeline, *audiotestsrc, *videotestsrc, *fakesink;
687   GstEncodingProfile *prof;
688   GstBus *bus;
689   gboolean done = FALSE;
690   GstPad *sinkpad1, *sinkpad2, *srcpad;
691
692   /* Create an encodebin and render 5s of vorbis/ogg */
693
694   pipeline = gst_pipeline_new ("encodebin-pipeline");
695   bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
696   audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL);
697   g_object_set (audiotestsrc, "num-buffers", 10, NULL);
698   videotestsrc = gst_element_factory_make ("videotestsrc", NULL);
699   g_object_set (videotestsrc, "num-buffers", 5, NULL);
700   fakesink = gst_element_factory_make ("fakesink", NULL);
701
702   ebin = gst_element_factory_make ("encodebin", NULL);
703
704   prof = create_ogg_theora_vorbis_profile (0, 0);
705   g_object_set (ebin, "profile", prof, NULL);
706   gst_encoding_profile_unref (prof);
707
708   gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, videotestsrc, ebin,
709       fakesink, NULL);
710
711   fail_unless (gst_element_link (ebin, fakesink));
712
713   srcpad = gst_element_get_static_pad (audiotestsrc, "src");
714   sinkpad1 = gst_element_get_request_pad (ebin, "audio_0");
715   fail_unless (srcpad != NULL);
716   fail_unless (sinkpad1 != NULL);
717   fail_unless_equals_int (gst_pad_link (srcpad, sinkpad1), GST_PAD_LINK_OK);
718   gst_object_unref (srcpad);
719
720   srcpad = gst_element_get_static_pad (videotestsrc, "src");
721   sinkpad2 = gst_element_get_request_pad (ebin, "video_1");
722   fail_unless_equals_int (gst_pad_link (srcpad, sinkpad2), GST_PAD_LINK_OK);
723   gst_object_unref (srcpad);
724
725   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
726       GST_STATE_CHANGE_ASYNC);
727
728   while (!done) {
729     GstMessage *msg;
730
731     /* poll the bus until we get EOS without any errors */
732     msg = gst_bus_timed_pop (bus, GST_SECOND / 10);
733     if (msg) {
734       switch (GST_MESSAGE_TYPE (msg)) {
735         case GST_MESSAGE_ERROR:
736           fail ("GST_MESSAGE_ERROR");
737           break;
738         case GST_MESSAGE_EOS:
739           done = TRUE;
740           break;
741         default:
742           break;
743       }
744       gst_message_unref (msg);
745     }
746   }
747
748   /* Set back to NULL */
749   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
750       GST_STATE_CHANGE_SUCCESS);
751
752   gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad1);
753   gst_object_unref (sinkpad1);
754   gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad2);
755   gst_object_unref (sinkpad2);
756
757   gst_object_unref (bus);
758
759   gst_object_unref (pipeline);
760 }
761
762 GST_END_TEST;
763
764 GST_START_TEST (test_encodebin_impossible_element_combination)
765 {
766   GstElement *ebin;
767   GstEncodingProfile *prof;
768   GstCaps *ogg, *x264;
769
770   ebin = gst_element_factory_make ("x264enc", NULL);
771   if (ebin == NULL) {
772     GST_DEBUG ("No available h264 encoder, skipping test");
773     return;
774   }
775   gst_object_unref (ebin);
776
777   /* Make sure that impossible combinations of encoders and muxer
778    * properly fail. In this case we try putting h264 in ogg.
779    *
780    * To properly test we abort early, we use a presence of zero for the
781    * h264 stream profile. */
782
783   ebin = gst_element_factory_make ("encodebin", NULL);
784
785   ogg = gst_caps_new_simple ("application/ogg", NULL);
786   prof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *)
787       "myprofile", NULL, ogg, NULL);
788   gst_caps_unref (ogg);
789
790   x264 = gst_caps_new_simple ("video/x-h264", NULL);
791   fail_unless (gst_encoding_container_profile_add_profile
792       (GST_ENCODING_CONTAINER_PROFILE (prof),
793           (GstEncodingProfile *) gst_encoding_video_profile_new (x264, NULL,
794               NULL, 0)));
795   gst_caps_unref (x264);
796
797   g_object_set (ebin, "profile", prof, NULL);
798   gst_encoding_profile_unref (prof);
799
800   /* It will go to READY... */
801   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY),
802       GST_STATE_CHANGE_SUCCESS);
803   /* ... but to not PAUSED */
804   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
805       GST_STATE_CHANGE_FAILURE);
806
807   gst_element_set_state (ebin, GST_STATE_NULL);
808
809   gst_object_unref (ebin);
810 };
811
812 GST_END_TEST;
813
814 static void
815 _test_encodebin_reuse (GstEncodingProfile * prof1, GstEncodingProfile * prof2)
816 {
817   GstElement *ebin;
818
819   ebin = gst_element_factory_make ("encodebin", NULL);
820
821   /* Set a profile on encodebin... */
822   if (prof1)
823     g_object_set (ebin, "profile", prof1, NULL);
824
825   /* Make sure we can go to PAUSED */
826   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
827       GST_STATE_CHANGE_SUCCESS);
828
829   /* Set back to NULL */
830   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
831       GST_STATE_CHANGE_SUCCESS);
832
833   if (prof2)
834     g_object_set (ebin, "profile", prof2, NULL);
835
836   /* Make sure we can go to PLAYING */
837   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED),
838       GST_STATE_CHANGE_SUCCESS);
839
840   /* Set back to NULL */
841   fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL),
842       GST_STATE_CHANGE_SUCCESS);
843
844   gst_object_unref (ebin);
845 }
846
847 GST_START_TEST (test_encodebin_reuse)
848 {
849   GstEncodingProfile *prof1;
850   GstEncodingProfile *prof2;
851   GstEncodingProfile *prof3;
852   GstCaps *caps;
853
854   caps = gst_caps_new_simple ("application/ogg", NULL);
855   prof1 = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *)
856       "myprofile", NULL, caps, NULL);
857   gst_caps_unref (caps);
858
859   prof2 = create_ogg_theora_vorbis_profile (1, 1);
860   prof3 = create_vorbis_only_profile ();
861
862   _test_encodebin_reuse (prof1, NULL);
863   _test_encodebin_reuse (prof1, prof1);
864
865   _test_encodebin_reuse (prof1, prof2);
866
867   _test_encodebin_reuse (prof2, prof3);
868
869   gst_encoding_profile_unref (prof1);
870   gst_encoding_profile_unref (prof2);
871   gst_encoding_profile_unref (prof3);
872 };
873
874 GST_END_TEST;
875
876
877 static Suite *
878 encodebin_suite (void)
879 {
880   Suite *s = suite_create ("encodebin element");
881   TCase *tc_chain = tcase_create ("general");
882
883   suite_add_tcase (s, tc_chain);
884   tcase_add_test (tc_chain, test_encodebin_states);
885   tcase_add_test (tc_chain, test_encodebin_sink_pads_static);
886   tcase_add_test (tc_chain, test_encodebin_sink_pads_nopreset_static);
887   tcase_add_test (tc_chain, test_encodebin_sink_pads_dynamic);
888   tcase_add_test (tc_chain, test_encodebin_sink_pads_multiple_static);
889   tcase_add_test (tc_chain, test_encodebin_sink_pads_multiple_dynamic);
890   tcase_add_test (tc_chain, test_encodebin_sink_pads_dynamic_encoder);
891   tcase_add_test (tc_chain, test_encodebin_render_audio_static);
892   tcase_add_test (tc_chain, test_encodebin_render_audio_only_static);
893   tcase_add_test (tc_chain, test_encodebin_render_audio_dynamic);
894   tcase_add_test (tc_chain, test_encodebin_render_audio_video_static);
895   tcase_add_test (tc_chain, test_encodebin_render_audio_video_dynamic);
896   tcase_add_test (tc_chain, test_encodebin_impossible_element_combination);
897   tcase_add_test (tc_chain, test_encodebin_reuse);
898
899   return s;
900 }
901
902 GST_CHECK_MAIN (encodebin);