Skip to content

Commit f54baf3

Browse files
committed
Select only A2DP features supported by BlueALSA
Fixes #609
1 parent dfaaf20 commit f54baf3

File tree

3 files changed

+120
-71
lines changed

3 files changed

+120
-71
lines changed

src/a2dp-aac.c

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* BlueALSA - a2dp-aac.c
3-
* Copyright (c) 2016-2022 Arkadiusz Bokowy
3+
* Copyright (c) 2016-2023 Arkadiusz Bokowy
44
*
55
* This file is a part of bluez-alsa.
66
*
@@ -63,7 +63,7 @@ struct a2dp_codec a2dp_aac_sink = {
6363
.dir = A2DP_SINK,
6464
.codec_id = A2DP_CODEC_MPEG24,
6565
.capabilities.aac = {
66-
/* NOTE: AAC Long Term Prediction and AAC Scalable are
66+
/* NOTE: AAC Long Term Prediction and AAC Scalable might be
6767
* not supported by the FDK-AAC library. */
6868
.object_type =
6969
AAC_OBJECT_TYPE_MPEG2_AAC_LC |
@@ -99,7 +99,7 @@ struct a2dp_codec a2dp_aac_source = {
9999
.dir = A2DP_SOURCE,
100100
.codec_id = A2DP_CODEC_MPEG24,
101101
.capabilities.aac = {
102-
/* NOTE: AAC Long Term Prediction and AAC Scalable are
102+
/* NOTE: AAC Long Term Prediction and AAC Scalable might be
103103
* not supported by the FDK-AAC library. */
104104
.object_type =
105105
AAC_OBJECT_TYPE_MPEG2_AAC_LC |
@@ -133,6 +133,21 @@ struct a2dp_codec a2dp_aac_source = {
133133

134134
void a2dp_aac_init(void) {
135135

136+
LIB_INFO info[16] = { 0 };
137+
info[ARRAYSIZE(info) - 1].module_id = ~FDK_NONE;
138+
139+
aacDecoder_GetLibInfo(info);
140+
aacEncGetLibInfo(info);
141+
142+
unsigned int caps_dec = FDKlibInfo_getCapabilities(info, FDK_AACDEC);
143+
unsigned int caps_enc = FDKlibInfo_getCapabilities(info, FDK_AACENC);
144+
debug("FDK-AAC lib capabilities: dec:%#x enc:%#x", caps_dec, caps_enc);
145+
146+
if (caps_dec & CAPF_ER_AAC_SCAL)
147+
a2dp_aac_sink.capabilities.aac.object_type |= AAC_OBJECT_TYPE_MPEG4_AAC_SCA;
148+
if (caps_enc & CAPF_ER_AAC_SCAL)
149+
a2dp_aac_source.capabilities.aac.object_type |= AAC_OBJECT_TYPE_MPEG4_AAC_SCA;
150+
136151
if (config.a2dp.force_mono)
137152
a2dp_aac_source.capabilities.aac.channels = AAC_CHANNELS_1;
138153
if (config.a2dp.force_44100)

src/a2dp.c

+78-68
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* BlueALSA - a2dp.c
3-
* Copyright (c) 2016-2022 Arkadiusz Bokowy
3+
* Copyright (c) 2016-2023 Arkadiusz Bokowy
44
*
55
* This file is a part of bluez-alsa.
66
*
@@ -628,15 +628,21 @@ int a2dp_select_configuration(
628628
return errno = EINVAL, -1;
629629
}
630630

631+
a2dp_t tmp;
632+
/* save original capabilities blob for later */
633+
memcpy(&tmp, capabilities, size);
634+
635+
/* Narrow capabilities to values supported by BlueALSA. */
636+
if (a2dp_filter_capabilities(codec, capabilities, size) != 0)
637+
return -1;
638+
631639
switch (codec->codec_id) {
632640
case A2DP_CODEC_SBC: {
633-
634641
a2dp_sbc_t *cap = capabilities;
635-
unsigned int cap_chm = cap->channel_mode;
636-
unsigned int cap_freq = cap->frequency;
637642

643+
const unsigned int cap_chm = cap->channel_mode;
638644
if ((cap->channel_mode = a2dp_codec_select_channel_mode(codec, cap_chm, false)) == 0) {
639-
error("SBC: No supported channel modes: %#x", cap_chm);
645+
error("SBC: No supported channel modes: %#x", tmp.sbc.channel_mode);
640646
goto fail;
641647
}
642648

@@ -645,72 +651,77 @@ int a2dp_select_configuration(
645651
if (cap_chm & SBC_CHANNEL_MODE_DUAL_CHANNEL)
646652
cap->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
647653
else
648-
warn("SBC XQ: Dual channel mode not supported: %#x", cap_chm);
654+
warn("SBC XQ: Dual channel mode not supported: %#x", tmp.sbc.channel_mode);
649655
}
650656

657+
const unsigned int cap_freq = cap->frequency;
651658
if ((cap->frequency = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) == 0) {
652-
error("SBC: No supported sampling frequencies: %#x", cap_freq);
659+
error("SBC: No supported sampling frequencies: %#x", tmp.sbc.frequency);
653660
goto fail;
654661
}
655662

656-
if (cap->block_length & SBC_BLOCK_LENGTH_16)
663+
const uint8_t cap_block_length = cap->block_length;
664+
if (cap_block_length & SBC_BLOCK_LENGTH_16)
657665
cap->block_length = SBC_BLOCK_LENGTH_16;
658-
else if (cap->block_length & SBC_BLOCK_LENGTH_12)
666+
else if (cap_block_length & SBC_BLOCK_LENGTH_12)
659667
cap->block_length = SBC_BLOCK_LENGTH_12;
660-
else if (cap->block_length & SBC_BLOCK_LENGTH_8)
668+
else if (cap_block_length & SBC_BLOCK_LENGTH_8)
661669
cap->block_length = SBC_BLOCK_LENGTH_8;
662-
else if (cap->block_length & SBC_BLOCK_LENGTH_4)
670+
else if (cap_block_length & SBC_BLOCK_LENGTH_4)
663671
cap->block_length = SBC_BLOCK_LENGTH_4;
664672
else {
665-
error("SBC: No supported block lengths: %#x", cap->block_length);
673+
error("SBC: No supported block lengths: %#x", tmp.sbc.block_length);
666674
goto fail;
667675
}
668676

669-
if (cap->subbands & SBC_SUBBANDS_8)
677+
const uint8_t cap_subbands = cap->subbands;
678+
if (cap_subbands & SBC_SUBBANDS_8)
670679
cap->subbands = SBC_SUBBANDS_8;
671-
else if (cap->subbands & SBC_SUBBANDS_4)
680+
else if (cap_subbands & SBC_SUBBANDS_4)
672681
cap->subbands = SBC_SUBBANDS_4;
673682
else {
674-
error("SBC: No supported sub-bands: %#x", cap->subbands);
683+
error("SBC: No supported sub-bands: %#x", tmp.sbc.subbands);
675684
goto fail;
676685
}
677686

678-
if (cap->allocation_method & SBC_ALLOCATION_LOUDNESS)
687+
const uint8_t cap_allocation_method = cap->allocation_method;
688+
if (cap_allocation_method & SBC_ALLOCATION_LOUDNESS)
679689
cap->allocation_method = SBC_ALLOCATION_LOUDNESS;
680-
else if (cap->allocation_method & SBC_ALLOCATION_SNR)
690+
else if (cap_allocation_method & SBC_ALLOCATION_SNR)
681691
cap->allocation_method = SBC_ALLOCATION_SNR;
682692
else {
683-
error("SBC: No supported allocation method: %#x", cap->allocation_method);
693+
error("SBC: No supported allocation method: %#x", tmp.sbc.allocation_method);
684694
goto fail;
685695
}
686696

687-
cap->min_bitpool = MAX(codec->capabilities.sbc.min_bitpool, cap->min_bitpool);
688-
cap->max_bitpool = MIN(codec->capabilities.sbc.max_bitpool, cap->max_bitpool);
689-
690697
break;
691698
}
692699

693700
#if ENABLE_MPEG
694701
case A2DP_CODEC_MPEG12: {
695-
696702
a2dp_mpeg_t *cap = capabilities;
697-
unsigned int cap_chm = cap->channel_mode;
698-
unsigned int cap_freq = cap->frequency;
699703

700-
if (cap->layer & MPEG_LAYER_MP3)
704+
const uint8_t cap_layer = cap->layer;
705+
if (cap_layer & MPEG_LAYER_MP3)
701706
cap->layer = MPEG_LAYER_MP3;
707+
else if (cap_layer & MPEG_LAYER_MP2)
708+
cap->layer = MPEG_LAYER_MP2;
709+
else if (cap_layer & MPEG_LAYER_MP1)
710+
cap->layer = MPEG_LAYER_MP1;
702711
else {
703-
error("MPEG: No supported layer: %#x", cap->layer);
712+
error("MPEG: No supported layer: %#x", tmp.mpeg.layer);
704713
goto fail;
705714
}
706715

716+
const unsigned int cap_chm = cap->channel_mode;
707717
if ((cap->channel_mode = a2dp_codec_select_channel_mode(codec, cap_chm, false)) == 0) {
708-
error("MPEG: No supported channel modes: %#x", cap_chm);
718+
error("MPEG: No supported channel modes: %#x", tmp.mpeg.channel_mode);
709719
goto fail;
710720
}
711721

722+
const unsigned int cap_freq = cap->frequency;
712723
if ((cap->frequency = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) == 0) {
713-
error("MPEG: No supported sampling frequencies: %#x", cap_freq);
724+
error("MPEG: No supported sampling frequencies: %#x", tmp.mpeg.frequency);
714725
goto fail;
715726
}
716727

@@ -725,34 +736,34 @@ int a2dp_select_configuration(
725736

726737
#if ENABLE_AAC
727738
case A2DP_CODEC_MPEG24: {
728-
729739
a2dp_aac_t *cap = capabilities;
730-
unsigned int cap_chm = cap->channels;
731-
unsigned int cap_freq = AAC_GET_FREQUENCY(*cap);
732740

733-
if (cap->object_type & AAC_OBJECT_TYPE_MPEG4_AAC_SCA)
741+
const uint8_t cap_object_type = cap->object_type;
742+
if (cap_object_type & AAC_OBJECT_TYPE_MPEG4_AAC_SCA)
734743
cap->object_type = AAC_OBJECT_TYPE_MPEG4_AAC_SCA;
735-
else if (cap->object_type & AAC_OBJECT_TYPE_MPEG4_AAC_LTP)
744+
else if (cap_object_type & AAC_OBJECT_TYPE_MPEG4_AAC_LTP)
736745
cap->object_type = AAC_OBJECT_TYPE_MPEG4_AAC_LTP;
737-
else if (cap->object_type & AAC_OBJECT_TYPE_MPEG4_AAC_LC)
746+
else if (cap_object_type & AAC_OBJECT_TYPE_MPEG4_AAC_LC)
738747
cap->object_type = AAC_OBJECT_TYPE_MPEG4_AAC_LC;
739-
else if (cap->object_type & AAC_OBJECT_TYPE_MPEG2_AAC_LC)
748+
else if (cap_object_type & AAC_OBJECT_TYPE_MPEG2_AAC_LC)
740749
cap->object_type = AAC_OBJECT_TYPE_MPEG2_AAC_LC;
741750
else {
742-
error("AAC: No supported object type: %#x", cap->object_type);
751+
error("AAC: No supported object type: %#x", tmp.aac.object_type);
743752
goto fail;
744753
}
745754

755+
const unsigned int cap_chm = cap->channels;
746756
if ((cap->channels = a2dp_codec_select_channel_mode(codec, cap_chm, false)) == 0) {
747-
error("AAC: No supported channels: %#x", cap_chm);
757+
error("AAC: No supported channels: %#x", tmp.aac.channels);
748758
goto fail;
749759
}
750760

751761
unsigned int freq;
762+
const unsigned int cap_freq = AAC_GET_FREQUENCY(*cap);
752763
if ((freq = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) != 0)
753764
AAC_SET_FREQUENCY(*cap, freq);
754765
else {
755-
error("AAC: No supported sampling frequencies: %#x", cap_freq);
766+
error("AAC: No supported sampling frequencies: %#x", AAC_GET_FREQUENCY(tmp.aac));
756767
goto fail;
757768
}
758769

@@ -772,18 +783,17 @@ int a2dp_select_configuration(
772783

773784
#if ENABLE_APTX
774785
case A2DP_CODEC_VENDOR_APTX: {
775-
776786
a2dp_aptx_t *cap = capabilities;
777-
unsigned int cap_chm = cap->channel_mode;
778-
unsigned int cap_freq = cap->frequency;
779787

788+
const unsigned int cap_chm = cap->channel_mode;
780789
if ((cap->channel_mode = a2dp_codec_select_channel_mode(codec, cap_chm, false)) == 0) {
781-
error("apt-X: No supported channel modes: %#x", cap_chm);
790+
error("apt-X: No supported channel modes: %#x", tmp.aptx.channel_mode);
782791
goto fail;
783792
}
784793

794+
const unsigned int cap_freq = cap->frequency;
785795
if ((cap->frequency = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) == 0) {
786-
error("apt-X: No supported sampling frequencies: %#x", cap_freq);
796+
error("apt-X: No supported sampling frequencies: %#x", tmp.aptx.frequency);
787797
goto fail;
788798
}
789799

@@ -793,18 +803,17 @@ int a2dp_select_configuration(
793803

794804
#if ENABLE_APTX_HD
795805
case A2DP_CODEC_VENDOR_APTX_HD: {
796-
797806
a2dp_aptx_hd_t *cap = capabilities;
798-
unsigned int cap_chm = cap->aptx.channel_mode;
799-
unsigned int cap_freq = cap->aptx.frequency;
800807

808+
const unsigned int cap_chm = cap->aptx.channel_mode;
801809
if ((cap->aptx.channel_mode = a2dp_codec_select_channel_mode(codec, cap_chm, false)) == 0) {
802-
error("apt-X HD: No supported channel modes: %#x", cap_chm);
810+
error("apt-X HD: No supported channel modes: %#x", tmp.aptx_hd.aptx.channel_mode);
803811
goto fail;
804812
}
805813

814+
const unsigned int cap_freq = cap->aptx.frequency;
806815
if ((cap->aptx.frequency = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) == 0) {
807-
error("apt-X HD: No supported sampling frequencies: %#x", cap_freq);
816+
error("apt-X HD: No supported sampling frequencies: %#x", tmp.aptx_hd.aptx.frequency);
808817
goto fail;
809818
}
810819

@@ -814,23 +823,24 @@ int a2dp_select_configuration(
814823

815824
#if ENABLE_FASTSTREAM
816825
case A2DP_CODEC_VENDOR_FASTSTREAM: {
817-
818826
a2dp_faststream_t *cap = capabilities;
819-
unsigned int cap_freq = cap->frequency_music;
820-
unsigned int cap_freq_bc = cap->frequency_voice;
821827

828+
const unsigned int cap_freq = cap->frequency_music;
822829
if ((cap->frequency_music = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) == 0) {
823-
error("FastStream: No supported sampling frequencies: %#x", cap_freq);
830+
error("FastStream: No supported sampling frequencies: %#x",
831+
tmp.faststream.frequency_music);
824832
goto fail;
825833
}
826834

835+
const unsigned int cap_freq_bc = cap->frequency_voice;
827836
if ((cap->frequency_voice = a2dp_codec_select_sampling_freq(codec, cap_freq_bc, true)) == 0) {
828-
error("FastStream: No supported back-channel sampling frequencies: %#x", cap_freq_bc);
837+
error("FastStream: No supported back-channel sampling frequencies: %#x",
838+
tmp.faststream.frequency_voice);
829839
goto fail;
830840
}
831841

832842
if ((cap->direction & (FASTSTREAM_DIRECTION_MUSIC | FASTSTREAM_DIRECTION_VOICE)) == 0) {
833-
error("FastStream: No supported directions: %#x", cap->direction);
843+
error("FastStream: No supported directions: %#x", tmp.faststream.direction);
834844
}
835845

836846
break;
@@ -839,32 +849,33 @@ int a2dp_select_configuration(
839849

840850
#if ENABLE_LC3PLUS
841851
case A2DP_CODEC_VENDOR_LC3PLUS: {
842-
843852
a2dp_lc3plus_t *cap = capabilities;
844-
unsigned int cap_chm = cap->channels;
845-
unsigned int cap_freq = LC3PLUS_GET_FREQUENCY(*cap);
846853

847-
if (cap->frame_duration & LC3PLUS_FRAME_DURATION_100)
854+
const uint8_t cap_frame_duration = cap->frame_duration;
855+
if (cap_frame_duration & LC3PLUS_FRAME_DURATION_100)
848856
cap->frame_duration = LC3PLUS_FRAME_DURATION_100;
849-
else if (cap->frame_duration & LC3PLUS_FRAME_DURATION_050)
857+
else if (cap_frame_duration & LC3PLUS_FRAME_DURATION_050)
850858
cap->frame_duration = LC3PLUS_FRAME_DURATION_050;
851-
else if (cap->frame_duration & LC3PLUS_FRAME_DURATION_025)
859+
else if (cap_frame_duration & LC3PLUS_FRAME_DURATION_025)
852860
cap->frame_duration = LC3PLUS_FRAME_DURATION_025;
853861
else {
854-
error("LC3plus: No supported frame duration: %#x", cap->frame_duration);
862+
error("LC3plus: No supported frame duration: %#x", tmp.lc3plus.frame_duration);
855863
goto fail;
856864
}
857865

866+
const unsigned int cap_chm = cap->channels;
858867
if ((cap->channels = a2dp_codec_select_channel_mode(codec, cap_chm, false)) == 0) {
859-
error("LC3plus: No supported channels: %#x", cap_chm);
868+
error("LC3plus: No supported channels: %#x", tmp.lc3plus.channels);
860869
goto fail;
861870
}
862871

863872
unsigned int freq;
873+
const unsigned int cap_freq = LC3PLUS_GET_FREQUENCY(*cap);
864874
if ((freq = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) != 0)
865875
LC3PLUS_SET_FREQUENCY(*cap, freq);
866876
else {
867-
error("LC3plus: No supported sampling frequencies: %#x", cap_freq);
877+
error("LC3plus: No supported sampling frequencies: %#x",
878+
LC3PLUS_GET_FREQUENCY(tmp.lc3plus));
868879
goto fail;
869880
}
870881

@@ -874,18 +885,17 @@ int a2dp_select_configuration(
874885

875886
#if ENABLE_LDAC
876887
case A2DP_CODEC_VENDOR_LDAC: {
877-
878888
a2dp_ldac_t *cap = capabilities;
879-
unsigned int cap_chm = cap->channel_mode;
880-
unsigned int cap_freq = cap->frequency;
881889

890+
const unsigned int cap_chm = cap->channel_mode;
882891
if ((cap->channel_mode = a2dp_codec_select_channel_mode(codec, cap_chm, false)) == 0) {
883-
error("LDAC: No supported channel modes: %#x", cap_chm);
892+
error("LDAC: No supported channel modes: %#x", tmp.ldac.channel_mode);
884893
goto fail;
885894
}
886895

896+
const unsigned int cap_freq = cap->frequency;
887897
if ((cap->frequency = a2dp_codec_select_sampling_freq(codec, cap_freq, false)) == 0) {
888-
error("LDAC: No supported sampling frequencies: %#x", cap_freq);
898+
error("LDAC: No supported sampling frequencies: %#x", tmp.ldac.frequency);
889899
goto fail;
890900
}
891901

0 commit comments

Comments
 (0)