[PATCH] Re: A2DP quality (bluetooth-alsa)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



ALSA bitpool patch is attached.

2012/3/27 Siarhei Siamashka <siarhei.siamashka@xxxxxxxxx>:
> The first patch adds debug prints to syslog from sbc encoder, just to
> clearly confirm the real bitpool used by the encoder.

It obviously worked:

Mar 27 17:49:41 machina-turbo pulseaudio[2355]: sbc_encode: bitpool set to 138

> The second patch removes default_bitpool() limitation, and this boosts
> bitpool from 53 to 64 for me.

I found it was my device that prevented Bluez from using higher
bitpools. Bluez assumes that requesting a wider range of bitpools from
a device will cause an error, and indeed, my device cannot be
configured with a bitpool range wider than 2-53. So the only way to
achieve higher bitrates is to force them.

There is (was) a rather serious problem in the ALSA module, when it
tried to set bitpool exceding device capabilities, it ended with an
error and next tries, even with a valid bitpool, resulted in "Invalid
seid 0" in syslog and required bluetooth service to be restarted. With
my patch, bluez only uses the configured bitpool for sbc, without
sending it to the device. So, any bitpool value not exceeding true
device and adapter capabilities will work (and these can be much
higher than negotiated).


Regards
--

Sebastian Olter
--- bluez-4.99-orig/audio/pcm_bluetooth.c	2011-12-21 23:53:54.000000000 +0100
+++ bluez-4.99/audio/pcm_bluetooth.c	2012-03-28 01:20:41.977829080 +0200
@@ -78,7 +78,7 @@
 # define MAX(x, y) ((x) > (y) ? (x) : (y))
 #endif
 
-#define MAX_BITPOOL 64
+#define MAX_BITPOOL 250
 #define MIN_BITPOOL 2
 
 /* adapted from glibc sys/time.h timersub() macro */
@@ -606,13 +606,12 @@
 		cap->allocation_method = BT_A2DP_ALLOCATION_SNR;
 
 	if (cfg->has_bitpool)
-		min_bitpool = max_bitpool = cfg->bitpool;
-	else {
-		min_bitpool = MAX(MIN_BITPOOL, cap->min_bitpool);
-		max_bitpool = MIN(default_bitpool(cap->frequency,
-					cap->channel_mode),
-					cap->max_bitpool);
-	}
+		data->a2dp.sbc.bitpool = cfg->bitpool;
+	else /* Initialize to MIN_BITPOOL in order to replace it with negotiated maximum */
+		data->a2dp.sbc.bitpool = MIN_BITPOOL;
+
+	min_bitpool = MAX(MIN_BITPOOL, cap->min_bitpool);
+	max_bitpool = MIN(MAX_BITPOOL, cap->max_bitpool);
 
 	cap->min_bitpool = min_bitpool;
 	cap->max_bitpool = max_bitpool;
@@ -623,11 +622,15 @@
 static void bluetooth_a2dp_setup(struct bluetooth_a2dp *a2dp)
 {
 	sbc_capabilities_t active_capabilities = a2dp->sbc_capabilities;
+	int stored_bitpool = a2dp->sbc.bitpool;
 
 	if (a2dp->sbc_initialized)
 		sbc_reinit(&a2dp->sbc, 0);
 	else
 		sbc_init(&a2dp->sbc, 0);
+
+	/* restore configured (or minimum) bitpool */
+	a2dp->sbc.bitpool = stored_bitpool;
 	a2dp->sbc_initialized = 1;
 
 	if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_16000)
@@ -682,7 +685,10 @@
 		break;
 	}
 
-	a2dp->sbc.bitpool = active_capabilities.max_bitpool;
+	/* Increase the bitpool to allowed maximum, if it was not configured */
+	if(a2dp->sbc.bitpool <= MIN_BITPOOL)
+	    a2dp->sbc.bitpool = active_capabilities.max_bitpool;
+ 
 	a2dp->codesize = sbc_get_codesize(&a2dp->sbc);
 	a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
 }
@@ -1714,7 +1720,7 @@
 		goto failed;
 
 	bluetooth_parse_capabilities(data, rsp);
-
+	
 	return 0;
 
 failed:

[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux