summaryrefslogtreecommitdiff
path: root/ext/webrtcdsp
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2018-02-19 18:30:13 +0200
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2018-08-03 13:20:12 +0300
commitd299c27892b9eff24df7107f979e93856c06672a (patch)
treea1695dbe9acdb0da03a18106221a84ea2a061e4f /ext/webrtcdsp
parent0591bc934a227d1c269b406c365178f77a8434f0 (diff)
webrtcdsp: add support for using F32/non-interleaved buffers
This is the native format that is in use by the webrtc audio processing library internally, so this avoids internal {de,}interleaving and format conversion (S16->F32 and back) https://bugzilla.gnome.org/show_bug.cgi?id=793605
Diffstat (limited to 'ext/webrtcdsp')
-rw-r--r--ext/webrtcdsp/Makefile.am3
-rw-r--r--ext/webrtcdsp/gstwebrtcdsp.cpp131
-rw-r--r--ext/webrtcdsp/gstwebrtcdsp.h3
-rw-r--r--ext/webrtcdsp/gstwebrtcechoprobe.cpp157
-rw-r--r--ext/webrtcdsp/gstwebrtcechoprobe.h8
-rw-r--r--ext/webrtcdsp/meson.build2
6 files changed, 247 insertions, 57 deletions
diff --git a/ext/webrtcdsp/Makefile.am b/ext/webrtcdsp/Makefile.am
index 63ebb45a4..16e829ccd 100644
--- a/ext/webrtcdsp/Makefile.am
+++ b/ext/webrtcdsp/Makefile.am
@@ -6,9 +6,12 @@ libgstwebrtcdsp_la_CXXFLAGS = \
$(GST_CXXFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS) \
+ -I$(top_srcdir)/gst-libs \
+ -I$(top_builddir)/gst-libs \
$(WEBRTCDSP_CFLAGS)
libgstwebrtcdsp_la_LIBADD = \
-lgstaudio-$(GST_API_VERSION) \
+ $(top_builddir)/gst-libs/gst/audio/libgstbadaudio-$(GST_API_VERSION).la \
$(GST_LIBS) $(GST_BASE_LIBS) \
$(GST_PLUGINS_BASE_LIBS) \
$(WEBRTCDSP_LIBS)
diff --git a/ext/webrtcdsp/gstwebrtcdsp.cpp b/ext/webrtcdsp/gstwebrtcdsp.cpp
index c92072ae2..9d7c8d2a3 100644
--- a/ext/webrtcdsp/gstwebrtcdsp.cpp
+++ b/ext/webrtcdsp/gstwebrtcdsp.cpp
@@ -95,6 +95,11 @@ GST_STATIC_PAD_TEMPLATE ("sink",
"format = (string) " GST_AUDIO_NE (S16) ", "
"layout = (string) interleaved, "
"rate = (int) { 48000, 32000, 16000, 8000 }, "
+ "channels = (int) [1, MAX];"
+ "audio/x-raw, "
+ "format = (string) " GST_AUDIO_NE (F32) ", "
+ "layout = (string) non-interleaved, "
+ "rate = (int) { 48000, 32000, 16000, 8000 }, "
"channels = (int) [1, MAX]")
);
@@ -106,6 +111,11 @@ GST_STATIC_PAD_TEMPLATE ("src",
"format = (string) " GST_AUDIO_NE (S16) ", "
"layout = (string) interleaved, "
"rate = (int) { 48000, 32000, 16000, 8000 }, "
+ "channels = (int) [1, MAX];"
+ "audio/x-raw, "
+ "format = (string) " GST_AUDIO_NE (F32) ", "
+ "layout = (string) non-interleaved, "
+ "rate = (int) { 48000, 32000, 16000, 8000 }, "
"channels = (int) [1, MAX]")
);
@@ -230,11 +240,14 @@ struct _GstWebrtcDsp
/* Protected by the object lock */
GstAudioInfo info;
+ gboolean interleaved;
guint period_size;
+ guint period_samples;
gboolean stream_has_voice;
/* Protected by the stream lock */
GstAdapter *adapter;
+ GstPlanarAudioAdapter *padapter;
webrtc::AudioProcessing * apm;
/* Protected by the object lock */
@@ -321,20 +334,35 @@ gst_webrtc_dsp_take_buffer (GstWebrtcDsp * self)
GstBuffer *buffer;
GstClockTime timestamp;
guint64 distance;
+ gboolean at_discont;
- timestamp = gst_adapter_prev_pts (self->adapter, &distance);
- timestamp += gst_util_uint64_scale_int (distance / self->info.bpf,
- GST_SECOND, self->info.rate);
+ if (self->interleaved) {
+ timestamp = gst_adapter_prev_pts (self->adapter, &distance);
+ distance /= self->info.bpf;
+ } else {
+ timestamp = gst_planar_audio_adapter_prev_pts (self->padapter, &distance);
+ }
- buffer = gst_adapter_take_buffer (self->adapter, self->period_size);
+ timestamp += gst_util_uint64_scale_int (distance, GST_SECOND, self->info.rate);
+
+ if (self->interleaved) {
+ buffer = gst_adapter_take_buffer (self->adapter, self->period_size);
+ at_discont = (gst_adapter_pts_at_discont (self->adapter) == timestamp);
+ } else {
+ buffer = gst_planar_audio_adapter_take_buffer (self->padapter,
+ self->period_samples, GST_MAP_READWRITE);
+ at_discont =
+ (gst_planar_audio_adapter_pts_at_discont (self->padapter) == timestamp);
+ }
GST_BUFFER_PTS (buffer) = timestamp;
GST_BUFFER_DURATION (buffer) = 10 * GST_MSECOND;
- if (gst_adapter_pts_at_discont (self->adapter) == timestamp && distance == 0) {
+ if (at_discont && distance == 0) {
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
- } else
+ } else {
GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
+ }
return buffer;
}
@@ -346,6 +374,7 @@ gst_webrtc_dsp_analyze_reverse_stream (GstWebrtcDsp * self,
GstWebrtcEchoProbe *probe = NULL;
webrtc::AudioProcessing * apm;
webrtc::AudioFrame frame;
+ GstBuffer *buf = NULL;
GstFlowReturn ret = GST_FLOW_OK;
gint err, delay;
@@ -364,7 +393,7 @@ gst_webrtc_dsp_analyze_reverse_stream (GstWebrtcDsp * self,
rec_time = GST_CLOCK_TIME_NONE;
again:
- delay = gst_webrtc_echo_probe_read (probe, rec_time, (gpointer) &frame);
+ delay = gst_webrtc_echo_probe_read (probe, rec_time, (gpointer) &frame, &buf);
apm->set_stream_delay_ms (delay);
if (delay < 0)
@@ -379,15 +408,31 @@ again:
goto done;
}
- if ((err = apm->AnalyzeReverseStream (&frame)) < 0)
- GST_WARNING_OBJECT (self, "Reverse stream analyses failed: %s.",
- webrtc_error_to_string (err));
+ if (buf) {
+ webrtc::StreamConfig config (frame.sample_rate_hz_, frame.num_channels_,
+ false);
+ GstAudioBuffer abuf;
+ float * const * data;
+
+ gst_audio_buffer_map (&abuf, &self->info, buf, GST_MAP_READWRITE);
+ data = (float * const *) abuf.planes;
+ if ((err = apm->ProcessReverseStream (data, config, config, data)) < 0)
+ GST_WARNING_OBJECT (self, "Reverse stream analyses failed: %s.",
+ webrtc_error_to_string (err));
+ gst_audio_buffer_unmap (&abuf);
+ gst_buffer_replace (&buf, NULL);
+ } else {
+ if ((err = apm->AnalyzeReverseStream (&frame)) < 0)
+ GST_WARNING_OBJECT (self, "Reverse stream analyses failed: %s.",
+ webrtc_error_to_string (err));
+ }
if (self->delay_agnostic)
goto again;
done:
gst_object_unref (probe);
+ gst_buffer_replace (&buf, NULL);
return ret;
}
@@ -418,23 +463,34 @@ static GstFlowReturn
gst_webrtc_dsp_process_stream (GstWebrtcDsp * self,
GstBuffer * buffer)
{
- GstMapInfo info;
+ GstAudioBuffer abuf;
webrtc::AudioProcessing * apm = self->apm;
- webrtc::AudioFrame frame;
gint err;
- frame.num_channels_ = self->info.channels;
- frame.sample_rate_hz_ = self->info.rate;
- frame.samples_per_channel_ = self->period_size / self->info.bpf;
-
- if (!gst_buffer_map (buffer, &info, (GstMapFlags) GST_MAP_READWRITE)) {
+ if (!gst_audio_buffer_map (&abuf, &self->info, buffer,
+ (GstMapFlags) GST_MAP_READWRITE)) {
gst_buffer_unref (buffer);
return GST_FLOW_ERROR;
}
- memcpy (frame.data_, info.data, self->period_size);
+ if (self->interleaved) {
+ webrtc::AudioFrame frame;
+ frame.num_channels_ = self->info.channels;
+ frame.sample_rate_hz_ = self->info.rate;
+ frame.samples_per_channel_ = self->period_samples;
+
+ memcpy (frame.data_, abuf.planes[0], self->period_size);
+ err = apm->ProcessStream (&frame);
+ if (err >= 0)
+ memcpy (abuf.planes[0], frame.data_, self->period_size);
+ } else {
+ float * const * data = (float * const *) abuf.planes;
+ webrtc::StreamConfig config (self->info.rate, self->info.channels, false);
+
+ err = apm->ProcessStream (data, config, config, data);
+ }
- if ((err = apm->ProcessStream (&frame)) < 0) {
+ if (err < 0) {
GST_WARNING_OBJECT (self, "Failed to filter the audio: %s.",
webrtc_error_to_string (err));
} else {
@@ -446,10 +502,9 @@ gst_webrtc_dsp_process_stream (GstWebrtcDsp * self,
self->stream_has_voice = stream_has_voice;
}
- memcpy (info.data, frame.data_, self->period_size);
}
- gst_buffer_unmap (buffer, &info);
+ gst_audio_buffer_unmap (&abuf);
return GST_FLOW_OK;
}
@@ -467,10 +522,16 @@ gst_webrtc_dsp_submit_input_buffer (GstBaseTransform * btrans,
if (is_discont) {
GST_DEBUG_OBJECT (self,
"Received discont, clearing adapter.");
- gst_adapter_clear (self->adapter);
+ if (self->interleaved)
+ gst_adapter_clear (self->adapter);
+ else
+ gst_planar_audio_adapter_clear (self->padapter);
}
- gst_adapter_push (self->adapter, buffer);
+ if (self->interleaved)
+ gst_adapter_push (self->adapter, buffer);
+ else
+ gst_planar_audio_adapter_push (self->padapter, buffer);
return GST_FLOW_OK;
}
@@ -480,8 +541,15 @@ gst_webrtc_dsp_generate_output (GstBaseTransform * btrans, GstBuffer ** outbuf)
{
GstWebrtcDsp *self = GST_WEBRTC_DSP (btrans);
GstFlowReturn ret;
+ gboolean not_enough;
+
+ if (self->interleaved)
+ not_enough = gst_adapter_available (self->adapter) < self->period_size;
+ else
+ not_enough = gst_planar_audio_adapter_available (self->padapter) <
+ self->period_samples;
- if (gst_adapter_available (self->adapter) < self->period_size) {
+ if (not_enough) {
*outbuf = NULL;
return GST_FLOW_OK;
}
@@ -545,13 +613,21 @@ gst_webrtc_dsp_setup (GstAudioFilter * filter, const GstAudioInfo * info)
GST_OBJECT_LOCK (self);
gst_adapter_clear (self->adapter);
+ gst_planar_audio_adapter_clear (self->padapter);
+
self->info = *info;
+ self->interleaved = (info->layout == GST_AUDIO_LAYOUT_INTERLEAVED);
apm = self->apm;
+ if (!self->interleaved)
+ gst_planar_audio_adapter_configure (self->padapter, info);
+
/* WebRTC library works with 10ms buffers, compute once this size */
- self->period_size = info->bpf * info->rate / 100;
+ self->period_samples = info->rate / 100;
+ self->period_size = self->period_samples * info->bpf;
- if ((webrtc::AudioFrame::kMaxDataSizeSamples * 2) < self->period_size)
+ if (self->interleaved &&
+ (webrtc::AudioFrame::kMaxDataSizeSamples * 2) < self->period_size)
goto period_too_big;
if (self->probe) {
@@ -676,6 +752,7 @@ gst_webrtc_dsp_stop (GstBaseTransform * btrans)
GST_OBJECT_LOCK (self);
gst_adapter_clear (self->adapter);
+ gst_planar_audio_adapter_clear (self->padapter);
if (self->probe) {
gst_webrtc_release_echo_probe (self->probe);
@@ -840,6 +917,7 @@ gst_webrtc_dsp_finalize (GObject * object)
GstWebrtcDsp *self = GST_WEBRTC_DSP (object);
gst_object_unref (self->adapter);
+ gst_object_unref (self->padapter);
g_free (self->probe_name);
G_OBJECT_CLASS (gst_webrtc_dsp_parent_class)->finalize (object);
@@ -849,6 +927,7 @@ static void
gst_webrtc_dsp_init (GstWebrtcDsp * self)
{
self->adapter = gst_adapter_new ();
+ self->padapter = gst_planar_audio_adapter_new ();
gst_audio_info_init (&self->info);
}
diff --git a/ext/webrtcdsp/gstwebrtcdsp.h b/ext/webrtcdsp/gstwebrtcdsp.h
index a2519dfac..e0e808f13 100644
--- a/ext/webrtcdsp/gstwebrtcdsp.h
+++ b/ext/webrtcdsp/gstwebrtcdsp.h
@@ -28,6 +28,9 @@
#include <gst/base/gstbasetransform.h>
#include <gst/audio/audio.h>
+#define GST_USE_UNSTABLE_API
+#include <gst/audio/gstplanaraudioadapter.h>
+
G_BEGIN_DECLS
#define GST_TYPE_WEBRTC_DSP (gst_webrtc_dsp_get_type())
diff --git a/ext/webrtcdsp/gstwebrtcechoprobe.cpp b/ext/webrtcdsp/gstwebrtcechoprobe.cpp
index a34fa5201..ad350e78b 100644
--- a/ext/webrtcdsp/gstwebrtcechoprobe.cpp
+++ b/ext/webrtcdsp/gstwebrtcechoprobe.cpp
@@ -49,6 +49,11 @@ GST_STATIC_PAD_TEMPLATE ("sink",
"format = (string) " GST_AUDIO_NE (S16) ", "
"layout = (string) interleaved, "
"rate = (int) { 48000, 32000, 16000, 8000 }, "
+ "channels = (int) [1, MAX];"
+ "audio/x-raw, "
+ "format = (string) " GST_AUDIO_NE (F32) ", "
+ "layout = (string) non-interleaved, "
+ "rate = (int) { 48000, 32000, 16000, 8000 }, "
"channels = (int) [1, MAX]")
);
@@ -60,6 +65,11 @@ GST_STATIC_PAD_TEMPLATE ("src",
"format = (string) " GST_AUDIO_NE (S16) ", "
"layout = (string) interleaved, "
"rate = (int) { 48000, 32000, 16000, 8000 }, "
+ "channels = (int) [1, MAX];"
+ "audio/x-raw, "
+ "format = (string) " GST_AUDIO_NE (F32) ", "
+ "layout = (string) non-interleaved, "
+ "rate = (int) { 48000, 32000, 16000, 8000 }, "
"channels = (int) [1, MAX]")
);
@@ -80,11 +90,17 @@ gst_webrtc_echo_probe_setup (GstAudioFilter * filter, const GstAudioInfo * info)
GST_WEBRTC_ECHO_PROBE_LOCK (self);
self->info = *info;
+ self->interleaved = (info->layout == GST_AUDIO_LAYOUT_INTERLEAVED);
+
+ if (!self->interleaved)
+ gst_planar_audio_adapter_configure (self->padapter, info);
/* WebRTC library works with 10ms buffers, compute once this size */
- self->period_size = info->bpf * info->rate / 100;
+ self->period_samples = info->rate / 100;
+ self->period_size = self->period_samples * info->bpf;
- if ((webrtc::AudioFrame::kMaxDataSizeSamples * 2) < self->period_size)
+ if (self->interleaved &&
+ (webrtc::AudioFrame::kMaxDataSizeSamples * 2) < self->period_size)
goto period_too_big;
GST_WEBRTC_ECHO_PROBE_UNLOCK (self);
@@ -107,6 +123,7 @@ gst_webrtc_echo_probe_stop (GstBaseTransform * btrans)
GST_WEBRTC_ECHO_PROBE_LOCK (self);
gst_adapter_clear (self->adapter);
+ gst_planar_audio_adapter_clear (self->padapter);
GST_WEBRTC_ECHO_PROBE_UNLOCK (self);
return TRUE;
@@ -163,11 +180,24 @@ gst_webrtc_echo_probe_transform_ip (GstBaseTransform * btrans,
/* Moves the buffer timestamp to be in Running time */
GST_BUFFER_PTS (newbuf) = gst_segment_to_running_time (&btrans->segment,
GST_FORMAT_TIME, GST_BUFFER_PTS (buffer));
- gst_adapter_push (self->adapter, newbuf);
- if (gst_adapter_available (self->adapter) > MAX_ADAPTER_SIZE)
- gst_adapter_flush (self->adapter,
- gst_adapter_available (self->adapter) - MAX_ADAPTER_SIZE);
+ if (self->interleaved) {
+ gst_adapter_push (self->adapter, newbuf);
+
+ if (gst_adapter_available (self->adapter) > MAX_ADAPTER_SIZE)
+ gst_adapter_flush (self->adapter,
+ gst_adapter_available (self->adapter) - MAX_ADAPTER_SIZE);
+ } else {
+ gsize available;
+
+ gst_planar_audio_adapter_push (self->padapter, newbuf);
+ available =
+ gst_planar_audio_adapter_available (self->padapter) * self->info.bpf;
+ if (available > MAX_ADAPTER_SIZE)
+ gst_planar_audio_adapter_flush (self->padapter,
+ (available - MAX_ADAPTER_SIZE) / self->info.bpf);
+ }
+
GST_WEBRTC_ECHO_PROBE_UNLOCK (self);
return GST_FLOW_OK;
@@ -183,7 +213,9 @@ gst_webrtc_echo_probe_finalize (GObject * object)
G_UNLOCK (gst_aec_probes);
gst_object_unref (self->adapter);
+ gst_object_unref (self->padapter);
self->adapter = NULL;
+ self->padapter = NULL;
G_OBJECT_CLASS (gst_webrtc_echo_probe_parent_class)->finalize (object);
}
@@ -192,6 +224,7 @@ static void
gst_webrtc_echo_probe_init (GstWebrtcEchoProbe * self)
{
self->adapter = gst_adapter_new ();
+ self->padapter = gst_planar_audio_adapter_new ();
gst_audio_info_init (&self->info);
g_mutex_init (&self->lock);
@@ -268,7 +301,7 @@ gst_webrtc_release_echo_probe (GstWebrtcEchoProbe * probe)
gint
gst_webrtc_echo_probe_read (GstWebrtcEchoProbe * self, GstClockTime rec_time,
- gpointer _frame)
+ gpointer _frame, GstBuffer ** buf)
{
webrtc::AudioFrame * frame = (webrtc::AudioFrame *) _frame;
GstClockTimeDiff diff;
@@ -281,31 +314,39 @@ gst_webrtc_echo_probe_read (GstWebrtcEchoProbe * self, GstClockTime rec_time,
!GST_AUDIO_INFO_IS_VALID (&self->info))
goto done;
+ if (self->interleaved)
+ avail = gst_adapter_available (self->adapter) / self->info.bpf;
+ else
+ avail = gst_planar_audio_adapter_available (self->padapter);
+
/* In delay agnostic mode, just return 10ms of data */
if (!GST_CLOCK_TIME_IS_VALID (rec_time)) {
- avail = gst_adapter_available (self->adapter);
-
- if (avail < self->period_size)
+ if (avail < self->period_samples)
goto done;
- size = self->period_size;
+ size = self->period_samples;
skip = 0;
offset = 0;
goto copy;
}
- if (gst_adapter_available (self->adapter) == 0) {
+ if (avail == 0) {
diff = G_MAXINT64;
} else {
GstClockTime play_time;
guint64 distance;
- play_time = gst_adapter_prev_pts (self->adapter, &distance);
+ if (self->interleaved) {
+ play_time = gst_adapter_prev_pts (self->adapter, &distance);
+ distance /= self->info.bpf;
+ } else {
+ play_time = gst_planar_audio_adapter_prev_pts (self->padapter, &distance);
+ }
if (GST_CLOCK_TIME_IS_VALID (play_time)) {
- play_time += gst_util_uint64_scale_int (distance / self->info.bpf,
- GST_SECOND, self->info.rate);
+ play_time += gst_util_uint64_scale_int (distance, GST_SECOND,
+ self->info.rate);
play_time += self->latency;
diff = GST_CLOCK_DIFF (rec_time, play_time) / GST_MSECOND;
@@ -315,33 +356,91 @@ gst_webrtc_echo_probe_read (GstWebrtcEchoProbe * self, GstClockTime rec_time,
}
}
- avail = gst_adapter_available (self->adapter);
-
if (diff > self->delay) {
- skip = (diff - self->delay) * self->info.rate / 1000 * self->info.bpf;
- skip = MIN (self->period_size, skip);
+ skip = (diff - self->delay) * self->info.rate / 1000;
+ skip = MIN (self->period_samples, skip);
offset = 0;
} else {
skip = 0;
- offset = (self->delay - diff) * self->info.rate / 1000 * self->info.bpf;
+ offset = (self->delay - diff) * self->info.rate / 1000;
offset = MIN (avail, offset);
}
- size = MIN (avail - offset, self->period_size - skip);
-
- if (size < self->period_size)
- memset (frame->data_, 0, self->period_size);
+ size = MIN (avail - offset, self->period_samples - skip);
copy:
- if (size) {
- gst_adapter_copy (self->adapter, (guint8 *) frame->data_ + skip,
- offset, size);
- gst_adapter_flush (self->adapter, offset + size);
+ if (self->interleaved) {
+ skip *= self->info.bpf;
+ offset *= self->info.bpf;
+ size *= self->info.bpf;
+
+ if (size < self->period_size)
+ memset (frame->data_, 0, self->period_size);
+
+ if (size) {
+ gst_adapter_copy (self->adapter, (guint8 *) frame->data_ + skip,
+ offset, size);
+ gst_adapter_flush (self->adapter, offset + size);
+ }
+ } else {
+ GstBuffer *ret, *taken, *tmp;
+
+ if (size) {
+ gst_planar_audio_adapter_flush (self->padapter, offset);
+
+ /* we need to fill silence at the beginning and/or the end of each
+ * channel plane in order to have exactly period_samples in the buffer */
+ if (size < self->period_samples) {
+ GstAudioMeta *meta;
+ gint bps = self->info.finfo->width / 8;
+ gsize padding = self->period_samples - (skip + size);
+ gint c;
+
+ taken = gst_planar_audio_adapter_take_buffer (self->padapter, size,
+ GST_MAP_READ);
+ meta = gst_buffer_get_audio_meta (taken);
+ ret = gst_buffer_new ();
+
+ for (c = 0; c < meta->info.channels; c++) {
+ /* need some silence at the beginning */
+ if (skip) {
+ tmp = gst_buffer_new_allocate (NULL, skip * bps, NULL);
+ gst_buffer_memset (tmp, 0, 0, skip * bps);
+ ret = gst_buffer_append (ret, tmp);
+ }
+
+ tmp = gst_buffer_copy_region (taken, GST_BUFFER_COPY_MEMORY,
+ meta->offsets[c], size * bps);
+ ret = gst_buffer_append (ret, tmp);
+
+ /* need some silence at the end */
+ if (padding) {
+ tmp = gst_buffer_new_allocate (NULL, padding * bps, NULL);
+ gst_buffer_memset (tmp, 0, 0, padding * bps);
+ ret = gst_buffer_append (ret, tmp);
+ }
+ }
+
+ gst_buffer_unref (taken);
+ gst_buffer_add_audio_meta (ret, &self->info, self->period_samples,
+ NULL);
+ } else {
+ ret = gst_planar_audio_adapter_take_buffer (self->padapter, size,
+ GST_MAP_READWRITE);
+ }
+ } else {
+ ret = gst_buffer_new_allocate (NULL, self->period_size, NULL);
+ gst_buffer_memset (ret, 0, 0, self->period_size);
+ gst_buffer_add_audio_meta (ret, &self->info, self->period_samples,
+ NULL);
+ }
+
+ *buf = ret;
}
frame->num_channels_ = self->info.channels;
frame->sample_rate_hz_ = self->info.rate;
- frame->samples_per_channel_ = self->period_size / self->info.bpf;
+ frame->samples_per_channel_ = self->period_samples;
delay = self->delay;
diff --git a/ext/webrtcdsp/gstwebrtcechoprobe.h b/ext/webrtcdsp/gstwebrtcechoprobe.h
index 7c8a24022..a8a889907 100644
--- a/ext/webrtcdsp/gstwebrtcechoprobe.h
+++ b/ext/webrtcdsp/gstwebrtcechoprobe.h
@@ -28,6 +28,9 @@
#include <gst/base/gstbasetransform.h>
#include <gst/audio/audio.h>
+#define GST_USE_UNSTABLE_API
+#include <gst/audio/gstplanaraudioadapter.h>
+
G_BEGIN_DECLS
#define GST_TYPE_WEBRTC_ECHO_PROBE (gst_webrtc_echo_probe_get_type())
@@ -62,11 +65,14 @@ struct _GstWebrtcEchoProbe
/* Protected by the lock */
GstAudioInfo info;
guint period_size;
+ guint period_samples;
GstClockTime latency;
gint delay;
+ gboolean interleaved;
GstSegment segment;
GstAdapter *adapter;
+ GstPlanarAudioAdapter *padapter;
/* Private */
gboolean acquired;
@@ -82,7 +88,7 @@ GType gst_webrtc_echo_probe_get_type (void);
GstWebrtcEchoProbe *gst_webrtc_acquire_echo_probe (const gchar * name);
void gst_webrtc_release_echo_probe (GstWebrtcEchoProbe * probe);
gint gst_webrtc_echo_probe_read (GstWebrtcEchoProbe * self,
- GstClockTime rec_time, gpointer frame);
+ GstClockTime rec_time, gpointer frame, GstBuffer ** buf);
G_END_DECLS
#endif /* __GST_WEBRTC_ECHO_PROBE_H__ */
diff --git a/ext/webrtcdsp/meson.build b/ext/webrtcdsp/meson.build
index 9d02a7faf..678d128bd 100644
--- a/ext/webrtcdsp/meson.build
+++ b/ext/webrtcdsp/meson.build
@@ -12,7 +12,7 @@ if webrtc_dep.found()
cpp_args : gst_plugins_bad_args,
link_args : noseh_link_args,
include_directories : [configinc],
- dependencies : [gstbase_dep, gstaudio_dep, webrtc_dep],
+ dependencies : [gstbase_dep, gstaudio_dep, gstbadaudio_dep, webrtc_dep],
install : true,
install_dir : plugins_install_dir,
)