上一篇介绍了蓝牙音频的播放通路和编解码器,接下来介绍Source和Sink如何选择编解码器以及编解码流程。
编解码器选择
连接蓝牙后想要播放音乐,需要协商使用哪种编码器,还需要协商编码器使用什么配置,前面介绍了如何协商编码器的配置,这里将介绍如何选择编码器,从spec可以知道,SBC codec是a2dp必须支持的codec,因此Source和Sink至少有一个codec是相同的,当然也可能有多个相同的codec。因此在A2DP中将codec抽象成SEP,一个codec对应一个SEP,在fluoride中SEP通过BtaAvCoSep
描述,设备通过BtaAvCoPeer
描述,核心成员如下:
class BtaAvCoSep {
public:
uint8_t sep_info_idx; // 对端设备SEP在本地的index(bta中)
uint8_t seid; // 对端SEP的index(对端设备中)
uint8_t codec_caps[AVDT_CODEC_SIZE]; // 对端SEP index对应codec的能力
};
class BtaAvCoPeer {
public:
RawAddress addr; // 对端设备地址
BtaAvCoSep sinks[BTAV_A2DP_CODEC_INDEX_MAX]; // 支持的sink sep
BtaAvCoSep sources[BTAV_A2DP_CODEC_INDEX_MAX]; // 支持的source sep
uint8_t num_sinks; // 对端sink的数量
uint8_t num_sources; // 对端source的数量
uint8_t num_rx_sinks; // 收到对端sink的数量
uint8_t num_rx_sources; // 收到对端source的数量
uint8_t num_sup_sinks; // 收到且支持的对端sink的数量
uint8_t num_sup_sources; // 收到且支持的对端source的数量
const BtaAvCoSep* p_sink; // 当前选择的的sink sep
const BtaAvCoSep* p_source; // 当前选择的source sep
uint8_t codec_config[AVDT_CODEC_SIZE]; // 当前的codec 配置
bool acceptor; // true表示连接接受方,反之表示发起方
private:
tBTA_AV_HNDL bta_av_handle_; // BTA AV handle to use
A2dpCodecs* codecs_; // 本地支持的codec
};
- 获取SEP数量
发起连接的设备通过AVDTP协议发现对端设备支持的SEP数量,发现的结果通过bta_av_co_audio_disc_res
回调通知给btif,结果中包含对端设备地址、sink SEP数量、source SEP数量、总的SEP数量&#