[banshee/gapless-ng: 11/836] [libbanshee] Explicitly set audiosink's buffer-length This is useful for gapless - it gives more tim
- From: Christopher James Halse Rogers <chrishr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee/gapless-ng: 11/836] [libbanshee] Explicitly set audiosink's buffer-length This is useful for gapless - it gives more tim
- Date: Thu, 25 Feb 2010 22:42:22 +0000 (UTC)
commit b9f04cafe7764673c887be7a49185eff9ce3fdfd
Author: Christopher James Halse Rogers <raof ubuntu com>
Date: Tue Jun 16 17:39:15 2009 +1000
[libbanshee] Explicitly set audiosink's buffer-length
This is useful for gapless - it gives more time to handle the about-to-finish callback
libbanshee/banshee-player-pipeline.c | 72 ++++++++++++++++++++++++++-------
libbanshee/banshee-player-private.h | 3 +
2 files changed, 59 insertions(+), 16 deletions(-)
---
diff --git a/libbanshee/banshee-player-pipeline.c b/libbanshee/banshee-player-pipeline.c
index d246c92..ca88e20 100644
--- a/libbanshee/banshee-player-pipeline.c
+++ b/libbanshee/banshee-player-pipeline.c
@@ -62,6 +62,38 @@ bp_pipeline_process_tag (const GstTagList *tag_list, const gchar *tag_name, Bans
}
}
+void bp_try_set_audiosink_buffer (GstElement *element, guint64 *buffer_len)
+{
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (element), "buffer-time")) {
+ g_object_set (G_OBJECT (element), "buffer-time", *buffer_len, NULL);
+ }
+ gst_object_unref (G_OBJECT (element));
+}
+
+static void
+bp_set_audiosink_buffer_length (BansheePlayer *player, guint64 buffer_len)
+{
+ GstIterator *sink_iterator;
+ GstIteratorResult iter_result;
+ GstElement *audiosink;
+
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+ audiosink = player->audiosink;
+ // If we've directly selected alsasink or directsoundsink then we'll have a
+ // buffer-time property on audiosink. If so, just set this and return.
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (audiosink), "buffer-time")) {
+ g_object_set (G_OBJECT (audiosink), "buffer-time", buffer_len, NULL);
+ return;
+ }
+ // If we've selected an auto audio sink, then the real audio sink is a child of the bin.
+ sink_iterator = gst_bin_iterate_recurse (GST_BIN (audiosink));
+ iter_result = gst_iterator_foreach (sink_iterator, (GFunc)&bp_try_set_audiosink_buffer, &buffer_len);
+ if (iter_result == GST_ITERATOR_ERROR) {
+ bp_debug ("Failed to set audio buffer length: failed to find sink");
+ }
+ gst_iterator_free (sink_iterator);
+}
+
static gboolean
bp_pipeline_bus_callback (GstBus *bus, GstMessage *message, gpointer userdata)
{
@@ -81,7 +113,15 @@ bp_pipeline_bus_callback (GstBus *bus, GstMessage *message, gpointer userdata)
case GST_MESSAGE_STATE_CHANGED: {
GstState old, new, pending;
gst_message_parse_state_changed (message, &old, &new, &pending);
-
+
+ if (new == GST_STATE_READY) {
+ // Explicitly set the buffer length to a value above the default.
+ // This increases the deadline for setting the URI after about-to-finish is triggered
+ // when using playbin2 for gapless playback.
+ //
+ // gconfaudiosink only has a real audiosink in it once it's made a transition to READY.
+ bp_set_audiosink_buffer_length (player, BP_BUFFER_LEN_MICROSECONDS);
+ }
_bp_missing_elements_handle_state_changed (player, old, new);
_bp_replaygain_handle_state_changed (player, old, new, pending);
@@ -194,26 +234,26 @@ _bp_pipeline_construct (BansheePlayer *player)
// Try to find an audio sink, prefer gconf, which typically is set to auto these days,
// fall back on auto, which should work on windows, and as a last ditch, try alsa
- audiosink = gst_element_factory_make ("gconfaudiosink", "audiosink");
- if (audiosink == NULL) {
- audiosink = gst_element_factory_make ("directsoundsink", "audiosink");
- if (audiosink != NULL) {
- g_object_set (G_OBJECT (audiosink), "volume", 1.0, NULL);
+ player->audiosink = gst_element_factory_make ("gconfaudiosink", "audiosink");
+ if (player->audiosink == NULL) {
+ player->audiosink = gst_element_factory_make ("directsoundsink", "audiosink");
+ if (player->audiosink != NULL) {
+ g_object_set (G_OBJECT (player->audiosink), "volume", 1.0, NULL);
} else {
- audiosink = gst_element_factory_make ("autoaudiosink", "audiosink");
- if (audiosink == NULL) {
- audiosink = gst_element_factory_make ("alsasink", "audiosink");
+ player->audiosink = gst_element_factory_make ("autoaudiosink", "audiosink");
+ if (player->audiosink == NULL) {
+ player->audiosink = gst_element_factory_make ("alsasink", "audiosink");
}
}
}
- g_return_val_if_fail (audiosink != NULL, FALSE);
+ g_return_val_if_fail (player->audiosink != NULL, FALSE);
// Set the profile to "music and movies" (gst-plugins-good 0.10.3)
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (audiosink), "profile")) {
- g_object_set (G_OBJECT (audiosink), "profile", 1, NULL);
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (player->audiosink), "profile")) {
+ g_object_set (G_OBJECT (player->audiosink), "profile", 1, NULL);
}
-
+
// Create a custom audio sink bin that will hold the real primary sink
player->audiobin = gst_bin_new ("audiobin");
g_return_val_if_fail (player->audiobin != NULL, FALSE);
@@ -244,7 +284,7 @@ _bp_pipeline_construct (BansheePlayer *player)
}
gst_bin_add (GST_BIN (player->audiobin), audiosinkqueue);
- gst_bin_add (GST_BIN (player->audiobin), audiosink);
+ gst_bin_add (GST_BIN (player->audiobin), player->audiosink);
// Ghost pad the audio bin so audio is passed from the bin into the tee
teepad = gst_element_get_pad (player->audiotee, "sink");
@@ -255,10 +295,10 @@ _bp_pipeline_construct (BansheePlayer *player)
if (player->equalizer != NULL) {
// link in equalizer, preamp and audioconvert.
gst_element_link_many (audiosinkqueue, eq_audioconvert, player->preamp,
- player->equalizer, eq_audioconvert2, audiosink, NULL);
+ player->equalizer, eq_audioconvert2, player->audiosink, NULL);
} else {
// link the queue with the real audio sink
- gst_element_link (audiosinkqueue, audiosink);
+ gst_element_link (audiosinkqueue, player->audiosink);
}
_bp_vis_pipeline_setup (player);
diff --git a/libbanshee/banshee-player-private.h b/libbanshee/banshee-player-private.h
index 5cbaa40..70b10f0 100644
--- a/libbanshee/banshee-player-private.h
+++ b/libbanshee/banshee-player-private.h
@@ -68,6 +68,8 @@
#define bp_debug(x...) banshee_log_debug ("player", x)
#endif
+#define BP_BUFFER_LEN_MICROSECONDS 1000000
+
typedef struct BansheePlayer BansheePlayer;
typedef void (* BansheePlayerEosCallback) (BansheePlayer *player);
@@ -100,6 +102,7 @@ struct BansheePlayer {
// Pipeline Elements
GstElement *playbin;
+ GstElement *audiosink;
GstElement *audiotee;
GstElement *audiobin;
GstElement *equalizer;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]