mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	a2dp: allow codec to hold Props params
Initial Props value are parsed from device settings, further changes are triggered by 'set_param' on a2dp node. Codec can then use props to tweak its transcoder.
This commit is contained in:
		
							parent
							
								
									6512c2b5f6
								
							
						
					
					
						commit
						1d390addb1
					
				
					 7 changed files with 123 additions and 23 deletions
				
			
		| 
						 | 
					@ -235,7 +235,7 @@ static int codec_enum_config(const struct a2dp_codec *codec,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
					static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
				
			||||||
		void *config, size_t config_len, const struct spa_audio_info *info,
 | 
							void *config, size_t config_len, const struct spa_audio_info *info,
 | 
				
			||||||
		const struct spa_dict *settings, size_t mtu)
 | 
							void *props, size_t mtu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *this;
 | 
						struct impl *this;
 | 
				
			||||||
	a2dp_aac_t *conf = config;
 | 
						a2dp_aac_t *conf = config;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -223,7 +223,7 @@ static int codec_get_block_size(void *data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
					static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
				
			||||||
		void *config, size_t config_len, const struct spa_audio_info *info,
 | 
							void *config, size_t config_len, const struct spa_audio_info *info,
 | 
				
			||||||
		const struct spa_dict *settings, size_t mtu)
 | 
							void *props, size_t mtu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *this;
 | 
						struct impl *this;
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,8 @@
 | 
				
			||||||
#include "rtp.h"
 | 
					#include "rtp.h"
 | 
				
			||||||
#include "a2dp-codecs.h"
 | 
					#include "a2dp-codecs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LDACBT_EQMID_AUTO -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LDAC_ABR_MAX_PACKET_NBYTES 1280
 | 
					#define LDAC_ABR_MAX_PACKET_NBYTES 1280
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LDAC_ABR_INTERVAL_MS 5 /* 2 frames * 128 lsu / 48000 */
 | 
					#define LDAC_ABR_INTERVAL_MS 5 /* 2 frames * 128 lsu / 48000 */
 | 
				
			||||||
| 
						 | 
					@ -51,6 +53,10 @@
 | 
				
			||||||
