All pastes #959808 Raw Edit

playback_filling_state.patch

public diff v1 · immutable
#959808 ·published 2008-03-27 18:25 UTC
rendered paste body
diff --git a/apps/playback.c b/apps/playback.cindex 421783e..4cdd721 100644--- a/apps/playback.c+++ b/apps/playback.c@@ -142,6 +142,14 @@ enum { #endif }; +enum filling_state {+    STATE_IDLE,+    STATE_WAITING,+    STATE_FILLING,+    STATE_FULL,+    STATE_FINISHED,+};+ /* As defined in plugins/lib/xxx2wav.h */ #if MEM > 1 #define MALLOC_BUFSIZE (512*1024)@@ -231,6 +239,8 @@ static int last_peek_offset = 0; /* Scrobbler support */ static unsigned long prev_track_elapsed = 0; /* Previous track elapsed time (C/A-)*/ +static enum filling_state filling;+ /* Track change controls */ static bool automatic_skip = false; /* Who initiated in-progress skip? (C/A-) */ static bool playlist_end = false;   /* Has the current playlist ended? (A) */@@ -1493,9 +1503,13 @@ static void buffering_audio_callback(enum callback_event ev, int value)     switch (ev)     {         case EVENT_BUFFER_LOW:-            LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER");-            queue_remove_from_head(&audio_queue, Q_AUDIO_FILL_BUFFER);-            queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);+            if (filling == STATE_WAITING || filling == STATE_FULL) {+                /* force a refill */+                filling = STATE_FILLING;+                LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER");+                queue_remove_from_head(&audio_queue, Q_AUDIO_FILL_BUFFER);+                queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);+            }             break;          case EVENT_HANDLE_REBUFFER:@@ -1709,6 +1723,8 @@ static bool audio_load_track(int offset, bool start_play)         logf("End-of-playlist");         playlist_end = true;         memset(&lasttrack_id3, 0, sizeof(struct mp3entry));+        filling = STATE_FINISHED;+        logf("finished buffering tracks");         return false;     } @@ -1741,7 +1757,7 @@ static bool audio_load_track(int offset, bool start_play)                 last_peek_offset--;                 close(fd);                 copy_mp3entry(&lasttrack_id3, &id3);-                return false;+                goto buffer_full;             }              if (track_widx == track_ridx)@@ -1806,7 +1822,7 @@ static bool audio_load_track(int offset, bool start_play)         if (tracks[track_widx].codec_hid == ERR_BUFFER_FULL)         {             /* No space for codec on buffer, not an error */-            return false;+            goto buffer_full;         }          /* This is an error condition, either no codec was found, or reading@@ -1874,7 +1890,7 @@ static bool audio_load_track(int offset, bool start_play)     tracks[track_widx].audio_hid = bufopen(trackname, file_offset, type);      if (tracks[track_widx].audio_hid < 0)-        return false;+        goto buffer_full;      /* All required data is now available for the codec. */     tracks[track_widx].taginfo_ready = true;@@ -1888,6 +1904,11 @@ static bool audio_load_track(int offset, bool start_play)     track_widx = (track_widx + 1) & MAX_TRACK_MASK;      return true;++buffer_full:+    logf("buffer is full for now");+    filling = STATE_FULL;+    return false; }  static void audio_fill_file_buffer(bool start_play, size_t offset)@@ -1919,16 +1940,8 @@ static void audio_fill_file_buffer(bool start_play, size_t offset)         start_play = false;         offset = 0;         sleep(1);-        if (queue_peek(&audio_queue, &ev)) {-            if (ev.id != Q_AUDIO_FILL_BUFFER)-            {-                /* There's a message in the queue. break the loop to treat it,-                and go back to filling after that. */-                LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER");-                queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);-            }+        if (queue_peek(&audio_queue, &ev))             break;-        }     } while (continue_buffering);      if (!had_next_track && audio_next_track())@@ -1953,6 +1966,7 @@ static void audio_rebuffer(void)     if (!CUR_TI->taginfo_ready)         memset(&curtrack_id3, 0, sizeof(struct mp3entry)); +    filling = STATE_FILLING;     audio_fill_file_buffer(false, 0); } @@ -2056,6 +2070,7 @@ static int audio_check_new_track(void)             {                 tracks[idx].audio_hid = -1;                 tracks[idx].filesize = 0;+                filling = STATE_WAITING;             }         }     }@@ -2182,6 +2197,8 @@ static void audio_stop_playback(void)     audio_stop_codec_flush();     playing = false; +    filling = STATE_IDLE;+     /* Mark all entries null. */     audio_clear_track_entries(); @@ -2231,6 +2248,9 @@ static void audio_play_start(size_t offset) #ifndef HAVE_FLASH_STORAGE     set_filebuf_watermark(buffer_margin, 0); #endif++    filling = STATE_FILLING;+     audio_fill_file_buffer(true, offset);     register_buffering_callback(buffering_audio_callback); @@ -2414,11 +2434,17 @@ static void audio_thread(void)             queue_wait_w_tmo(&audio_queue, &ev, HZ/2);          switch (ev.id) {+             case Q_AUDIO_FILL_BUFFER:                 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER");-                if (!playing || playlist_end || ci.stop_codec)-                    break;-                audio_fill_file_buffer(false, 0);+                switch (filling) {+                    case STATE_WAITING:+                        audio_fill_file_buffer(false, 0);+                        break;++                    default:+                        break;+                }                 break;              case Q_AUDIO_PLAY:@@ -2434,6 +2460,7 @@ static void audio_thread(void)              case Q_AUDIO_STOP:                 LOGFQUEUE("audio < Q_AUDIO_STOP");+                filling = STATE_IDLE;                 if (playing)                     audio_stop_playback();                 if (ev.data != 0)@@ -2520,6 +2547,8 @@ static void audio_thread(void)              case SYS_TIMEOUT:                 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT");+                if (filling == STATE_FILLING)+                    audio_fill_file_buffer(false, 0);                 break;              default: