Common API for all bluetooth codecs is now pa_bt_codec.
API to negotiate and configure A2DP SEP over Bluez is now pa_a2dp_endpoint_conf.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/507>
#include <pulsecore/core.h>
+#include "bt-codec-api.h"
+
#define MAX_A2DP_CAPS_SIZE 254
#define DEFAULT_OUTPUT_RATE_REFRESH_INTERVAL_MS 500
uint16_t vendor_codec_id;
} pa_a2dp_codec_id;
-typedef struct pa_a2dp_codec {
- /* Unique name of the codec, lowercase and without whitespaces, used for
- * constructing identifier, D-Bus paths, ... */
- const char *name;
- /* Human readable codec description */
- const char *description;
-
+typedef struct pa_a2dp_endpoint_conf {
/* A2DP codec id */
pa_a2dp_codec_id id;
/* Fill preferred codec configuration, returns size of filled buffer or 0 on failure */
uint8_t (*fill_preferred_configuration)(const pa_sample_spec *default_sample_spec, const uint8_t *capabilities_buffer, uint8_t capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]);
- /* Initialize codec, returns codec info data and set sample_spec,
- * for_encoding is true when codec_info is used for encoding,
- * for_backchannel is true when codec_info is used for backchannel */
- void *(*init)(bool for_encoding, bool for_backchannel, const uint8_t *config_buffer, uint8_t config_size, pa_sample_spec *sample_spec, pa_core *core);
- /* Deinitialize and release codec info data in codec_info */
- void (*deinit)(void *codec_info);
- /* Reset internal state of codec info data in codec_info, returns
- * a negative value on failure */
- int (*reset)(void *codec_info);
-
- /* Get read block size for codec, it is minimal size of buffer
- * needed to decode read_link_mtu bytes of encoded data */
- size_t (*get_read_block_size)(void *codec_info, size_t read_link_mtu);
- /* Get write block size for codec, it is maximal size of buffer
- * which can produce at most write_link_mtu bytes of encoded data */
- size_t (*get_write_block_size)(void *codec_info, size_t write_link_mtu);
- /* Get encoded block size for codec to hold one encoded frame.
- * Note HFP mSBC codec encoded block may not fit into one MTU and is sent out in chunks. */
- size_t (*get_encoded_block_size)(void *codec_info, size_t input_size);
-
- /* Reduce encoder bitrate for codec, returns new write block size or zero
- * if not changed, called when socket is not accepting encoded data fast
- * enough */
- size_t (*reduce_encoder_bitrate)(void *codec_info, size_t write_link_mtu);
-
- /* Increase encoder bitrate for codec, returns new write block size or zero
- * if not changed, called periodically when socket is keeping up with
- * encoded data */
- size_t (*increase_encoder_bitrate)(void *codec_info, size_t write_link_mtu);
-
- /* Encode input_buffer of input_size to output_buffer of output_size,
- * returns size of filled ouput_buffer and set processed to size of
- * processed input_buffer */
- size_t (*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);
- /* Decode input_buffer of input_size to output_buffer of output_size,
- * returns size of filled ouput_buffer and set processed to size of
- * processed input_buffer */
- size_t (*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);
-} pa_a2dp_codec;
+ /* Bluetooth codec */
+ pa_bt_codec bt_codec;
+} pa_a2dp_endpoint_conf;
#endif
return written;
}
-const pa_a2dp_codec pa_a2dp_codec_aptx = {
- .name = "aptx",
- .description = "aptX",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx = {
.id = { A2DP_CODEC_VENDOR, APTX_VENDOR_ID, APTX_CODEC_ID },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration,
- .init = init,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .encode_buffer = encode_buffer,
- .decode_buffer = decode_buffer,
+ .bt_codec = {
+ .name = "aptx",
+ .description = "aptX",
+ .init = init,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ .decode_buffer = decode_buffer,
+ },
};
-const pa_a2dp_codec pa_a2dp_codec_aptx_hd = {
- .name = "aptx_hd",
- .description = "aptX HD",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx_hd = {
.id = { A2DP_CODEC_VENDOR, APTX_HD_VENDOR_ID, APTX_HD_CODEC_ID },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities_hd,
.is_configuration_valid = is_configuration_valid_hd,
.fill_preferred_configuration = fill_preferred_configuration_hd,
- .init = init_hd,
- .deinit = deinit,
- .reset = reset_hd,
- .get_read_block_size = get_block_size_hd,
- .get_write_block_size = get_block_size_hd,
- .get_encoded_block_size = get_encoded_block_size_hd,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .encode_buffer = encode_buffer_hd,
- .decode_buffer = decode_buffer_hd,
+ .bt_codec = {
+ .name = "aptx_hd",
+ .description = "aptX HD",
+ .init = init_hd,
+ .deinit = deinit,
+ .reset = reset_hd,
+ .get_read_block_size = get_block_size_hd,
+ .get_write_block_size = get_block_size_hd,
+ .get_encoded_block_size = get_encoded_block_size_hd,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .encode_buffer = encode_buffer_hd,
+ .decode_buffer = decode_buffer_hd,
+ },
};
return written;
}
-const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_hq = {
- .name = "ldac_hq",
- .description = "LDAC (High Quality)",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq = {
.id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration,
- .init = init_hq,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .encode_buffer = encode_buffer,
+ .bt_codec = {
+ .name = "ldac_hq",
+ .description = "LDAC (High Quality)",
+ .init = init_hq,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ },
};
-const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_sq = {
- .name = "ldac_sq",
- .description = "LDAC (Standard Quality)",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq = {
.id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration,
- .init = init_sq,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .encode_buffer = encode_buffer,
+ .bt_codec = {
+ .name = "ldac_sq",
+ .description = "LDAC (Standard Quality)",
+ .init = init_sq,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ },
};
-const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_mq = {
- .name = "ldac_mq",
- .description = "LDAC (Mobile Quality)",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_mq = {
.id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration,
- .init = init_mq,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .encode_buffer = encode_buffer,
+ .bt_codec = {
+ .name = "ldac_mq",
+ .description = "LDAC (Mobile Quality)",
+ .init = init_mq,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ },
};
return d - output_buffer;
}
-const pa_a2dp_codec pa_a2dp_codec_sbc = {
- .name = "sbc",
- .description = "SBC",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc = {
.id = { A2DP_CODEC_SBC, 0, 0 },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration,
- .init = init,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .increase_encoder_bitrate = increase_encoder_bitrate,
- .encode_buffer = encode_buffer,
- .decode_buffer = decode_buffer,
+ .bt_codec = {
+ .name = "sbc",
+ .description = "SBC",
+ .init = init,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .increase_encoder_bitrate = increase_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ .decode_buffer = decode_buffer,
+ },
};
/* There are multiple definitions of SBC XQ, but in all cases this is
* we can gain from increased bitrate.
*/
-const pa_a2dp_codec pa_a2dp_codec_sbc_xq_453 = {
- .name = "sbc_xq_453",
- .description = "SBC XQ 453kbps",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_453 = {
.id = { A2DP_CODEC_SBC, 0, 0 },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities_xq,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration_xq_453kbps,
- .init = init,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .increase_encoder_bitrate = increase_encoder_bitrate,
- .encode_buffer = encode_buffer,
- .decode_buffer = decode_buffer,
+ .bt_codec = {
+ .name = "sbc_xq_453",
+ .description = "SBC XQ 453kbps",
+ .init = init,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .increase_encoder_bitrate = increase_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ .decode_buffer = decode_buffer,
+ },
};
-const pa_a2dp_codec pa_a2dp_codec_sbc_xq_512 = {
- .name = "sbc_xq_512",
- .description = "SBC XQ 512kbps",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_512 = {
.id = { A2DP_CODEC_SBC, 0, 0 },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities_xq,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration_xq_512kbps,
- .init = init,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .increase_encoder_bitrate = increase_encoder_bitrate,
- .encode_buffer = encode_buffer,
- .decode_buffer = decode_buffer,
+ .bt_codec = {
+ .name = "sbc_xq_512",
+ .description = "SBC XQ 512kbps",
+ .init = init,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .increase_encoder_bitrate = increase_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ .decode_buffer = decode_buffer,
+ },
};
-const pa_a2dp_codec pa_a2dp_codec_sbc_xq_552 = {
- .name = "sbc_xq_552",
- .description = "SBC XQ 552kbps",
+const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_552 = {
.id = { A2DP_CODEC_SBC, 0, 0 },
.support_backchannel = false,
.can_be_supported = can_be_supported,
.fill_capabilities = fill_capabilities_xq,
.is_configuration_valid = is_configuration_valid,
.fill_preferred_configuration = fill_preferred_configuration_xq_552kbps,
- .init = init,
- .deinit = deinit,
- .reset = reset,
- .get_read_block_size = get_block_size,
- .get_write_block_size = get_block_size,
- .get_encoded_block_size = get_encoded_block_size,
- .reduce_encoder_bitrate = reduce_encoder_bitrate,
- .increase_encoder_bitrate = increase_encoder_bitrate,
- .encode_buffer = encode_buffer,
- .decode_buffer = decode_buffer,
+ .bt_codec = {
+ .name = "sbc_xq_552",
+ .description = "SBC XQ 552kbps",
+ .init = init,
+ .deinit = deinit,
+ .reset = reset,
+ .get_read_block_size = get_block_size,
+ .get_write_block_size = get_block_size,
+ .get_encoded_block_size = get_encoded_block_size,
+ .reduce_encoder_bitrate = reduce_encoder_bitrate,
+ .increase_encoder_bitrate = increase_encoder_bitrate,
+ .encode_buffer = encode_buffer,
+ .decode_buffer = decode_buffer,
+ },
};
#include "a2dp-codec-util.h"
-extern const pa_a2dp_codec pa_bt_codec_msbc;
-extern const pa_a2dp_codec pa_bt_codec_cvsd;
+extern const pa_bt_codec pa_bt_codec_msbc;
+extern const pa_bt_codec pa_bt_codec_cvsd;
/* List of HSP/HFP codecs.
*/
-static const pa_a2dp_codec *pa_hf_codecs[] = {
+static const pa_bt_codec *pa_hf_codecs[] = {
&pa_bt_codec_cvsd,
&pa_bt_codec_msbc,
};
-extern const pa_a2dp_codec pa_a2dp_codec_sbc;
-extern const pa_a2dp_codec pa_a2dp_codec_sbc_xq_453;
-extern const pa_a2dp_codec pa_a2dp_codec_sbc_xq_512;
-extern const pa_a2dp_codec pa_a2dp_codec_sbc_xq_552;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_453;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_512;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_552;
#ifdef HAVE_GSTAPTX
-extern const pa_a2dp_codec pa_a2dp_codec_aptx;
-extern const pa_a2dp_codec pa_a2dp_codec_aptx_hd;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx_hd;
#endif
#ifdef HAVE_GSTLDAC
-extern const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_hq;
-extern const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_sq;
-extern const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_mq;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq;
+extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_mq;
#endif
/* This is list of supported codecs. Their order is important.
* Codec with lower index has higher priority. */
-static const pa_a2dp_codec *pa_a2dp_codecs[] = {
+static const pa_a2dp_endpoint_conf *pa_a2dp_endpoint_configurations[] = {
#ifdef HAVE_GSTLDAC
- &pa_a2dp_codec_ldac_eqmid_hq,
- &pa_a2dp_codec_ldac_eqmid_sq,
- &pa_a2dp_codec_ldac_eqmid_mq,
+ &pa_a2dp_endpoint_conf_ldac_eqmid_hq,
+ &pa_a2dp_endpoint_conf_ldac_eqmid_sq,
+ &pa_a2dp_endpoint_conf_ldac_eqmid_mq,
#endif
#ifdef HAVE_GSTAPTX
- &pa_a2dp_codec_aptx_hd,
- &pa_a2dp_codec_aptx,
+ &pa_a2dp_endpoint_conf_aptx_hd,
+ &pa_a2dp_endpoint_conf_aptx,
#endif
- &pa_a2dp_codec_sbc,
- &pa_a2dp_codec_sbc_xq_453,
- &pa_a2dp_codec_sbc_xq_512,
- &pa_a2dp_codec_sbc_xq_552,
+ &pa_a2dp_endpoint_conf_sbc,
+ &pa_a2dp_endpoint_conf_sbc_xq_453,
+ &pa_a2dp_endpoint_conf_sbc_xq_512,
+ &pa_a2dp_endpoint_conf_sbc_xq_552,
};
-unsigned int pa_bluetooth_a2dp_codec_count(void) {
- return PA_ELEMENTSOF(pa_a2dp_codecs);
+unsigned int pa_bluetooth_a2dp_endpoint_conf_count(void) {
+ return PA_ELEMENTSOF(pa_a2dp_endpoint_configurations);
}
-const pa_a2dp_codec *pa_bluetooth_a2dp_codec_iter(unsigned int i) {
- pa_assert(i < pa_bluetooth_a2dp_codec_count());
- return pa_a2dp_codecs[i];
+const pa_a2dp_endpoint_conf *pa_bluetooth_a2dp_endpoint_conf_iter(unsigned int i) {
+ pa_assert(i < pa_bluetooth_a2dp_endpoint_conf_count());
+ return pa_a2dp_endpoint_configurations[i];
}
unsigned int pa_bluetooth_hf_codec_count(void) {
return PA_ELEMENTSOF(pa_hf_codecs);
}
-const pa_a2dp_codec *pa_bluetooth_hf_codec_iter(unsigned int i) {
+const pa_bt_codec *pa_bluetooth_hf_codec_iter(unsigned int i) {
pa_assert(i < pa_bluetooth_hf_codec_count());
return pa_hf_codecs[i];
}
-const pa_a2dp_codec *pa_bluetooth_get_hf_codec(const char *name) {
+const pa_bt_codec *pa_bluetooth_get_hf_codec(const char *name) {
unsigned int i;
for (i = 0; i < PA_ELEMENTSOF(pa_hf_codecs); ++i) {
return NULL;
}
-const pa_a2dp_codec *pa_bluetooth_get_a2dp_codec(const char *name) {
+const pa_a2dp_endpoint_conf *pa_bluetooth_get_a2dp_endpoint_conf(const char *name) {
unsigned int i;
- unsigned int count = pa_bluetooth_a2dp_codec_count();
+ unsigned int count = pa_bluetooth_a2dp_endpoint_conf_count();
for (i = 0; i < count; i++) {
- if (pa_streq(pa_a2dp_codecs[i]->name, name))
- return pa_a2dp_codecs[i];
+ if (pa_streq(pa_a2dp_endpoint_configurations[i]->bt_codec.name, name))
+ return pa_a2dp_endpoint_configurations[i];
}
return NULL;
bool pa_bluetooth_a2dp_codec_is_available(const pa_a2dp_codec_id *id, bool is_a2dp_sink) {
unsigned int i;
- unsigned int count = pa_bluetooth_a2dp_codec_count();
- const pa_a2dp_codec *a2dp_codec;
+ unsigned int count = pa_bluetooth_a2dp_endpoint_conf_count();
+ const pa_a2dp_endpoint_conf *conf;
for (i = 0; i < count; i++) {
- a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
- if (memcmp(id, &a2dp_codec->id, sizeof(pa_a2dp_codec_id)) == 0
- && a2dp_codec->can_be_supported(is_a2dp_sink))
+ conf = pa_bluetooth_a2dp_endpoint_conf_iter(i);
+ if (memcmp(id, &conf->id, sizeof(pa_a2dp_codec_id)) == 0
+ && conf->can_be_supported(is_a2dp_sink))
return true;
}
#include "a2dp-codec-api.h"
/* Get number of supported A2DP codecs */
-unsigned int pa_bluetooth_a2dp_codec_count(void);
+unsigned int pa_bluetooth_a2dp_endpoint_conf_count(void);
/* Get i-th codec. Codec with higher number has higher priority */
-const pa_a2dp_codec *pa_bluetooth_a2dp_codec_iter(unsigned int i);
+const pa_a2dp_endpoint_conf *pa_bluetooth_a2dp_endpoint_conf_iter(unsigned int i);
/* Get codec by name */
-const pa_a2dp_codec *pa_bluetooth_get_a2dp_codec(const char *name);
+const pa_a2dp_endpoint_conf *pa_bluetooth_get_a2dp_endpoint_conf(const char *name);
/* Check if the given codec can be supported in A2DP_SINK or A2DP_SOURCE */
bool pa_bluetooth_a2dp_codec_is_available(const pa_a2dp_codec_id *id, bool is_a2dp_sink);
unsigned int pa_bluetooth_hf_codec_count(void);
/* Get i-th codec. Codec with higher number has higher priority */
-const pa_a2dp_codec *pa_bluetooth_hf_codec_iter(unsigned int i);
+const pa_bt_codec *pa_bluetooth_hf_codec_iter(unsigned int i);
/* Get HSP/HFP codec by name */
-const pa_a2dp_codec *pa_bluetooth_get_hf_codec(const char *name);
+const pa_bt_codec *pa_bluetooth_get_hf_codec(const char *name);
#endif
return t;
}
-void pa_bluetooth_transport_reconfigure(pa_bluetooth_transport *t, const pa_a2dp_codec *bt_codec,
+void pa_bluetooth_transport_reconfigure(pa_bluetooth_transport *t, const pa_bt_codec *bt_codec,
pa_bluetooth_transport_write_cb write_cb, pa_bluetooth_transport_setsockopt_cb setsockopt_cb) {
pa_assert(t);
}
bool pa_bluetooth_device_switch_codec(pa_bluetooth_device *device, pa_bluetooth_profile_t profile,
- pa_hashmap *capabilities_hashmap, const pa_a2dp_codec *a2dp_codec,
+ pa_hashmap *capabilities_hashmap, const pa_a2dp_endpoint_conf *endpoint_conf,
void (*codec_switch_cb)(bool, pa_bluetooth_profile_t profile, void *), void *userdata) {
DBusMessageIter iter, dict;
DBusMessage *m;
pa_assert(device);
pa_assert(capabilities_hashmap);
- pa_assert(a2dp_codec);
+ pa_assert(endpoint_conf);
if (device->codec_switching_in_progress) {
pa_log_error("Codec switching operation already in progress");
all_endpoints = NULL;
all_endpoints = pa_hashmap_get(is_a2dp_sink ? device->a2dp_sink_endpoints : device->a2dp_source_endpoints,
- &a2dp_codec->id);
+ &endpoint_conf->id);
pa_assert(all_endpoints);
- pa_assert_se(endpoint = a2dp_codec->choose_remote_endpoint(capabilities_hashmap, &device->discovery->core->default_sample_spec, is_a2dp_sink));
+ pa_assert_se(endpoint = endpoint_conf->choose_remote_endpoint(capabilities_hashmap, &device->discovery->core->default_sample_spec, is_a2dp_sink));
pa_assert_se(capabilities = pa_hashmap_get(all_endpoints, endpoint));
- config_size = a2dp_codec->fill_preferred_configuration(&device->discovery->core->default_sample_spec,
+ config_size = endpoint_conf->fill_preferred_configuration(&device->discovery->core->default_sample_spec,
capabilities->buffer, capabilities->size, config);
if (config_size == 0)
return false;
pa_endpoint = pa_sprintf_malloc("%s/%s", is_a2dp_sink ? A2DP_SOURCE_ENDPOINT : A2DP_SINK_ENDPOINT,
- a2dp_codec->name);
+ endpoint_conf->bt_codec.name);
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, endpoint,
BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SetConfiguration"));
pa_xfree(endpoint);
}
-static void register_legacy_sbc_endpoint(pa_bluetooth_discovery *y, const pa_a2dp_codec *a2dp_codec, const char *path, const char *endpoint, const char *uuid) {
+static void register_legacy_sbc_endpoint(pa_bluetooth_discovery *y, const pa_a2dp_endpoint_conf *endpoint_conf, const char *path, const char *endpoint, const char *uuid) {
DBusMessage *m;
DBusMessageIter i, d;
uint8_t capabilities[MAX_A2DP_CAPS_SIZE];
pa_log_debug("Registering %s on adapter %s", endpoint, path);
- codec_id = a2dp_codec->id.codec_id;
- capabilities_size = a2dp_codec->fill_capabilities(capabilities);
+ codec_id = endpoint_conf->id.codec_id;
+ capabilities_size = endpoint_conf->fill_capabilities(capabilities);
pa_assert(capabilities_size != 0);
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, path, BLUEZ_MEDIA_INTERFACE, "RegisterEndpoint"));
if (fallback) {
/* If bluez does not support RegisterApplication, fallback to old legacy API with just one SBC codec */
- const pa_a2dp_codec *a2dp_codec_sbc;
- a2dp_codec_sbc = pa_bluetooth_get_a2dp_codec("sbc");
- pa_assert(a2dp_codec_sbc);
- register_legacy_sbc_endpoint(y, a2dp_codec_sbc, path, A2DP_SINK_ENDPOINT "/sbc",
+ const pa_a2dp_endpoint_conf *endpoint_conf;
+ endpoint_conf = pa_bluetooth_get_a2dp_endpoint_conf("sbc");
+ pa_assert(endpoint_conf);
+ register_legacy_sbc_endpoint(y, endpoint_conf, path, A2DP_SINK_ENDPOINT "/sbc",
PA_BLUETOOTH_UUID_A2DP_SINK);
- register_legacy_sbc_endpoint(y, a2dp_codec_sbc, path, A2DP_SOURCE_ENDPOINT "/sbc",
+ register_legacy_sbc_endpoint(y, endpoint_conf, path, A2DP_SOURCE_ENDPOINT "/sbc",
PA_BLUETOOTH_UUID_A2DP_SOURCE);
pa_log_warn("Only SBC codec is available for A2DP profiles");
}
pa_assert_not_reached();
}
-static const pa_a2dp_codec *a2dp_endpoint_to_a2dp_codec(const char *endpoint) {
+static const pa_a2dp_endpoint_conf *a2dp_sep_to_a2dp_endpoint_conf(const char *endpoint) {
const char *codec_name;
if (pa_startswith(endpoint, A2DP_SINK_ENDPOINT "/"))
else
return NULL;
- return pa_bluetooth_get_a2dp_codec(codec_name);
+ return pa_bluetooth_get_a2dp_endpoint_conf(codec_name);
}
static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
pa_bluetooth_discovery *y = userdata;
pa_bluetooth_device *d;
pa_bluetooth_transport *t;
- const pa_a2dp_codec *a2dp_codec = NULL;
+ const pa_a2dp_endpoint_conf *endpoint_conf = NULL;
const char *sender, *path, *endpoint_path, *dev_path = NULL, *uuid = NULL;
const uint8_t *config = NULL;
int size = 0;
dbus_message_iter_get_fixed_array(&array, &config, &size);
- a2dp_codec = a2dp_endpoint_to_a2dp_codec(endpoint_path);
- pa_assert(a2dp_codec);
+ endpoint_conf = a2dp_sep_to_a2dp_endpoint_conf(endpoint_path);
+ pa_assert(endpoint_conf);
- if (!a2dp_codec->is_configuration_valid(config, size))
+ if (!endpoint_conf->is_configuration_valid(config, size))
goto fail;
}
dbus_message_iter_next(&props);
}
- if (!a2dp_codec)
+ if (!endpoint_conf)
goto fail2;
if ((d = pa_hashmap_get(y->devices, dev_path))) {
t = pa_bluetooth_transport_new(d, sender, path, p, config, size);
t->acquire = bluez5_transport_acquire_cb;
t->release = bluez5_transport_release_cb;
- pa_bluetooth_transport_reconfigure(t, a2dp_codec, a2dp_transport_write, NULL);
+ pa_bluetooth_transport_reconfigure(t, &endpoint_conf->bt_codec, a2dp_transport_write, NULL);
pa_bluetooth_transport_put(t);
pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
- pa_log_info("Selected codec: %s", a2dp_codec->name);
+ pa_log_info("Selected codec: %s", endpoint_conf->bt_codec.name);
return NULL;
const char *endpoint_path;
uint8_t *cap;
int size;
- const pa_a2dp_codec *a2dp_codec;
+ const pa_a2dp_endpoint_conf *endpoint_conf;
uint8_t config[MAX_A2DP_CAPS_SIZE];
uint8_t *config_ptr = config;
size_t config_size;
goto fail;
}
- a2dp_codec = a2dp_endpoint_to_a2dp_codec(endpoint_path);
- pa_assert(a2dp_codec);
+ endpoint_conf = a2dp_sep_to_a2dp_endpoint_conf(endpoint_path);
+ pa_assert(endpoint_conf);
- config_size = a2dp_codec->fill_preferred_configuration(&y->core->default_sample_spec, cap, size, config);
+ config_size = endpoint_conf->fill_preferred_configuration(&y->core->default_sample_spec, cap, size, config);
if (config_size == 0)
goto fail;
pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
- if (!a2dp_endpoint_to_a2dp_codec(path))
+ if (!a2dp_sep_to_a2dp_endpoint_conf(path))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) {
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&array);
- for (i = 0; i < pa_bluetooth_a2dp_codec_count(); i++) {
- const pa_a2dp_codec *a2dp_codec;
+ for (i = 0; i < pa_bluetooth_a2dp_endpoint_conf_count(); i++) {
+ const pa_a2dp_endpoint_conf *endpoint_conf;
uint8_t capabilities[MAX_A2DP_CAPS_SIZE];
uint8_t capabilities_size;
uint8_t codec_id;
char *endpoint;
- a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
+ endpoint_conf = pa_bluetooth_a2dp_endpoint_conf_iter(i);
- codec_id = a2dp_codec->id.codec_id;
+ codec_id = endpoint_conf->id.codec_id;
- if (a2dp_codec->can_be_supported(false)) {
- capabilities_size = a2dp_codec->fill_capabilities(capabilities);
+ if (endpoint_conf->can_be_supported(false)) {
+ capabilities_size = endpoint_conf->fill_capabilities(capabilities);
pa_assert(capabilities_size != 0);
- endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
+ endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, endpoint_conf->bt_codec.name);
append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SINK, codec_id,
capabilities, capabilities_size);
pa_xfree(endpoint);
}
- if (a2dp_codec->can_be_supported(true)) {
- capabilities_size = a2dp_codec->fill_capabilities(capabilities);
+ if (endpoint_conf->can_be_supported(true)) {
+ capabilities_size = endpoint_conf->fill_capabilities(capabilities);
pa_assert(capabilities_size != 0);
- endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name);
+ endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, endpoint_conf->bt_codec.name);
append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SOURCE, codec_id,
capabilities, capabilities_size);
pa_xfree(endpoint);
DBusError err;
DBusConnection *conn;
unsigned i, count;
- const pa_a2dp_codec *a2dp_codec;
+ const pa_a2dp_endpoint_conf *endpoint_conf;
char *endpoint;
pa_bluetooth_a2dp_codec_gst_init();
object_manager_init(y);
- count = pa_bluetooth_a2dp_codec_count();
+ count = pa_bluetooth_a2dp_endpoint_conf_count();
for (i = 0; i < count; i++) {
- a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
- if (a2dp_codec->can_be_supported(false)) {
- endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
+ endpoint_conf = pa_bluetooth_a2dp_endpoint_conf_iter(i);
+ if (endpoint_conf->can_be_supported(false)) {
+ endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, endpoint_conf->bt_codec.name);
endpoint_init(y, endpoint);
pa_xfree(endpoint);
}
- if (a2dp_codec->can_be_supported(true)) {
- endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name);
+ if (endpoint_conf->can_be_supported(true)) {
+ endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, endpoint_conf->bt_codec.name);
endpoint_init(y, endpoint);
pa_xfree(endpoint);
}
void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
unsigned i, count;
- const pa_a2dp_codec *a2dp_codec;
+ const pa_a2dp_endpoint_conf *endpoint_conf;
char *endpoint;
pa_assert(y);
object_manager_done(y);
- count = pa_bluetooth_a2dp_codec_count();
+ count = pa_bluetooth_a2dp_endpoint_conf_count();
for (i = 0; i < count; i++) {
- a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
+ endpoint_conf = pa_bluetooth_a2dp_endpoint_conf_iter(i);
- if (a2dp_codec->can_be_supported(false)) {
- endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
+ if (endpoint_conf->can_be_supported(false)) {
+ endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, endpoint_conf->bt_codec.name);
endpoint_done(y, endpoint);
pa_xfree(endpoint);
}
- if (a2dp_codec->can_be_supported(true)) {
- endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name);
+ if (endpoint_conf->can_be_supported(true)) {
+ endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, endpoint_conf->bt_codec.name);
endpoint_done(y, endpoint);
pa_xfree(endpoint);
}
void *config;
size_t config_size;
- const pa_a2dp_codec *bt_codec;
+ const pa_bt_codec *bt_codec;
int stream_write_type;
size_t last_read_size;
pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,
pa_bluetooth_profile_t p, const uint8_t *config, size_t size);
-void pa_bluetooth_transport_reconfigure(pa_bluetooth_transport *t, const pa_a2dp_codec *bt_codec,
+void pa_bluetooth_transport_reconfigure(pa_bluetooth_transport *t, const pa_bt_codec *bt_codec,
pa_bluetooth_transport_write_cb write_cb, pa_bluetooth_transport_setsockopt_cb setsockopt_cb);
void pa_bluetooth_transport_set_state(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state);
void pa_bluetooth_transport_free(pa_bluetooth_transport *t);
bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d);
-bool pa_bluetooth_device_switch_codec(pa_bluetooth_device *device, pa_bluetooth_profile_t profile, pa_hashmap *capabilities_hashmap, const pa_a2dp_codec *a2dp_codec, void (*codec_switch_cb)(bool, pa_bluetooth_profile_t profile, void *), void *userdata);
+bool pa_bluetooth_device_switch_codec(pa_bluetooth_device *device, pa_bluetooth_profile_t profile, pa_hashmap *capabilities_hashmap, const pa_a2dp_endpoint_conf *endpoint_conf, void (*codec_switch_cb)(bool, pa_bluetooth_profile_t profile, void *), void *userdata);
pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_path(pa_bluetooth_discovery *y, const char *path);
pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local);
--- /dev/null
+#pragma once
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulsecore/core.h>
+
+typedef struct pa_bt_codec {
+ /* Unique name of the codec, lowercase and without whitespaces, used for
+ * constructing identifier, D-Bus paths, ... */
+ const char *name;
+ /* Human readable codec description */
+ const char *description;
+
+ /* Initialize codec, returns codec info data and set sample_spec,
+ * for_encoding is true when codec_info is used for encoding,
+ * for_backchannel is true when codec_info is used for backchannel */
+ void *(*init)(bool for_encoding, bool for_backchannel, const uint8_t *config_buffer, uint8_t config_size, pa_sample_spec *sample_spec, pa_core *core);
+ /* Deinitialize and release codec info data in codec_info */
+ void (*deinit)(void *codec_info);
+ /* Reset internal state of codec info data in codec_info, returns
+ * a negative value on failure */
+ int (*reset)(void *codec_info);
+
+ /* Get read block size for codec, it is minimal size of buffer
+ * needed to decode read_link_mtu bytes of encoded data */
+ size_t (*get_read_block_size)(void *codec_info, size_t read_link_mtu);
+ /* Get write block size for codec, it is maximal size of buffer
+ * which can produce at most write_link_mtu bytes of encoded data */
+ size_t (*get_write_block_size)(void *codec_info, size_t write_link_mtu);
+ /* Get encoded block size for codec to hold one encoded frame.
+ * Note HFP mSBC codec encoded block may not fit into one MTU and is sent out in chunks. */
+ size_t (*get_encoded_block_size)(void *codec_info, size_t input_size);
+
+ /* Reduce encoder bitrate for codec, returns new write block size or zero
+ * if not changed, called when socket is not accepting encoded data fast
+ * enough */
+ size_t (*reduce_encoder_bitrate)(void *codec_info, size_t write_link_mtu);
+
+ /* Increase encoder bitrate for codec, returns new write block size or zero
+ * if not changed, called periodically when socket is keeping up with
+ * encoded data */
+ size_t (*increase_encoder_bitrate)(void *codec_info, size_t write_link_mtu);
+
+ /* Encode input_buffer of input_size to output_buffer of output_size,
+ * returns size of filled ouput_buffer and set processed to size of
+ * processed input_buffer */
+ size_t (*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);
+ /* Decode input_buffer of input_size to output_buffer of output_size,
+ * returns size of filled ouput_buffer and set processed to size of
+ * processed input_buffer */
+ size_t (*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);
+} pa_bt_codec;
#include <config.h>
#endif
-#include "a2dp-codec-api.h"
+#include <pulsecore/core.h>
+#include "bt-codec-api.h"
typedef struct codec_info {
pa_sample_spec sample_spec;
}
/* dummy passthrough codec used with HSP/HFP CVSD */
-const pa_a2dp_codec pa_bt_codec_cvsd = {
+const pa_bt_codec pa_bt_codec_cvsd = {
.name = "CVSD",
.description = "CVSD",
.init = init,
#include <config.h>
#endif
-#include "a2dp-codec-api.h"
+#include <pulsecore/core.h>
+#include "bt-codec-api.h"
#include "bt-codec-msbc.h"
#include <sbc/sbc.h>
}
/* Modified SBC codec for HFP Wideband Speech*/
-const pa_a2dp_codec pa_bt_codec_msbc = {
+const pa_bt_codec pa_bt_codec_msbc = {
.name = "mSBC",
.description = "mSBC",
.init = init,
pa_smoother *read_smoother;
pa_memchunk write_memchunk;
- const pa_a2dp_codec *bt_codec;
+ const pa_bt_codec *bt_codec;
void *encoder_info;
pa_sample_spec encoder_sample_spec;
a2dp_endpoints = is_a2dp_sink ? u->device->a2dp_sink_endpoints : u->device->a2dp_source_endpoints;
PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, a2dp_endpoints, state) {
- for (i = 0; i < pa_bluetooth_a2dp_codec_count(); i++) {
- const pa_a2dp_codec *a2dp_codec;
+ for (i = 0; i < pa_bluetooth_a2dp_endpoint_conf_count(); i++) {
+ const pa_a2dp_endpoint_conf *endpoint_conf;
- a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
+ endpoint_conf = pa_bluetooth_a2dp_endpoint_conf_iter(i);
- if (memcmp(key, &a2dp_codec->id, sizeof(pa_a2dp_codec_id)) == 0) {
- if (a2dp_codec->can_be_supported(is_a2dp_sink)) {
+ if (memcmp(key, &endpoint_conf->id, sizeof(pa_a2dp_codec_id)) == 0) {
+ if (endpoint_conf->can_be_supported(is_a2dp_sink)) {
pa_json_encoder_begin_element_object(encoder);
- pa_json_encoder_add_member_string(encoder, "name", a2dp_codec->name);
- pa_json_encoder_add_member_string(encoder, "description", a2dp_codec->description);
+ pa_json_encoder_add_member_string(encoder, "name", endpoint_conf->bt_codec.name);
+ pa_json_encoder_add_member_string(encoder, "description", endpoint_conf->bt_codec.description);
pa_json_encoder_end_object(encoder);
}
} else {
/* find out active codec selection from device profile */
for (i = 0; i < pa_bluetooth_hf_codec_count(); i++) {
- const pa_a2dp_codec *hf_codec;
+ const pa_bt_codec *hf_codec;
hf_codec = pa_bluetooth_hf_codec_iter(i);
char *message_handler_path;
pa_hashmap *capabilities_hashmap;
pa_bluetooth_profile_t profile;
- const pa_a2dp_codec *codec;
+ const pa_a2dp_endpoint_conf *endpoint_conf;
const char *codec_name;
struct userdata *u;
bool is_a2dp_sink;
return -PA_ERR_INVALID;
}
- codec = pa_bluetooth_get_a2dp_codec(codec_name);
- if (codec == NULL) {
+ endpoint_conf = pa_bluetooth_get_a2dp_endpoint_conf(codec_name);
+ if (endpoint_conf == NULL) {
pa_log_info("Invalid codec %s specified for switching", codec_name);
return -PA_ERR_INVALID;
}
is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
- if (!codec->can_be_supported(is_a2dp_sink)) {
+ if (!endpoint_conf->can_be_supported(is_a2dp_sink)) {
pa_log_info("Codec not found on system");
return -PA_ERR_NOTSUPPORTED;
}
return -PA_ERR_INVALID;
}
- capabilities_hashmap = pa_hashmap_get(is_a2dp_sink ? u->device->a2dp_sink_endpoints : u->device->a2dp_source_endpoints, &codec->id);
+ capabilities_hashmap = pa_hashmap_get(is_a2dp_sink ? u->device->a2dp_sink_endpoints : u->device->a2dp_source_endpoints, &endpoint_conf->id);
if (!capabilities_hashmap) {
pa_log_info("No remote endpoint found for %s codec. Codec not supported by remote endpoint.",
- codec->name);
+ endpoint_conf->bt_codec.name);
return -PA_ERR_INVALID;
}
- pa_log_info("Initiating codec switching process to %s", codec->name);
+ pa_log_info("Initiating codec switching process to %s", endpoint_conf->bt_codec.name);
/*
* The current profile needs to be saved before we stop the thread and
stop_thread(u);
- if (!pa_bluetooth_device_switch_codec(u->device, profile, capabilities_hashmap, codec, switch_codec_cb_handler, userdata)
+ if (!pa_bluetooth_device_switch_codec(u->device, profile, capabilities_hashmap, endpoint_conf, switch_codec_cb_handler, userdata)
&& !u->device->codec_switching_in_progress)
goto profile_off;