play: tests: Refactor to use new Message bus API
authorPhilippe Normand <philn@igalia.com>
Sat, 14 Nov 2020 10:56:51 +0000 (10:56 +0000)
committerPhilippe Normand <philn@igalia.com>
Tue, 9 Mar 2021 18:03:48 +0000 (18:03 +0000)
Instead of relying on an extra GMainLoop, the messages are poped from the player
bus and handled synchronously. This should avoid flaky behaviors.

Fixes #608

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2061>

meson_options.txt
tests/check/libs/play.c [moved from tests/check/libs/player.c with 56% similarity]
tests/check/meson.build

index c03f1b1..0326851 100644 (file)
@@ -1,5 +1,5 @@
-option('gst_player_tests', type: 'boolean', value: false,
-       description: 'Enable GstPlayer tests that need network access')
+option('gst_play_tests', type: 'boolean', value: false,
+       description: 'Enable GstPlay tests that need network access')
 
 # Feature options for plugins without external deps
 option('accurip', type : 'feature', value : 'auto')
similarity index 56%
rename from tests/check/libs/player.c
rename to tests/check/libs/play.c
index b7a6fbf..1f6f6f1 100644 (file)
@@ -63,13 +63,13 @@ G_STMT_START {                                                          \
     "'" #a "' (%lf) is not equal to '" #b"' (%lf)", first, second);     \
 } G_STMT_END;
 
-#include <gst/player/player.h>
+#include <gst/play/play.h>
 
 START_TEST (test_create_and_free)
 {
-  GstPlayer *player;
+  GstPlay *player;
 
-  player = gst_player_new (NULL, NULL);
+  player = gst_play_new (NULL);
   fail_unless (player != NULL);
   g_object_unref (player);
 }
@@ -78,15 +78,15 @@ END_TEST;
 
 START_TEST (test_set_and_get_uri)
 {
-  GstPlayer *player;
+  GstPlay *player;
   gchar *uri;
 
-  player = gst_player_new (NULL, NULL);
+  player = gst_play_new (NULL);
 
   fail_unless (player != NULL);
 
-  gst_player_set_uri (player, "file:///path/to/a/file");
-  uri = gst_player_get_uri (player);
+  gst_play_set_uri (player, "file:///path/to/a/file");
+  uri = gst_play_get_uri (player);
 
   fail_unless (g_strcmp0 (uri, "file:///path/to/a/file") == 0);
 
@@ -98,19 +98,19 @@ END_TEST;
 
 START_TEST (test_set_and_get_position_update_interval)
 {
-  GstPlayer *player;
+  GstPlay *player;
   guint interval = 0;
   GstStructure *config;
 
-  player = gst_player_new (NULL, NULL);
+  player = gst_play_new (NULL);
 
   fail_unless (player != NULL);
 
-  config = gst_player_get_config (player);
-  gst_player_config_set_position_update_interval (config, 500);
-  interval = gst_player_config_get_position_update_interval (config);
+  config = gst_play_get_config (player);
+  gst_play_config_set_position_update_interval (config, 500);
+  interval = gst_play_config_get_position_update_interval (config);
   fail_unless (interval == 500);
-  gst_player_set_config (player, config);
+  gst_play_set_config (player, config);
 
   g_object_unref (player);
 }
@@ -133,7 +133,7 @@ typedef enum
 } TestPlayerStateChange;
 
 static const gchar *
-test_player_state_change_get_name (TestPlayerStateChange change)
+test_play_state_change_get_name (TestPlayerStateChange change)
 {
   switch (change) {
     case STATE_CHANGE_BUFFERING:
@@ -167,24 +167,25 @@ test_player_state_change_get_name (TestPlayerStateChange change)
 typedef struct _TestPlayerState TestPlayerState;
 struct _TestPlayerState
 {
-  GMainLoop *loop;
-
   gint buffering_percent;
   guint64 position, duration, seek_done_position;
   gboolean end_of_stream, error, warning, seek_done;
-  GstPlayerState state;
-  gint width, height;
-  GstPlayerMediaInfo *media_info;
+  GstPlayState state;
+  guint width, height;
+  GstPlayMediaInfo *media_info;
   gchar *uri_loaded;
-  gboolean stopping;
+  GstClockTime last_position;
+  gboolean done;
 
-  void (*test_callback) (GstPlayer * player, TestPlayerStateChange change,
+  void (*test_callback) (GstPlay * player, TestPlayerStateChange change,
       TestPlayerState * old_state, TestPlayerState * new_state);
   gpointer test_data;
 };
 
+static void process_play_messages (GstPlay * player, TestPlayerState * state);
+
 static void
-test_player_state_change_debug (GstPlayer * player,
+test_play_state_change_debug (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
@@ -200,7 +201,7 @@ test_player_state_change_debug (GstPlayer * player,
       "\twidth/height %d/%d -> %d/%d\n"
       "\tmedia_info %p -> %p\n"
       "\turi_loaded %s -> %s",
-      test_player_state_change_get_name (change),
+      test_play_state_change_get_name (change),
       old_state->buffering_percent, new_state->buffering_percent,
       GST_TIME_ARGS (old_state->position), GST_TIME_ARGS (new_state->position),
       GST_TIME_ARGS (old_state->duration), GST_TIME_ARGS (new_state->duration),
@@ -208,195 +209,39 @@ test_player_state_change_debug (GstPlayer * player,
       GST_TIME_ARGS (new_state->seek_done_position), old_state->end_of_stream,
       new_state->end_of_stream, old_state->error, new_state->error,
       old_state->seek_done, new_state->seek_done,
-      gst_player_state_get_name (old_state->state),
-      gst_player_state_get_name (new_state->state), old_state->width,
+      gst_play_state_get_name (old_state->state),
+      gst_play_state_get_name (new_state->state), old_state->width,
       old_state->height, new_state->width, new_state->height,
       old_state->media_info, new_state->media_info,
       old_state->uri_loaded, new_state->uri_loaded);
 }
 
 static void
-test_player_state_reset (TestPlayerState * state)
+test_play_state_reset (GstPlay * player, TestPlayerState * state)
 {
   state->buffering_percent = 100;
   state->position = state->duration = state->seek_done_position = -1;
   state->end_of_stream = state->error = state->seek_done = FALSE;
-  state->state = GST_PLAYER_STATE_STOPPED;
+  state->state = GST_PLAY_STATE_STOPPED;
   state->width = state->height = 0;
   state->media_info = NULL;
-  state->stopping = FALSE;
+  state->last_position = GST_CLOCK_TIME_NONE;
+  state->done = FALSE;
   g_clear_pointer (&state->uri_loaded, g_free);
 }
 
-static void
-buffering_cb (GstPlayer * player, gint percent, TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->buffering_percent = percent;
-  test_player_state_change_debug (player, STATE_CHANGE_BUFFERING, &old_state,
-      state);
-  state->test_callback (player, STATE_CHANGE_BUFFERING, &old_state, state);
-}
-
-static void
-duration_changed_cb (GstPlayer * player, guint64 duration,
-    TestPlayerState * state)
+static GstPlay *
+test_play_new (TestPlayerState * state)
 {
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->duration = duration;
-  test_player_state_change_debug (player, STATE_CHANGE_DURATION_CHANGED,
-      &old_state, state);
-  state->test_callback (player, STATE_CHANGE_DURATION_CHANGED, &old_state,
-      state);
-}
-
-static void
-end_of_stream_cb (GstPlayer * player, TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->end_of_stream = TRUE;
-  test_player_state_change_debug (player, STATE_CHANGE_END_OF_STREAM,
-      &old_state, state);
-  state->test_callback (player, STATE_CHANGE_END_OF_STREAM, &old_state, state);
-}
-
-static void
-error_cb (GstPlayer * player, GError * error, TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->error = TRUE;
-  test_player_state_change_debug (player, STATE_CHANGE_ERROR, &old_state,
-      state);
-  state->test_callback (player, STATE_CHANGE_ERROR, &old_state, state);
-}
-
-static void
-warning_cb (GstPlayer * player, GError * error, TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->warning = TRUE;
-  test_player_state_change_debug (player, STATE_CHANGE_WARNING, &old_state,
-      state);
-  state->test_callback (player, STATE_CHANGE_WARNING, &old_state, state);
-}
-
-static void
-position_updated_cb (GstPlayer * player, guint64 position,
-    TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->position = position;
-  test_player_state_change_debug (player, STATE_CHANGE_POSITION_UPDATED,
-      &old_state, state);
-  state->test_callback (player, STATE_CHANGE_POSITION_UPDATED, &old_state,
-      state);
-}
-
-static void
-media_info_updated_cb (GstPlayer * player, GstPlayerMediaInfo * media_info,
-    TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->media_info = media_info;
-
-  test_player_state_change_debug (player, STATE_CHANGE_MEDIA_INFO_UPDATED,
-      &old_state, state);
-  state->test_callback (player, STATE_CHANGE_MEDIA_INFO_UPDATED, &old_state,
-      state);
-}
-
-static void
-state_changed_cb (GstPlayer * player, GstPlayerState player_state,
-    TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping || player_state == GST_PLAYER_STATE_STOPPED);
-
-  state->state = player_state;
-
-  if (player_state == GST_PLAYER_STATE_STOPPED)
-    test_player_state_reset (state);
-
-  test_player_state_change_debug (player, STATE_CHANGE_STATE_CHANGED,
-      &old_state, state);
-  state->test_callback (player, STATE_CHANGE_STATE_CHANGED, &old_state, state);
-}
-
-static void
-video_dimensions_changed_cb (GstPlayer * player, gint width, gint height,
-    TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->width = width;
-  state->height = height;
-  test_player_state_change_debug (player, STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED,
-      &old_state, state);
-  state->test_callback (player, STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED,
-      &old_state, state);
-}
-
-static void
-seek_done_cb (GstPlayer * player, guint64 position, TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  g_assert (!state->stopping);
-
-  state->seek_done = TRUE;
-  state->seek_done_position = position;
-  test_player_state_change_debug (player, STATE_CHANGE_SEEK_DONE,
-      &old_state, state);
-  state->test_callback (player, STATE_CHANGE_SEEK_DONE, &old_state, state);
-}
-
-static void
-uri_loaded_cb (GstPlayer * player, const gchar * uri, TestPlayerState * state)
-{
-  TestPlayerState old_state = *state;
-
-  state->uri_loaded = g_strdup (uri);
-  state->test_callback (player, STATE_CHANGE_URI_LOADED, &old_state, state);
-}
-
-static GstPlayer *
-test_player_new (TestPlayerState * state)
-{
-  GstPlayer *player;
+  GstPlay *player;
   GstElement *playbin, *fakesink;
 
-  player =
-      gst_player_new (NULL,
-      gst_player_g_main_context_signal_dispatcher_new (NULL));
+  player = gst_play_new (NULL);
   fail_unless (player != NULL);
 
-  test_player_state_reset (state);
+  test_play_state_reset (player, state);
 
-  playbin = gst_player_get_pipeline (player);
+  playbin = gst_play_get_pipeline (player);
   fakesink = gst_element_factory_make ("fakesink", "audio-sink");
   g_object_set (fakesink, "sync", TRUE, NULL);
   g_object_set (playbin, "audio-sink", fakesink, NULL);
@@ -405,51 +250,34 @@ test_player_new (TestPlayerState * state)
   g_object_set (playbin, "video-sink", fakesink, NULL);
   gst_object_unref (playbin);
 
-  g_signal_connect (player, "buffering", G_CALLBACK (buffering_cb), state);
-  g_signal_connect (player, "duration-changed",
-      G_CALLBACK (duration_changed_cb), state);
-  g_signal_connect (player, "end-of-stream", G_CALLBACK (end_of_stream_cb),
-      state);
-  g_signal_connect (player, "error", G_CALLBACK (error_cb), state);
-  g_signal_connect (player, "warning", G_CALLBACK (warning_cb), state);
-  g_signal_connect (player, "position-updated",
-      G_CALLBACK (position_updated_cb), state);
-  g_signal_connect (player, "state-changed", G_CALLBACK (state_changed_cb),
-      state);
-  g_signal_connect (player, "media-info-updated",
-      G_CALLBACK (media_info_updated_cb), state);
-  g_signal_connect (player, "video-dimensions-changed",
-      G_CALLBACK (video_dimensions_changed_cb), state);
-  g_signal_connect (player, "seek-done", G_CALLBACK (seek_done_cb), state);
-  g_signal_connect (player, "uri-loaded", G_CALLBACK (uri_loaded_cb), state);
-
   return player;
 }
 
 static void
-test_player_stopped_cb (GstPlayer * player, TestPlayerStateChange change,
+test_play_stopped_cb (GstPlay * player, TestPlayerStateChange change,
     TestPlayerState * old_state, TestPlayerState * new_state)
 {
-  if (new_state->state == GST_PLAYER_STATE_STOPPED) {
-    g_main_loop_quit (new_state->loop);
+  if (new_state->state == GST_PLAY_STATE_STOPPED) {
+    new_state->done = TRUE;
   }
 }
 
 static void
-stop_player (GstPlayer * player, TestPlayerState * state)
+stop_player (GstPlay * player, TestPlayerState * state)
 {
-  if (state->state != GST_PLAYER_STATE_STOPPED) {
+  if (state->state != GST_PLAY_STATE_STOPPED) {
     /* Make sure all pending operations are finished so the player won't be
      * appear as 'leaked' to leak detection tools. */
-    state->test_callback = test_player_stopped_cb;
-    gst_player_stop (player);
-    state->stopping = TRUE;
-    g_main_loop_run (state->loop);
+    state->test_callback = test_play_stopped_cb;
+    gst_play_stop (player);
+    state->done = FALSE;
+    process_play_messages (player, state);
   }
+  test_play_state_reset (player, state);
 }
 
 static void
-test_play_audio_video_eos_cb (GstPlayer * player, TestPlayerStateChange change,
+test_play_audio_video_eos_cb (GstPlay * player, TestPlayerStateChange change,
     TestPlayerState * old_state, TestPlayerState * new_state)
 {
   gint step = GPOINTER_TO_INT (new_state->test_data);
@@ -472,8 +300,8 @@ test_play_audio_video_eos_cb (GstPlayer * player, TestPlayerStateChange change,
       break;
     case 1:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_STOPPED);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_BUFFERING);
       new_state->test_data =
           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
       break;
@@ -495,47 +323,44 @@ test_play_audio_video_eos_cb (GstPlayer * player, TestPlayerStateChange change,
           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
       break;
     case 4:
-      fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
-      new_state->test_data =
-          GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
-      break;
-    case 5:
       fail_unless_equals_int (change, STATE_CHANGE_DURATION_CHANGED);
       fail_unless_equals_uint64 (new_state->duration,
           G_GUINT64_CONSTANT (464399092));
       new_state->test_data =
           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
       break;
-    case 6:
-      fail_unless_equals_int (change, STATE_CHANGE_POSITION_UPDATED);
-      fail_unless_equals_uint64 (new_state->position, G_GUINT64_CONSTANT (0));
+    case 5:
+      fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
       new_state->test_data =
           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
       break;
-    case 7:
+    case 6:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_PLAYING);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_BUFFERING);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_PLAYING);
       new_state->test_data =
           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
       break;
-    case 8:
-      if (change == STATE_CHANGE_POSITION_UPDATED) {
-        fail_unless (old_state->position <= new_state->position);
-      } else {
-        fail_unless_equals_uint64 (old_state->position, old_state->duration);
-        fail_unless_equals_int (change, STATE_CHANGE_END_OF_STREAM);
+    case 7:
+      fail_unless_equals_int (change, STATE_CHANGE_POSITION_UPDATED);
+      g_assert (new_state->position <= old_state->duration);
+      if (new_state->position == old_state->duration)
         new_state->test_data =
             GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
-      }
+      break;
+    case 8:
+      fail_unless_equals_int (change, STATE_CHANGE_END_OF_STREAM);
+      fail_unless_equals_uint64 (new_state->position, old_state->duration);
+      new_state->test_data =
+          GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
       break;
     case 9:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_PLAYING);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_STOPPED);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_PLAYING);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_STOPPED);
       new_state->test_data =
           GINT_TO_POINTER ((video ? 0x10 : 0x00) | (step + 1));
-      g_main_loop_quit (new_state->loop);
+      new_state->done = TRUE;
       break;
     default:
       fail ();
@@ -543,72 +368,204 @@ test_play_audio_video_eos_cb (GstPlayer * player, TestPlayerStateChange change,
   }
 }
 
+void
+process_play_messages (GstPlay * player, TestPlayerState * state)
+{
+  GstBus *bus = gst_play_get_message_bus (player);
+  do {
+    GstMessage *msg =
+        gst_bus_timed_pop_filtered (bus, -1, GST_MESSAGE_APPLICATION);
+    GST_INFO ("message: %" GST_PTR_FORMAT, msg);
+
+    if (gst_play_is_play_message (msg)) {
+      TestPlayerState old_state = *state;
+      GstPlayMessage type;
+
+      gst_play_message_parse_type (msg, &type);
+      switch (type) {
+        case GST_PLAY_MESSAGE_URI_LOADED:
+          state->uri_loaded = gst_play_get_uri (player);
+          state->test_callback (player, STATE_CHANGE_URI_LOADED, &old_state,
+              state);
+          break;
+        case GST_PLAY_MESSAGE_POSITION_UPDATED:
+          gst_play_message_parse_position_updated (msg, &state->position);
+          test_play_state_change_debug (player, STATE_CHANGE_POSITION_UPDATED,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_POSITION_UPDATED,
+              &old_state, state);
+          break;
+        case GST_PLAY_MESSAGE_DURATION_CHANGED:{
+          GstClockTime duration;
+          gst_play_message_parse_duration_updated (msg, &duration);
+          state->duration = duration;
+          test_play_state_change_debug (player, STATE_CHANGE_DURATION_CHANGED,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_DURATION_CHANGED,
+              &old_state, state);
+          break;
+        }
+        case GST_PLAY_MESSAGE_STATE_CHANGED:{
+          GstPlayState play_state;
+          gst_play_message_parse_state_changed (msg, &play_state);
+
+          state->state = play_state;
+
+          if (play_state == GST_PLAY_STATE_STOPPED)
+            test_play_state_reset (player, state);
+
+          test_play_state_change_debug (player, STATE_CHANGE_STATE_CHANGED,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_STATE_CHANGED, &old_state,
+              state);
+          break;
+        }
+        case GST_PLAY_MESSAGE_BUFFERING:{
+          guint percent;
+          gst_play_message_parse_buffering_percent (msg, &percent);
+
+          state->buffering_percent = percent;
+          test_play_state_change_debug (player, STATE_CHANGE_BUFFERING,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_BUFFERING, &old_state,
+              state);
+          break;
+        }
+        case GST_PLAY_MESSAGE_END_OF_STREAM:
+          state->end_of_stream = TRUE;
+          test_play_state_change_debug (player, STATE_CHANGE_END_OF_STREAM,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_END_OF_STREAM, &old_state,
+              state);
+          break;
+        case GST_PLAY_MESSAGE_ERROR:{
+          state->error = TRUE;
+          test_play_state_change_debug (player, STATE_CHANGE_ERROR,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_ERROR, &old_state, state);
+          break;
+        }
+        case GST_PLAY_MESSAGE_WARNING:{
+          state->warning = TRUE;
+          test_play_state_change_debug (player, STATE_CHANGE_WARNING,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_WARNING, &old_state,
+              state);
+          break;
+        }
+        case GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED:{
+          guint width, height;
+          gst_play_message_parse_video_dimensions_changed (msg, &width,
+              &height);
+
+          state->width = width;
+          state->height = height;
+          test_play_state_change_debug (player,
+              STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED, &old_state, state);
+          state->test_callback (player, STATE_CHANGE_VIDEO_DIMENSIONS_CHANGED,
+              &old_state, state);
+          break;
+        }
+        case GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED:{
+          GstPlayMediaInfo *media_info;
+          gst_play_message_parse_media_info_updated (msg, &media_info);
+
+          state->media_info = media_info;
+          test_play_state_change_debug (player,
+              STATE_CHANGE_MEDIA_INFO_UPDATED, &old_state, state);
+          state->test_callback (player, STATE_CHANGE_MEDIA_INFO_UPDATED,
+              &old_state, state);
+          break;
+        }
+        case GST_PLAY_MESSAGE_VOLUME_CHANGED:{
+          gdouble volume;
+          gst_play_message_parse_volume_changed (msg, &volume);
+          break;
+        }
+        case GST_PLAY_MESSAGE_MUTE_CHANGED:{
+          gboolean is_muted;
+          gst_play_message_parse_muted_changed (msg, &is_muted);
+          break;
+        }
+        case GST_PLAY_MESSAGE_SEEK_DONE:
+          state->seek_done = TRUE;
+          state->seek_done_position = gst_play_get_position (player);
+          test_play_state_change_debug (player, STATE_CHANGE_SEEK_DONE,
+              &old_state, state);
+          state->test_callback (player, STATE_CHANGE_SEEK_DONE, &old_state,
+              state);
+          break;
+      }
+    }
+    gst_message_unref (msg);
+    if (state->done)
+      break;
+  } while (1);
+  gst_object_unref (bus);
+}
+
 START_TEST (test_play_audio_eos)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_audio_video_eos_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/audio-short.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 10);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_audio_info (GstPlayerMediaInfo * media_info)
