This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/xawtv3.git tree:

Subject: alsa: Fix not being able to get a larger latency on capture devices 
with small max period sizes
Author:  Hans de Goede <[email protected]>
Date:    Mon Feb 1 21:43:37 2016 +0100

On some capture devices (e.g. bttv cards) the max period size is somewhat
small. Since we only use 2 perios on these devices we end up with only
allowing small latencies, which is a problem when e.g. using a usb codec
as output.

This commit fixes this by adjusting the amount of periods on the capture
side when this happens.

Signed-off-by: Hans de Goede <[email protected]>

 common/alsa_stream.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/xawtv3.git/commit/?id=daf4665a0d3c1af65b31887575ea8848ad71ace2
diff --git a/common/alsa_stream.c b/common/alsa_stream.c
index 3e33b5e5f7ba..1165554f8e23 100644
--- a/common/alsa_stream.c
+++ b/common/alsa_stream.c
@@ -109,9 +109,10 @@ static void getparams_periods(snd_pcm_t *handle,
                      snd_pcm_hw_params_t *params,
                      unsigned int *usecs,
                      unsigned int *count,
-                     const char *id)
+                     int allow_adjust, const char *id)
 {
     unsigned min = 0, max = 0;
+    unsigned desired = *usecs * *count;
 
     snd_pcm_hw_params_get_periods_min(params, &min, 0);
     snd_pcm_hw_params_get_periods_max(params, &max, 0);
@@ -137,6 +138,13 @@ static void getparams_periods(snd_pcm_t *handle,
        if (*usecs > max)
            *usecs = max;
     }
+
+    /* If we deviate from the desired size by more then 20% adjust count */
+    if (allow_adjust && (((*usecs * *count) < (desired *  8 / 10)) ||
+                         ((*usecs * *count) > (desired * 12 / 10)))) {
+        *count = (desired + *usecs / 2) / *usecs;
+        getparams_periods(handle, params, usecs, count, 0, id);
+    }
 }
 
 static int setparams_periods(snd_pcm_t *handle,
@@ -351,12 +359,16 @@ static int setparams(snd_pcm_t *phandle, snd_pcm_t 
*chandle,
     /* Negotiate period parameters */
 
     c_periodtime = latency * 1000 / c_periods;
-    getparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, 
"capture");
+    getparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, 1, 
"capture");
     p_periods = c_periods * 2;
     p_periodtime = c_periodtime;
-    getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, 
"playback");
+    getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, 0, 
"playback");
     c_periods = p_periods / 2;
 
+    if (verbose)
+       fprintf(error_fp, "alsa: Capture %u periods of %u usecs, Playback %u 
periods of %u usecs\n",
+               c_periods, c_periodtime, p_periods, p_periodtime);
+
     /*
      * Some playback devices support a very limited periodtime range. If the 
user needs to
      * use a higher latency to avoid overrun/underrun, use an alternate 
algorithm of incresing
@@ -365,10 +377,10 @@ static int setparams(snd_pcm_t *phandle, snd_pcm_t 
*chandle,
     if (p_periodtime < c_periodtime) {
        c_periodtime = p_periodtime;
        c_periods = round (latency * 1000.0 / c_periodtime + 0.5);
-       getparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, 
"capture");
+       getparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, 0, 
"capture");
        p_periods = c_periods * 2;
        p_periodtime = c_periodtime;
-       getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, 
"playback");
+       getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, 0, 
"playback");
        c_periods = p_periods / 2;
     }
 

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to