audiobuffersplit: Added max-silence-time property

This commit is contained in:
Vivia Nikolaidou 2019-02-21 15:16:37 +00:00 committed by Sebastian Dröge
parent 7c767f3fcd
commit ce0be4d1ac
2 changed files with 117 additions and 82 deletions

View file

@ -47,6 +47,7 @@ enum
PROP_DISCONT_WAIT, PROP_DISCONT_WAIT,
PROP_STRICT_BUFFER_SIZE, PROP_STRICT_BUFFER_SIZE,
PROP_GAPLESS, PROP_GAPLESS,
PROP_MAX_SILENCE_TIME,
LAST_PROP LAST_PROP
}; };
@ -56,6 +57,7 @@ enum
#define DEFAULT_DISCONT_WAIT (1 * GST_SECOND) #define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
#define DEFAULT_STRICT_BUFFER_SIZE (FALSE) #define DEFAULT_STRICT_BUFFER_SIZE (FALSE)
#define DEFAULT_GAPLESS (FALSE) #define DEFAULT_GAPLESS (FALSE)
#define DEFAULT_MAX_SILENCE_TIME (0)
#define parent_class gst_audio_buffer_split_parent_class #define parent_class gst_audio_buffer_split_parent_class
G_DEFINE_TYPE (GstAudioBufferSplit, gst_audio_buffer_split, GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstAudioBufferSplit, gst_audio_buffer_split, GST_TYPE_ELEMENT);
@ -123,6 +125,15 @@ gst_audio_buffer_split_class_init (GstAudioBufferSplitClass * klass)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY)); GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_MAX_SILENCE_TIME,
g_param_spec_uint64 ("max-silence-time",
"Maximum time of silence to insert",
"Do not insert silence in gapless mode if the gap exceeds this "
"period (in ns) (0 = disabled)",
0, G_MAXUINT64, DEFAULT_MAX_SILENCE_TIME,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
gst_element_class_set_static_metadata (gstelement_class, gst_element_class_set_static_metadata (gstelement_class,
"Audio Buffer Split", "Audio/Filter", "Audio Buffer Split", "Audio/Filter",
"Splits raw audio buffers into equal sized chunks", "Splits raw audio buffers into equal sized chunks",
@ -253,6 +264,9 @@ gst_audio_buffer_split_set_property (GObject * object, guint property_id,
case PROP_GAPLESS: case PROP_GAPLESS:
self->gapless = g_value_get_boolean (value); self->gapless = g_value_get_boolean (value);
break; break;
case PROP_MAX_SILENCE_TIME:
self->max_silence_time = g_value_get_uint64 (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -288,6 +302,9 @@ gst_audio_buffer_split_get_property (GObject * object, guint property_id,
case PROP_GAPLESS: case PROP_GAPLESS:
g_value_set_boolean (value, self->gapless); g_value_set_boolean (value, self->gapless);
break; break;
case PROP_MAX_SILENCE_TIME:
g_value_set_uint64 (value, self->max_silence_time);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -420,6 +437,11 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
{ {
gboolean discont; gboolean discont;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
guint avail = gst_adapter_available (self->adapter);
guint avail_samples = avail / bpf;
guint64 new_offset;
GstClockTime current_timestamp;
GstClockTime current_timestamp_end;
GST_OBJECT_LOCK (self); GST_OBJECT_LOCK (self);
discont = discont =
@ -430,12 +452,8 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
NULL); NULL);
GST_OBJECT_UNLOCK (self); GST_OBJECT_UNLOCK (self);
if (discont) { if (!discont)
guint avail = gst_adapter_available (self->adapter); return ret;
guint avail_samples = avail / bpf;
guint64 new_offset;
GstClockTime current_timestamp;
GstClockTime current_timestamp_end;
/* Reset */ /* Reset */
self->drop_samples = 0; self->drop_samples = 0;
@ -461,6 +479,7 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
/* We only set resync time on the very first buffer */ /* We only set resync time on the very first buffer */
self->current_offset = 0; self->current_offset = 0;
self->resync_time = GST_BUFFER_PTS (buffer); self->resync_time = GST_BUFFER_PTS (buffer);
discont = FALSE;
} else { } else {
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"Got discont in gapless mode: Current timestamp %" GST_TIME_FORMAT "Got discont in gapless mode: Current timestamp %" GST_TIME_FORMAT
@ -485,16 +504,25 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
"Dropping %" G_GUINT64_FORMAT " samples (%" GST_TIME_FORMAT ")", "Dropping %" G_GUINT64_FORMAT " samples (%" GST_TIME_FORMAT ")",
drop_samples, GST_TIME_ARGS (gst_util_uint64_scale (drop_samples, drop_samples, GST_TIME_ARGS (gst_util_uint64_scale (drop_samples,
GST_SECOND, rate))); GST_SECOND, rate)));
discont = FALSE;
} else if (new_offset > self->current_offset + avail_samples) { } else if (new_offset > self->current_offset + avail_samples) {
guint64 silence_samples = guint64 silence_samples =
new_offset - (self->current_offset + avail_samples); new_offset - (self->current_offset + avail_samples);
const GstAudioFormatInfo *info = gst_audio_format_get_info (format); const GstAudioFormatInfo *info = gst_audio_format_get_info (format);
GstClockTime silence_time =
gst_util_uint64_scale (silence_samples, GST_SECOND, rate);
if (silence_time > self->max_silence_time) {
GST_DEBUG_OBJECT (self,
"Not inserting %" G_GUINT64_FORMAT " samples of silence (%"
GST_TIME_FORMAT " exceeds maximum %" GST_TIME_FORMAT ")",
silence_samples, GST_TIME_ARGS (silence_time),
GST_TIME_ARGS (self->max_silence_time));
} else {
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"Inserting %" G_GUINT64_FORMAT " samples of silence (%" "Inserting %" G_GUINT64_FORMAT " samples of silence (%"
GST_TIME_FORMAT ")", silence_samples, GST_TIME_FORMAT ")", silence_samples,
GST_TIME_ARGS (gst_util_uint64_scale (silence_samples, GST_SECOND, GST_TIME_ARGS (silence_time));
rate)));
/* Insert silence buffers to fill the gap in 1s chunks */ /* Insert silence buffers to fill the gap in 1s chunks */
while (silence_samples > 0) { while (silence_samples > 0) {
@ -517,6 +545,8 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
silence_samples -= n_samples; silence_samples -= n_samples;
} }
discont = FALSE;
}
} else if (new_offset < self->current_offset + avail_samples) { } else if (new_offset < self->current_offset + avail_samples) {
guint64 drop_samples = guint64 drop_samples =
self->current_offset + avail_samples - new_offset; self->current_offset + avail_samples - new_offset;
@ -526,9 +556,14 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
drop_samples, GST_TIME_ARGS (gst_util_uint64_scale (drop_samples, drop_samples, GST_TIME_ARGS (gst_util_uint64_scale (drop_samples,
GST_SECOND, rate))); GST_SECOND, rate)));
self->drop_samples = drop_samples; self->drop_samples = drop_samples;
discont = FALSE;
} }
} }
} else { }
if (discont) {
/* We might end up in here also in gapless mode, if the above code decided
* that no silence is to be inserted, because e.g. the gap is too big */
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"Got discont: Current timestamp %" GST_TIME_FORMAT "Got discont: Current timestamp %" GST_TIME_FORMAT
", current end timestamp %" GST_TIME_FORMAT ", current end timestamp %" GST_TIME_FORMAT
@ -550,7 +585,6 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
self->accumulated_error = 0; self->accumulated_error = 0;
self->resync_time = GST_BUFFER_PTS (buffer); self->resync_time = GST_BUFFER_PTS (buffer);
} }
}
return ret; return ret;
} }

View file

@ -63,6 +63,7 @@ struct _GstAudioBufferSplit {
gboolean strict_buffer_size; gboolean strict_buffer_size;
gboolean gapless; gboolean gapless;
GstClockTime max_silence_time;
}; };
struct _GstAudioBufferSplitClass { struct _GstAudioBufferSplitClass {