From da1600eb61cc5d3007d5039e448220cdbc762b12 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 21 Jan 2021 09:43:16 +0100 Subject: [PATCH] bluetooth/gst: Determine PA input/output caps in generic code Make the code ever so slightly more generic by not using appsrc and appsink in codec-specific logic when assigning caps specific to the raw (PCM) format provided by or returned to PA. Note that caps have to be set (= event) after starting, can't send events in flushing state. Part-of: --- src/modules/bluetooth/a2dp-codec-aptx-gst.c | 19 -------- src/modules/bluetooth/a2dp-codec-gst.c | 53 +++++++++++++++++++++ src/modules/bluetooth/a2dp-codec-ldac-gst.c | 11 ----- 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/modules/bluetooth/a2dp-codec-aptx-gst.c b/src/modules/bluetooth/a2dp-codec-aptx-gst.c index cdf92f7d9..82cbc2c9f 100644 --- a/src/modules/bluetooth/a2dp-codec-aptx-gst.c +++ b/src/modules/bluetooth/a2dp-codec-aptx-gst.c @@ -342,16 +342,6 @@ bool gst_init_aptx(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) goto fail; } - caps = gst_caps_new_simple("audio/x-raw", - "format", G_TYPE_STRING, "S24LE", - "rate", G_TYPE_INT, (int) ss->rate, - "channels", G_TYPE_INT, (int) ss->channels, - "channel-mask", G_TYPE_INT, 0, - "layout", G_TYPE_STRING, "interleaved", - NULL); - g_object_set(info->enc_src, "caps", caps, NULL); - gst_caps_unref(caps); - caps = gst_caps_new_simple(aptx_codec_media_type, "rate", G_TYPE_INT, (int) ss->rate, "channels", G_TYPE_INT, (int) ss->channels, @@ -386,15 +376,6 @@ bool gst_init_aptx(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) g_object_set(info->dec_src, "caps", caps, NULL); gst_caps_unref(caps); - caps = gst_caps_new_simple("audio/x-raw", - "format", G_TYPE_STRING, "S24LE", - "rate", G_TYPE_INT, (int) ss->rate, - "channels", G_TYPE_INT, (int) ss->channels, - "layout", G_TYPE_STRING, "interleaved", - NULL); - g_object_set(info->dec_sink, "caps", caps, NULL); - gst_caps_unref(caps); - info->dec_bin = gst_bin_new("aptx_dec_bin"); pa_assert(info->dec_bin); diff --git a/src/modules/bluetooth/a2dp-codec-gst.c b/src/modules/bluetooth/a2dp-codec-gst.c index 930484ee3..d6db11711 100644 --- a/src/modules/bluetooth/a2dp-codec-gst.c +++ b/src/modules/bluetooth/a2dp-codec-gst.c @@ -306,13 +306,63 @@ static GstPadProbeReturn gst_decoder_buffer_probe(GstPad *pad, GstPadProbeInfo * return GST_PAD_PROBE_OK; } +static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) { + gchar *sample_format; + GstCaps *caps; + int channel_mask; + + switch (ss->format) { + case PA_SAMPLE_S16LE: + sample_format = "S16LE"; + break; + case PA_SAMPLE_S24LE: + sample_format = "S24LE"; + break; + case PA_SAMPLE_S32LE: + sample_format = "S32LE"; + break; + default: + pa_assert_not_reached(); + break; + } + + switch (ss->channels) { + case 1: + channel_mask = 0x1; + break; + case 2: + channel_mask = 0x3; + break; + default: + pa_assert_not_reached(); + break; + } + + caps = gst_caps_new_simple("audio/x-raw", + "format", G_TYPE_STRING, sample_format, + "rate", G_TYPE_INT, (int) ss->rate, + "channels", G_TYPE_INT, (int) ss->channels, + "channel-mask", GST_TYPE_BITMASK, channel_mask, + "layout", G_TYPE_STRING, "interleaved", + NULL); + + pa_assert(caps); + return caps; +} + bool gst_codec_init(struct gst_info *info, bool for_encoding) { GstPad *pad; + GstCaps *caps; info->seq_num = 0; + caps = gst_create_caps_from_sample_spec(info->ss); + /* In case if we ever have a codec which supports decoding but not encoding */ if (for_encoding && info->enc_bin) { + g_object_set(info->enc_src, "caps", caps, NULL); + gst_caps_unref(caps); + gst_bin_add_many(GST_BIN(info->enc_pipeline), info->enc_src, info->enc_bin, info->enc_sink, NULL); if (!gst_element_link_many(info->enc_src, info->enc_bin, info->enc_sink, NULL)) { @@ -330,6 +380,9 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding) { gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, gst_encoder_buffer_probe, info, NULL); gst_object_unref(pad); } else if (!for_encoding && info->dec_bin) { + g_object_set(info->dec_sink, "caps", caps, NULL); + gst_caps_unref(caps); + gst_bin_add_many(GST_BIN(info->dec_pipeline), info->dec_src, info->dec_bin, info->dec_sink, NULL); if (!gst_element_link_many(info->dec_src, info->dec_bin, info->dec_sink, NULL)) { diff --git a/src/modules/bluetooth/a2dp-codec-ldac-gst.c b/src/modules/bluetooth/a2dp-codec-ldac-gst.c index 45fe0f078..58dce9e4d 100644 --- a/src/modules/bluetooth/a2dp-codec-ldac-gst.c +++ b/src/modules/bluetooth/a2dp-codec-ldac-gst.c @@ -201,7 +201,6 @@ static uint8_t fill_preferred_configuration(const pa_sample_spec *default_sample bool gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) { GstElement *rtpldacpay; GstElement *enc; - GstCaps *caps; GstPad *pad; if (!for_encoding) { @@ -264,16 +263,6 @@ bool gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) goto fail; } - caps = gst_caps_new_simple("audio/x-raw", - "format", G_TYPE_STRING, "S32LE", - "rate", G_TYPE_INT, (int) ss->rate, - "channels", G_TYPE_INT, (int) ss->channels, - "channel-mask", G_TYPE_INT, 0, - "layout", G_TYPE_STRING, "interleaved", - NULL); - g_object_set(info->enc_src, "caps", caps, NULL); - gst_caps_unref(caps); - rtpldacpay = gst_element_factory_make("rtpldacpay", "rtp_ldac_pay"); if (!rtpldacpay) { pa_log_error("Could not create RTP LDAC payloader element");