summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarijn Suijten <marijns95@gmail.com>2021-01-22 01:33:43 +0100
committerArun Raghavan <arun@asymptotic.io>2022-02-21 12:31:32 -0500
commit5f37914eb808d5e201530927fee3b42a2ece8a41 (patch)
tree9c5105e75dab8c2cba5608c7c9954989c481f282
parent201dc6542b8e0e720aa04edec2615f2be1f9e98c (diff)
downloadpulseaudio-5f37914eb808d5e201530927fee3b42a2ece8a41.tar.gz
bluetooth/gst: Replace buffer accumulation in adapter with direct pull
Bluetooth codecs should always have fixed in/output and are hence able to have their results directly read from the codec, instead of accumulating in a buffer asynchronously that is subsequently only read in the transcode callback. The Bluetooth backends calling encode/decode also expect these fixed buffer sizes. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/494>
-rw-r--r--src/modules/bluetooth/a2dp-codec-gst.c52
-rw-r--r--src/modules/bluetooth/a2dp-codec-gst.h1
2 files changed, 13 insertions, 40 deletions
diff --git a/src/modules/bluetooth/a2dp-codec-gst.c b/src/modules/bluetooth/a2dp-codec-gst.c
index 6b2404dc3..30a3d52f8 100644
--- a/src/modules/bluetooth/a2dp-codec-gst.c
+++ b/src/modules/bluetooth/a2dp-codec-gst.c
@@ -39,31 +39,11 @@ static void app_sink_eos(GstAppSink *appsink, gpointer userdata) {
pa_log_debug("Sink got EOS");
}
-/* Called from the GStreamer streaming thread */
-static GstFlowReturn app_sink_new_sample(GstAppSink *appsink, gpointer userdata) {
- struct gst_info *info = (struct gst_info *) userdata;
- GstSample *sample = NULL;
- GstBuffer *buf;
-
- sample = gst_app_sink_pull_sample(GST_APP_SINK(info->app_sink));
- if (!sample)
- return GST_FLOW_OK;
-
- buf = gst_sample_get_buffer(sample);
- gst_buffer_ref(buf);
- gst_adapter_push(info->sink_adapter, buf);
- gst_sample_unref(sample);
-
- return GST_FLOW_OK;
-}
-
static void gst_deinit_common(struct gst_info *info) {
if (!info)
return;
if (info->app_sink)
gst_object_unref(info->app_sink);
- if (info->sink_adapter)
- g_object_unref(info->sink_adapter);
if (info->bin)
gst_object_unref(info->bin);
}
@@ -71,7 +51,6 @@ static void gst_deinit_common(struct gst_info *info) {
bool gst_init_common(struct gst_info *info) {
GstElement *bin = NULL;
GstElement *appsink = NULL;
- GstAdapter *adapter;
GstAppSinkCallbacks callbacks = { 0, };
appsink = gst_element_factory_make("appsink", "app_sink");
@@ -82,17 +61,12 @@ bool gst_init_common(struct gst_info *info) {
g_object_set(appsink, "sync", FALSE, "async", FALSE, "enable-last-sample", FALSE, NULL);
callbacks.eos = app_sink_eos;
- callbacks.new_sample = app_sink_new_sample;
gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
- adapter = gst_adapter_new();
- pa_assert(adapter);
-
bin = gst_bin_new(NULL);
pa_assert(bin);
info->app_sink = appsink;
- info->sink_adapter = adapter;
info->bin = bin;
return true;
@@ -234,10 +208,11 @@ common_fail:
size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
struct gst_info *info = (struct gst_info *) codec_info;
- gsize available, transcoded;
+ gsize transcoded;
GstBuffer *in_buf;
GstFlowReturn ret;
size_t written = 0;
+ GstSample *sample;
pa_assert(info->pad_sink);
@@ -262,17 +237,19 @@ size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_
goto fail;
}
- available = gst_adapter_available(info->sink_adapter);
-
- if (available) {
- transcoded = PA_MIN(available, output_size);
-
- gst_adapter_copy(info->sink_adapter, output_buffer, 0, transcoded);
- gst_adapter_flush(info->sink_adapter, transcoded);
+ while ((sample = gst_app_sink_try_pull_sample(GST_APP_SINK(info->app_sink), 0))) {
+ in_buf = gst_sample_get_buffer(sample);
+ transcoded = gst_buffer_get_size(in_buf);
written += transcoded;
- } else
- pa_log_debug("No transcoded data available in adapter");
+ pa_assert(written <= output_size);
+
+ GstMapInfo map_info;
+ pa_assert_se(gst_buffer_map(in_buf, &map_info, GST_MAP_READ));
+ memcpy(output_buffer, map_info.data, transcoded);
+ gst_buffer_unmap(in_buf, &map_info);
+ gst_sample_unref(sample);
+ }
*processed = input_size;
@@ -292,9 +269,6 @@ void gst_codec_deinit(void *codec_info) {
gst_object_unref(info->bin);
}
- if (info->sink_adapter)
- g_object_unref(info->sink_adapter);
-
if (info->pad_sink)
gst_object_unref(GST_OBJECT(info->pad_sink));
diff --git a/src/modules/bluetooth/a2dp-codec-gst.h b/src/modules/bluetooth/a2dp-codec-gst.h
index dfc784546..0928a8432 100644
--- a/src/modules/bluetooth/a2dp-codec-gst.h
+++ b/src/modules/bluetooth/a2dp-codec-gst.h
@@ -46,7 +46,6 @@ struct gst_info {
/* The appsink element that accumulates encoded/decoded buffers */
GstElement *app_sink;
GstElement *bin;
- GstAdapter *sink_adapter;
/* The sink pad to push to-be-encoded/decoded buffers into */
GstPad *pad_sink;