• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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