From 248d2bb79585c87cc00c598b5ece9ba4c297d57d Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Fri, 11 Sep 2020 18:17:20 +0530 Subject: [PATCH] audiobuffersplit: Add support for specifying output buffer size Currently for buffer splitting only output duration can be specified. Allow specifying a buffer size in bytes for splitting. Consider a use case of the below pipeline appsrc ! rptL16pay ! capsfilter ! rtpbin ! udpsink Maintaining MTU for RTP transfer is desirable but in a scenario where the buffers being pushed to appsrc do not adhere to this, an audiobuffersplit element placed between appsrc and rtpL16pay with output buffer size specified considering the MTU can help mitigate this. While rtpL16pay already has a MTU setting, in case of where an incoming buffer has a size close to MTU, for eg. with a MTU of 1280, a buffer of size 1276 bytes would be split into two buffers, one of 1268 and other of 8 bytes considering RTP header size of 12 bytes. Putting audiobuffersplit between appsrc and rtpL16pay can take care of this. While buffer duration could still be used being able to specify the size in bytes is helpful here. Part-of: --- docs/plugins/gst_plugins_cache.json | 14 ++++++++++ gst/audiobuffersplit/gstaudiobuffersplit.c | 30 ++++++++++++++++++++++ gst/audiobuffersplit/gstaudiobuffersplit.h | 1 + 3 files changed, 45 insertions(+) diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json index 82491a194d..0b952c8a8e 100644 --- a/docs/plugins/gst_plugins_cache.json +++ b/docs/plugins/gst_plugins_cache.json @@ -1054,6 +1054,20 @@ "type": "GstFraction", "writable": true }, + "output-buffer-size": { + "blurb": "Output block size in bytes, takes precedence over buffer duration when set to non zero", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "2147483647", + "min": "0", + "mutable": "ready", + "readable": true, + "type": "guint", + "writable": true + }, "strict-buffer-size": { "blurb": "Discard the last samples at EOS or discont if they are too small to fill a buffer", "conditionally-available": false, diff --git a/gst/audiobuffersplit/gstaudiobuffersplit.c b/gst/audiobuffersplit/gstaudiobuffersplit.c index f5ec18085e..e717b5ba54 100644 --- a/gst/audiobuffersplit/gstaudiobuffersplit.c +++ b/gst/audiobuffersplit/gstaudiobuffersplit.c @@ -45,6 +45,7 @@ enum { PROP_0, PROP_OUTPUT_BUFFER_DURATION, + PROP_OUTPUT_BUFFER_SIZE, PROP_ALIGNMENT_THRESHOLD, PROP_DISCONT_WAIT, PROP_STRICT_BUFFER_SIZE, @@ -98,6 +99,22 @@ gst_audio_buffer_split_class_init (GstAudioBufferSplitClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); + /** + * GstAudioBufferSplit:output-buffer-size + * + * Allow specifying a buffer size for splitting. Zero by default. + * Takes precedence over output-buffer-duration when set to a + * non zero value else will not be in effect. + * + * Since: 1.20 + */ + g_object_class_install_property (gobject_class, PROP_OUTPUT_BUFFER_SIZE, + g_param_spec_uint ("output-buffer-size", "Output buffer size", + "Output block size in bytes, takes precedence over " + "buffer duration when set to non zero", 0, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, PROP_ALIGNMENT_THRESHOLD, g_param_spec_uint64 ("alignment-threshold", "Alignment Threshold", "Timestamp alignment threshold in nanoseconds", 0, @@ -171,6 +188,7 @@ gst_audio_buffer_split_init (GstAudioBufferSplit * self) self->output_buffer_duration_d = DEFAULT_OUTPUT_BUFFER_DURATION_D; self->strict_buffer_size = DEFAULT_STRICT_BUFFER_SIZE; self->gapless = DEFAULT_GAPLESS; + self->output_buffer_size = 0; self->adapter = gst_adapter_new (); @@ -211,6 +229,11 @@ gst_audio_buffer_split_update_samples_per_buffer (GstAudioBufferSplit * self) goto out; } + if (self->output_buffer_size) { + self->output_buffer_duration_n = GST_AUDIO_INFO_BPF (&self->info); + self->output_buffer_duration_d = self->output_buffer_size; + } + self->samples_per_buffer = (((guint64) GST_AUDIO_INFO_RATE (&self->info)) * self->output_buffer_duration_n) / self->output_buffer_duration_d; @@ -248,6 +271,10 @@ gst_audio_buffer_split_set_property (GObject * object, guint property_id, gst_value_get_fraction_denominator (value); gst_audio_buffer_split_update_samples_per_buffer (self); break; + case PROP_OUTPUT_BUFFER_SIZE: + self->output_buffer_size = g_value_get_uint (value); + gst_audio_buffer_split_update_samples_per_buffer (self); + break; case PROP_ALIGNMENT_THRESHOLD: GST_OBJECT_LOCK (self); gst_audio_stream_align_set_alignment_threshold (self->stream_align, @@ -286,6 +313,9 @@ gst_audio_buffer_split_get_property (GObject * object, guint property_id, gst_value_set_fraction (value, self->output_buffer_duration_n, self->output_buffer_duration_d); break; + case PROP_OUTPUT_BUFFER_SIZE: + g_value_set_uint (value, self->output_buffer_size); + break; case PROP_ALIGNMENT_THRESHOLD: GST_OBJECT_LOCK (self); g_value_set_uint64 (value, diff --git a/gst/audiobuffersplit/gstaudiobuffersplit.h b/gst/audiobuffersplit/gstaudiobuffersplit.h index d902cbd09e..31fda864ad 100644 --- a/gst/audiobuffersplit/gstaudiobuffersplit.h +++ b/gst/audiobuffersplit/gstaudiobuffersplit.h @@ -45,6 +45,7 @@ struct _GstAudioBufferSplit { /* Properties */ gint output_buffer_duration_n; gint output_buffer_duration_d; + guint output_buffer_size; /* State */ GstSegment in_segment, out_segment;