From patchwork Fri Feb 5 15:17:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 8235771 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D18109F6DA for ; Fri, 5 Feb 2016 15:17:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F211F20384 for ; Fri, 5 Feb 2016 15:17:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 06D2320357 for ; Fri, 5 Feb 2016 15:17:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753614AbcBEPRg (ORCPT ); Fri, 5 Feb 2016 10:17:36 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54993 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751076AbcBEPRf (ORCPT ); Fri, 5 Feb 2016 10:17:35 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D4DFFBC6C1 for ; Fri, 5 Feb 2016 15:17:35 +0000 (UTC) Received: from shalem.localdomain.com (vpn1-5-66.ams2.redhat.com [10.36.5.66]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u15FHX6A004693; Fri, 5 Feb 2016 10:17:34 -0500 From: Hans de Goede To: Linux Media Mailing List Cc: Hans de Goede Subject: [PATCH xawtv3 1/2] alsa: Fix not being able to get a larger latency on capture devices with small max period sizes Date: Fri, 5 Feb 2016 16:17:29 +0100 Message-Id: <1454685450-30470-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- common/alsa_stream.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/common/alsa_stream.c b/common/alsa_stream.c index 3e33b5e..1165554 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; }