X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=mafw-gst-subtitles-renderer%2Ftests%2Fcheck-mafw-gst-renderer.c;fp=mafw-gst-subtitles-renderer%2Ftests%2Fcheck-mafw-gst-renderer.c;h=ae4982b3fbf0cf14963338c9cb3666c09689d145;hb=be2c98fb83895d10ac44af7b9a9c3e00ca54bf49;hp=0000000000000000000000000000000000000000;hpb=c2bbb2bb3bead80144e2dda3ccd40599e4a2b48d;p=mafwsubrenderer diff --git a/mafw-gst-subtitles-renderer/tests/check-mafw-gst-renderer.c b/mafw-gst-subtitles-renderer/tests/check-mafw-gst-renderer.c new file mode 100644 index 0000000..ae4982b --- /dev/null +++ b/mafw-gst-subtitles-renderer/tests/check-mafw-gst-renderer.c @@ -0,0 +1,4174 @@ +/* + * This file is a part of MAFW + * + * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved. + * + * Contact: Visa Smolander + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +/* + * check-gst-renderer.c + * + * Gst Renderer unit tests + * + * Copyright (C) 2007 Nokia Corporation + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "config.h" + +#include "mafw-gst-renderer.h" +#include "mafw-mock-playlist.h" +#include "mafw-mock-pulseaudio.h" + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "check-mafw-gstreamer-renderer" + +#define SAMPLE_AUDIO_CLIP "test.wav" +#define SAMPLE_VIDEO_CLIP "test.avi" +#define SAMPLE_IMAGE "testframe.png" + +/* Base timeout used when waiting for state transitions or execution of + user function callbacks associated to each mafw-renderer function */ +#define DEFAULT_WAIT_TOUT 2000 + +/* EOS timeout must be longer than the clip duration */ +#define EOS_TIMEOUT 7000 + +SRunner *configure_tests(void); + +typedef struct { + gint index; + MafwPlayState state; +} RendererInfo; + +typedef struct { + gboolean called; + gboolean error; + gint err_code; + gchar *err_msg; + gint seek_position; + gboolean error_signal_expected; + GError *error_signal_received; + const gchar *property_expected; + GValue *property_received; +} CallbackInfo; + +typedef struct { + const gchar *expected_key; + GValue *value; +} MetadataChangedInfo; + +typedef struct { + const gchar *expected; + GValue *received; +} PropertyChangedInfo; + +typedef struct { + gboolean requested; + gboolean received; + gfloat value; +} BufferingInfo; + +static gint wait_tout_val; + +/* Globals. */ + +static MafwRenderer *g_gst_renderer = NULL; + +/* Error messages. */ + +static const gchar *callback_err_msg = "Error received when %s: (%d) %s"; +static const gchar *callback_no_err_msg = "No error received when %s: (%d) %s"; +static const gchar *no_callback_msg = "We forgot to call the user callback"; +static const gchar *state_err_msg = "Call %s didn't change state to %s. " \ +"Current state is: %d"; +static const gchar *index_err_msg = "Actual index is (%d) instead of the " \ +"expected index (%d)"; + + +/*---------------------------------------------------------------------------- + Signal handlers + ----------------------------------------------------------------------------*/ + + +static void error_cb(MafwRenderer *s, GQuark domain, gint code, gchar *msg, + gpointer user_data) +{ + CallbackInfo* c = (CallbackInfo*) user_data; + + /* "MafwExtension::error" signal handler */ + if (user_data == NULL || !c->error_signal_expected) { + fail("Signal error received: (%d) %s", code, msg); + } else { + if (c->error_signal_received != NULL) { + fail("Error received already initialized"); + } else { + c->error_signal_received = + g_error_new_literal(domain, code, msg); + } + } +} + +static void state_changed_cb(MafwRenderer *s, MafwPlayState state, + gpointer user_data) +{ + /* "MafwRenderer::state-changed" signal handler */ + RendererInfo *si = (RendererInfo *) user_data; + gchar *states[] = {"Stopped","Playing","Paused","Transitioning"}; + + si->state = state; + g_debug("state changed (%s) ---", states[state]); +} + +static gboolean media_changed_called; + +static void media_changed_cb(MafwRenderer *s, gint index, gchar *objectid, + gpointer user_data) +{ + /* "MafwRenderer::media-changed" signal handler */ + RendererInfo *si = (RendererInfo *) user_data; + + si->index = index; + g_debug("media changed (%d) ---", index); + media_changed_called = TRUE; +} +static void playlist_changed_cb (MafwRenderer *self, + GObject *playlist, + gpointer user_data) +{ + g_debug("playlist changed"); + fail_if(media_changed_called, "At first playlist-changed should be called"); +} + +static void metadata_changed_cb(MafwRenderer *self, const gchar *key, + GValueArray *value, gpointer user_data) +{ + MetadataChangedInfo *m = user_data; + + if (m->expected_key != NULL && strcmp(key, m->expected_key) == 0) + { + GValue *original; + + original = g_value_array_get_nth(value, 0); + + m->value = g_new0(GValue, 1); + g_value_init(m->value, G_VALUE_TYPE(original)); + g_value_copy(original, m->value); + } +} + +static void property_changed_cb(MafwExtension *extension, const gchar *name, + const GValue *value, gpointer user_data) +{ + PropertyChangedInfo* p = (PropertyChangedInfo*) user_data; + gchar *value_string; + + value_string = g_strdup_value_contents(value); + + g_debug("property_changed_cb: %s (%s)", name, value_string); + g_free(value_string); + + if (p->expected != NULL && + strcmp(p->expected, name) == 0) { + p->received = g_new0(GValue, 1); + g_value_init(p->received, G_VALUE_TYPE(value)); + g_value_copy(value, p->received); + } +} + +static void buffering_info_cb(MafwRenderer *self, gfloat status, + gpointer user_data) +{ + BufferingInfo *b = user_data; + + if (b->requested) { + b->received = TRUE; + b->value = status; + } +} + +/*---------------------------------------------------------------------------- + Function callbacks + ----------------------------------------------------------------------------*/ + + +static void status_cb(MafwRenderer* renderer, MafwPlaylist* playlist, guint index, + MafwPlayState state, + const gchar* object_id, + gpointer user_data, + const GError *error) +{ + /* MafwRendererStatusCB */ + RendererInfo* s = (RendererInfo*) user_data; + g_assert(s != NULL); + + if (error != NULL) { + fail("Error received while trying to get renderer status: (%d) %s", + error->code, error->message); + } + s->state = state; + +} + +static void playback_cb(MafwRenderer* renderer, gpointer user_data, const GError* error) +{ + /* MafwRendererPlaybackCB: + + Called after mafw_renderer_play(), mafw_renderer_play_uri(), + mafw_renderer_play_object(), mafw_renderer_stop(), mafw_renderer_pause(), + mafw_renderer_resume(), mafw_renderer_next(), mafw_renderer_previous() or + mafw_renderer_goto_index() has been called. */ + CallbackInfo* c = (CallbackInfo*) user_data; + g_assert(c != NULL); + + c->called = TRUE; + if (error != NULL) { + c->error = TRUE; + c->err_code = error->code; + c->err_msg = g_strdup(error->message); + } +} + +static void seek_cb (MafwRenderer *self, gint position, gpointer user_data, + const GError *error) +{ + /* Called when seeking */ + + CallbackInfo* c = (CallbackInfo*) user_data; + g_assert(c != NULL); + + c->called = TRUE; + c->seek_position = position; + if (error != NULL) { + c->error = TRUE; + c->err_code = error->code; + c->err_msg = g_strdup(error->message); + } +} + +static void get_position_cb(MafwRenderer *self, gint position, + gpointer user_data, const GError *error) +{ + CallbackInfo* c = (CallbackInfo*) user_data; + + g_debug("get position cb: %d", position); + + if (error != NULL) { + c->error = TRUE; + c->err_code = error->code; + c->err_msg = g_strdup(error->message); + } + c->called = TRUE; +} + +static void get_property_cb(MafwExtension *self, + const gchar *name, + GValue *value, + gpointer user_data, + const GError *error) +{ + CallbackInfo* c = (CallbackInfo*) user_data; + gchar *value_string; + + value_string = g_strdup_value_contents(value); + + g_debug("get property cb: %s (%s)", name, value_string); + g_free(value_string); + + if (error != NULL) { + c->error = TRUE; + c->err_code = error->code; + c->err_msg = g_strdup(error->message); + } + + if (c->property_expected != NULL && + strcmp(c->property_expected, name) == 0) { + c->property_received = g_new0(GValue, 1); + g_value_init(c->property_received, G_VALUE_TYPE(value)); + g_value_copy(value, c->property_received); + + c->called = TRUE; + } +} + +/*---------------------------------------------------------------------------- + Helpers + ----------------------------------------------------------------------------*/ + +static gchar *get_sample_clip_path(const gchar *clip) +{ + gchar *my_dir, *media; + + /* Makefile.am sets TESTS_DIR, required for VPATH builds (like make + * distcheck). Otherwise assume we are running in-place. */ + my_dir = g_strdup(g_getenv("TESTS_DIR")); + if (!my_dir) + my_dir = g_get_current_dir(); + media = g_strconcat("file://", my_dir, G_DIR_SEPARATOR_S, + "media" G_DIR_SEPARATOR_S, clip, + NULL); + g_free(my_dir); + return media; +} + +static gchar *get_sample_clip_objectid(const gchar *clip) +{ + gchar *path = NULL; + gchar *objectid = NULL; + + path = get_sample_clip_path(clip); + objectid = mafw_source_create_objectid(path); + g_free(path); + + return objectid; +} + +static gboolean stop_wait_timeout(gpointer user_data) +{ + gboolean *do_stop = (gboolean *) user_data; + g_debug("stop wait timeout"); + *do_stop = TRUE; + + return FALSE; +} + +static gboolean wait_until_timeout_finishes(guint millis) +{ + guint timeout = 0; + gboolean stop_wait = FALSE; + gboolean result = FALSE; + + g_debug("Init wait_"); + /* We'll wait a limitted ammount of time */ + timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait); + while(!stop_wait) { + result= g_main_context_iteration(NULL, TRUE); + } + + g_debug("End wait_"); + return TRUE; +} + +static gboolean wait_for_state(RendererInfo *renderer_info, + MafwPlayState expected_state, guint millis) +{ + guint timeout = 0; + gboolean stop_wait = FALSE; + + g_debug("Init wait for state"); + /* We'll wait a limitted ammount of time */ + timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait); + + while(renderer_info->state != expected_state && !stop_wait) { + g_main_context_iteration(NULL, TRUE); + } + + if (!stop_wait) { + g_source_remove(timeout); + } + + g_debug("End wait for state"); + return (renderer_info->state == expected_state); +} + +static gboolean wait_for_callback(CallbackInfo *callback, guint millis) +{ + guint timeout = 0; + gboolean stop_wait = FALSE; + + g_debug("Init wait for callback"); + /* We'll wait a limitted ammount of time */ + timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait); + + while (callback->called == FALSE && !stop_wait) { + g_main_context_iteration(NULL, TRUE); + } + if (!stop_wait) { + g_source_remove(timeout); + } + g_debug("End wait for callback"); + return callback->called; +} + +static gboolean wait_for_metadata(MetadataChangedInfo *callback, guint millis) +{ + guint timeout = 0; + gboolean stop_wait = FALSE; + + g_debug("Init wait for metadata"); + /* We'll wait a limitted ammount of time */ + timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait); + + while (callback->value == NULL && !stop_wait) { + g_main_context_iteration(NULL, TRUE); + } + if (!stop_wait) { + g_source_remove(timeout); + } + g_debug("End wait for metadata"); + return callback->value != NULL; +} + +static gboolean wait_for_property(PropertyChangedInfo *callback, guint millis) +{ + guint timeout = 0; + gboolean stop_wait = FALSE; + + g_debug("Init wait for property changed"); + /* We'll wait a limitted ammount of time */ + timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait); + + while (callback->received == NULL && !stop_wait) { + g_main_context_iteration(NULL, TRUE); + } + if (!stop_wait) { + g_source_remove(timeout); + } + g_debug("End wait for callback"); + return callback->received != NULL; +} + +static gboolean wait_for_buffering(BufferingInfo *callback, guint millis) +{ + guint timeout = 0; + gboolean stop_wait = FALSE; + + g_debug("Init wait for buffering info"); + /* We'll wait a limitted ammount of time */ + timeout = g_timeout_add(millis, stop_wait_timeout, &stop_wait); + + while (!callback->received && !stop_wait) { + g_main_context_iteration(NULL, TRUE); + } + if (!stop_wait) { + g_source_remove(timeout); + } + g_debug("End wait for buffering info"); + return callback->received; +} + +static void reset_callback_info(CallbackInfo *callback_info) +{ + if (callback_info->err_msg != NULL) + g_free(callback_info->err_msg); + + callback_info->err_msg = NULL; + callback_info->called = FALSE; + callback_info->error = FALSE; + callback_info->seek_position = 0; + callback_info->error_signal_expected = FALSE; + if (callback_info->error_signal_received != NULL) { + g_error_free(callback_info->error_signal_received); + callback_info->error_signal_received = NULL; + } + callback_info->property_expected = NULL; + if (callback_info->property_received != NULL) { + g_value_unset(callback_info->property_received); + callback_info->property_received = NULL; + } +} + +/*---------------------------------------------------------------------------- + Fixtures + ----------------------------------------------------------------------------*/ + +static void fx_setup_dummy_gst_renderer(void) +{ + MafwRegistry *registry; + + /* Setup GLib */ + g_type_init(); + + /* Create a gst renderer instance */ + registry = MAFW_REGISTRY(mafw_registry_get_instance()); + fail_if(registry == NULL, + "Error: cannot get MAFW registry"); + + g_gst_renderer = MAFW_RENDERER(mafw_gst_renderer_new(registry)); + fail_if(!MAFW_IS_GST_RENDERER(g_gst_renderer), + "Could not create gst renderer instance"); +} + +static void fx_teardown_dummy_gst_renderer(void) +{ + g_object_unref(g_gst_renderer); +} + +/*---------------------------------------------------------------------------- + Mockups + ----------------------------------------------------------------------------*/ + +/* GStreamer mock */ + +GstElement * gst_element_factory_make(const gchar * factoryname, + const gchar * name) +{ + GstElementFactory *factory; + GstElement *element; + const gchar *use_factoryname; + + g_return_val_if_fail(factoryname != NULL, NULL); + + /* For testing, use playbin instead of playbin2 */ + if (g_ascii_strcasecmp(factoryname, "playbin2") == 0) + use_factoryname = "playbin"; + else + use_factoryname = factoryname; + + GST_LOG("gstelementfactory: make \"%s\" \"%s\"", + use_factoryname, GST_STR_NULL (name)); + + factory = gst_element_factory_find(use_factoryname); + if (factory == NULL) { + /* No factory */ + GST_INFO("no such element factory \"%s\"!", use_factoryname); + return NULL; + } + + GST_LOG_OBJECT(factory, "found factory %p", factory); + if (g_ascii_strcasecmp(use_factoryname, "pulsesink") == 0) { + element = gst_element_factory_make("fakesink", "pulsesink"); + g_object_set(G_OBJECT(element), "sync", TRUE, NULL); + } else if (g_ascii_strcasecmp(use_factoryname, "xvimagesink") == 0) { + element = gst_element_factory_make("fakesink", "xvimagesink"); + g_object_set(G_OBJECT(element), "sync", TRUE, NULL); + } else { + element = gst_element_factory_create(factory, name); + } + gst_object_unref(factory); + + if (element == NULL) { + /* Create failed */ + GST_INFO_OBJECT(factory, "couldn't create instance!"); + return NULL; + } + + GST_LOG("gstelementfactory: make \"%s\" \"%s\"",use_factoryname, + GST_STR_NULL(name)); + + /* Playbin will use fake renderer */ + if (g_ascii_strcasecmp(use_factoryname, "playbin") == 0) { + GstElement *audiorenderer = gst_element_factory_make("fakesink", + "audiorenderer"); + + g_object_set(G_OBJECT(audiorenderer), "sync", TRUE, NULL); + g_object_set(G_OBJECT(element), + "audio-sink", + audiorenderer, + NULL); + g_object_set(G_OBJECT(element), + "video-sink", + audiorenderer, + NULL); + } + + return element; +} + + +/*---------------------------------------------------------------------------- + Test cases + ----------------------------------------------------------------------------*/ + +START_TEST(test_basic_playback) +{ + RendererInfo s; + CallbackInfo c; + MetadataChangedInfo m; + GstBus *bus = NULL; + GstMessage *message = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + m.expected_key = NULL; + m.value = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "metadata-changed", + G_CALLBACK(metadata_changed_cb), + &m); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + /* No media item has been set so, we should get an error */ + if (c.error == FALSE) + fail("Play of unset media did not return an error"); + } else { + fail(no_callback_msg); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + gchar *objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c); + + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Transitioning", + s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + g_free(objectid); + + /* --- Get position --- */ + + reset_callback_info(&c); + + mafw_renderer_get_position(g_gst_renderer, get_position_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_position", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Duration emission --- */ + + m.expected_key = MAFW_METADATA_KEY_DURATION; + + bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus; + fail_if(bus == NULL, "No GstBus"); + + message = gst_message_new_duration(NULL, GST_FORMAT_TIME, + 5 * GST_SECOND); + gst_bus_post(bus, message); + + if (wait_for_metadata(&m, wait_tout_val) == FALSE) { + fail("Expected " MAFW_METADATA_KEY_DURATION + ", but not received"); + } + + fail_if(m.value == NULL, "Metadata " MAFW_METADATA_KEY_DURATION + " not received"); + + g_value_unset(m.value); + g_free(m.value); + m.value = NULL; + m.expected_key = NULL; + + /* --- Pause --- */ + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_pause", "Paused", s.state); + } + + /* --- Resume --- */ + + reset_callback_info(&c); + + g_debug("resume..."); + mafw_renderer_resume(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "resuming", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_resume", "Playing", s.state); + } + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state); + } + +} +END_TEST + +START_TEST(test_playlist_playback) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + RendererInfo s = {0, }; + CallbackInfo c = {0, }; + gchar *cur_item_oid = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Create and assign a playlist --- */ + + g_debug("assign playlist..."); + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + for (i=0; i<10; i++) { + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + } + g_free(cur_item_oid); + cur_item_oid = get_sample_clip_objectid("unexisting.wav"); + mafw_playlist_insert_item(playlist, 9, cur_item_oid, NULL); + g_free(cur_item_oid); + + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Playing", s.state); + } + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_stop", "Stopped", s.state); + } + + /* --- Next --- */ + + /* Get actual index */ + + gint initial_index = s.index; + + for (i=0; i<3; i++) { + + reset_callback_info(&c); + + g_debug("move to next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != initial_index + (i+1), index_err_msg, s.index, + initial_index + (i+1)); + } + + + /* --- Prev --- */ + + /* Get actual index */ + initial_index = s.index; + + for (i=0; i<3; i++) { + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != initial_index - (i+1), index_err_msg, s.index, + initial_index - (i+1)); + } + + /* Check if renderer remains in Stopped state after some Prev operations */ + fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state " + "after doing prev. The actual state is %s and must be %s", + s.state, "Stopped"); + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping playback", + c.err_code, c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg,"mafw_renderer_stop","Stopped", s.state); + } + + /* --- Go to index in Stopped state --- */ + + reset_callback_info(&c); + + g_debug("goto index 3..."); + mafw_renderer_goto_index(g_gst_renderer, 3, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 3", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != 3, index_err_msg, s.index, 3); + + /* Check if renderer remains in Stopped state after running go to index */ + fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state " + "after running go to index. The actual state is %s and must be" + " %s", s.state, "Stopped"); + + /* --- Play (playlist index is 3) --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Playing", s.state); + } + + /* --- Goto index in Playing state --- */ + + reset_callback_info(&c); + + g_debug("goto index 5..."); + mafw_renderer_goto_index(g_gst_renderer, 5, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_goto_index", "Playing", s.state); + } + + /* Check if the index if correct */ + fail_if(s.index != 5, index_err_msg, s.index, 5); + + /* Check if renderer remains in Playing state after running go to index */ + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail("Gst renderer didn't remain in Playing state after running " + "go to index. The actual state is %s and must be %s", + s.state, "Playing"); + } + + /* --- Goto an invalid index --- */ + + reset_callback_info(&c); + + g_debug("goto the invalid index 20..."); + mafw_renderer_goto_index(g_gst_renderer, 20, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error == FALSE) + fail("Error not received when we go to an incorrect" + "index"); + } else { + fail(no_callback_msg); + } + + /* Check if the previous index (5) remains after an incorrect go to + index request */ + fail_if(s.index != 5, index_err_msg, 5, s.index); + + reset_callback_info(&c); + + /* --- Reassigning playlist --- */ + + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, + g_object_ref(playlist), NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Go to index with invalid media --- */ + + reset_callback_info(&c); + + g_debug("goto index 9..."); + mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 9", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != 9, index_err_msg, s.index, 9); + + /* Check if renderer remains in Stopped state after running go + * to index */ + fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped " + "state after running go to index. The actual state is %d and " + "must be %s", s.state, "Stopped"); + + /* --- Play (playlist index is 9) --- */ + + reset_callback_info(&c); + + c.error_signal_expected = TRUE; + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Transitioning", + s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Playing", s.state); + } + + fail_if(c.error_signal_received == NULL || + !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR, + MAFW_RENDERER_ERROR_INVALID_URI), + "No error received or incorrect one"); + + if (c.error_signal_received != NULL) { + g_error_free(c.error_signal_received); + c.error_signal_received = NULL; + } + c.error_signal_expected = FALSE; + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping playback", + c.err_code, c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg,"mafw_renderer_stop","Stopped", s.state); + } + + /* --- Remove last media --- */ + + mafw_playlist_remove_item(playlist, 10, NULL); + + /* --- Go to index with invalid media --- */ + + reset_callback_info(&c); + + g_debug("goto index 9..."); + mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 9", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != 9, index_err_msg, s.index, 9); + + /* Check if renderer remains in Stopped state after running go + * to index */ + fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped " + "state after running go to index. The actual state is %d and " + "must be %s", s.state, "Stopped"); + + /* --- Play (playlist index is 9) --- */ + + reset_callback_info(&c); + + c.error_signal_expected = TRUE; + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Transitioning", + s.state); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Stopped", s.state); + } + + fail_if(c.error_signal_received == NULL || + !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR, + MAFW_RENDERER_ERROR_INVALID_URI), + "No error received or incorrect one"); + + if (c.error_signal_received != NULL) { + g_error_free(c.error_signal_received); + c.error_signal_received = NULL; + } + c.error_signal_expected = FALSE; + + /* --- Play incorrect object --- */ + + reset_callback_info(&c); + + c.error_signal_expected = TRUE; + + gchar *objectid = get_sample_clip_objectid("unexisting.wav"); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", + s.state); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Stopped", + s.state); + } + + fail_if(c.error_signal_received == NULL || + !g_error_matches(c.error_signal_received, MAFW_RENDERER_ERROR, + MAFW_RENDERER_ERROR_INVALID_URI), + "No error received or incorrect one"); + + if (c.error_signal_received != NULL) { + g_error_free(c.error_signal_received); + c.error_signal_received = NULL; + } + c.error_signal_expected = FALSE; + + g_free(objectid); + +} +END_TEST + + +START_TEST(test_repeat_mode_playback) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Create playlist --- */ + + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + for (i=0; i<10; i++) { + gchar *cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + g_free(cur_item_oid); + } + + /* Set repeat mode */ + mafw_playlist_set_repeat(playlist, TRUE); + + /* --- Assign playlist --- */ + + g_debug("assign playlist..."); + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Playing", s.state); + } + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 9..."); + /* go to the end of the playlist */ + mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 9", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* check if the movement was successful */ + fail_if(s.index != 9, index_err_msg, 9, s.index); + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping playback", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_stop", "Stopped", s.state); + } + + /* --- Next --- */ + + reset_callback_info(&c); + + g_debug("next..."); + /* The actual index is 9 */ + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* check if the movement was successful */ + fail_if(s.index != 0, index_err_msg, s.index, 0); + + /* Check if renderer remains in Stopped state after moving to next */ + fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state " + "after doing next. The actual state is %s and must be %s", + s.state, "Stopped"); + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("prev..."); + /* The actual index is 0 */ + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* check if the movement was successful */ + fail_if(s.index != 9, index_err_msg, s.index, 9); + + /* Check if renderer remains in Stopped state after moving to next */ + fail_if(s.state != Stopped, "Gst renderer didn't remain in Stopped state " + "after doing next. The actual state is %s and must be %s", + s.state, "Stopped"); +} +END_TEST + + +START_TEST(test_gst_renderer_mode) +{ + MafwPlaylist *playlist = NULL; + MafwGstRenderer *renderer = NULL; + MafwGstRendererPlaybackMode play_mode; + gchar *objectid = NULL; + gint i = 0; + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + gchar *modes[] = {"MAFW_GST_RENDERER_MODE_PLAYLIST", + "MAFW_GST_RENDERER_MODE_STANDALONE"}; + + renderer = MAFW_GST_RENDERER(g_gst_renderer); + + /* Initiliaze callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Create playlist --- */ + + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + for (i=0; i<10; i++) { + gchar *cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + g_free(cur_item_oid); + } + + /* --- Assign playlist --- */ + + g_debug("assign playlist..."); + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Transitioning", s.state); + } + + /* Check that renderer is playing a playlist */ + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Playing", s.state); + } + play_mode = mafw_gst_renderer_get_playback_mode(renderer); + fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST, + "Incorrect value of playback_mode: %s", modes[play_mode]); + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s",objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c); + g_free(objectid); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Transitioning", + s.state); + } + + /* Check that renderer is playing an object */ + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + play_mode = mafw_gst_renderer_get_playback_mode(renderer); + fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE, + "Incorrect value of playback_mode: %s", modes[play_mode]); + + /* Wait EOS_TIMEOUT to ensure that the play_object has finished */ + wait_until_timeout_finishes(EOS_TIMEOUT); + + /* Check that after playing the object, renderer returns to the playlist + playback */ + play_mode = mafw_gst_renderer_get_playback_mode(renderer); + fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST, + "Incorrect value of playback_mode: %s", modes[play_mode]); + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c); + g_free(objectid); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Transitioning", + s.state); + } + + /* Check that renderer is playing an object */ + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + play_mode = mafw_gst_renderer_get_playback_mode(renderer); + fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE, + "Incorrect value of playback_mode: %s", modes[play_mode]); + + + /* --- Move to next when renderer is playing an object --- */ + + reset_callback_info(&c); + + g_debug("next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check that "next" function finishes the object playback and returns + to the playlist playback */ + play_mode = mafw_gst_renderer_get_playback_mode(renderer); + fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST, + "Incorrect value of playback_mode: %s", modes[play_mode]); + + /* Check that renderer is still in Playing state */ + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Transitioning", + s.state); + } + + /* Check that renderer is playing an object */ + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + play_mode = mafw_gst_renderer_get_playback_mode(renderer); + fail_if(play_mode != MAFW_GST_RENDERER_MODE_STANDALONE, + "Incorrect value of playback_mode: %s", modes[play_mode]); + + /* Wait EOS_TIMEOUT to ensure that object playback finishes */ + wait_until_timeout_finishes(EOS_TIMEOUT); + + /* Check if renderer is in playlist mode and the renderer state is the state before + playing the object */ + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state); + } + play_mode = mafw_gst_renderer_get_playback_mode(renderer); + fail_if(play_mode != MAFW_GST_RENDERER_MODE_PLAYLIST, + "Incorrect value of playback_mode: %s", modes[play_mode]); + + g_free(objectid); +} +END_TEST + +#define MOCK_SOURCE(o) \ + (G_TYPE_CHECK_INSTANCE_CAST((o), \ + mock_source_get_type(), \ + MockSource)) + +typedef struct { + MafwSourceClass parent; +} MockSourceClass; + +typedef struct { + MafwSource parent; + + +} MockSource; + +GType mock_source_get_type(void); +GObject* mock_source_new(void); + +G_DEFINE_TYPE(MockSource, mock_source, MAFW_TYPE_SOURCE); + +static GHashTable *get_md_ht; /* Metadata hash-table for the metadata result */ +static GError *get_md_err; /* Error value for the metadata result */ +static gboolean set_mdata_called; /* Whether set_metadata was called or not */ +static gboolean get_mdata_called; /* Whether get_metadata was called or not */ +static gint reference_pcount; /* Reference playcount, what should come in set_metadata */ +static gboolean set_for_playcount; /* TRUE, when the set_metadata is called to modify the playcount */ +static gboolean set_for_lastplayed; /* TRUE, when the set_metadata is called to modify the last-played */ + +static void get_metadata(MafwSource *self, + const gchar *object_id, + const gchar *const *metadata, + MafwSourceMetadataResultCb callback, + gpointer user_data) +{ + get_mdata_called = TRUE; + fail_if(strcmp(object_id, "mocksource::test")); + callback(self, object_id, get_md_ht, user_data, get_md_err); +} + +static void set_metadata(MafwSource *self, const gchar *object_id, + GHashTable *metadata, + MafwSourceMetadataSetCb callback, + gpointer user_data) +{ + GValue *curval; + gint htsize = 0; + + if (set_for_playcount) + htsize++; + if (set_for_lastplayed) + htsize++; + fail_if(strcmp(object_id, "mocksource::test")); + fail_if(!metadata); + fail_if(g_hash_table_size(metadata) != htsize, "Hash table size: %d vs %d", g_hash_table_size(metadata), htsize); + if (set_for_playcount) + { + curval = mafw_metadata_first(metadata, + MAFW_METADATA_KEY_PLAY_COUNT); + fail_if(!curval); + fail_if(g_value_get_int(curval) != reference_pcount); + } + if (set_for_lastplayed) + { + curval = mafw_metadata_first(metadata, + MAFW_METADATA_KEY_LAST_PLAYED); + fail_if(!curval); + fail_if(!G_VALUE_HOLDS(curval, G_TYPE_LONG)); + } + set_mdata_called = TRUE; +} + +static void mock_source_class_init(MockSourceClass *klass) +{ + MafwSourceClass *sclass = MAFW_SOURCE_CLASS(klass); + + sclass->get_metadata = get_metadata; + sclass->set_metadata = set_metadata; + +} + +static void mock_source_init(MockSource *source) +{ + /* NOP */ +} + +GObject* mock_source_new(void) +{ + GObject* object; + object = g_object_new(mock_source_get_type(), + "plugin", "mockland", + "uuid", "mocksource", + "name", "mocksource", + NULL); + return object; +} + + +START_TEST(test_update_stats) +{ + MafwGstRenderer *renderer = NULL; + MafwSource *src; + MafwRegistry *registry; + + registry = MAFW_REGISTRY(mafw_registry_get_instance()); + fail_if(registry == NULL, + "Error: cannot get MAFW registry"); + + + renderer = MAFW_GST_RENDERER(g_gst_renderer); + src = MAFW_SOURCE(mock_source_new()); + + mafw_registry_add_extension(registry, MAFW_EXTENSION(src)); + + /* Error on get_mdata_cb*/ + set_for_playcount = FALSE; + set_for_lastplayed = FALSE; + get_md_err = NULL; + g_set_error(&get_md_err, MAFW_SOURCE_ERROR, + MAFW_SOURCE_ERROR_INVALID_OBJECT_ID, + "Wrong object id mocksource::test"); + renderer->media->object_id = g_strdup("mocksource::test"); + mafw_gst_renderer_update_stats(renderer); + g_error_free(get_md_err); + fail_if(set_mdata_called); + fail_if(!get_mdata_called); + + /* get_mdata ok, but HashTable is NULL */ + reference_pcount = 1; + get_mdata_called = FALSE; + set_for_lastplayed = TRUE; + set_for_playcount = TRUE; + get_md_err = NULL; + mafw_gst_renderer_update_stats(renderer); + fail_if(!set_mdata_called); + fail_if(!get_mdata_called); + + /* get_mdata ok, but HashTable is empty */ + get_mdata_called = FALSE; + set_mdata_called = FALSE; + set_for_lastplayed = TRUE; + set_for_playcount = TRUE; + get_md_ht = mafw_metadata_new(); + mafw_gst_renderer_update_stats(renderer); + fail_if(!set_mdata_called); + fail_if(!get_mdata_called); + + /* get_mdata ok, but HashTable has valid value */ + get_mdata_called = FALSE; + set_mdata_called = FALSE; + set_for_lastplayed = TRUE; + set_for_playcount = TRUE; + mafw_metadata_add_int(get_md_ht, + MAFW_METADATA_KEY_PLAY_COUNT, + 1); + reference_pcount = 2; + mafw_gst_renderer_update_stats(renderer); + fail_if(!set_mdata_called); + fail_if(!get_mdata_called); +} +END_TEST + +START_TEST(test_play_state) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + gchar *objectid = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + if (wait_for_state(&s, Stopped, 3000) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Stop", + s.state); + } + + g_free(objectid); + + + /* --- Create and assign a playlist --- */ + + g_debug("assign playlist..."); + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + for (i=0; i<10; i++) { + gchar *cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + g_free(cur_item_oid); + } + mafw_playlist_set_repeat(playlist, FALSE); + + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, + NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail("Play after assigning playlist failed"); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Playing", + s.state); + } + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 9, index_err_msg, s.index, 9); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", "Playing", + s.state); + } + + /* Removing last element */ + + g_debug("removing last element..."); + fail_if(mafw_playlist_get_size(playlist, NULL) != 10, + "Playlist should have 10 elements"); + mafw_playlist_remove_item(playlist, 9, NULL); + fail_if(mafw_playlist_get_size(playlist, NULL) != 9, + "Playlist should have 9 elements"); + fail_if(s.index != 8, index_err_msg, s.index, 8); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_playlist_remove_element", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_playlist_remove_element", "Playing", + s.state); + } + + /* --- Next --- */ + + reset_callback_info(&c); + + g_debug("move to next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 0, index_err_msg, s.index, 0); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_next", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_next", "Playing", + s.state); + } + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 8..."); + mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 8", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 8, index_err_msg, s.index, 8); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_goto_index", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_goto_index", "Playing", + s.state); + } + + /* --- Seeking --- */ + + reset_callback_info(&c); + + g_debug("seeking..."); + mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1, + seek_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "seeking failed", c.err_code, + c.err_msg); + if (c.seek_position != 1) { + fail("seeking failed"); + } + } else { + fail(no_callback_msg); + } + + /* --- Waiting EOS --- */ + + if (wait_for_state(&s, Stopped, 2000) == FALSE) { + fail(state_err_msg, "EOS", "Stop", + s.state); + } +} +END_TEST + +START_TEST(test_pause_state) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + gchar *objectid = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Create and assign a playlist --- */ + + g_debug("assign playlist..."); + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + for (i=0; i<10; i++) { + gchar *cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + g_free(cur_item_oid); + } + mafw_playlist_set_repeat(playlist, FALSE); + + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, + NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail("Play failed"); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", + "Transitioning", s.state); + } + + /* Testing pause in transitioning */ + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Testing resume in transitioning */ + + reset_callback_info(&c); + + g_debug("resume..."); + mafw_renderer_resume(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "resuming", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + reset_callback_info(&c); + + /* Testing resume without having paused in transitioning */ + + reset_callback_info(&c); + + g_debug("resume..."); + mafw_renderer_resume(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_no_err_msg, "resuming", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_pause", "Paused", + s.state); + } + + /* --- Play object in pause --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_pause", "Paused", + s.state); + } + + g_free(objectid); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail("Play failed"); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", + "Transitioning", s.state); + } + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_pause", "Paused", + s.state); + } + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != 9, index_err_msg, s.index, 9); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", + "Transitioning", s.state); + } + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", "Playing", + s.state); + } + + /* Removing last element */ + + g_debug("removing last element..."); + fail_if(mafw_playlist_get_size(playlist, NULL) != 10, + "Playlist should have 10 elements"); + mafw_playlist_remove_item(playlist, 9, NULL); + fail_if(mafw_playlist_get_size(playlist, NULL) != 9, + "Playlist should have 9 elements"); + fail_if(s.index != 8, index_err_msg, s.index, 8); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_playlist_remove_item", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_playlist_remove_item", "Playing", + s.state); + } + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_playlist_remove_item", "Playing", + s.state); + } + + /* --- Next --- */ + + reset_callback_info(&c); + + g_debug("move to next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != 0, index_err_msg, s.index, 0); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_next", + "Transitioning", s.state); + } + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_next", "Playing", + s.state); + } + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 8..."); + mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 8", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* Check if the playlist index is correct */ + fail_if(s.index != 8, index_err_msg, s.index, 8); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_goto_index", + "Transitioning", s.state); + } + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_goto_index", "Playing", + s.state); + } + + /* --- Seeking --- */ + + reset_callback_info(&c); + + mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1, + seek_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "seeking", c.err_code, + c.err_msg); + if (c.seek_position != 1) { + fail("seeking failed"); + } + } else { + fail(no_callback_msg); + } + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state); + } +} +END_TEST + +START_TEST(test_stop_state) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_no_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Next --- */ + + reset_callback_info(&c); + + g_debug("move to next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_no_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 8..."); + mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_no_err_msg, "going to index 8", + c.err_code, c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Create and assign a playlist --- */ + + g_debug("assign playlist..."); + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + for (i=0; i<10; i++) { + gchar *cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + g_free(cur_item_oid); + } + mafw_playlist_set_repeat(playlist, FALSE); + + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, + NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* Removing last element */ + + g_debug("removing last element..."); + fail_if(mafw_playlist_get_size(playlist, NULL) != 10, + "Playlist should have 10 elements"); + mafw_playlist_remove_item(playlist, 9, NULL); + fail_if(mafw_playlist_get_size(playlist, NULL) != 9, + "Playlist should have 9 elements"); + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 9..."); + mafw_renderer_goto_index(g_gst_renderer, 9, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_no_err_msg, "going to index 9", + c.err_code, c.err_msg); + } else { + fail(no_callback_msg); + } + reset_callback_info(&c); +} +END_TEST + +START_TEST(test_transitioning_state) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + gchar *objectid = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Create and assign a playlist --- */ + + g_debug("assign playlist..."); + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + for (i=0; i<10; i++) { + gchar *cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + g_free(cur_item_oid); + } + mafw_playlist_set_repeat(playlist, FALSE); + + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, + NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail("Play after assigning playlist failed"); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", + "Transitioning", s.state); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + g_free(objectid); + + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 9, index_err_msg, s.index, 9); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", + "Transitioning", s.state); + } + + /* Removing last element */ + + g_debug("removing last element..."); + fail_if(mafw_playlist_get_size(playlist, NULL) != 10, + "Playlist should have 10 elements"); + mafw_playlist_remove_item(playlist, 9, NULL); + fail_if(mafw_playlist_get_size(playlist, NULL) != 9, + "Playlist should have 9 elements"); + fail_if(s.index != 8, index_err_msg, s.index, 8); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_playlist_remove_element", + "Transitioning", s.state); + } + + /* --- Next --- */ + + reset_callback_info(&c); + + g_debug("move to next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 0, index_err_msg, s.index, 0); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_next", + "Transitioning", s.state); + } + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 8..."); + mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 8", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 8, index_err_msg, s.index, 8); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_goto_index", + "Transitioning", s.state); + } +} +END_TEST + +START_TEST(test_state_class) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + gchar *objectid = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_no_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Next --- */ + + reset_callback_info(&c); + + g_debug("move to next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_no_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 8..."); + mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (!c.error) + fail(callback_err_msg, "going to index 8", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Create and assign a playlist --- */ + + g_debug("assign playlist..."); + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + for (i=0; i<10; i++) { + gchar *cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item( + playlist, i, cur_item_oid, NULL); + g_free(cur_item_oid); + } + mafw_playlist_set_repeat(playlist, FALSE); + + media_changed_called = FALSE; + if (!mafw_renderer_assign_playlist(g_gst_renderer, playlist, + NULL)) + { + fail("Assign playlist failed"); + } + + wait_for_state(&s, Stopped, wait_tout_val); + + /* --- Play object --- */ + + reset_callback_info(&c); + + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Next --- */ + + reset_callback_info(&c); + + g_debug("move to next..."); + mafw_renderer_next(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to next", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 1, index_err_msg, s.index, 1); + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_next", "Playing", + s.state); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Go to index --- */ + + reset_callback_info(&c); + + g_debug("goto index 8..."); + mafw_renderer_goto_index(g_gst_renderer, 8, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "going to index 8", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 8, index_err_msg, s.index, 8); + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_goto_index", "Playing", + s.state); + } + + /* --- Play object --- */ + + reset_callback_info(&c); + + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 7, index_err_msg, s.index, 7); + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", "Playing", + s.state); + } + + /* --- Play --- */ + + reset_callback_info(&c); + + g_debug("play..."); + mafw_renderer_play(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail("Play after assigning playlist failed"); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play", "Playing", + s.state); + } + + /* --- Prev --- */ + + reset_callback_info(&c); + + g_debug("move to prev..."); + mafw_renderer_previous(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "moving to prev", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(s.index != 6, index_err_msg, s.index, 6); + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", + "Transitioning", s.state); + } + + /* --- Seeking --- */ + + reset_callback_info(&c); + + g_debug("seeking..."); + mafw_renderer_set_position(g_gst_renderer, SeekRelative, 1, + seek_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "seeking failed", c.err_code, + c.err_msg); + if (c.seek_position != 1) { + fail("seeking failed"); + } + } else { + fail(no_callback_msg); + } + + /* --- Seeking --- */ + + reset_callback_info(&c); + + g_debug("seeking..."); + mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, -1, + seek_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "seeking failed", c.err_code, + c.err_msg); + if (c.seek_position != -1) { + fail("seeking failed"); + } + } else { + fail(no_callback_msg); + } + + /* --- Seeking --- */ + + reset_callback_info(&c); + + g_debug("seeking..."); + mafw_renderer_set_position(g_gst_renderer, SeekAbsolute, 1, + seek_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "seeking failed", c.err_code, + c.err_msg); + if (c.seek_position != 1) { + fail("seeking failed"); + } + } else { + fail(no_callback_msg); + } +} +END_TEST + +START_TEST(test_playlist_iterator) +{ + MafwPlaylist *playlist = NULL; + gint i = 0; + CallbackInfo c = {0, };; + MafwPlaylistIterator *iterator = NULL; + GError *error = NULL; + gint size; + gint index; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error = FALSE; + reset_callback_info(&c); + + /* --- Create and assign a playlist --- */ + + g_debug("assign playlist..."); + playlist = MAFW_PLAYLIST(mafw_mock_playlist_new()); + + iterator = mafw_playlist_iterator_new(); + mafw_playlist_iterator_initialize(iterator, playlist, &error); + if (error != NULL) { + fail("Error found: %s, %d, %s", + g_quark_to_string(error->domain), + error->code, error->message); + } + + for (i = 0; i < 3; i++) { + gchar *cur_item_oid = NULL; + cur_item_oid = + get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + mafw_playlist_insert_item(playlist, 0, cur_item_oid, NULL); + g_free(cur_item_oid); + } + + size = mafw_playlist_iterator_get_size(iterator, NULL); + fail_if(size != 3, "Playlist should have 3 elements and it has %d", + size); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != 2, "Index should be 2 and it is %d", index); + + mafw_playlist_move_item(playlist, 1, 2, NULL); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != 1, "Index should be 1 and it is %d", index); + + mafw_playlist_move_item(playlist, 2, 1, NULL); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != 2, "Index should be 2 and it is %d", index); + + mafw_playlist_move_item(playlist, 2, 1, NULL); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != 1, "Index should be 1 and it is %d", index); + + mafw_playlist_remove_item(playlist, 0, &error); + if (error != NULL) { + fail("Error found: %s, %d, %s", + g_quark_to_string(error->domain), + error->code, error->message); + } + + size = mafw_playlist_iterator_get_size(iterator, NULL); + fail_if(size != 2, "Playlist should have 2 elements and it has %d", + size); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != 0, "Index should be 0 and it is %d", index); + + mafw_playlist_iterator_reset(iterator, NULL); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != 0, "Index should be 0 and it is %d", index); + + mafw_playlist_remove_item(playlist, 0, &error); + if (error != NULL) { + fail("Error found: %s, %d, %s", + g_quark_to_string(error->domain), + error->code, error->message); + } + + size = mafw_playlist_iterator_get_size(iterator, NULL); + fail_if(size != 1, "Playlist should have 1 elements and it has %d", + size); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != 0, "Index should be 0 and it is %d", index); + + mafw_playlist_remove_item(playlist, 0, &error); + if (error != NULL) { + fail("Error found: %s, %d, %s", + g_quark_to_string(error->domain), + error->code, error->message); + } + + size = mafw_playlist_iterator_get_size(iterator, NULL); + fail_if(size != 0, "Playlist should have 0 elements and it has %d", + size); + index = mafw_playlist_iterator_get_current_index(iterator); + fail_if(index != -1, "Index should be -1 and it is %d", index); + + g_object_unref(iterator); +} +END_TEST + +START_TEST(test_video) +{ + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + MetadataChangedInfo m; + gchar *objectid = NULL; + GstBus *bus = NULL; + GstStructure *structure = NULL; + GstMessage *message = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + m.expected_key = NULL; + m.value = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + g_signal_connect(g_gst_renderer, "metadata-changed", + G_CALLBACK(metadata_changed_cb), + &m); + +#ifdef HAVE_GDKPIXBUF + mafw_extension_set_property_boolean( + MAFW_EXTENSION(g_gst_renderer), + MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE, + TRUE); +#endif + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_VIDEO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + MAFW_GST_RENDERER(g_gst_renderer)->worker->xid = 0x1; + bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus; + fail_if(bus == NULL, "No GstBus"); + + structure = gst_structure_new("prepare-xwindow-id", "width", + G_TYPE_INT, 64, "height", G_TYPE_INT, 32, + NULL); + message = gst_message_new_element(NULL, structure); + gst_bus_post(bus, message); + + /* --- Pause --- */ + + reset_callback_info(&c); + + m.expected_key = MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI; + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", "Playing", + s.state); + } + + if (wait_for_metadata(&m, wait_tout_val) == FALSE) { + fail("Expected " MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI + ", but not received"); + } + + fail_if(m.value == NULL, "Metadata " + MAFW_METADATA_KEY_PAUSED_THUMBNAIL_URI " not received"); + + g_value_unset(m.value); + g_free(m.value); + m.value = NULL; + m.expected_key = NULL; + + /* --- Resume --- */ + + reset_callback_info(&c); + + g_debug("resume..."); + mafw_renderer_resume(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "resuming", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + /* --- EOS --- */ + + if (wait_for_state(&s, Stopped, 3000) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Stop", + s.state); + } + + g_free(objectid); +} +END_TEST + +START_TEST(test_media_art) +{ + RendererInfo s = {0, };; + CallbackInfo c = {0, };; + MetadataChangedInfo m; + gchar *objectid = NULL; + GstBus *bus = NULL; + GstMessage *message = NULL; + GstTagList *list = NULL; + GstBuffer *buffer = NULL; + guchar *image = NULL; + gchar *image_path = NULL; + gsize image_length; + GstCaps *caps = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + m.expected_key = NULL; + m.value = NULL; + c.property_expected = NULL; + c.property_received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "media-changed", + G_CALLBACK(media_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "playlist-changed", + G_CALLBACK(playlist_changed_cb), + NULL); + g_signal_connect(g_gst_renderer, "metadata-changed", + G_CALLBACK(metadata_changed_cb), + &m); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Play object --- */ + + reset_callback_info(&c); + + objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, + &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + /* --- Pause --- */ + + reset_callback_info(&c); + + g_debug("pause..."); + mafw_renderer_pause(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "pausing", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Paused, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_prev", "Playing", + s.state); + } + + /* Emit image */ + + bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus; + fail_if(bus == NULL, "No GstBus"); + + m.expected_key = MAFW_METADATA_KEY_RENDERER_ART_URI; + + image_path = get_sample_clip_path(SAMPLE_IMAGE); + fail_if(!g_file_get_contents(image_path + 7, (gchar **) &image, + &image_length, NULL), + "Could not load test image"); + g_free(image_path); + + buffer = gst_buffer_new(); + gst_buffer_set_data(buffer, image, image_length); + caps = gst_caps_new_simple("image/png", "image-type", + GST_TYPE_TAG_IMAGE_TYPE, + GST_TAG_IMAGE_TYPE_FRONT_COVER, NULL); + gst_buffer_set_caps(buffer, caps); + gst_caps_unref(caps); + + list = gst_tag_list_new(); + gst_tag_list_add(list, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, buffer, + NULL); + + message = gst_message_new_tag(NULL, list); + gst_bus_post(bus, message); + + /* --- Resume --- */ + + reset_callback_info(&c); + + g_debug("resume..."); + mafw_renderer_resume(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "resuming", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + if (wait_for_metadata(&m, wait_tout_val) == FALSE) { + fail("Expected " MAFW_METADATA_KEY_RENDERER_ART_URI + ", but not received"); + } + + fail_if(m.value == NULL, "Metadata " + MAFW_METADATA_KEY_RENDERER_ART_URI " not received"); + + g_value_unset(m.value); + g_free(m.value); + m.value = NULL; + m.expected_key = NULL; + + /* --- EOS --- */ + + if (wait_for_state(&s, Stopped, 3000) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Stop", + s.state); + } + + g_free(objectid); +} +END_TEST + +START_TEST(test_properties_management) +{ + RendererInfo s; + CallbackInfo c = {0, };; + PropertyChangedInfo p; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + p.expected = NULL; + p.received = NULL; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "property-changed", + G_CALLBACK(property_changed_cb), + &p); + + /* Wait for the volume manager to be initialized */ + + /* Volume */ + + p.expected = MAFW_PROPERTY_RENDERER_VOLUME; + + if (!wait_for_property(&p, wait_tout_val)) { + fail("No property %s received", p.expected); + } + + fail_if(p.received == NULL, "No property %s received", + p.expected); + fail_if(p.received != NULL && + g_value_get_uint(p.received) != 48, + "Property with value %d and %d expected", + g_value_get_uint(p.received), 48); + + if (p.received != NULL) { + g_value_unset(p.received); + g_free(p.received); + p.received = NULL; + } + p.expected = NULL; + + /* --- mute --- */ + + reset_callback_info(&c); + + c.property_expected = MAFW_PROPERTY_RENDERER_MUTE; + + mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, TRUE); + + p.expected = MAFW_PROPERTY_RENDERER_MUTE; + +#ifdef MAFW_GST_RENDERER_ENABLE_MUTE + if (!wait_for_property(&p, wait_tout_val)) { + fail("No property %s received", p.expected); + } + + fail_if(p.received == NULL, "No property %s received", + p.expected); + fail_if(p.received != NULL && + g_value_get_boolean(p.received) != TRUE, + "Property with value %d and %d expected", + g_value_get_boolean(p.received), TRUE); +#else + if (wait_for_property(&p, wait_tout_val)) { + fail("Property %s received and it should not have been", + p.expected); + } + + fail_if(p.received != NULL, + "Property %s received and it should not have been", + p.expected); +#endif + + if (p.received != NULL) { + g_value_unset(p.received); + g_free(p.received); + p.received = NULL; + } + p.expected = NULL; + + mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, get_property_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_property", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(c.property_received == NULL, + "No property %s received and expected", c.property_expected); +#ifdef MAFW_GST_RENDERER_ENABLE_MUTE + fail_if(c.property_received != NULL && + g_value_get_boolean(c.property_received) != TRUE, + "Property with value %d and %d expected", + g_value_get_boolean(c.property_received), TRUE); +#else + fail_if(c.property_received != NULL && + g_value_get_boolean(c.property_received) != FALSE, + "Property with value %d and %d expected", + g_value_get_boolean(c.property_received), FALSE); +#endif + + /* --- xid --- */ + + reset_callback_info(&c); + + c.property_expected = MAFW_PROPERTY_RENDERER_XID; + + mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, 50); + + mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, get_property_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_property", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(c.property_received == NULL, + "No property %s received and expected", c.property_expected); + fail_if(c.property_received != NULL && + g_value_get_uint(c.property_received) != 50, + "Property with value %d and %d expected", + g_value_get_uint(c.property_received), 50); + + /* --- error policy --- */ + + reset_callback_info(&c); + + c.property_expected = MAFW_PROPERTY_RENDERER_ERROR_POLICY; + + mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, 1); + + mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, get_property_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_property", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(c.property_received == NULL, + "No property %s received and expected", c.property_expected); + fail_if(c.property_received != NULL && + g_value_get_uint(c.property_received) != 1, + "Property with value %d and %d expected", + g_value_get_uint(c.property_received), 1); + + /* --- autopaint --- */ + + reset_callback_info(&c); + + c.property_expected = MAFW_PROPERTY_RENDERER_AUTOPAINT; + + mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, TRUE); + + mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, get_property_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_property", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(c.property_received == NULL, + "No property %s received and expected", c.property_expected); + fail_if(c.property_received != NULL && + g_value_get_boolean(c.property_received) != TRUE, + "Property with value %d and %d expected", + g_value_get_boolean(c.property_received), TRUE); + + /* --- colorkey --- */ + + reset_callback_info(&c); + + c.property_expected = MAFW_PROPERTY_RENDERER_COLORKEY; + + mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, get_property_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_property", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(c.property_received == NULL, + "No property %s received and expected", c.property_expected); + fail_if(c.property_received != NULL && + g_value_get_int(c.property_received) != -1, + "Property with value %d and %d expected", + g_value_get_int(c.property_received), -1); + + /* --- current frame on pause --- */ + + reset_callback_info(&c); + + c.property_expected = MAFW_PROPERTY_GST_RENDERER_CURRENT_FRAME_ON_PAUSE; + + mafw_extension_set_property_boolean(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, TRUE); + + mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, get_property_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_property", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(c.property_received == NULL, + "No property %s received and expected", c.property_expected); + fail_if(c.property_received != NULL && + g_value_get_boolean(c.property_received) != TRUE, + "Property with value %d and %d expected", + g_value_get_boolean(c.property_received), TRUE); + + /* --- volume --- */ + + p.expected = MAFW_PROPERTY_RENDERER_VOLUME; + + mafw_extension_set_property_uint(MAFW_EXTENSION(g_gst_renderer), + p.expected, 50); + + if (!wait_for_property(&p, wait_tout_val)) { + fail("No property %s received", p.expected); + } + + fail_if(p.received == NULL, "No property %s received", + p.expected); + fail_if(p.received != NULL && + g_value_get_uint(p.received) != 50, + "Property with value %d and %d expected", + g_value_get_uint(p.received), 50); + + if (p.received != NULL) { + g_value_unset(p.received); + g_free(p.received); + p.received = NULL; + } + p.expected = NULL; + + c.property_expected = MAFW_PROPERTY_RENDERER_VOLUME; + + mafw_extension_get_property(MAFW_EXTENSION(g_gst_renderer), + c.property_expected, get_property_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "get_property", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + fail_if(c.property_received == NULL, + "No property %s received and expected", c.property_expected); + fail_if(c.property_received != NULL && + g_value_get_uint(c.property_received) != 50, + "Property with value %d and %d expected", + g_value_get_uint(c.property_received), 50); + +#ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME + /* Test reconnection to pulse */ + + pa_context_disconnect(pa_context_get_instance()); + + /* Wait for the volume manager to be reinitialized */ + + /* Volume */ + + p.expected = MAFW_PROPERTY_RENDERER_VOLUME; + + if (!wait_for_property(&p, wait_tout_val)) { + fail("No property %s received", p.expected); + } + + fail_if(p.received == NULL, "No property %s received", + p.expected); + fail_if(p.received != NULL && + g_value_get_uint(p.received) != 48, + "Property with value %d and %d expected", + g_value_get_uint(p.received), 48); + + if (p.received != NULL) { + g_value_unset(p.received); + g_free(p.received); + p.received = NULL; + } + p.expected = NULL; + + reset_callback_info(&c); +#endif +} +END_TEST + +START_TEST(test_buffering) +{ + RendererInfo s; + CallbackInfo c; + BufferingInfo b; + GstBus *bus = NULL; + GstMessage *message = NULL; + + /* Initialize callback info */ + c.err_msg = NULL; + c.error_signal_expected = FALSE; + c.error_signal_received = NULL; + c.property_expected = NULL; + c.property_received = NULL; + b.requested = FALSE; + b.received = FALSE; + b.value = 0.0; + + /* Connect to renderer signals */ + g_signal_connect(g_gst_renderer, "error", + G_CALLBACK(error_cb), + &c); + g_signal_connect(g_gst_renderer, "state-changed", + G_CALLBACK(state_changed_cb), + &s); + g_signal_connect(g_gst_renderer, "buffering-info", + G_CALLBACK(buffering_info_cb), + &b); + + /* --- Get initial status --- */ + + reset_callback_info(&c); + + g_debug("get status..."); + mafw_renderer_get_status(g_gst_renderer, status_cb, &s); + + /* --- Play object --- */ + + reset_callback_info(&c); + + gchar *objectid = get_sample_clip_objectid(SAMPLE_AUDIO_CLIP); + g_debug("play_object... %s", objectid); + mafw_renderer_play_object(g_gst_renderer, objectid, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "playing an object", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Transitioning, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", + "Transitioning", s.state); + } + + if (wait_for_state(&s, Playing, wait_tout_val) == FALSE) { + fail(state_err_msg, "mafw_renderer_play_object", "Playing", + s.state); + } + + g_free(objectid); + + /* --- Buffering info --- */ + + b.requested = TRUE; + + bus = MAFW_GST_RENDERER(g_gst_renderer)->worker->bus; + fail_if(bus == NULL, "No GstBus"); + + message = gst_message_new_buffering(NULL, 50); + gst_bus_post(bus, message); + + if (wait_for_buffering(&b, wait_tout_val) == FALSE) { + fail("Expected buffering message but not received"); + } + + fail_if(b.value != 0.5, "Expected buffering 0.50 and received %1.2f", + b.value); + + b.requested = FALSE; + b.received = FALSE; + b.value = 0; + + /* --- Buffering info --- */ + + b.requested = TRUE; + + message = gst_message_new_buffering(NULL, 100); + gst_bus_post(bus, message); + + if (wait_for_buffering(&b, wait_tout_val) == FALSE) { + fail("Expected buffering message but not received"); + } + + fail_if(b.value != 1.0, "Expected buffering 1.00 and received %1.2f", + b.value); + + b.requested = FALSE; + b.received = FALSE; + b.value = 0; + + /* --- Stop --- */ + + reset_callback_info(&c); + + g_debug("stop..."); + mafw_renderer_stop(g_gst_renderer, playback_cb, &c); + + if (wait_for_callback(&c, wait_tout_val)) { + if (c.error) + fail(callback_err_msg, "stopping", c.err_code, + c.err_msg); + } else { + fail(no_callback_msg); + } + + if (wait_for_state(&s, Stopped, wait_tout_val) == FALSE) { + fail(state_err_msg,"mafw_renderer_stop", "Stopped", s.state); + } +} +END_TEST + +/*---------------------------------------------------------------------------- + Suit creation + ----------------------------------------------------------------------------*/ + +SRunner * configure_tests(void) +{ + SRunner *sr = NULL; + Suite *s = NULL; + const gchar *tout = g_getenv("WAIT_TIMEOUT"); + + if (!tout) + wait_tout_val = DEFAULT_WAIT_TOUT; + else + { + wait_tout_val = (gint)strtol(tout, NULL, 0); + if (wait_tout_val<=0) + wait_tout_val = DEFAULT_WAIT_TOUT; + } + + checkmore_wants_dbus(); + mafw_log_init(":error"); + /* Create the suite */ + s = suite_create("MafwGstRenderer"); + + /* Create test cases */ + TCase *tc1 = tcase_create("Playback"); + + /* Create unit tests for test case "Playback" */ + tcase_add_checked_fixture(tc1, fx_setup_dummy_gst_renderer, + fx_teardown_dummy_gst_renderer); +if (1) tcase_add_test(tc1, test_basic_playback); +if (1) tcase_add_test(tc1, test_playlist_playback); +if (1) tcase_add_test(tc1, test_repeat_mode_playback); +if (1) tcase_add_test(tc1, test_gst_renderer_mode); +if (1) tcase_add_test(tc1, test_update_stats); +if (1) tcase_add_test(tc1, test_play_state); +if (1) tcase_add_test(tc1, test_pause_state); +if (1) tcase_add_test(tc1, test_stop_state); +if (1) tcase_add_test(tc1, test_transitioning_state); +if (1) tcase_add_test(tc1, test_state_class); +if (1) tcase_add_test(tc1, test_playlist_iterator); +if (1) tcase_add_test(tc1, test_video); +if (1) tcase_add_test(tc1, test_media_art); +if (1) tcase_add_test(tc1, test_properties_management); +if (1) tcase_add_test(tc1, test_buffering); + + tcase_set_timeout(tc1, 0); + + suite_add_tcase(s, tc1); + + /* Create srunner object with the test suite */ + sr = srunner_create(s); + + return sr; +} + +/* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */