mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									c7c9ca22ab
								
							
						
					
					
						commit
						310e2877a0
					
				
					 12 changed files with 322 additions and 275 deletions
				
			
		| 
						 | 
					@ -22,6 +22,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <pulsecore/core.h>
 | 
					#include <pulsecore/core.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "bt-codec-api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_A2DP_CAPS_SIZE 254
 | 
					#define MAX_A2DP_CAPS_SIZE 254
 | 
				
			||||||
#define DEFAULT_OUTPUT_RATE_REFRESH_INTERVAL_MS 500
 | 
					#define DEFAULT_OUTPUT_RATE_REFRESH_INTERVAL_MS 500
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,13 +38,7 @@ typedef struct pa_a2dp_codec_id {
 | 
				
			||||||
    uint16_t vendor_codec_id;
 | 
					    uint16_t vendor_codec_id;
 | 
				
			||||||
} pa_a2dp_codec_id;
 | 
					} pa_a2dp_codec_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct pa_a2dp_codec {
 | 
					typedef struct pa_a2dp_endpoint_conf {
 | 
				
			||||||
    /* 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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* A2DP codec id */
 | 
					    /* A2DP codec id */
 | 
				
			||||||
    pa_a2dp_codec_id 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 */
 | 
					    /* 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]);
 | 
					    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,
 | 
					    /* Bluetooth codec */
 | 
				
			||||||
     * for_encoding is true when codec_info is used for encoding,
 | 
					    pa_bt_codec bt_codec;
 | 
				
			||||||
     * for_backchannel is true when codec_info is used for backchannel */
 | 
					} pa_a2dp_endpoint_conf;
 | 
				
			||||||
    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;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -554,9 +554,7 @@ static size_t decode_buffer_hd(void *codec_info, const uint8_t *input_buffer, si
 | 
				
			||||||
    return written;
 | 
					    return written;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pa_a2dp_codec pa_a2dp_codec_aptx = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx = {
 | 
				
			||||||
    .name = "aptx",
 | 
					 | 
				
			||||||
    .description = "aptX",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_VENDOR, APTX_VENDOR_ID, APTX_CODEC_ID },
 | 
					    .id = { A2DP_CODEC_VENDOR, APTX_VENDOR_ID, APTX_CODEC_ID },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .can_be_supported = can_be_supported,
 | 
				
			||||||
| 
						 | 
					@ -565,20 +563,22 @@ const pa_a2dp_codec pa_a2dp_codec_aptx = {
 | 
				
			||||||
    .fill_capabilities = fill_capabilities,
 | 
					    .fill_capabilities = fill_capabilities,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration,
 | 
				
			||||||
    .init = init,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "aptx",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "aptX",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .get_write_block_size = get_block_size,
 | 
				
			||||||
    .decode_buffer = decode_buffer,
 | 
					        .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 = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx_hd = {
 | 
				
			||||||
    .name = "aptx_hd",
 | 
					 | 
				
			||||||
    .description = "aptX HD",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_VENDOR, APTX_HD_VENDOR_ID, APTX_HD_CODEC_ID },
 | 
					    .id = { A2DP_CODEC_VENDOR, APTX_HD_VENDOR_ID, APTX_HD_CODEC_ID },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .can_be_supported = can_be_supported,
 | 
				
			||||||
| 
						 | 
					@ -587,13 +587,17 @@ const pa_a2dp_codec pa_a2dp_codec_aptx_hd = {
 | 
				
			||||||
    .fill_capabilities = fill_capabilities_hd,
 | 
					    .fill_capabilities = fill_capabilities_hd,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid_hd,
 | 
					    .is_configuration_valid = is_configuration_valid_hd,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration_hd,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration_hd,
 | 
				
			||||||
    .init = init_hd,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "aptx_hd",
 | 
				
			||||||
    .reset = reset_hd,
 | 
					        .description = "aptX HD",
 | 
				
			||||||
    .get_read_block_size = get_block_size_hd,
 | 
					        .init = init_hd,
 | 
				
			||||||
    .get_write_block_size = get_block_size_hd,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size_hd,
 | 
					        .reset = reset_hd,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size_hd,
 | 
				
			||||||
    .encode_buffer = encode_buffer_hd,
 | 
					        .get_write_block_size = get_block_size_hd,
 | 
				
			||||||
    .decode_buffer = decode_buffer_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,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -424,9 +424,7 @@ static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t
 | 
				
			||||||
    return written;
 | 
					    return written;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_hq = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq = {
 | 
				
			||||||
    .name = "ldac_hq",
 | 
					 | 
				
			||||||
    .description = "LDAC (High Quality)",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
					    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .can_be_supported = can_be_supported,
 | 
				
			||||||
| 
						 | 
					@ -435,19 +433,21 @@ const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_hq = {
 | 
				
			||||||
    .fill_capabilities = fill_capabilities,
 | 
					    .fill_capabilities = fill_capabilities,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration,
 | 
				
			||||||
    .init = init_hq,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "ldac_hq",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "LDAC (High Quality)",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init_hq,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .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 = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq = {
 | 
				
			||||||
    .name = "ldac_sq",
 | 
					 | 
				
			||||||
    .description = "LDAC (Standard Quality)",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
					    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .can_be_supported = can_be_supported,
 | 
				
			||||||
| 
						 | 
					@ -456,19 +456,21 @@ const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_sq = {
 | 
				
			||||||
    .fill_capabilities = fill_capabilities,
 | 
					    .fill_capabilities = fill_capabilities,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration,
 | 
				
			||||||
    .init = init_sq,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "ldac_sq",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "LDAC (Standard Quality)",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init_sq,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .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 = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_mq = {
 | 
				
			||||||
    .name = "ldac_mq",
 | 
					 | 
				
			||||||
    .description = "LDAC (Mobile Quality)",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
					    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .can_be_supported = can_be_supported,
 | 
				
			||||||
| 
						 | 
					@ -477,12 +479,16 @@ const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_mq = {
 | 
				
			||||||
    .fill_capabilities = fill_capabilities,
 | 
					    .fill_capabilities = fill_capabilities,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration,
 | 
				
			||||||
    .init = init_mq,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "ldac_mq",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "LDAC (Mobile Quality)",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init_mq,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .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,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -896,9 +896,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_
 | 
				
			||||||
    return d - output_buffer;
 | 
					    return d - output_buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pa_a2dp_codec pa_a2dp_codec_sbc = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc = {
 | 
				
			||||||
    .name = "sbc",
 | 
					 | 
				
			||||||
    .description = "SBC",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
					    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .can_be_supported = can_be_supported,
 | 
				
			||||||
| 
						 | 
					@ -907,16 +905,20 @@ const pa_a2dp_codec pa_a2dp_codec_sbc = {
 | 
				
			||||||
    .fill_capabilities = fill_capabilities,
 | 
					    .fill_capabilities = fill_capabilities,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration,
 | 
				
			||||||
    .init = init,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "sbc",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "SBC",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .increase_encoder_bitrate = increase_encoder_bitrate,
 | 
					        .get_write_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .get_encoded_block_size = get_encoded_block_size,
 | 
				
			||||||
    .decode_buffer = decode_buffer,
 | 
					        .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
 | 
					/* 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.
 | 
					 * we can gain from increased bitrate.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pa_a2dp_codec pa_a2dp_codec_sbc_xq_453 = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_453 = {
 | 
				
			||||||
    .name = "sbc_xq_453",
 | 
					 | 
				
			||||||
    .description = "SBC XQ 453kbps",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
					    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .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,
 | 
					    .fill_capabilities = fill_capabilities_xq,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration_xq_453kbps,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration_xq_453kbps,
 | 
				
			||||||
    .init = init,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "sbc_xq_453",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "SBC XQ 453kbps",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .increase_encoder_bitrate = increase_encoder_bitrate,
 | 
					        .get_write_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .get_encoded_block_size = get_encoded_block_size,
 | 
				
			||||||
    .decode_buffer = decode_buffer,
 | 
					        .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 = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_512 = {
 | 
				
			||||||
    .name = "sbc_xq_512",
 | 
					 | 
				
			||||||
    .description = "SBC XQ 512kbps",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
					    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .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,
 | 
					    .fill_capabilities = fill_capabilities_xq,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration_xq_512kbps,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration_xq_512kbps,
 | 
				
			||||||
    .init = init,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "sbc_xq_512",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "SBC XQ 512kbps",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .increase_encoder_bitrate = increase_encoder_bitrate,
 | 
					        .get_write_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .get_encoded_block_size = get_encoded_block_size,
 | 
				
			||||||
    .decode_buffer = decode_buffer,
 | 
					        .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 = {
 | 
					const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_552 = {
 | 
				
			||||||
    .name = "sbc_xq_552",
 | 
					 | 
				
			||||||
    .description = "SBC XQ 552kbps",
 | 
					 | 
				
			||||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
					    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
				
			||||||
    .support_backchannel = false,
 | 
					    .support_backchannel = false,
 | 
				
			||||||
    .can_be_supported = can_be_supported,
 | 
					    .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,
 | 
					    .fill_capabilities = fill_capabilities_xq,
 | 
				
			||||||
    .is_configuration_valid = is_configuration_valid,
 | 
					    .is_configuration_valid = is_configuration_valid,
 | 
				
			||||||
    .fill_preferred_configuration = fill_preferred_configuration_xq_552kbps,
 | 
					    .fill_preferred_configuration = fill_preferred_configuration_xq_552kbps,
 | 
				
			||||||
    .init = init,
 | 
					    .bt_codec = {
 | 
				
			||||||
    .deinit = deinit,
 | 
					        .name = "sbc_xq_552",
 | 
				
			||||||
    .reset = reset,
 | 
					        .description = "SBC XQ 552kbps",
 | 
				
			||||||
    .get_read_block_size = get_block_size,
 | 
					        .init = init,
 | 
				
			||||||
    .get_write_block_size = get_block_size,
 | 
					        .deinit = deinit,
 | 
				
			||||||
    .get_encoded_block_size = get_encoded_block_size,
 | 
					        .reset = reset,
 | 
				
			||||||
    .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
					        .get_read_block_size = get_block_size,
 | 
				
			||||||
    .increase_encoder_bitrate = increase_encoder_bitrate,
 | 
					        .get_write_block_size = get_block_size,
 | 
				
			||||||
    .encode_buffer = encode_buffer,
 | 
					        .get_encoded_block_size = get_encoded_block_size,
 | 
				
			||||||
    .decode_buffer = decode_buffer,
 | 
					        .reduce_encoder_bitrate = reduce_encoder_bitrate,
 | 
				
			||||||
 | 
					        .increase_encoder_bitrate = increase_encoder_bitrate,
 | 
				
			||||||
 | 
					        .encode_buffer = encode_buffer,
 | 
				
			||||||
 | 
					        .decode_buffer = decode_buffer,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,67 +29,67 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "a2dp-codec-util.h"
 | 
					#include "a2dp-codec-util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const pa_a2dp_codec pa_bt_codec_msbc;
 | 
					extern const pa_bt_codec pa_bt_codec_msbc;
 | 
				
			||||||
extern const pa_a2dp_codec pa_bt_codec_cvsd;
 | 
					extern const pa_bt_codec pa_bt_codec_cvsd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* List of HSP/HFP codecs.
 | 
					/* 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_cvsd,
 | 
				
			||||||
    &pa_bt_codec_msbc,
 | 
					    &pa_bt_codec_msbc,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const pa_a2dp_codec pa_a2dp_codec_sbc;
 | 
					extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc;
 | 
				
			||||||
extern const pa_a2dp_codec pa_a2dp_codec_sbc_xq_453;
 | 
					extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_453;
 | 
				
			||||||
extern const pa_a2dp_codec pa_a2dp_codec_sbc_xq_512;
 | 
					extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_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_xq_552;
 | 
				
			||||||
#ifdef HAVE_GSTAPTX
 | 
					#ifdef HAVE_GSTAPTX
 | 
				
			||||||
extern const pa_a2dp_codec pa_a2dp_codec_aptx;
 | 
					extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx;
 | 
				
			||||||
extern const pa_a2dp_codec pa_a2dp_codec_aptx_hd;
 | 
					extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx_hd;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef HAVE_GSTLDAC
 | 
					#ifdef HAVE_GSTLDAC
 | 
				
			||||||
extern const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_hq;
 | 
					extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq;
 | 
				
			||||||
extern const pa_a2dp_codec pa_a2dp_codec_ldac_eqmid_sq;
 | 
					extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_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_mq;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This is list of supported codecs. Their order is important.
 | 
					/* This is list of supported codecs. Their order is important.
 | 
				
			||||||
 * Codec with lower index has higher priority. */
 | 
					 * 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
 | 
					#ifdef HAVE_GSTLDAC
 | 
				
			||||||
    &pa_a2dp_codec_ldac_eqmid_hq,
 | 
					    &pa_a2dp_endpoint_conf_ldac_eqmid_hq,
 | 
				
			||||||
    &pa_a2dp_codec_ldac_eqmid_sq,
 | 
					    &pa_a2dp_endpoint_conf_ldac_eqmid_sq,
 | 
				
			||||||
    &pa_a2dp_codec_ldac_eqmid_mq,
 | 
					    &pa_a2dp_endpoint_conf_ldac_eqmid_mq,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef HAVE_GSTAPTX
 | 
					#ifdef HAVE_GSTAPTX
 | 
				
			||||||
    &pa_a2dp_codec_aptx_hd,
 | 
					    &pa_a2dp_endpoint_conf_aptx_hd,
 | 
				
			||||||
    &pa_a2dp_codec_aptx,
 | 
					    &pa_a2dp_endpoint_conf_aptx,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    &pa_a2dp_codec_sbc,
 | 
					    &pa_a2dp_endpoint_conf_sbc,
 | 
				
			||||||
    &pa_a2dp_codec_sbc_xq_453,
 | 
					    &pa_a2dp_endpoint_conf_sbc_xq_453,
 | 
				
			||||||
    &pa_a2dp_codec_sbc_xq_512,
 | 
					    &pa_a2dp_endpoint_conf_sbc_xq_512,
 | 
				
			||||||
    &pa_a2dp_codec_sbc_xq_552,
 | 
					    &pa_a2dp_endpoint_conf_sbc_xq_552,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int pa_bluetooth_a2dp_codec_count(void) {
 | 
					unsigned int pa_bluetooth_a2dp_endpoint_conf_count(void) {
 | 
				
			||||||
    return PA_ELEMENTSOF(pa_a2dp_codecs);
 | 
					    return PA_ELEMENTSOF(pa_a2dp_endpoint_configurations);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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) {
 | 
				
			||||||
    pa_assert(i < pa_bluetooth_a2dp_codec_count());
 | 
					    pa_assert(i < pa_bluetooth_a2dp_endpoint_conf_count());
 | 
				
			||||||
    return pa_a2dp_codecs[i];
 | 
					    return pa_a2dp_endpoint_configurations[i];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int pa_bluetooth_hf_codec_count(void) {
 | 
					unsigned int pa_bluetooth_hf_codec_count(void) {
 | 
				
			||||||
    return PA_ELEMENTSOF(pa_hf_codecs);
 | 
					    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());
 | 
					    pa_assert(i < pa_bluetooth_hf_codec_count());
 | 
				
			||||||
    return pa_hf_codecs[i];
 | 
					    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;
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < PA_ELEMENTSOF(pa_hf_codecs); ++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;
 | 
					    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 i;
 | 
				
			||||||
    unsigned int count = pa_bluetooth_a2dp_codec_count();
 | 
					    unsigned int count = pa_bluetooth_a2dp_endpoint_conf_count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < count; i++) {
 | 
					    for (i = 0; i < count; i++) {
 | 
				
			||||||
        if (pa_streq(pa_a2dp_codecs[i]->name, name))
 | 
					        if (pa_streq(pa_a2dp_endpoint_configurations[i]->bt_codec.name, name))
 | 
				
			||||||
            return pa_a2dp_codecs[i];
 | 
					            return pa_a2dp_endpoint_configurations[i];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return NULL;
 | 
					    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) {
 | 
					bool pa_bluetooth_a2dp_codec_is_available(const pa_a2dp_codec_id *id, bool is_a2dp_sink) {
 | 
				
			||||||
    unsigned int i;
 | 
					    unsigned int i;
 | 
				
			||||||
    unsigned int count = pa_bluetooth_a2dp_codec_count();
 | 
					    unsigned int count = pa_bluetooth_a2dp_endpoint_conf_count();
 | 
				
			||||||
    const pa_a2dp_codec *a2dp_codec;
 | 
					    const pa_a2dp_endpoint_conf *conf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < count; i++) {
 | 
					    for (i = 0; i < count; i++) {
 | 
				
			||||||
        a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
					        conf = pa_bluetooth_a2dp_endpoint_conf_iter(i);
 | 
				
			||||||
        if (memcmp(id, &a2dp_codec->id, sizeof(pa_a2dp_codec_id)) == 0
 | 
					        if (memcmp(id, &conf->id, sizeof(pa_a2dp_codec_id)) == 0
 | 
				
			||||||
                && a2dp_codec->can_be_supported(is_a2dp_sink))
 | 
					                && conf->can_be_supported(is_a2dp_sink))
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,13 +23,13 @@
 | 
				
			||||||
#include "a2dp-codec-api.h"
 | 
					#include "a2dp-codec-api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get number of supported A2DP codecs */
 | 
					/* 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 */
 | 
					/* 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 */
 | 
					/* 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 */
 | 
					/* 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);
 | 
					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);
 | 
					unsigned int pa_bluetooth_hf_codec_count(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get i-th codec. Codec with higher number has higher priority */
 | 
					/* 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 */
 | 
					/* 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
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,7 +184,7 @@ pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const
 | 
				
			||||||
    return t;
 | 
					    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_bluetooth_transport_write_cb write_cb, pa_bluetooth_transport_setsockopt_cb setsockopt_cb) {
 | 
				
			||||||
    pa_assert(t);
 | 
					    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,
 | 
					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) {
 | 
					        void (*codec_switch_cb)(bool, pa_bluetooth_profile_t profile, void *), void *userdata) {
 | 
				
			||||||
    DBusMessageIter iter, dict;
 | 
					    DBusMessageIter iter, dict;
 | 
				
			||||||
    DBusMessage *m;
 | 
					    DBusMessage *m;
 | 
				
			||||||
| 
						 | 
					@ -380,7 +380,7 @@ bool pa_bluetooth_device_switch_codec(pa_bluetooth_device *device, pa_bluetooth_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(device);
 | 
					    pa_assert(device);
 | 
				
			||||||
    pa_assert(capabilities_hashmap);
 | 
					    pa_assert(capabilities_hashmap);
 | 
				
			||||||
    pa_assert(a2dp_codec);
 | 
					    pa_assert(endpoint_conf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (device->codec_switching_in_progress) {
 | 
					    if (device->codec_switching_in_progress) {
 | 
				
			||||||
        pa_log_error("Codec switching operation already 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 = NULL;
 | 
				
			||||||
    all_endpoints = pa_hashmap_get(is_a2dp_sink ? device->a2dp_sink_endpoints : device->a2dp_source_endpoints,
 | 
					    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(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));
 | 
					    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);
 | 
					            capabilities->buffer, capabilities->size, config);
 | 
				
			||||||
    if (config_size == 0)
 | 
					    if (config_size == 0)
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_endpoint = pa_sprintf_malloc("%s/%s", is_a2dp_sink ? A2DP_SOURCE_ENDPOINT : A2DP_SINK_ENDPOINT,
 | 
					    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,
 | 
					    pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, endpoint,
 | 
				
			||||||
                BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SetConfiguration"));
 | 
					                BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SetConfiguration"));
 | 
				
			||||||
| 
						 | 
					@ -1169,7 +1169,7 @@ finish:
 | 
				
			||||||
    pa_xfree(endpoint);
 | 
					    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;
 | 
					    DBusMessage *m;
 | 
				
			||||||
    DBusMessageIter i, d;
 | 
					    DBusMessageIter i, d;
 | 
				
			||||||
    uint8_t capabilities[MAX_A2DP_CAPS_SIZE];
 | 
					    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);
 | 
					    pa_log_debug("Registering %s on adapter %s", endpoint, path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    codec_id = a2dp_codec->id.codec_id;
 | 
					    codec_id = endpoint_conf->id.codec_id;
 | 
				
			||||||
    capabilities_size = a2dp_codec->fill_capabilities(capabilities);
 | 
					    capabilities_size = endpoint_conf->fill_capabilities(capabilities);
 | 
				
			||||||
    pa_assert(capabilities_size != 0);
 | 
					    pa_assert(capabilities_size != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, path, BLUEZ_MEDIA_INTERFACE, "RegisterEndpoint"));
 | 
					    pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, path, BLUEZ_MEDIA_INTERFACE, "RegisterEndpoint"));
 | 
				
			||||||
| 
						 | 
					@ -1245,12 +1245,12 @@ finish:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (fallback) {
 | 
					    if (fallback) {
 | 
				
			||||||
        /* If bluez does not support RegisterApplication, fallback to old legacy API with just one SBC codec */
 | 
					        /* If bluez does not support RegisterApplication, fallback to old legacy API with just one SBC codec */
 | 
				
			||||||
        const pa_a2dp_codec *a2dp_codec_sbc;
 | 
					        const pa_a2dp_endpoint_conf *endpoint_conf;
 | 
				
			||||||
        a2dp_codec_sbc = pa_bluetooth_get_a2dp_codec("sbc");
 | 
					        endpoint_conf = pa_bluetooth_get_a2dp_endpoint_conf("sbc");
 | 
				
			||||||
        pa_assert(a2dp_codec_sbc);
 | 
					        pa_assert(endpoint_conf);
 | 
				
			||||||
        register_legacy_sbc_endpoint(y, a2dp_codec_sbc, path, A2DP_SINK_ENDPOINT "/sbc",
 | 
					        register_legacy_sbc_endpoint(y, endpoint_conf, path, A2DP_SINK_ENDPOINT "/sbc",
 | 
				
			||||||
                PA_BLUETOOTH_UUID_A2DP_SINK);
 | 
					                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_BLUETOOTH_UUID_A2DP_SOURCE);
 | 
				
			||||||
        pa_log_warn("Only SBC codec is available for A2DP profiles");
 | 
					        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();
 | 
					    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;
 | 
					    const char *codec_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_startswith(endpoint, A2DP_SINK_ENDPOINT "/"))
 | 
					    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
 | 
					    else
 | 
				
			||||||
        return NULL;
 | 
					        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) {
 | 
					static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
 | 
				
			||||||
    pa_bluetooth_discovery *y = userdata;
 | 
					    pa_bluetooth_discovery *y = userdata;
 | 
				
			||||||
    pa_bluetooth_device *d;
 | 
					    pa_bluetooth_device *d;
 | 
				
			||||||
    pa_bluetooth_transport *t;
 | 
					    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 char *sender, *path, *endpoint_path, *dev_path = NULL, *uuid = NULL;
 | 
				
			||||||
    const uint8_t *config = NULL;
 | 
					    const uint8_t *config = NULL;
 | 
				
			||||||
    int size = 0;
 | 
					    int size = 0;
 | 
				
			||||||
| 
						 | 
					@ -1925,17 +1925,17 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            dbus_message_iter_get_fixed_array(&array, &config, &size);
 | 
					            dbus_message_iter_get_fixed_array(&array, &config, &size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            a2dp_codec = a2dp_endpoint_to_a2dp_codec(endpoint_path);
 | 
					            endpoint_conf = a2dp_sep_to_a2dp_endpoint_conf(endpoint_path);
 | 
				
			||||||
            pa_assert(a2dp_codec);
 | 
					            pa_assert(endpoint_conf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!a2dp_codec->is_configuration_valid(config, size))
 | 
					            if (!endpoint_conf->is_configuration_valid(config, size))
 | 
				
			||||||
                goto fail;
 | 
					                goto fail;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dbus_message_iter_next(&props);
 | 
					        dbus_message_iter_next(&props);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!a2dp_codec)
 | 
					    if (!endpoint_conf)
 | 
				
			||||||
        goto fail2;
 | 
					        goto fail2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((d = pa_hashmap_get(y->devices, dev_path))) {
 | 
					    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 = pa_bluetooth_transport_new(d, sender, path, p, config, size);
 | 
				
			||||||
    t->acquire = bluez5_transport_acquire_cb;
 | 
					    t->acquire = bluez5_transport_acquire_cb;
 | 
				
			||||||
    t->release = bluez5_transport_release_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_bluetooth_transport_put(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
 | 
					    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;
 | 
					    return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1984,7 +1984,7 @@ static DBusMessage *endpoint_select_configuration(DBusConnection *conn, DBusMess
 | 
				
			||||||
    const char *endpoint_path;
 | 
					    const char *endpoint_path;
 | 
				
			||||||
    uint8_t *cap;
 | 
					    uint8_t *cap;
 | 
				
			||||||
    int size;
 | 
					    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[MAX_A2DP_CAPS_SIZE];
 | 
				
			||||||
    uint8_t *config_ptr = config;
 | 
					    uint8_t *config_ptr = config;
 | 
				
			||||||
    size_t config_size;
 | 
					    size_t config_size;
 | 
				
			||||||
| 
						 | 
					@ -2001,10 +2001,10 @@ static DBusMessage *endpoint_select_configuration(DBusConnection *conn, DBusMess
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a2dp_codec = a2dp_endpoint_to_a2dp_codec(endpoint_path);
 | 
					    endpoint_conf = a2dp_sep_to_a2dp_endpoint_conf(endpoint_path);
 | 
				
			||||||
    pa_assert(a2dp_codec);
 | 
					    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)
 | 
					    if (config_size == 0)
 | 
				
			||||||
        goto fail;
 | 
					        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);
 | 
					    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;
 | 
					        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) {
 | 
					    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,
 | 
					                                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
 | 
				
			||||||
                                         &array);
 | 
					                                         &array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < pa_bluetooth_a2dp_codec_count(); i++) {
 | 
					        for (i = 0; i < pa_bluetooth_a2dp_endpoint_conf_count(); i++) {
 | 
				
			||||||
            const pa_a2dp_codec *a2dp_codec;
 | 
					            const pa_a2dp_endpoint_conf *endpoint_conf;
 | 
				
			||||||
            uint8_t capabilities[MAX_A2DP_CAPS_SIZE];
 | 
					            uint8_t capabilities[MAX_A2DP_CAPS_SIZE];
 | 
				
			||||||
            uint8_t capabilities_size;
 | 
					            uint8_t capabilities_size;
 | 
				
			||||||
            uint8_t codec_id;
 | 
					            uint8_t codec_id;
 | 
				
			||||||
            char *endpoint;
 | 
					            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)) {
 | 
					            if (endpoint_conf->can_be_supported(false)) {
 | 
				
			||||||
                capabilities_size = a2dp_codec->fill_capabilities(capabilities);
 | 
					                capabilities_size = endpoint_conf->fill_capabilities(capabilities);
 | 
				
			||||||
                pa_assert(capabilities_size != 0);
 | 
					                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,
 | 
					                append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SINK, codec_id,
 | 
				
			||||||
                        capabilities, capabilities_size);
 | 
					                        capabilities, capabilities_size);
 | 
				
			||||||
                pa_xfree(endpoint);
 | 
					                pa_xfree(endpoint);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (a2dp_codec->can_be_supported(true)) {
 | 
					            if (endpoint_conf->can_be_supported(true)) {
 | 
				
			||||||
                capabilities_size = a2dp_codec->fill_capabilities(capabilities);
 | 
					                capabilities_size = endpoint_conf->fill_capabilities(capabilities);
 | 
				
			||||||
                pa_assert(capabilities_size != 0);
 | 
					                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,
 | 
					                append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SOURCE, codec_id,
 | 
				
			||||||
                        capabilities, capabilities_size);
 | 
					                        capabilities, capabilities_size);
 | 
				
			||||||
                pa_xfree(endpoint);
 | 
					                pa_xfree(endpoint);
 | 
				
			||||||
| 
						 | 
					@ -2273,7 +2273,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backe
 | 
				
			||||||
    DBusError err;
 | 
					    DBusError err;
 | 
				
			||||||
    DBusConnection *conn;
 | 
					    DBusConnection *conn;
 | 
				
			||||||
    unsigned i, count;
 | 
					    unsigned i, count;
 | 
				
			||||||
    const pa_a2dp_codec *a2dp_codec;
 | 
					    const pa_a2dp_endpoint_conf *endpoint_conf;
 | 
				
			||||||
    char *endpoint;
 | 
					    char *endpoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_bluetooth_a2dp_codec_gst_init();
 | 
					    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);
 | 
					    object_manager_init(y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    count = pa_bluetooth_a2dp_codec_count();
 | 
					    count = pa_bluetooth_a2dp_endpoint_conf_count();
 | 
				
			||||||
    for (i = 0; i < count; i++) {
 | 
					    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)) {
 | 
					        if (endpoint_conf->can_be_supported(false)) {
 | 
				
			||||||
            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);
 | 
				
			||||||
            endpoint_init(y, endpoint);
 | 
					            endpoint_init(y, endpoint);
 | 
				
			||||||
            pa_xfree(endpoint);
 | 
					            pa_xfree(endpoint);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (a2dp_codec->can_be_supported(true)) {
 | 
					        if (endpoint_conf->can_be_supported(true)) {
 | 
				
			||||||
            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);
 | 
				
			||||||
            endpoint_init(y, endpoint);
 | 
					            endpoint_init(y, endpoint);
 | 
				
			||||||
            pa_xfree(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) {
 | 
					void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 | 
				
			||||||
    unsigned i, count;
 | 
					    unsigned i, count;
 | 
				
			||||||
    const pa_a2dp_codec *a2dp_codec;
 | 
					    const pa_a2dp_endpoint_conf *endpoint_conf;
 | 
				
			||||||
    char *endpoint;
 | 
					    char *endpoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(y);
 | 
					    pa_assert(y);
 | 
				
			||||||
| 
						 | 
					@ -2422,18 +2422,18 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        object_manager_done(y);
 | 
					        object_manager_done(y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        count = pa_bluetooth_a2dp_codec_count();
 | 
					        count = pa_bluetooth_a2dp_endpoint_conf_count();
 | 
				
			||||||
        for (i = 0; i < count; i++) {
 | 
					        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)) {
 | 
					            if (endpoint_conf->can_be_supported(false)) {
 | 
				
			||||||
                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);
 | 
				
			||||||
                endpoint_done(y, endpoint);
 | 
					                endpoint_done(y, endpoint);
 | 
				
			||||||
                pa_xfree(endpoint);
 | 
					                pa_xfree(endpoint);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (a2dp_codec->can_be_supported(true)) {
 | 
					            if (endpoint_conf->can_be_supported(true)) {
 | 
				
			||||||
                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);
 | 
				
			||||||
                endpoint_done(y, endpoint);
 | 
					                endpoint_done(y, endpoint);
 | 
				
			||||||
                pa_xfree(endpoint);
 | 
					                pa_xfree(endpoint);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,7 @@ struct pa_bluetooth_transport {
 | 
				
			||||||
    void *config;
 | 
					    void *config;
 | 
				
			||||||
    size_t config_size;
 | 
					    size_t config_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const pa_a2dp_codec *bt_codec;
 | 
					    const pa_bt_codec *bt_codec;
 | 
				
			||||||
    int stream_write_type;
 | 
					    int stream_write_type;
 | 
				
			||||||
    size_t last_read_size;
 | 
					    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_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);
 | 
					                                                   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);
 | 
					                                        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_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);
 | 
					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_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_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);
 | 
					pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										67
									
								
								src/modules/bluetooth/bt-codec-api.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/modules/bluetooth/bt-codec-api.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,8 @@
 | 
				
			||||||
#include <config.h>
 | 
					#include <config.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "a2dp-codec-api.h"
 | 
					#include <pulsecore/core.h>
 | 
				
			||||||
 | 
					#include "bt-codec-api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct codec_info {
 | 
					typedef struct codec_info {
 | 
				
			||||||
    pa_sample_spec sample_spec;
 | 
					    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 */
 | 
					/* 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",
 | 
					    .name = "CVSD",
 | 
				
			||||||
    .description = "CVSD",
 | 
					    .description = "CVSD",
 | 
				
			||||||
    .init = init,
 | 
					    .init = init,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,8 @@
 | 
				
			||||||
#include <config.h>
 | 
					#include <config.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "a2dp-codec-api.h"
 | 
					#include <pulsecore/core.h>
 | 
				
			||||||
 | 
					#include "bt-codec-api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "bt-codec-msbc.h"
 | 
					#include "bt-codec-msbc.h"
 | 
				
			||||||
#include <sbc/sbc.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*/
 | 
					/* 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",
 | 
					    .name = "mSBC",
 | 
				
			||||||
    .description = "mSBC",
 | 
					    .description = "mSBC",
 | 
				
			||||||
    .init = init,
 | 
					    .init = init,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,7 +138,7 @@ struct userdata {
 | 
				
			||||||
    pa_smoother *read_smoother;
 | 
					    pa_smoother *read_smoother;
 | 
				
			||||||
    pa_memchunk write_memchunk;
 | 
					    pa_memchunk write_memchunk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const pa_a2dp_codec *bt_codec;
 | 
					    const pa_bt_codec *bt_codec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void *encoder_info;
 | 
					    void *encoder_info;
 | 
				
			||||||
    pa_sample_spec encoder_sample_spec;
 | 
					    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;
 | 
					        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) {
 | 
					        PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, a2dp_endpoints, state) {
 | 
				
			||||||
            for (i = 0; i < pa_bluetooth_a2dp_codec_count(); i++) {
 | 
					            for (i = 0; i < pa_bluetooth_a2dp_endpoint_conf_count(); i++) {
 | 
				
			||||||
                const pa_a2dp_codec *a2dp_codec;
 | 
					                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 (memcmp(key, &endpoint_conf->id, sizeof(pa_a2dp_codec_id)) == 0) {
 | 
				
			||||||
                    if (a2dp_codec->can_be_supported(is_a2dp_sink)) {
 | 
					                    if (endpoint_conf->can_be_supported(is_a2dp_sink)) {
 | 
				
			||||||
                        pa_json_encoder_begin_element_object(encoder);
 | 
					                        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, "name", endpoint_conf->bt_codec.name);
 | 
				
			||||||
                        pa_json_encoder_add_member_string(encoder, "description", a2dp_codec->description);
 | 
					                        pa_json_encoder_add_member_string(encoder, "description", endpoint_conf->bt_codec.description);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        pa_json_encoder_end_object(encoder);
 | 
					                        pa_json_encoder_end_object(encoder);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					@ -2391,7 +2391,7 @@ static char *list_codecs(struct userdata *u) {
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* find out active codec selection from device profile */
 | 
					        /* find out active codec selection from device profile */
 | 
				
			||||||
        for (i = 0; i < pa_bluetooth_hf_codec_count(); i++) {
 | 
					        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);
 | 
					            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;
 | 
					    char *message_handler_path;
 | 
				
			||||||
    pa_hashmap *capabilities_hashmap;
 | 
					    pa_hashmap *capabilities_hashmap;
 | 
				
			||||||
    pa_bluetooth_profile_t profile;
 | 
					    pa_bluetooth_profile_t profile;
 | 
				
			||||||
    const pa_a2dp_codec *codec;
 | 
					    const pa_a2dp_endpoint_conf *endpoint_conf;
 | 
				
			||||||
    const char *codec_name;
 | 
					    const char *codec_name;
 | 
				
			||||||
    struct userdata *u;
 | 
					    struct userdata *u;
 | 
				
			||||||
    bool is_a2dp_sink;
 | 
					    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;
 | 
					            return -PA_ERR_INVALID;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        codec = pa_bluetooth_get_a2dp_codec(codec_name);
 | 
					        endpoint_conf = pa_bluetooth_get_a2dp_endpoint_conf(codec_name);
 | 
				
			||||||
        if (codec == NULL) {
 | 
					        if (endpoint_conf == NULL) {
 | 
				
			||||||
            pa_log_info("Invalid codec %s specified for switching", codec_name);
 | 
					            pa_log_info("Invalid codec %s specified for switching", codec_name);
 | 
				
			||||||
            return -PA_ERR_INVALID;
 | 
					            return -PA_ERR_INVALID;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
 | 
					        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");
 | 
					            pa_log_info("Codec not found on system");
 | 
				
			||||||
            return -PA_ERR_NOTSUPPORTED;
 | 
					            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;
 | 
					            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) {
 | 
					        if (!capabilities_hashmap) {
 | 
				
			||||||
            pa_log_info("No remote endpoint found for %s codec. Codec not supported by remote endpoint.",
 | 
					            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;
 | 
					            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
 | 
					         * 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);
 | 
					        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)
 | 
					                && !u->device->codec_switching_in_progress)
 | 
				
			||||||
            goto profile_off;
 | 
					            goto profile_off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue