mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 18:35:35 +00:00
TODO: delete this file, it is by far outdated
Original commit message from CVS: * TODO: delete this file, it is by far outdated * ext/alsa/gstalsa.1: remove * ext/alsa/gstalsa.c: (add_rates), (add_channels), (gst_alsa_caps), (gst_alsa_check_sample_rates), (gst_alsa_rates_probe), (gst_alsa_get_caps): Add HW probing for supported sample rates. Fixes #161704
This commit is contained in:
parent
f7b012fa2f
commit
dbebd65ced
3 changed files with 129 additions and 69 deletions
25
TODO
25
TODO
|
@ -1,25 +0,0 @@
|
||||||
Warning !!! most of those item are probably obsolete :
|
|
||||||
|
|
||||||
configure.ac / build :
|
|
||||||
* version the element check m4
|
|
||||||
* check GST_* in configure.ac, there is too much in it
|
|
||||||
* check if we can drop some of the AC_SUBST's for libs and cflags
|
|
||||||
|
|
||||||
plugins :
|
|
||||||
* ext/a52dec check options, it has some arch stuff and some opti stuff that looks dodgy
|
|
||||||
* ext/arts[d] need a good onceover
|
|
||||||
* ext/jack plugin is rotten, won't work with current jack versions
|
|
||||||
* ext/ladspa add header check stuff and dir stuff
|
|
||||||
* ext/mpeg2dec what to do with the perftest ?
|
|
||||||
* ext/sdl check SDL optimisation flags
|
|
||||||
* gst/festival should have checks and stuff and added properly
|
|
||||||
* gst/wavenc merge gst/wavenc/riff.h and gst-libs/gst/riff/riff-ids.h
|
|
||||||
* sys/qcam it includes source of the qcam package that might be librified
|
|
||||||
|
|
||||||
* gst-libs/gst/riff: do we need those cflags ?
|
|
||||||
|
|
||||||
packaging :
|
|
||||||
* work on spec file :
|
|
||||||
add plugins with AC stuff (maybe from bits ?)
|
|
||||||
write script that builds rpm's one from one
|
|
||||||
get postun script right; gstreamer-register should be installed for example
|
|
|
@ -1,22 +0,0 @@
|
||||||
.TH "GStreamer ALSA Plugin" "1" "June 2002" "Christian F. K. Schaller" ""
|
|
||||||
.SH "NAME"
|
|
||||||
gstalsa \- GStreamer plugins for recieving and sending audio through the ALSA audio framework
|
|
||||||
.SH "SYNOPSIS"
|
|
||||||
pipeline ! \fBalsasink\fR
|
|
||||||
|
|
||||||
\fBalsasrc\fR ! pipeline
|
|
||||||
.SH "DESCRIPTION"
|
|
||||||
.LP
|
|
||||||
\fIgstalsa\fP is a plugin to be used with the \fIGStreamer\fP media framework.
|
|
||||||
The plugin contains several elements that can be used in to interface with an
|
|
||||||
ALSA sound device. \fIgstalsa\fP contains an element to recieve sound
|
|
||||||
(\fBalsasrc\fR) aquired through ALSA. Probably the most common use, however, is
|
|
||||||
to output sound generated by a GStreamer pipeline to an ALSA device
|
|
||||||
(\fBalsasink\fR).
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR gstoss (1),
|
|
||||||
.BR gstjack (1)
|
|
||||||
|
|
||||||
.SH "AUTHOR"
|
|
||||||
The GStreamer team at http://gstreamer.net/
|
|
|
@ -719,8 +719,7 @@ gst_alsa_get_caps_internal (snd_pcm_format_t format)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
add_channels (GstStructure * structure, gint min_rate, gint max_rate,
|
add_rates (GstStructure * structure, gint min_rate, gint max_rate)
|
||||||
gint min_channels, gint max_channels)
|
|
||||||
{
|
{
|
||||||
if (min_rate < 0) {
|
if (min_rate < 0) {
|
||||||
min_rate = GST_ALSA_MIN_RATE;
|
min_rate = GST_ALSA_MIN_RATE;
|
||||||
|
@ -743,6 +742,11 @@ add_channels (GstStructure * structure, gint min_rate, gint max_rate,
|
||||||
gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, min_rate,
|
gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, min_rate,
|
||||||
max_rate, NULL);
|
max_rate, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
add_channels (GstStructure * structure, gint min_channels, gint max_channels)
|
||||||
|
{
|
||||||
if (min_channels < 0) {
|
if (min_channels < 0) {
|
||||||
min_channels = 1;
|
min_channels = 1;
|
||||||
max_channels = GST_ALSA_MAX_CHANNELS;
|
max_channels = GST_ALSA_MAX_CHANNELS;
|
||||||
|
@ -785,7 +789,8 @@ gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels)
|
||||||
g_assert (ret_caps != NULL);
|
g_assert (ret_caps != NULL);
|
||||||
g_assert (gst_caps_get_size (ret_caps) == 1);
|
g_assert (gst_caps_get_size (ret_caps) == 1);
|
||||||
|
|
||||||
add_channels (gst_caps_get_structure (ret_caps, 0), rate, -1, channels, -1);
|
add_rates (gst_caps_get_structure (ret_caps, 0), rate, -1);
|
||||||
|
add_channels (gst_caps_get_structure (ret_caps, 0), channels, -1);
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
GstCaps *temp;
|
GstCaps *temp;
|
||||||
|
@ -797,7 +802,8 @@ gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels)
|
||||||
/* can be NULL, because not all alsa formats can be specified as caps */
|
/* can be NULL, because not all alsa formats can be specified as caps */
|
||||||
if (temp != NULL) {
|
if (temp != NULL) {
|
||||||
g_assert (gst_caps_get_size (temp) == 1);
|
g_assert (gst_caps_get_size (temp) == 1);
|
||||||
add_channels (gst_caps_get_structure (temp, 0), rate, -1, channels, -1);
|
add_rates (gst_caps_get_structure (temp, 0), rate, -1);
|
||||||
|
add_channels (gst_caps_get_structure (temp, 0), channels, -1);
|
||||||
gst_caps_append (ret_caps, temp);
|
gst_caps_append (ret_caps, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -807,6 +813,107 @@ gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels)
|
||||||
return ret_caps;
|
return ret_caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
gst_alsa_check_sample_rates (snd_pcm_t * device_handle,
|
||||||
|
snd_pcm_hw_params_t * hw_params, unsigned int *tested_rates,
|
||||||
|
GValue * supported_rates)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char init_done = 0;
|
||||||
|
|
||||||
|
GValue value = { 0 };
|
||||||
|
g_value_init (&value, G_TYPE_INT);
|
||||||
|
|
||||||
|
for (i = 0; tested_rates[i] != 0; i++) {
|
||||||
|
if (!snd_pcm_hw_params_test_rate (device_handle, hw_params, tested_rates[i],
|
||||||
|
0)) {
|
||||||
|
if (!init_done) {
|
||||||
|
/* at least one sample rate supported */
|
||||||
|
g_value_init (supported_rates, GST_TYPE_LIST);
|
||||||
|
init_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_set_int (&value, tested_rates[i]);
|
||||||
|
gst_value_list_append_value (supported_rates, &value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only one -> G_TYPE_INT
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
return init_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gst_alsa_rates_probe (snd_pcm_t * device_handle,
|
||||||
|
snd_pcm_hw_params_t * hw_params, GValue * supported_rates)
|
||||||
|
{
|
||||||
|
unsigned int common_rates[] =
|
||||||
|
{ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 88200,
|
||||||
|
96000, 192000, 0
|
||||||
|
};
|
||||||
|
unsigned int uncommon_rates[] = { 12345, 0 }; /* this dummy sample rate should only be supported by a software device */
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
int dir;
|
||||||
|
unsigned int min_rate, max_rate;
|
||||||
|
|
||||||
|
/* Get MIN/MAX supported rate */
|
||||||
|
snd_pcm_hw_params_get_rate_min (hw_params, &min_rate, &dir);
|
||||||
|
min_rate =
|
||||||
|
min_rate <
|
||||||
|
GST_ALSA_MIN_RATE ? GST_ALSA_MIN_RATE : (min_rate +
|
||||||
|
GST_ALSA_DIR_MIN (dir));
|
||||||
|
snd_pcm_hw_params_get_rate_max (hw_params, &max_rate, &dir);
|
||||||
|
max_rate =
|
||||||
|
max_rate >
|
||||||
|
GST_ALSA_MAX_RATE ? GST_ALSA_MAX_RATE : (max_rate +
|
||||||
|
GST_ALSA_DIR_MAX (dir));
|
||||||
|
|
||||||
|
|
||||||
|
ret =
|
||||||
|
gst_alsa_check_sample_rates (device_handle, hw_params, uncommon_rates,
|
||||||
|
supported_rates);
|
||||||
|
if (ret) {
|
||||||
|
/* Uncommon sample rates supported, it is certainly a "software"/dummy device */
|
||||||
|
g_value_unset (supported_rates);
|
||||||
|
g_value_init (supported_rates, GST_TYPE_INT_RANGE);
|
||||||
|
|
||||||
|
if (min_rate != max_rate) {
|
||||||
|
gst_value_set_int_range (supported_rates, min_rate, max_rate);
|
||||||
|
} else {
|
||||||
|
/* Only one supported */
|
||||||
|
g_value_unset (supported_rates);
|
||||||
|
g_value_init (supported_rates, G_TYPE_INT);
|
||||||
|
g_value_set_int (supported_rates, min_rate);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Check common sample rates for real hardware support */
|
||||||
|
ret =
|
||||||
|
gst_alsa_check_sample_rates (device_handle, hw_params, common_rates,
|
||||||
|
supported_rates);
|
||||||
|
if (ret) {
|
||||||
|
if (gst_value_list_get_size (supported_rates) == 1) {
|
||||||
|
/* Only one supported */
|
||||||
|
GValue *rate = (GValue *) gst_value_list_get_value (supported_rates, 0);
|
||||||
|
|
||||||
|
min_rate = g_value_get_int (rate);
|
||||||
|
g_value_unset (supported_rates);
|
||||||
|
g_value_init (supported_rates, G_TYPE_INT);
|
||||||
|
g_value_set_int (supported_rates, min_rate);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No sample rate supported ?! WTF */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return better caps when device is open */
|
/* Return better caps when device is open */
|
||||||
GstCaps *
|
GstCaps *
|
||||||
gst_alsa_get_caps (GstPad * pad)
|
gst_alsa_get_caps (GstPad * pad)
|
||||||
|
@ -815,7 +922,7 @@ gst_alsa_get_caps (GstPad * pad)
|
||||||
snd_pcm_hw_params_t *hw_params;
|
snd_pcm_hw_params_t *hw_params;
|
||||||
snd_pcm_format_mask_t *mask;
|
snd_pcm_format_mask_t *mask;
|
||||||
int i;
|
int i;
|
||||||
unsigned int min_rate, max_rate;
|
GValue supported_rates = { 0 };
|
||||||
unsigned int min_period_cnt, max_period_cnt;
|
unsigned int min_period_cnt, max_period_cnt;
|
||||||
snd_pcm_uframes_t min_period_sz, max_period_sz;
|
snd_pcm_uframes_t min_period_sz, max_period_sz;
|
||||||
snd_pcm_uframes_t min_buffer_sz, max_buffer_sz;
|
snd_pcm_uframes_t min_buffer_sz, max_buffer_sz;
|
||||||
|
@ -840,26 +947,20 @@ gst_alsa_get_caps (GstPad * pad)
|
||||||
min_channels = 1;
|
min_channels = 1;
|
||||||
max_channels = -1;
|
max_channels = -1;
|
||||||
} else {
|
} else {
|
||||||
ERROR_CHECK (snd_pcm_hw_params_get_channels_min (hw_params, &min_rate),
|
ERROR_CHECK (snd_pcm_hw_params_get_channels_min (hw_params, &min_channels),
|
||||||
"Couldn't get minimum channel count for device %s: %s", this->device);
|
"Couldn't get minimum channel count for device %s: %s", this->device);
|
||||||
ERROR_CHECK (snd_pcm_hw_params_get_channels_max (hw_params, &max_rate),
|
ERROR_CHECK (snd_pcm_hw_params_get_channels_max (hw_params, &max_channels),
|
||||||
"Couldn't get maximum channel count for device %s: %s", this->device);
|
"Couldn't get maximum channel count for device %s: %s", this->device);
|
||||||
min_channels = min_rate;
|
min_channels = min_channels < 1 ? 1 : min_channels;
|
||||||
max_channels =
|
max_channels =
|
||||||
max_rate > GST_ALSA_MAX_CHANNELS ? GST_ALSA_MAX_CHANNELS : max_rate;
|
max_channels >
|
||||||
|
GST_ALSA_MAX_CHANNELS ? GST_ALSA_MAX_CHANNELS : max_channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERROR_CHECK (snd_pcm_hw_params_get_rate_min (hw_params, &min_rate, &i),
|
/* Check available sample rates */
|
||||||
"Couldn't get minimum rate for device %s: %s", this->device);
|
if (!gst_alsa_rates_probe (this->handle, hw_params, &supported_rates)) {
|
||||||
min_rate =
|
;
|
||||||
min_rate <
|
}
|
||||||
GST_ALSA_MIN_RATE ? GST_ALSA_MIN_RATE : (min_rate + GST_ALSA_DIR_MIN (i));
|
|
||||||
ERROR_CHECK (snd_pcm_hw_params_get_rate_max (hw_params, &max_rate, &i),
|
|
||||||
"Couldn't get maximum rate for device %s: %s", this->device);
|
|
||||||
max_rate =
|
|
||||||
max_rate >
|
|
||||||
GST_ALSA_MAX_RATE ? GST_ALSA_MAX_RATE : (max_rate + GST_ALSA_DIR_MAX (i));
|
|
||||||
|
|
||||||
|
|
||||||
/* Probe period_count and adjust default/user provided value against probed MIN/MAX */
|
/* Probe period_count and adjust default/user provided value against probed MIN/MAX */
|
||||||
ERROR_CHECK (snd_pcm_hw_params_get_periods_min (hw_params, &min_period_cnt,
|
ERROR_CHECK (snd_pcm_hw_params_get_periods_min (hw_params, &min_period_cnt,
|
||||||
|
@ -940,8 +1041,12 @@ gst_alsa_get_caps (GstPad * pad)
|
||||||
gint n;
|
gint n;
|
||||||
|
|
||||||
g_assert (gst_caps_get_size (caps) == 1);
|
g_assert (gst_caps_get_size (caps) == 1);
|
||||||
add_channels (gst_caps_get_structure (caps, 0), min_rate, max_rate,
|
|
||||||
min_channels, max_channels);
|
gst_structure_set_value (gst_caps_get_structure (caps, 0), "rate",
|
||||||
|
&supported_rates);
|
||||||
|
|
||||||
|
add_channels (gst_caps_get_structure (caps, 0), min_channels,
|
||||||
|
max_channels);
|
||||||
|
|
||||||
/* channel configuration */
|
/* channel configuration */
|
||||||
/* MIN used to spped up because we don't support more than 8 channels */
|
/* MIN used to spped up because we don't support more than 8 channels */
|
||||||
|
@ -1000,6 +1105,8 @@ gst_alsa_get_caps (GstPad * pad)
|
||||||
gst_caps_do_simplify (ret);
|
gst_caps_do_simplify (ret);
|
||||||
GST_LOG_OBJECT (this, "get_caps returns %P", ret);
|
GST_LOG_OBJECT (this, "get_caps returns %P", ret);
|
||||||
|
|
||||||
|
g_value_unset (&supported_rates);
|
||||||
|
|
||||||
this->cached_caps = gst_caps_copy (ret);
|
this->cached_caps = gst_caps_copy (ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue