[pulseaudio-discuss] [PATCH RFCv3 48/51] alsa-sink: Assume left_to_play can be computed, save one call to snd_pcm_avail()

Peter Meerwald pmeerw at pmeerw.net
Tue Nov 4 15:26:43 PST 2014


From: Peter Meerwald <p.meerwald at bct-electronic.com>

after a completed write in mmap_write(), compute the new left_to_play instead
of asking ALSA what the new value would be

Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>
---
 src/modules/alsa/alsa-sink.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 3690d8d..0d13716 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -512,13 +512,16 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, bool polled, bo
     bool work_done = false;
     pa_usec_t max_sleep_usec = 0, process_usec = 0;
     size_t left_to_play, input_underrun;
+    size_t sleep_bytes = 0;
     unsigned j = 0;
 
     pa_assert(u);
     pa_sink_assert_ref(u->sink);
 
-    if (u->use_tsched)
+    if (u->use_tsched) {
         hw_sleep_time(u, &max_sleep_usec, &process_usec);
+        sleep_bytes = PA_USEC_TO_BYTES(process_usec + max_sleep_usec/2, &u->sink->sample_spec);
+    }
 
     for (;;) {
         snd_pcm_sframes_t n;
@@ -554,8 +557,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, bool polled, bo
             * need to guarantee that clients only have to keep around
             * a single hw buffer length. */
 
-            if (!polled &&
-                PA_BYTES_TO_USEC(left_to_play, &u->sink->sample_spec) > process_usec+max_sleep_usec/2) {
+            if (!polled && left_to_play > sleep_bytes) {
 #ifdef DEBUG_TIMING
                 pa_log_debug("Not filling up, because too early.");
 #endif
@@ -666,13 +668,21 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, bool polled, bo
             pa_log_debug("Wrote %lu bytes (of possible %lu bytes)", (unsigned long) written, (unsigned long) n_bytes);
 #endif
 
-            if (written >= n_bytes)
-                break;
+            if (written >= n_bytes) {
+                if (u->use_tsched &&
+                    sframes * u->frame_size == n_bytes &&
+                    left_to_play + n_bytes > sleep_bytes) {
+                    left_to_play += n_bytes;
+                    goto done;
+                } else
+                    break;
+            }
 
             n_bytes -= written;
         }
     }
 
+done:
     input_underrun = pa_sink_process_input_underruns(u->sink, left_to_play);
 
     if (u->use_tsched) {
-- 
1.9.1



More information about the pulseaudio-discuss mailing list