bluetooth/gst: Move common enc/dec initialization back to generic init
authorMarijn Suijten <marijns95@gmail.com>
Fri, 22 Jan 2021 09:55:02 +0000 (10:55 +0100)
committerMarijn Suijten <marijns95@gmail.com>
Fri, 22 Jan 2021 10:04:19 +0000 (11:04 +0100)
Now that codec-specific code only touches its own bin and not any
elements (appsink/src) outside of it, make things official by
initializng them later in gst_codec_init where they are actually needed.

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/484>

src/modules/bluetooth/a2dp-codec-aptx-gst.c
src/modules/bluetooth/a2dp-codec-gst.c
src/modules/bluetooth/a2dp-codec-gst.h
src/modules/bluetooth/a2dp-codec-ldac-gst.c

index 2b8d3af..e94eee6 100644 (file)
@@ -425,33 +425,14 @@ static void *init_common(enum a2dp_codec_type codec_type, bool for_encoding, boo
     } else
         pa_assert_not_reached();
 
-    /*
-     * The common encoder/decoder initialisation functions need to be called
-     * before the codec specific ones, as the codec specific initialisation
-     * function needs to set the caps specific property appropriately on the
-     * appsrc and appsink as per the sample spec and the codec.
-     */
-    if (for_encoding) {
-        if (!gst_init_enc_common(info))
-            goto fail;
-    } else {
-        if (!gst_init_dec_common(info))
-            goto fail;
-    }
-
     if (!gst_init_aptx(info, sample_spec, for_encoding))
-        goto enc_dec_fail;
+        goto fail;
 
     if (!gst_codec_init(info, for_encoding))
-        goto enc_dec_fail;
+        goto fail;
 
     return info;
 
-enc_dec_fail:
-    if (for_encoding)
-        gst_deinit_enc_common(info);
-    else
-        gst_deinit_dec_common(info);
 fail:
     if (info)
         pa_xfree(info);
index d6db117..bbc5984 100644 (file)
@@ -82,7 +82,7 @@ static GstFlowReturn dec_sink_new_sample(GstAppSink *appsink, gpointer userdata)
     return GST_FLOW_OK;
 }
 
-void gst_deinit_enc_common(struct gst_info *info) {
+static void gst_deinit_enc_common(struct gst_info *info) {
     if (!info)
         return;
     if (info->enc_fdsem)
@@ -97,7 +97,7 @@ void gst_deinit_enc_common(struct gst_info *info) {
         gst_object_unref(info->enc_pipeline);
 }
 
-void gst_deinit_dec_common(struct gst_info *info) {
+static void gst_deinit_dec_common(struct gst_info *info) {
     if (!info)
         return;
     if (info->dec_fdsem)
@@ -356,10 +356,20 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding) {
 
     info->seq_num = 0;
 
+    if (for_encoding) {
+        if (!gst_init_enc_common(info))
+            goto fail_common;
+    } else {
+        if (!gst_init_dec_common(info))
+            goto fail_common;
+    }
+
     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) {
+    if (for_encoding) {
+        pa_assert(info->enc_bin);
+
         g_object_set(info->enc_src, "caps", caps, NULL);
         gst_caps_unref(caps);
 
@@ -379,7 +389,9 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding) {
         pad = gst_element_get_static_pad(info->enc_bin, "sink");
         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) {
+    } else {
+        pa_assert(info->dec_bin);
+
         g_object_set(info->dec_sink, "caps", caps, NULL);
         gst_caps_unref(caps);
 
@@ -399,10 +411,9 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding) {
         pad = gst_element_get_static_pad(info->dec_bin, "sink");
         gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, gst_decoder_buffer_probe, info, NULL);
         gst_object_unref(pad);
-    } else
-        pa_assert_not_reached();
+    }
 
-    pa_log_info("Gstreamer pipeline initialisation succeeded");
+    pa_log_info("GStreamer pipeline initialisation succeeded");
 
     return true;
 
@@ -412,7 +423,21 @@ enc_dec_fail:
     else
         gst_deinit_dec_common(info);
 
-    pa_log_error("Gstreamer pipeline initialisation failed");
+    pa_log_error("GStreamer pipeline initialisation failed");
+
+    return false;
+
+fail_common:
+    /* If common initialization fails these have not had their ownership
+     * transferred to the pipeline yet.
+     */
+    if (for_encoding)
+        gst_object_unref(info->enc_bin);
+    else
+        gst_object_unref(info->dec_bin);
+
+
+    pa_log_error("GStreamer pipeline creation failed");
 
     return false;
 }
index 562c012..400a0d9 100644 (file)
@@ -59,8 +59,3 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding);
 size_t gst_encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed);
 size_t gst_decode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed);
 void gst_codec_deinit(void *codec_info);
-
-bool gst_init_enc_common(struct gst_info *info);
-bool gst_init_dec_common(struct gst_info *info);
-void gst_deinit_enc_common(struct gst_info *info);
-void gst_deinit_dec_common(struct gst_info *info);
index 58dce9e..d14a355 100644 (file)
@@ -297,6 +297,11 @@ fail:
 static void *init_common(enum a2dp_codec_type codec_type, bool for_encoding, bool for_backchannel, const uint8_t *config_buffer, uint8_t config_size, pa_sample_spec *sample_spec, pa_core *core) {
     struct gst_info *info = NULL;
 
+    if (!for_encoding) {
+        pa_log_error("LDAC decoder not supported");
+        return NULL;
+    }
+
     info = pa_xnew0(struct gst_info, 1);
     pa_assert(info);
 
@@ -307,25 +312,14 @@ static void *init_common(enum a2dp_codec_type codec_type, bool for_encoding, boo
     info->a2dp_codec_t.ldac_config = (const a2dp_ldac_t *) config_buffer;
     pa_assert(config_size == sizeof(*(info->a2dp_codec_t.ldac_config)));
 
-    /*
-     * The common encoder/decoder initialisation functions need to be called
-     * before the codec specific ones, as the codec specific initialisation
-     * function needs to set the caps specific property appropriately on the
-     * appsrc and appsink as per the sample spec and the codec.
-     */
-    if (!gst_init_enc_common(info))
-        goto fail;
-
     if (!gst_init_ldac(info, sample_spec, for_encoding))
-        goto enc_fail;
+        goto fail;
 
     if (!gst_codec_init(info, for_encoding))
-        goto enc_fail;
+        goto fail;
 
     return info;
 
-enc_fail:
-    gst_deinit_enc_common(info);
 fail:
     if (info)
         pa_xfree(info);