* [PATCH 01/10] alsa_stream: port changes made on xawtv3
@ 2011-09-06 15:29 Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 02/10] Fix make dist target Mauro Carvalho Chehab
` (2 more replies)
0 siblings, 3 replies; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
There are several issues with the original alsa_stream code that got
fixed on xawtv3, made by me and by Hans de Goede. Basically, the
code were re-written, in order to follow the alsa best practises.
Backport the changes from xawtv, in order to make it to work on a
wider range of V4L and sound adapters.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
src/alsa_stream.c | 629 ++++++++++++++++++++++++++++++-----------------------
src/alsa_stream.h | 6 +-
src/tvtime.c | 6 +-
3 files changed, 363 insertions(+), 278 deletions(-)
diff --git a/src/alsa_stream.c b/src/alsa_stream.c
index 2243b02..b6a41a5 100644
--- a/src/alsa_stream.c
+++ b/src/alsa_stream.c
@@ -6,6 +6,9 @@
* Derived from the alsa-driver test tool latency.c:
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
+ * Copyright (c) 2011 - Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Ported to xawtv, with bug fixes and improvements
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -32,8 +35,16 @@
#include <alsa/asoundlib.h>
#include <sys/time.h>
#include <math.h>
+#include "alsa_stream.h"
+
+/* Private vars to control alsa thread status */
+static int alsa_is_running = 0;
+static int stop_alsa = 0;
+/* Error handlers */
snd_output_t *output = NULL;
+FILE *error_fp;
+int verbose = 0;
struct final_params {
int bufsize;
@@ -42,403 +53,435 @@ struct final_params {
int channels;
};
-int setparams_stream(snd_pcm_t *handle,
- snd_pcm_hw_params_t *params,
- snd_pcm_format_t format,
- int channels,
- int rate,
- const char *id)
+static int setparams_stream(snd_pcm_t *handle,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_format_t format,
+ int channels,
+ const char *id)
{
int err;
- unsigned int rrate;
err = snd_pcm_hw_params_any(handle, params);
if (err < 0) {
- printf("Broken configuration for %s PCM: no configurations available: %s\n", snd_strerror(err), id);
- return err;
- }
- err = snd_pcm_hw_params_set_rate_resample(handle, params, 1);
- if (err < 0) {
- printf("Resample setup failed for %s: %s\n", id, snd_strerror(err));
+ fprintf(error_fp,
+ "alsa: Broken configuration for %s PCM: no configurations available: %s\n",
+ snd_strerror(err), id);
return err;
}
+
err = snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
- printf("Access type not available for %s: %s\n", id,
- snd_strerror(err));
+ fprintf(error_fp, "alsa: Access type not available for %s: %s\n", id,
+ snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_format(handle, params, format);
if (err < 0) {
- printf("Sample format not available for %s: %s\n", id,
+ fprintf(error_fp, "alsa: Sample format not available for %s: %s\n", id,
snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_channels(handle, params, channels);
if (err < 0) {
- printf("Channels count (%i) not available for %s: %s\n", channels, id,
- snd_strerror(err));
- return err;
- }
- rrate = rate;
- err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
- if (err < 0) {
- printf("Rate %iHz not available for %s: %s\n", rate, id,
- snd_strerror(err));
+ fprintf(error_fp, "alsa: Channels count (%i) not available for %s: %s\n",
+ channels, id, snd_strerror(err));
return err;
}
- if ((int)rrate != rate) {
- printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
- return -EINVAL;
- }
+
return 0;
}
-int setparams_bufsize(snd_pcm_t *handle,
+static void getparams_periods(snd_pcm_t *handle,
snd_pcm_hw_params_t *params,
- snd_pcm_hw_params_t *tparams,
- snd_pcm_uframes_t bufsize,
- int period_size,
+ unsigned int *usecs,
+ unsigned int *count,
+ const char *id)
+{
+ unsigned min = 0, max = 0;
+
+ snd_pcm_hw_params_get_periods_min(params, &min, 0);
+ snd_pcm_hw_params_get_periods_max(params, &max, 0);
+ if (min && max) {
+ if (verbose)
+ fprintf(error_fp, "alsa: %s periods range between %u and %u. Want: %u\n",
+ id, min, max, *count);
+ if (*count < min)
+ *count = min;
+ if (*count > max)
+ *count = max;
+ }
+
+ min = max = 0;
+ snd_pcm_hw_params_get_period_time_min(params, &min, 0);
+ snd_pcm_hw_params_get_period_time_max(params, &max, 0);
+ if (min && max) {
+ if (verbose)
+ fprintf(error_fp, "alsa: %s period time range between %u and %u. Want: %u\n",
+ id, min, max, *usecs);
+ if (*usecs < min)
+ *usecs = min;
+ if (*usecs > max)
+ *usecs = max;
+ }
+}
+
+static int setparams_periods(snd_pcm_t *handle,
+ snd_pcm_hw_params_t *params,
+ unsigned int *usecs,
+ unsigned int *count,
const char *id)
{
int err;
- snd_pcm_uframes_t periodsize;
- snd_pcm_hw_params_copy(params, tparams);
- periodsize = bufsize * 2;
- err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &periodsize);
+ err = snd_pcm_hw_params_set_period_time_near(handle, params, usecs, 0);
if (err < 0) {
- printf("Unable to set buffer size %li for %s: %s\n",
- bufsize * 2, id, snd_strerror(err));
- return err;
+ fprintf(error_fp, "alsa: Unable to set period time %u for %s: %s\n",
+ *usecs, id, snd_strerror(err));
+ return err;
}
- if (period_size > 0)
- periodsize = period_size;
- else
- periodsize /= 2;
- err = snd_pcm_hw_params_set_period_size_near(handle, params, &periodsize,
- 0);
+
+ err = snd_pcm_hw_params_set_periods_near(handle, params, count, 0);
if (err < 0) {
- printf("Unable to set period size %li for %s: %s\n", periodsize, id,
- snd_strerror(err));
+ fprintf(error_fp, "alsa: Unable to set %u periods for %s: %s\n",
+ *count, id, snd_strerror(err));
return err;
}
+
+ if (verbose)
+ fprintf(error_fp, "alsa: %s period set to %u periods of %u time\n",
+ id, *count, *usecs);
+
return 0;
}
-int setparams_set(snd_pcm_t *handle,
- snd_pcm_hw_params_t *params,
- snd_pcm_sw_params_t *swparams,
- const char *id)
+static int setparams_set(snd_pcm_t *handle,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_sw_params_t *swparams,
+ snd_pcm_uframes_t start_treshold,
+ const char *id)
{
int err;
err = snd_pcm_hw_params(handle, params);
if (err < 0) {
- printf("Unable to set hw params for %s: %s\n", id, snd_strerror(err));
+ fprintf(error_fp, "alsa: Unable to set hw params for %s: %s\n",
+ id, snd_strerror(err));
return err;
}
err = snd_pcm_sw_params_current(handle, swparams);
if (err < 0) {
- printf("Unable to determine current swparams for %s: %s\n", id,
- snd_strerror(err));
+ fprintf(error_fp, "alsa: Unable to determine current swparams for %s: %s\n",
+ id, snd_strerror(err));
return err;
}
- err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0x7fffffff);
+ err = snd_pcm_sw_params_set_start_threshold(handle, swparams,
+ start_treshold);
if (err < 0) {
- printf("Unable to set start threshold mode for %s: %s\n", id,
- snd_strerror(err));
+ fprintf(error_fp, "alsa: Unable to set start threshold mode for %s: %s\n",
+ id, snd_strerror(err));
return err;
}
err = snd_pcm_sw_params_set_avail_min(handle, swparams, 4);
if (err < 0) {
- printf("Unable to set avail min for %s: %s\n", id, snd_strerror(err));
+ fprintf(error_fp, "alsa: Unable to set avail min for %s: %s\n",
+ id, snd_strerror(err));
return err;
}
err = snd_pcm_sw_params(handle, swparams);
if (err < 0) {
- printf("Unable to set sw params for %s: %s\n", id, snd_strerror(err));
+ fprintf(error_fp, "alsa: Unable to set sw params for %s: %s\n",
+ id, snd_strerror(err));
return err;
}
return 0;
}
-int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, snd_pcm_format_t format,
- struct final_params *negotiated)
+static int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle,
+ snd_pcm_format_t format,
+ int latency, int allow_resample,
+ struct final_params *negotiated)
{
- int rate = 48000;
- int latency_min = 600; /* in frames / 2 */
- int channels = 2;
- int latency = latency_min - 4;
- int bufsize = latency;
- int err, last_bufsize = bufsize;
- snd_pcm_hw_params_t *pt_params, *ct_params;
- snd_pcm_hw_params_t *p_params, *c_params;
+ int i;
+ unsigned ratep, ratec = 0;
+ unsigned ratemin = 32000, ratemax = 96000, val;
+ int err, channels = 2;
+ snd_pcm_hw_params_t *p_hwparams, *c_hwparams;
snd_pcm_sw_params_t *p_swparams, *c_swparams;
- snd_pcm_uframes_t p_size, c_size, p_psize, c_psize;
- unsigned int p_time, c_time;
-
- snd_pcm_hw_params_alloca(&p_params);
- snd_pcm_hw_params_alloca(&c_params);
- snd_pcm_hw_params_alloca(&pt_params);
- snd_pcm_hw_params_alloca(&ct_params);
+ snd_pcm_uframes_t c_size, p_psize, c_psize;
+ /* Our latency is 2 periods (in usecs) */
+ unsigned int c_periods = 2, p_periods;
+ unsigned int c_periodtime, p_periodtime;
+
+ snd_pcm_hw_params_alloca(&p_hwparams);
+ snd_pcm_hw_params_alloca(&c_hwparams);
snd_pcm_sw_params_alloca(&p_swparams);
snd_pcm_sw_params_alloca(&c_swparams);
- if ((err = setparams_stream(phandle, pt_params, format, channels, rate,
- "playback")) < 0) {
- printf("Unable to set parameters for playback stream: %s\n", snd_strerror(err));
- return 1;
- }
- if ((err = setparams_stream(chandle, ct_params, format, channels, rate,
- "capture")) < 0) {
- printf("Unable to set parameters for playback stream: %s\n", snd_strerror(err));
+
+ if (setparams_stream(phandle, p_hwparams, format, channels, "playback"))
return 1;
- }
- __again:
- if (last_bufsize == bufsize)
- bufsize += 4;
- last_bufsize = bufsize;
+ if (setparams_stream(chandle, c_hwparams, format, channels, "capture"))
+ return 1;
- if ((err = setparams_bufsize(phandle, p_params, pt_params, bufsize, 0,
- "playback")) < 0) {
- printf("Unable to set sw parameters for playback stream: %s\n",
- snd_strerror(err));
- return -1;
- }
- if ((err = setparams_bufsize(chandle, c_params, ct_params, bufsize, 0,
- "capture")) < 0) {
- printf("Unable to set sw parameters for playback stream: %s\n",
- snd_strerror(err));
- return -1;
+ if (allow_resample) {
+ err = snd_pcm_hw_params_set_rate_resample(chandle, c_hwparams, 1);
+ if (err < 0) {
+ fprintf(error_fp, "alsa: Resample setup failed: %s\n", snd_strerror(err));
+ return 1;
+ } else if (verbose)
+ fprintf(error_fp, "alsa: Resample enabled.\n");
+ }
+
+ err = snd_pcm_hw_params_get_rate_min(c_hwparams, &ratemin, 0);
+ if (err >= 0 && verbose)
+ fprintf(error_fp, "alsa: Capture min rate is %d\n", ratemin);
+ err = snd_pcm_hw_params_get_rate_max(c_hwparams, &ratemax, 0);
+ if (err >= 0 && verbose)
+ fprintf(error_fp, "alsa: Capture max rate is %u\n", ratemax);
+
+ err = snd_pcm_hw_params_get_rate_min(p_hwparams, &val, 0);
+ if (err >= 0) {
+ if (verbose)
+ fprintf(error_fp, "alsa: Playback min rate is %u\n", val);
+ if (val > ratemin)
+ ratemin = val;
+ }
+ err = snd_pcm_hw_params_get_rate_max(p_hwparams, &val, 0);
+ if (err >= 0) {
+ if (verbose)
+ fprintf(error_fp, "alsa: Playback max rate is %u\n", val);
+ if (val < ratemax)
+ ratemax = val;
+ }
+
+ if (verbose)
+ fprintf(error_fp, "alsa: Will search a common rate between %u and %u\n",
+ ratemin, ratemax);
+
+ for (i = ratemin; i <= ratemax; i+= 100) {
+ err = snd_pcm_hw_params_set_rate_near(chandle, c_hwparams, &i, 0);
+ if (err)
+ continue;
+ ratec = i;
+ ratep = i;
+ err = snd_pcm_hw_params_set_rate_near(phandle, p_hwparams, &ratep, 0);
+ if (err)
+ continue;
+ if (ratep == ratec)
+ break;
+ if (verbose)
+ fprintf(error_fp,
+ "alsa: Failed to set to %u: capture wanted %u, playback wanted %u%s\n",
+ i, ratec, ratep,
+ allow_resample ? " with resample enabled": "");
}
- snd_pcm_hw_params_get_period_size(p_params, &p_psize, NULL);
- if (p_psize > (unsigned int)bufsize)
- bufsize = p_psize;
-
- snd_pcm_hw_params_get_period_size(c_params, &c_psize, NULL);
- if (c_psize > (unsigned int)bufsize)
- bufsize = c_psize;
+ if (err < 0) {
+ fprintf(error_fp, "alsa: Failed to set a supported rate: %s\n",
+ snd_strerror(err));
+ return 1;
+ }
+ if (ratep != ratec) {
+ if (verbose || allow_resample)
+ fprintf(error_fp,
+ "alsa: Couldn't find a rate that it is supported by both playback and capture\n");
+ return 2;
+ }
+ if (verbose)
+ fprintf(error_fp, "alsa: Using Rate %d\n", ratec);
+
+ /* Negociate period parameters */
+
+ c_periodtime = latency * 1000 / c_periods;
+ getparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, "capture");
+ p_periods = c_periods * 2;
+ p_periodtime = c_periodtime;
+ getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, "playback");
+ c_periods = p_periods / 2;
+
+ /*
+ * 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
+ * the number of periods, to archive the needed latency
+ */
+ 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");
+ p_periods = c_periods * 2;
+ p_periodtime = c_periodtime;
+ getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, "playback");
+ c_periods = p_periods / 2;
+ }
+
+ if (setparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, "capture"))
+ return 1;
- snd_pcm_hw_params_get_period_time(p_params, &p_time, NULL);
- snd_pcm_hw_params_get_period_time(c_params, &c_time, NULL);
+ /* Note we use twice as much periods for the playback buffer, since we
+ will get a period size near the requested time and we don't want it to
+ end up smaller then the capture buffer as then we could end up blocking
+ on writing to it. Note we will configure the playback dev to start
+ playing as soon as it has 2 capture periods worth of data, so this
+ won't influence latency */
+ if (setparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, "playback"))
+ return 1;
- if (p_time != c_time)
- goto __again;
+ snd_pcm_hw_params_get_period_size(p_hwparams, &p_psize, NULL);
+ snd_pcm_hw_params_get_period_size(c_hwparams, &c_psize, NULL);
+ snd_pcm_hw_params_get_buffer_size(c_hwparams, &c_size);
- snd_pcm_hw_params_get_buffer_size(p_params, &p_size);
- if (p_psize * 2 < p_size)
- goto __again;
- snd_pcm_hw_params_get_buffer_size(c_params, &c_size);
- if (c_psize * 2 < c_size)
- goto __again;
+ latency = c_periods * c_psize;
+ if (setparams_set(phandle, p_hwparams, p_swparams, latency, "playback"))
+ return 1;
- if ((err = setparams_set(phandle, p_params, p_swparams, "playback")) < 0) {
- printf("Unable to set sw parameters for playback stream: %s\n",
- snd_strerror(err));
- return -1;
- }
- if ((err = setparams_set(chandle, c_params, c_swparams, "capture")) < 0) {
- printf("Unable to set sw parameters for playback stream: %s\n",
- snd_strerror(err));
- return -1;
- }
+ if (setparams_set(chandle, c_hwparams, c_swparams, c_psize, "capture"))
+ return 1;
if ((err = snd_pcm_prepare(phandle)) < 0) {
- printf("Prepare error: %s\n", snd_strerror(err));
- return -1;
+ fprintf(error_fp, "alsa: Prepare error: %s\n", snd_strerror(err));
+ return 1;
}
-#ifdef SHOW_ALSA_DEBUG
- printf("final config\n");
- snd_pcm_dump_setup(phandle, output);
- snd_pcm_dump_setup(chandle, output);
- printf("Parameters are %iHz, %s, %i channels\n", rate,
- snd_pcm_format_name(format), channels);
- fflush(stdout);
-#endif
+ if (verbose) {
+ fprintf(error_fp, "alsa: Negociated configuration:\n");
+ snd_pcm_dump_setup(phandle, output);
+ snd_pcm_dump_setup(chandle, output);
+ fprintf(error_fp, "alsa: Parameters are %iHz, %s, %i channels\n",
+ ratep, snd_pcm_format_name(format), channels);
+ fprintf(error_fp, "alsa: Set bitrate to %u%s, buffer size is %u\n", ratec,
+ allow_resample ? " with resample enabled at playback": "",
+ (unsigned int)c_size);
+ }
- negotiated->bufsize = bufsize;
- negotiated->rate = rate;
+ negotiated->bufsize = c_size;
+ negotiated->rate = ratep;
negotiated->channels = channels;
- negotiated->latency = bufsize;
+ negotiated->latency = latency;
return 0;
}
-void setscheduler(void)
-{
- struct sched_param sched_param;
-
- if (sched_getparam(0, &sched_param) < 0) {
- printf("Scheduler getparam failed...\n");
- return;
- }
- sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
- if (!sched_setscheduler(0, SCHED_RR, &sched_param)) {
- printf("Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);
- fflush(stdout);
- return;
- }
- printf("!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority);
-}
-
-snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len,
- size_t *frames, size_t *max)
+/* Read up to len frames */
+static snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len)
{
snd_pcm_sframes_t r;
r = snd_pcm_readi(handle, buf, len);
- if (r < 0) {
- return r;
+ if (r < 0 && r != -EAGAIN) {
+ r = snd_pcm_recover(handle, r, 0);
+ if (r < 0)
+ fprintf(error_fp, "alsa: overrun recover error: %s\n", snd_strerror(r));
}
-
- if (r > 0) {
- *frames += r;
- if ((long)*max < r)
- *max = r;
- }
-
return r;
}
-snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char *buf, long len,
- size_t *frames)
+/* Write len frames (note not up to len, but all of len!) */
+static snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char *buf, long len)
{
snd_pcm_sframes_t r;
- while (len > 0) {
+ while (1) {
r = snd_pcm_writei(handle, buf, len);
+ if (r == len)
+ return 0;
if (r < 0) {
- return r;
+ r = snd_pcm_recover(handle, r, 0);
+ if (r < 0) {
+ fprintf(error_fp, "alsa: underrun recover error: %s\n",
+ snd_strerror(r));
+ return r;
+ }
}
-
buf += r * 4;
len -= r;
- *frames += r;
- }
- return 0;
-}
-
-int startup_capture(snd_pcm_t *phandle, snd_pcm_t *chandle,
- snd_pcm_format_t format, char *buffer, int latency,
- int channels)
-{
- size_t frames_out;
- int err;
-
- frames_out = 0;
- if (snd_pcm_format_set_silence(format, buffer, latency*channels) < 0) {
- fprintf(stderr, "silence error\n");
- return 1;
- }
- if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
- fprintf(stderr, "write error\n");
- return 1;
+ snd_pcm_wait(handle, 100);
}
- if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
- fprintf(stderr, "write error\n");
- return 1;
- }
-
- if ((err = snd_pcm_start(chandle)) < 0) {
- printf("Go error: %s\n", snd_strerror(err));
- return 1;
- }
- return 0;
}
-int tvtime_alsa_stream(const char *pdevice, const char *cdevice)
+static int alsa_stream(const char *pdevice, const char *cdevice, int latency)
{
snd_pcm_t *phandle, *chandle;
char *buffer;
int err;
ssize_t r;
- size_t frames_in, frames_out, in_max;
struct final_params negotiated;
- int ret = 0;
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
+ char pdevice_new[32];
- err = snd_output_stdio_attach(&output, stdout, 0);
+ err = snd_output_stdio_attach(&output, error_fp, 0);
if (err < 0) {
- printf("Output failed: %s\n", snd_strerror(err));
+ fprintf(error_fp, "alsa: Output failed: %s\n", snd_strerror(err));
return 0;
}
-// setscheduler();
-
- printf("Playback device is %s\n", pdevice);
- printf("Capture device is %s\n", cdevice);
-
/* Open the devices */
if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK,
- SND_PCM_NONBLOCK)) < 0) {
- printf("Cannot open ALSA Playback device %s: %s\n", pdevice,
- snd_strerror(err));
+ 0)) < 0) {
+ fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n",
+ pdevice, snd_strerror(err));
return 0;
}
if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE,
SND_PCM_NONBLOCK)) < 0) {
- printf("Cannot open ALSA Capture device %s: %s\n",
- cdevice, snd_strerror(err));
+ fprintf(error_fp, "alsa: Cannot open capture device %s: %s\n",
+ cdevice, snd_strerror(err));
return 0;
}
- frames_in = frames_out = 0;
- if (setparams(phandle, chandle, format, &negotiated) < 0) {
- printf("setparams failed\n");
+ err = setparams(phandle, chandle, format, latency, 0, &negotiated);
+
+ /* Try to use plughw instead, as it allows emulating speed */
+ if (err == 2 && strncmp(pdevice, "hw", 2) == 0) {
+
+ snd_pcm_close(phandle);
+
+ sprintf(pdevice_new, "plug%s", pdevice);
+ pdevice = pdevice_new;
+ if (verbose)
+ fprintf(error_fp, "alsa: Trying %s for playback\n", pdevice);
+ if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK,
+ 0)) < 0) {
+ fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n",
+ pdevice, snd_strerror(err));
+ }
+
+ err = setparams(phandle, chandle, format, latency, 1, &negotiated);
+ }
+
+ if (err != 0) {
+ fprintf(error_fp, "alsa: setparams failed\n");
return 1;
}
buffer = malloc((negotiated.bufsize * snd_pcm_format_width(format) / 8)
* negotiated.channels);
if (buffer == NULL) {
- printf("Failed allocating buffer for audio\n");
+ fprintf(error_fp, "alsa: Failed allocating buffer for audio\n");
return 0;
-
- }
- if ((err = snd_pcm_link(chandle, phandle)) < 0) {
- printf("Streams link error: %d %s\n", err, snd_strerror(err));
- return 1;
}
- startup_capture(phandle, chandle, format, buffer, negotiated.latency,
- negotiated.channels);
-
- while (1) {
- in_max = 0;
-
+ /*
+ * Buffering delay is due for capture and for playback, so we
+ * need to multiply it by two.
+ */
+ fprintf(error_fp,
+ "alsa: stream started from %s to %s (%i Hz, buffer delay = %.2f ms)\n",
+ cdevice, pdevice, negotiated.rate,
+ negotiated.latency * 1000.0 / negotiated.rate);
+
+ alsa_is_running = 1;
+
+ while (!stop_alsa) {
+ /* We start with a read and not a wait to auto(re)start the capture */
+ r = readbuf(chandle, buffer, negotiated.bufsize);
+ if (r == 0) /* Succesfully recovered from an overrun? */
+ continue; /* Force restart of capture stream */
+ if (r > 0)
+ writebuf(phandle, buffer, r);
/* use poll to wait for next event */
- ret = snd_pcm_wait(chandle, 1000);
- if (ret < 0) {
- if ((err = snd_pcm_recover(chandle, ret, 0)) < 0) {
- fprintf(stderr, "xrun: recover error: %s",
- snd_strerror(err));
- break;
- }
-
- /* Restart capture */
- startup_capture(phandle, chandle, format, buffer,
- negotiated.latency, negotiated.channels);
- continue;
- } else if (ret == 0) {
- /* Timed out */
- continue;
- }
-
- if ((r = readbuf(chandle, buffer, negotiated.latency, &frames_in,
- &in_max)) > 0) {
- if (writebuf(phandle, buffer, r, &frames_out) < 0) {
- startup_capture(phandle, chandle, format, buffer,
- negotiated.latency, negotiated.channels);
- }
- } else if (r < 0) {
- startup_capture(phandle, chandle, format, buffer,
- negotiated.latency, negotiated.channels);
- }
+ snd_pcm_wait(chandle, 1000);
}
snd_pcm_drop(chandle);
@@ -451,28 +494,55 @@ int tvtime_alsa_stream(const char *pdevice, const char *cdevice)
snd_pcm_close(phandle);
snd_pcm_close(chandle);
+
+ alsa_is_running = 0;
return 0;
}
struct input_params {
- const char *pdevice;
- const char *cdevice;
+ char *pdevice;
+ char *cdevice;
+ int latency;
};
-void *tvtime_alsa_thread_entry(void *whatever)
+static void *alsa_thread_entry(void *whatever)
{
struct input_params *inputs = (struct input_params *) whatever;
- tvtime_alsa_stream(inputs->pdevice, inputs->cdevice);
+
+ if (verbose)
+ fprintf(error_fp, "alsa: starting copying alsa stream from %s to %s\n",
+ inputs->cdevice, inputs->pdevice);
+ alsa_stream(inputs->pdevice, inputs->cdevice, inputs->latency);
+ fprintf(error_fp, "alsa: stream stopped\n");
+
+ free(inputs->pdevice);
+ free(inputs->cdevice);
+ free(inputs);
+
+ return NULL;
}
-int tvtime_alsa_thread_startup(const char *pdevice, const char *cdevice)
+/*************************************************************************
+ Public functions
+ *************************************************************************/
+
+int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency,
+ FILE *__error_fp, int __verbose)
{
int ret;
pthread_t thread;
struct input_params *inputs = malloc(sizeof(struct input_params));
+ if (__error_fp)
+ error_fp = __error_fp;
+ else
+ error_fp = stderr;
+
+ verbose = __verbose;
+
+
if (inputs == NULL) {
- printf("failed allocating memory for ALSA inputs\n");
+ fprintf(error_fp, "alsa: failed allocating memory for inputs\n");
return 0;
}
@@ -484,18 +554,27 @@ int tvtime_alsa_thread_startup(const char *pdevice, const char *cdevice)
inputs->pdevice = strdup(pdevice);
inputs->cdevice = strdup(cdevice);
+ inputs->latency = latency;
+
+ if (alsa_is_running) {
+ stop_alsa = 1;
+ while ((volatile int)alsa_is_running)
+ usleep(10);
+ }
+
+ stop_alsa = 0;
ret = pthread_create(&thread, NULL,
- &tvtime_alsa_thread_entry, (void *) inputs);
+ &alsa_thread_entry, (void *) inputs);
return ret;
}
-#ifdef TVTIME_ALSA_DEBUGGING
-/* This allows the alsa_stream.c to be a standalone binary for debugging */
- int main(int argc, char *argv[])
+void alsa_thread_stop(void)
+{
+ stop_alsa = 1;
+}
+
+int alsa_thread_is_running(void)
{
- char *pdevice = "hw:0,0";
- char *cdevice = "hw:1,0";
- tvtime_alsa_stream(pdevice, cdevice);
+ return alsa_is_running;
}
-#endif
diff --git a/src/alsa_stream.h b/src/alsa_stream.h
index 8572c8b..c68fd6d 100644
--- a/src/alsa_stream.h
+++ b/src/alsa_stream.h
@@ -1 +1,5 @@
-int tvtime_alsa_thread_startup(char *pdevice, char *cdevice);
+int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency,
+ FILE *__error_fp,
+ int __verbose);
+void alsa_thread_stop(void);
+int alsa_thread_is_running(void);
diff --git a/src/tvtime.c b/src/tvtime.c
index 75257d1..d9066cc 100644
--- a/src/tvtime.c
+++ b/src/tvtime.c
@@ -1256,8 +1256,10 @@ int tvtime_main( rtctimer_t *rtctimer, int read_stdin, int realtime,
}
/* Setup the ALSA streaming device */
- tvtime_alsa_thread_startup(config_get_alsa_outputdev( ct ),
- config_get_alsa_inputdev( ct ) );
+ alsa_thread_startup(config_get_alsa_outputdev( ct ),
+ config_get_alsa_inputdev( ct ),
+ 30, /* FIXME: Add a var to adjust latency */
+ stderr, verbose );
/* Setup the speedy calls. */
setup_speedy_calls( mm_accel(), verbose );
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 02/10] Fix make dist target
2011-09-06 15:29 [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 03/10] Backport mixer-alsa patch from Fedora Mauro Carvalho Chehab
2011-09-06 15:40 ` [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
2011-09-07 2:58 ` Devin Heitmueller
2 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
src/Makefile.am | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 50687c2..3a38aac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,7 +38,7 @@ COMMON_SRCS = mixer.c videoinput.c rtctimer.c leetft.c osdtools.c tvtimeconf.c \
speedtools.h vbiscreen.h vbiscreen.c fifo.h fifo.c commands.h \
commands.c videofilter.h videofilter.c station.h station.c bands.h \
utils.h utils.c pulldown.h pulldown.c hashtable.h hashtable.c \
- cpuinfo.h cpuinfo.c videodev2.h menu.c menu.h \
+ cpuinfo.h cpuinfo.c menu.c menu.h \
outputfilter.h outputfilter.c xmltv.h xmltv.c gettext.h tvtimeglyphs.h \
copyfunctions.h copyfunctions.c alsa_stream.c
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 03/10] Backport mixer-alsa patch from Fedora
2011-09-06 15:29 ` [PATCH 02/10] Fix make dist target Mauro Carvalho Chehab
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 04/10] Properly document alsa mixer Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
commit e53212e85a71d831fff3bf61c792ed7235fa3a79
Author: Tomas Smetana <tsmetana@fedoraproject.org>
Date: Mon May 11 16:24:09 2009 +0000
Added first version of the ALSA mixer patch. Unused yet.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
configure.ac | 12 ++-
src/Makefile.am | 15 ++-
src/commands.c | 8 +-
src/mixer-alsa.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++
src/mixer-oss.c | 261 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/mixer.c | 272 +++++++++++++++---------------------------------------
src/mixer.h | 31 +++++--
src/tvtime.c | 10 +-
src/videoinput.c | 6 +-
9 files changed, 628 insertions(+), 227 deletions(-)
create mode 100644 src/mixer-alsa.c
create mode 100644 src/mixer-oss.c
diff --git a/configure.ac b/configure.ac
index eac6c20..6cdedfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,18 +76,26 @@ dnl ---------------------------------------------
dnl libxml2
dnl ---------------------------------------------
dnl Test for libxml2
-
AC_PATH_PROG(LIBXML2_CONFIG,xml2-config,no)
if test "$LIBXML2_CONFIG" = "no" ; then
AC_MSG_ERROR(libxml2 needed and xml2-config not found)
else
XML2_LIBS="`$LIBXML2_CONFIG --libs`"
XML2_FLAG="`$LIBXML2_CONFIG --cflags`"
- AC_DEFINE(HAVE_LIBXML2,,[LIBXML2 support])
+ AC_DEFINE(HAVE_LIBXML2,,[LIBXML2 support])
fi
AC_SUBST(XML2_LIBS)
AC_SUBST(XML2_FLAG)
+dnl ---------------------------------------------
+dnl libasound2
+dnl ---------------------------------------------
+dnl Test for ALSA
+AM_PATH_ALSA(1.0.9,
+ [ AC_DEFINE(HAVE_ALSA,1,[Define this if you have Alsa (libasound) installed]) ],
+ AC_MSG_RESULT(libasound needed and not found))
+AM_CONDITIONAL(HAVE_ALSA, test x"$no_alsa" != "yes")
+
dnl ---------------------------------------------
dnl asound
diff --git a/src/Makefile.am b/src/Makefile.am
index 3a38aac..56e26a6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,11 @@ OPT_CFLAGS = -Wall -pedantic -I. -DDATADIR="\"$(pkgdatadir)\"" \
-DCONFDIR="\"$(pkgsysconfdir)\"" -DFIFODIR="\"$(tmpdir)\"" \
-D_LARGEFILE64_SOURCE -DLOCALEDIR="\"$(localedir)\""
+if HAVE_ALSA
+ALSA_SRCS = mixer-alsa.c
+else
+ALSA_SRCS =
+endif
COMMON_SRCS = mixer.c videoinput.c rtctimer.c leetft.c osdtools.c tvtimeconf.c \
pngoutput.c tvtimeosd.c input.c cpu_accel.c speedy.c pnginput.c \
deinterlace.c videotools.c attributes.h deinterlace.h leetft.h \
@@ -40,7 +45,7 @@ COMMON_SRCS = mixer.c videoinput.c rtctimer.c leetft.c osdtools.c tvtimeconf.c \
utils.h utils.c pulldown.h pulldown.c hashtable.h hashtable.c \
cpuinfo.h cpuinfo.c menu.c menu.h \
outputfilter.h outputfilter.c xmltv.h xmltv.c gettext.h tvtimeglyphs.h \
- copyfunctions.h copyfunctions.c alsa_stream.c
+ copyfunctions.h copyfunctions.c alsa_stream.c mixer-oss.c $(ALSA_SRCS)
if ARCH_X86
DSCALER_SRCS = $(top_srcdir)/plugins/dscalerapi.h \
@@ -74,10 +79,10 @@ bin_PROGRAMS = tvtime tvtime-command tvtime-configure tvtime-scanner
tvtime_SOURCES = $(COMMON_SRCS) $(OUTPUT_SRCS) $(PLUGIN_SRCS) tvtime.c
tvtime_CFLAGS = $(TTF_CFLAGS) $(PNG_CFLAGS) $(OPT_CFLAGS) \
- $(PLUGIN_CFLAGS) $(X11_CFLAGS) $(XML2_FLAG) \
+ $(PLUGIN_CFLAGS) $(X11_CFLAGS) $(XML2_FLAG) $(ALSA_CFLAGS) \
$(FONT_CFLAGS) $(AM_CFLAGS)
tvtime_LDFLAGS = $(TTF_LIBS) $(ZLIB_LIBS) $(PNG_LIBS) \
- $(X11_LIBS) $(XML2_LIBS) $(ASOUND_LIBS) -lm -lstdc++
+ $(X11_LIBS) $(XML2_LIBS) $(ALSA_LIBS) -lm -lstdc++
tvtime_command_SOURCES = utils.h utils.c tvtimeconf.h tvtimeconf.c \
tvtime-command.c
@@ -90,6 +95,6 @@ tvtime_configure_LDFLAGS = $(ZLIB_LIBS) $(XML2_LIBS)
tvtime_scanner_SOURCES = utils.h utils.c videoinput.h videoinput.c \
tvtimeconf.h tvtimeconf.c station.h station.c tvtime-scanner.c \
mixer.h mixer.c
-tvtime_scanner_CFLAGS = $(OPT_CFLAGS) $(XML2_FLAG) $(AM_CFLAGS)
-tvtime_scanner_LDFLAGS = $(ZLIB_LIBS) $(XML2_LIBS)
+tvtime_scanner_CFLAGS = $(OPT_CFLAGS) $(XML2_FLAG) $(ALSA_CFLAGS) $(AM_CFLAGS)
+tvtime_scanner_LDFLAGS = $(ZLIB_LIBS) $(XML2_LIBS) $(ALSA_LIBS)
diff --git a/src/commands.c b/src/commands.c
index 964cab7..9141276 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -3012,10 +3012,10 @@ void commands_handle( commands_t *cmd, int tvtime_cmd, const char *arg )
break;
case TVTIME_MIXER_TOGGLE_MUTE:
- mixer_mute( !mixer_ismute() );
+ mixer->mute( !mixer->ismute() );
if( cmd->osd ) {
- tvtime_osd_show_data_bar( cmd->osd, _("Volume"), (mixer_get_volume()) & 0xff );
+ tvtime_osd_show_data_bar( cmd->osd, _("Volume"), (mixer->get_volume()) & 0xff );
}
break;
@@ -3029,9 +3029,9 @@ void commands_handle( commands_t *cmd, int tvtime_cmd, const char *arg )
/* Check to see if an argument was passed, if so, use it. */
if (atoi(arg) > 0) {
int perc = atoi(arg);
- volume = mixer_set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? perc : -perc ) );
+ volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? perc : -perc ) );
} else {
- volume = mixer_set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? 1 : -1 ) );
+ volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? 1 : -1 ) );
}
if( cmd->osd ) {
diff --git a/src/mixer-alsa.c b/src/mixer-alsa.c
new file mode 100644
index 0000000..635d44c
--- /dev/null
+++ b/src/mixer-alsa.c
@@ -0,0 +1,240 @@
+/**
+ * Copyright (C) 2006 Philipp Hahn <pmhahn@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <math.h>
+#include <alsa/asoundlib.h>
+#include "utils.h"
+#include "mixer.h"
+
+static const char alsa_core_devnames[] = "default";
+static char *card, *channel;
+static int muted = 0;
+static int mutecount = 0;
+static snd_mixer_t *handle = NULL;
+static snd_mixer_elem_t *elem = NULL;
+
+static long alsa_min, alsa_max, alsa_vol;
+
+static void alsa_open_mixer( void )
+{
+ int err;
+ static snd_mixer_selem_id_t *sid = NULL;
+ if ((err = snd_mixer_open (&handle, 0)) < 0) {
+ fprintf(stderr, "mixer: open error: %s\n", snd_strerror(err));
+ return;
+ }
+ if ((err = snd_mixer_attach (handle, card)) < 0) {
+ fprintf(stderr, "mixer: attach error: %s\n", snd_strerror(err));
+ goto error;
+ }
+ if ((err = snd_mixer_selem_register (handle, NULL, NULL)) < 0) {
+ fprintf(stderr, "mixer: register error: %s\n", snd_strerror(err));
+ goto error;
+ }
+ if ((err = snd_mixer_load (handle)) < 0) {
+ fprintf(stderr, "mixer: load error: %s\n", snd_strerror(err));
+ goto error;
+ }
+ snd_mixer_selem_id_malloc(&sid);
+ if (sid == NULL)
+ goto error;
+ snd_mixer_selem_id_set_name(sid, channel);
+ if (!(elem = snd_mixer_find_selem(handle, sid))) {
+ fprintf(stderr, "mixer: find error: %s\n", snd_strerror(err));
+ goto error;
+ }
+ if (!snd_mixer_selem_has_playback_volume(elem)) {
+ fprintf(stderr, "mixer: no playback\n");
+ goto error;
+ }
+ snd_mixer_selem_get_playback_volume_range(elem, &alsa_min, &alsa_max);
+ if ((alsa_max - alsa_min) <= 0) {
+ fprintf(stderr, "mixer: no valid playback range\n");
+ goto error;
+ }
+ snd_mixer_selem_id_free(sid);
+ return;
+
+error:
+ if (sid)
+ snd_mixer_selem_id_free(sid);
+ if (handle) {
+ snd_mixer_close(handle);
+ handle = NULL;
+ }
+ return;
+}
+
+/* Volume saved to file */
+static int alsa_get_unmute_volume( void )
+{
+ long val;
+ assert (elem);
+
+ if (snd_mixer_selem_is_playback_mono(elem)) {
+ snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
+ return val;
+ } else {
+ int c, n = 0;
+ long sum = 0;
+ for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
+ if (snd_mixer_selem_has_playback_channel(elem, c)) {
+ snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
+ sum += val;
+ n++;
+ }
+ }
+ if (! n) {
+ return 0;
+ }
+
+ val = sum / n;
+ sum = (long)((double)(alsa_vol * (alsa_max - alsa_min)) / 100. + 0.5);
+
+ if (sum != val) {
+ alsa_vol = (long)(((val * 100.) / (alsa_max - alsa_min)) + 0.5);
+ }
+ return alsa_vol;
+ }
+}
+
+static int alsa_get_volume( void )
+{
+ if (muted)
+ return 0;
+ else
+ return alsa_get_unmute_volume();
+}
+
+static int alsa_set_volume( int percentdiff )
+{
+ long volume;
+
+ alsa_get_volume();
+
+ alsa_vol += percentdiff;
+ if( alsa_vol > 100 ) alsa_vol = 100;
+ if( alsa_vol < 0 ) alsa_vol = 0;
+
+ volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + 0.5);
+
+ snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
+ snd_mixer_selem_set_playback_switch_all(elem, 1);
+ muted = 0;
+ mutecount = 0;
+
+ return alsa_vol;
+}
+
+static void alsa_mute( int mute )
+{
+ /**
+ * Make sure that if multiple users mute the card,
+ * we only honour the last one.
+ */
+ if( !mute && mutecount ) mutecount--;
+ if( mutecount ) return;
+
+ if( mute ) {
+ mutecount++;
+ muted = 1;
+ if (snd_mixer_selem_has_playback_switch(elem))
+ snd_mixer_selem_set_playback_switch_all(elem, 0);
+ else
+ fprintf(stderr, "mixer: mute not implemented\n");
+ } else {
+ muted = 0;
+ if (snd_mixer_selem_has_playback_switch(elem))
+ snd_mixer_selem_set_playback_switch_all(elem, 1);
+ else
+ fprintf(stderr, "mixer: mute not implemented\n");
+ }
+}
+
+static int alsa_ismute( void )
+{
+ return muted;
+}
+
+static int alsa_set_device( const char *devname )
+{
+ int i;
+
+ if (card) free(card);
+ card = strdup( devname );
+ if( !card ) return -1;
+
+ i = strcspn( card, "/" );
+ if( i == strlen( card ) ) {
+ channel = "Line";
+ } else {
+ card[i] = 0;
+ channel = card + i + 1;
+ }
+ alsa_open_mixer();
+ if (!handle) {
+ fprintf( stderr, "mixer: Can't open mixer %s, "
+ "mixer volume and mute unavailable.\n", card );
+ return -1;
+ }
+ return 0;
+}
+
+static void alsa_set_state( int ismuted, int unmute_volume )
+{
+ /**
+ * 1. we come back unmuted: Don't touch anything
+ * 2. we don't have a saved volume: Don't touch anything
+ * 3. we come back muted and we have a saved volume:
+ * - if tvtime muted it, unmute to old volume
+ * - if user did it, remember that we're muted and old volume
+ */
+ if( alsa_get_volume() == 0 && unmute_volume > 0 ) {
+ snd_mixer_selem_set_playback_volume_all(elem, unmute_volume);
+ muted = 1;
+
+ if( !ismuted ) {
+ alsa_mute( 0 );
+ }
+ }
+}
+
+static void alsa_close_device( void )
+{
+ elem = NULL;
+ if (handle)
+ snd_mixer_close(handle);
+ handle = NULL;
+ muted = 0;
+ mutecount = 0;
+}
+
+struct mixer alsa_mixer = {
+ .set_device = alsa_set_device,
+ .set_state = alsa_set_state,
+ .get_volume = alsa_get_volume,
+ .get_unmute_volume = alsa_get_unmute_volume,
+ .set_volume = alsa_set_volume,
+ .mute = alsa_mute,
+ .ismute = alsa_ismute,
+ .close_device = alsa_close_device,
+};
+// vim: ts=4 sw=4 et foldmethod=marker
diff --git a/src/mixer-oss.c b/src/mixer-oss.c
new file mode 100644
index 0000000..08aa0ca
--- /dev/null
+++ b/src/mixer-oss.c
@@ -0,0 +1,261 @@
+/**
+ * Copyright (C) 2002, 2003 Doug Bell <drbell@users.sourceforge.net>
+ *
+ * Some mixer routines from mplayer, http://mplayer.sourceforge.net.
+ * Copyright (C) 2000-2002. by A'rpi/ESP-team & others
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+#include <sys/mman.h>
+#include <string.h>
+#include "utils.h"
+#include "mixer.h"
+
+static char *mixer_device = "/dev/mixer";
+static int saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
+static int mixer_channel = SOUND_MIXER_LINE;
+static int mixer_dev_mask = 1 << SOUND_MIXER_LINE;
+static int muted = 0;
+static int mutecount = 0;
+static int fd = -1;
+
+static int oss_get_volume( void )
+{
+ int v, cmd, devs;
+ int curvol = 0;
+
+ if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
+ if( fd != -1 ) {
+
+ ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
+ if( devs & mixer_dev_mask ) {
+ cmd = MIXER_READ( mixer_channel );
+ } else {
+ return curvol;
+ }
+
+ ioctl( fd, cmd, &v );
+ curvol = ( v & 0xFF00 ) >> 8;
+ }
+
+ return curvol;
+}
+
+static int oss_get_unmute_volume( void )
+{
+ if( muted ) {
+ return saved_volume;
+ } else {
+ int v, cmd, devs;
+
+ if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
+ if( fd != -1 ) {
+
+ ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
+ if( devs & mixer_dev_mask ) {
+ cmd = MIXER_READ( mixer_channel );
+ } else {
+ return -1;
+ }
+
+ ioctl( fd, cmd, &v );
+ return v;
+ }
+ }
+
+ return -1;
+}
+
+static int oss_set_volume( int percentdiff )
+{
+ int v, cmd, devs, levelpercentage;
+
+ levelpercentage = oss_get_volume();
+
+ levelpercentage += percentdiff;
+ if( levelpercentage > 100 ) levelpercentage = 100;
+ if( levelpercentage < 0 ) levelpercentage = 0;
+
+ if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
+ if( fd != -1 ) {
+ ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
+ if( devs & mixer_dev_mask ) {
+ cmd = MIXER_WRITE( mixer_channel );
+ } else {
+ return 0;
+ }
+
+ v = ( levelpercentage << 8 ) | levelpercentage;
+ ioctl( fd, cmd, &v );
+ muted = 0;
+ mutecount = 0;
+ return v;
+ }
+
+ return 0;
+}
+
+static void oss_mute( int mute )
+{
+ int v, cmd, devs;
+
+ /**
+ * Make sure that if multiple users mute the card,
+ * we only honour the last one.
+ */
+ if( !mute && mutecount ) mutecount--;
+ if( mutecount ) return;
+
+ if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
+
+ if( mute ) {
+ mutecount++;
+ if( fd != -1 ) {
+
+ /* Save volume */
+ ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
+ if( devs & mixer_dev_mask ) {
+ cmd = MIXER_READ( mixer_channel );
+ } else {
+ return;
+ }
+
+ ioctl( fd,cmd,&v );
+ saved_volume = v;
+
+ /* Now set volume to 0 */
+ ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
+ if( devs & mixer_dev_mask ) {
+ cmd = MIXER_WRITE( mixer_channel );
+ } else {
+ return;
+ }
+
+ v = 0;
+ ioctl( fd, cmd, &v );
+
+ muted = 1;
+ return;
+ }
+ } else {
+ if( fd != -1 ) {
+ ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
+ if( devs & mixer_dev_mask ) {
+ cmd = MIXER_WRITE( mixer_channel );
+ } else {
+ return;
+ }
+
+ v = saved_volume;
+ ioctl( fd, cmd, &v );
+ muted = 0;
+ return;
+ }
+ }
+}
+
+static int oss_ismute( void )
+{
+ return muted;
+}
+
+static char *oss_core_devnames[] = SOUND_DEVICE_NAMES;
+
+static int oss_set_device( const char *devname )
+{
+ const char *channame;
+ int found = 0;
+ int i;
+
+ mixer_device = strdup( devname );
+ if( !mixer_device ) return -1;
+
+ i = strcspn( mixer_device, ":" );
+ if( i == strlen( mixer_device ) ) {
+ channame = "line";
+ } else {
+ mixer_device[ i ] = 0;
+ channame = mixer_device + i + 1;
+ }
+ if( !file_is_openable_for_read( mixer_device ) ) {
+ fprintf( stderr, "mixer: Can't open device %s, "
+ "mixer volume and mute unavailable.\n", mixer_device );
+ return -1;
+ }
+
+ mixer_channel = SOUND_MIXER_LINE;
+ for( i = 0; i < SOUND_MIXER_NRDEVICES; i++ ) {
+ if( !strcasecmp( channame, oss_core_devnames[ i ] ) ) {
+ mixer_channel = i;
+ found = 1;
+ break;
+ }
+ }
+ if( !found ) {
+ fprintf( stderr, "mixer: No such mixer channel '%s', using channel 'line'.\n", channame );
+ return -1;
+ }
+ mixer_dev_mask = 1 << mixer_channel;
+ return 0;
+}
+
+static void oss_set_state( int ismuted, int unmute_volume )
+{
+ /**
+ * 1. we come back unmuted: Don't touch anything
+ * 2. we don't have a saved volume: Don't touch anything
+ * 3. we come back muted and we have a saved volume:
+ * - if tvtime muted it, unmute to old volume
+ * - if user did it, remember that we're muted and old volume
+ */
+ if( oss_get_volume() == 0 && unmute_volume > 0 ) {
+ saved_volume = unmute_volume;
+ muted = 1;
+
+ if( !ismuted ) {
+ oss_mute( 0 );
+ }
+ }
+}
+
+static void oss_close_device( void )
+{
+ if( fd >= 0 ) close( fd );
+ saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
+ mixer_channel = SOUND_MIXER_LINE;
+ mixer_dev_mask = 1 << SOUND_MIXER_LINE;
+ muted = 0;
+ mutecount = 0;
+ fd = -1;
+}
+
+struct mixer oss_mixer = {
+ .set_device = oss_set_device,
+ .set_state = oss_set_state,
+ .get_volume = oss_get_volume,
+ .get_unmute_volume = oss_get_unmute_volume,
+ .set_volume = oss_set_volume,
+ .mute = oss_mute,
+ .ismute = oss_ismute,
+ .close_device = oss_close_device,
+};
diff --git a/src/mixer.c b/src/mixer.c
index bd2e5d9..901ef78 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -19,230 +19,104 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-#include <sys/mman.h>
-#include <string.h>
-#include "utils.h"
#include "mixer.h"
-static char *mixer_device = "/dev/mixer";
-static int saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
-static int mixer_channel = SOUND_MIXER_LINE;
-static int mixer_dev_mask = 1 << SOUND_MIXER_LINE;
-static int muted = 0;
-static int mutecount = 0;
-static int fd = -1;
-
-int mixer_get_volume( void )
+/**
+ * Sets the mixer device and channel.
+ */
+static int null_set_device( const char *devname )
{
- int v, cmd, devs;
- int curvol = 0;
-
- if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
- if( fd != -1 ) {
-
- ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
- if( devs & mixer_dev_mask ) {
- cmd = MIXER_READ( mixer_channel );
- } else {
- return curvol;
- }
-
- ioctl( fd, cmd, &v );
- curvol = ( v & 0xFF00 ) >> 8;
- }
-
- return curvol;
+ return 0;
}
-int mixer_get_unmute_volume( void )
+/**
+ * Sets the initial state of the mixer device.
+ */
+static void null_set_state( int ismuted, int unmute_volume )
{
- if( muted ) {
- return saved_volume;
- } else {
- int v, cmd, devs;
-
- if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
- if( fd != -1 ) {
-
- ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
- if( devs & mixer_dev_mask ) {
- cmd = MIXER_READ( mixer_channel );
- } else {
- return -1;
- }
-
- ioctl( fd, cmd, &v );
- return v;
- }
- }
-
- return -1;
}
-int mixer_set_volume( int percentdiff )
+/**
+ * Returns the current volume setting.
+ */
+static int null_get_volume( void )
{
- int v, cmd, devs, levelpercentage;
-
- levelpercentage = mixer_get_volume();
-
- levelpercentage += percentdiff;
- if( levelpercentage > 100 ) levelpercentage = 100;
- if( levelpercentage < 0 ) levelpercentage = 0;
-
- if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
- if( fd != -1 ) {
- ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
- if( devs & mixer_dev_mask ) {
- cmd = MIXER_WRITE( mixer_channel );
- } else {
- return 0;
- }
-
- v = ( levelpercentage << 8 ) | levelpercentage;
- ioctl( fd, cmd, &v );
- muted = 0;
- mutecount = 0;
- return v;
- }
-
return 0;
}
-void mixer_mute( int mute )
+/**
+ * Returns the volume that would be used to restore the unmute state.
+ */
+static int null_get_unmute_volume( void )
{
- int v, cmd, devs;
-
- /**
- * Make sure that if multiple users mute the card,
- * we only honour the last one.
- */
- if( !mute && mutecount ) mutecount--;
- if( mutecount ) return;
-
- if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
-
- if( mute ) {
- mutecount++;
- if( fd != -1 ) {
-
- /* Save volume */
- ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
- if( devs & mixer_dev_mask ) {
- cmd = MIXER_READ( mixer_channel );
- } else {
- return;
- }
-
- ioctl( fd,cmd,&v );
- saved_volume = v;
-
- /* Now set volume to 0 */
- ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
- if( devs & mixer_dev_mask ) {
- cmd = MIXER_WRITE( mixer_channel );
- } else {
- return;
- }
+ return 0;
+}
- v = 0;
- ioctl( fd, cmd, &v );
+/**
+ * Tunes the relative volume.
+ */
+static int null_set_volume( int percentdiff )
+{
+ return 0;
+}
- muted = 1;
- return;
- }
- } else {
- if( fd != -1 ) {
- ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
- if( devs & mixer_dev_mask ) {
- cmd = MIXER_WRITE( mixer_channel );
- } else {
- return;
- }
+/**
+ * Sets the mute state.
+ */
+static void null_mute( int mute )
+{
+}
- v = saved_volume;
- ioctl( fd, cmd, &v );
- muted = 0;
- return;
- }
- }
+/**
+ * Returns true if the mixer is muted.
+ */
+static int null_ismute( void )
+{
+ return 0;
}
-int mixer_ismute( void )
+/**
+ * Closes the mixer device if it is open.
+ */
+static void null_close_device( void )
{
- return muted;
}
-static char *oss_core_devnames[] = SOUND_DEVICE_NAMES;
+/* The null device, which always works. */
+static struct mixer null_mixer = {
+ .set_device = null_set_device,
+ .set_state = null_set_state,
+ .get_volume = null_get_volume,
+ .get_unmute_volume = null_get_unmute_volume,
+ .set_volume = null_set_volume,
+ .mute = null_mute,
+ .ismute = null_ismute,
+ .close_device = null_close_device,
+};
+
+/* List of all available access methods.
+ * Uses weak symbols: NULL is not linked in. */
+static struct mixer *mixers[] = {
+ &alsa_mixer,
+ &oss_mixer,
+ &null_mixer /* LAST */
+};
+/* The actual access method. */
+struct mixer *mixer = &null_mixer;
+/**
+ * Sets the mixer device and channel.
+ * Try each access method until one succeeds.
+ */
void mixer_set_device( const char *devname )
{
- const char *channame;
- int found = 0;
int i;
-
- mixer_device = strdup( devname );
- if( !mixer_device ) return;
-
- i = strcspn( mixer_device, ":" );
- if( i == strlen( mixer_device ) ) {
- channame = "line";
- } else {
- mixer_device[ i ] = 0;
- channame = mixer_device + i + 1;
- }
- if( !file_is_openable_for_read( mixer_device ) ) {
- fprintf( stderr, "mixer: Can't open device %s, "
- "mixer volume and mute unavailable.\n", mixer_device );
- }
-
- mixer_channel = SOUND_MIXER_LINE;
- for( i = 0; i < SOUND_MIXER_NRDEVICES; i++ ) {
- if( !strcasecmp( channame, oss_core_devnames[ i ] ) ) {
- mixer_channel = i;
- found = 1;
+ mixer->close_device();
+ for (i = 0; i < sizeof(mixers)/sizeof(mixers[0]); i++) {
+ mixer = mixers[i];
+ if (!mixer)
+ continue;
+ if (mixer->set_device(devname) == 0)
break;
- }
- }
- if( !found ) {
- fprintf( stderr, "mixer: No such mixer channel '%s', using channel 'line'.\n", channame );
- }
- mixer_dev_mask = 1 << mixer_channel;
-}
-
-void mixer_set_state( int ismuted, int unmute_volume )
-{
- /**
- * 1. we come back unmuted: Don't touch anything
- * 2. we don't have a saved volume: Don't touch anything
- * 3. we come back muted and we have a saved volume:
- * - if tvtime muted it, unmute to old volume
- * - if user did it, remember that we're muted and old volume
- */
- if( mixer_get_volume() == 0 && unmute_volume > 0 ) {
- saved_volume = unmute_volume;
- muted = 1;
-
- if( !ismuted ) {
- mixer_mute( 0 );
- }
}
}
-
-void mixer_close_device( void )
-{
- if( fd >= 0 ) close( fd );
- saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
- mixer_channel = SOUND_MIXER_LINE;
- mixer_dev_mask = 1 << SOUND_MIXER_LINE;
- muted = 0;
- mutecount = 0;
- fd = -1;
-}
-
diff --git a/src/mixer.h b/src/mixer.h
index 07923f4..a26fc88 100644
--- a/src/mixer.h
+++ b/src/mixer.h
@@ -27,45 +27,58 @@ extern "C" {
#endif
/**
- * Sets the mixer device and channel. The device name is of the form
- * devicename:channelname. The default is /dev/mixer:line.
+ * Sets the mixer device and channel.
+ * All interfaces are scanned until one succeeds.
*/
void mixer_set_device( const char *devname );
+struct mixer {
+/**
+ * Sets the mixer device and channel.
+ */
+int (* set_device)( const char *devname );
+
/**
* Sets the initial state of the mixer device.
*/
-void mixer_set_state( int ismuted, int unmute_volume );
+void (* set_state)( int ismuted, int unmute_volume );
/**
* Returns the current volume setting.
*/
-int mixer_get_volume( void );
+int (* get_volume)( void );
/**
* Returns the volume that would be used to restore the unmute state.
*/
-int mixer_get_unmute_volume( void );
+int (* get_unmute_volume)( void );
/**
* Tunes the relative volume.
*/
-int mixer_set_volume( int percentdiff );
+int (* set_volume)( int percentdiff );
/**
* Sets the mute state.
*/
-void mixer_mute( int mute );
+void (* mute)( int mute );
/**
* Returns true if the mixer is muted.
*/
-int mixer_ismute( void );
+int (* ismute)( void );
/**
* Closes the mixer device if it is open.
*/
-void mixer_close_device( void );
+void (* close_device)( void );
+};
+
+#pragma weak alsa_mixer
+extern struct mixer alsa_mixer;
+#pragma weak oss_mixer
+extern struct mixer oss_mixer;
+extern struct mixer *mixer;
#ifdef __cplusplus
};
diff --git a/src/tvtime.c b/src/tvtime.c
index d9066cc..3d42d53 100644
--- a/src/tvtime.c
+++ b/src/tvtime.c
@@ -1430,7 +1430,7 @@ int tvtime_main( rtctimer_t *rtctimer, int read_stdin, int realtime,
/* Set the mixer device. */
mixer_set_device( config_get_mixer_device( ct ) );
- mixer_set_state( config_get_muted( ct ), config_get_unmute_volume( ct ) );
+ mixer->set_state( config_get_muted( ct ), config_get_unmute_volume( ct ) );
/* Setup OSD stuff. */
pixel_aspect = ( (double) width ) /
@@ -2555,14 +2555,14 @@ int tvtime_main( rtctimer_t *rtctimer, int read_stdin, int realtime,
snprintf( number, 4, "%d", quiet_screenshots );
config_save( ct, "QuietScreenshots", number );
- snprintf( number, 6, "%d", mixer_get_unmute_volume() );
+ snprintf( number, 6, "%d", mixer->get_unmute_volume() );
config_save( ct, "UnmuteVolume", number );
- snprintf( number, 4, "%d", mixer_ismute() );
+ snprintf( number, 4, "%d", mixer->ismute() );
config_save( ct, "Muted", number );
if( config_get_mute_on_exit( ct ) ) {
- mixer_mute( 1 );
+ mixer->mute( 1 );
}
if( vidin ) {
@@ -2599,7 +2599,7 @@ int tvtime_main( rtctimer_t *rtctimer, int read_stdin, int realtime,
if( osd ) {
tvtime_osd_delete( osd );
}
- mixer_close_device();
+ mixer->close_device();
/* Free temporary memory. */
free( colourbars );
diff --git a/src/videoinput.c b/src/videoinput.c
index dd60334..2102b04 100644
--- a/src/videoinput.c
+++ b/src/videoinput.c
@@ -760,7 +760,7 @@ void videoinput_set_tuner_freq( videoinput_t *vidin, int freqKHz )
}
vidin->change_muted = 1;
- mixer_mute( 1 );
+ mixer->mute( 1 );
videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
vidin->cur_tuner_state = TUNER_STATE_SIGNAL_DETECTED;
vidin->signal_acquire_wait = SIGNAL_ACQUIRE_DELAY;
@@ -931,7 +931,7 @@ int videoinput_check_for_signal( videoinput_t *vidin, int check_freq_present )
if( vidin->change_muted ) {
vidin->change_muted = 0;
videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
- mixer_mute( 0 );
+ mixer->mute( 0 );
}
break;
}
@@ -942,7 +942,7 @@ int videoinput_check_for_signal( videoinput_t *vidin, int check_freq_present )
vidin->cur_tuner_state = TUNER_STATE_SIGNAL_LOST;
vidin->signal_recover_wait = SIGNAL_RECOVER_DELAY;
vidin->change_muted = 1;
- mixer_mute( 1 );
+ mixer->mute( 1 );
videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
case TUNER_STATE_SIGNAL_LOST:
if( vidin->signal_recover_wait ) {
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 04/10] Properly document alsa mixer
2011-09-06 15:29 ` [PATCH 03/10] Backport mixer-alsa patch from Fedora Mauro Carvalho Chehab
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 05/10] Ignore auto-generated files Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
Backported from Fedora:
commit 16ee4edaccd1a6a6869e4abf07581a2f7c6df1fb
Author: Tomas Smetana <tsmetana@fedoraproject.org>
Date: Thu Jul 9 07:09:44 2009 +0000
- fix a typo in the default config file
commit a4c64442a7c94cd175bca661e88682ee8de87ce4
Author: Tomas Smetana <tsmetana@fedoraproject.org>
Date: Sun Jun 28 10:01:27 2009 +0000
- try to document the new ALSA mixer settings, make ALSA mixer the default
one
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
docs/html/default.tvtime.xml | 8 +++++---
docs/man/en/tvtime.xml.5 | 5 ++++-
src/tvtimeconf.c | 18 +++++++++++-------
3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/docs/html/default.tvtime.xml b/docs/html/default.tvtime.xml
index 29d939a..bc71d10 100644
--- a/docs/html/default.tvtime.xml
+++ b/docs/html/default.tvtime.xml
@@ -116,13 +116,15 @@
<option name="VBIDevice" value="/dev/vbi0"/>
<!--
- This sets the mixer device and channel to use. The format is device
- name:channel name. Valid channels are:
+ This sets the mixer device and channel to use. The format for OSS
+ is device name:channel name. Valid OSS channels are:
vol, bass, treble, synth, pcm, speaker, line, mic, cd, mix, pcm2,
rec, igain, ogain, line1, line2, line3, dig1, dig2, dig3, phin,
phout, video, radio, monitor
+ The format for ALSA mixer is device/channel (e.g., "default/Line"
+ or "hw:0/CD")
-->
- <option name="MixerDevice" value="/dev/mixer:line"/>
+ <option name="MixerDevice" value="default/Line"/>
<!--
This option enables 16:9 aspect ratio mode by default on startup.
diff --git a/docs/man/en/tvtime.xml.5 b/docs/man/en/tvtime.xml.5
index 2fa6b61..08ec5df 100644
--- a/docs/man/en/tvtime.xml.5
+++ b/docs/man/en/tvtime.xml.5
@@ -234,7 +234,10 @@ This sets which device to use for VBI decoding.
.TP
<option name="MixerDevice" value="/dev/mixer:line"/>
This sets the mixer device and channel to use. The format is device
-name:channel name. Valid channels are:
+name:channel name for OSS mixer (e.g., "/dev/mixer:Line") or device/channel
+for ALSA (e.g., "hw:0/CD").
+
+Valid OSS channels are:
.nh
.IR vol ", " bass ", " treble ", " synth ", " pcm ", " speaker ", "
diff --git a/src/tvtimeconf.c b/src/tvtimeconf.c
index 5db6325..375686f 100644
--- a/src/tvtimeconf.c
+++ b/src/tvtimeconf.c
@@ -643,9 +643,11 @@ static void print_usage( char **argv )
lfputs( _(" -l, --xmltvlanguage=LANG Use XMLTV data in given language, if available.\n"), stderr );
lfputs( _(" -v, --verbose Print debugging messages to stderr.\n"), stderr );
lfputs( _(" -X, --display=DISPLAY Use the given X display to connect to.\n"), stderr );
- lfputs( _(" -x, --mixer=DEVICE[:CH] The mixer device and channel to control.\n"
- " (defaults to /dev/mixer:line)\n\n"
- " Valid channels are:\n"
+ lfputs( _(" -x, --mixer=<DEVICE[:CH]>|<DEVICE/CH>\n"
+ " The mixer device and channel to control. The first\n"
+ " variant sets the OSS mixer the second one ALSA.\n"
+ " (defaults to default/Line)\n\n"
+ " Valid channels for OSS are:\n"
" vol, bass, treble, synth, pcm, speaker, line,\n"
" mic, cd, mix, pcm2, rec, igain, ogain, line1,\n"
" line2, line3, dig1, dig2, dig3, phin, phout,\n"
@@ -691,9 +693,11 @@ static void print_config_usage( char **argv )
lfputs( _(" -R, --priority=PRI Sets the process priority to run tvtime at.\n"), stderr );
lfputs( _(" -t, --xmltv=FILE Read XMLTV listings from the given file.\n"), stderr );
lfputs( _(" -l, --xmltvlanguage=LANG Use XMLTV data in given language, if available.\n"), stderr );
- lfputs( _(" -x, --mixer=DEVICE[:CH] The mixer device and channel to control.\n"
- " (defaults to /dev/mixer:line)\n\n"
- " Valid channels are:\n"
+ lfputs( _(" -x, --mixer=<DEVICE[:CH]>|<DEVICE/CH>\n"
+ " The mixer device and channel to control. The first\n"
+ " variant sets the OSS mixer the second one ALSA.\n"
+ " (defaults to default/Line)\n\n"
+ " Valid channels for OSS are:\n"
" vol, bass, treble, synth, pcm, speaker, line,\n"
" mic, cd, mix, pcm2, rec, igain, ogain, line1,\n"
" line2, line3, dig1, dig2, dig3, phin, phout,\n"
@@ -786,7 +790,7 @@ config_t *config_new( void )
ct->uid = getuid();
- ct->mixerdev = strdup( "/dev/mixer:line" );
+ ct->mixerdev = strdup( "default/Line" );
ct->deinterlace_method = strdup( "GreedyH" );
ct->check_freq_present = 1;
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 05/10] Ignore auto-generated files
2011-09-06 15:29 ` [PATCH 04/10] Properly document alsa mixer Mauro Carvalho Chehab
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 06/10] Backport UVC fix from Fedora Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
.gitignore | 17 +++++++++++++++++
docs/.gitignore | 3 +++
intl/.gitignore | 2 ++
m4/.gitignore | 8 ++++++++
po/.gitignore | 7 +++++++
src/.gitignore | 9 +++++++++
6 files changed, 46 insertions(+), 0 deletions(-)
create mode 100644 .gitignore
create mode 100644 docs/.gitignore
create mode 100644 intl/.gitignore
create mode 100644 m4/.gitignore
create mode 100644 po/.gitignore
create mode 100644 src/.gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9bbc8df
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+autom4te.cache/
+Makefile
+Makefile.in
+aclocal.m4
+config.guess
+config.h
+config.h.in
+config.log
+config.status
+config.sub
+configure
+install-sh
+libtool
+ltmain.sh
+missing
+stamp-h1
+depcomp
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..22a4e72
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+
diff --git a/intl/.gitignore b/intl/.gitignore
new file mode 100644
index 0000000..5c1aa8c
--- /dev/null
+++ b/intl/.gitignore
@@ -0,0 +1,2 @@
+plural.c
+
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 0000000..19aca97
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1,8 @@
+Makefile
+Makefile.in
+libtool.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+lt~obsolete.m4
+
diff --git a/po/.gitignore b/po/.gitignore
new file mode 100644
index 0000000..d2fdb57
--- /dev/null
+++ b/po/.gitignore
@@ -0,0 +1,7 @@
+*.gmo
+Makefile
+Makefile.in
+POTFILES
+remove-potcdate.sed
+stamp-po
+
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..3a6766d
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1,9 @@
+*.o
+.deps/
+Makefile
+Makefile.in
+tvtime
+tvtime-command
+tvtime-configure
+tvtime-scanner
+
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 06/10] Backport UVC fix from Fedora
2011-09-06 15:29 ` [PATCH 05/10] Ignore auto-generated files Mauro Carvalho Chehab
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 07/10] Add mkinstalldirs Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
>From Fedora logs:
fix #655038 - tvtime does not work with UVC webcams
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
src/videoinput.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/videoinput.c b/src/videoinput.c
index 2102b04..a8fd829 100644
--- a/src/videoinput.c
+++ b/src/videoinput.c
@@ -294,6 +294,7 @@ uint8_t *videoinput_next_frame( videoinput_t *vidin, int *frameid )
wait_for_frame_v4l2( vidin );
cur_buf.type = vidin->capbuffers[ 0 ].vidbuf.type;
+ cur_buf.memory = vidin->capbuffers[ 0 ].vidbuf.memory;
if( ioctl( vidin->grab_fd, VIDIOC_DQBUF, &cur_buf ) < 0 ) {
/* some drivers return EIO when there is no signal */
if( errno != EIO ) {
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 07/10] Add mkinstalldirs
2011-09-06 15:29 ` [PATCH 06/10] Backport UVC fix from Fedora Mauro Carvalho Chehab
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 08/10] Use a saner way to disable screensaver Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
This is needed for make distcheck to be happy. Not sure why this
script is not here already... tvtime 1.0.2 tarball has it.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
mkinstalldirs | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 3 +-
2 files changed, 113 insertions(+), 1 deletions(-)
create mode 100755 mkinstalldirs
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..d2d5f21
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage" 1>&2
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+case $dirmode in
+ '')
+ if mkdir -p -- . 2>/dev/null; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ fi
+ ;;
+esac
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
diff --git a/src/Makefile.am b/src/Makefile.am
index 56e26a6..e48ef4c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,7 +45,8 @@ COMMON_SRCS = mixer.c videoinput.c rtctimer.c leetft.c osdtools.c tvtimeconf.c \
utils.h utils.c pulldown.h pulldown.c hashtable.h hashtable.c \
cpuinfo.h cpuinfo.c menu.c menu.h \
outputfilter.h outputfilter.c xmltv.h xmltv.c gettext.h tvtimeglyphs.h \
- copyfunctions.h copyfunctions.c alsa_stream.c mixer-oss.c $(ALSA_SRCS)
+ copyfunctions.h copyfunctions.c alsa_stream.c alsa_stream.h \
+ mixer-oss.c $(ALSA_SRCS)
if ARCH_X86
DSCALER_SRCS = $(top_srcdir)/plugins/dscalerapi.h \
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 08/10] Use a saner way to disable screensaver
2011-09-06 15:29 ` [PATCH 07/10] Add mkinstalldirs Mauro Carvalho Chehab
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
[not found] ` <1315322996-10576-9-git-send-email-mchehab@redhat.com>
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
Backport a Fedora patch that improves the way to disable
the screensaver:
commit 36cc9d2e1d762eddf5d8278fa58edd4680a7b449
Author: Tomas Smetana <tsmetana@zaphod.usersys.redhat.com>
Date: Mon Nov 8 22:01:57 2010 +0100
- fix #571339 use a saner way to disable screensaver, thanks to Debian folks
for the patch, namely Resul Cetin
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
configure.ac | 10 +++++-----
src/xcommon.c | 50 +++++++++++++++++++++++---------------------------
2 files changed, 28 insertions(+), 32 deletions(-)
diff --git a/configure.ac b/configure.ac
index 6cdedfb..f102b5b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -140,11 +140,11 @@ if test x"$no_x" != x"yes"; then
X11_LIBS="$X11_LIBS -lXinerama"],,
[$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
- dnl check for XTest
- AC_CHECK_LIB([Xtst],[XTestFakeKeyEvent],
- [AC_DEFINE([HAVE_XTESTEXTENSION],,[XTest support])
- X11_LIBS="$X11_LIBS -lXtst"],,
- [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
+ dnl check for XSs
+ PKG_CHECK_MODULES(XSS, xscrnsaver >= 1.2.0,
+ AC_DEFINE([HAVE_XSSEXTENSION],,[XScrnSaver support])
+ AC_SUBST(XSS_LIBS)
+ X11_LIBS="$X11_LIBS $XSS_LIBS",)
dnl check for Xvidmode
AC_CHECK_LIB([Xxf86vm],[XF86VidModeGetModeLine],
diff --git a/src/xcommon.c b/src/xcommon.c
index 8e3be4c..681b895 100644
--- a/src/xcommon.c
+++ b/src/xcommon.c
@@ -45,8 +45,8 @@
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#include <X11/extensions/XShm.h>
-#ifdef HAVE_XTESTEXTENSION
-#include <X11/extensions/XTest.h>
+#ifdef HAVE_XSSEXTENSION
+#include <X11/extensions/scrnsaver.h>
#endif
#include "xfullscreen.h"
@@ -67,7 +67,7 @@ static Window wm_window;
static Window fs_window;
static Window output_window;
static GC gc;
-static int have_xtest;
+static int have_xss;
static int output_width, output_height;
static int output_aspect;
static int output_on_root;
@@ -107,10 +107,6 @@ static Atom wm_delete_window;
static Atom xawtv_station;
static Atom xawtv_remote;
-#ifdef HAVE_XTESTEXTENSION
-static KeyCode kc_shift_l; /* Fake key to send. */
-#endif
-
static area_t video_area;
static area_t window_area;
static area_t scale_area;
@@ -248,12 +244,12 @@ static void x11_wait_mapped( Display *dpy, Window win )
} while ( (event.type != MapNotify) || (event.xmap.event != win) );
}
-static int have_xtestextention( void )
+static int have_xssextention( void )
{
-#ifdef HAVE_XTESTEXTENSION
- int dummy1, dummy2, dummy3, dummy4;
+#ifdef HAVE_XSSEXTENSION
+ int dummy1, dummy2;
- return (XTestQueryExtension( display, &dummy1, &dummy2, &dummy3, &dummy4 ) == True);
+ return (XScreenSaverQueryExtension( display, &dummy1, &dummy2 ) == True);
#endif
return 0;
}
@@ -843,7 +839,7 @@ int xcommon_open_display( const char *user_geometry, int aspect, int verbose )
output_aspect = aspect;
output_height = 576;
- have_xtest = 0;
+ have_xss = 0;
output_on_root = 0;
has_ewmh_state_fullscreen = 0;
has_ewmh_state_above = 0;
@@ -927,13 +923,16 @@ int xcommon_open_display( const char *user_geometry, int aspect, int verbose )
xfullscreen_print_summary( xf );
}
-#ifdef HAVE_XTESTEXTENSION
- kc_shift_l = XKeysymToKeycode( display, XK_Shift_L );
-#endif
- have_xtest = have_xtestextention();
- if( have_xtest && xcommon_verbose ) {
- fprintf( stderr, "xcommon: Have XTest, will use it to ping the screensaver.\n" );
+ have_xss = have_xssextention();
+ if( have_xss && xcommon_verbose ) {
+ fprintf( stderr, "xcommon: Have XSS, will use it to disable the screensaver.\n" );
+ }
+
+#ifdef HAVE_XSSEXTENSION
+ if ( have_xss ) {
+ XScreenSaverSuspend( display, True );
}
+#endif
/* Initially, get the best width for our height. */
output_width = xv_get_width_for_height( output_height );
@@ -1112,15 +1111,7 @@ void xcommon_ping_screensaver( void )
gettimeofday( &curtime, 0 );
if( timediff( &curtime, &last_ping_time ) > SCREENSAVER_PING_TIME ) {
last_ping_time = curtime;
-#ifdef HAVE_XTESTEXTENSION
- if( have_xtest ) {
- XTestFakeKeyEvent( display, kc_shift_l, True, CurrentTime );
- XTestFakeKeyEvent( display, kc_shift_l, False, CurrentTime );
- } else
-#endif
- {
- XResetScreenSaver( display );
- }
+ XResetScreenSaver( display );
}
}
@@ -1715,6 +1706,11 @@ void xcommon_poll_events( input_t *in )
void xcommon_close_display( void )
{
+#ifdef HAVE_XSSEXTENSION
+ if ( have_xss ) {
+ XScreenSaverSuspend( display, False );
+ }
+#endif
XDestroyWindow( display, output_window );
XDestroyWindow( display, wm_window );
XDestroyWindow( display, fs_window );
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 10/10] tvtime: Bump to version 1.0.3
[not found] ` <1315322996-10576-9-git-send-email-mchehab@redhat.com>
@ 2011-09-06 15:29 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
Need to update its version, in order to allow distros to use it.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
ChangeLog | 7 +++++++
NEWS | 10 +++++-----
configure.ac | 4 ++--
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 147b822..c613bde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+1.0.3 - Tue Sep 6 14:53:23 CEST 2011
+ * djh: Conversion to Mercurial, compilation fixes, patch backports
+ from other places, more generic VBI handling, Alsa streaming
+ support, get rid of V4L1.
+ * mchehab/hdegoede: Improved alsa audio streaming code.
+ * mchehab: Backport the remaining patches found on Fedora.
+
1.0.2 - Wed Nov 9 21:46:28 EST 2005
* vektor: Add a proper TVTIME_NOOP command so that you can remove
keybindings. Thanks to Andrew Dalton for the fix.
diff --git a/NEWS b/NEWS
index 7fe5522..0279b1d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,8 @@
-
-For news and updates on tvtime, please visit our website at:
-
- http://tvtime.net/
-
+News for 1.0.3
+ * V4L1 removal
+ * Alsa streaming support
+ * Compilation fixes, patch backports from other places
+ * More generic VBI handling
News for 1.0.2
diff --git a/configure.ac b/configure.ac
index f102b5b..37c2871 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,8 +1,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.52)
-AC_INIT(tvtime, 1.0.2, http://tvtime.net/)
+AC_INIT(tvtime, 1.0.3, http://linuxtv.org/)
AC_CONFIG_SRCDIR([src/tvtime.c])
-AM_INIT_AUTOMAKE(tvtime,1.0.2)
+AM_INIT_AUTOMAKE(tvtime,1.0.3)
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
AC_CANONICAL_HOST
--
1.7.6.1
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 15:29 [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 02/10] Fix make dist target Mauro Carvalho Chehab
@ 2011-09-06 15:40 ` Mauro Carvalho Chehab
2011-09-06 16:24 ` Devin Heitmueller
2011-09-07 2:58 ` Devin Heitmueller
2 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 15:40 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Linux Media Mailing List
Hi Devin,
Em 06-09-2011 12:29, Mauro Carvalho Chehab escreveu:
> There are several issues with the original alsa_stream code that got
> fixed on xawtv3, made by me and by Hans de Goede. Basically, the
> code were re-written, in order to follow the alsa best practises.
>
> Backport the changes from xawtv, in order to make it to work on a
> wider range of V4L and sound adapters.
FYI, just flooded your mailbox with 10 patches for tvtime. ;)
I'm wanting to test some things with tvtime on one of my testboxes, but some
of my cards weren't working with the alsa streaming, due to a few bugs that
were solved on xawtv fork.
So, I decided to backport it to tvtime and recompile the Fedora package for it.
That's where the other 9 patches come ;)
Basically, after applying this series of 10 patches, we can just remove all
patches from Fedora, making life easier for distro maintainers (as the same
thing is probably true on other distros - at least one of the Fedora patches
came from Debian, from the fedora git logs).
One important thing for distros is to have a tarball with the latest version
hosted on a public site, so I've increased the version to 1.0.3 and I'm
thinking on storing a copy of it at linuxtv, just like we do with xawtv3.
If you prefer, all patches are also on my tvtime git tree, at:
http://git.linuxtv.org/mchehab/tvtime.git
Thanks,
Mauro
>
> Signed-off-by: Mauro Carvalho Chehab<mchehab@redhat.com>
> ---
> src/alsa_stream.c | 629 ++++++++++++++++++++++++++++++-----------------------
> src/alsa_stream.h | 6 +-
> src/tvtime.c | 6 +-
> 3 files changed, 363 insertions(+), 278 deletions(-)
>
> diff --git a/src/alsa_stream.c b/src/alsa_stream.c
> index 2243b02..b6a41a5 100644
> --- a/src/alsa_stream.c
> +++ b/src/alsa_stream.c
> @@ -6,6 +6,9 @@
> * Derived from the alsa-driver test tool latency.c:
> * Copyright (c) by Jaroslav Kysela<perex@perex.cz>
> *
> + * Copyright (c) 2011 - Mauro Carvalho Chehab<mchehab@redhat.com>
> + * Ported to xawtv, with bug fixes and improvements
> + *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> * the Free Software Foundation; either version 2 of the License, or
> @@ -32,8 +35,16 @@
> #include<alsa/asoundlib.h>
> #include<sys/time.h>
> #include<math.h>
> +#include "alsa_stream.h"
> +
> +/* Private vars to control alsa thread status */
> +static int alsa_is_running = 0;
> +static int stop_alsa = 0;
>
> +/* Error handlers */
> snd_output_t *output = NULL;
> +FILE *error_fp;
> +int verbose = 0;
>
> struct final_params {
> int bufsize;
> @@ -42,403 +53,435 @@ struct final_params {
> int channels;
> };
>
> -int setparams_stream(snd_pcm_t *handle,
> - snd_pcm_hw_params_t *params,
> - snd_pcm_format_t format,
> - int channels,
> - int rate,
> - const char *id)
> +static int setparams_stream(snd_pcm_t *handle,
> + snd_pcm_hw_params_t *params,
> + snd_pcm_format_t format,
> + int channels,
> + const char *id)
> {
> int err;
> - unsigned int rrate;
>
> err = snd_pcm_hw_params_any(handle, params);
> if (err< 0) {
> - printf("Broken configuration for %s PCM: no configurations available: %s\n", snd_strerror(err), id);
> - return err;
> - }
> - err = snd_pcm_hw_params_set_rate_resample(handle, params, 1);
> - if (err< 0) {
> - printf("Resample setup failed for %s: %s\n", id, snd_strerror(err));
> + fprintf(error_fp,
> + "alsa: Broken configuration for %s PCM: no configurations available: %s\n",
> + snd_strerror(err), id);
> return err;
> }
> +
> err = snd_pcm_hw_params_set_access(handle, params,
> SND_PCM_ACCESS_RW_INTERLEAVED);
> if (err< 0) {
> - printf("Access type not available for %s: %s\n", id,
> - snd_strerror(err));
> + fprintf(error_fp, "alsa: Access type not available for %s: %s\n", id,
> + snd_strerror(err));
> return err;
> }
>
> err = snd_pcm_hw_params_set_format(handle, params, format);
> if (err< 0) {
> - printf("Sample format not available for %s: %s\n", id,
> + fprintf(error_fp, "alsa: Sample format not available for %s: %s\n", id,
> snd_strerror(err));
> return err;
> }
> err = snd_pcm_hw_params_set_channels(handle, params, channels);
> if (err< 0) {
> - printf("Channels count (%i) not available for %s: %s\n", channels, id,
> - snd_strerror(err));
> - return err;
> - }
> - rrate = rate;
> - err = snd_pcm_hw_params_set_rate_near(handle, params,&rrate, 0);
> - if (err< 0) {
> - printf("Rate %iHz not available for %s: %s\n", rate, id,
> - snd_strerror(err));
> + fprintf(error_fp, "alsa: Channels count (%i) not available for %s: %s\n",
> + channels, id, snd_strerror(err));
> return err;
> }
> - if ((int)rrate != rate) {
> - printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
> - return -EINVAL;
> - }
> +
> return 0;
> }
>
> -int setparams_bufsize(snd_pcm_t *handle,
> +static void getparams_periods(snd_pcm_t *handle,
> snd_pcm_hw_params_t *params,
> - snd_pcm_hw_params_t *tparams,
> - snd_pcm_uframes_t bufsize,
> - int period_size,
> + unsigned int *usecs,
> + unsigned int *count,
> + const char *id)
> +{
> + unsigned min = 0, max = 0;
> +
> + snd_pcm_hw_params_get_periods_min(params,&min, 0);
> + snd_pcm_hw_params_get_periods_max(params,&max, 0);
> + if (min&& max) {
> + if (verbose)
> + fprintf(error_fp, "alsa: %s periods range between %u and %u. Want: %u\n",
> + id, min, max, *count);
> + if (*count< min)
> + *count = min;
> + if (*count> max)
> + *count = max;
> + }
> +
> + min = max = 0;
> + snd_pcm_hw_params_get_period_time_min(params,&min, 0);
> + snd_pcm_hw_params_get_period_time_max(params,&max, 0);
> + if (min&& max) {
> + if (verbose)
> + fprintf(error_fp, "alsa: %s period time range between %u and %u. Want: %u\n",
> + id, min, max, *usecs);
> + if (*usecs< min)
> + *usecs = min;
> + if (*usecs> max)
> + *usecs = max;
> + }
> +}
> +
> +static int setparams_periods(snd_pcm_t *handle,
> + snd_pcm_hw_params_t *params,
> + unsigned int *usecs,
> + unsigned int *count,
> const char *id)
> {
> int err;
> - snd_pcm_uframes_t periodsize;
>
> - snd_pcm_hw_params_copy(params, tparams);
> - periodsize = bufsize * 2;
> - err = snd_pcm_hw_params_set_buffer_size_near(handle, params,&periodsize);
> + err = snd_pcm_hw_params_set_period_time_near(handle, params, usecs, 0);
> if (err< 0) {
> - printf("Unable to set buffer size %li for %s: %s\n",
> - bufsize * 2, id, snd_strerror(err));
> - return err;
> + fprintf(error_fp, "alsa: Unable to set period time %u for %s: %s\n",
> + *usecs, id, snd_strerror(err));
> + return err;
> }
> - if (period_size> 0)
> - periodsize = period_size;
> - else
> - periodsize /= 2;
> - err = snd_pcm_hw_params_set_period_size_near(handle, params,&periodsize,
> - 0);
> +
> + err = snd_pcm_hw_params_set_periods_near(handle, params, count, 0);
> if (err< 0) {
> - printf("Unable to set period size %li for %s: %s\n", periodsize, id,
> - snd_strerror(err));
> + fprintf(error_fp, "alsa: Unable to set %u periods for %s: %s\n",
> + *count, id, snd_strerror(err));
> return err;
> }
> +
> + if (verbose)
> + fprintf(error_fp, "alsa: %s period set to %u periods of %u time\n",
> + id, *count, *usecs);
> +
> return 0;
> }
>
> -int setparams_set(snd_pcm_t *handle,
> - snd_pcm_hw_params_t *params,
> - snd_pcm_sw_params_t *swparams,
> - const char *id)
> +static int setparams_set(snd_pcm_t *handle,
> + snd_pcm_hw_params_t *params,
> + snd_pcm_sw_params_t *swparams,
> + snd_pcm_uframes_t start_treshold,
> + const char *id)
> {
> int err;
>
> err = snd_pcm_hw_params(handle, params);
> if (err< 0) {
> - printf("Unable to set hw params for %s: %s\n", id, snd_strerror(err));
> + fprintf(error_fp, "alsa: Unable to set hw params for %s: %s\n",
> + id, snd_strerror(err));
> return err;
> }
> err = snd_pcm_sw_params_current(handle, swparams);
> if (err< 0) {
> - printf("Unable to determine current swparams for %s: %s\n", id,
> - snd_strerror(err));
> + fprintf(error_fp, "alsa: Unable to determine current swparams for %s: %s\n",
> + id, snd_strerror(err));
> return err;
> }
> - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0x7fffffff);
> + err = snd_pcm_sw_params_set_start_threshold(handle, swparams,
> + start_treshold);
> if (err< 0) {
> - printf("Unable to set start threshold mode for %s: %s\n", id,
> - snd_strerror(err));
> + fprintf(error_fp, "alsa: Unable to set start threshold mode for %s: %s\n",
> + id, snd_strerror(err));
> return err;
> }
>
> err = snd_pcm_sw_params_set_avail_min(handle, swparams, 4);
> if (err< 0) {
> - printf("Unable to set avail min for %s: %s\n", id, snd_strerror(err));
> + fprintf(error_fp, "alsa: Unable to set avail min for %s: %s\n",
> + id, snd_strerror(err));
> return err;
> }
> err = snd_pcm_sw_params(handle, swparams);
> if (err< 0) {
> - printf("Unable to set sw params for %s: %s\n", id, snd_strerror(err));
> + fprintf(error_fp, "alsa: Unable to set sw params for %s: %s\n",
> + id, snd_strerror(err));
> return err;
> }
> return 0;
> }
>
> -int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, snd_pcm_format_t format,
> - struct final_params *negotiated)
> +static int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle,
> + snd_pcm_format_t format,
> + int latency, int allow_resample,
> + struct final_params *negotiated)
> {
> - int rate = 48000;
> - int latency_min = 600; /* in frames / 2 */
> - int channels = 2;
> - int latency = latency_min - 4;
> - int bufsize = latency;
> - int err, last_bufsize = bufsize;
> - snd_pcm_hw_params_t *pt_params, *ct_params;
> - snd_pcm_hw_params_t *p_params, *c_params;
> + int i;
> + unsigned ratep, ratec = 0;
> + unsigned ratemin = 32000, ratemax = 96000, val;
> + int err, channels = 2;
> + snd_pcm_hw_params_t *p_hwparams, *c_hwparams;
> snd_pcm_sw_params_t *p_swparams, *c_swparams;
> - snd_pcm_uframes_t p_size, c_size, p_psize, c_psize;
> - unsigned int p_time, c_time;
> -
> - snd_pcm_hw_params_alloca(&p_params);
> - snd_pcm_hw_params_alloca(&c_params);
> - snd_pcm_hw_params_alloca(&pt_params);
> - snd_pcm_hw_params_alloca(&ct_params);
> + snd_pcm_uframes_t c_size, p_psize, c_psize;
> + /* Our latency is 2 periods (in usecs) */
> + unsigned int c_periods = 2, p_periods;
> + unsigned int c_periodtime, p_periodtime;
> +
> + snd_pcm_hw_params_alloca(&p_hwparams);
> + snd_pcm_hw_params_alloca(&c_hwparams);
> snd_pcm_sw_params_alloca(&p_swparams);
> snd_pcm_sw_params_alloca(&c_swparams);
> - if ((err = setparams_stream(phandle, pt_params, format, channels, rate,
> - "playback"))< 0) {
> - printf("Unable to set parameters for playback stream: %s\n", snd_strerror(err));
> - return 1;
> - }
> - if ((err = setparams_stream(chandle, ct_params, format, channels, rate,
> - "capture"))< 0) {
> - printf("Unable to set parameters for playback stream: %s\n", snd_strerror(err));
> +
> + if (setparams_stream(phandle, p_hwparams, format, channels, "playback"))
> return 1;
> - }
>
> - __again:
> - if (last_bufsize == bufsize)
> - bufsize += 4;
> - last_bufsize = bufsize;
> + if (setparams_stream(chandle, c_hwparams, format, channels, "capture"))
> + return 1;
>
> - if ((err = setparams_bufsize(phandle, p_params, pt_params, bufsize, 0,
> - "playback"))< 0) {
> - printf("Unable to set sw parameters for playback stream: %s\n",
> - snd_strerror(err));
> - return -1;
> - }
> - if ((err = setparams_bufsize(chandle, c_params, ct_params, bufsize, 0,
> - "capture"))< 0) {
> - printf("Unable to set sw parameters for playback stream: %s\n",
> - snd_strerror(err));
> - return -1;
> + if (allow_resample) {
> + err = snd_pcm_hw_params_set_rate_resample(chandle, c_hwparams, 1);
> + if (err< 0) {
> + fprintf(error_fp, "alsa: Resample setup failed: %s\n", snd_strerror(err));
> + return 1;
> + } else if (verbose)
> + fprintf(error_fp, "alsa: Resample enabled.\n");
> + }
> +
> + err = snd_pcm_hw_params_get_rate_min(c_hwparams,&ratemin, 0);
> + if (err>= 0&& verbose)
> + fprintf(error_fp, "alsa: Capture min rate is %d\n", ratemin);
> + err = snd_pcm_hw_params_get_rate_max(c_hwparams,&ratemax, 0);
> + if (err>= 0&& verbose)
> + fprintf(error_fp, "alsa: Capture max rate is %u\n", ratemax);
> +
> + err = snd_pcm_hw_params_get_rate_min(p_hwparams,&val, 0);
> + if (err>= 0) {
> + if (verbose)
> + fprintf(error_fp, "alsa: Playback min rate is %u\n", val);
> + if (val> ratemin)
> + ratemin = val;
> + }
> + err = snd_pcm_hw_params_get_rate_max(p_hwparams,&val, 0);
> + if (err>= 0) {
> + if (verbose)
> + fprintf(error_fp, "alsa: Playback max rate is %u\n", val);
> + if (val< ratemax)
> + ratemax = val;
> + }
> +
> + if (verbose)
> + fprintf(error_fp, "alsa: Will search a common rate between %u and %u\n",
> + ratemin, ratemax);
> +
> + for (i = ratemin; i<= ratemax; i+= 100) {
> + err = snd_pcm_hw_params_set_rate_near(chandle, c_hwparams,&i, 0);
> + if (err)
> + continue;
> + ratec = i;
> + ratep = i;
> + err = snd_pcm_hw_params_set_rate_near(phandle, p_hwparams,&ratep, 0);
> + if (err)
> + continue;
> + if (ratep == ratec)
> + break;
> + if (verbose)
> + fprintf(error_fp,
> + "alsa: Failed to set to %u: capture wanted %u, playback wanted %u%s\n",
> + i, ratec, ratep,
> + allow_resample ? " with resample enabled": "");
> }
>
> - snd_pcm_hw_params_get_period_size(p_params,&p_psize, NULL);
> - if (p_psize> (unsigned int)bufsize)
> - bufsize = p_psize;
> -
> - snd_pcm_hw_params_get_period_size(c_params,&c_psize, NULL);
> - if (c_psize> (unsigned int)bufsize)
> - bufsize = c_psize;
> + if (err< 0) {
> + fprintf(error_fp, "alsa: Failed to set a supported rate: %s\n",
> + snd_strerror(err));
> + return 1;
> + }
> + if (ratep != ratec) {
> + if (verbose || allow_resample)
> + fprintf(error_fp,
> + "alsa: Couldn't find a rate that it is supported by both playback and capture\n");
> + return 2;
> + }
> + if (verbose)
> + fprintf(error_fp, "alsa: Using Rate %d\n", ratec);
> +
> + /* Negociate period parameters */
> +
> + c_periodtime = latency * 1000 / c_periods;
> + getparams_periods(chandle, c_hwparams,&c_periodtime,&c_periods, "capture");
> + p_periods = c_periods * 2;
> + p_periodtime = c_periodtime;
> + getparams_periods(phandle, p_hwparams,&p_periodtime,&p_periods, "playback");
> + c_periods = p_periods / 2;
> +
> + /*
> + * 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
> + * the number of periods, to archive the needed latency
> + */
> + 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");
> + p_periods = c_periods * 2;
> + p_periodtime = c_periodtime;
> + getparams_periods(phandle, p_hwparams,&p_periodtime,&p_periods, "playback");
> + c_periods = p_periods / 2;
> + }
> +
> + if (setparams_periods(chandle, c_hwparams,&c_periodtime,&c_periods, "capture"))
> + return 1;
>
> - snd_pcm_hw_params_get_period_time(p_params,&p_time, NULL);
> - snd_pcm_hw_params_get_period_time(c_params,&c_time, NULL);
> + /* Note we use twice as much periods for the playback buffer, since we
> + will get a period size near the requested time and we don't want it to
> + end up smaller then the capture buffer as then we could end up blocking
> + on writing to it. Note we will configure the playback dev to start
> + playing as soon as it has 2 capture periods worth of data, so this
> + won't influence latency */
> + if (setparams_periods(phandle, p_hwparams,&p_periodtime,&p_periods, "playback"))
> + return 1;
>
> - if (p_time != c_time)
> - goto __again;
> + snd_pcm_hw_params_get_period_size(p_hwparams,&p_psize, NULL);
> + snd_pcm_hw_params_get_period_size(c_hwparams,&c_psize, NULL);
> + snd_pcm_hw_params_get_buffer_size(c_hwparams,&c_size);
>
> - snd_pcm_hw_params_get_buffer_size(p_params,&p_size);
> - if (p_psize * 2< p_size)
> - goto __again;
> - snd_pcm_hw_params_get_buffer_size(c_params,&c_size);
> - if (c_psize * 2< c_size)
> - goto __again;
> + latency = c_periods * c_psize;
> + if (setparams_set(phandle, p_hwparams, p_swparams, latency, "playback"))
> + return 1;
>
> - if ((err = setparams_set(phandle, p_params, p_swparams, "playback"))< 0) {
> - printf("Unable to set sw parameters for playback stream: %s\n",
> - snd_strerror(err));
> - return -1;
> - }
> - if ((err = setparams_set(chandle, c_params, c_swparams, "capture"))< 0) {
> - printf("Unable to set sw parameters for playback stream: %s\n",
> - snd_strerror(err));
> - return -1;
> - }
> + if (setparams_set(chandle, c_hwparams, c_swparams, c_psize, "capture"))
> + return 1;
>
> if ((err = snd_pcm_prepare(phandle))< 0) {
> - printf("Prepare error: %s\n", snd_strerror(err));
> - return -1;
> + fprintf(error_fp, "alsa: Prepare error: %s\n", snd_strerror(err));
> + return 1;
> }
>
> -#ifdef SHOW_ALSA_DEBUG
> - printf("final config\n");
> - snd_pcm_dump_setup(phandle, output);
> - snd_pcm_dump_setup(chandle, output);
> - printf("Parameters are %iHz, %s, %i channels\n", rate,
> - snd_pcm_format_name(format), channels);
> - fflush(stdout);
> -#endif
> + if (verbose) {
> + fprintf(error_fp, "alsa: Negociated configuration:\n");
> + snd_pcm_dump_setup(phandle, output);
> + snd_pcm_dump_setup(chandle, output);
> + fprintf(error_fp, "alsa: Parameters are %iHz, %s, %i channels\n",
> + ratep, snd_pcm_format_name(format), channels);
> + fprintf(error_fp, "alsa: Set bitrate to %u%s, buffer size is %u\n", ratec,
> + allow_resample ? " with resample enabled at playback": "",
> + (unsigned int)c_size);
> + }
>
> - negotiated->bufsize = bufsize;
> - negotiated->rate = rate;
> + negotiated->bufsize = c_size;
> + negotiated->rate = ratep;
> negotiated->channels = channels;
> - negotiated->latency = bufsize;
> + negotiated->latency = latency;
> return 0;
> }
>
> -void setscheduler(void)
> -{
> - struct sched_param sched_param;
> -
> - if (sched_getparam(0,&sched_param)< 0) {
> - printf("Scheduler getparam failed...\n");
> - return;
> - }
> - sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
> - if (!sched_setscheduler(0, SCHED_RR,&sched_param)) {
> - printf("Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);
> - fflush(stdout);
> - return;
> - }
> - printf("!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority);
> -}
> -
> -snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len,
> - size_t *frames, size_t *max)
> +/* Read up to len frames */
> +static snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len)
> {
> snd_pcm_sframes_t r;
>
> r = snd_pcm_readi(handle, buf, len);
> - if (r< 0) {
> - return r;
> + if (r< 0&& r != -EAGAIN) {
> + r = snd_pcm_recover(handle, r, 0);
> + if (r< 0)
> + fprintf(error_fp, "alsa: overrun recover error: %s\n", snd_strerror(r));
> }
> -
> - if (r> 0) {
> - *frames += r;
> - if ((long)*max< r)
> - *max = r;
> - }
> -
> return r;
> }
>
> -snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char *buf, long len,
> - size_t *frames)
> +/* Write len frames (note not up to len, but all of len!) */
> +static snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char *buf, long len)
> {
> snd_pcm_sframes_t r;
>
> - while (len> 0) {
> + while (1) {
> r = snd_pcm_writei(handle, buf, len);
> + if (r == len)
> + return 0;
> if (r< 0) {
> - return r;
> + r = snd_pcm_recover(handle, r, 0);
> + if (r< 0) {
> + fprintf(error_fp, "alsa: underrun recover error: %s\n",
> + snd_strerror(r));
> + return r;
> + }
> }
> -
> buf += r * 4;
> len -= r;
> - *frames += r;
> - }
> - return 0;
> -}
> -
> -int startup_capture(snd_pcm_t *phandle, snd_pcm_t *chandle,
> - snd_pcm_format_t format, char *buffer, int latency,
> - int channels)
> -{
> - size_t frames_out;
> - int err;
> -
> - frames_out = 0;
> - if (snd_pcm_format_set_silence(format, buffer, latency*channels)< 0) {
> - fprintf(stderr, "silence error\n");
> - return 1;
> - }
> - if (writebuf(phandle, buffer, latency,&frames_out)< 0) {
> - fprintf(stderr, "write error\n");
> - return 1;
> + snd_pcm_wait(handle, 100);
> }
> - if (writebuf(phandle, buffer, latency,&frames_out)< 0) {
> - fprintf(stderr, "write error\n");
> - return 1;
> - }
> -
> - if ((err = snd_pcm_start(chandle))< 0) {
> - printf("Go error: %s\n", snd_strerror(err));
> - return 1;
> - }
> - return 0;
> }
>
> -int tvtime_alsa_stream(const char *pdevice, const char *cdevice)
> +static int alsa_stream(const char *pdevice, const char *cdevice, int latency)
> {
> snd_pcm_t *phandle, *chandle;
> char *buffer;
> int err;
> ssize_t r;
> - size_t frames_in, frames_out, in_max;
> struct final_params negotiated;
> - int ret = 0;
> snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
> + char pdevice_new[32];
>
> - err = snd_output_stdio_attach(&output, stdout, 0);
> + err = snd_output_stdio_attach(&output, error_fp, 0);
> if (err< 0) {
> - printf("Output failed: %s\n", snd_strerror(err));
> + fprintf(error_fp, "alsa: Output failed: %s\n", snd_strerror(err));
> return 0;
> }
>
> -// setscheduler();
> -
> - printf("Playback device is %s\n", pdevice);
> - printf("Capture device is %s\n", cdevice);
> -
> /* Open the devices */
> if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK,
> - SND_PCM_NONBLOCK))< 0) {
> - printf("Cannot open ALSA Playback device %s: %s\n", pdevice,
> - snd_strerror(err));
> + 0))< 0) {
> + fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n",
> + pdevice, snd_strerror(err));
> return 0;
> }
> if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE,
> SND_PCM_NONBLOCK))< 0) {
> - printf("Cannot open ALSA Capture device %s: %s\n",
> - cdevice, snd_strerror(err));
> + fprintf(error_fp, "alsa: Cannot open capture device %s: %s\n",
> + cdevice, snd_strerror(err));
> return 0;
> }
>
> - frames_in = frames_out = 0;
> - if (setparams(phandle, chandle, format,&negotiated)< 0) {
> - printf("setparams failed\n");
> + err = setparams(phandle, chandle, format, latency, 0,&negotiated);
> +
> + /* Try to use plughw instead, as it allows emulating speed */
> + if (err == 2&& strncmp(pdevice, "hw", 2) == 0) {
> +
> + snd_pcm_close(phandle);
> +
> + sprintf(pdevice_new, "plug%s", pdevice);
> + pdevice = pdevice_new;
> + if (verbose)
> + fprintf(error_fp, "alsa: Trying %s for playback\n", pdevice);
> + if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK,
> + 0))< 0) {
> + fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n",
> + pdevice, snd_strerror(err));
> + }
> +
> + err = setparams(phandle, chandle, format, latency, 1,&negotiated);
> + }
> +
> + if (err != 0) {
> + fprintf(error_fp, "alsa: setparams failed\n");
> return 1;
> }
>
> buffer = malloc((negotiated.bufsize * snd_pcm_format_width(format) / 8)
> * negotiated.channels);
> if (buffer == NULL) {
> - printf("Failed allocating buffer for audio\n");
> + fprintf(error_fp, "alsa: Failed allocating buffer for audio\n");
> return 0;
> -
> - }
> - if ((err = snd_pcm_link(chandle, phandle))< 0) {
> - printf("Streams link error: %d %s\n", err, snd_strerror(err));
> - return 1;
> }
>
> - startup_capture(phandle, chandle, format, buffer, negotiated.latency,
> - negotiated.channels);
> -
> - while (1) {
> - in_max = 0;
> -
> + /*
> + * Buffering delay is due for capture and for playback, so we
> + * need to multiply it by two.
> + */
> + fprintf(error_fp,
> + "alsa: stream started from %s to %s (%i Hz, buffer delay = %.2f ms)\n",
> + cdevice, pdevice, negotiated.rate,
> + negotiated.latency * 1000.0 / negotiated.rate);
> +
> + alsa_is_running = 1;
> +
> + while (!stop_alsa) {
> + /* We start with a read and not a wait to auto(re)start the capture */
> + r = readbuf(chandle, buffer, negotiated.bufsize);
> + if (r == 0) /* Succesfully recovered from an overrun? */
> + continue; /* Force restart of capture stream */
> + if (r> 0)
> + writebuf(phandle, buffer, r);
> /* use poll to wait for next event */
> - ret = snd_pcm_wait(chandle, 1000);
> - if (ret< 0) {
> - if ((err = snd_pcm_recover(chandle, ret, 0))< 0) {
> - fprintf(stderr, "xrun: recover error: %s",
> - snd_strerror(err));
> - break;
> - }
> -
> - /* Restart capture */
> - startup_capture(phandle, chandle, format, buffer,
> - negotiated.latency, negotiated.channels);
> - continue;
> - } else if (ret == 0) {
> - /* Timed out */
> - continue;
> - }
> -
> - if ((r = readbuf(chandle, buffer, negotiated.latency,&frames_in,
> - &in_max))> 0) {
> - if (writebuf(phandle, buffer, r,&frames_out)< 0) {
> - startup_capture(phandle, chandle, format, buffer,
> - negotiated.latency, negotiated.channels);
> - }
> - } else if (r< 0) {
> - startup_capture(phandle, chandle, format, buffer,
> - negotiated.latency, negotiated.channels);
> - }
> + snd_pcm_wait(chandle, 1000);
> }
>
> snd_pcm_drop(chandle);
> @@ -451,28 +494,55 @@ int tvtime_alsa_stream(const char *pdevice, const char *cdevice)
>
> snd_pcm_close(phandle);
> snd_pcm_close(chandle);
> +
> + alsa_is_running = 0;
> return 0;
> }
>
> struct input_params {
> - const char *pdevice;
> - const char *cdevice;
> + char *pdevice;
> + char *cdevice;
> + int latency;
> };
>
> -void *tvtime_alsa_thread_entry(void *whatever)
> +static void *alsa_thread_entry(void *whatever)
> {
> struct input_params *inputs = (struct input_params *) whatever;
> - tvtime_alsa_stream(inputs->pdevice, inputs->cdevice);
> +
> + if (verbose)
> + fprintf(error_fp, "alsa: starting copying alsa stream from %s to %s\n",
> + inputs->cdevice, inputs->pdevice);
> + alsa_stream(inputs->pdevice, inputs->cdevice, inputs->latency);
> + fprintf(error_fp, "alsa: stream stopped\n");
> +
> + free(inputs->pdevice);
> + free(inputs->cdevice);
> + free(inputs);
> +
> + return NULL;
> }
>
> -int tvtime_alsa_thread_startup(const char *pdevice, const char *cdevice)
> +/*************************************************************************
> + Public functions
> + *************************************************************************/
> +
> +int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency,
> + FILE *__error_fp, int __verbose)
> {
> int ret;
> pthread_t thread;
> struct input_params *inputs = malloc(sizeof(struct input_params));
>
> + if (__error_fp)
> + error_fp = __error_fp;
> + else
> + error_fp = stderr;
> +
> + verbose = __verbose;
> +
> +
> if (inputs == NULL) {
> - printf("failed allocating memory for ALSA inputs\n");
> + fprintf(error_fp, "alsa: failed allocating memory for inputs\n");
> return 0;
> }
>
> @@ -484,18 +554,27 @@ int tvtime_alsa_thread_startup(const char *pdevice, const char *cdevice)
>
> inputs->pdevice = strdup(pdevice);
> inputs->cdevice = strdup(cdevice);
> + inputs->latency = latency;
> +
> + if (alsa_is_running) {
> + stop_alsa = 1;
> + while ((volatile int)alsa_is_running)
> + usleep(10);
> + }
> +
> + stop_alsa = 0;
>
> ret = pthread_create(&thread, NULL,
> - &tvtime_alsa_thread_entry, (void *) inputs);
> + &alsa_thread_entry, (void *) inputs);
> return ret;
> }
>
> -#ifdef TVTIME_ALSA_DEBUGGING
> -/* This allows the alsa_stream.c to be a standalone binary for debugging */
> - int main(int argc, char *argv[])
> +void alsa_thread_stop(void)
> +{
> + stop_alsa = 1;
> +}
> +
> +int alsa_thread_is_running(void)
> {
> - char *pdevice = "hw:0,0";
> - char *cdevice = "hw:1,0";
> - tvtime_alsa_stream(pdevice, cdevice);
> + return alsa_is_running;
> }
> -#endif
> diff --git a/src/alsa_stream.h b/src/alsa_stream.h
> index 8572c8b..c68fd6d 100644
> --- a/src/alsa_stream.h
> +++ b/src/alsa_stream.h
> @@ -1 +1,5 @@
> -int tvtime_alsa_thread_startup(char *pdevice, char *cdevice);
> +int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency,
> + FILE *__error_fp,
> + int __verbose);
> +void alsa_thread_stop(void);
> +int alsa_thread_is_running(void);
> diff --git a/src/tvtime.c b/src/tvtime.c
> index 75257d1..d9066cc 100644
> --- a/src/tvtime.c
> +++ b/src/tvtime.c
> @@ -1256,8 +1256,10 @@ int tvtime_main( rtctimer_t *rtctimer, int read_stdin, int realtime,
> }
>
> /* Setup the ALSA streaming device */
> - tvtime_alsa_thread_startup(config_get_alsa_outputdev( ct ),
> - config_get_alsa_inputdev( ct ) );
> + alsa_thread_startup(config_get_alsa_outputdev( ct ),
> + config_get_alsa_inputdev( ct ),
> + 30, /* FIXME: Add a var to adjust latency */
> + stderr, verbose );
>
> /* Setup the speedy calls. */
> setup_speedy_calls( mm_accel(), verbose );
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 15:40 ` [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
@ 2011-09-06 16:24 ` Devin Heitmueller
2011-09-06 18:19 ` Hans de Goede
2011-09-06 18:40 ` Mauro Carvalho Chehab
0 siblings, 2 replies; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-06 16:24 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: Linux Media Mailing List
On Tue, Sep 6, 2011 at 11:40 AM, Mauro Carvalho Chehab
<mchehab@redhat.com> wrote:
> Hi Devin,
>
> Em 06-09-2011 12:29, Mauro Carvalho Chehab escreveu:
>> There are several issues with the original alsa_stream code that got
>> fixed on xawtv3, made by me and by Hans de Goede. Basically, the
>> code were re-written, in order to follow the alsa best practises.
>>
>> Backport the changes from xawtv, in order to make it to work on a
>> wider range of V4L and sound adapters.
>
> FYI, just flooded your mailbox with 10 patches for tvtime. ;)
>
> I'm wanting to test some things with tvtime on one of my testboxes, but some
> of my cards weren't working with the alsa streaming, due to a few bugs that
> were solved on xawtv fork.
>
> So, I decided to backport it to tvtime and recompile the Fedora package for it.
> That's where the other 9 patches come ;)
>
> Basically, after applying this series of 10 patches, we can just remove all
> patches from Fedora, making life easier for distro maintainers (as the same
> thing is probably true on other distros - at least one of the Fedora patches
> came from Debian, from the fedora git logs).
>
> One important thing for distros is to have a tarball with the latest version
> hosted on a public site, so I've increased the version to 1.0.3 and I'm
> thinking on storing a copy of it at linuxtv, just like we do with xawtv3.
>
> If you prefer, all patches are also on my tvtime git tree, at:
> http://git.linuxtv.org/mchehab/tvtime.git
>
> Thanks,
> Mauro
Hi Mauro,
Funny you should send these along today. Last Friday I was actually
poking around at the Fedora tvtime repo because I was curious how they
had dealt with the V4L1 support issue (whether they were using my
patch removing v4l1 or some variant).
I've actually pulled in Fedora patches in the past (as you can see
from the hg repo), and it has always been my intention to do it for
the other distros as well (e.g. debian/Ubuntu). So I appreciate your
having sent these along.
I'll pull these in this week, do some testing to make sure nothing
serious got broken, and work to spin a 1.0.3 toward the end of the
week. Given the number of features/changes, and how long it's been
since the last formal release, I was considering calling it 1.1.0
instead though.
I've been thinking for a while that perhaps the project should be
renamed (or I considered prepending "kl" onto the front resulting in
it being called "kl-tvtime"). This isn't out of vanity but rather my
concern that the fork will get confused with the original project (for
example, I believe Ubuntu actually already calls their modified tree
tvtime 1.0.3). I'm open to suggestions in this regards.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 16:24 ` Devin Heitmueller
@ 2011-09-06 18:19 ` Hans de Goede
2011-09-06 18:35 ` Michael Krufky
2011-09-06 18:41 ` Devin Heitmueller
2011-09-06 18:40 ` Mauro Carvalho Chehab
1 sibling, 2 replies; 32+ messages in thread
From: Hans de Goede @ 2011-09-06 18:19 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Mauro Carvalho Chehab, Linux Media Mailing List
Hi,
On 09/06/2011 06:24 PM, Devin Heitmueller wrote:
<snip>
> I've been thinking for a while that perhaps the project should be
> renamed (or I considered prepending "kl" onto the front resulting in
> it being called "kl-tvtime"). This isn't out of vanity but rather my
> concern that the fork will get confused with the original project (for
> example, I believe Ubuntu actually already calls their modified tree
> tvtime 1.0.3). I'm open to suggestions in this regards.
I think that what should be done is contact the debian / ubuntu maintainers,
get any interesting fixes they have which the kl version misses merged,
and then just declare the kl version as being the new official upstream
(with the blessing of the debian / ubuntu guys, and if possible also
with the blessing of the original authors).
This would require kl git to be open to others for pushing, or we
could move the tree to git.linuxtv.org (which I assume may be
easier then for you to make the necessary changes to give
others push rights on kl.org).
Regards,
Hans
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 18:19 ` Hans de Goede
@ 2011-09-06 18:35 ` Michael Krufky
2011-09-06 18:43 ` Hans de Goede
2011-09-06 18:41 ` Devin Heitmueller
1 sibling, 1 reply; 32+ messages in thread
From: Michael Krufky @ 2011-09-06 18:35 UTC (permalink / raw)
To: Hans de Goede
Cc: Devin Heitmueller, Mauro Carvalho Chehab,
Linux Media Mailing List
On Tue, Sep 6, 2011 at 2:19 PM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 09/06/2011 06:24 PM, Devin Heitmueller wrote:
>
> <snip>
>
>> I've been thinking for a while that perhaps the project should be
>> renamed (or I considered prepending "kl" onto the front resulting in
>> it being called "kl-tvtime"). This isn't out of vanity but rather my
>> concern that the fork will get confused with the original project (for
>> example, I believe Ubuntu actually already calls their modified tree
>> tvtime 1.0.3). I'm open to suggestions in this regards.
>
> I think that what should be done is contact the debian / ubuntu maintainers,
> get any interesting fixes they have which the kl version misses merged,
> and then just declare the kl version as being the new official upstream
> (with the blessing of the debian / ubuntu guys, and if possible also
> with the blessing of the original authors).
>
> This would require kl git to be open to others for pushing, or we
> could move the tree to git.linuxtv.org (which I assume may be
> easier then for you to make the necessary changes to give
> others push rights on kl.org).
Hans,
Everybody is welcome to contribute to open source projects, but global
contribution doesn't mean that a given server be opened up to commits
by the general public. You should feel free to push to your own git
tree hosted on linuxtv.org (or any public git server, for that matter)
and send pull requests to Devin Heitmueller, who is currently
maintaining the kernellabs version of tvtime.
Regards,
Michael Krufky
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 16:24 ` Devin Heitmueller
2011-09-06 18:19 ` Hans de Goede
@ 2011-09-06 18:40 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 18:40 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Linux Media Mailing List
Em 06-09-2011 13:24, Devin Heitmueller escreveu:
> On Tue, Sep 6, 2011 at 11:40 AM, Mauro Carvalho Chehab
> <mchehab@redhat.com> wrote:
>> Hi Devin,
>>
>> Em 06-09-2011 12:29, Mauro Carvalho Chehab escreveu:
>>> There are several issues with the original alsa_stream code that got
>>> fixed on xawtv3, made by me and by Hans de Goede. Basically, the
>>> code were re-written, in order to follow the alsa best practises.
>>>
>>> Backport the changes from xawtv, in order to make it to work on a
>>> wider range of V4L and sound adapters.
>>
>> FYI, just flooded your mailbox with 10 patches for tvtime. ;)
>>
>> I'm wanting to test some things with tvtime on one of my testboxes, but some
>> of my cards weren't working with the alsa streaming, due to a few bugs that
>> were solved on xawtv fork.
>>
>> So, I decided to backport it to tvtime and recompile the Fedora package for it.
>> That's where the other 9 patches come ;)
>>
>> Basically, after applying this series of 10 patches, we can just remove all
>> patches from Fedora, making life easier for distro maintainers (as the same
>> thing is probably true on other distros - at least one of the Fedora patches
>> came from Debian, from the fedora git logs).
>>
>> One important thing for distros is to have a tarball with the latest version
>> hosted on a public site, so I've increased the version to 1.0.3 and I'm
>> thinking on storing a copy of it at linuxtv, just like we do with xawtv3.
>>
>> If you prefer, all patches are also on my tvtime git tree, at:
>> http://git.linuxtv.org/mchehab/tvtime.git
>>
>> Thanks,
>> Mauro
>
> Hi Mauro,
>
> Funny you should send these along today. Last Friday I was actually
> poking around at the Fedora tvtime repo because I was curious how they
> had dealt with the V4L1 support issue (whether they were using my
> patch removing v4l1 or some variant).
Well, right time then ;)
>
> I've actually pulled in Fedora patches in the past (as you can see
> from the hg repo),
Yes, I saw it. Nice work!
> and it has always been my intention to do it for
> the other distros as well (e.g. debian/Ubuntu). So I appreciate your
> having sent these along.
It is a good idea to take a look at them. I looked into their repositories
for the xawtv patches and I found some good stuff there.
> I'll pull these in this week, do some testing to make sure nothing
> serious got broken, and work to spin a 1.0.3 toward the end of the
> week.
Great!
> Given the number of features/changes, and how long it's been
> since the last formal release, I was considering calling it 1.1.0
> instead though.
Seems fine for me.
> I've been thinking for a while that perhaps the project should be
> renamed (or I considered prepending "kl" onto the front resulting in
> it being called "kl-tvtime"). This isn't out of vanity but rather my
> concern that the fork will get confused with the original project (for
> example, I believe Ubuntu actually already calls their modified tree
> tvtime 1.0.3). I'm open to suggestions in this regards.
IMO, I won't rename it. It is a well-known tool, and it is not a new
version, but somebody's else took over its maintainership. I think
you should touch the readme files in order to point to kl.com and to
the places where the tree will be stored.
Em 06-09-2011 15:19, Hans de Goede escreveu:
> Hi,
<snip>
> I think that what should be done is contact the debian / ubuntu maintainers,
> get any interesting fixes they have which the kl version misses merged,
> and then just declare the kl version as being the new official upstream
> (with the blessing of the debian / ubuntu guys, and if possible also
> with the blessing of the original authors).
Agree. I think Devin already tried to contact vektor about that.
> This would require kl git to be open to others for pushing, or we
> could move the tree to git.linuxtv.org (which I assume may be
> easier then for you to make the necessary changes to give
> others push rights on kl.org).
I like this idea too. From my side, it proved to be very useful to be
able to write on both Fedora and upstream repositories on xawtv3.
I've made already the Fedora changes for tvtime 1.0.3 (in order to test
it on my test boxes), so being able of adding a new release at both
repos at the same time is a good idea.
Thanks,
Mauro
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 18:19 ` Hans de Goede
2011-09-06 18:35 ` Michael Krufky
@ 2011-09-06 18:41 ` Devin Heitmueller
2011-09-06 19:12 ` Mauro Carvalho Chehab
1 sibling, 1 reply; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-06 18:41 UTC (permalink / raw)
To: Hans de Goede; +Cc: Mauro Carvalho Chehab, Linux Media Mailing List
On Tue, Sep 6, 2011 at 2:19 PM, Hans de Goede <hdegoede@redhat.com> wrote:
> I think that what should be done is contact the debian / ubuntu maintainers,
> get any interesting fixes they have which the kl version misses merged,
> and then just declare the kl version as being the new official upstream
> (with the blessing of the debian / ubuntu guys, and if possible also
> with the blessing of the original authors).
It has always been my intention to get the Debian/Ubuntu patches
merged (as well as other distros). My thoughts behind renaming were
oriented around the notion that that there are more distros out there
than just Fedora/Ubuntu/Debian, but that may be something that isn't
really a concern. Also, I had no idea whether the distros would
actually switch over to the Kernel Labs version as the official
upstream source, so providing it under a different name would in
theory allow both packages to be available in parallel.
>From a practical standpoint, the Ubuntu folks have the original tvtime
tarball and all their changes in one patch, which is clearly a bunch
of patches that are mashed together probably in their build system. I
need to reach out to them to find where they have an actual SCM tree
or the individual patches. They've got a bunch of patches which would
be good to get into a single tree (autobuild fixes, cross-compilation,
locale updates, etc).
> This would require kl git to be open to others for pushing, or we
> could move the tree to git.linuxtv.org (which I assume may be
> easier then for you to make the necessary changes to give
> others push rights on kl.org).
Kernel Labs has never really had any real interest in "owning" tvtime.
I just setup the hg tree in an effort to get all the distro patches
in one place and have something that builds against current kernels
(and on which I can add improvements/fixes without users having to
deal with patches). At the time there was also nobody who clearly had
the desire to serve as an official maintainer.
In the long term I have no real issue with the LinuxTV group being the
official maintainer of record. I've got lots of ideas and things I
would like to do to improve tvtime, but in practice I've done a pretty
crappy job of maintaining the source (merging patches, etc) at this
point.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 18:35 ` Michael Krufky
@ 2011-09-06 18:43 ` Hans de Goede
2011-09-06 19:11 ` Michael Krufky
0 siblings, 1 reply; 32+ messages in thread
From: Hans de Goede @ 2011-09-06 18:43 UTC (permalink / raw)
To: Michael Krufky
Cc: Devin Heitmueller, Mauro Carvalho Chehab,
Linux Media Mailing List
Hi,
On 09/06/2011 08:35 PM, Michael Krufky wrote:
> On Tue, Sep 6, 2011 at 2:19 PM, Hans de Goede<hdegoede@redhat.com> wrote:
>> Hi,
>>
>> On 09/06/2011 06:24 PM, Devin Heitmueller wrote:
>>
>> <snip>
>>
>>> I've been thinking for a while that perhaps the project should be
>>> renamed (or I considered prepending "kl" onto the front resulting in
>>> it being called "kl-tvtime"). This isn't out of vanity but rather my
>>> concern that the fork will get confused with the original project (for
>>> example, I believe Ubuntu actually already calls their modified tree
>>> tvtime 1.0.3). I'm open to suggestions in this regards.
>>
>> I think that what should be done is contact the debian / ubuntu maintainers,
>> get any interesting fixes they have which the kl version misses merged,
>> and then just declare the kl version as being the new official upstream
>> (with the blessing of the debian / ubuntu guys, and if possible also
>> with the blessing of the original authors).
>>
>> This would require kl git to be open to others for pushing, or we
>> could move the tree to git.linuxtv.org (which I assume may be
>> easier then for you to make the necessary changes to give
>> others push rights on kl.org).
>
> Hans,
>
> Everybody is welcome to contribute to open source projects, but global
> contribution doesn't mean that a given server be opened up to commits
> by the general public.
I didn't write open to commits by the general public, now did I? I wrote
open to commits by others. For most upstream projects it is quite normal
that several people have push rights to the master tree. This actually
is quite a good idea, as it avoids adding a SPOF into the chain. It
means development can continue if one of the maintainers is on vacation
for a a few weeks, or just having a period in his/her life where he
is too busy to actively contribute to a spare time project.
Regards,
Hans
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 18:43 ` Hans de Goede
@ 2011-09-06 19:11 ` Michael Krufky
0 siblings, 0 replies; 32+ messages in thread
From: Michael Krufky @ 2011-09-06 19:11 UTC (permalink / raw)
To: Hans de Goede
Cc: Devin Heitmueller, Mauro Carvalho Chehab,
Linux Media Mailing List
On Tue, Sep 6, 2011 at 2:43 PM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 09/06/2011 08:35 PM, Michael Krufky wrote:
>>
>> On Tue, Sep 6, 2011 at 2:19 PM, Hans de Goede<hdegoede@redhat.com> wrote:
>>>
>>> Hi,
>>>
>>> On 09/06/2011 06:24 PM, Devin Heitmueller wrote:
>>>
>>> <snip>
>>>
>>>> I've been thinking for a while that perhaps the project should be
>>>> renamed (or I considered prepending "kl" onto the front resulting in
>>>> it being called "kl-tvtime"). This isn't out of vanity but rather my
>>>> concern that the fork will get confused with the original project (for
>>>> example, I believe Ubuntu actually already calls their modified tree
>>>> tvtime 1.0.3). I'm open to suggestions in this regards.
>>>
>>> I think that what should be done is contact the debian / ubuntu
>>> maintainers,
>>> get any interesting fixes they have which the kl version misses merged,
>>> and then just declare the kl version as being the new official upstream
>>> (with the blessing of the debian / ubuntu guys, and if possible also
>>> with the blessing of the original authors).
>>>
>>> This would require kl git to be open to others for pushing, or we
>>> could move the tree to git.linuxtv.org (which I assume may be
>>> easier then for you to make the necessary changes to give
>>> others push rights on kl.org).
>>
>> Hans,
>>
>> Everybody is welcome to contribute to open source projects, but global
>> contribution doesn't mean that a given server be opened up to commits
>> by the general public.
>
> I didn't write open to commits by the general public, now did I? I wrote
> open to commits by others. For most upstream projects it is quite normal
> that several people have push rights to the master tree. This actually
> is quite a good idea, as it avoids adding a SPOF into the chain. It
> means development can continue if one of the maintainers is on vacation
> for a a few weeks, or just having a period in his/her life where he
> is too busy to actively contribute to a spare time project.
Hans,
Now I understand -- that's completely reasonable. It looks like Devin
is happy having the tree hosted on linuxtv.org anyway, so no worries
:-) Sorry for the misunderstanding.
Best Regards,
Mike Krufky
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 18:41 ` Devin Heitmueller
@ 2011-09-06 19:12 ` Mauro Carvalho Chehab
2011-09-06 21:18 ` Devin Heitmueller
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 19:12 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Hans de Goede, Linux Media Mailing List
Em 06-09-2011 15:41, Devin Heitmueller escreveu:
> On Tue, Sep 6, 2011 at 2:19 PM, Hans de Goede <hdegoede@redhat.com> wrote:
>> I think that what should be done is contact the debian / ubuntu maintainers,
>> get any interesting fixes they have which the kl version misses merged,
>> and then just declare the kl version as being the new official upstream
>> (with the blessing of the debian / ubuntu guys, and if possible also
>> with the blessing of the original authors).
>
> It has always been my intention to get the Debian/Ubuntu patches
> merged (as well as other distros). My thoughts behind renaming were
> oriented around the notion that that there are more distros out there
> than just Fedora/Ubuntu/Debian, but that may be something that isn't
> really a concern. Also, I had no idea whether the distros would
> actually switch over to the Kernel Labs version as the official
> upstream source, so providing it under a different name would in
> theory allow both packages to be available in parallel.
>
> From a practical standpoint, the Ubuntu folks have the original tvtime
> tarball and all their changes in one patch, which is clearly a bunch
> of patches that are mashed together probably in their build system. I
> need to reach out to them to find where they have an actual SCM tree
> or the individual patches. They've got a bunch of patches which would
> be good to get into a single tree (autobuild fixes, cross-compilation,
> locale updates, etc).
Yeah, it seems interesting. Maybe we can get something from this place:
http://packages.qa.debian.org/t/tvtime.html
The maintainer there seems to be:
http://qa.debian.org/developer.php?login=bartm@debian.org
>> This would require kl git to be open to others for pushing, or we
>> could move the tree to git.linuxtv.org (which I assume may be
>> easier then for you to make the necessary changes to give
>> others push rights on kl.org).
>
> Kernel Labs has never really had any real interest in "owning" tvtime.
> I just setup the hg tree in an effort to get all the distro patches
> in one place and have something that builds against current kernels
> (and on which I can add improvements/fixes without users having to
> deal with patches). At the time there was also nobody who clearly had
> the desire to serve as an official maintainer.
>
> In the long term I have no real issue with the LinuxTV group being the
> official maintainer of record. I've got lots of ideas and things I
> would like to do to improve tvtime, but in practice I've done a pretty
> crappy job of maintaining the source (merging patches, etc) at this
> point.
Putting it on a common place and giving permissions to a group of people
is interesting, as none of us are focused on userspace, so we all
have a very limited amount of time for dealing with userspace applications.
By giving commit rights to a group of developers, it ends that more
developers will contribute, speeding up the development.
That was what happened with v4l-utils and, on a minor scale, with xawtv3.
If you're ok with that, I can set a tvtime git repository at LinuxTV,
cloning the tree I've created there already (it is a pure conversion
of your tree from mercurial into git, if I remove the patches I've
done so far from your clone), giving you the ownership of the new tree,
and marking it as a shared repository.
I have already all set there to allow shared access to the repository
(in opposite to -hg, git works really cool with shared repositories).
We can later add permissions to the developers interested on helping
the tvtime maintenance that you agree to add.
Regards,
Mauro
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 19:12 ` Mauro Carvalho Chehab
@ 2011-09-06 21:18 ` Devin Heitmueller
2011-09-06 21:50 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-06 21:18 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: Hans de Goede, Linux Media Mailing List
On Tue, Sep 6, 2011 at 3:12 PM, Mauro Carvalho Chehab
<mchehab@redhat.com> wrote:
>> From a practical standpoint, the Ubuntu folks have the original tvtime
>> tarball and all their changes in one patch, which is clearly a bunch
>> of patches that are mashed together probably in their build system. I
>> need to reach out to them to find where they have an actual SCM tree
>> or the individual patches. They've got a bunch of patches which would
>> be good to get into a single tree (autobuild fixes, cross-compilation,
>> locale updates, etc).
>
> Yeah, it seems interesting. Maybe we can get something from this place:
> http://packages.qa.debian.org/t/tvtime.html
>
> The maintainer there seems to be:
> http://qa.debian.org/developer.php?login=bartm@debian.org
I reached out to the Ubuntu maintainer; we'll see if he gets back to
me. From what I can tell it seems like Debian is actually taking the
patches from Ubuntu (yes, I realize this is backwards from their
typical process where Ubuntu bases their stuff on Debian).
>> In the long term I have no real issue with the LinuxTV group being the
>> official maintainer of record. I've got lots of ideas and things I
>> would like to do to improve tvtime, but in practice I've done a pretty
>> crappy job of maintaining the source (merging patches, etc) at this
>> point.
>
> Putting it on a common place and giving permissions to a group of people
> is interesting, as none of us are focused on userspace, so we all
> have a very limited amount of time for dealing with userspace applications.
>
> By giving commit rights to a group of developers, it ends that more
> developers will contribute, speeding up the development.
>
> That was what happened with v4l-utils and, on a minor scale, with xawtv3.
>
> If you're ok with that, I can set a tvtime git repository at LinuxTV,
> cloning the tree I've created there already (it is a pure conversion
> of your tree from mercurial into git, if I remove the patches I've
> done so far from your clone), giving you the ownership of the new tree,
> and marking it as a shared repository.
I have no problem with this. Let's set it up.
> I have already all set there to allow shared access to the repository
> (in opposite to -hg, git works really cool with shared repositories).
I actually haven't hosted any git repos on linuxtv.org before. I'm
assuming my ssh public key got copied over from when I was hosting hg
repos there?
> We can later add permissions to the developers interested on helping
> the tvtime maintenance that you agree to add.
Sounds good.
As said earlier, Kernel Labs never really wanted to be the maintainer
for tvtime - we did it because nobody else wanted to (and vektor never
responded to emails I sent him offering to help). That said, a
community oriented approach is probably the best for everybody
involved.
I'll probably be looking in the next couple of weeks to write some
fresh content for a tvtime website. The stuff on
tvtime.sourceforge.net is so dated almost none of it still applies.
Thanks,
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 21:18 ` Devin Heitmueller
@ 2011-09-06 21:50 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-06 21:50 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Hans de Goede, Linux Media Mailing List
Em 06-09-2011 18:18, Devin Heitmueller escreveu:
> On Tue, Sep 6, 2011 at 3:12 PM, Mauro Carvalho Chehab
> <mchehab@redhat.com> wrote:
>>> From a practical standpoint, the Ubuntu folks have the original tvtime
>>> tarball and all their changes in one patch, which is clearly a bunch
>>> of patches that are mashed together probably in their build system. I
>>> need to reach out to them to find where they have an actual SCM tree
>>> or the individual patches. They've got a bunch of patches which would
>>> be good to get into a single tree (autobuild fixes, cross-compilation,
>>> locale updates, etc).
>>
>> Yeah, it seems interesting. Maybe we can get something from this place:
>> http://packages.qa.debian.org/t/tvtime.html
>>
>> The maintainer there seems to be:
>> http://qa.debian.org/developer.php?login=bartm@debian.org
>
> I reached out to the Ubuntu maintainer; we'll see if he gets back to
> me. From what I can tell it seems like Debian is actually taking the
> patches from Ubuntu (yes, I realize this is backwards from their
> typical process where Ubuntu bases their stuff on Debian).
Good!
>>> In the long term I have no real issue with the LinuxTV group being the
>>> official maintainer of record. I've got lots of ideas and things I
>>> would like to do to improve tvtime, but in practice I've done a pretty
>>> crappy job of maintaining the source (merging patches, etc) at this
>>> point.
>>
>> Putting it on a common place and giving permissions to a group of people
>> is interesting, as none of us are focused on userspace, so we all
>> have a very limited amount of time for dealing with userspace applications.
>>
>> By giving commit rights to a group of developers, it ends that more
>> developers will contribute, speeding up the development.
>>
>> That was what happened with v4l-utils and, on a minor scale, with xawtv3.
>>
>> If you're ok with that, I can set a tvtime git repository at LinuxTV,
>> cloning the tree I've created there already (it is a pure conversion
>> of your tree from mercurial into git, if I remove the patches I've
>> done so far from your clone), giving you the ownership of the new tree,
>> and marking it as a shared repository.
>
> I have no problem with this. Let's set it up.
Ok. The repository is here:
http://git.linuxtv.org/tvtime.git
In thesis, everything is set for group usage. Please let me know if
you experience any troubles with it.
>> I have already all set there to allow shared access to the repository
>> (in opposite to -hg, git works really cool with shared repositories).
>
> I actually haven't hosted any git repos on linuxtv.org before. I'm
> assuming my ssh public key got copied over from when I was hosting hg
> repos there?
The same key is used, whatever you're committing to cvs, hg or git. The
maintenance application for git is called git-menu.
>> We can later add permissions to the developers interested on helping
>> the tvtime maintenance that you agree to add.
>
> Sounds good.
>From my side, I'm interested on helping with it.
When I have some time, I'd like to fix a few issues with it.
For example, there's a local cable operator that broadcasts some channels
with PAL/M and others with NTSC/M (not a big deal for STBs and TV sets, as
almost all support both standards here).
However, tvtime, needs to be restarted every time it changes from one to
the other, and it is not possible to set a per-channel standard. To be
worse, when tvtime is restarted, it doesn't honor the "-d" option, with
means that it will open my laptop's webcam instead of the TV card.
>
> As said earlier, Kernel Labs never really wanted to be the maintainer
> for tvtime - we did it because nobody else wanted to (and vektor never
> responded to emails I sent him offering to help). That said, a
> community oriented approach is probably the best for everybody
> involved.
>
> I'll probably be looking in the next couple of weeks to write some
> fresh content for a tvtime website. The stuff on
> tvtime.sourceforge.net is so dated almost none of it still applies.
Yeah, that makes sense.
> Thanks,
>
> Devin
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-06 15:29 [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 02/10] Fix make dist target Mauro Carvalho Chehab
2011-09-06 15:40 ` [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
@ 2011-09-07 2:58 ` Devin Heitmueller
2011-09-07 3:20 ` Devin Heitmueller
2011-09-07 3:23 ` Mauro Carvalho Chehab
2 siblings, 2 replies; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-07 2:58 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media
On Tue, Sep 6, 2011 at 11:29 AM, Mauro Carvalho Chehab
<mchehab@redhat.com> wrote:
> There are several issues with the original alsa_stream code that got
> fixed on xawtv3, made by me and by Hans de Goede. Basically, the
> code were re-written, in order to follow the alsa best practises.
>
> Backport the changes from xawtv, in order to make it to work on a
> wider range of V4L and sound adapters.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Mauro,
What tuners did you test this patch with? I went ahead and did a git
pull of your patch series into my local git tree, and now my DVC-90
(an em28xx device) is capturing at 32 KHz instead of 48 (this is one
of the snd-usb-audio based devices, not em28xx-alsa).
Note I tested immediately before pulling your patch series and the
audio capture was working fine.
I think this patch series is going in the right direction in general,
but this patch in particular seems to cause a regression. Is this
something you want to investigate? I think we need to hold off on
pulling this series into the new tvtime master until this problem is
resolved.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 2:58 ` Devin Heitmueller
@ 2011-09-07 3:20 ` Devin Heitmueller
2011-09-07 3:29 ` Mauro Carvalho Chehab
2011-09-07 3:23 ` Mauro Carvalho Chehab
1 sibling, 1 reply; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-07 3:20 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media
On Tue, Sep 6, 2011 at 10:58 PM, Devin Heitmueller
<dheitmueller@kernellabs.com> wrote:
> On Tue, Sep 6, 2011 at 11:29 AM, Mauro Carvalho Chehab
> <mchehab@redhat.com> wrote:
>> There are several issues with the original alsa_stream code that got
>> fixed on xawtv3, made by me and by Hans de Goede. Basically, the
>> code were re-written, in order to follow the alsa best practises.
>>
>> Backport the changes from xawtv, in order to make it to work on a
>> wider range of V4L and sound adapters.
>>
>> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
>
> Mauro,
>
> What tuners did you test this patch with? I went ahead and did a git
> pull of your patch series into my local git tree, and now my DVC-90
> (an em28xx device) is capturing at 32 KHz instead of 48 (this is one
> of the snd-usb-audio based devices, not em28xx-alsa).
>
> Note I tested immediately before pulling your patch series and the
> audio capture was working fine.
>
> I think this patch series is going in the right direction in general,
> but this patch in particular seems to cause a regression. Is this
> something you want to investigate? I think we need to hold off on
> pulling this series into the new tvtime master until this problem is
> resolved.
>
> Devin
>
> --
> Devin J. Heitmueller - Kernel Labs
> http://www.kernellabs.com
>
Spent a few minutes digging into this. Looks like the snd-usb-audio
driver advertises 8-48KHz. However, it seems that it only captures
successfully at 48 KHz.
I made the following hack and it started working:
diff --git a/src/alsa_stream.c b/src/alsa_stream.c
index b6a41a5..57e3c3d 100644
--- a/src/alsa_stream.c
+++ b/src/alsa_stream.c
@@ -261,7 +261,7 @@ static int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle,
fprintf(error_fp, "alsa: Will search a common rate between %u and %u\n",
ratemin, ratemax);
- for (i = ratemin; i <= ratemax; i+= 100) {
+ for (i = ratemax; i >= ratemin; i-= 100) {
err = snd_pcm_hw_params_set_rate_near(chandle, c_hwparams, &i, 0);
if (err)
continue;
Basically the above starts at the *maximum* capture resolution and
works its way down. One might argue that this heuristic makes more
sense anyway - why *wouldn't* you want the highest quality audio
possible by default (rather than the lowest)?
Even with that patch though, I hit severe underrun/overrun conditions
at 30ms of latency (to the point where the audio is interrupted dozens
of times per second). Turned it up to 50ms and it's much better.
That said, of course such a change would impact lipsync, so perhaps we
need to be adjusting the periods instead.
ALSA has never been my area of expertise, so I look to you and Hans to
offer some suggestions.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 2:58 ` Devin Heitmueller
2011-09-07 3:20 ` Devin Heitmueller
@ 2011-09-07 3:23 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-07 3:23 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media
Em 06-09-2011 23:58, Devin Heitmueller escreveu:
> On Tue, Sep 6, 2011 at 11:29 AM, Mauro Carvalho Chehab
> <mchehab@redhat.com> wrote:
>> There are several issues with the original alsa_stream code that
>> got fixed on xawtv3, made by me and by Hans de Goede. Basically,
>> the code were re-written, in order to follow the alsa best
>> practises.
>>
>> Backport the changes from xawtv, in order to make it to work on a
>> wider range of V4L and sound adapters.
>>
>> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
>
> Mauro,
>
> What tuners did you test this patch with?
I tested with some em28xx-based devices, like HVR-950 and WinTV USB2.
> I went ahead and did a git pull of your patch series into my local
> git tree, and now my DVC-90 (an em28xx device) is capturing at 32 KHz
> instead of 48 (this is one of the snd-usb-audio based devices, not
> em28xx-alsa).
The new approach tries to match an speed that it is compatible between
the audio and the video card. The algorithm tries first to not use
software interpolation for audio, as it would reduce the audio quality.
If it can't do it without interpolation, it will enable interpolation
and seek again. By default, pulseaudio does interpolation, if you request
it to use a different resolution.
> Note I tested immediately before pulling your patch series and the
> audio capture was working fine.
Had you test to disable pulseaudio and see what speeds your boards
accept? If you enable verbose mode, you'll see more details about
the device detection.
For example, this is what I get here with hvr-950, calling "tvtime -v":
alsa: starting copying alsa stream from hw:1,0 to hw:0,0
videoinput: Using video4linux2 driver 'em28xx', card 'Hauppauge WinTV HVR 950' (bus usb-0000:00:1d.7-1).
videoinput: Version is 196608, capabilities 5030051.
alsa: Capture min rate is 48000
alsa: Capture max rate is 48000
alsa: Playback min rate is 44100
alsa: Playback max rate is 192000
alsa: Will search a common rate between 48000 and 48000
alsa: Using Rate 48000
alsa: capture periods range between 2 and 98. Want: 2
alsa: capture period time range between 333 and 65334. Want: 15000
alsa: playback periods range between 2 and 32. Want: 4
alsa: playback period time range between 666 and 10922667. Want: 15000
alsa: capture period set to 2 periods of 15000 time
alsa: playback period set to 4 periods of 15333 time
alsa: Negociated configuration:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits : 16
buffer_size : 2944
period_size : 736
period_time : 15333
tstamp_mode : NONE
period_step : 1
avail_min : 736
period_event : 0
start_threshold : 1440
stop_threshold : 2944
silence_threshold: 0
silence_size : 0
boundary : 1543503872
stream : CAPTURE
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits : 16
buffer_size : 1440
period_size : 720
period_time : 15000
tstamp_mode : NONE
period_step : 1
avail_min : 720
period_event : 0
start_threshold : 720
stop_threshold : 1440
silence_threshold: 0
silence_size : 0
boundary : 1509949440
alsa: Parameters are 48000Hz, S16_LE, 2 channels
alsa: Set bitrate to 48000, buffer size is 1440
alsa: stream started from hw:1,0 to hw:0,0 (48000 Hz, buffer delay = 30,00 ms)
And those are the results with WinTV USB2:
videoinput: Using video4linux2 driver 'em28xx', card 'Hauppauge WinTV USB 2' (bus usb-0000:00:1d.7-1).
videoinput: Version is 196608, capabilities 5030041.
alsa: starting copying alsa stream from hw:1,0 to hw:0,0
alsa: Capture min rate is 32000
alsa: Capture max rate is 32000
alsa: Playback min rate is 44100
alsa: Playback max rate is 192000
alsa: Will search a common rate between 44100 and 32000
alsa: Couldn't find a rate that it is supported by both playback and capture
alsa: Trying plughw:0,0 for playback
alsa: Resample enabled.
alsa: Capture min rate is 32000
alsa: Capture max rate is 32000
alsa: Playback min rate is 4000
alsa: Playback max rate is 4294967295
alsa: Will search a common rate between 32000 and 32000
alsa: Using Rate 32000
alsa: capture periods range between 2 and 1024. Want: 2
alsa: capture period time range between 500 and 4096000. Want: 15000
alsa: playback period time range between 333 and 5461334. Want: 15000
alsa: capture period set to 2 periods of 15000 time
alsa: playback period set to 4 periods of 15000 time
alsa: Negociated configuration:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 32000
exact rate : 32000 (32000/1)
msbits : 16
buffer_size : 1920
period_size : 480
period_time : 15000
tstamp_mode : NONE
period_step : 1
avail_min : 480
period_event : 0
start_threshold : 960
stop_threshold : 1920
silence_threshold: 0
silence_size : 0
boundary : 503316480
stream : CAPTURE
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 32000
exact rate : 32000 (32000/1)
msbits : 16
buffer_size : 960
period_size : 480
period_time : 15000
tstamp_mode : NONE
period_step : 1
avail_min : 480
period_event : 0
start_threshold : 480
stop_threshold : 960
silence_threshold: 0
silence_size : 0
boundary : 2013265920
alsa: Parameters are 32000Hz, S16_LE, 2 channels
alsa: Set bitrate to 32000 with resample enabled at playback, buffer size is 960
alsa: stream started from hw:1,0 to plughw:0,0 (32000 Hz, buffer delay = 30,00 ms)
You should notice that snd-usb-audio only reports 32 kHz speed for this
device.
> I think this patch series is going in the right direction in
> general, but this patch in particular seems to cause a regression.
> Is this something you want to investigate? I think we need to hold
> off on pulling this series into the new tvtime master until this
> problem is resolved.
>
> Devin
>
/
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 3:20 ` Devin Heitmueller
@ 2011-09-07 3:29 ` Mauro Carvalho Chehab
2011-09-07 3:37 ` Devin Heitmueller
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-07 3:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media
Em 07-09-2011 00:20, Devin Heitmueller escreveu:
> On Tue, Sep 6, 2011 at 10:58 PM, Devin Heitmueller
> <dheitmueller@kernellabs.com> wrote:
>> On Tue, Sep 6, 2011 at 11:29 AM, Mauro Carvalho Chehab
>> <mchehab@redhat.com> wrote:
>>> There are several issues with the original alsa_stream code that got
>>> fixed on xawtv3, made by me and by Hans de Goede. Basically, the
>>> code were re-written, in order to follow the alsa best practises.
>>>
>>> Backport the changes from xawtv, in order to make it to work on a
>>> wider range of V4L and sound adapters.
>>>
>>> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
>>
>> Mauro,
>>
>> What tuners did you test this patch with? I went ahead and did a git
>> pull of your patch series into my local git tree, and now my DVC-90
>> (an em28xx device) is capturing at 32 KHz instead of 48 (this is one
>> of the snd-usb-audio based devices, not em28xx-alsa).
>>
>> Note I tested immediately before pulling your patch series and the
>> audio capture was working fine.
>>
>> I think this patch series is going in the right direction in general,
>> but this patch in particular seems to cause a regression. Is this
>> something you want to investigate? I think we need to hold off on
>> pulling this series into the new tvtime master until this problem is
>> resolved.
>>
>> Devin
>>
>> --
>> Devin J. Heitmueller - Kernel Labs
>> http://www.kernellabs.com
>>
>
> Spent a few minutes digging into this. Looks like the snd-usb-audio
> driver advertises 8-48KHz. However, it seems that it only captures
> successfully at 48 KHz.
>
> I made the following hack and it started working:
>
> diff --git a/src/alsa_stream.c b/src/alsa_stream.c
> index b6a41a5..57e3c3d 100644
> --- a/src/alsa_stream.c
> +++ b/src/alsa_stream.c
> @@ -261,7 +261,7 @@ static int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle,
> fprintf(error_fp, "alsa: Will search a common rate between %u and %u\n",
> ratemin, ratemax);
>
> - for (i = ratemin; i <= ratemax; i+= 100) {
> + for (i = ratemax; i >= ratemin; i-= 100) {
> err = snd_pcm_hw_params_set_rate_near(chandle, c_hwparams, &i, 0);
> if (err)
> continue;
>
> Basically the above starts at the *maximum* capture resolution and
> works its way down. One might argue that this heuristic makes more
> sense anyway - why *wouldn't* you want the highest quality audio
> possible by default (rather than the lowest)?
That change makes sense to me. Yet, you should try to disable pulseaudio
and see what's the _real_ speed that the audio announces. On Fedora,
just removing pulsaudio-oss-plugin (or something like that) is enough.
It seems doubtful that my em2820 WinTV USB2 is different than yours.
I suspect that pulseaudio is passing the "extra" range, offering to
interpolate the data.
> Even with that patch though, I hit severe underrun/overrun conditions
> at 30ms of latency (to the point where the audio is interrupted dozens
> of times per second).
Yes, it is the same here: 30ms on my notebook is not enough for WinTV
USB2 (it is OK with HVR-950).
> Turned it up to 50ms and it's much better.
> That said, of course such a change would impact lipsync, so perhaps we
> need to be adjusting the periods instead.
We've added a parameter for that on xawtv3 (--alsa-latency). We've parametrized
it at the alsa stream function call. So, all it needs is to add a new parameter
at tvtime config file.
> ALSA has never been my area of expertise, so I look to you and Hans to
> offer some suggestions.
>
> Devin
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 3:29 ` Mauro Carvalho Chehab
@ 2011-09-07 3:37 ` Devin Heitmueller
2011-09-07 3:42 ` Devin Heitmueller
` (2 more replies)
0 siblings, 3 replies; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-07 3:37 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media
On Tue, Sep 6, 2011 at 11:29 PM, Mauro Carvalho Chehab
<mchehab@redhat.com> wrote:
>> Basically the above starts at the *maximum* capture resolution and
>> works its way down. One might argue that this heuristic makes more
>> sense anyway - why *wouldn't* you want the highest quality audio
>> possible by default (rather than the lowest)?
>
> That change makes sense to me. Yet, you should try to disable pulseaudio
> and see what's the _real_ speed that the audio announces. On Fedora,
> just removing pulsaudio-oss-plugin (or something like that) is enough.
>
> It seems doubtful that my em2820 WinTV USB2 is different than yours.
> I suspect that pulseaudio is passing the "extra" range, offering to
> interpolate the data.
I disabled pulseaudio and the capture device is advertising the exact
same range (8-48 KHz). Seems to be behaving the same way as well.
So while I'm usually willing to blame things on Pulse, this doesn't
look like the case here.
>> Even with that patch though, I hit severe underrun/overrun conditions
>> at 30ms of latency (to the point where the audio is interrupted dozens
>> of times per second).
>
> Yes, it is the same here: 30ms on my notebook is not enough for WinTV
> USB2 (it is OK with HVR-950).
>
>> Turned it up to 50ms and it's much better.
>> That said, of course such a change would impact lipsync, so perhaps we
>> need to be adjusting the periods instead.
>
> We've added a parameter for that on xawtv3 (--alsa-latency). We've parametrized
> it at the alsa stream function call. So, all it needs is to add a new parameter
> at tvtime config file.
Ugh. We really need some sort of heuristic to do this. It's
unreasonable to expect users to know about some magic parameter buried
in a config file which causes it to start working. Perhaps a counter
that increments whenever an underrun is hit, and after a certain
number it automatically restarts the stream with a higher latency. Or
perhaps we're just making some poor choice in terms of the
buffers/periods for a given rate.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 3:37 ` Devin Heitmueller
@ 2011-09-07 3:42 ` Devin Heitmueller
2011-09-07 4:06 ` Devin Heitmueller
2011-09-07 6:29 ` [PATCH 01/10] alsa_stream: port changes made on xawtv3 Hans de Goede
2011-09-07 12:49 ` Mauro Carvalho Chehab
2 siblings, 1 reply; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-07 3:42 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media
On Tue, Sep 6, 2011 at 11:37 PM, Devin Heitmueller
<dheitmueller@kernellabs.com> wrote:
> On Tue, Sep 6, 2011 at 11:29 PM, Mauro Carvalho Chehab
> <mchehab@redhat.com> wrote:
>>> Basically the above starts at the *maximum* capture resolution and
>>> works its way down. One might argue that this heuristic makes more
>>> sense anyway - why *wouldn't* you want the highest quality audio
>>> possible by default (rather than the lowest)?
>>
>> That change makes sense to me. Yet, you should try to disable pulseaudio
>> and see what's the _real_ speed that the audio announces. On Fedora,
>> just removing pulsaudio-oss-plugin (or something like that) is enough.
>>
>> It seems doubtful that my em2820 WinTV USB2 is different than yours.
>> I suspect that pulseaudio is passing the "extra" range, offering to
>> interpolate the data.
>
> I disabled pulseaudio and the capture device is advertising the exact
> same range (8-48 KHz). Seems to be behaving the same way as well.
>
> So while I'm usually willing to blame things on Pulse, this doesn't
> look like the case here.
>
>>> Even with that patch though, I hit severe underrun/overrun conditions
>>> at 30ms of latency (to the point where the audio is interrupted dozens
>>> of times per second).
>>
>> Yes, it is the same here: 30ms on my notebook is not enough for WinTV
>> USB2 (it is OK with HVR-950).
>>
>>> Turned it up to 50ms and it's much better.
>>> That said, of course such a change would impact lipsync, so perhaps we
>>> need to be adjusting the periods instead.
>>
>> We've added a parameter for that on xawtv3 (--alsa-latency). We've parametrized
>> it at the alsa stream function call. So, all it needs is to add a new parameter
>> at tvtime config file.
>
> Ugh. We really need some sort of heuristic to do this. It's
> unreasonable to expect users to know about some magic parameter buried
> in a config file which causes it to start working. Perhaps a counter
> that increments whenever an underrun is hit, and after a certain
> number it automatically restarts the stream with a higher latency. Or
> perhaps we're just making some poor choice in terms of the
> buffers/periods for a given rate.
>
> Devin
>
> --
> Devin J. Heitmueller - Kernel Labs
> http://www.kernellabs.com
>
One more thing worth noting before I quit for the night:
What audio processor is on your WinTV USB 2 device? The DVC-90 has an
emp202. Perhaps the WInTV uses a different audio processor (while
still using an em2820 as the bridge)? That might explain why your
device advertises effectively only one capture rate (32), while mine
advertises a whole range (8-48).
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 3:42 ` Devin Heitmueller
@ 2011-09-07 4:06 ` Devin Heitmueller
2011-10-07 1:59 ` tvtime at linuxtv.org Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Devin Heitmueller @ 2011-09-07 4:06 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media
On Tue, Sep 6, 2011 at 11:42 PM, Devin Heitmueller
<dheitmueller@kernellabs.com> wrote:
> One more thing worth noting before I quit for the night:
>
> What audio processor is on your WinTV USB 2 device? The DVC-90 has an
> emp202. Perhaps the WInTV uses a different audio processor (while
> still using an em2820 as the bridge)? That might explain why your
> device advertises effectively only one capture rate (32), while mine
> advertises a whole range (8-48).
Just took a look at the driver code. Seems we are calling
em28xx_analog_audio_set() even if it's not using vendor audio. And
that function actually hard-codes the rate to 48KHz.
So here's the question: if using snd-usb-audio, should we really be
poking at the AC97 registers at all? It seems that doing such can
just get the audio processor state out of sync with however
snd-usb-audio set it up. For example, the snd-usb-audio driver may
very well be configuring the audio to 32 KHz, and then we reset the
chip's state to 48Khz when we start streaming without the
snd-usb-audio driver's knowledge.
It seems like we should only be setting up the AC97 registers if it's
an AC97 audio processor *and* it's using vendor audio.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 3:37 ` Devin Heitmueller
2011-09-07 3:42 ` Devin Heitmueller
@ 2011-09-07 6:29 ` Hans de Goede
2011-09-07 12:49 ` Mauro Carvalho Chehab
2 siblings, 0 replies; 32+ messages in thread
From: Hans de Goede @ 2011-09-07 6:29 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Mauro Carvalho Chehab, linux-media
Hi,
Lots of good stuff in this thread! It seems Mauro has answered most
things, so I'm just going to respond to this bit.
On 09/07/2011 05:37 AM, Devin Heitmueller wrote:
<Snip>
>> We've added a parameter for that on xawtv3 (--alsa-latency). We've parametrized
>> it at the alsa stream function call. So, all it needs is to add a new parameter
>> at tvtime config file.
>
> Ugh. We really need some sort of heuristic to do this. It's
> unreasonable to expect users to know about some magic parameter buried
> in a config file which causes it to start working. Perhaps a counter
> that increments whenever an underrun is hit, and after a certain
> number it automatically restarts the stream with a higher latency. Or
> perhaps we're just making some poor choice in terms of the
> buffers/periods for a given rate.
This may have something to do with usb versus pci capture, on my bttv card
30 ms works fine, but I can imagine it being a bit on the low side when
doing video + audio capture over USB. So maybe should default to say
50 for usb capture devices and 30 for pci capture devices?
In the end if people load there system enough / have a slow enough
system our default will always be wrong for them. All we can do is try to
get a default which is sane for most setups ...
Regards,
Hans
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 01/10] alsa_stream: port changes made on xawtv3
2011-09-07 3:37 ` Devin Heitmueller
2011-09-07 3:42 ` Devin Heitmueller
2011-09-07 6:29 ` [PATCH 01/10] alsa_stream: port changes made on xawtv3 Hans de Goede
@ 2011-09-07 12:49 ` Mauro Carvalho Chehab
2 siblings, 0 replies; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-07 12:49 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media
Em 07-09-2011 00:37, Devin Heitmueller escreveu:
> On Tue, Sep 6, 2011 at 11:29 PM, Mauro Carvalho Chehab
> <mchehab@redhat.com> wrote:
>>> Basically the above starts at the *maximum* capture resolution and
>>> works its way down. One might argue that this heuristic makes more
>>> sense anyway - why *wouldn't* you want the highest quality audio
>>> possible by default (rather than the lowest)?
>>
>> That change makes sense to me. Yet, you should try to disable pulseaudio
>> and see what's the _real_ speed that the audio announces. On Fedora,
>> just removing pulsaudio-oss-plugin (or something like that) is enough.
>>
>> It seems doubtful that my em2820 WinTV USB2 is different than yours.
>> I suspect that pulseaudio is passing the "extra" range, offering to
>> interpolate the data.
>
> I disabled pulseaudio and the capture device is advertising the exact
> same range (8-48 KHz). Seems to be behaving the same way as well.
Hmm... just checked with WinTV USB2:
[ 3.819236] msp3400 15-0044: MSP3445G-B8 found @ 0x88 (em28xx #0)
While this device uses snd-usb-audio, it is a non-AC97 adapter. So,
we may expect it to be different from yours.
Its A/D works at a fixed rate of 32 kHZ, according with MSP34x5G datasheet,
so snd-usb-audio is working properly here.
> So while I'm usually willing to blame things on Pulse, this doesn't
> look like the case here.
That's good. One less problem to deal with.
>>> Even with that patch though, I hit severe underrun/overrun conditions
>>> at 30ms of latency (to the point where the audio is interrupted dozens
>>> of times per second).
>>
>> Yes, it is the same here: 30ms on my notebook is not enough for WinTV
>> USB2 (it is OK with HVR-950).
>>
>>> Turned it up to 50ms and it's much better.
>>> That said, of course such a change would impact lipsync, so perhaps we
>>> need to be adjusting the periods instead.
>>
>> We've added a parameter for that on xawtv3 (--alsa-latency). We've parametrized
>> it at the alsa stream function call. So, all it needs is to add a new parameter
>> at tvtime config file.
>
> Ugh. We really need some sort of heuristic to do this. It's
> unreasonable to expect users to know about some magic parameter buried
> in a config file which causes it to start working.
Agreed, but still it makes sense to allow users to adjust, as extra delays
might be needed on really slow machines.
> Perhaps a counter
> that increments whenever an underrun is hit, and after a certain
> number it automatically restarts the stream with a higher latency. Or
> perhaps we're just making some poor choice in terms of the
> buffers/periods for a given rate.
>
> Devin
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* tvtime at linuxtv.org
2011-09-07 4:06 ` Devin Heitmueller
@ 2011-10-07 1:59 ` Mauro Carvalho Chehab
2011-10-07 13:38 ` Devin Heitmueller
0 siblings, 1 reply; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-10-07 1:59 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mikael Magnusson
Hi Devin,
I had some discussions with Mikael today at the #linuxtv channel about
tvtime. Mikael has write access to the tvtime site at sourceforge and he
is doing some maintainance on it for some time, and worked on some bugs
from Gentoo, and also imported some stuff from Ubuntu.
I've merged his patches on my repository:
http://git.linuxtv.org/mchehab/tvtime.git
Tvtime is compiling, at least on Fedora 15. I also added your patch there,
and changed the latency delay to 50ms. I didn't test it yet. I'll do it later
today or tomorrow.
Btw, Mikael updated the Related Sites there to point to the LinuxTV site:
http://tvtime.sourceforge.net/links.html
He will try to contact Vektor again, in order to get his ack about adding
a note at the main page pointing to us.
I think we should move those patches to the main repository after testing the
merges, and give write rights to the ones that are interested on maintaining
tvtime.
I'm interested on it, and also Mikael.
IMHO, after testing it and applying a few other patches that Mikael might have,
it is time for us to rename the version to 1.10 and do a tvtime release.
Would that work for you?
Thank you!
Mauro
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: tvtime at linuxtv.org
2011-10-07 1:59 ` tvtime at linuxtv.org Mauro Carvalho Chehab
@ 2011-10-07 13:38 ` Devin Heitmueller
2011-10-07 15:18 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 32+ messages in thread
From: Devin Heitmueller @ 2011-10-07 13:38 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Mikael Magnusson
On Thu, Oct 6, 2011 at 9:59 PM, Mauro Carvalho Chehab
<mchehab@redhat.com> wrote:
> Hi Devin,
>
> I had some discussions with Mikael today at the #linuxtv channel about
> tvtime. Mikael has write access to the tvtime site at sourceforge and he
> is doing some maintainance on it for some time, and worked on some bugs
> from Gentoo, and also imported some stuff from Ubuntu.
>
> I've merged his patches on my repository:
> http://git.linuxtv.org/mchehab/tvtime.git
>
> Tvtime is compiling, at least on Fedora 15. I also added your patch there,
> and changed the latency delay to 50ms. I didn't test it yet. I'll do it
> later
> today or tomorrow.
>
> Btw, Mikael updated the Related Sites there to point to the LinuxTV site:
> http://tvtime.sourceforge.net/links.html
>
> He will try to contact Vektor again, in order to get his ack about adding
> a note at the main page pointing to us.
>
> I think we should move those patches to the main repository after testing
> the
> merges, and give write rights to the ones that are interested on maintaining
> tvtime.
>
> I'm interested on it, and also Mikael.
>
> IMHO, after testing it and applying a few other patches that Mikael might
> have,
> it is time for us to rename the version to 1.10 and do a tvtime release.
>
> Would that work for you?
>
> Thank you!
> Mauro
Hi Mauro,
It's good to hear that patches are continuing to be merged, and of
course contributors are always welcome.
The more I think about this, the more I recognize that I'm not really
adding any value to this process. While I would really like to put
more time/energy into tvtime, I just don't have the time and it
appears I'm actually slowing down a community of contributors who are
trying to move things forward.
At this point I would recommend the LinuxTV community just take over
the project, give yourself write access to the main repo, and spin a
release. I would indeed recommend calling it 1.10, to prevent
confusion with the various vendor branches where I believe some of
which may actually already be calling themselves 1.03.
Regarding expanding the list of individuals with commit rights, I
might suggest keeping the list of write privileges for the main repo
to a minimum in the short term (starting with yourself), until
developers have demonstrated their ability to author coherent patches
which won't cause breakage as well as the ability to review the work
of others.
Cheers,
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: tvtime at linuxtv.org
2011-10-07 13:38 ` Devin Heitmueller
@ 2011-10-07 15:18 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 32+ messages in thread
From: Mauro Carvalho Chehab @ 2011-10-07 15:18 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mikael Magnusson, Hans De Goede
Em 07-10-2011 10:38, Devin Heitmueller escreveu:
> On Thu, Oct 6, 2011 at 9:59 PM, Mauro Carvalho Chehab
> <mchehab@redhat.com> wrote:
>> Hi Devin,
>>
>> I had some discussions with Mikael today at the #linuxtv channel about
>> tvtime. Mikael has write access to the tvtime site at sourceforge and he
>> is doing some maintainance on it for some time, and worked on some bugs
>> from Gentoo, and also imported some stuff from Ubuntu.
>>
>> I've merged his patches on my repository:
>> http://git.linuxtv.org/mchehab/tvtime.git
>>
>> Tvtime is compiling, at least on Fedora 15. I also added your patch there,
>> and changed the latency delay to 50ms. I didn't test it yet. I'll do it
>> later
>> today or tomorrow.
>>
>> Btw, Mikael updated the Related Sites there to point to the LinuxTV site:
>> http://tvtime.sourceforge.net/links.html
>>
>> He will try to contact Vektor again, in order to get his ack about adding
>> a note at the main page pointing to us.
>>
>> I think we should move those patches to the main repository after testing
>> the
>> merges, and give write rights to the ones that are interested on maintaining
>> tvtime.
>>
>> I'm interested on it, and also Mikael.
>>
>> IMHO, after testing it and applying a few other patches that Mikael might
>> have,
>> it is time for us to rename the version to 1.10 and do a tvtime release.
>>
>> Would that work for you?
>>
>> Thank you!
>> Mauro
>
> Hi Mauro,
>
> It's good to hear that patches are continuing to be merged, and of
> course contributors are always welcome.
>
> The more I think about this, the more I recognize that I'm not really
> adding any value to this process. While I would really like to put
> more time/energy into tvtime, I just don't have the time and it
> appears I'm actually slowing down a community of contributors who are
> trying to move things forward.
>
> At this point I would recommend the LinuxTV community just take over
> the project, give yourself write access to the main repo, and spin a
> release. I would indeed recommend calling it 1.10, to prevent
> confusion with the various vendor branches where I believe some of
> which may actually already be calling themselves 1.03.
Ok, I've added myself into it.
I've just pushed everything into:
http://git.linuxtv.org/tvtime.git
For now, it is showing as version 1.0.4. I'll rename it to 1.1.0 after getting
some feedback and maybe some additional fixes, and add an announcement about
that when we'll be there.
I tested it yesterday, and it seems to be working properly. Mikael patches
were putting it on a borderless mode, with looked weird on my eyes ;)
So, I added a new parameter (-L) to allow selecting the borderless mode
for those that prefer that way. The default is to have borders.
> Regarding expanding the list of individuals with commit rights, I
> might suggest keeping the list of write privileges for the main repo
> to a minimum in the short term (starting with yourself), until
> developers have demonstrated their ability to author coherent patches
> which won't cause breakage as well as the ability to review the work
> of others.
Maybe Hans de Goede would also like to get his hands on it, as he wrote
a few patches for it on Fedora.
Thanks,
Mauro
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2011-10-07 15:19 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-06 15:29 [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 02/10] Fix make dist target Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 03/10] Backport mixer-alsa patch from Fedora Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 04/10] Properly document alsa mixer Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 05/10] Ignore auto-generated files Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 06/10] Backport UVC fix from Fedora Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 07/10] Add mkinstalldirs Mauro Carvalho Chehab
2011-09-06 15:29 ` [PATCH 08/10] Use a saner way to disable screensaver Mauro Carvalho Chehab
[not found] ` <1315322996-10576-9-git-send-email-mchehab@redhat.com>
2011-09-06 15:29 ` [PATCH 10/10] tvtime: Bump to version 1.0.3 Mauro Carvalho Chehab
2011-09-06 15:40 ` [PATCH 01/10] alsa_stream: port changes made on xawtv3 Mauro Carvalho Chehab
2011-09-06 16:24 ` Devin Heitmueller
2011-09-06 18:19 ` Hans de Goede
2011-09-06 18:35 ` Michael Krufky
2011-09-06 18:43 ` Hans de Goede
2011-09-06 19:11 ` Michael Krufky
2011-09-06 18:41 ` Devin Heitmueller
2011-09-06 19:12 ` Mauro Carvalho Chehab
2011-09-06 21:18 ` Devin Heitmueller
2011-09-06 21:50 ` Mauro Carvalho Chehab
2011-09-06 18:40 ` Mauro Carvalho Chehab
2011-09-07 2:58 ` Devin Heitmueller
2011-09-07 3:20 ` Devin Heitmueller
2011-09-07 3:29 ` Mauro Carvalho Chehab
2011-09-07 3:37 ` Devin Heitmueller
2011-09-07 3:42 ` Devin Heitmueller
2011-09-07 4:06 ` Devin Heitmueller
2011-10-07 1:59 ` tvtime at linuxtv.org Mauro Carvalho Chehab
2011-10-07 13:38 ` Devin Heitmueller
2011-10-07 15:18 ` Mauro Carvalho Chehab
2011-09-07 6:29 ` [PATCH 01/10] alsa_stream: port changes made on xawtv3 Hans de Goede
2011-09-07 12:49 ` Mauro Carvalho Chehab
2011-09-07 3:23 ` Mauro Carvalho Chehab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).