mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 08:17:01 +00:00
ext/alsa/gstalsa.*: Add HW probing for period_count/size and buffer_size MIX/MAX
Original commit message from CVS: * ext/alsa/gstalsa.c: (gst_alsa_class_init), (gst_alsa_get_caps): * ext/alsa/gstalsa.h: Add HW probing for period_count/size and buffer_size MIX/MAX Adjust default/user defined value if out of bounds Should fix bug #162024
This commit is contained in:
parent
620c1765bb
commit
6686d9e7ee
3 changed files with 109 additions and 7 deletions
|
@ -1,3 +1,11 @@
|
|||
2005-01-10 Stephane LOEUILLET <stephane.loeuillet@tiscali.fr>
|
||||
|
||||
* ext/alsa/gstalsa.c: (gst_alsa_class_init), (gst_alsa_get_caps):
|
||||
* ext/alsa/gstalsa.h:
|
||||
Add HW probing for period_count/size and buffer_size MIX/MAX
|
||||
Adjust default/user defined value if out of bounds
|
||||
Should fix bug #162024
|
||||
|
||||
2005-01-09 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* gst/qtdemux/qtdemux.c: (gst_qtdemux_handle_sink_event):
|
||||
|
|
|
@ -177,19 +177,22 @@ gst_alsa_class_init (gpointer g_class, gpointer class_data)
|
|||
g_object_class_install_property (object_class, ARG_PERIODCOUNT,
|
||||
g_param_spec_int ("period-count", "Period count",
|
||||
"Number of hardware buffers to use",
|
||||
2, 64, 2, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
GST_ALSA_MIN_PERIOD_CNT, GST_ALSA_MAX_PERIOD_CNT,
|
||||
GST_ALSA_MIN_PERIOD_CNT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
g_object_class_install_property (object_class, ARG_PERIODSIZE,
|
||||
g_param_spec_int ("period-size", "Period size",
|
||||
"Number of frames (samples on each channel) in one hardware period",
|
||||
2, 8192, 8192, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
GST_ALSA_MIN_PERIOD_SZ, GST_ALSA_MAX_PERIOD_SZ,
|
||||
GST_ALSA_MAX_PERIOD_SZ, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
g_object_class_install_property (object_class, ARG_BUFFERSIZE,
|
||||
g_param_spec_int ("buffer-size", "Buffer size",
|
||||
"Number of frames the hardware buffer can hold",
|
||||
4, 65536, 16384, G_PARAM_READWRITE));
|
||||
GST_ALSA_MIN_BUFFER_SZ, GST_ALSA_MAX_BUFFER_SZ,
|
||||
GST_ALSA_MIN_PERIOD_CNT * GST_ALSA_MAX_PERIOD_SZ, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, ARG_AUTORECOVER,
|
||||
g_param_spec_boolean ("autorecover", "Automatic xrun recovery",
|
||||
"When TRUE tries to reduce processor load on xruns",
|
||||
TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
"When TRUE tries to reduce processor load on xruns", TRUE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
g_object_class_install_property (object_class, ARG_MMAP,
|
||||
g_param_spec_boolean ("mmap", "Use mmap'ed access",
|
||||
"Wether to use mmap (faster) or standard read/write (more compatible)",
|
||||
|
@ -813,6 +816,10 @@ gst_alsa_get_caps (GstPad * pad)
|
|||
snd_pcm_format_mask_t *mask;
|
||||
int i;
|
||||
unsigned int min_rate, max_rate;
|
||||
unsigned int min_period_cnt, max_period_cnt;
|
||||
snd_pcm_uframes_t min_period_sz, max_period_sz;
|
||||
snd_pcm_uframes_t min_buffer_sz, max_buffer_sz;
|
||||
gint buffer_size;
|
||||
gint min_channels, max_channels;
|
||||
GstCaps *ret = NULL;
|
||||
|
||||
|
@ -844,10 +851,83 @@ gst_alsa_get_caps (GstPad * pad)
|
|||
|
||||
ERROR_CHECK (snd_pcm_hw_params_get_rate_min (hw_params, &min_rate, &i),
|
||||
"Couldn't get minimum rate for device %s: %s", this->device);
|
||||
min_rate = min_rate < GST_ALSA_MIN_RATE ? GST_ALSA_MIN_RATE : min_rate + i;
|
||||
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 + i;
|
||||
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 */
|
||||
ERROR_CHECK (snd_pcm_hw_params_get_periods_min (hw_params, &min_period_cnt,
|
||||
&i), "Couldn't get minimum period_count for device %s: %s",
|
||||
this->device);
|
||||
min_period_cnt =
|
||||
min_period_cnt <
|
||||
GST_ALSA_MIN_PERIOD_CNT ? GST_ALSA_MIN_PERIOD_CNT : (min_period_cnt +
|
||||
GST_ALSA_DIR_MIN (i));
|
||||
if (this->period_count < min_period_cnt) {
|
||||
this->period_count = min_period_cnt;
|
||||
};
|
||||
ERROR_CHECK (snd_pcm_hw_params_get_periods_max (hw_params, &max_period_cnt,
|
||||
&i), "Couldn't get maximum period_count for device %s: %s",
|
||||
this->device);
|
||||
max_period_cnt =
|
||||
max_period_cnt >
|
||||
GST_ALSA_MAX_PERIOD_CNT ? GST_ALSA_MAX_PERIOD_CNT : (max_period_cnt +
|
||||
GST_ALSA_DIR_MAX (i));
|
||||
if (this->period_count > max_period_cnt) {
|
||||
this->period_count = max_period_cnt;
|
||||
};
|
||||
|
||||
/* Probe period_size and adjust default/user provided value against probed MIN/MAX */
|
||||
ERROR_CHECK (snd_pcm_hw_params_get_period_size_min (hw_params, &min_period_sz,
|
||||
&i), "Couldn't get minimum period_size for device %s: %s",
|
||||
this->device);
|
||||
min_period_sz =
|
||||
min_period_sz <
|
||||
GST_ALSA_MIN_PERIOD_SZ ? GST_ALSA_MIN_PERIOD_SZ : (min_period_sz +
|
||||
GST_ALSA_DIR_MIN (i));
|
||||
if (this->period_size < min_period_sz) {
|
||||
this->period_size = min_period_sz;
|
||||
};
|
||||
ERROR_CHECK (snd_pcm_hw_params_get_period_size_max (hw_params, &max_period_sz,
|
||||
&i), "Couldn't get maximum period_size for device %s: %s",
|
||||
this->device);
|
||||
max_period_sz =
|
||||
max_period_sz >
|
||||
GST_ALSA_MAX_PERIOD_SZ ? GST_ALSA_MAX_PERIOD_SZ : (max_period_sz +
|
||||
GST_ALSA_DIR_MAX (i));
|
||||
if (this->period_size > max_period_sz) {
|
||||
this->period_size = max_period_sz;
|
||||
};
|
||||
|
||||
/* Probe buffer_size MIN/MAX */
|
||||
buffer_size = this->period_count * this->period_size;
|
||||
ERROR_CHECK (snd_pcm_hw_params_get_buffer_size_min (hw_params,
|
||||
&min_buffer_sz), "Couldn't get minimum buffer_size for device %s: %s",
|
||||
this->device);
|
||||
min_buffer_sz =
|
||||
min_buffer_sz <
|
||||
GST_ALSA_MIN_BUFFER_SZ ? GST_ALSA_MIN_BUFFER_SZ : min_buffer_sz;
|
||||
if (buffer_size < min_buffer_sz) {
|
||||
buffer_size = min_buffer_sz;
|
||||
this->period_size = GST_ALSA_MIN_BUFFER_SZ / this->period_count;
|
||||
};
|
||||
ERROR_CHECK (snd_pcm_hw_params_get_buffer_size_max (hw_params,
|
||||
&max_buffer_sz), "Couldn't get maximum buffer_size for device %s: %s",
|
||||
this->device);
|
||||
max_buffer_sz =
|
||||
max_buffer_sz >
|
||||
GST_ALSA_MAX_BUFFER_SZ ? GST_ALSA_MAX_BUFFER_SZ : max_buffer_sz;
|
||||
if (buffer_size > max_buffer_sz) {
|
||||
buffer_size = max_buffer_sz;
|
||||
this->period_size = GST_ALSA_MAX_BUFFER_SZ / this->period_count;
|
||||
};
|
||||
|
||||
|
||||
snd_pcm_format_mask_alloca (&mask);
|
||||
snd_pcm_hw_params_get_format_mask (hw_params, mask);
|
||||
|
|
|
@ -78,9 +78,23 @@ GST_DEBUG_CATEGORY_EXTERN (alsa_debug);
|
|||
|
||||
#define GST_ALSA_MIN_RATE 8000
|
||||
#define GST_ALSA_MAX_RATE 192000
|
||||
#define GST_ALSA_MIN_PERIOD_CNT 2
|
||||
#define GST_ALSA_MAX_PERIOD_CNT 64
|
||||
#define GST_ALSA_MIN_PERIOD_SZ 2
|
||||
#define GST_ALSA_MAX_PERIOD_SZ 8192
|
||||
#define GST_ALSA_MIN_BUFFER_SZ GST_ALSA_MIN_PERIOD_CNT*GST_ALSA_MIN_PERIOD_SZ
|
||||
#define GST_ALSA_MAX_BUFFER_SZ 65536
|
||||
#define GST_ALSA_MAX_TRACKS 64 /* we don't support more than 64 tracks */
|
||||
#define GST_ALSA_MAX_CHANNELS 32 /* tracks can have up to 32 channels */
|
||||
|
||||
/* a few alsa functions return an int value and a 'direction', -1, 0 or +1
|
||||
0 = exact value
|
||||
-1 = real value is up to 1 before given value
|
||||
+1 = real value is up to 1 after given value
|
||||
*/
|
||||
#define GST_ALSA_DIR_MIN(i) ((i == 1) ? 1 : 0)
|
||||
#define GST_ALSA_DIR_MAX(i) ((i ==-1) ?-1 : 0)
|
||||
|
||||
/* Mono is 1 channel ; the 5.1 standard is 6 channels. The value for
|
||||
GST_ALSA_MAX_CHANNELS comes from alsa/mixer.h. */
|
||||
|
||||
|
|
Loading…
Reference in a new issue