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