+test_audio_info (GstPlayMediaInfo * media_info)
 {
   gint i = 0;
   GList *list;
 
-  for (list = gst_player_media_info_get_audio_streams (media_info);
+  for (list = gst_play_media_info_get_audio_streams (media_info);
       list != NULL; list = list->next) {
-    GstPlayerStreamInfo *stream = (GstPlayerStreamInfo *) list->data;
-    GstPlayerAudioInfo *audio_info = (GstPlayerAudioInfo *) stream;
+    GstPlayStreamInfo *stream = (GstPlayStreamInfo *) list->data;
+    GstPlayAudioInfo *audio_info = (GstPlayAudioInfo *) stream;
 
-    fail_unless (gst_player_stream_info_get_tags (stream) != NULL);
-    fail_unless (gst_player_stream_info_get_caps (stream) != NULL);
-    fail_unless_equals_string (gst_player_stream_info_get_stream_type (stream),
+    fail_unless (gst_play_stream_info_get_tags (stream) != NULL);
+    fail_unless (gst_play_stream_info_get_caps (stream) != NULL);
+    fail_unless_equals_string (gst_play_stream_info_get_stream_type (stream),
         "audio");
 
     if (i == 0) {
-      fail_unless_equals_string (gst_player_stream_info_get_codec (stream),
+      fail_unless_equals_string (gst_play_stream_info_get_codec (stream),
           "MPEG-1 Layer 3 (MP3)");
-      fail_unless_equals_int (gst_player_audio_info_get_sample_rate
+      fail_unless_equals_int (gst_play_audio_info_get_sample_rate
           (audio_info), 48000);
-      fail_unless_equals_int (gst_player_audio_info_get_channels (audio_info),
-          2);
-      fail_unless_equals_int (gst_player_audio_info_get_max_bitrate
+      fail_unless_equals_int (gst_play_audio_info_get_channels (audio_info), 2);
+      fail_unless_equals_int (gst_play_audio_info_get_max_bitrate
           (audio_info), 192000);
-      fail_unless (gst_player_audio_info_get_language (audio_info) != NULL);
+      fail_unless (gst_play_audio_info_get_language (audio_info) != NULL);
     } else {
-      fail_unless_equals_string (gst_player_stream_info_get_codec (stream),
+      fail_unless_equals_string (gst_play_stream_info_get_codec (stream),
           "MPEG-4 AAC");
-      fail_unless_equals_int (gst_player_audio_info_get_sample_rate
+      fail_unless_equals_int (gst_play_audio_info_get_sample_rate
           (audio_info), 48000);
-      fail_unless_equals_int (gst_player_audio_info_get_channels (audio_info),
-          6);
-      fail_unless (gst_player_audio_info_get_language (audio_info) != NULL);
+      fail_unless_equals_int (gst_play_audio_info_get_channels (audio_info), 6);
+      fail_unless (gst_play_audio_info_get_language (audio_info) != NULL);
     }
 
     i++;
@@ -616,84 +573,84 @@ test_audio_info (GstPlayerMediaInfo * media_info)
 }
 
 static void
-test_video_info (GstPlayerMediaInfo * media_info)
+test_video_info (GstPlayMediaInfo * media_info)
 {
   GList *list;
 
-  for (list = gst_player_media_info_get_video_streams (media_info);
+  for (list = gst_play_media_info_get_video_streams (media_info);
       list != NULL; list = list->next) {
     gint fps_d, fps_n;
     guint par_d, par_n;
-    GstPlayerStreamInfo *stream = (GstPlayerStreamInfo *) list->data;
-    GstPlayerVideoInfo *video_info = (GstPlayerVideoInfo *) stream;
+    GstPlayStreamInfo *stream = (GstPlayStreamInfo *) list->data;
+    GstPlayVideoInfo *video_info = (GstPlayVideoInfo *) stream;
 
-    fail_unless (gst_player_stream_info_get_tags (stream) != NULL);
-    fail_unless (gst_player_stream_info_get_caps (stream) != NULL);
-    fail_unless_equals_int (gst_player_stream_info_get_index (stream), 0);
-    fail_unless (strstr (gst_player_stream_info_get_codec (stream),
+    fail_unless (gst_play_stream_info_get_tags (stream) != NULL);
+    fail_unless (gst_play_stream_info_get_caps (stream) != NULL);
+    fail_unless_equals_int (gst_play_stream_info_get_index (stream), 0);
+    fail_unless (strstr (gst_play_stream_info_get_codec (stream),
             "H.264") != NULL
-        || strstr (gst_player_stream_info_get_codec (stream), "H264") != NULL);
-    fail_unless_equals_int (gst_player_video_info_get_width (video_info), 320);
-    fail_unless_equals_int (gst_player_video_info_get_height (video_info), 240);
-    gst_player_video_info_get_framerate (video_info, &fps_n, &fps_d);
+        || strstr (gst_play_stream_info_get_codec (stream), "H264") != NULL);
+    fail_unless_equals_int (gst_play_video_info_get_width (video_info), 320);
+    fail_unless_equals_int (gst_play_video_info_get_height (video_info), 240);
+    gst_play_video_info_get_framerate (video_info, &fps_n, &fps_d);
     fail_unless_equals_int (fps_n, 24);
     fail_unless_equals_int (fps_d, 1);
-    gst_player_video_info_get_pixel_aspect_ratio (video_info, &par_n, &par_d);
+    gst_play_video_info_get_pixel_aspect_ratio (video_info, &par_n, &par_d);
     fail_unless_equals_int (par_n, 33);
     fail_unless_equals_int (par_d, 20);
   }
 }
 
 static void
-test_subtitle_info (GstPlayerMediaInfo * media_info)
+test_subtitle_info (GstPlayMediaInfo * media_info)
 {
   GList *list;
 
-  for (list = gst_player_media_info_get_subtitle_streams (media_info);
+  for (list = gst_play_media_info_get_subtitle_streams (media_info);
       list != NULL; list = list->next) {
-    GstPlayerStreamInfo *stream = (GstPlayerStreamInfo *) list->data;
-    GstPlayerSubtitleInfo *sub = (GstPlayerSubtitleInfo *) stream;
+    GstPlayStreamInfo *stream = (GstPlayStreamInfo *) list->data;
+    GstPlaySubtitleInfo *sub = (GstPlaySubtitleInfo *) stream;
 
-    fail_unless_equals_string (gst_player_stream_info_get_stream_type (stream),
+    fail_unless_equals_string (gst_play_stream_info_get_stream_type (stream),
         "subtitle");
-    fail_unless (gst_player_stream_info_get_tags (stream) != NULL);
-    fail_unless (gst_player_stream_info_get_caps (stream) != NULL);
-    fail_unless_equals_string (gst_player_stream_info_get_codec (stream),
+    fail_unless (gst_play_stream_info_get_tags (stream) != NULL);
+    fail_unless (gst_play_stream_info_get_caps (stream) != NULL);
+    fail_unless_equals_string (gst_play_stream_info_get_codec (stream),
         "Timed Text");
-    fail_unless (gst_player_subtitle_info_get_language (sub) != NULL);
+    fail_unless (gst_play_subtitle_info_get_language (sub) != NULL);
   }
 }
 
 static void
-test_media_info_object (GstPlayer * player, GstPlayerMediaInfo * media_info)
+test_media_info_object (GstPlay * player, GstPlayMediaInfo * media_info)
 {
   GList *list;
 
   /* global tag */
-  fail_unless (gst_player_media_info_is_seekable (media_info) == TRUE);
-  fail_unless (gst_player_media_info_get_tags (media_info) != NULL);
-  fail_unless_equals_string (gst_player_media_info_get_title (media_info),
+  fail_unless (gst_play_media_info_is_seekable (media_info) == TRUE);
+  fail_unless (gst_play_media_info_get_tags (media_info) != NULL);
+  fail_unless_equals_string (gst_play_media_info_get_title (media_info),
       "Sintel");
-  fail_unless_equals_string (gst_player_media_info_get_container_format
+  fail_unless_equals_string (gst_play_media_info_get_container_format
       (media_info), "Matroska");
-  fail_unless (gst_player_media_info_get_image_sample (media_info) == NULL);
-  fail_unless (strstr (gst_player_media_info_get_uri (media_info),
+  fail_unless (gst_play_media_info_get_image_sample (media_info) == NULL);
+  fail_unless (strstr (gst_play_media_info_get_uri (media_info),
           "sintel.mkv") != NULL);
 
   /* number of streams */
-  list = gst_player_media_info_get_stream_list (media_info);
+  list = gst_play_media_info_get_stream_list (media_info);
   fail_unless (list != NULL);
   fail_unless_equals_int (g_list_length (list), 10);
 
-  list = gst_player_media_info_get_video_streams (media_info);
+  list = gst_play_media_info_get_video_streams (media_info);
   fail_unless (list != NULL);
   fail_unless_equals_int (g_list_length (list), 1);
 
-  list = gst_player_media_info_get_audio_streams (media_info);
+  list = gst_play_media_info_get_audio_streams (media_info);
   fail_unless (list != NULL);
   fail_unless_equals_int (g_list_length (list), 2);
 
-  list = gst_player_media_info_get_subtitle_streams (media_info);
+  list = gst_play_media_info_get_subtitle_streams (media_info);
   fail_unless (list != NULL);
   fail_unless_equals_int (g_list_length (list), 7);
 
@@ -708,7 +665,7 @@ test_media_info_object (GstPlayer * player, GstPlayerMediaInfo * media_info)
 }
 
 static void
-test_play_media_info_cb (GstPlayer * player, TestPlayerStateChange change,
+test_play_media_info_cb (GstPlay * player, TestPlayerStateChange change,
     TestPlayerState * old_state, TestPlayerState * new_state)
 {
   gint completed = GPOINTER_TO_INT (new_state->test_data);
@@ -716,295 +673,285 @@ test_play_media_info_cb (GstPlayer * player, TestPlayerStateChange change,
   if (change == STATE_CHANGE_MEDIA_INFO_UPDATED) {
     test_media_info_object (player, new_state->media_info);
     new_state->test_data = GINT_TO_POINTER (completed + 1);
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   } else if (change == STATE_CHANGE_END_OF_STREAM ||
       change == STATE_CHANGE_ERROR) {
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
 START_TEST (test_play_media_info)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_media_info_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 1);
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_error_invalid_external_suburi_cb (GstPlayer * player,
-    TestPlayerStateChange change, TestPlayerState * old_state,
-    TestPlayerState * new_state)
-{
-  gint steps = GPOINTER_TO_INT (new_state->test_data);
-
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
-    gchar *suburi;
-
-    suburi = gst_filename_to_uri (TEST_PATH "/foo.srt", NULL);
-    fail_unless (suburi != NULL);
-
-    new_state->test_data = GINT_TO_POINTER (steps + 1);
-    /* load invalid suburi */
-    gst_player_set_subtitle_uri (player, suburi);
-    g_free (suburi);
-
-  } else if (steps && change == STATE_CHANGE_WARNING) {
-    new_state->test_data = GINT_TO_POINTER (steps + 1);
-    g_main_loop_quit (new_state->loop);
-
-  } else if (change == STATE_CHANGE_END_OF_STREAM ||
-      change == STATE_CHANGE_ERROR)
-    g_main_loop_quit (new_state->loop);
-}
-
-static void
-test_play_stream_disable_cb (GstPlayer * player,
+test_play_stream_disable_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
   gint steps = GPOINTER_TO_INT (new_state->test_data) & 0xf;
   gint mask = GPOINTER_TO_INT (new_state->test_data) & 0xf0;
 
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
+  if (new_state->state == GST_PLAY_STATE_PLAYING && !steps) {
     new_state->test_data = GINT_TO_POINTER (0x10 + steps + 1);
-    gst_player_set_audio_track_enabled (player, FALSE);
+    gst_play_set_audio_track_enabled (player, FALSE);
 
   } else if (mask == 0x10 && change == STATE_CHANGE_POSITION_UPDATED) {
-    GstPlayerAudioInfo *audio;
+    GstPlayAudioInfo *audio;
 
-    audio = gst_player_get_current_audio_track (player);
+    audio = gst_play_get_current_audio_track (player);
     fail_unless (audio == NULL);
     new_state->test_data = GINT_TO_POINTER (0x20 + steps + 1);
-    gst_player_set_subtitle_track_enabled (player, FALSE);
+    gst_play_set_subtitle_track_enabled (player, FALSE);
 
   } else if (mask == 0x20 && change == STATE_CHANGE_POSITION_UPDATED) {
-    GstPlayerSubtitleInfo *sub;
+    GstPlaySubtitleInfo *sub;
 
-    sub = gst_player_get_current_subtitle_track (player);
+    sub = gst_play_get_current_subtitle_track (player);
     fail_unless (sub == NULL);
     new_state->test_data = GINT_TO_POINTER (0x30 + steps + 1);
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
 
   } else if (change == STATE_CHANGE_END_OF_STREAM ||
       change == STATE_CHANGE_ERROR) {
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
 START_TEST (test_play_stream_disable)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_stream_disable_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 0x33);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_stream_switch_audio_cb (GstPlayer * player,
+test_play_stream_switch_audio_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
   gint steps = GPOINTER_TO_INT (new_state->test_data);
 
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
+  if (new_state->state == GST_PLAY_STATE_PLAYING && !steps) {
     gint ret;
 
     new_state->test_data = GINT_TO_POINTER (steps + 1);
-    ret = gst_player_set_audio_track (player, 1);
+    ret = gst_play_set_audio_track (player, 1);
     fail_unless_equals_int (ret, 1);
 
   } else if (steps && change == STATE_CHANGE_POSITION_UPDATED) {
     gint index;
-    GstPlayerAudioInfo *audio;
+    GstPlayAudioInfo *audio;
 
-    audio = gst_player_get_current_audio_track (player);
+    audio = gst_play_get_current_audio_track (player);
     fail_unless (audio != NULL);
-    index = gst_player_stream_info_get_index ((GstPlayerStreamInfo *) audio);
+    index = gst_play_stream_info_get_index ((GstPlayStreamInfo *) audio);
     fail_unless_equals_int (index, 1);
     g_object_unref (audio);
 
     new_state->test_data = GINT_TO_POINTER (steps + 1);
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
 
   } else if (change == STATE_CHANGE_END_OF_STREAM ||
       change == STATE_CHANGE_ERROR) {
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
 START_TEST (test_play_stream_switch_audio)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_stream_switch_audio_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_stream_switch_subtitle_cb (GstPlayer * player,
+test_play_stream_switch_subtitle_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
   gint steps = GPOINTER_TO_INT (new_state->test_data);
 
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
+  if (new_state->state == GST_PLAY_STATE_PLAYING && !steps) {
     gint ret;
 
     new_state->test_data = GINT_TO_POINTER (steps + 1);
-    ret = gst_player_set_subtitle_track (player, 5);
+    ret = gst_play_set_subtitle_track (player, 5);
     fail_unless_equals_int (ret, 1);
 
   } else if (steps && change == STATE_CHANGE_POSITION_UPDATED) {
     gint index;
-    GstPlayerSubtitleInfo *sub;
+    GstPlaySubtitleInfo *sub;
 
-    sub = gst_player_get_current_subtitle_track (player);
+    sub = gst_play_get_current_subtitle_track (player);
     fail_unless (sub != NULL);
-    index = gst_player_stream_info_get_index ((GstPlayerStreamInfo *) sub);
+    index = gst_play_stream_info_get_index ((GstPlayStreamInfo *) sub);
     fail_unless_equals_int (index, 5);
     g_object_unref (sub);
 
     new_state->test_data = GINT_TO_POINTER (steps + 1);
-    g_main_loop_quit (new_state->loop);
-
+    new_state->done = TRUE;
   } else if (change == STATE_CHANGE_END_OF_STREAM ||
       change == STATE_CHANGE_ERROR) {
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
 START_TEST (test_play_stream_switch_subtitle)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_stream_switch_subtitle_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
+static void
+test_play_error_invalid_external_suburi_cb (GstPlay * player,
+    TestPlayerStateChange change, TestPlayerState * old_state,
+    TestPlayerState * new_state)
+{
+  gint steps = GPOINTER_TO_INT (new_state->test_data);
+
+  if (new_state->state == GST_PLAY_STATE_PLAYING && !steps) {
+    gchar *suburi;
+
+    suburi = gst_filename_to_uri (TEST_PATH "/foo.srt", NULL);
+    fail_unless (suburi != NULL);
+
+    new_state->test_data = GINT_TO_POINTER (steps + 1);
+    /* load invalid suburi */
+    gst_play_set_subtitle_uri (player, suburi);
+    g_free (suburi);
+
+  } else if (steps && change == STATE_CHANGE_WARNING) {
+    new_state->test_data = GINT_TO_POINTER (steps + 1);
+    new_state->done = TRUE;
+  } else if (change == STATE_CHANGE_END_OF_STREAM ||
+      change == STATE_CHANGE_ERROR) {
+    new_state->test_data = GINT_TO_POINTER (steps + 1);
+    new_state->done = TRUE;
+  }
+}
+
 START_TEST (test_play_error_invalid_external_suburi)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_error_invalid_external_suburi_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/audio-video.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
@@ -1012,26 +959,26 @@ END_TEST;
 static gboolean
 has_subtitle_stream (TestPlayerState * new_state)
 {
-  if (gst_player_media_info_get_subtitle_streams (new_state->media_info))
+  if (gst_play_media_info_get_subtitle_streams (new_state->media_info))
     return TRUE;
 
   return FALSE;
 }
 
 static void
-test_play_external_suburi_cb (GstPlayer * player,
+test_play_external_suburi_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
   gint steps = GPOINTER_TO_INT (new_state->test_data);
 
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
+  if (new_state->state == GST_PLAY_STATE_PLAYING && !steps) {
     gchar *suburi;
 
     suburi = gst_filename_to_uri (TEST_PATH "/test_sub.srt", NULL);
     fail_unless (suburi != NULL);
 
-    gst_player_set_subtitle_uri (player, suburi);
+    gst_play_set_subtitle_uri (player, suburi);
     g_free (suburi);
     new_state->test_data = GINT_TO_POINTER (steps + 1);
 
@@ -1039,7 +986,7 @@ test_play_external_suburi_cb (GstPlayer * player,
       has_subtitle_stream (new_state)) {
     gchar *current_suburi, *suburi;
 
-    current_suburi = gst_player_get_subtitle_uri (player);
+    current_suburi = gst_play_get_subtitle_uri (player);
     fail_unless (current_suburi != NULL);
     suburi = gst_filename_to_uri (TEST_PATH "/test_sub.srt", NULL);
     fail_unless (suburi != NULL);
@@ -1049,76 +996,74 @@ test_play_external_suburi_cb (GstPlayer * player,
     g_free (current_suburi);
     g_free (suburi);
     new_state->test_data = GINT_TO_POINTER (steps + 1);
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
 
   } else if (change == STATE_CHANGE_END_OF_STREAM ||
       change == STATE_CHANGE_ERROR)
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
 }
 
 START_TEST (test_play_external_suburi)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_external_suburi_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/audio-video.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_rate_cb (GstPlayer * player,
+test_play_rate_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
   gint steps = GPOINTER_TO_INT (new_state->test_data) & 0xf;
   gint mask = GPOINTER_TO_INT (new_state->test_data) & 0xf0;
 
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
+  if (new_state->state == GST_PLAY_STATE_PLAYING && !steps) {
     guint64 dur = -1, pos = -1;
 
     g_object_get (player, "position", &pos, "duration", &dur, NULL);
     pos = pos + dur * 0.2;      /* seek 20% */
-    gst_player_seek (player, pos);
+    gst_play_seek (player, pos);
 
     /* default rate should be 1.0 */
-    fail_unless_equals_double (gst_player_get_rate (player), 1.0);
+    fail_unless_equals_double (gst_play_get_rate (player), 1.0);
     new_state->test_data = GINT_TO_POINTER (mask + steps + 1);
   } else if (change == STATE_CHANGE_END_OF_STREAM ||
       change == STATE_CHANGE_ERROR) {
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   } else if (steps == 1 && change == STATE_CHANGE_SEEK_DONE) {
     if (mask == 0x10)
-      gst_player_set_rate (player, 1.5);
+      gst_play_set_rate (player, 1.5);
     else if (mask == 0x20)
-      gst_player_set_rate (player, -1.0);
+      gst_play_set_rate (player, -1.0);
 
     new_state->test_data = GINT_TO_POINTER (mask + steps + 1);
   } else if (steps && (change == STATE_CHANGE_POSITION_UPDATED)) {
     if (steps == 10) {
-      g_main_loop_quit (new_state->loop);
+      new_state->done = TRUE;
     } else {
       if (mask == 0x10 && (new_state->position > old_state->position))
         new_state->test_data = GINT_TO_POINTER (mask + steps + 1);
@@ -1130,102 +1075,96 @@ test_play_rate_cb (GstPlayer * player,
 
 START_TEST (test_play_forward_rate)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_rate_cb;
   state.test_data = GINT_TO_POINTER (0x10);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/audio.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & 0xf, 10);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 START_TEST (test_play_backward_rate)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_rate_cb;
   state.test_data = GINT_TO_POINTER (0x20);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/audio.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & 0xf, 10);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 START_TEST (test_play_audio_video_eos)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_audio_video_eos_cb;
   state.test_data = GINT_TO_POINTER (0x10);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/audio-video-short.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & (~0x10), 10);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_error_invalid_uri_cb (GstPlayer * player,
+test_play_error_invalid_uri_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
@@ -1239,8 +1178,8 @@ test_play_error_invalid_uri_cb (GstPlayer * player,
       break;
     case 1:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_STOPPED);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_BUFFERING);
       new_state->test_data = GINT_TO_POINTER (step + 1);
       break;
     case 2:
@@ -1249,10 +1188,10 @@ test_play_error_invalid_uri_cb (GstPlayer * player,
       break;
     case 3:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_STOPPED);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_BUFFERING);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_STOPPED);
       new_state->test_data = GINT_TO_POINTER (step + 1);
-      g_main_loop_quit (new_state->loop);
+      new_state->done = TRUE;
       break;
     default:
       fail ();
@@ -1262,34 +1201,32 @@ test_play_error_invalid_uri_cb (GstPlayer * player,
 
 START_TEST (test_play_error_invalid_uri)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_error_invalid_uri_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
-  gst_player_set_uri (player, "foo://bar");
+  gst_play_set_uri (player, "foo://bar");
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 4);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_error_invalid_uri_and_play_cb (GstPlayer * player,
+test_play_error_invalid_uri_and_play_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
@@ -1304,8 +1241,8 @@ test_play_error_invalid_uri_and_play_cb (GstPlayer * player,
       break;
     case 1:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_STOPPED);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_BUFFERING);
       new_state->test_data = GINT_TO_POINTER (step + 1);
       break;
     case 2:
@@ -1314,16 +1251,16 @@ test_play_error_invalid_uri_and_play_cb (GstPlayer * player,
       break;
     case 3:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_STOPPED);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_BUFFERING);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_STOPPED);
       new_state->test_data = GINT_TO_POINTER (step + 1);
 
       uri = gst_filename_to_uri (TEST_PATH "/audio-short.ogg", NULL);
       fail_unless (uri != NULL);
-      gst_player_set_uri (player, uri);
+      gst_play_set_uri (player, uri);
       g_free (uri);
 
-      gst_player_play (player);
+      gst_play_play (player);
       break;
     case 4:
       fail_unless_equals_int (change, STATE_CHANGE_URI_LOADED);
@@ -1332,8 +1269,8 @@ test_play_error_invalid_uri_and_play_cb (GstPlayer * player,
       break;
     case 5:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_STOPPED);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_BUFFERING);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_STOPPED);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_BUFFERING);
       new_state->test_data = GINT_TO_POINTER (step + 1);
       break;
     case 6:
@@ -1347,26 +1284,21 @@ test_play_error_invalid_uri_and_play_cb (GstPlayer * player,
       new_state->test_data = GINT_TO_POINTER (step + 1);
       break;
     case 8:
-      fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
-      new_state->test_data = GINT_TO_POINTER (step + 1);
-      break;
-    case 9:
       fail_unless_equals_int (change, STATE_CHANGE_DURATION_CHANGED);
       fail_unless_equals_uint64 (new_state->duration,
           G_GUINT64_CONSTANT (464399092));
       new_state->test_data = GINT_TO_POINTER (step + 1);
       break;
-    case 10:
-      fail_unless_equals_int (change, STATE_CHANGE_POSITION_UPDATED);
-      fail_unless_equals_uint64 (new_state->position, G_GUINT64_CONSTANT (0));
+    case 9:
+      fail_unless_equals_int (change, STATE_CHANGE_MEDIA_INFO_UPDATED);
       new_state->test_data = GINT_TO_POINTER (step + 1);
       break;
-    case 11:
+    case 10:
       fail_unless_equals_int (change, STATE_CHANGE_STATE_CHANGED);
-      fail_unless_equals_int (old_state->state, GST_PLAYER_STATE_BUFFERING);
-      fail_unless_equals_int (new_state->state, GST_PLAYER_STATE_PLAYING);
+      fail_unless_equals_int (old_state->state, GST_PLAY_STATE_BUFFERING);
+      fail_unless_equals_int (new_state->state, GST_PLAY_STATE_PLAYING);
       new_state->test_data = GINT_TO_POINTER (step + 1);
-      g_main_loop_quit (new_state->loop);
+      new_state->done = TRUE;
       break;
     default:
       fail ();
@@ -1376,180 +1308,169 @@ test_play_error_invalid_uri_and_play_cb (GstPlayer * player,
 
 START_TEST (test_play_error_invalid_uri_and_play)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_error_invalid_uri_and_play_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
-  gst_player_set_uri (player, "foo://bar");
+  gst_play_set_uri (player, "foo://bar");
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
-  fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 12);
+  fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 11);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_seek_done_cb (GstPlayer * player,
+test_play_seek_done_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
   gint step = GPOINTER_TO_INT (new_state->test_data) & (~0x10);
 
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !step) {
-    gst_player_seek (player, 0);
+  if (new_state->state == GST_PLAY_STATE_PAUSED && !step) {
+    gst_play_seek (player, 0);
     new_state->test_data = GINT_TO_POINTER (step + 1);
-  } else if (change == STATE_CHANGE_SEEK_DONE || change == STATE_CHANGE_ERROR) {
+  } else if (change == STATE_CHANGE_SEEK_DONE && step == 1) {
     fail_unless_equals_int (change, STATE_CHANGE_SEEK_DONE);
     fail_unless_equals_uint64 (new_state->seek_done_position,
         G_GUINT64_CONSTANT (0));
     new_state->test_data = GINT_TO_POINTER (step + 1);
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
 START_TEST (test_play_audio_video_seek_done)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_seek_done_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/audio-video.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_pause (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data) & (~0x10), 2);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_play_position_update_interval_cb (GstPlayer * player,
+test_play_position_update_interval_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
-  static gboolean do_quit = TRUE;
-  static GstClockTime last_position = GST_CLOCK_TIME_NONE;
-
   gint steps = GPOINTER_TO_INT (new_state->test_data);
 
-  if (new_state->state == GST_PLAYER_STATE_PLAYING && !steps) {
+  if (new_state->state == GST_PLAY_STATE_PLAYING && !steps) {
     new_state->test_data = GINT_TO_POINTER (steps + 1);
   } else if (steps && change == STATE_CHANGE_POSITION_UPDATED) {
-    GstClockTime position = gst_player_get_position (player);
+    GstStructure *config = gst_play_get_config (player);
+    guint update_interval =
+        gst_play_config_get_position_update_interval (config);
+    GstClockTime position = gst_play_get_position (player);
     new_state->test_data = GINT_TO_POINTER (steps + 1);
 
-    if (GST_CLOCK_TIME_IS_VALID (last_position)) {
-      GstClockTime interval = GST_CLOCK_DIFF (last_position, position);
+    gst_structure_free (config);
+    if (GST_CLOCK_TIME_IS_VALID (old_state->last_position)) {
+      GstClockTime delta = GST_CLOCK_DIFF (old_state->last_position, position);
       GST_DEBUG_OBJECT (player,
-          "position update interval: %" GST_TIME_FORMAT "\n",
-          GST_TIME_ARGS (interval));
-      fail_unless (interval > (590 * GST_MSECOND)
-          && interval < (610 * GST_MSECOND));
+          "current delta: %" GST_TIME_FORMAT " interval: %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (delta), GST_TIME_ARGS (update_interval));
+
+      if (update_interval > 10) {
+        fail_unless (delta > ((update_interval - 10) * GST_MSECOND)
+            && delta < ((update_interval + 10) * GST_MSECOND));
+      }
     }
 
-    last_position = position;
+    new_state->last_position = position;
 
-    if (do_quit && position >= 2000 * GST_MSECOND) {
-      do_quit = FALSE;
-      g_main_loop_quit (new_state->loop);
+    if (position >= 2000 * GST_MSECOND) {
+      new_state->done = TRUE;
     }
   } else if (change == STATE_CHANGE_END_OF_STREAM ||
       change == STATE_CHANGE_ERROR) {
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
-static gboolean
-quit_loop_cb (gpointer user_data)
-{
-  GMainLoop *loop = user_data;
-  g_main_loop_quit (loop);
-
-  return G_SOURCE_REMOVE;
-}
-
 START_TEST (test_play_position_update_interval)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
   GstStructure *config;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_play_position_update_interval_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
-  config = gst_player_get_config (player);
-  gst_player_config_set_position_update_interval (config, 600);
-  gst_player_set_config (player, config);
+  config = gst_play_get_config (player);
+  gst_play_config_set_position_update_interval (config, 600);
+  gst_play_set_config (player, config);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 5);
 
   /* Disable position updates */
-  gst_player_stop (player);
+  gst_play_stop (player);
 
-  config = gst_player_get_config (player);
-  gst_player_config_set_position_update_interval (config, 0);
-  gst_player_set_config (player, config);
+  config = gst_play_get_config (player);
+  gst_play_config_set_position_update_interval (config, 0);
+  gst_play_set_config (player, config);
+  state.last_position = GST_CLOCK_TIME_NONE;
 
-  g_timeout_add (2000, quit_loop_cb, state.loop);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
 
-  fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 5);
+  fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 6);
 
   stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
 
 static void
-test_restart_cb (GstPlayer * player,
+test_restart_cb (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
@@ -1559,14 +1480,14 @@ test_restart_cb (GstPlayer * player,
     fail_unless (g_str_has_suffix (new_state->uri_loaded, "sintel.mkv"));
     new_state->test_data = GINT_TO_POINTER (steps + 1);
   } else if (change == STATE_CHANGE_STATE_CHANGED
-      && new_state->state == GST_PLAYER_STATE_BUFFERING) {
+      && new_state->state == GST_PLAY_STATE_BUFFERING) {
     new_state->test_data = GINT_TO_POINTER (steps + 1);
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
 static void
-test_restart_cb2 (GstPlayer * player,
+test_restart_cb2 (GstPlay * player,
     TestPlayerStateChange change, TestPlayerState * old_state,
     TestPlayerState * new_state)
 {
@@ -1576,35 +1497,34 @@ test_restart_cb2 (GstPlayer * player,
     fail_unless (g_str_has_suffix (new_state->uri_loaded, "audio-short.ogg"));
     new_state->test_data = GINT_TO_POINTER (steps + 1);
   } else if (change == STATE_CHANGE_STATE_CHANGED
-      && new_state->state == GST_PLAYER_STATE_BUFFERING) {
+      && new_state->state == GST_PLAY_STATE_BUFFERING) {
     new_state->test_data = GINT_TO_POINTER (steps + 1);
-    g_main_loop_quit (new_state->loop);
+    new_state->done = TRUE;
   }
 }
 
 
 START_TEST (test_restart)
 {
-  GstPlayer *player;
+  GstPlay *player;
   TestPlayerState state;
   gchar *uri;
 
   memset (&state, 0, sizeof (state));
-  state.loop = g_main_loop_new (NULL, FALSE);
   state.test_callback = test_restart_cb;
   state.test_data = GINT_TO_POINTER (0);
 
-  player = test_player_new (&state);
+  player = test_play_new (&state);
 
   fail_unless (player != NULL);
 
   uri = gst_filename_to_uri (TEST_PATH "/sintel.mkv", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
   stop_player (player, &state);
 
@@ -1614,16 +1534,15 @@ START_TEST (test_restart)
 
   uri = gst_filename_to_uri (TEST_PATH "/audio-short.ogg", NULL);
   fail_unless (uri != NULL);
-  gst_player_set_uri (player, uri);
+  gst_play_set_uri (player, uri);
   g_free (uri);
 
-  gst_player_play (player);
-  g_main_loop_run (state.loop);
+  gst_play_play (player);
+  process_play_messages (player, &state);
   fail_unless_equals_int (GPOINTER_TO_INT (state.test_data), 2);
   stop_player (player, &state);
 
   g_object_unref (player);
-  g_main_loop_unref (state.loop);
 }
 
 END_TEST;
@@ -1631,59 +1550,68 @@ END_TEST;
 #define TEST_USER_AGENT "test user agent"
 
 static void
-source_setup_cb (GstElement * playbin, GstElement * source, GMainLoop * loop)
+test_user_agent_cb (GstPlay * player,
+    TestPlayerStateChange change, TestPlayerState * old_state,
+    TestPlayerState * new_state)
 {
-  gchar *user_agent;
-
-  g_object_get (source, "user-agent", &user_agent, NULL);
-  fail_unless_equals_string (user_agent, TEST_USER_AGENT);
-  g_free (user_agent);
-
-  g_main_loop_quit (loop);
+  /* React on error message, which is a hack. If we were playing a valid asset
+     hosted on a local/mock server, we could instead react on state change
+     notifications. */
+  if (change == STATE_CHANGE_ERROR) {
+    GstElement *pipeline;
+    GstElement *source;
+    gchar *user_agent;
+
+    pipeline = gst_play_get_pipeline (player);
+    source = gst_bin_get_by_name (GST_BIN_CAST (pipeline), "source");
+    g_object_get (source, "user-agent", &user_agent, NULL);
+    fail_unless_equals_string (user_agent, TEST_USER_AGENT);
+    g_free (user_agent);
+    gst_object_unref (source);
+    gst_object_unref (pipeline);
+    new_state->done = TRUE;
+  }
 }
 
 START_TEST (test_user_agent)
 {
-  GstPlayer *player;
-  GMainLoop *loop;
-  GstElement *pipeline;
+  GstPlay *player;
   GstStructure *config;
   gchar *user_agent;
+  TestPlayerState state;
 
-  loop = g_main_loop_new (NULL, FALSE);
-  player = gst_player_new (NULL, NULL);
+  memset (&state, 0, sizeof (state));
+  state.test_callback = test_user_agent_cb;
+  state.test_data = GINT_TO_POINTER (0);
+
+  player = gst_play_new (NULL);
   fail_unless (player != NULL);
 
-  gst_player_set_uri (player, "http://badger.com/test.mkv");
+  /* FIXME: This test should rely on a HTTP mock (or local) server. */
+  gst_play_set_uri (player, "http://example.com/test.mkv");
 
-  config = gst_player_get_config (player);
-  gst_player_config_set_user_agent (config, TEST_USER_AGENT);
+  config = gst_play_get_config (player);
+  gst_play_config_set_user_agent (config, TEST_USER_AGENT);
 
-  user_agent = gst_player_config_get_user_agent (config);
+  user_agent = gst_play_config_get_user_agent (config);
   fail_unless_equals_string (user_agent, TEST_USER_AGENT);
   g_free (user_agent);
 
-  gst_player_set_config (player, config);
-
-  pipeline = gst_player_get_pipeline (player);
-  g_signal_connect (pipeline, "source-setup", G_CALLBACK (source_setup_cb),
-      loop);
-
-  gst_player_pause (player);
-  g_main_loop_run (loop);
+  gst_play_set_config (player, config);
 
-  gst_object_unref (pipeline);
+  gst_play_pause (player);
+  process_play_messages (player, &state);
 
+  stop_player (player, &state);
   g_object_unref (player);
-  g_main_loop_unref (loop);
 }
 
 END_TEST;
 
 static Suite *
-player_suite (void)
+play_suite (void)
 {
-  Suite *s = suite_create ("GstPlayer");
+  Suite *s = suite_create ("GstPlay");
 
   TCase *tc_general = tcase_create ("general");
 
@@ -1701,35 +1629,32 @@ player_suite (void)
   tcase_add_test (tc_general, test_set_and_get_uri);
   tcase_add_test (tc_general, test_set_and_get_position_update_interval);
 
-  /* Skip playback tests for now.
-   * See https://bugzilla.gnome.org/show_bug.cgi?id=787374 */
-
 #ifdef HAVE_VALGRIND
   if (RUNNING_ON_VALGRIND) {
   } else
 #endif
   {
-    tcase_skip_broken_test (tc_general, test_play_position_update_interval);
+    tcase_add_test (tc_general, test_play_position_update_interval);
   }
-  tcase_skip_broken_test (tc_general, test_play_audio_eos);
-  tcase_skip_broken_test (tc_general, test_play_audio_video_eos);
-  tcase_skip_broken_test (tc_general, test_play_error_invalid_uri);
-  tcase_skip_broken_test (tc_general, test_play_error_invalid_uri_and_play);
-  tcase_skip_broken_test (tc_general, test_play_media_info);
-  tcase_skip_broken_test (tc_general, test_play_stream_disable);
-  tcase_skip_broken_test (tc_general, test_play_stream_switch_audio);
-  tcase_skip_broken_test (tc_general, test_play_stream_switch_subtitle);
-  tcase_skip_broken_test (tc_general, test_play_error_invalid_external_suburi);
-  tcase_skip_broken_test (tc_general, test_play_external_suburi);
-  tcase_skip_broken_test (tc_general, test_play_forward_rate);
-  tcase_skip_broken_test (tc_general, test_play_backward_rate);
-  tcase_skip_broken_test (tc_general, test_play_audio_video_seek_done);
-  tcase_skip_broken_test (tc_general, test_restart);
-  tcase_skip_broken_test (tc_general, test_user_agent);
+  tcase_add_test (tc_general, test_play_audio_eos);
+  tcase_add_test (tc_general, test_play_audio_video_eos);
+  tcase_add_test (tc_general, test_play_error_invalid_uri);
+  tcase_add_test (tc_general, test_play_error_invalid_uri_and_play);
+  tcase_add_test (tc_general, test_play_media_info);
+  tcase_add_test (tc_general, test_play_stream_disable);
+  tcase_add_test (tc_general, test_play_stream_switch_audio);
+  tcase_add_test (tc_general, test_play_stream_switch_subtitle);
+  tcase_add_test (tc_general, test_play_error_invalid_external_suburi);
+  tcase_add_test (tc_general, test_play_external_suburi);
+  tcase_add_test (tc_general, test_play_forward_rate);
+  tcase_add_test (tc_general, test_play_backward_rate);
+  tcase_add_test (tc_general, test_play_audio_video_seek_done);
+  tcase_add_test (tc_general, test_restart);
+  tcase_add_test (tc_general, test_user_agent);
 
   suite_add_tcase (s, tc_general);
 
   return s;
 }
 
-GST_CHECK_MAIN (player)
+GST_CHECK_MAIN (play)
index c7d90c3..fc51ff6 100644 (file)
@@ -15,7 +15,7 @@ exif_dep = dependency('libexif', version : '>= 0.6.16', required : false)
 # Since nalutils API is internal, need to build it again
 nalutils_dep = gstcodecparsers_dep.partial_dependency (compile_args: true, includes: true)
 
-enable_gst_player_tests = get_option('gst_player_tests')
+enable_gst_play_tests = get_option('gst_play_tests')
 
 # name, condition when to skip the test and extra dependencies
 base_tests = [
@@ -69,7 +69,7 @@ base_tests = [
   [['libs/mpegts.c'], false, [gstmpegts_dep]],
   [['libs/mpegvideoparser.c'], false, [gstcodecparsers_dep]],
   [['libs/planaraudioadapter.c'], false, [gstbadaudio_dep]],
-  [['libs/player.c'], not enable_gst_player_tests, [gstplayer_dep]],
+  [['libs/play.c'], not enable_gst_play_tests, [gstplay_dep]],
   [['libs/vc1parser.c'], false, [gstcodecparsers_dep]],
   [['libs/vp8parser.c'], false, [gstcodecparsers_dep]],
   [['libs/vp9parser.c'], false, [gstcodecparsers_dep]],
@@ -229,6 +229,6 @@ if have_orcc and orc_test_dep.found()
   endforeach
 endif
 
-if enable_gst_player_tests
+if enable_gst_play_tests
   subdir ('media')
 endif