mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	bluetooth: Check support for encoding and decoding separately
As suggested in [1]: This way it is possible for a codec to have both the encoding and decoding part optional, instead of getting both or nothing (where PA theoretically supports both). In addition this cleans up code that was previously checking the existence of a function pointer, or nothing at all (switch_codec). [1]: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440#note_768146 Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/479>
This commit is contained in:
		
							parent
							
								
									8816b6b05b
								
							
						
					
					
						commit
						519052e77e
					
				
					 6 changed files with 37 additions and 38 deletions
				
			
		| 
						 | 
					@ -49,7 +49,7 @@ typedef struct pa_a2dp_codec {
 | 
				
			||||||
    bool support_backchannel;
 | 
					    bool support_backchannel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Returns true if the codec can be supported on the system */
 | 
					    /* Returns true if the codec can be supported on the system */
 | 
				
			||||||
    bool (*can_be_supported)(void);
 | 
					    bool (*can_be_supported)(bool for_encoding);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Returns true if codec accepts capabilities, for_encoding is true when
 | 
					    /* Returns true if codec accepts capabilities, for_encoding is true when
 | 
				
			||||||
     * capabilities are used for encoding */
 | 
					     * capabilities are used for encoding */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,25 +33,27 @@
 | 
				
			||||||
#include "a2dp-codec-gst.h"
 | 
					#include "a2dp-codec-gst.h"
 | 
				
			||||||
#include "rtp.h"
 | 
					#include "rtp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool can_be_supported(void) {
 | 
					static bool can_be_supported(bool for_encoding) {
 | 
				
			||||||
    GstElementFactory *element_factory;
 | 
					    GstElementFactory *element_factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    element_factory = gst_element_factory_find("openaptxenc");
 | 
					    if (for_encoding) {
 | 
				
			||||||
    if (element_factory == NULL) {
 | 
					        element_factory = gst_element_factory_find("openaptxenc");
 | 
				
			||||||
        pa_log_info("aptX encoder not found");
 | 
					        if (element_factory == NULL) {
 | 
				
			||||||
        return false;
 | 
					            pa_log_info("aptX encoder not found");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        gst_object_unref(element_factory);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        element_factory = gst_element_factory_find("openaptxdec");
 | 
				
			||||||
 | 
					        if (element_factory == NULL) {
 | 
				
			||||||
 | 
					            pa_log_info("aptX decoder not found");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        gst_object_unref(element_factory);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gst_object_unref(element_factory);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    element_factory = gst_element_factory_find("openaptxdec");
 | 
					 | 
				
			||||||
    if (element_factory == NULL) {
 | 
					 | 
				
			||||||
        pa_log_info("aptX decoder not found");
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gst_object_unref(element_factory);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,9 +33,12 @@
 | 
				
			||||||
#include "a2dp-codec-gst.h"
 | 
					#include "a2dp-codec-gst.h"
 | 
				
			||||||
#include "rtp.h"
 | 
					#include "rtp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool can_be_supported(void) {
 | 
					static bool can_be_supported(bool for_encoding) {
 | 
				
			||||||
    GstElementFactory *element_factory;
 | 
					    GstElementFactory *element_factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!for_encoding)
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    element_factory = gst_element_factory_find("ldacenc");
 | 
					    element_factory = gst_element_factory_find("ldacenc");
 | 
				
			||||||
    if (element_factory == NULL) {
 | 
					    if (element_factory == NULL) {
 | 
				
			||||||
        pa_log_info("LDAC encoder not found");
 | 
					        pa_log_info("LDAC encoder not found");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,7 +53,7 @@ struct sbc_info {
 | 
				
			||||||
    uint8_t max_bitpool;
 | 
					    uint8_t max_bitpool;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool can_be_supported(void) {
 | 
					static bool can_be_supported(bool for_encoding) {
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2108,21 +2108,21 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage *
 | 
				
			||||||
            char *endpoint;
 | 
					            char *endpoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
					            a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
				
			||||||
            if (!a2dp_codec->can_be_supported())
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            codec_id = a2dp_codec->id.codec_id;
 | 
					            codec_id = a2dp_codec->id.codec_id;
 | 
				
			||||||
            capabilities_size = a2dp_codec->fill_capabilities(capabilities);
 | 
					 | 
				
			||||||
            pa_assert(capabilities_size != 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (a2dp_codec->decode_buffer != NULL) {
 | 
					            if (a2dp_codec->can_be_supported(false)) {
 | 
				
			||||||
 | 
					                capabilities_size = a2dp_codec->fill_capabilities(capabilities);
 | 
				
			||||||
 | 
					                pa_assert(capabilities_size != 0);
 | 
				
			||||||
                endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
 | 
					                endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_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->encode_buffer != NULL) {
 | 
					            if (a2dp_codec->can_be_supported(true)) {
 | 
				
			||||||
 | 
					                capabilities_size = a2dp_codec->fill_capabilities(capabilities);
 | 
				
			||||||
 | 
					                pa_assert(capabilities_size != 0);
 | 
				
			||||||
                endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name);
 | 
					                endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_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);
 | 
				
			||||||
| 
						 | 
					@ -2222,16 +2222,13 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backe
 | 
				
			||||||
    count = pa_bluetooth_a2dp_codec_count();
 | 
					    count = pa_bluetooth_a2dp_codec_count();
 | 
				
			||||||
    for (i = 0; i < count; i++) {
 | 
					    for (i = 0; i < count; i++) {
 | 
				
			||||||
        a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
					        a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
				
			||||||
        if (!a2dp_codec->can_be_supported())
 | 
					        if (a2dp_codec->can_be_supported(false)) {
 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (a2dp_codec->decode_buffer != NULL) {
 | 
					 | 
				
			||||||
            endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
 | 
					            endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
 | 
				
			||||||
            endpoint_init(y, endpoint);
 | 
					            endpoint_init(y, endpoint);
 | 
				
			||||||
            pa_xfree(endpoint);
 | 
					            pa_xfree(endpoint);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (a2dp_codec->encode_buffer != NULL) {
 | 
					        if (a2dp_codec->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, a2dp_codec->name);
 | 
				
			||||||
            endpoint_init(y, endpoint);
 | 
					            endpoint_init(y, endpoint);
 | 
				
			||||||
            pa_xfree(endpoint);
 | 
					            pa_xfree(endpoint);
 | 
				
			||||||
| 
						 | 
					@ -2316,16 +2313,13 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 | 
				
			||||||
        for (i = 0; i < count; i++) {
 | 
					        for (i = 0; i < count; i++) {
 | 
				
			||||||
            a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
					            a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!a2dp_codec->can_be_supported())
 | 
					            if (a2dp_codec->can_be_supported(false)) {
 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (a2dp_codec->decode_buffer != NULL) {
 | 
					 | 
				
			||||||
                endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
 | 
					                endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
 | 
				
			||||||
                endpoint_done(y, endpoint);
 | 
					                endpoint_done(y, endpoint);
 | 
				
			||||||
                pa_xfree(endpoint);
 | 
					                pa_xfree(endpoint);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (a2dp_codec->encode_buffer != NULL) {
 | 
					            if (a2dp_codec->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, a2dp_codec->name);
 | 
				
			||||||
                endpoint_done(y, endpoint);
 | 
					                endpoint_done(y, endpoint);
 | 
				
			||||||
                pa_xfree(endpoint);
 | 
					                pa_xfree(endpoint);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2307,7 +2307,7 @@ static char *list_codecs(struct userdata *u) {
 | 
				
			||||||
            a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
					            a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (memcmp(key, &a2dp_codec->id, sizeof(pa_a2dp_codec_id)) == 0) {
 | 
					            if (memcmp(key, &a2dp_codec->id, sizeof(pa_a2dp_codec_id)) == 0) {
 | 
				
			||||||
                if (a2dp_codec->can_be_supported()) {
 | 
					                if (a2dp_codec->can_be_supported(is_a2dp_sink)) {
 | 
				
			||||||
                    pa_message_params_begin_list(param);
 | 
					                    pa_message_params_begin_list(param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    pa_message_params_write_string(param, a2dp_codec->name);
 | 
					                    pa_message_params_write_string(param, a2dp_codec->name);
 | 
				
			||||||
| 
						 | 
					@ -2383,13 +2383,13 @@ static int bluez5_device_message_handler(const char *object_path, const char *me
 | 
				
			||||||
            return -PA_ERR_INVALID;
 | 
					            return -PA_ERR_INVALID;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!codec->can_be_supported()) {
 | 
					        is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!u->a2dp_codec->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;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * We need to check if we have valid sink or source endpoints which
 | 
					         * We need to check if we have valid sink or source endpoints which
 | 
				
			||||||
         * were registered during the negotiation process. If we do, then we
 | 
					         * were registered during the negotiation process. If we do, then we
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue