[SCM] libgroove/upstream: ability to stop buffering when any sinks are full

andrewrk-guest at users.alioth.debian.org andrewrk-guest at users.alioth.debian.org
Sat Jun 14 01:19:27 UTC 2014


The following commit has been merged in the upstream branch:
commit 33dfd74c9f7c717c1aec79c5325729df395d859b
Author: Andrew Kelley <superjoe30 at gmail.com>
Date:   Fri Jun 13 17:37:01 2014 -0700

    ability to stop buffering when any sinks are full

diff --git a/groove/groove.h b/groove/groove.h
index 7ce546a..ec2fd5d 100644
--- a/groove/groove.h
+++ b/groove/groove.h
@@ -180,8 +180,7 @@ struct GroovePlaylist {
     double gain;
 };
 
-/* a playlist manages keeping an audio buffer full
- * to send the buffer to your speakers, use groove_player_create
+/* a playlist keeps its sinks full.
  */
 struct GroovePlaylist *groove_playlist_create(void);
 /* this will not call groove_file_close on any files
@@ -244,6 +243,20 @@ void groove_playlist_set_item_gain(struct GroovePlaylist *playlist,
 void groove_playlist_set_item_peak(struct GroovePlaylist *playlist,
         struct GroovePlaylistItem *item, double peak);
 
+/* This is the default behavior. The playlist will decode audio if any sinks
+ * are not full. If any sinks do not drain fast enough the data will buffer up
+ * in the playlist.
+ */
+#define GROOVE_EVERY_SINK_FULL 0
+
+/* With this behavior, the playlist will stop decoding audio when any attached
+ * sink is full, and then resume decoding audio every sink is not full.
+ */
+#define GROOVE_ANY_SINK_FULL   1
+
+/* Use this to set the fill mode using the constants above */
+void groove_playlist_set_fill_mode(struct GroovePlaylist *playlist, int mode);
+
 /************ GrooveBuffer ****************/
 
 #define GROOVE_BUFFER_NO  0
diff --git a/groove/playlist.c b/groove/playlist.c
index d41e9fc..ec07b1c 100644
--- a/groove/playlist.c
+++ b/groove/playlist.c
@@ -93,6 +93,8 @@ struct GroovePlaylistPrivate {
     int sent_end_of_q;
 
     struct GroovePlaylistItem *purge_item; // set temporarily
+
+    int (*detect_full_sinks)(struct GroovePlaylist*);
 };
 
 // this is used to tell the difference between a buffer underrun
@@ -511,6 +513,10 @@ static int every_sink_full(struct GroovePlaylist *playlist) {
     return every_sink(playlist, sink_is_full, 1);
 }
 
+static int any_sink_full(struct GroovePlaylist *playlist) {
+    return every_sink(playlist, sink_is_full, 0);
+}
+
 static int sink_signal_end(struct GrooveSink *sink) {
     struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
     groove_queue_put(s->audioq, end_of_q_sentinel);
@@ -669,7 +675,7 @@ static void *decode_thread(void *arg) {
         struct GrooveFile *file = p->decode_head->file;
         struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
 
-        if (every_sink_full(playlist) && (f->seek_pos < 0 || !f->seek_flush)) {
+        if (p->detect_full_sinks(playlist) && (f->seek_pos < 0 || !f->seek_flush)) {
             if (!f->paused) {
                 av_read_pause(f->ic);
                 f->paused = 1;
@@ -926,6 +932,8 @@ struct GroovePlaylist * groove_playlist_create(void) {
     // queue sentinel early.
     p->sent_end_of_q = 1;
 
+    p->detect_full_sinks = every_sink_full;
+
     if (pthread_mutex_init(&p->decode_head_mutex, NULL) != 0) {
         groove_playlist_destroy(playlist);
         av_log(NULL, AV_LOG_ERROR, "unable to allocate mutex\n");
@@ -1320,3 +1328,17 @@ int groove_sink_set_gain(struct GrooveSink *sink, double gain) {
     pthread_mutex_unlock(&p->decode_head_mutex);
     return 0;
 }
+
+void groove_playlist_set_fill_mode(struct GroovePlaylist *playlist, int mode) {
+    struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
+
+    pthread_mutex_lock(&p->decode_head_mutex);
+
+    if (mode == GROOVE_EVERY_SINK_FULL) {
+        p->detect_full_sinks = every_sink_full;
+    } else {
+        p->detect_full_sinks = any_sink_full;
+    }
+
+    pthread_mutex_unlock(&p->decode_head_mutex);
+}

-- 
libgroove packaging



More information about the pkg-multimedia-commits mailing list