From 8b52e44836fc28fe23943f86a5f539cc105e9077 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 11 Dec 2020 13:30:11 +0100 Subject: [PATCH] bluez5: support other ldac bit depth Make the format_info const in codec_init, we just need to read the final negotiated format in some cases. Add some more ldac bit depths we support. --- spa/plugins/bluez5/a2dp-codec-aac.c | 6 +-- spa/plugins/bluez5/a2dp-codec-aptx.c | 55 +++------------------ spa/plugins/bluez5/a2dp-codec-ldac.c | 73 +++++++++++++--------------- spa/plugins/bluez5/a2dp-codec-sbc.c | 30 +++--------- spa/plugins/bluez5/a2dp-codecs.h | 2 +- 5 files changed, 50 insertions(+), 116 deletions(-) diff --git a/spa/plugins/bluez5/a2dp-codec-aac.c b/spa/plugins/bluez5/a2dp-codec-aac.c index e25d36ef9..33b3601a3 100644 --- a/spa/plugins/bluez5/a2dp-codec-aac.c +++ b/spa/plugins/bluez5/a2dp-codec-aac.c @@ -140,7 +140,7 @@ static int codec_select_config(const struct a2dp_codec *codec, uint32_t flags, } static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, - void *config, size_t config_len, struct spa_audio_info *info, size_t mtu) + void *config, size_t config_len, const struct spa_audio_info *info, size_t mtu) { struct impl *this; int res; @@ -150,10 +150,6 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, res = -errno; goto error; } - - spa_zero(*info); - info->media_type = SPA_MEDIA_TYPE_audio; - info->media_subtype = SPA_MEDIA_SUBTYPE_aac; this->mtu = mtu; return this; diff --git a/spa/plugins/bluez5/a2dp-codec-aptx.c b/spa/plugins/bluez5/a2dp-codec-aptx.c index b151899fd..dbbec11f1 100644 --- a/spa/plugins/bluez5/a2dp-codec-aptx.c +++ b/spa/plugins/bluez5/a2dp-codec-aptx.c @@ -202,10 +202,9 @@ static int codec_get_block_size(void *data) } static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, - void *config, size_t config_len, struct spa_audio_info *info, size_t mtu) + void *config, size_t config_len, const struct spa_audio_info *info, size_t mtu) { struct impl *this; - a2dp_aptx_t *conf = config; int res, hd; if ((this = calloc(1, sizeof(struct impl))) == NULL) @@ -218,54 +217,12 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, this->mtu = mtu; - spa_zero(*info); - info->media_type = SPA_MEDIA_TYPE_audio; - info->media_subtype = SPA_MEDIA_SUBTYPE_raw; - info->info.raw.format = SPA_AUDIO_FORMAT_S16; - - switch (conf->frequency) { - case APTX_SAMPLING_FREQ_16000: - info->info.raw.rate = 16000; - break; - case APTX_SAMPLING_FREQ_32000: - info->info.raw.rate = 32000; - break; - case APTX_SAMPLING_FREQ_44100: - info->info.raw.rate = 44100; - break; - case APTX_SAMPLING_FREQ_48000: - info->info.raw.rate = 48000; - break; - default: + if (info->media_type != SPA_MEDIA_TYPE_audio || + info->media_subtype != SPA_MEDIA_SUBTYPE_raw || + info->info.raw.format != SPA_AUDIO_FORMAT_S16) { res = -EINVAL; - goto error; - } - - switch (conf->channel_mode) { - case APTX_CHANNEL_MODE_MONO: - info->info.raw.channels = 1; - break; - case APTX_CHANNEL_MODE_STEREO: - info->info.raw.channels = 2; - break; - default: - res = -EINVAL; - goto error; - } - - switch (info->info.raw.channels) { - case 1: - info->info.raw.position[0] = SPA_AUDIO_CHANNEL_MONO; - break; - case 2: - info->info.raw.position[0] = SPA_AUDIO_CHANNEL_FL; - info->info.raw.position[1] = SPA_AUDIO_CHANNEL_FR; - break; - default: - res = -EINVAL; - goto error; + goto error; } - this->frame_length = hd ? 6 : 4; this->codesize = 4 * 3 * 2; @@ -275,6 +232,8 @@ error_errno: res = -errno; goto error; error: + if (this->aptx) + aptx_finish(this->aptx); free(this); errno = -res; return NULL; diff --git a/spa/plugins/bluez5/a2dp-codec-ldac.c b/spa/plugins/bluez5/a2dp-codec-ldac.c index 95e789900..eae382f79 100644 --- a/spa/plugins/bluez5/a2dp-codec-ldac.c +++ b/spa/plugins/bluez5/a2dp-codec-ldac.c @@ -45,10 +45,8 @@ struct impl { int mtu; int eqmid; - int channel_mode; int frequency; int fmt; - int lsu; int codesize; int frame_length; }; @@ -130,7 +128,12 @@ static int codec_enum_config(const struct a2dp_codec *codec, spa_pod_builder_add(b, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_S16), + SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(5, + SPA_AUDIO_FORMAT_F32, + SPA_AUDIO_FORMAT_F32, + SPA_AUDIO_FORMAT_S32, + SPA_AUDIO_FORMAT_S24, + SPA_AUDIO_FORMAT_S16), 0); spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_rate, 0); @@ -240,7 +243,7 @@ static int codec_get_block_size(void *data) } static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, - void *config, size_t config_len, struct spa_audio_info *info, size_t mtu) + void *config, size_t config_len, const struct spa_audio_info *info, size_t mtu) { struct impl *this; a2dp_ldac_t *conf = config; @@ -255,64 +258,56 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, goto error_errno; this->eqmid = LDACBT_EQMID_SQ; + this->mtu = mtu; + this->frequency = info->info.raw.rate; + this->codesize = info->info.raw.channels; - spa_zero(*info); - info->media_type = SPA_MEDIA_TYPE_audio; - info->media_subtype = SPA_MEDIA_SUBTYPE_raw; - info->info.raw.format = SPA_AUDIO_FORMAT_S16; - this->fmt = LDACBT_SMPL_FMT_S16; - this->mtu =mtu; + switch (info->info.raw.format) { + case SPA_AUDIO_FORMAT_F32: + this->fmt = LDACBT_SMPL_FMT_F32; + this->codesize *= 4; + break; + case SPA_AUDIO_FORMAT_S32: + this->fmt = LDACBT_SMPL_FMT_S32; + this->codesize *= 4; + break; + case SPA_AUDIO_FORMAT_S24: + this->fmt = LDACBT_SMPL_FMT_S24; + this->codesize *= 3; + break; + case SPA_AUDIO_FORMAT_S16: + this->fmt = LDACBT_SMPL_FMT_S16; + this->codesize *= 2; + break; + default: + res = -EINVAL; + goto error; + } switch(conf->frequency) { case LDACBT_SAMPLING_FREQ_044100: - info->info.raw.rate = 44100; - this->lsu = 128; - break; case LDACBT_SAMPLING_FREQ_048000: - info->info.raw.rate = 48000; - this->lsu = 128; + this->codesize *= 128; break; case LDACBT_SAMPLING_FREQ_088200: - info->info.raw.rate = 88200; - this->lsu = 256; - break; case LDACBT_SAMPLING_FREQ_096000: - info->info.raw.rate = 96000; - this->lsu = 256; + this->codesize *= 256; break; default: res = -EINVAL; goto error; } - this->frequency = info->info.raw.rate; - - switch(conf->channel_mode) { - case LDACBT_CHANNEL_MODE_STEREO: - info->info.raw.channels = 2; - break; - case LDACBT_CHANNEL_MODE_DUAL_CHANNEL: - info->info.raw.channels = 2; - break; - case LDACBT_CHANNEL_MODE_MONO: - info->info.raw.channels = 1; - break; - default: - res = -EINVAL; - goto error; - } - this->channel_mode = conf->channel_mode; res = ldacBT_init_handle_encode(this->ldac, this->mtu, this->eqmid, - this->channel_mode, + conf->channel_mode, this->fmt, this->frequency); if (res < 0) goto error; this->frame_length = get_frame_length(this); - this->codesize = this->lsu * info->info.raw.channels * 2; return this; diff --git a/spa/plugins/bluez5/a2dp-codec-sbc.c b/spa/plugins/bluez5/a2dp-codec-sbc.c index 4fd9768ff..381ab39e4 100644 --- a/spa/plugins/bluez5/a2dp-codec-sbc.c +++ b/spa/plugins/bluez5/a2dp-codec-sbc.c @@ -303,7 +303,7 @@ static int codec_get_block_size(void *data) } static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, - void *config, size_t config_len, struct spa_audio_info *info, size_t mtu) + void *config, size_t config_len, const struct spa_audio_info *info, size_t mtu) { struct impl *this; a2dp_sbc_t *conf = config; @@ -319,27 +319,25 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, this->sbc.endian = SBC_LE; this->mtu = mtu; - spa_zero(*info); - info->media_type = SPA_MEDIA_TYPE_audio; - info->media_subtype = SPA_MEDIA_SUBTYPE_raw; - info->info.raw.format = SPA_AUDIO_FORMAT_S16; + if (info->media_type != SPA_MEDIA_TYPE_audio || + info->media_subtype != SPA_MEDIA_SUBTYPE_raw || + info->info.raw.format != SPA_AUDIO_FORMAT_S16) { + res = -EINVAL; + goto error; + } switch (conf->frequency) { case SBC_SAMPLING_FREQ_16000: this->sbc.frequency = SBC_FREQ_16000; - info->info.raw.rate = 16000; break; case SBC_SAMPLING_FREQ_32000: this->sbc.frequency = SBC_FREQ_32000; - info->info.raw.rate = 32000; break; case SBC_SAMPLING_FREQ_44100: this->sbc.frequency = SBC_FREQ_44100; - info->info.raw.rate = 44100; break; case SBC_SAMPLING_FREQ_48000: this->sbc.frequency = SBC_FREQ_48000; - info->info.raw.rate = 48000; break; default: res = -EINVAL; @@ -349,35 +347,21 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags, switch (conf->channel_mode) { case SBC_CHANNEL_MODE_MONO: this->sbc.mode = SBC_MODE_MONO; - info->info.raw.channels = 1; break; case SBC_CHANNEL_MODE_DUAL_CHANNEL: this->sbc.mode = SBC_MODE_DUAL_CHANNEL; - info->info.raw.channels = 2; break; case SBC_CHANNEL_MODE_STEREO: this->sbc.mode = SBC_MODE_STEREO; - info->info.raw.channels = 2; break; case SBC_CHANNEL_MODE_JOINT_STEREO: this->sbc.mode = SBC_MODE_JOINT_STEREO; - info->info.raw.channels = 2; break; default: res = -EINVAL; goto error; } - switch (info->info.raw.channels) { - case 1: - info->info.raw.position[0] = SPA_AUDIO_CHANNEL_MONO; - break; - case 2: - info->info.raw.position[0] = SPA_AUDIO_CHANNEL_FL; - info->info.raw.position[1] = SPA_AUDIO_CHANNEL_FR; - break; - } - switch (conf->subbands) { case SBC_SUBBANDS_4: this->sbc.subbands = SBC_SB_4; diff --git a/spa/plugins/bluez5/a2dp-codecs.h b/spa/plugins/bluez5/a2dp-codecs.h index 566ed2b08..a659ea4a5 100644 --- a/spa/plugins/bluez5/a2dp-codecs.h +++ b/spa/plugins/bluez5/a2dp-codecs.h @@ -336,7 +336,7 @@ struct a2dp_codec { struct spa_pod_builder *builder, struct spa_pod **param); void *(*init) (const struct a2dp_codec *codec, uint32_t flags, void *config, size_t config_size, - struct spa_audio_info *info, size_t mtu); + const struct spa_audio_info *info, size_t mtu); void (*deinit) (void *data); int (*get_block_size) (void *data);