1 /* GStreamer
2  *
3  * Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
4  * Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
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 /* TODO:
23  * - start with pause, go to playing
24  * - play, pause, play
25  * - set uri in play/pause
26  * - play/pause after eos
27  * - seek in play/pause/stopped, after eos, back to 0, after duration
28  * - http buffering
29  */
30 
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 
35 #ifdef HAVE_VALGRIND
36 # include <valgrind/valgrind.h>
37 #endif
38 
39 #include <gst/check/gstcheck.h>
40 
41 #define fail_unless_equals_int(a, b)                                    \
42 G_STMT_START {                                                          \
43   int first = a;                                                        \
44   int second = b;                                                       \
45   fail_unless(first == second,                                          \
46     "'" #a "' (%d) is not equal to '" #b"' (%d)", first, second);       \
47 } G_STMT_END;
48 
49 #define fail_unless_equals_uint64(a, b)                                 \
50 G_STMT_START {                                                          \
51   guint64 first = a;                                                    \
52   guint64 second = b;                                                   \
53   fail_unless(first == second,                                          \
54     "'" #a "' (%" G_GUINT64_FORMAT ") is not equal to '" #b"' (%"       \
55     G_GUINT64_FORMAT ")", first, second);                               \
56 } G_STMT_END;
57 
58 #define fail_unless_equals_double(a, b)                                 \
59 G_STMT_START {                                                          \
60   double first = a;                                                     \
61   double second = b;                                                    \
62   fail_unless(first == second,                                          \
63     "'" #a "' (%lf) is not equal to '" #b"' (%lf)", first, second);     \
64 } G_STMT_END;
65 
66 #include <gst/player/player.h>
67 
START_TEST(test_create_and_free)68 START_TEST (test_create_and_free)
69 {
70   GstPlayer *player;
71 
72   player = gst_player_new (NULL, NULL);
73   fail_unless (player != NULL);
74   g_object_unref (player);
75 }
76 
77 END_TEST;
78 
START_TEST(test_set_and_get_uri)79 START_TEST (test_set_and_get_uri)
80 {
81   GstPlayer *player;
82   gchar *uri;
83 
84   player = gst_player_new (NULL, NULL);
85 
86   fail_unless (player != NULL);
87 
88   gst_player_set_uri (player, "file:///path/to/a/file");
89   uri = gst_player_get_uri (player);
90 
91   fail_unless (g_strcmp0 (uri, "file:///path/to/a/file") == 0);
92 
93   g_free (uri);
94   g_object_unref (player);
95 }
96 
97 END_TEST;
98 
START_TEST(test_set_and_get_position_update_interval)99 START_TEST (test_set_and_get_position_update_interval)
100 {
101   GstPlayer *player;
102   guint interval = 0;
103   GstStructure *config;
104 
105   player = gst_player_new (NULL, NULL);
106 
107   fail_unless (player != NULL);
108 
109   config = gst_player_get_config (player);
110   gst_player_config_set_position_update_interval (config, 500);
111   interval = gst_player_config_get_position_update_interval (config);
112   fail_unless (interval == 500);
113   gst_player_set_config (player, config);
114 
115   g_object_unref (player);
116 }
117 
118 END_TEST;
119 
120 typedef enum
121 {
122   STATE_CHANGE_BUFFERING,
123   STATE_CHANGE_DURATION_CHANGED,
124   STATE_CHANGE_END_OF_STREAM,
125   STATE_CHANGE_ERROR,
126   STATE_CHANGE_WARNING,
127   STATE_CHANGE_POSITION_UPDATED,
128   STATE_CHANGE_STATE_CHANGED,
129   STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED,
130   STATE_CHANGE_MEDIA_INFO_UPDATED,
131   STATE_CHANGE_SEEK_DONE,
132   STATE_CHANGE_URI_LOADED,
133 } TestPlayerStateChange;
134 
135 static const gchar *
test_player_state_change_get_name(TestPlayerStateChange change)136 test_player_state_change_get_name (TestPlayerStateChange change)
137 {
138   switch (change) {
139     case STATE_CHANGE_BUFFERING:
140       return "buffering";
141     case STATE_CHANGE_DURATION_CHANGED:
142       return "duration-changed";
143     case STATE_CHANGE_END_OF_STREAM:
144       return "end-of-stream";
145     case STATE_CHANGE_WARNING:
146       return "warning";
147     case STATE_CHANGE_ERROR:
148       return "error";
149     case STATE_CHANGE_POSITION_UPDATED:
150       return "position-updated";
151     case STATE_CHANGE_STATE_CHANGED:
152       return "state-changed";
153     case STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED:
154       return "video-dimensions-changed";
155     case STATE_CHANGE_MEDIA_INFO_UPDATED:
156       return "media-info-updated";
157     case STATE_CHANGE_SEEK_DONE:
158       return "seek-done";
159     case STATE_CHANGE_URI_LOADED:
160       return "uri-loaded";
161     default:
162       g_assert_not_reached ();
163       break;
164   }
165 }
166 
167 typedef struct _TestPlayerState TestPlayerState;
168 struct _TestPlayerState
169 {
170   GMainLoop *loop;
171 
172   gint buffering_percent;
173   guint64 position, duration, seek_done_position;
174   gboolean end_of_stream, error, warning, seek_done;
175   GstPlayerState state;
176   gint width, height;
177   GstPlayerMediaInfo *media_info;
178   gchar *uri_loaded;
179   gboolean stopping;
180 
181   void (*test_callback) (GstPlayer * player, TestPlayerStateChange change,
182       TestPlayerState * old_state, TestPlayerState * new_state);
183   gpointer test_data;
184 };
185 
186 static void
test_player_state_change_debug(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)187 test_player_state_change_debug (GstPlayer * player,
188     TestPlayerStateChange change, TestPlayerState * old_state,
189     TestPlayerState * new_state)
190 {
191   GST_DEBUG_OBJECT (player, "Changed %s:\n"
192       "\tbuffering %d%% -> %d%%\n"
193       "\tposition %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "\n"
194       "\tduration %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "\n"
195       "\tseek position %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "\n"
196       "\tend-of-stream %d -> %d\n"
197       "\terror %d -> %d\n"
198       "\tseek_done %d -> %d\n"
199       "\tstate %s -> %s\n"
200       "\twidth/height %d/%d -> %d/%d\n"
201       "\tmedia_info %p -> %p\n"
202       "\turi_loaded %s -> %s",
203       test_player_state_change_get_name (change),
204       old_state->buffering_percent, new_state->buffering_percent,
205       GST_TIME_ARGS (old_state->position), GST_TIME_ARGS (new_state->position),
206       GST_TIME_ARGS (old_state->duration), GST_TIME_ARGS (new_state->duration),
207       GST_TIME_ARGS (old_state->seek_done_position),
208       GST_TIME_ARGS (new_state->seek_done_position), old_state->end_of_stream,
209       new_state->end_of_stream, old_state->error, new_state->error,
210       old_state->seek_done, new_state->seek_done,
211       gst_player_state_get_name (old_state->state),
212       gst_player_state_get_name (new_state->state), old_state->width,
213       old_state->height, new_state->width, new_state->height,
214       old_state->media_info, new_state->media_info,
215       old_state->uri_loaded, new_state->uri_loaded);
216 }
217 
218 static void
test_player_state_reset(TestPlayerState * state)219 test_player_state_reset (TestPlayerState * state)
220 {
221   state->buffering_percent = 100;
222   state->position = state->duration = state->seek_done_position = -1;
223   state->end_of_stream = state->error = state->seek_done = FALSE;
224   state->state = GST_PLAYER_STATE_STOPPED;
225   state->width = state->height = 0;
226   state->media_info = NULL;
227   state->stopping = FALSE;
228   g_clear_pointer (&state->uri_loaded, g_free);
229 }
230 
231 static void
buffering_cb(GstPlayer * player,gint percent,TestPlayerState * state)232 buffering_cb (GstPlayer * player, gint percent, TestPlayerState * state)
233 {
234   TestPlayerState old_state = *state;
235 
236   g_assert (!state->stopping);
237 
238   state->buffering_percent = percent;
239   test_player_state_change_debug (player, STATE_CHANGE_BUFFERING, &old_state,
240       state);
241   state->test_callback (player, STATE_CHANGE_BUFFERING, &old_state, state);
242 }
243 
244 static void
duration_changed_cb(GstPlayer * player,guint64 duration,TestPlayerState * state)245 duration_changed_cb (GstPlayer * player, guint64 duration,
246     TestPlayerState * state)
247 {
248   TestPlayerState old_state = *state;
249 
250   g_assert (!state->stopping);
251 
252   state->duration = duration;
253   test_player_state_change_debug (player, STATE_CHANGE_DURATION_CHANGED,
254       &old_state, state);
255   state->test_callback (player, STATE_CHANGE_DURATION_CHANGED, &old_state,
256       state);
257 }
258 
259 static void
end_of_stream_cb(GstPlayer * player,TestPlayerState * state)260 end_of_stream_cb (GstPlayer * player, TestPlayerState * state)
261 {
262   TestPlayerState old_state = *state;
263 
264   g_assert (!state->stopping);
265 
266   state->end_of_stream = TRUE;
267   test_player_state_change_debug (player, STATE_CHANGE_END_OF_STREAM,
268       &old_state, state);
269   state->test_callback (player, STATE_CHANGE_END_OF_STREAM, &old_state, state);
270 }
271 
272 static void
error_cb(GstPlayer * player,GError * error,TestPlayerState * state)273 error_cb (GstPlayer * player, GError * error, TestPlayerState * state)
274 {
275   TestPlayerState old_state = *state;
276 
277   g_assert (!state->stopping);
278 
279   state->error = TRUE;
280   test_player_state_change_debug (player, STATE_CHANGE_ERROR, &old_state,
281       state);
282   state->test_callback (player, STATE_CHANGE_ERROR, &old_state, state);
283 }
284 
285 static void
warning_cb(GstPlayer * player,GError * error,TestPlayerState * state)286 warning_cb (GstPlayer * player, GError * error, TestPlayerState * state)
287 {
288   TestPlayerState old_state = *state;
289 
290   g_assert (!state->stopping);
291 
292   state->warning = TRUE;
293   test_player_state_change_debug (player, STATE_CHANGE_WARNING, &old_state,
294       state);
295   state->test_callback (player, STATE_CHANGE_WARNING, &old_state, state);
296 }
297 
298 static void
position_updated_cb(GstPlayer * player,guint64 position,TestPlayerState * state)299 position_updated_cb (GstPlayer * player, guint64 position,
300     TestPlayerState * state)
301 {
302   TestPlayerState old_state = *state;
303 
304   g_assert (!state->stopping);
305 
306   state->position = position;
307   test_player_state_change_debug (player, STATE_CHANGE_POSITION_UPDATED,
308       &old_state, state);
309   state->test_callback (player, STATE_CHANGE_POSITION_UPDATED, &old_state,
310       state);
311 }
312 
313 static void
media_info_updated_cb(GstPlayer * player,GstPlayerMediaInfo * media_info,TestPlayerState * state)314 media_info_updated_cb (GstPlayer * player, GstPlayerMediaInfo * media_info,
315     TestPlayerState * state)
316 {
317   TestPlayerState old_state = *state;
318 
319   g_assert (!state->stopping);
320 
321   state->media_info = media_info;
322 
323   test_player_state_change_debug (player, STATE_CHANGE_MEDIA_INFO_UPDATED,
324       &old_state, state);
325   state->test_callback (player, STATE_CHANGE_MEDIA_INFO_UPDATED, &old_state,
326       state);
327 }
328 
329 static void
state_changed_cb(GstPlayer * player,GstPlayerState player_state,TestPlayerState * state)330 state_changed_cb (GstPlayer * player, GstPlayerState player_state,
331     TestPlayerState * state)
332 {
333   TestPlayerState old_state = *state;
334 
335   g_assert (!state->stopping || player_state == GST_PLAYER_STATE_STOPPED);
336 
337   state->state = player_state;
338 
339   if (player_state == GST_PLAYER_STATE_STOPPED)
340     test_player_state_reset (state);
341 
342   test_player_state_change_debug (player, STATE_CHANGE_STATE_CHANGED,
343       &old_state, state);
344   state->test_callback (player, STATE_CHANGE_STATE_CHANGED, &old_state, state);
345 }
346 
347 static void
video_dimensions_changed_cb(GstPlayer * player,gint width,gint height,TestPlayerState * state)348 video_dimensions_changed_cb (GstPlayer * player, gint width, gint height,
349     TestPlayerState * state)
350 {
351   TestPlayerState old_state = *state;
352 
353   g_assert (!state->stopping);
354 
355   state->width = width;
356   state->height = height;
357   test_player_state_change_debug (player, STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED,
358       &old_state, state);
359   state->test_callback (player, STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED,
360       &old_state, state);
361 }
362 
363 static void
seek_done_cb(GstPlayer * player,guint64 position,TestPlayerState * state)364 seek_done_cb (GstPlayer * player, guint64 position, TestPlayerState * state)
365 {
366   TestPlayerState old_state = *state;
367 
368   g_assert (!state->stopping);
369 
370   state->seek_done = TRUE;
371   state->seek_done_position = position;
372   test_player_state_change_debug (player, STATE_CHANGE_SEEK_DONE,
373       &old_state, state);
374   state->test_callback (player, STATE_CHANGE_SEEK_DONE, &old_state, state);
375 }
376 
377 static void
uri_loaded_cb(GstPlayer * player,const gchar * uri,TestPlayerState * state)378 uri_loaded_cb (GstPlayer * player, const gchar * uri, TestPlayerState * state)
379 {
380   TestPlayerState old_state = *state;
381 
382   state->uri_loaded = g_strdup (uri);
383   state->test_callback (player, STATE_CHANGE_URI_LOADED, &old_state, state);
384 }
385 
386 static GstPlayer *
test_player_new(TestPlayerState * state)387 test_player_new (TestPlayerState * state)
388 {
389   GstPlayer *player;
390   GstElement *playbin, *fakesink;
391 
392   player =
393       gst_player_new (NULL,
394       gst_player_g_main_context_signal_dispatcher_new (NULL));
395   fail_unless (player != NULL);
396 
397   test_player_state_reset (state);
398 
399   playbin = gst_player_get_pipeline (player);
400   fakesink = gst_element_factory_make ("fakesink", "audio-sink");
401   g_object_set (fakesink, "sync", TRUE, NULL);
402   g_object_set (playbin, "audio-sink", fakesink, NULL);
403   fakesink = gst_element_factory_make ("fakesink", "video-sink");
404   g_object_set (fakesink, "sync", TRUE, NULL);
405   g_object_set (playbin, "video-sink", fakesink, NULL);
406   gst_object_unref (playbin);
407 
408   g_signal_connect (player, "buffering", G_CALLBACK (buffering_cb), state);
409   g_signal_connect (player, "duration-changed",
410       G_CALLBACK (duration_changed_cb), state);
411   g_signal_connect (player, "end-of-stream", G_CALLBACK (end_of_stream_cb),
412       state);
413   g_signal_connect (player, "error", G_CALLBACK (error_cb), state);
414   g_signal_connect (player, "warning", G_CALLBACK (warning_cb), state);
415   g_signal_connect (player, "position-updated",
416       G_CALLBACK (position_updated_cb), state);
417   g_signal_connect (player, "state-changed", G_CALLBACK (state_changed_cb),
418       state);
419   g_signal_connect (player, "media-info-updated",
420       G_CALLBACK (media_info_updated_cb), state);
421   g_signal_connect (player, "video-dimensions-changed",
422       G_CALLBACK (video_dimensions_changed_cb), state);
423   g_signal_connect (player, "seek-done", G_CALLBACK (seek_done_cb), state);
424   g_signal_connect (player, "uri-loaded", G_CALLBACK (uri_loaded_cb), state);
425 
426   return player;
427 }
428 
429 static void
test_player_stopped_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)430 test_player_stopped_cb (GstPlayer * player, TestPlayerStateChange change,
431     TestPlayerState * old_state, TestPlayerState * new_state)
432 {
433   if (new_state->state == GST_PLAYER_STATE_STOPPED) {
434     g_main_loop_quit (new_state->loop);
435   }
436 }
437 
438 static void
stop_player(GstPlayer * player,TestPlayerState * state)439 stop_player (GstPlayer * player, TestPlayerState * state)
440 {
441   if (state->state != GST_PLAYER_STATE_STOPPED) {
442     /* Make sure all pending operations are finished so the player won't be
443      * appear as 'leaked' to leak detection tools. */
444     state->test_callback = test_player_stopped_cb;
445     gst_player_stop (player);
446     state->stopping = TRUE;
447     g_main_loop_run (state->loop);
448   }
449 }
450 
451 static void
test_play_audio_video_eos_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)452 test_play_audio_video_eos_cb (GstPlayer * player, TestPlayerStateChange change,
453     TestPlayerState * old_state, TestPlayerState * new_state)
454 {
455   gint step = GPOINTER_TO_INT (new_state->test_data);
456   gboolean video;
457 
458   video = ! !(step & 0x10);
459   step = (step & (~0x10));
460 
461   switch (step) {
462     case 0:
463       fail_unless_equals_int (change, STATE_CHANGE_URI_LOADED);
464       if (video)
465         fail_unless (g_str_has_suffix (new_state->uri_loaded,
466                 "audio-video-short.ogg"));
467       else
468         fail_unless (g_str_has_suffix (new_state->uri_loaded,
469                 "audio-short.ogg"));
470       new_state->test_data =
471           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
472       break;
473     case 1:
474       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
475       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
476       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
477       new_state->test_data =
478           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
479       break;
480     case 2:
481       fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
482       new_state->test_data =
483           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
484       break;
485     case 3:
486       fail_unless_equals_int (change, STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED);
487       if (video) {
488         fail_unless_equals_int (new_state->width, 320);
489         fail_unless_equals_int (new_state->height, 240);
490       } else {
491         fail_unless_equals_int (new_state->width, 0);
492         fail_unless_equals_int (new_state->height, 0);
493       }
494       new_state->test_data =
495           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
496       break;
497     case 4:
498       fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
499       new_state->test_data =
500           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
501       break;
502     case 5:
503       fail_unless_equals_int (change, STATE_CHANGE_DURATION_CHANGED);
504       fail_unless_equals_uint64 (new_state->duration,
505           G_GUINT64_CONSTANT (464399092));
506       new_state->test_data =
507           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
508       break;
509     case 6:
510       fail_unless_equals_int (change, STATE_CHANGE_POSITION_UPDATED);
511       fail_unless_equals_uint64 (new_state->position, G_GUINT64_CONSTANT (0));
512       new_state->test_data =
513           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
514       break;
515     case 7:
516       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
517       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
518       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_PLAYING);
519       new_state->test_data =
520           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
521       break;
522     case 8:
523       if (change == STATE_CHANGE_POSITION_UPDATED) {
524         fail_unless (old_state->position <= new_state->position);
525       } else {
526         fail_unless_equals_uint64 (old_state->position, old_state->duration);
527         fail_unless_equals_int (change, STATE_CHANGE_END_OF_STREAM);
528         new_state->test_data =
529             GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
530       }
531       break;
532     case 9:
533       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
534       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_PLAYING);
535       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_STOPPED);
536       new_state->test_data =
537           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
538       g_main_loop_quit (new_state->loop);
539       break;
540     default:
541       fail ();
542       break;
543   }
544 }
545 
START_TEST(test_play_audio_eos)546 START_TEST (test_play_audio_eos)
547 {
548   GstPlayer *player;
549   TestPlayerState state;
550   gchar *uri;
551 
552   memset (&state, 0, sizeof (state));
553   state.loop = g_main_loop_new (NULL, FALSE);
554   state.test_callback = test_play_audio_video_eos_cb;
555   state.test_data = GINT_TO_POINTER (0);
556 
557   player = test_player_new (&state);
558 
559   fail_unless (player != NULL);
560 
561   uri = gst_filename_to_uri (TEST_PATH "/audio-short.ogg", NULL);
562   fail_unless (uri != NULL);
563   gst_player_set_uri (player, uri);
564   g_free (uri);
565 
566   gst_player_play (player);
567   g_main_loop_run (state.loop);
568 
569   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 10);
570 
571   stop_player (player, &state);
572   g_object_unref (player);
573   g_main_loop_unref (state.loop);
574 }
575 
576 END_TEST;
577 
578 static void
test_audio_info(GstPlayerMediaInfo * media_info)579 test_audio_info (GstPlayerMediaInfo * media_info)
580 {
581   gint i = 0;
582   GList *list;
583 
584   for (list = gst_player_media_info_get_audio_streams (media_info);
585       list != NULL; list = list->next) {
586     GstPlayerStreamInfo *stream = (GstPlayerStreamInfo *) list->data;
587     GstPlayerAudioInfo *audio_info = (GstPlayerAudioInfo *) stream;
588 
589     fail_unless (gst_player_stream_info_get_tags (stream) != NULL);
590     fail_unless (gst_player_stream_info_get_caps (stream) != NULL);
591     fail_unless_equals_string (gst_player_stream_info_get_stream_type (stream),
592         "audio");
593 
594     if (i == 0) {
595       fail_unless_equals_string (gst_player_stream_info_get_codec (stream),
596           "MPEG-1 Layer 3 (MP3)");
597       fail_unless_equals_int (gst_player_audio_info_get_sample_rate
598           (audio_info), 48000);
599       fail_unless_equals_int (gst_player_audio_info_get_channels (audio_info),
600           2);
601       fail_unless_equals_int (gst_player_audio_info_get_max_bitrate
602           (audio_info), 192000);
603       fail_unless (gst_player_audio_info_get_language (audio_info) != NULL);
604     } else {
605       fail_unless_equals_string (gst_player_stream_info_get_codec (stream),
606           "MPEG-4 AAC");
607       fail_unless_equals_int (gst_player_audio_info_get_sample_rate
608           (audio_info), 48000);
609       fail_unless_equals_int (gst_player_audio_info_get_channels (audio_info),
610           6);
611       fail_unless (gst_player_audio_info_get_language (audio_info) != NULL);
612     }
613 
614     i++;
615   }
616 }
617 
618 static void
test_video_info(GstPlayerMediaInfo * media_info)619 test_video_info (GstPlayerMediaInfo * media_info)
620 {
621   GList *list;
622 
623   for (list = gst_player_media_info_get_video_streams (media_info);
624       list != NULL; list = list->next) {
625     gint fps_d, fps_n;
626     guint par_d, par_n;
627     GstPlayerStreamInfo *stream = (GstPlayerStreamInfo *) list->data;
628     GstPlayerVideoInfo *video_info = (GstPlayerVideoInfo *) stream;
629 
630     fail_unless (gst_player_stream_info_get_tags (stream) != NULL);
631     fail_unless (gst_player_stream_info_get_caps (stream) != NULL);
632     fail_unless_equals_int (gst_player_stream_info_get_index (stream), 0);
633     fail_unless (strstr (gst_player_stream_info_get_codec (stream),
634             "H.264") != NULL
635         || strstr (gst_player_stream_info_get_codec (stream), "H264") != NULL);
636     fail_unless_equals_int (gst_player_video_info_get_width (video_info), 320);
637     fail_unless_equals_int (gst_player_video_info_get_height (video_info), 240);
638     gst_player_video_info_get_framerate (video_info, &fps_n, &fps_d);
639     fail_unless_equals_int (fps_n, 24);
640     fail_unless_equals_int (fps_d, 1);
641     gst_player_video_info_get_pixel_aspect_ratio (video_info, &par_n, &par_d);
642     fail_unless_equals_int (par_n, 33);
643     fail_unless_equals_int (par_d, 20);
644   }
645 }
646 
647 static void
test_subtitle_info(GstPlayerMediaInfo * media_info)648 test_subtitle_info (GstPlayerMediaInfo * media_info)
649 {
650   GList *list;
651 
652   for (list = gst_player_media_info_get_subtitle_streams (media_info);
653       list != NULL; list = list->next) {
654     GstPlayerStreamInfo *stream = (GstPlayerStreamInfo *) list->data;
655     GstPlayerSubtitleInfo *sub = (GstPlayerSubtitleInfo *) stream;
656 
657     fail_unless_equals_string (gst_player_stream_info_get_stream_type (stream),
658         "subtitle");
659     fail_unless (gst_player_stream_info_get_tags (stream) != NULL);
660     fail_unless (gst_player_stream_info_get_caps (stream) != NULL);
661     fail_unless_equals_string (gst_player_stream_info_get_codec (stream),
662         "Timed Text");
663     fail_unless (gst_player_subtitle_info_get_language (sub) != NULL);
664   }
665 }
666 
667 static void
test_media_info_object(GstPlayer * player,GstPlayerMediaInfo * media_info)668 test_media_info_object (GstPlayer * player, GstPlayerMediaInfo * media_info)
669 {
670   GList *list;
671 
672   /* gloabl tag */
673   fail_unless (gst_player_media_info_is_seekable (media_info) == TRUE);
674   fail_unless (gst_player_media_info_get_tags (media_info) != NULL);
675   fail_unless_equals_string (gst_player_media_info_get_title (media_info),
676       "Sintel");
677   fail_unless_equals_string (gst_player_media_info_get_container_format
678       (media_info), "Matroska");
679   fail_unless (gst_player_media_info_get_image_sample (media_info) == NULL);
680   fail_unless (strstr (gst_player_media_info_get_uri (media_info),
681           "sintel.mkv") != NULL);
682 
683   /* number of streams */
684   list = gst_player_media_info_get_stream_list (media_info);
685   fail_unless (list != NULL);
686   fail_unless_equals_int (g_list_length (list), 10);
687 
688   list = gst_player_media_info_get_video_streams (media_info);
689   fail_unless (list != NULL);
690   fail_unless_equals_int (g_list_length (list), 1);
691 
692   list = gst_player_media_info_get_audio_streams (media_info);
693   fail_unless (list != NULL);
694   fail_unless_equals_int (g_list_length (list), 2);
695 
696   list = gst_player_media_info_get_subtitle_streams (media_info);
697   fail_unless (list != NULL);
698   fail_unless_equals_int (g_list_length (list), 7);
699 
700   /* test subtitle */
701   test_subtitle_info (media_info);
702 
703   /* test audio */
704   test_audio_info (media_info);
705 
706   /* test video */
707   test_video_info (media_info);
708 }
709 
710 static void
test_play_media_info_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)711 test_play_media_info_cb (GstPlayer * player, TestPlayerStateChange change,
712     TestPlayerState * old_state, TestPlayerState * new_state)
713 {
714   gint completed = GPOINTER_TO_INT (new_state->test_data);
715 
716   if (change == STATE_CHANGE_MEDIA_INFO_UPDATED) {
717     test_media_info_object (player, new_state->media_info);
718     new_state->test_data = GINT_TO_POINTER (completed + 1);
719     g_main_loop_quit (new_state->loop);
720   } else if (change == STATE_CHANGE_END_OF_STREAM ||
721       change == STATE_CHANGE_ERROR) {
722     g_main_loop_quit (new_state->loop);
723   }
724 }
725 
START_TEST(test_play_media_info)726 START_TEST (test_play_media_info)
727 {
728   GstPlayer *player;
729   TestPlayerState state;
730   gchar *uri;
731 
732   memset (&state, 0, sizeof (state));
733   state.loop = g_main_loop_new (NULL, FALSE);
734   state.test_callback = test_play_media_info_cb;
735   state.test_data = GINT_TO_POINTER (0);
736 
737   player = test_player_new (&state);
738 
739   fail_unless (player != NULL);
740 
741   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
742   fail_unless (uri != NULL);
743   gst_player_set_uri (player, uri);
744   g_free (uri);
745 
746   gst_player_play (player);
747   g_main_loop_run (state.loop);
748 
749   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 1);
750   stop_player (player, &state);
751   g_object_unref (player);
752   g_main_loop_unref (state.loop);
753 }
754 
755 END_TEST;
756 
757 static void
test_play_error_invalid_external_suburi_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)758 test_play_error_invalid_external_suburi_cb (GstPlayer * player,
759     TestPlayerStateChange change, TestPlayerState * old_state,
760     TestPlayerState * new_state)
761 {
762   gint steps = GPOINTER_TO_INT (new_state->test_data);
763 
764   if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
765     gchar *suburi;
766 
767     suburi = gst_filename_to_uri (TEST_PATH "/foo.srt", NULL);
768     fail_unless (suburi != NULL);
769 
770     new_state->test_data = GINT_TO_POINTER (steps + 1);
771     /* load invalid suburi */
772     gst_player_set_subtitle_uri (player, suburi);
773     g_free (suburi);
774 
775   } else if (steps && change == STATE_CHANGE_WARNING) {
776     new_state->test_data = GINT_TO_POINTER (steps + 1);
777     g_main_loop_quit (new_state->loop);
778 
779   } else if (change == STATE_CHANGE_END_OF_STREAM ||
780       change == STATE_CHANGE_ERROR)
781     g_main_loop_quit (new_state->loop);
782 }
783 
784 static void
test_play_stream_disable_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)785 test_play_stream_disable_cb (GstPlayer * player,
786     TestPlayerStateChange change, TestPlayerState * old_state,
787     TestPlayerState * new_state)
788 {
789   gint steps = GPOINTER_TO_INT (new_state->test_data) & 0xf;
790   gint mask = GPOINTER_TO_INT (new_state->test_data) & 0xf0;
791 
792   if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
793     new_state->test_data = GINT_TO_POINTER (0x10 + steps + 1);
794     gst_player_set_audio_track_enabled (player, FALSE);
795 
796   } else if (mask == 0x10 && change == STATE_CHANGE_POSITION_UPDATED) {
797     GstPlayerAudioInfo *audio;
798 
799     audio = gst_player_get_current_audio_track (player);
800     fail_unless (audio == NULL);
801     new_state->test_data = GINT_TO_POINTER (0x20 + steps + 1);
802     gst_player_set_subtitle_track_enabled (player, FALSE);
803 
804   } else if (mask == 0x20 && change == STATE_CHANGE_POSITION_UPDATED) {
805     GstPlayerSubtitleInfo *sub;
806 
807     sub = gst_player_get_current_subtitle_track (player);
808     fail_unless (sub == NULL);
809     new_state->test_data = GINT_TO_POINTER (0x30 + steps + 1);
810     g_main_loop_quit (new_state->loop);
811 
812   } else if (change == STATE_CHANGE_END_OF_STREAM ||
813       change == STATE_CHANGE_ERROR) {
814     g_main_loop_quit (new_state->loop);
815   }
816 }
817 
START_TEST(test_play_stream_disable)818 START_TEST (test_play_stream_disable)
819 {
820   GstPlayer *player;
821   TestPlayerState state;
822   gchar *uri;
823 
824   memset (&state, 0, sizeof (state));
825   state.loop = g_main_loop_new (NULL, FALSE);
826   state.test_callback = test_play_stream_disable_cb;
827   state.test_data = GINT_TO_POINTER (0);
828 
829   player = test_player_new (&state);
830 
831   fail_unless (player != NULL);
832 
833   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
834   fail_unless (uri != NULL);
835   gst_player_set_uri (player, uri);
836   g_free (uri);
837 
838   gst_player_play (player);
839   g_main_loop_run (state.loop);
840 
841   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 0x33);
842 
843   stop_player (player, &state);
844   g_object_unref (player);
845   g_main_loop_unref (state.loop);
846 }
847 
848 END_TEST;
849 
850 static void
test_play_stream_switch_audio_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)851 test_play_stream_switch_audio_cb (GstPlayer * player,
852     TestPlayerStateChange change, TestPlayerState * old_state,
853     TestPlayerState * new_state)
854 {
855   gint steps = GPOINTER_TO_INT (new_state->test_data);
856 
857   if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
858     gint ret;
859 
860     new_state->test_data = GINT_TO_POINTER (steps + 1);
861     ret = gst_player_set_audio_track (player, 1);
862     fail_unless_equals_int (ret, 1);
863 
864   } else if (steps && change == STATE_CHANGE_POSITION_UPDATED) {
865     gint index;
866     GstPlayerAudioInfo *audio;
867 
868     audio = gst_player_get_current_audio_track (player);
869     fail_unless (audio != NULL);
870     index = gst_player_stream_info_get_index ((GstPlayerStreamInfo *) audio);
871     fail_unless_equals_int (index, 1);
872     g_object_unref (audio);
873 
874     new_state->test_data = GINT_TO_POINTER (steps + 1);
875     g_main_loop_quit (new_state->loop);
876 
877   } else if (change == STATE_CHANGE_END_OF_STREAM ||
878       change == STATE_CHANGE_ERROR) {
879     g_main_loop_quit (new_state->loop);
880   }
881 }
882 
START_TEST(test_play_stream_switch_audio)883 START_TEST (test_play_stream_switch_audio)
884 {
885   GstPlayer *player;
886   TestPlayerState state;
887   gchar *uri;
888 
889   memset (&state, 0, sizeof (state));
890   state.loop = g_main_loop_new (NULL, FALSE);
891   state.test_callback = test_play_stream_switch_audio_cb;
892   state.test_data = GINT_TO_POINTER (0);
893 
894   player = test_player_new (&state);
895 
896   fail_unless (player != NULL);
897 
898   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
899   fail_unless (uri != NULL);
900   gst_player_set_uri (player, uri);
901   g_free (uri);
902 
903   gst_player_play (player);
904   g_main_loop_run (state.loop);
905 
906   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
907 
908   stop_player (player, &state);
909   g_object_unref (player);
910   g_main_loop_unref (state.loop);
911 }
912 
913 END_TEST;
914 
915 static void
test_play_stream_switch_subtitle_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)916 test_play_stream_switch_subtitle_cb (GstPlayer * player,
917     TestPlayerStateChange change, TestPlayerState * old_state,
918     TestPlayerState * new_state)
919 {
920   gint steps = GPOINTER_TO_INT (new_state->test_data);
921 
922   if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
923     gint ret;
924 
925     new_state->test_data = GINT_TO_POINTER (steps + 1);
926     ret = gst_player_set_subtitle_track (player, 5);
927     fail_unless_equals_int (ret, 1);
928 
929   } else if (steps && change == STATE_CHANGE_POSITION_UPDATED) {
930     gint index;
931     GstPlayerSubtitleInfo *sub;
932 
933     sub = gst_player_get_current_subtitle_track (player);
934     fail_unless (sub != NULL);
935     index = gst_player_stream_info_get_index ((GstPlayerStreamInfo *) sub);
936     fail_unless_equals_int (index, 5);
937     g_object_unref (sub);
938 
939     new_state->test_data = GINT_TO_POINTER (steps + 1);
940     g_main_loop_quit (new_state->loop);
941 
942   } else if (change == STATE_CHANGE_END_OF_STREAM ||
943       change == STATE_CHANGE_ERROR) {
944     g_main_loop_quit (new_state->loop);
945   }
946 }
947 
START_TEST(test_play_stream_switch_subtitle)948 START_TEST (test_play_stream_switch_subtitle)
949 {
950   GstPlayer *player;
951   TestPlayerState state;
952   gchar *uri;
953 
954   memset (&state, 0, sizeof (state));
955   state.loop = g_main_loop_new (NULL, FALSE);
956   state.test_callback = test_play_stream_switch_subtitle_cb;
957   state.test_data = GINT_TO_POINTER (0);
958 
959   player = test_player_new (&state);
960 
961   fail_unless (player != NULL);
962 
963   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
964   fail_unless (uri != NULL);
965   gst_player_set_uri (player, uri);
966   g_free (uri);
967 
968   gst_player_play (player);
969   g_main_loop_run (state.loop);
970 
971   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
972 
973   stop_player (player, &state);
974   g_object_unref (player);
975   g_main_loop_unref (state.loop);
976 }
977 
978 END_TEST;
979 
START_TEST(test_play_error_invalid_external_suburi)980 START_TEST (test_play_error_invalid_external_suburi)
981 {
982   GstPlayer *player;
983   TestPlayerState state;
984   gchar *uri;
985 
986   memset (&state, 0, sizeof (state));
987   state.loop = g_main_loop_new (NULL, FALSE);
988   state.test_callback = test_play_error_invalid_external_suburi_cb;
989   state.test_data = GINT_TO_POINTER (0);
990 
991   player = test_player_new (&state);
992 
993   fail_unless (player != NULL);
994 
995   uri = gst_filename_to_uri (TEST_PATH "/audio-video.ogg", NULL);
996   fail_unless (uri != NULL);
997   gst_player_set_uri (player, uri);
998   g_free (uri);
999 
1000   gst_player_play (player);
1001   g_main_loop_run (state.loop);
1002 
1003   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
1004 
1005   stop_player (player, &state);
1006   g_object_unref (player);
1007   g_main_loop_unref (state.loop);
1008 }
1009 
1010 END_TEST;
1011 
1012 static gboolean
has_subtitle_stream(TestPlayerState * new_state)1013 has_subtitle_stream (TestPlayerState * new_state)
1014 {
1015   if (gst_player_media_info_get_subtitle_streams (new_state->media_info))
1016     return TRUE;
1017 
1018   return FALSE;
1019 }
1020 
1021 static void
test_play_external_suburi_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1022 test_play_external_suburi_cb (GstPlayer * player,
1023     TestPlayerStateChange change, TestPlayerState * old_state,
1024     TestPlayerState * new_state)
1025 {
1026   gint steps = GPOINTER_TO_INT (new_state->test_data);
1027 
1028   if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
1029     gchar *suburi;
1030 
1031     suburi = gst_filename_to_uri (TEST_PATH "/test_sub.srt", NULL);
1032     fail_unless (suburi != NULL);
1033 
1034     gst_player_set_subtitle_uri (player, suburi);
1035     g_free (suburi);
1036     new_state->test_data = GINT_TO_POINTER (steps + 1);
1037 
1038   } else if (change == STATE_CHANGE_MEDIA_INFO_UPDATED &&
1039       has_subtitle_stream (new_state)) {
1040     gchar *current_suburi, *suburi;
1041 
1042     current_suburi = gst_player_get_subtitle_uri (player);
1043     fail_unless (current_suburi != NULL);
1044     suburi = gst_filename_to_uri (TEST_PATH "/test_sub.srt", NULL);
1045     fail_unless (suburi != NULL);
1046 
1047     fail_unless_equals_int (g_strcmp0 (current_suburi, suburi), 0);
1048 
1049     g_free (current_suburi);
1050     g_free (suburi);
1051     new_state->test_data = GINT_TO_POINTER (steps + 1);
1052     g_main_loop_quit (new_state->loop);
1053 
1054   } else if (change == STATE_CHANGE_END_OF_STREAM ||
1055       change == STATE_CHANGE_ERROR)
1056     g_main_loop_quit (new_state->loop);
1057 }
1058 
START_TEST(test_play_external_suburi)1059 START_TEST (test_play_external_suburi)
1060 {
1061   GstPlayer *player;
1062   TestPlayerState state;
1063   gchar *uri;
1064 
1065   memset (&state, 0, sizeof (state));
1066   state.loop = g_main_loop_new (NULL, FALSE);
1067   state.test_callback = test_play_external_suburi_cb;
1068   state.test_data = GINT_TO_POINTER (0);
1069 
1070   player = test_player_new (&state);
1071 
1072   fail_unless (player != NULL);
1073 
1074   uri = gst_filename_to_uri (TEST_PATH "/audio-video.ogg", NULL);
1075   fail_unless (uri != NULL);
1076   gst_player_set_uri (player, uri);
1077   g_free (uri);
1078 
1079   gst_player_play (player);
1080   g_main_loop_run (state.loop);
1081 
1082   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
1083 
1084   stop_player (player, &state);
1085   g_object_unref (player);
1086   g_main_loop_unref (state.loop);
1087 }
1088 
1089 END_TEST;
1090 
1091 static void
test_play_rate_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1092 test_play_rate_cb (GstPlayer * player,
1093     TestPlayerStateChange change, TestPlayerState * old_state,
1094     TestPlayerState * new_state)
1095 {
1096   gint steps = GPOINTER_TO_INT (new_state->test_data) & 0xf;
1097   gint mask = GPOINTER_TO_INT (new_state->test_data) & 0xf0;
1098 
1099   if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
1100     guint64 dur = -1, pos = -1;
1101 
1102     g_object_get (player, "position", &pos, "duration", &dur, NULL);
1103     pos = pos + dur * 0.2;      /* seek 20% */
1104     gst_player_seek (player, pos);
1105 
1106     /* default rate should be 1.0 */
1107     fail_unless_equals_double (gst_player_get_rate (player), 1.0);
1108     new_state->test_data = GINT_TO_POINTER (mask + steps + 1);
1109   } else if (change == STATE_CHANGE_END_OF_STREAM ||
1110       change == STATE_CHANGE_ERROR) {
1111     g_main_loop_quit (new_state->loop);
1112   } else if (steps == 1 && change == STATE_CHANGE_SEEK_DONE) {
1113     if (mask == 0x10)
1114       gst_player_set_rate (player, 1.5);
1115     else if (mask == 0x20)
1116       gst_player_set_rate (player, -1.0);
1117 
1118     new_state->test_data = GINT_TO_POINTER (mask + steps + 1);
1119   } else if (steps && (change == STATE_CHANGE_POSITION_UPDATED)) {
1120     if (steps == 10) {
1121       g_main_loop_quit (new_state->loop);
1122     } else {
1123       if (mask == 0x10 && (new_state->position > old_state->position))
1124         new_state->test_data = GINT_TO_POINTER (mask + steps + 1);
1125       else if (mask == 0x20 && (new_state->position < old_state->position))
1126         new_state->test_data = GINT_TO_POINTER (mask + steps + 1);
1127     }
1128   }
1129 }
1130 
START_TEST(test_play_forward_rate)1131 START_TEST (test_play_forward_rate)
1132 {
1133   GstPlayer *player;
1134   TestPlayerState state;
1135   gchar *uri;
1136 
1137   memset (&state, 0, sizeof (state));
1138   state.loop = g_main_loop_new (NULL, FALSE);
1139   state.test_callback = test_play_rate_cb;
1140   state.test_data = GINT_TO_POINTER (0x10);
1141 
1142   player = test_player_new (&state);
1143 
1144   fail_unless (player != NULL);
1145 
1146   uri = gst_filename_to_uri (TEST_PATH "/audio.ogg", NULL);
1147   fail_unless (uri != NULL);
1148   gst_player_set_uri (player, uri);
1149   g_free (uri);
1150 
1151   gst_player_play (player);
1152   g_main_loop_run (state.loop);
1153 
1154   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & 0xf, 10);
1155 
1156   stop_player (player, &state);
1157   g_object_unref (player);
1158   g_main_loop_unref (state.loop);
1159 }
1160 
1161 END_TEST;
1162 
START_TEST(test_play_backward_rate)1163 START_TEST (test_play_backward_rate)
1164 {
1165   GstPlayer *player;
1166   TestPlayerState state;
1167   gchar *uri;
1168 
1169   memset (&state, 0, sizeof (state));
1170   state.loop = g_main_loop_new (NULL, FALSE);
1171   state.test_callback = test_play_rate_cb;
1172   state.test_data = GINT_TO_POINTER (0x20);
1173 
1174   player = test_player_new (&state);
1175 
1176   fail_unless (player != NULL);
1177 
1178   uri = gst_filename_to_uri (TEST_PATH "/audio.ogg", NULL);
1179   fail_unless (uri != NULL);
1180   gst_player_set_uri (player, uri);
1181   g_free (uri);
1182 
1183   gst_player_play (player);
1184   g_main_loop_run (state.loop);
1185 
1186   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & 0xf, 10);
1187 
1188   stop_player (player, &state);
1189   g_object_unref (player);
1190   g_main_loop_unref (state.loop);
1191 }
1192 
1193 END_TEST;
1194 
START_TEST(test_play_audio_video_eos)1195 START_TEST (test_play_audio_video_eos)
1196 {
1197   GstPlayer *player;
1198   TestPlayerState state;
1199   gchar *uri;
1200 
1201   memset (&state, 0, sizeof (state));
1202   state.loop = g_main_loop_new (NULL, FALSE);
1203   state.test_callback = test_play_audio_video_eos_cb;
1204   state.test_data = GINT_TO_POINTER (0x10);
1205 
1206   player = test_player_new (&state);
1207 
1208   fail_unless (player != NULL);
1209 
1210   uri = gst_filename_to_uri (TEST_PATH "/audio-video-short.ogg", NULL);
1211   fail_unless (uri != NULL);
1212   gst_player_set_uri (player, uri);
1213   g_free (uri);
1214 
1215   gst_player_play (player);
1216   g_main_loop_run (state.loop);
1217 
1218   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & (~0x10), 10);
1219 
1220   stop_player (player, &state);
1221   g_object_unref (player);
1222   g_main_loop_unref (state.loop);
1223 }
1224 
1225 END_TEST;
1226 
1227 static void
test_play_error_invalid_uri_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1228 test_play_error_invalid_uri_cb (GstPlayer * player,
1229     TestPlayerStateChange change, TestPlayerState * old_state,
1230     TestPlayerState * new_state)
1231 {
1232   gint step = GPOINTER_TO_INT (new_state->test_data);
1233 
1234   switch (step) {
1235     case 0:
1236       fail_unless_equals_int (change, STATE_CHANGE_URI_LOADED);
1237       fail_unless_equals_string (new_state->uri_loaded, "foo://bar");
1238       new_state->test_data = GINT_TO_POINTER (step + 1);
1239       break;
1240     case 1:
1241       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
1242       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
1243       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
1244       new_state->test_data = GINT_TO_POINTER (step + 1);
1245       break;
1246     case 2:
1247       fail_unless_equals_int (change, STATE_CHANGE_ERROR);
1248       new_state->test_data = GINT_TO_POINTER (step + 1);
1249       break;
1250     case 3:
1251       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
1252       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
1253       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_STOPPED);
1254       new_state->test_data = GINT_TO_POINTER (step + 1);
1255       g_main_loop_quit (new_state->loop);
1256       break;
1257     default:
1258       fail ();
1259       break;
1260   }
1261 }
1262 
START_TEST(test_play_error_invalid_uri)1263 START_TEST (test_play_error_invalid_uri)
1264 {
1265   GstPlayer *player;
1266   TestPlayerState state;
1267 
1268   memset (&state, 0, sizeof (state));
1269   state.loop = g_main_loop_new (NULL, FALSE);
1270   state.test_callback = test_play_error_invalid_uri_cb;
1271   state.test_data = GINT_TO_POINTER (0);
1272 
1273   player = test_player_new (&state);
1274 
1275   fail_unless (player != NULL);
1276 
1277   gst_player_set_uri (player, "foo://bar");
1278 
1279   gst_player_play (player);
1280   g_main_loop_run (state.loop);
1281 
1282   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 4);
1283 
1284   stop_player (player, &state);
1285   g_object_unref (player);
1286   g_main_loop_unref (state.loop);
1287 }
1288 
1289 END_TEST;
1290 
1291 static void
test_play_error_invalid_uri_and_play_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1292 test_play_error_invalid_uri_and_play_cb (GstPlayer * player,
1293     TestPlayerStateChange change, TestPlayerState * old_state,
1294     TestPlayerState * new_state)
1295 {
1296   gint step = GPOINTER_TO_INT (new_state->test_data);
1297   gchar *uri;
1298 
1299   switch (step) {
1300     case 0:
1301       fail_unless_equals_int (change, STATE_CHANGE_URI_LOADED);
1302       fail_unless_equals_string (new_state->uri_loaded, "foo://bar");
1303       new_state->test_data = GINT_TO_POINTER (step + 1);
1304       break;
1305     case 1:
1306       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
1307       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
1308       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
1309       new_state->test_data = GINT_TO_POINTER (step + 1);
1310       break;
1311     case 2:
1312       fail_unless_equals_int (change, STATE_CHANGE_ERROR);
1313       new_state->test_data = GINT_TO_POINTER (step + 1);
1314       break;
1315     case 3:
1316       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
1317       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
1318       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_STOPPED);
1319       new_state->test_data = GINT_TO_POINTER (step + 1);
1320 
1321       uri = gst_filename_to_uri (TEST_PATH "/audio-short.ogg", NULL);
1322       fail_unless (uri != NULL);
1323       gst_player_set_uri (player, uri);
1324       g_free (uri);
1325 
1326       gst_player_play (player);
1327       break;
1328     case 4:
1329       fail_unless_equals_int (change, STATE_CHANGE_URI_LOADED);
1330       fail_unless (g_str_has_suffix (new_state->uri_loaded, "audio-short.ogg"));
1331       new_state->test_data = GINT_TO_POINTER (step + 1);
1332       break;
1333     case 5:
1334       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
1335       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
1336       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
1337       new_state->test_data = GINT_TO_POINTER (step + 1);
1338       break;
1339     case 6:
1340       fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
1341       new_state->test_data = GINT_TO_POINTER (step + 1);
1342       break;
1343     case 7:
1344       fail_unless_equals_int (change, STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED);
1345       fail_unless_equals_int (new_state->width, 0);
1346       fail_unless_equals_int (new_state->height, 0);
1347       new_state->test_data = GINT_TO_POINTER (step + 1);
1348       break;
1349     case 8:
1350       fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
1351       new_state->test_data = GINT_TO_POINTER (step + 1);
1352       break;
1353     case 9:
1354       fail_unless_equals_int (change, STATE_CHANGE_DURATION_CHANGED);
1355       fail_unless_equals_uint64 (new_state->duration,
1356           G_GUINT64_CONSTANT (464399092));
1357       new_state->test_data = GINT_TO_POINTER (step + 1);
1358       break;
1359     case 10:
1360       fail_unless_equals_int (change, STATE_CHANGE_POSITION_UPDATED);
1361       fail_unless_equals_uint64 (new_state->position, G_GUINT64_CONSTANT (0));
1362       new_state->test_data = GINT_TO_POINTER (step + 1);
1363       break;
1364     case 11:
1365       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
1366       fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
1367       fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_PLAYING);
1368       new_state->test_data = GINT_TO_POINTER (step + 1);
1369       g_main_loop_quit (new_state->loop);
1370       break;
1371     default:
1372       fail ();
1373       break;
1374   }
1375 }
1376 
START_TEST(test_play_error_invalid_uri_and_play)1377 START_TEST (test_play_error_invalid_uri_and_play)
1378 {
1379   GstPlayer *player;
1380   TestPlayerState state;
1381 
1382   memset (&state, 0, sizeof (state));
1383   state.loop = g_main_loop_new (NULL, FALSE);
1384   state.test_callback = test_play_error_invalid_uri_and_play_cb;
1385   state.test_data = GINT_TO_POINTER (0);
1386 
1387   player = test_player_new (&state);
1388 
1389   fail_unless (player != NULL);
1390 
1391   gst_player_set_uri (player, "foo://bar");
1392 
1393   gst_player_play (player);
1394   g_main_loop_run (state.loop);
1395 
1396   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 12);
1397 
1398   stop_player (player, &state);
1399   g_object_unref (player);
1400   g_main_loop_unref (state.loop);
1401 }
1402 
1403 END_TEST;
1404 
1405 static void
test_play_seek_done_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1406 test_play_seek_done_cb (GstPlayer * player,
1407     TestPlayerStateChange change, TestPlayerState * old_state,
1408     TestPlayerState * new_state)
1409 {
1410   gint step = GPOINTER_TO_INT (new_state->test_data) & (~0x10);
1411 
1412   if (new_state->state == GST_PLAYER_STATE_PLAYING && !step) {
1413     gst_player_seek (player, 0);
1414     new_state->test_data = GINT_TO_POINTER (step + 1);
1415   } else if (change == STATE_CHANGE_SEEK_DONE || change == STATE_CHANGE_ERROR) {
1416     fail_unless_equals_int (change, STATE_CHANGE_SEEK_DONE);
1417     fail_unless_equals_uint64 (new_state->seek_done_position,
1418         G_GUINT64_CONSTANT (0));
1419     new_state->test_data = GINT_TO_POINTER (step + 1);
1420     g_main_loop_quit (new_state->loop);
1421   }
1422 }
1423 
START_TEST(test_play_audio_video_seek_done)1424 START_TEST (test_play_audio_video_seek_done)
1425 {
1426   GstPlayer *player;
1427   TestPlayerState state;
1428   gchar *uri;
1429 
1430   memset (&state, 0, sizeof (state));
1431   state.loop = g_main_loop_new (NULL, FALSE);
1432   state.test_callback = test_play_seek_done_cb;
1433   state.test_data = GINT_TO_POINTER (0);
1434 
1435   player = test_player_new (&state);
1436 
1437   fail_unless (player != NULL);
1438 
1439   uri = gst_filename_to_uri (TEST_PATH "/audio-video.ogg", NULL);
1440   fail_unless (uri != NULL);
1441   gst_player_set_uri (player, uri);
1442   g_free (uri);
1443 
1444   gst_player_play (player);
1445   g_main_loop_run (state.loop);
1446 
1447   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & (~0x10), 2);
1448 
1449   stop_player (player, &state);
1450   g_object_unref (player);
1451   g_main_loop_unref (state.loop);
1452 }
1453 
1454 END_TEST;
1455 
1456 static void
test_play_position_update_interval_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1457 test_play_position_update_interval_cb (GstPlayer * player,
1458     TestPlayerStateChange change, TestPlayerState * old_state,
1459     TestPlayerState * new_state)
1460 {
1461   static gboolean do_quit = TRUE;
1462   static GstClockTime last_position = GST_CLOCK_TIME_NONE;
1463 
1464   gint steps = GPOINTER_TO_INT (new_state->test_data);
1465 
1466   if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
1467     new_state->test_data = GINT_TO_POINTER (steps + 1);
1468   } else if (steps && change == STATE_CHANGE_POSITION_UPDATED) {
1469     GstClockTime position = gst_player_get_position (player);
1470     new_state->test_data = GINT_TO_POINTER (steps + 1);
1471 
1472     if (GST_CLOCK_TIME_IS_VALID (last_position)) {
1473       GstClockTime interval = GST_CLOCK_DIFF (last_position, position);
1474       GST_DEBUG_OBJECT (player,
1475           "position update interval: %" GST_TIME_FORMAT "\n",
1476           GST_TIME_ARGS (interval));
1477       fail_unless (interval > (590 * GST_MSECOND)
1478           && interval < (610 * GST_MSECOND));
1479     }
1480 
1481     last_position = position;
1482 
1483     if (do_quit && position >= 2000 * GST_MSECOND) {
1484       do_quit = FALSE;
1485       g_main_loop_quit (new_state->loop);
1486     }
1487   } else if (change == STATE_CHANGE_END_OF_STREAM ||
1488       change == STATE_CHANGE_ERROR) {
1489     g_main_loop_quit (new_state->loop);
1490   }
1491 }
1492 
1493 static gboolean
quit_loop_cb(gpointer user_data)1494 quit_loop_cb (gpointer user_data)
1495 {
1496   GMainLoop *loop = user_data;
1497   g_main_loop_quit (loop);
1498 
1499   return G_SOURCE_REMOVE;
1500 }
1501 
START_TEST(test_play_position_update_interval)1502 START_TEST (test_play_position_update_interval)
1503 {
1504   GstPlayer *player;
1505   TestPlayerState state;
1506   gchar *uri;
1507   GstStructure *config;
1508 
1509   memset (&state, 0, sizeof (state));
1510   state.loop = g_main_loop_new (NULL, FALSE);
1511   state.test_callback = test_play_position_update_interval_cb;
1512   state.test_data = GINT_TO_POINTER (0);
1513 
1514   player = test_player_new (&state);
1515 
1516   config = gst_player_get_config (player);
1517   gst_player_config_set_position_update_interval (config, 600);
1518   gst_player_set_config (player, config);
1519 
1520   fail_unless (player != NULL);
1521 
1522   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
1523   fail_unless (uri != NULL);
1524   gst_player_set_uri (player, uri);
1525   g_free (uri);
1526 
1527   gst_player_play (player);
1528   g_main_loop_run (state.loop);
1529 
1530   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 5);
1531 
1532   /* Disable position updates */
1533   gst_player_stop (player);
1534 
1535   config = gst_player_get_config (player);
1536   gst_player_config_set_position_update_interval (config, 0);
1537   gst_player_set_config (player, config);
1538 
1539   g_timeout_add (2000, quit_loop_cb, state.loop);
1540   g_main_loop_run (state.loop);
1541 
1542   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 5);
1543 
1544   stop_player (player, &state);
1545   g_object_unref (player);
1546   g_main_loop_unref (state.loop);
1547 }
1548 
1549 END_TEST;
1550 
1551 static void
test_restart_cb(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1552 test_restart_cb (GstPlayer * player,
1553     TestPlayerStateChange change, TestPlayerState * old_state,
1554     TestPlayerState * new_state)
1555 {
1556   gint steps = GPOINTER_TO_INT (new_state->test_data);
1557 
1558   if (!steps && change == STATE_CHANGE_URI_LOADED) {
1559     fail_unless (g_str_has_suffix (new_state->uri_loaded, "sintel.mkv"));
1560     new_state->test_data = GINT_TO_POINTER (steps + 1);
1561   } else if (change == STATE_CHANGE_STATE_CHANGED
1562       && new_state->state == GST_PLAYER_STATE_BUFFERING) {
1563     new_state->test_data = GINT_TO_POINTER (steps + 1);
1564     g_main_loop_quit (new_state->loop);
1565   }
1566 }
1567 
1568 static void
test_restart_cb2(GstPlayer * player,TestPlayerStateChange change,TestPlayerState * old_state,TestPlayerState * new_state)1569 test_restart_cb2 (GstPlayer * player,
1570     TestPlayerStateChange change, TestPlayerState * old_state,
1571     TestPlayerState * new_state)
1572 {
1573   gint steps = GPOINTER_TO_INT (new_state->test_data);
1574 
1575   if (!steps && change == STATE_CHANGE_URI_LOADED) {
1576     fail_unless (g_str_has_suffix (new_state->uri_loaded, "audio-short.ogg"));
1577     new_state->test_data = GINT_TO_POINTER (steps + 1);
1578   } else if (change == STATE_CHANGE_STATE_CHANGED
1579       && new_state->state == GST_PLAYER_STATE_BUFFERING) {
1580     new_state->test_data = GINT_TO_POINTER (steps + 1);
1581     g_main_loop_quit (new_state->loop);
1582   }
1583 }
1584 
1585 
START_TEST(test_restart)1586 START_TEST (test_restart)
1587 {
1588   GstPlayer *player;
1589   TestPlayerState state;
1590   gchar *uri;
1591 
1592   memset (&state, 0, sizeof (state));
1593   state.loop = g_main_loop_new (NULL, FALSE);
1594   state.test_callback = test_restart_cb;
1595   state.test_data = GINT_TO_POINTER (0);
1596 
1597   player = test_player_new (&state);
1598 
1599   fail_unless (player != NULL);
1600 
1601   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
1602   fail_unless (uri != NULL);
1603   gst_player_set_uri (player, uri);
1604   g_free (uri);
1605 
1606   gst_player_play (player);
1607   g_main_loop_run (state.loop);
1608   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
1609   stop_player (player, &state);
1610 
1611   /* Try again with another URI */
1612   state.test_data = GINT_TO_POINTER (0);
1613   state.test_callback = test_restart_cb2;
1614 
1615   uri = gst_filename_to_uri (TEST_PATH "/audio-short.ogg", NULL);
1616   fail_unless (uri != NULL);
1617   gst_player_set_uri (player, uri);
1618   g_free (uri);
1619 
1620   gst_player_play (player);
1621   g_main_loop_run (state.loop);
1622   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
1623   stop_player (player, &state);
1624 
1625   g_object_unref (player);
1626   g_main_loop_unref (state.loop);
1627 }
1628 
1629 END_TEST;
1630 
1631 #define TEST_USER_AGENT "test user agent"
1632 
1633 static void
source_setup_cb(GstElement * playbin,GstElement * source,GMainLoop * loop)1634 source_setup_cb (GstElement * playbin, GstElement * source, GMainLoop * loop)
1635 {
1636   gchar *user_agent;
1637 
1638   g_object_get (source, "user-agent", &user_agent, NULL);
1639   fail_unless_equals_string (user_agent, TEST_USER_AGENT);
1640   g_free (user_agent);
1641 
1642   g_main_loop_quit (loop);
1643 }
1644 
START_TEST(test_user_agent)1645 START_TEST (test_user_agent)
1646 {
1647   GstPlayer *player;
1648   GMainLoop *loop;
1649   GstElement *pipeline;
1650   GstStructure *config;
1651   gchar *user_agent;
1652 
1653   loop = g_main_loop_new (NULL, FALSE);
1654   player = gst_player_new (NULL, NULL);
1655   fail_unless (player != NULL);
1656 
1657   gst_player_set_uri (player, "http://badger.com/test.mkv");
1658 
1659   config = gst_player_get_config (player);
1660   gst_player_config_set_user_agent (config, TEST_USER_AGENT);
1661 
1662   user_agent = gst_player_config_get_user_agent (config);
1663   fail_unless_equals_string (user_agent, TEST_USER_AGENT);
1664   g_free (user_agent);
1665 
1666   gst_player_set_config (player, config);
1667 
1668   pipeline = gst_player_get_pipeline (player);
1669   g_signal_connect (pipeline, "source-setup", G_CALLBACK (source_setup_cb),
1670       loop);
1671 
1672   gst_player_pause (player);
1673   g_main_loop_run (loop);
1674 
1675   gst_object_unref (pipeline);
1676 
1677   g_object_unref (player);
1678   g_main_loop_unref (loop);
1679 }
1680 
1681 END_TEST;
1682 
1683 static Suite *
player_suite(void)1684 player_suite (void)
1685 {
1686   Suite *s = suite_create ("GstPlayer");
1687 
1688   TCase *tc_general = tcase_create ("general");
1689 
1690   /* Use a longer timeout */
1691 #ifdef HAVE_VALGRIND
1692   if (RUNNING_ON_VALGRIND) {
1693     tcase_set_timeout (tc_general, 5 * 60);
1694   } else
1695 #endif
1696   {
1697     tcase_set_timeout (tc_general, 2 * 60);
1698   }
1699 
1700   tcase_add_test (tc_general, test_create_and_free);
1701   tcase_add_test (tc_general, test_set_and_get_uri);
1702   tcase_add_test (tc_general, test_set_and_get_position_update_interval);
1703 
1704   /* Skip playback tests for now.
1705    * See https://bugzilla.gnome.org/show_bug.cgi?id=787374 */
1706 
1707 #ifdef HAVE_VALGRIND
1708   if (RUNNING_ON_VALGRIND) {
1709   } else
1710 #endif
1711   {
1712     tcase_skip_broken_test (tc_general, test_play_position_update_interval);
1713   }
1714   tcase_skip_broken_test (tc_general, test_play_audio_eos);
1715   tcase_skip_broken_test (tc_general, test_play_audio_video_eos);
1716   tcase_skip_broken_test (tc_general, test_play_error_invalid_uri);
1717   tcase_skip_broken_test (tc_general, test_play_error_invalid_uri_and_play);
1718   tcase_skip_broken_test (tc_general, test_play_media_info);
1719   tcase_skip_broken_test (tc_general, test_play_stream_disable);
1720   tcase_skip_broken_test (tc_general, test_play_stream_switch_audio);
1721   tcase_skip_broken_test (tc_general, test_play_stream_switch_subtitle);
1722   tcase_skip_broken_test (tc_general, test_play_error_invalid_external_suburi);
1723   tcase_skip_broken_test (tc_general, test_play_external_suburi);
1724   tcase_skip_broken_test (tc_general, test_play_forward_rate);
1725   tcase_skip_broken_test (tc_general, test_play_backward_rate);
1726   tcase_skip_broken_test (tc_general, test_play_audio_video_seek_done);
1727   tcase_skip_broken_test (tc_general, test_restart);
1728   tcase_skip_broken_test (tc_general, test_user_agent);
1729 
1730   suite_add_tcase (s, tc_general);
1731 
1732   return s;
1733 }
1734 
1735 GST_CHECK_MAIN (player)
1736