mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	bluez5: adjust codec profile priority ordering
Higher priority for A2DP over HFP/HSP. Prefer mSBC over CVSD for HFP, and put A2DP codecs in the order we tell BlueZ to use. Ensures that picking highest-priority profile gives sensible results (e.g. does not pick HFP unless input route is required, and prefers A2DP duplex codecs over HFP).
This commit is contained in:
		
							parent
							
								
									878e630527
								
							
						
					
					
						commit
						effa0ca124
					
				
					 1 changed files with 20 additions and 8 deletions
				
			
		|  | @ -183,13 +183,17 @@ static void get_a2dp_codecs(struct impl *this, enum spa_bluetooth_audio_codec id | ||||||
| 	*codecs = NULL; | 	*codecs = NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct a2dp_codec *get_supported_a2dp_codec(struct impl *this, enum spa_bluetooth_audio_codec id) | static const struct a2dp_codec *get_supported_a2dp_codec(struct impl *this, enum spa_bluetooth_audio_codec id, size_t *idx) | ||||||
| { | { | ||||||
| 	const struct a2dp_codec *a2dp_codec = NULL; | 	const struct a2dp_codec *a2dp_codec = NULL; | ||||||
| 	size_t i; | 	size_t i; | ||||||
| 	for (i = 0; i < this->supported_codec_count; ++i) | 	for (i = 0; i < this->supported_codec_count; ++i) { | ||||||
| 		if (this->supported_codecs[i]->id == id) | 		if (this->supported_codecs[i]->id == id) { | ||||||
| 			a2dp_codec = this->supported_codecs[i]; | 			a2dp_codec = this->supported_codecs[i]; | ||||||
|  | 			if (idx) | ||||||
|  | 				*idx = i; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	return a2dp_codec; | 	return a2dp_codec; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -684,7 +688,7 @@ static int emit_nodes(struct impl *this) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (get_supported_a2dp_codec(this, this->props.codec) == NULL) | 		if (get_supported_a2dp_codec(this, this->props.codec, NULL) == NULL) | ||||||
| 			this->props.codec = 0; | 			this->props.codec = 0; | ||||||
| 		break; | 		break; | ||||||
| 	case DEVICE_PROFILE_HSP_HFP: | 	case DEVICE_PROFILE_HSP_HFP: | ||||||
|  | @ -894,7 +898,7 @@ static void profiles_changed(void *userdata, uint32_t prev_profiles, uint32_t pr | ||||||
| 			      nodes_changed); | 			      nodes_changed); | ||||||
| 		break; | 		break; | ||||||
| 	case DEVICE_PROFILE_A2DP: | 	case DEVICE_PROFILE_A2DP: | ||||||
| 		if (get_supported_a2dp_codec(this, this->props.codec) == NULL) | 		if (get_supported_a2dp_codec(this, this->props.codec, NULL) == NULL) | ||||||
| 			this->props.codec = 0; | 			this->props.codec = 0; | ||||||
| 		nodes_changed = (connected_change & (SPA_BT_PROFILE_A2DP_SINK | | 		nodes_changed = (connected_change & (SPA_BT_PROFILE_A2DP_SINK | | ||||||
| 						     SPA_BT_PROFILE_A2DP_SOURCE)); | 						     SPA_BT_PROFILE_A2DP_SOURCE)); | ||||||
|  | @ -990,7 +994,7 @@ static uint32_t profile_direction_mask(struct impl *this, uint32_t index, enum s | ||||||
| 		if (device->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) | 		if (device->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) | ||||||
| 			have_output = true; | 			have_output = true; | ||||||
| 
 | 
 | ||||||
| 		a2dp_codec = get_supported_a2dp_codec(this, codec); | 		a2dp_codec = get_supported_a2dp_codec(this, codec, NULL); | ||||||
| 		if (a2dp_codec && a2dp_codec->duplex_codec) | 		if (a2dp_codec && a2dp_codec->duplex_codec) | ||||||
| 			have_input = true; | 			have_input = true; | ||||||
| 		break; | 		break; | ||||||
|  | @ -1138,11 +1142,13 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder * | ||||||
| 	char *desc_and_codec = NULL; | 	char *desc_and_codec = NULL; | ||||||
| 	uint32_t n_source = 0, n_sink = 0; | 	uint32_t n_source = 0, n_sink = 0; | ||||||
| 	uint32_t capture[1] = { DEVICE_ID_SOURCE }, playback[1] = { DEVICE_ID_SINK }; | 	uint32_t capture[1] = { DEVICE_ID_SOURCE }, playback[1] = { DEVICE_ID_SINK }; | ||||||
|  | 	int priority; | ||||||
| 
 | 
 | ||||||
| 	switch (profile_index) { | 	switch (profile_index) { | ||||||
| 	case DEVICE_PROFILE_OFF: | 	case DEVICE_PROFILE_OFF: | ||||||
| 		name = "off"; | 		name = "off"; | ||||||
| 		desc = _("Off"); | 		desc = _("Off"); | ||||||
|  | 		priority = 0; | ||||||
| 		break; | 		break; | ||||||
| 	case DEVICE_PROFILE_AG: | 	case DEVICE_PROFILE_AG: | ||||||
| 	{ | 	{ | ||||||
|  | @ -1154,6 +1160,7 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder * | ||||||
| 			name = "audio-gateway"; | 			name = "audio-gateway"; | ||||||
| 			desc = _("Audio Gateway (A2DP Source & HSP/HFP AG)"); | 			desc = _("Audio Gateway (A2DP Source & HSP/HFP AG)"); | ||||||
| 		} | 		} | ||||||
|  | 		priority = 256; | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	case DEVICE_PROFILE_A2DP: | 	case DEVICE_PROFILE_A2DP: | ||||||
|  | @ -1167,7 +1174,8 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder * | ||||||
| 		name = spa_bt_profile_name(profile); | 		name = spa_bt_profile_name(profile); | ||||||
| 		n_sink++; | 		n_sink++; | ||||||
| 		if (codec) { | 		if (codec) { | ||||||
| 			const struct a2dp_codec *a2dp_codec = get_supported_a2dp_codec(this, codec); | 			size_t idx; | ||||||
|  | 			const struct a2dp_codec *a2dp_codec = get_supported_a2dp_codec(this, codec, &idx); | ||||||
| 			if (a2dp_codec == NULL) { | 			if (a2dp_codec == NULL) { | ||||||
| 				errno = EINVAL; | 				errno = EINVAL; | ||||||
| 				return NULL; | 				return NULL; | ||||||
|  | @ -1183,12 +1191,14 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder * | ||||||
| 
 | 
 | ||||||
| 			} | 			} | ||||||
| 			desc = desc_and_codec; | 			desc = desc_and_codec; | ||||||
|  | 			priority = 16 + this->supported_codec_count - idx;  /* order as in codec list */ | ||||||
| 		} else { | 		} else { | ||||||
| 			if (profile == SPA_BT_PROFILE_A2DP_SINK) { | 			if (profile == SPA_BT_PROFILE_A2DP_SINK) { | ||||||
| 				desc = _("High Fidelity Playback (A2DP Sink)"); | 				desc = _("High Fidelity Playback (A2DP Sink)"); | ||||||
| 			} else { | 			} else { | ||||||
| 				desc = _("High Fidelity Duplex (A2DP Source/Sink)"); | 				desc = _("High Fidelity Duplex (A2DP Source/Sink)"); | ||||||
| 			} | 			} | ||||||
|  | 			priority = 16; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  | @ -1217,8 +1227,10 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder * | ||||||
| 			desc_and_codec = spa_aprintf(_("Headset Head Unit (HSP/HFP, codec %s)"), | 			desc_and_codec = spa_aprintf(_("Headset Head Unit (HSP/HFP, codec %s)"), | ||||||
| 						get_hfp_codec_description(hfp_codec)); | 						get_hfp_codec_description(hfp_codec)); | ||||||
| 			desc = desc_and_codec; | 			desc = desc_and_codec; | ||||||
|  | 			priority = 1 + hfp_codec;  /* prefer msbc over cvsd */ | ||||||
| 		} else { | 		} else { | ||||||
| 			desc = _("Headset Head Unit (HSP/HFP)"); | 			desc = _("Headset Head Unit (HSP/HFP)"); | ||||||
|  | 			priority = 1; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  | @ -1233,7 +1245,7 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder * | ||||||
| 		SPA_PARAM_PROFILE_name, SPA_POD_String(name), | 		SPA_PARAM_PROFILE_name, SPA_POD_String(name), | ||||||
| 		SPA_PARAM_PROFILE_description, SPA_POD_String(desc), | 		SPA_PARAM_PROFILE_description, SPA_POD_String(desc), | ||||||
| 		SPA_PARAM_PROFILE_available, SPA_POD_Id(SPA_PARAM_AVAILABILITY_yes), | 		SPA_PARAM_PROFILE_available, SPA_POD_Id(SPA_PARAM_AVAILABILITY_yes), | ||||||
| 		SPA_PARAM_PROFILE_priority, SPA_POD_Int(codec), | 		SPA_PARAM_PROFILE_priority, SPA_POD_Int(priority), | ||||||
| 		0); | 		0); | ||||||
| 	if (n_source > 0 || n_sink > 0) { | 	if (n_source > 0 || n_sink > 0) { | ||||||
| 		spa_pod_builder_prop(b, SPA_PARAM_PROFILE_classes, 0); | 		spa_pod_builder_prop(b, SPA_PARAM_PROFILE_classes, 0); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Pauli Virtanen
						Pauli Virtanen