#define LDAC_ABR_SOCK_BUFFER_SIZE (LDAC_ABR_THRESHOLD_CRITICAL * LDAC_ABR_MAX_PACKET_NBYTES)
 | 
					#define LDAC_ABR_SOCK_BUFFER_SIZE (LDAC_ABR_THRESHOLD_CRITICAL * LDAC_ABR_MAX_PACKET_NBYTES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct props {
 | 
				
			||||||
 | 
						int eqmid;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct impl {
 | 
					struct impl {
 | 
				
			||||||
	HANDLE_LDAC_BT ldac;
 | 
						HANDLE_LDAC_BT ldac;
 | 
				
			||||||
#ifdef ENABLE_LDAC_ABR
 | 
					#ifdef ENABLE_LDAC_ABR
 | 
				
			||||||
| 
						 | 
					@ -317,7 +323,7 @@ static int codec_get_block_size(void *data)
 | 
				
			||||||
static int string_to_eqmid(const char * eqmid)
 | 
					static int string_to_eqmid(const char * eqmid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!strcmp("auto", eqmid))
 | 
						if (!strcmp("auto", eqmid))
 | 
				
			||||||
		return LDACBT_EQMID_ABR;
 | 
							return LDACBT_EQMID_AUTO;
 | 
				
			||||||
	else if (!strcmp("hq", eqmid))
 | 
						else if (!strcmp("hq", eqmid))
 | 
				
			||||||
		return LDACBT_EQMID_HQ;
 | 
							return LDACBT_EQMID_HQ;
 | 
				
			||||||
	else if (!strcmp("sq", eqmid))
 | 
						else if (!strcmp("sq", eqmid))
 | 
				
			||||||
| 
						 | 
					@ -325,17 +331,37 @@ static int string_to_eqmid(const char * eqmid)
 | 
				
			||||||
	else if (!strcmp("mq", eqmid))
 | 
						else if (!strcmp("mq", eqmid))
 | 
				
			||||||
		return LDACBT_EQMID_MQ;
 | 
							return LDACBT_EQMID_MQ;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		return LDACBT_EQMID_ABR;
 | 
							return LDACBT_EQMID_AUTO;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *codec_init_props(const struct a2dp_codec *codec, const struct spa_dict *settings)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct props *p = calloc(1, sizeof(struct props));
 | 
				
			||||||
 | 
						const char *str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (p == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (settings == NULL || (str = spa_dict_lookup(settings, "bluez5.a2dp.ldac.quality")) == NULL)
 | 
				
			||||||
 | 
							str = "auto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p->eqmid = string_to_eqmid(str);
 | 
				
			||||||
 | 
						return p;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void codec_clear_props(void *props)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						free(props);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
					static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
				
			||||||
		void *config, size_t config_len, const struct spa_audio_info *info,
 | 
							void *config, size_t config_len, const struct spa_audio_info *info,
 | 
				
			||||||
		const struct spa_dict *settings, size_t mtu)
 | 
							void *props, size_t mtu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *this;
 | 
						struct impl *this;
 | 
				
			||||||
	a2dp_ldac_t *conf = config;
 | 
						a2dp_ldac_t *conf = config;
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
	const char *str;
 | 
						struct props *p = props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this = calloc(1, sizeof(struct impl));
 | 
						this = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (this == NULL)
 | 
						if (this == NULL)
 | 
				
			||||||
| 
						 | 
					@ -351,12 +377,12 @@ static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
				
			||||||
		goto error_errno;
 | 
							goto error_errno;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((str = spa_dict_lookup(settings, "bluez5.a2dp.ldac.quality")) == NULL)
 | 
						if (p == NULL || p->eqmid == LDACBT_EQMID_AUTO) {
 | 
				
			||||||
		str = "auto";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((this->eqmid = string_to_eqmid(str)) == LDACBT_EQMID_ABR) {
 | 
					 | 
				
			||||||
		this->eqmid = LDACBT_EQMID_SQ;
 | 
							this->eqmid = LDACBT_EQMID_SQ;
 | 
				
			||||||
		this->enable_abr = true;
 | 
							this->enable_abr = true;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							this->eqmid = p->eqmid;
 | 
				
			||||||
 | 
							this->enable_abr = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->mtu = mtu;
 | 
						this->mtu = mtu;
 | 
				
			||||||
| 
						 | 
					@ -520,6 +546,8 @@ const struct a2dp_codec a2dp_codec_ldac = {
 | 
				
			||||||
	.fill_caps = codec_fill_caps,
 | 
						.fill_caps = codec_fill_caps,
 | 
				
			||||||
	.select_config = codec_select_config,
 | 
						.select_config = codec_select_config,
 | 
				
			||||||
	.enum_config = codec_enum_config,
 | 
						.enum_config = codec_enum_config,
 | 
				
			||||||
 | 
						.init_props = codec_init_props,
 | 
				
			||||||
 | 
						.clear_props = codec_clear_props,
 | 
				
			||||||
	.init = codec_init,
 | 
						.init = codec_init,
 | 
				
			||||||
	.deinit = codec_deinit,
 | 
						.deinit = codec_deinit,
 | 
				
			||||||
	.get_block_size = codec_get_block_size,
 | 
						.get_block_size = codec_get_block_size,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -427,7 +427,7 @@ static int codec_get_block_size(void *data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
					static void *codec_init(const struct a2dp_codec *codec, uint32_t flags,
 | 
				
			||||||
		void *config, size_t config_len, const struct spa_audio_info *info,
 | 
							void *config, size_t config_len, const struct spa_audio_info *info,
 | 
				
			||||||
		const struct spa_dict *settings, size_t mtu)
 | 
							void *props, size_t mtu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *this;
 | 
						struct impl *this;
 | 
				
			||||||
	a2dp_sbc_t *conf = config;
 | 
						a2dp_sbc_t *conf = config;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -356,11 +356,17 @@ struct a2dp_codec {
 | 
				
			||||||
	int (*caps_preference_cmp) (const struct a2dp_codec *codec, const void *caps1, size_t caps1_size,
 | 
						int (*caps_preference_cmp) (const struct a2dp_codec *codec, const void *caps1, size_t caps1_size,
 | 
				
			||||||
			const void *caps2, size_t caps2_size);
 | 
								const void *caps2, size_t caps2_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *(*init_props) (const struct a2dp_codec *codec, const struct spa_dict *settings);
 | 
				
			||||||
 | 
						void (*clear_props) (void *);
 | 
				
			||||||
 | 
						int (*enum_props) (void *props, const struct spa_dict *settings, uint32_t id, uint32_t idx,
 | 
				
			||||||
 | 
								struct spa_pod_builder *builder, struct spa_pod **param);
 | 
				
			||||||
 | 
						int (*set_props) (void *props, const struct spa_pod *param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void *(*init) (const struct a2dp_codec *codec, uint32_t flags, void *config, size_t config_size,
 | 
						void *(*init) (const struct a2dp_codec *codec, uint32_t flags, void *config, size_t config_size,
 | 
				
			||||||
			const struct spa_audio_info *info, const struct spa_dict *settings, size_t mtu);
 | 
								const struct spa_audio_info *info, void *props, size_t mtu);
 | 
				
			||||||
	void (*deinit) (void *data);
 | 
						void (*deinit) (void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int (*update_settings) (void *data, const struct spa_dict *settings);
 | 
						int (*update_props) (void *data, void *props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int (*get_block_size) (void *data);
 | 
						int (*get_block_size) (void *data);
 | 
				
			||||||
	int (*get_num_blocks) (void *data);
 | 
						int (*get_num_blocks) (void *data);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,6 +128,8 @@ struct impl {
 | 
				
			||||||
	uint64_t last_error;
 | 
						uint64_t last_error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const struct a2dp_codec *codec;
 | 
						const struct a2dp_codec *codec;
 | 
				
			||||||
 | 
						bool codec_props_changed;
 | 
				
			||||||
 | 
						void *codec_props;
 | 
				
			||||||
	void *codec_data;
 | 
						void *codec_data;
 | 
				
			||||||
	struct spa_audio_info codec_format;
 | 
						struct spa_audio_info codec_format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,7 +169,8 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
	struct spa_pod_builder b = { 0 };
 | 
						struct spa_pod_builder b = { 0 };
 | 
				
			||||||
	uint8_t buffer[1024];
 | 
						uint8_t buffer[1024];
 | 
				
			||||||
	struct spa_result_node_params result;
 | 
						struct spa_result_node_params result;
 | 
				
			||||||
	uint32_t count = 0;
 | 
						uint32_t count = 0, index_offset = 0;
 | 
				
			||||||
 | 
						bool enum_codec = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_return_val_if_fail(this != NULL, -EINVAL);
 | 
						spa_return_val_if_fail(this != NULL, -EINVAL);
 | 
				
			||||||
	spa_return_val_if_fail(num != 0, -EINVAL);
 | 
						spa_return_val_if_fail(num != 0, -EINVAL);
 | 
				
			||||||
| 
						 | 
					@ -207,7 +210,8 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
				SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0, INT64_MIN, INT64_MAX));
 | 
									SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0, INT64_MIN, INT64_MAX));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return 0;
 | 
								enum_codec = true;
 | 
				
			||||||
 | 
								index_offset = 3;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -224,7 +228,8 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
				SPA_PROP_latencyOffsetNsec, SPA_POD_Long(p->latency_offset));
 | 
									SPA_PROP_latencyOffsetNsec, SPA_POD_Long(p->latency_offset));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return 0;
 | 
								enum_codec = true;
 | 
				
			||||||
 | 
								index_offset = 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -232,6 +237,16 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enum_codec) {
 | 
				
			||||||
 | 
							int res;
 | 
				
			||||||
 | 
							if (this->codec->enum_props == NULL || this->codec_props == NULL)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							else if ((res = this->codec->enum_props(this->codec_props,
 | 
				
			||||||
 | 
										this->transport->device->settings,
 | 
				
			||||||
 | 
										id, result.index - index_offset, &b, ¶m)) != 1)
 | 
				
			||||||
 | 
								return res;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
						if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
				
			||||||
		goto next;
 | 
							goto next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -340,7 +355,14 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
 | 
				
			||||||
	switch (id) {
 | 
						switch (id) {
 | 
				
			||||||
	case SPA_PARAM_Props:
 | 
						case SPA_PARAM_Props:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (apply_props(this, param) > 0) {
 | 
							int res, codec_res = 0;
 | 
				
			||||||
 | 
							res = apply_props(this, param);
 | 
				
			||||||
 | 
							if (this->codec_props && this->codec->set_props) {
 | 
				
			||||||
 | 
								codec_res = this->codec->set_props(this->codec_props, param);
 | 
				
			||||||
 | 
								if (codec_res > 0)
 | 
				
			||||||
 | 
									this->codec_props_changed = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (res > 0 || codec_res > 0) {
 | 
				
			||||||
			this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
 | 
								this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
 | 
				
			||||||
			this->params[1].flags ^= SPA_PARAM_INFO_SERIAL;
 | 
								this->params[1].flags ^= SPA_PARAM_INFO_SERIAL;
 | 
				
			||||||
			emit_node_info(this, false);
 | 
								emit_node_info(this, false);
 | 
				
			||||||
| 
						 | 
					@ -361,6 +383,11 @@ static void update_num_blocks(struct impl *this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int reset_buffer(struct impl *this)
 | 
					static int reset_buffer(struct impl *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (this->codec_props_changed && this->codec_props
 | 
				
			||||||
 | 
								&& this->codec->update_props) {
 | 
				
			||||||
 | 
							this->codec->update_props(this->codec_data, this->codec_props);
 | 
				
			||||||
 | 
							this->codec_props_changed = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	this->frame_count = 0;
 | 
						this->frame_count = 0;
 | 
				
			||||||
	this->buffer_used = this->codec->start_encode(this->codec_data,
 | 
						this->buffer_used = this->codec->start_encode(this->codec_data,
 | 
				
			||||||
			this->buffer, sizeof(this->buffer),
 | 
								this->buffer, sizeof(this->buffer),
 | 
				
			||||||
| 
						 | 
					@ -708,7 +735,7 @@ static int do_start(struct impl *this)
 | 
				
			||||||
			this->transport->configuration,
 | 
								this->transport->configuration,
 | 
				
			||||||
			this->transport->configuration_len,
 | 
								this->transport->configuration_len,
 | 
				
			||||||
			&port->current_format,
 | 
								&port->current_format,
 | 
				
			||||||
			this->transport->device->settings,
 | 
								this->codec_props,
 | 
				
			||||||
			this->transport->write_mtu);
 | 
								this->transport->write_mtu);
 | 
				
			||||||
	if (this->codec_data == NULL)
 | 
						if (this->codec_data == NULL)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
| 
						 | 
					@ -1317,6 +1344,8 @@ static int impl_clear(struct spa_handle *handle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->codec_data)
 | 
						if (this->codec_data)
 | 
				
			||||||
		this->codec->deinit(this->codec_data);
 | 
							this->codec->deinit(this->codec_data);
 | 
				
			||||||
 | 
						if (this->codec_props && this->codec->clear_props)
 | 
				
			||||||
 | 
							this->codec->clear_props(this->codec_props);
 | 
				
			||||||
	if (this->transport)
 | 
						if (this->transport)
 | 
				
			||||||
		spa_hook_remove(&this->transport_listener);
 | 
							spa_hook_remove(&this->transport_listener);
 | 
				
			||||||
	spa_system_close(this->data_system, this->timerfd);
 | 
						spa_system_close(this->data_system, this->timerfd);
 | 
				
			||||||
| 
						 | 
					@ -1408,6 +1437,9 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	this->codec = this->transport->a2dp_codec;
 | 
						this->codec = this->transport->a2dp_codec;
 | 
				
			||||||
 | 
						if (this->codec->init_props != NULL)
 | 
				
			||||||
 | 
							this->codec_props = this->codec->init_props(this->codec,
 | 
				
			||||||
 | 
										this->transport->device->settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_bt_transport_add_listener(this->transport,
 | 
						spa_bt_transport_add_listener(this->transport,
 | 
				
			||||||
			&this->transport_listener, &transport_events, this);
 | 
								&this->transport_listener, &transport_events, this);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,6 +120,8 @@ struct impl {
 | 
				
			||||||
        struct spa_io_position *position;
 | 
					        struct spa_io_position *position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const struct a2dp_codec *codec;
 | 
						const struct a2dp_codec *codec;
 | 
				
			||||||
 | 
						bool codec_props_changed;
 | 
				
			||||||
 | 
						void *codec_props;
 | 
				
			||||||
	void *codec_data;
 | 
						void *codec_data;
 | 
				
			||||||
	struct spa_audio_info codec_format;
 | 
						struct spa_audio_info codec_format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,7 +153,8 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
	struct spa_pod_builder b = { 0 };
 | 
						struct spa_pod_builder b = { 0 };
 | 
				
			||||||
	uint8_t buffer[1024];
 | 
						uint8_t buffer[1024];
 | 
				
			||||||
	struct spa_result_node_params result;
 | 
						struct spa_result_node_params result;
 | 
				
			||||||
	uint32_t count = 0;
 | 
						uint32_t count = 0, index_offset = 0;
 | 
				
			||||||
 | 
						bool enum_codec = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_return_val_if_fail(this != NULL, -EINVAL);
 | 
						spa_return_val_if_fail(this != NULL, -EINVAL);
 | 
				
			||||||
	spa_return_val_if_fail(num != 0, -EINVAL);
 | 
						spa_return_val_if_fail(num != 0, -EINVAL);
 | 
				
			||||||
| 
						 | 
					@ -184,7 +187,8 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
				SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->max_latency, 1, INT32_MAX));
 | 
									SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->max_latency, 1, INT32_MAX));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return 0;
 | 
								enum_codec = true;
 | 
				
			||||||
 | 
								index_offset = 2;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -200,7 +204,8 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
				SPA_PROP_maxLatency, SPA_POD_Int(p->max_latency));
 | 
									SPA_PROP_maxLatency, SPA_POD_Int(p->max_latency));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return 0;
 | 
								enum_codec = true;
 | 
				
			||||||
 | 
								index_offset = 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -208,6 +213,17 @@ static int impl_node_enum_params(void *object, int seq,
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enum_codec) {
 | 
				
			||||||
 | 
							int res;
 | 
				
			||||||
 | 
							if (this->codec->enum_props == NULL || this->codec_props == NULL)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							else if ((res = this->codec->enum_props(this->codec_props,
 | 
				
			||||||
 | 
										this->transport->device->settings,
 | 
				
			||||||
 | 
										id, result.index - index_offset,
 | 
				
			||||||
 | 
										&b, ¶m)) != 1)
 | 
				
			||||||
 | 
								return res;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
						if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
				
			||||||
		goto next;
 | 
							goto next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -292,7 +308,14 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
 | 
				
			||||||
	switch (id) {
 | 
						switch (id) {
 | 
				
			||||||
	case SPA_PARAM_Props:
 | 
						case SPA_PARAM_Props:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (apply_props(this, param) > 0) {
 | 
							int res, codec_res = 0;
 | 
				
			||||||
 | 
							res = apply_props(this, param);
 | 
				
			||||||
 | 
							if (this->codec_props && this->codec->set_props) {
 | 
				
			||||||
 | 
								codec_res = this->codec->set_props(this->codec_props, param);
 | 
				
			||||||
 | 
								if (codec_res > 0)
 | 
				
			||||||
 | 
									this->codec_props_changed = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (res > 0 || codec_res > 0) {
 | 
				
			||||||
			this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
 | 
								this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
 | 
				
			||||||
			this->params[1].flags ^= SPA_PARAM_INFO_SERIAL;
 | 
								this->params[1].flags ^= SPA_PARAM_INFO_SERIAL;
 | 
				
			||||||
			emit_node_info(this, false);
 | 
								emit_node_info(this, false);
 | 
				
			||||||
| 
						 | 
					@ -438,6 +461,12 @@ static void a2dp_on_ready_read(struct spa_source *source)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	spa_log_trace(this->log, "read socket data %d", size_read);
 | 
						spa_log_trace(this->log, "read socket data %d", size_read);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (this->codec_props_changed && this->codec_props
 | 
				
			||||||
 | 
								&& this->codec->update_props) {
 | 
				
			||||||
 | 
							this->codec->update_props(this->codec_data, this->codec_props);
 | 
				
			||||||
 | 
							this->codec_props_changed = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* decode */
 | 
						/* decode */
 | 
				
			||||||
	decoded = decode_data(this, this->buffer_read, size_read,
 | 
						decoded = decode_data(this, this->buffer_read, size_read,
 | 
				
			||||||
			read_decoded, sizeof (read_decoded));
 | 
								read_decoded, sizeof (read_decoded));
 | 
				
			||||||
| 
						 | 
					@ -569,7 +598,7 @@ static int transport_start(struct impl *this)
 | 
				
			||||||
			this->transport->configuration,
 | 
								this->transport->configuration,
 | 
				
			||||||
			this->transport->configuration_len,
 | 
								this->transport->configuration_len,
 | 
				
			||||||
			&port->current_format,
 | 
								&port->current_format,
 | 
				
			||||||
			this->transport->device->settings,
 | 
								this->codec_props,
 | 
				
			||||||
			this->transport->read_mtu);
 | 
								this->transport->read_mtu);
 | 
				
			||||||
	if (this->codec_data == NULL)
 | 
						if (this->codec_data == NULL)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
| 
						 | 
					@ -1186,6 +1215,8 @@ static int impl_clear(struct spa_handle *handle)
 | 
				
			||||||
	struct impl *this = (struct impl *) handle;
 | 
						struct impl *this = (struct impl *) handle;
 | 
				
			||||||
	if (this->codec_data)
 | 
						if (this->codec_data)
 | 
				
			||||||
		this->codec->deinit(this->codec_data);
 | 
							this->codec->deinit(this->codec_data);
 | 
				
			||||||
 | 
						if (this->codec_props && this->codec->clear_props)
 | 
				
			||||||
 | 
							this->codec->clear_props(this->codec_props);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1282,6 +1313,9 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	this->codec = this->transport->a2dp_codec;
 | 
						this->codec = this->transport->a2dp_codec;
 | 
				
			||||||
 | 
						if (this->codec->init_props != NULL)
 | 
				
			||||||
 | 
							this->codec_props = this->codec->init_props(this->codec,
 | 
				
			||||||
 | 
										this->transport->device->settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue