Index: jamboree/configure.in =================================================================== --- jamboree.orig/configure.in 2005-06-02 12:20:56.612465896 +0200 +++ jamboree/configure.in 2005-06-02 12:21:09.213550240 +0200 @@ -47,7 +47,7 @@ AM_CONDITIONAL(HAVE_DBUS, test x$have_dbus = xyes) -GST_VER=0.8.8 +GST_VER=0.9.0 dnl Dependencies dnl ========================== @@ -56,13 +56,14 @@ gnome-vfs-2.0 >= 2.8.0 libglade-2.0 esound >= 0.2.30 - gstreamer-0.8 >= $GST_VER gstreamer-control-0.8 >= $GST_VER gstreamer-gconf-0.8 >= $GST_VER + gstreamer-0.9 >= $GST_VER gstreamer-control-0.9 >= $GST_VER $dbus_pkgconfig ]) AC_SUBST(JAMBOREE_CFLAGS) AC_SUBST(JAMBOREE_LIBS) +GST_INSPECT=gst-inspect-0.9 missing= AM_GST_ELEMENT_CHECK(decodebin,,missing="$missing decodebin") AM_GST_ELEMENT_CHECK(volume,,missing="$missing volume") @@ -144,6 +145,7 @@ data/glade/Makefile data/images/Makefile po/Makefile.in +test/Makefile ]) echo Index: jamboree/src/player.c =================================================================== --- jamboree.orig/src/player.c 2005-06-02 12:20:56.613465744 +0200 +++ jamboree/src/player.c 2005-06-02 12:21:09.231547504 +0200 @@ -22,7 +22,7 @@ #include #include #include -#include +/* #include */ #include #include #include "jamboree-marshal.h" @@ -62,7 +62,7 @@ struct _Player { GObject parent; - GstElement *thread; + GstElement *pipeline; GstElement *source; GstElement *decoder; GstElement *audioconvert; @@ -189,7 +189,7 @@ PlayingState player_get_state (void) { - if (!player->thread) { + if (!player->pipeline) { return PLAYING_STATE_STOPPED; } @@ -201,85 +201,66 @@ } static gboolean -eos_idle_cb (void) +message_received (GstBus * bus, GstMessage * message, gpointer unused) { - d(g_print ("eos_idle_cb\n")); - - if (player->has_error) { - return FALSE; - } - - player_stop (); - - g_signal_emit (player, signals[TICK], 0, (int) 0); - g_signal_emit (player, signals[EOS], 0, player->current_song, NULL); - - ///g_signal_emit (player, signals[STATE_CHANGED], 0, PLAYING_STATE_STOPPED); - - return FALSE; -} - -static void -eos_cb (GstElement *element, gpointer data) -{ - g_idle_add_full (G_PRIORITY_HIGH, (GSourceFunc) eos_idle_cb, player, NULL); -} - -static gboolean -error_idle_cb (GError *error) -{ - d(g_print ("error_idle_cb\n")); - - if (!player->has_error) { - return FALSE; - } - - player_stop (); - - g_signal_emit (player, signals[TICK], 0, (int) 0); - g_signal_emit (player, signals[ERROR], 0, error); - g_signal_emit (player, signals[STATE_CHANGED], 0, PLAYING_STATE_STOPPED); - - g_error_free (error); - - return FALSE; -} - -static void -error_cb (GObject *object, - GstElement *origin, - GError *error, - char *debug, - Player *player) -{ - GError *new_error; - - if (player->has_error) { - return; - } - - if (g_getenv ("JAM_DEBUG_GST")) { - g_print ("error origin: %p, domain: %d, msg: %s\n", origin, error->domain, error->message); - } - - if (origin == player->sink && error->domain == GST_RESOURCE_ERROR) { - new_error = g_error_new (PLAYER_ERROR, - PLAYER_ERROR_RESOURCE_BUSY, - _("The audio device is busy.")); - } else { - new_error = g_error_copy (error); - } + switch (message->type) { + case GST_MESSAGE_EOS: + if (!player->has_error) { + player_stop (); + g_signal_emit (player, signals[TICK], 0, (int) 0); + g_signal_emit (player, signals[EOS], 0, player->current_song, NULL); + ///g_signal_emit (player, signals[STATE_CHANGED], 0, PLAYING_STATE_STOPPED); + } + break; - player->has_error = TRUE; + case GST_MESSAGE_ERROR: + if (!player->has_error) { + GError *error, *new_error; + gchar *debug; + GstObject *src; + + gst_message_parse_error (message, &error, &debug); + src = GST_MESSAGE_SRC (message); + + player->has_error = TRUE; + + if (g_getenv ("JAM_DEBUG_GST")) { + g_print ("error origin: %p, domain: %d, msg: %s\n", + src, error->domain, error->message); + } + + if (src == (GstObject*)player->sink && error->domain == GST_RESOURCE_ERROR) { + new_error = g_error_new (PLAYER_ERROR, + PLAYER_ERROR_RESOURCE_BUSY, + _("The audio device is busy.")); + } else { + new_error = g_error_copy (error); + } + + player_stop (); + g_signal_emit (player, signals[TICK], 0, (int) 0); + g_signal_emit (player, signals[ERROR], 0, new_error); + g_signal_emit (player, signals[STATE_CHANGED], 0, PLAYING_STATE_STOPPED); + } + break; + + default: + break; + } - g_idle_add_full (G_PRIORITY_HIGH, (GSourceFunc) error_idle_cb, new_error, NULL); + return TRUE; } static gboolean tick_timeout_cb (void) { if (!player->has_error && player->playing && player->sink) { - if (gst_element_get_state (player->sink) == GST_STATE_PLAYING) { + GstElementStateReturn res; + GstElementState state, pending; + GTimeVal tv = { 0, 50 }; + + res = gst_element_get_state (player->sink, &state, &pending, &tv); + if (res == GST_STATE_SUCCESS && state == GST_STATE_PLAYING) { g_signal_emit (player, signals[TICK], 0, (int) timer_get_time ()); } } @@ -321,7 +302,7 @@ return FALSE; } - if (!player->thread) { + if (!player->pipeline) { return player_play_song (player->current_song, error); } @@ -372,7 +353,7 @@ emit = player->playing; player->playing = FALSE; - if (player->thread) { + if (player->pipeline) { /* Reset the location so we close the file as soon as possible * if something below fails. This seems to help against Jamboree * keeping lots of played files open indefinitely. @@ -381,7 +362,7 @@ g_object_set (player->source, "location", NULL, NULL); } - gst_element_set_state (player->thread, GST_STATE_NULL); + gst_element_set_state (player->pipeline, GST_STATE_NULL); /* If these are not added, we need to free them ourselves. */ if (!gst_element_get_parent (player->audioconvert)) { @@ -391,9 +372,9 @@ g_object_unref (player->sink); } - gst_object_unref (GST_OBJECT (player->thread)); + gst_object_unref (GST_OBJECT (player->pipeline)); - player->thread = NULL; + player->pipeline = NULL; player->source = NULL; player->decoder = NULL; player->audioconvert = NULL; @@ -446,20 +427,20 @@ void player_seek (int t) { - if (!player->thread || !player->sink) { + if (!player->pipeline || !player->sink) { return; } - if (gst_element_set_state (player->thread, GST_STATE_PAUSED) != GST_STATE_SUCCESS) { + if (gst_element_set_state (player->pipeline, GST_STATE_PAUSED) != GST_STATE_SUCCESS) { return; } timer_stop (); - gst_element_seek (player->sink, GST_SEEK_METHOD_SET | GST_FORMAT_TIME, t * GST_SECOND); + gst_element_seek (player->sink, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH | GST_FORMAT_TIME, t * GST_SECOND); if (player->playing) { - gst_element_set_state (player->thread, GST_STATE_PLAYING); + gst_element_set_state (player->pipeline, GST_STATE_PLAYING); timer_start (); } @@ -496,14 +477,15 @@ player_update_state (void) { if (player->playing) { - gst_element_set_state (player->thread, GST_STATE_PLAYING); + gst_element_set_state (player->pipeline, GST_STATE_PAUSED); + gst_element_set_state (player->pipeline, GST_STATE_PLAYING); timer_start (); start_tick (); } else { stop_tick (); - if (player->thread) { - gst_element_set_state (player->thread, GST_STATE_PAUSED); + if (player->pipeline) { + gst_element_set_state (player->pipeline, GST_STATE_PAUSED); gst_element_set_state (player->sink, GST_STATE_NULL); timer_pause (); @@ -534,26 +516,19 @@ caps = gst_pad_get_caps (pad); str = gst_caps_get_structure (caps, 0); if (!g_strrstr (gst_structure_get_name (str), "audio")) { - gst_caps_free (caps); + gst_caps_unref (caps); return; } - gst_caps_free (caps); + gst_caps_unref (caps); gst_pad_link (pad, audio_pad); - gst_bin_add_many (GST_BIN (player->thread), - player->audioconvert, - player->audioscale, - player->volume, - player->sink, - NULL); - gst_bin_sync_children_state (GST_BIN (player->thread)); } static GstElement * create_pipeline (const char *sink_name, GError **error) { - GstElement *thread; + GstElement *pipeline; GstElement *source; GstElement *decodebin; GstElement *audioconvert; @@ -563,16 +538,16 @@ /* src -> decodebin -> audioconvert -> audioscale -> volume -> sink */ - thread = gst_element_factory_make ("thread", "thread"); + pipeline = gst_element_factory_make ("pipeline", "pipeline"); source = gst_element_factory_make ("filesrc", "source"); decodebin = gst_element_factory_make ("decodebin", "decoder"); audioconvert = gst_element_factory_make ("audioconvert", "audioconvert"); - audioscale = gst_element_factory_make ("audioscale", "audioscale"); + audioscale = gst_element_factory_make ("identity", "audioscale"); volume = gst_element_factory_make ("volume", "volume"); sink = gst_element_factory_make (sink_name, "sink"); if (g_getenv ("JAM_DEBUG_GST")) { - g_print ("thread: %s\n", thread ? "OK" : "failed"); + g_print ("pipeline: %s\n", pipeline ? "OK" : "failed"); g_print ("source: %s\n", source ? "OK" : "failed"); g_print ("decodebin: %s\n", decodebin ? "OK" : "failed"); g_print ("audioconvert: %s\n", audioconvert ? "OK" : "failed"); @@ -581,11 +556,19 @@ g_print ("sink: %s (%s)\n", sink ? "OK" : "failed", sink_name); } - if (!thread || !source || !decodebin || !audioconvert || !audioscale || !volume || !sink) { + if (!pipeline || !source || !decodebin || !audioconvert || !audioscale || !volume || !sink) { goto fail; } - gst_bin_add_many (GST_BIN (thread), source, decodebin, NULL); + gst_bin_add_many (GST_BIN (pipeline), + source, + decodebin, + audioconvert, + audioscale, + volume, + sink, + NULL); + if (!gst_element_link_many (source, decodebin, NULL)) { goto fail; } @@ -601,15 +584,15 @@ player->volume = volume; player->sink = sink; - return thread; + return pipeline; fail: /* This is pretty much fatal so don't bother too much with cleaning * up. */ - if (thread) { - g_object_unref (thread); + if (pipeline) { + g_object_unref (pipeline); } g_set_error (error, @@ -625,10 +608,11 @@ { char *sink_name; GstDParamManager *dpman; + GstBus *bus; player->has_error = FALSE; - if (player->thread) { + if (player->pipeline) { player_stop (); } @@ -659,20 +643,19 @@ return FALSE; } - player->thread = create_pipeline (sink_name, error); + player->pipeline = create_pipeline (sink_name, error); g_free (sink_name); - if (!player->thread) { + if (!player->pipeline) { goto bail; } g_object_set (player->source, "location", song_get_path (player->current_song), NULL); - g_signal_connect (player->thread, - "error", - G_CALLBACK (error_cb), - player); + bus = gst_element_get_bus (player->pipeline); + gst_bus_add_watch (bus, message_received, NULL); + gst_object_unref ((GstObject*)bus); g_signal_connect (player->decoder, "new_decoded_pad", @@ -684,13 +667,6 @@ gst_dpman_attach_dparam (dpman, "volume", player->volume_dparam); player_set_volume (player->volume_level); - g_signal_connect (player->sink, - "eos", - G_CALLBACK (eos_cb), - player); - - player_update_state (); - return TRUE; bail: @@ -804,7 +780,7 @@ { char *sink_name; - sink_name = gst_gconf_get_string ("default/audiosink"); + sink_name = g_strdup ("alsasink"); /* gstgconf_get_string ("default/audiosink"); */ if (!sink_name) { g_warning ("GStreamer gconf setup broken, please check your installation. " Index: jamboree/test/Makefile.am =================================================================== --- jamboree.orig/test/Makefile.am 2005-06-02 12:32:08.659299248 +0200 +++ jamboree/test/Makefile.am 2005-06-02 12:34:13.232361264 +0200 @@ -1,2 +1,9 @@ +noinst_PROGRAMS=read-tags +read_tags_SOURCES=read-tags.c \ + $(top_srcdir)/src/tag-reader.c \ + $(top_srcdir)/src/song.c \ + $(top_srcdir)/src/string-utils.c +read_tags_CFLAGS=$(JAMBOREE_CFLAGS) +read_tags_LDFLAGS=$(JAMBOREE_LIBS) Index: jamboree/test/read-tags.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ jamboree/test/read-tags.c 2005-06-02 12:34:13.233361112 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2004-2005 Imendio AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include +#include "../src/string-utils.h" +#include "../src/tag-reader.h" + + +static void +usage (gchar *prog) +{ + g_print ("usage: %s MEDIA-FILE\n", prog); + exit (1); +} + +static void +song_read (Song *song, + gpointer user_data) +{ + _song_print (song); +} + +static gboolean +song_found (const char *path, + gpointer user_data) +{ + /* g_print ("Adding song %s...\n", path); */ + return TRUE; +} + +static gboolean +progress (const char *path, + gpointer user_data) +{ + return TRUE; +} + +int +main (int argc, char **argv) +{ + gst_init (&argc, &argv); + shared_string_init (); + + if (argc != 2) { + usage (argv[0]); + } + + if (!tag_reader_read_path (argv[1], + song_found, + song_read, + progress, + NULL)) { + g_print ("Error reading %s\n", argv[1]); + return 1; + } + + g_print ("Successfully read %s\n", argv[1]); + return 0; +}