/* * Copyright 2014 (c) Anna Schumaker. */ #include Driver :: Driver() {} Driver :: ~Driver() {} #ifdef CONFIG_TEST TestDriver :: TestDriver() : playing(false), cur_pos(0), cur_duration(0) {} TestDriver :: ~TestDriver() {} void TestDriver :: init(int *argc, char ***argv, void (*eos_cb)(), void (*error_cb)()) { on_eos = eos_cb; on_error = error_cb; } void TestDriver :: load(const std::string &file) { cur_file = file; playing = false; cur_pos = 0; } bool TestDriver :: play() { playing = true; return true; } bool TestDriver :: pause() { playing = false; return true; } bool TestDriver :: is_playing() { return playing; } void TestDriver :: seek_to(long pos) { cur_pos = pos; } long TestDriver :: position() { return cur_pos; } long TestDriver :: duration() { return cur_duration; } void TestDriver :: eos() { on_eos(); } void TestDriver :: error() { on_error(); } #else /* CONFIG_TEST */ static gboolean on_gst_message(GstBus *bus, GstMessage *message, gpointer data) { GSTDriver *driver = (GSTDriver *)data; driver->on_message(message); return TRUE; } static void parse_gst_error(GstMessage *error, const std::string filepath) { GError *err; gchar *debug; gst_message_parse_error(error, &err, &debug); g_print("Error playing file: %s\n", filepath.c_str()); g_print("Error: %s\n", err->message); g_error_free(err); g_free(debug); } GSTDriver :: GSTDriver() {} GSTDriver :: ~GSTDriver() { change_state(GST_STATE_NULL); gst_deinit(); } bool GSTDriver :: change_state(GstState state) { GstStateChangeReturn ret = gst_element_set_state(player, state); switch (ret) { case GST_STATE_CHANGE_SUCCESS: case GST_STATE_CHANGE_ASYNC: return true; default: return false; } } void GSTDriver :: init(int *argc, char ***argv, void (*eos_cb)(), void (*error_cb)()) { GstBus *bus; on_eos = eos_cb; on_error = error_cb; gst_init(argc, argv); player = gst_element_factory_make("playbin", "ocarina_player"); bus = gst_pipeline_get_bus(GST_PIPELINE(player)); gst_bus_add_watch(bus, on_gst_message, this); } void GSTDriver :: load(const std::string &filepath) { gchar *uri; cur_file = filepath; change_state(GST_STATE_NULL); uri = gst_filename_to_uri(filepath.c_str(), NULL); g_object_set(G_OBJECT(player), "uri", uri, NULL); g_free(uri); } bool GSTDriver :: play() { return change_state(GST_STATE_PLAYING); } bool GSTDriver :: pause() { return change_state(GST_STATE_PAUSED); } bool GSTDriver :: is_playing() { GstState state; gst_element_get_state(player, &state, NULL, GST_CLOCK_TIME_NONE); return state == GST_STATE_PLAYING; } void GSTDriver :: seek_to(long pos) { gst_element_seek_simple(player, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, pos); } long GSTDriver :: position() { long position; if (gst_element_query_position(player, GST_FORMAT_TIME, &position)) return position; return 0; } long GSTDriver :: duration() { long duration; if (gst_element_query_duration(player, GST_FORMAT_TIME, &duration)) return duration; return 0; } void GSTDriver :: on_message(GstMessage *message) { switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_ERROR: parse_gst_error(message, cur_file); on_error(); break; case GST_MESSAGE_EOS: on_eos(); break; default: break; } } #endif /* CONFIG_TEST */ #ifdef CONFIG_TEST static TestDriver cur_driver; #else /* CONFIG_TEST */ static GSTDriver cur_driver; #endif /* CONFIG_TEST */ Driver *driver :: get_driver() { return &cur_driver; }