mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-17 21:06:17 +00:00
audiomixer: Change blocksize property to output-buffer-duration in time format
This makes the interface of audiomixer independent of the actual caps.
This commit is contained in:
parent
6771db209d
commit
7c575af6df
3 changed files with 36 additions and 24 deletions
|
@ -174,7 +174,7 @@ gst_audiomixer_pad_init (GstAudioMixerPad * pad)
|
||||||
|
|
||||||
#define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND)
|
#define DEFAULT_ALIGNMENT_THRESHOLD (40 * GST_MSECOND)
|
||||||
#define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
|
#define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
|
||||||
#define DEFAULT_BLOCKSIZE (1024)
|
#define DEFAULT_OUTPUT_BUFFER_DURATION (10 * GST_MSECOND)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -182,7 +182,7 @@ enum
|
||||||
PROP_FILTER_CAPS,
|
PROP_FILTER_CAPS,
|
||||||
PROP_ALIGNMENT_THRESHOLD,
|
PROP_ALIGNMENT_THRESHOLD,
|
||||||
PROP_DISCONT_WAIT,
|
PROP_DISCONT_WAIT,
|
||||||
PROP_BLOCKSIZE
|
PROP_OUTPUT_BUFFER_DURATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/* elementfactory information */
|
/* elementfactory information */
|
||||||
|
@ -792,10 +792,10 @@ gst_audiomixer_class_init (GstAudioMixerClass * klass)
|
||||||
G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
|
G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
|
g_object_class_install_property (gobject_class, PROP_OUTPUT_BUFFER_DURATION,
|
||||||
g_param_spec_uint ("blocksize", "Block Size",
|
g_param_spec_uint64 ("output-buffer-duration", "Output Buffer Duration",
|
||||||
"Output block size in number of samples", 1,
|
"Output block size in number of samples", 1,
|
||||||
G_MAXUINT, DEFAULT_BLOCKSIZE,
|
G_MAXUINT64, DEFAULT_OUTPUT_BUFFER_DURATION,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gst_element_class_add_pad_template (gstelement_class,
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
|
@ -841,7 +841,9 @@ gst_audiomixer_init (GstAudioMixer * audiomixer)
|
||||||
audiomixer->filter_caps = NULL;
|
audiomixer->filter_caps = NULL;
|
||||||
audiomixer->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
|
audiomixer->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
|
||||||
audiomixer->discont_wait = DEFAULT_DISCONT_WAIT;
|
audiomixer->discont_wait = DEFAULT_DISCONT_WAIT;
|
||||||
audiomixer->blocksize = DEFAULT_BLOCKSIZE;
|
audiomixer->output_buffer_duration = DEFAULT_OUTPUT_BUFFER_DURATION;
|
||||||
|
gst_aggregator_set_latency (GST_AGGREGATOR (audiomixer),
|
||||||
|
audiomixer->output_buffer_duration, GST_CLOCK_TIME_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -889,8 +891,10 @@ gst_audiomixer_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_DISCONT_WAIT:
|
case PROP_DISCONT_WAIT:
|
||||||
audiomixer->discont_wait = g_value_get_uint64 (value);
|
audiomixer->discont_wait = g_value_get_uint64 (value);
|
||||||
break;
|
break;
|
||||||
case PROP_BLOCKSIZE:
|
case PROP_OUTPUT_BUFFER_DURATION:
|
||||||
audiomixer->blocksize = g_value_get_uint (value);
|
audiomixer->output_buffer_duration = g_value_get_uint64 (value);
|
||||||
|
gst_aggregator_set_latency (GST_AGGREGATOR (audiomixer),
|
||||||
|
audiomixer->output_buffer_duration, GST_CLOCK_TIME_NONE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
@ -916,8 +920,8 @@ gst_audiomixer_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case PROP_DISCONT_WAIT:
|
case PROP_DISCONT_WAIT:
|
||||||
g_value_set_uint64 (value, audiomixer->discont_wait);
|
g_value_set_uint64 (value, audiomixer->discont_wait);
|
||||||
break;
|
break;
|
||||||
case PROP_BLOCKSIZE:
|
case PROP_OUTPUT_BUFFER_DURATION:
|
||||||
g_value_set_uint (value, audiomixer->blocksize);
|
g_value_set_uint64 (value, audiomixer->output_buffer_duration);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
@ -1149,9 +1153,15 @@ gst_audio_mixer_mix_buffer (GstAudioMixer * audiomixer, GstAudioMixerPad * pad,
|
||||||
GstBuffer *inbuf;
|
GstBuffer *inbuf;
|
||||||
GstMapInfo inmap;
|
GstMapInfo inmap;
|
||||||
gint bpf;
|
gint bpf;
|
||||||
|
guint blocksize;
|
||||||
|
|
||||||
GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
|
GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
|
||||||
|
|
||||||
|
blocksize =
|
||||||
|
gst_util_uint64_scale (audiomixer->output_buffer_duration,
|
||||||
|
GST_AUDIO_INFO_RATE (&audiomixer->info), GST_SECOND);
|
||||||
|
blocksize = MAX (1, blocksize);
|
||||||
|
|
||||||
bpf = GST_AUDIO_INFO_BPF (&audiomixer->info);
|
bpf = GST_AUDIO_INFO_BPF (&audiomixer->info);
|
||||||
|
|
||||||
/* Overlap => mix */
|
/* Overlap => mix */
|
||||||
|
@ -1161,8 +1171,8 @@ gst_audio_mixer_mix_buffer (GstAudioMixer * audiomixer, GstAudioMixerPad * pad,
|
||||||
out_start = 0;
|
out_start = 0;
|
||||||
|
|
||||||
overlap = pad->size / bpf - pad->position / bpf;
|
overlap = pad->size / bpf - pad->position / bpf;
|
||||||
if (overlap > audiomixer->blocksize - out_start)
|
if (overlap > blocksize - out_start)
|
||||||
overlap = audiomixer->blocksize - out_start;
|
overlap = blocksize - out_start;
|
||||||
|
|
||||||
inbuf = gst_aggregator_pad_get_buffer (aggpad);
|
inbuf = gst_aggregator_pad_get_buffer (aggpad);
|
||||||
if (inbuf == NULL)
|
if (inbuf == NULL)
|
||||||
|
@ -1360,6 +1370,7 @@ gst_audiomixer_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
gboolean dropped = FALSE;
|
gboolean dropped = FALSE;
|
||||||
gboolean is_eos = TRUE;
|
gboolean is_eos = TRUE;
|
||||||
gboolean is_done = TRUE;
|
gboolean is_done = TRUE;
|
||||||
|
guint blocksize;
|
||||||
|
|
||||||
audiomixer = GST_AUDIO_MIXER (agg);
|
audiomixer = GST_AUDIO_MIXER (agg);
|
||||||
|
|
||||||
|
@ -1367,11 +1378,13 @@ gst_audiomixer_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
if (G_UNLIKELY (audiomixer->info.finfo->format == GST_AUDIO_FORMAT_UNKNOWN))
|
if (G_UNLIKELY (audiomixer->info.finfo->format == GST_AUDIO_FORMAT_UNKNOWN))
|
||||||
goto not_negotiated;
|
goto not_negotiated;
|
||||||
|
|
||||||
|
blocksize =
|
||||||
|
gst_util_uint64_scale (audiomixer->output_buffer_duration,
|
||||||
|
GST_AUDIO_INFO_RATE (&audiomixer->info), GST_SECOND);
|
||||||
|
blocksize = MAX (1, blocksize);
|
||||||
|
|
||||||
if (audiomixer->send_caps) {
|
if (audiomixer->send_caps) {
|
||||||
gst_aggregator_set_src_caps (agg, audiomixer->current_caps);
|
gst_aggregator_set_src_caps (agg, audiomixer->current_caps);
|
||||||
gst_aggregator_set_latency (agg,
|
|
||||||
gst_util_uint64_scale (audiomixer->blocksize, GST_SECOND,
|
|
||||||
GST_AUDIO_INFO_RATE (&audiomixer->info)), GST_CLOCK_TIME_NONE);
|
|
||||||
|
|
||||||
if (agg->segment.rate > 0.0)
|
if (agg->segment.rate > 0.0)
|
||||||
agg->segment.position = agg->segment.start;
|
agg->segment.position = agg->segment.start;
|
||||||
|
@ -1392,16 +1405,16 @@ gst_audiomixer_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
|
|
||||||
/* FIXME: Reverse mixing does not work at all yet */
|
/* FIXME: Reverse mixing does not work at all yet */
|
||||||
if (agg->segment.rate > 0.0) {
|
if (agg->segment.rate > 0.0) {
|
||||||
next_offset = audiomixer->offset + audiomixer->blocksize;
|
next_offset = audiomixer->offset + blocksize;
|
||||||
} else {
|
} else {
|
||||||
next_offset = audiomixer->offset - audiomixer->blocksize;
|
next_offset = audiomixer->offset - blocksize;
|
||||||
}
|
}
|
||||||
next_timestamp = gst_util_uint64_scale (next_offset, GST_SECOND, rate);
|
next_timestamp = gst_util_uint64_scale (next_offset, GST_SECOND, rate);
|
||||||
|
|
||||||
if (audiomixer->current_buffer) {
|
if (audiomixer->current_buffer) {
|
||||||
outbuf = audiomixer->current_buffer;
|
outbuf = audiomixer->current_buffer;
|
||||||
} else {
|
} else {
|
||||||
outbuf = gst_buffer_new_and_alloc (audiomixer->blocksize * bpf);
|
outbuf = gst_buffer_new_and_alloc (blocksize * bpf);
|
||||||
gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE);
|
gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE);
|
||||||
gst_audio_format_fill_silence (audiomixer->info.finfo, outmap.data,
|
gst_audio_format_fill_silence (audiomixer->info.finfo, outmap.data,
|
||||||
outmap.size);
|
outmap.size);
|
||||||
|
@ -1411,7 +1424,7 @@ gst_audiomixer_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
|
|
||||||
GST_LOG_OBJECT (agg,
|
GST_LOG_OBJECT (agg,
|
||||||
"Starting to mix %u samples for offset %" G_GUINT64_FORMAT
|
"Starting to mix %u samples for offset %" G_GUINT64_FORMAT
|
||||||
" with timestamp %" GST_TIME_FORMAT, audiomixer->blocksize,
|
" with timestamp %" GST_TIME_FORMAT, blocksize,
|
||||||
audiomixer->offset, GST_TIME_ARGS (agg->segment.position));
|
audiomixer->offset, GST_TIME_ARGS (agg->segment.position));
|
||||||
|
|
||||||
gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE);
|
gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE);
|
||||||
|
@ -1476,8 +1489,7 @@ gst_audiomixer_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pad->output_offset >= audiomixer->offset
|
if (pad->output_offset >= audiomixer->offset
|
||||||
&& pad->output_offset <
|
&& pad->output_offset < audiomixer->offset + blocksize && pad->buffer) {
|
||||||
audiomixer->offset + audiomixer->blocksize && pad->buffer) {
|
|
||||||
GST_LOG_OBJECT (aggpad, "Mixing buffer for current offset");
|
GST_LOG_OBJECT (aggpad, "Mixing buffer for current offset");
|
||||||
gst_audio_mixer_mix_buffer (audiomixer, pad, &outmap);
|
gst_audio_mixer_mix_buffer (audiomixer, pad, &outmap);
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,8 @@ struct _GstAudioMixer {
|
||||||
|
|
||||||
gint64 base_time;
|
gint64 base_time;
|
||||||
|
|
||||||
/* Size in samples that is output per buffer */
|
/* Duration of every output buffer */
|
||||||
guint blocksize;
|
GstClockTime output_buffer_duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstAudioMixerClass {
|
struct _GstAudioMixerClass {
|
||||||
|
|
|
@ -1373,7 +1373,7 @@ run_sync_test (SendBuffersFunction send_buffers,
|
||||||
queue1 = gst_element_factory_make ("queue", "queue1");
|
queue1 = gst_element_factory_make ("queue", "queue1");
|
||||||
queue2 = gst_element_factory_make ("queue", "queue2");
|
queue2 = gst_element_factory_make ("queue", "queue2");
|
||||||
audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
|
audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
|
||||||
g_object_set (audiomixer, "blocksize", 500, NULL);
|
g_object_set (audiomixer, "output-buffer-duration", 500 * GST_MSECOND, NULL);
|
||||||
sink = gst_element_factory_make ("fakesink", "sink");
|
sink = gst_element_factory_make ("fakesink", "sink");
|
||||||
g_object_set (sink, "signal-handoffs", TRUE, NULL);
|
g_object_set (sink, "signal-handoffs", TRUE, NULL);
|
||||||
g_signal_connect (sink, "handoff", (GCallback) handoff_buffer_collect_cb,
|
g_signal_connect (sink, "handoff", (GCallback) handoff_buffer_collect_cb,
|
||||||
|
|
Loading…
Reference in a new issue