mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
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>
This commit is contained in:
parent
201dc6542b
commit
5f37914eb8
2 changed files with 13 additions and 40 deletions
|
|
@ -39,31 +39,11 @@ static void app_sink_eos(GstAppSink *appsink, gpointer userdata) {
|
||||||
pa_log_debug("Sink got EOS");
|
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) {
|
static void gst_deinit_common(struct gst_info *info) {
|
||||||
if (!info)
|
if (!info)
|
||||||
return;
|
return;
|
||||||
if (info->app_sink)
|
if (info->app_sink)
|
||||||
gst_object_unref(info->app_sink);
|
gst_object_unref(info->app_sink);
|
||||||
if (info->sink_adapter)
|
|
||||||
g_object_unref(info->sink_adapter);
|
|
||||||
if (info->bin)
|
if (info->bin)
|
||||||
gst_object_unref(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) {
|
bool gst_init_common(struct gst_info *info) {
|
||||||
GstElement *bin = NULL;
|
GstElement *bin = NULL;
|
||||||
GstElement *appsink = NULL;
|
GstElement *appsink = NULL;
|
||||||
GstAdapter *adapter;
|
|
||||||
GstAppSinkCallbacks callbacks = { 0, };
|
GstAppSinkCallbacks callbacks = { 0, };
|
||||||
|
|
||||||
appsink = gst_element_factory_make("appsink", "app_sink");
|
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);
|
g_object_set(appsink, "sync", FALSE, "async", FALSE, "enable-last-sample", FALSE, NULL);
|
||||||
|
|
||||||
callbacks.eos = app_sink_eos;
|
callbacks.eos = app_sink_eos;
|
||||||
callbacks.new_sample = app_sink_new_sample;
|
|
||||||
gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
|
gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
|
||||||
|
|
||||||
adapter = gst_adapter_new();
|
|
||||||
pa_assert(adapter);
|
|
||||||
|
|
||||||
bin = gst_bin_new(NULL);
|
bin = gst_bin_new(NULL);
|
||||||
pa_assert(bin);
|
pa_assert(bin);
|
||||||
|
|
||||||
info->app_sink = appsink;
|
info->app_sink = appsink;
|
||||||
info->sink_adapter = adapter;
|
|
||||||
info->bin = bin;
|
info->bin = bin;
|
||||||
|
|
||||||
return true;
|
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) {
|
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;
|
struct gst_info *info = (struct gst_info *) codec_info;
|
||||||
gsize available, transcoded;
|
gsize transcoded;
|
||||||
GstBuffer *in_buf;
|
GstBuffer *in_buf;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
GstSample *sample;
|
||||||
|
|
||||||
pa_assert(info->pad_sink);
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
available = gst_adapter_available(info->sink_adapter);
|
while ((sample = gst_app_sink_try_pull_sample(GST_APP_SINK(info->app_sink), 0))) {
|
||||||
|
in_buf = gst_sample_get_buffer(sample);
|
||||||
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);
|
|
||||||
|
|
||||||
|
transcoded = gst_buffer_get_size(in_buf);
|
||||||
written += transcoded;
|
written += transcoded;
|
||||||
} else
|
pa_assert(written <= output_size);
|
||||||
pa_log_debug("No transcoded data available in adapter");
|
|
||||||
|
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;
|
*processed = input_size;
|
||||||
|
|
||||||
|
|
@ -292,9 +269,6 @@ void gst_codec_deinit(void *codec_info) {
|
||||||
gst_object_unref(info->bin);
|
gst_object_unref(info->bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->sink_adapter)
|
|
||||||
g_object_unref(info->sink_adapter);
|
|
||||||
|
|
||||||
if (info->pad_sink)
|
if (info->pad_sink)
|
||||||
gst_object_unref(GST_OBJECT(info->pad_sink));
|
gst_object_unref(GST_OBJECT(info->pad_sink));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ struct gst_info {
|
||||||
/* The appsink element that accumulates encoded/decoded buffers */
|
/* The appsink element that accumulates encoded/decoded buffers */
|
||||||
GstElement *app_sink;
|
GstElement *app_sink;
|
||||||
GstElement *bin;
|
GstElement *bin;
|
||||||
GstAdapter *sink_adapter;
|
|
||||||
/* The sink pad to push to-be-encoded/decoded buffers into */
|
/* The sink pad to push to-be-encoded/decoded buffers into */
|
||||||
GstPad *pad_sink;
|
GstPad *pad_sink;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue