diff options
author | Igor V. Kovalenko <igor.v.kovalenko@gmail.com> | 2021-03-02 21:33:24 +0300 |
---|---|---|
committer | PulseAudio Marge Bot <pulseaudio-maintainers@lists.freedesktop.org> | 2021-04-05 15:43:32 +0000 |
commit | 310e2877a00fa2e81d8a8fc28de19f79fcfcdbbe (patch) | |
tree | 2a77bb7f7edf4ad078d5029994f6d271982d71f3 | |
parent | c7c9ca22abd6fd0871be31eaf5cff4225861634f (diff) | |
download | pulseaudio-310e2877a00fa2e81d8a8fc28de19f79fcfcdbbe.tar.gz |
bluetooth: split BT codec from A2DP SEP configuration api
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>
-rw-r--r-- | src/modules/bluetooth/a2dp-codec-api.h | 52 | ||||
-rw-r--r-- | src/modules/bluetooth/a2dp-codec-aptx-gst.c | 52 | ||||
-rw-r--r-- | src/modules/bluetooth/a2dp-codec-ldac-gst.c | 72 | ||||
-rw-r--r-- | src/modules/bluetooth/a2dp-codec-sbc.c | 112 | ||||
-rw-r--r-- | src/modules/bluetooth/a2dp-codec-util.c | 76 | ||||
-rw-r--r-- | src/modules/bluetooth/a2dp-codec-util.h | 10 | ||||
-rw-r--r-- | src/modules/bluetooth/bluez5-util.c | 106 | ||||
-rw-r--r-- | src/modules/bluetooth/bluez5-util.h | 6 | ||||
-rw-r--r-- | src/modules/bluetooth/bt-codec-api.h | 67 | ||||
-rw-r--r-- | src/modules/bluetooth/bt-codec-cvsd.c | 5 | ||||
-rw-r--r-- | src/modules/bluetooth/bt-codec-msbc.c | 5 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluez5-device.c | 34 |
12 files changed, 322 insertions, 275 deletions
diff --git a/src/modules/bluetooth/a2dp-codec-api.h b/src/modules/bluetooth/a2dp-codec-api.h index ed7bbe081..bdfd3f390 100644 --- a/src/modules/bluetooth/a2dp-codec-api.h +++ b/src/modules/bluetooth/a2dp-codec-api.h @@ -22,6 +22,8 @@ #include <pulsecore/core.h> +#include "bt-codec-api.h" + #define MAX_A2DP_CAPS_SIZE 254 #define DEFAULT_OUTPUT_RATE_REFRESH_INTERVAL_MS 500 @@ -36,13 +38,7 @@ typedef struct pa_a2dp_codec_id { 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; @@ -67,44 +63,8 @@ typedef struct pa_a2dp_codec { /* 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 diff --git a/src/modules/bluetooth/a2dp-codec-aptx-gst.c b/src/modules/bluetooth/a2dp-codec-aptx-gst.c index 2e4afaacb..3d30d9004 100644 --- a/src/modules/bluetooth/a2dp-codec-aptx-gst.c +++ b/src/modules/bluetooth/a2dp-codec-aptx-gst.c @@ -554,9 +554,7 @@ static size_t decode_buffer_hd(void *codec_info, const uint8_t *input_buffer, si 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, @@ -565,20 +563,22 @@ const pa_a2dp_codec pa_a2dp_codec_aptx = { .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, @@ -587,13 +587,17 @@ const pa_a2dp_codec pa_a2dp_codec_aptx_hd = { .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, + }, }; diff --git a/src/modules/bluetooth/a2dp-codec-ldac-gst.c b/src/modules/bluetooth/a2dp-codec-ldac-gst.c index 261443356..036d3b446 100644 --- a/src/modules/bluetooth/a2dp-codec-ldac-gst.c +++ b/src/modules/bluetooth/a2dp-codec-ldac-gst.c @@ -424,9 +424,7 @@ static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t 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, @@ -435,19 +433,21 @@ const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_hq = { .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, @@ -456,19 +456,21 @@ const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_sq = { .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, @@ -477,12 +479,16 @@ const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_mq = { .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, + }, }; diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c b/src/modules/bluetooth/a2dp-codec-sbc.c index 3ab334040..5095a1b3c 100644 --- a/src/modules/bluetooth/a2dp-codec-sbc.c +++ b/src/modules/bluetooth/a2dp-codec-sbc.c @@ -896,9 +896,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_ 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, @@ -907,16 +905,20 @@ const pa_a2dp_codec pa_a2dp_codec_sbc = { .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 @@ -932,9 +934,7 @@ const pa_a2dp_codec pa_a2dp_codec_sbc = { * 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, @@ -943,21 +943,23 @@ const pa_a2dp_codec pa_a2dp_codec_sbc_xq_453 = { .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, @@ -966,21 +968,23 @@ const pa_a2dp_codec pa_a2dp_codec_sbc_xq_512 = { .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, @@ -989,14 +993,18 @@ const pa_a2dp_codec pa_a2dp_codec_sbc_xq_552 = { .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, + }, }; diff --git a/src/modules/bluetooth/a2dp-codec-util.c b/src/modules/bluetooth/a2dp-codec-util.c index ca8df468e..7db025164 100644 --- a/src/modules/bluetooth/a2dp-codec-util.c +++ b/src/modules/bluetooth/a2dp-codec-util.c @@ -29,67 +29,67 @@ #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) { @@ -100,13 +100,13 @@ const pa_a2dp_codec *pa_bluetooth_get_hf_codec(const char *name) { 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; @@ -127,13 +127,13 @@ void pa_bluetooth_a2dp_codec_gst_init(void) { 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; } diff --git a/src/modules/bluetooth/a2dp-codec-util.h b/src/modules/bluetooth/a2dp-codec-util.h index 57a15c744..7288cffc5 100644 --- a/src/modules/bluetooth/a2dp-codec-util.h +++ b/src/modules/bluetooth/a2dp-codec-util.h @@ -23,13 +23,13 @@ #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); @@ -41,9 +41,9 @@ void pa_bluetooth_a2dp_codec_gst_init(void); 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 diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 55b50a6fc..663c4beb4 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -184,7 +184,7 @@ pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const 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); @@ -365,7 +365,7 @@ static void pa_bluetooth_device_switch_codec_reply(DBusPendingCall *pending, voi } 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; @@ -380,7 +380,7 @@ bool pa_bluetooth_device_switch_codec(pa_bluetooth_device *device, pa_bluetooth_ 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"); @@ -391,19 +391,19 @@ bool pa_bluetooth_device_switch_codec(pa_bluetooth_device *device, pa_bluetooth_ 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")); @@ -1169,7 +1169,7 @@ finish: 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]; @@ -1178,8 +1178,8 @@ static void register_legacy_sbc_endpoint(pa_bluetooth_discovery *y, const pa_a2d 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")); @@ -1245,12 +1245,12 @@ finish: 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"); } @@ -1824,7 +1824,7 @@ bool pa_bluetooth_profile_should_attenuate_volume(pa_bluetooth_profile_t peer_pr 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 "/")) @@ -1834,14 +1834,14 @@ static const pa_a2dp_codec *a2dp_endpoint_to_a2dp_codec(const char *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; @@ -1925,17 +1925,17 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage 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))) { @@ -1963,11 +1963,11 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage 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; @@ -1984,7 +1984,7 @@ static DBusMessage *endpoint_select_configuration(DBusConnection *conn, DBusMess 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; @@ -2001,10 +2001,10 @@ static DBusMessage *endpoint_select_configuration(DBusConnection *conn, DBusMess 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; @@ -2086,7 +2086,7 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi 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")) { @@ -2212,30 +2212,30 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage * 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); @@ -2273,7 +2273,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backe 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(); @@ -2332,17 +2332,17 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backe 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); } @@ -2370,7 +2370,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y) { 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); @@ -2422,18 +2422,18 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *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); } diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index 584f32bbb..a62bca0fa 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -101,7 +101,7 @@ struct pa_bluetooth_transport { 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; @@ -182,7 +182,7 @@ static inline void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetoo 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); @@ -191,7 +191,7 @@ void pa_bluetooth_transport_unlink(pa_bluetooth_transport *t); 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); diff --git a/src/modules/bluetooth/bt-codec-api.h b/src/modules/bluetooth/bt-codec-api.h new file mode 100644 index 000000000..900ffe942 --- /dev/null +++ b/src/modules/bluetooth/bt-codec-api.h @@ -0,0 +1,67 @@ +#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; diff --git a/src/modules/bluetooth/bt-codec-cvsd.c b/src/modules/bluetooth/bt-codec-cvsd.c index b121dc5a1..fe229d2f6 100644 --- a/src/modules/bluetooth/bt-codec-cvsd.c +++ b/src/modules/bluetooth/bt-codec-cvsd.c @@ -18,7 +18,8 @@ #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; @@ -106,7 +107,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_ } /* 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, diff --git a/src/modules/bluetooth/bt-codec-msbc.c b/src/modules/bluetooth/bt-codec-msbc.c index b1011434d..91c169d8d 100644 --- a/src/modules/bluetooth/bt-codec-msbc.c +++ b/src/modules/bluetooth/bt-codec-msbc.c @@ -18,7 +18,8 @@ #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> @@ -300,7 +301,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_ } /* 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, diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c index 4d3d0c9c2..9cbb33166 100644 --- a/src/modules/bluetooth/module-bluez5-device.c +++ b/src/modules/bluetooth/module-bluez5-device.c @@ -138,7 +138,7 @@ struct userdata { 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; @@ -2371,17 +2371,17 @@ static char *list_codecs(struct userdata *u) { 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); } @@ -2391,7 +2391,7 @@ static char *list_codecs(struct userdata *u) { } 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); @@ -2415,7 +2415,7 @@ static int bluez5_device_message_handler(const char *object_path, const char *me 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; @@ -2472,15 +2472,15 @@ static int bluez5_device_message_handler(const char *object_path, const char *me 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; } @@ -2496,14 +2496,14 @@ static int bluez5_device_message_handler(const char *object_path, const char *me 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 @@ -2514,7 +2514,7 @@ static int bluez5_device_message_handler(const char *object_path, const char *me 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; |