mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	bluetooth: apply write MTU detection based on read packet size
HFP Audio Connection SCO configuration is negotiated symmetrically in both directions, and USB HCI SCO packet framing is also symmetric in both directions. This means that packet size will be the same for reads and writes over HFP SCO socket. HFP profile specification states that valid speech data shall exist on the Synchronous Connection in both directions after the Audio Connection is established. This guarantees that an incoming packet will arrive shortly after SCO connection is established. Use it's size to fix write MTU in case kernel value is wrong. Discussion here https://lore.kernel.org/patchwork/patch/1303411/ Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/507>
This commit is contained in:
		
							parent
							
								
									4444ecad6f
								
							
						
					
					
						commit
						62776cc815
					
				
					 4 changed files with 22 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -365,6 +365,10 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void
 | 
			
		|||
 | 
			
		||||
    pa_assert(t);
 | 
			
		||||
 | 
			
		||||
    /* since SCO setup is symmetric, fix write MTU to be size of last read packet */
 | 
			
		||||
    if (t->last_read_size)
 | 
			
		||||
        write_mtu = PA_MIN(t->last_read_size, write_mtu);
 | 
			
		||||
 | 
			
		||||
    /* if encoder buffer has less data than required to make complete packet */
 | 
			
		||||
    if (size < write_mtu)
 | 
			
		||||
        return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -386,6 +390,11 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void
 | 
			
		|||
            pa_log_debug("Got EAGAIN on write() after POLLOUT, probably there is a temporary connection loss.");
 | 
			
		||||
            /* Drain write buffer */
 | 
			
		||||
            written = size;
 | 
			
		||||
        } else if (errno == EINVAL && t->last_read_size == 0) {
 | 
			
		||||
            /* Likely write_link_mtu is still wrong, retry after next successful read */
 | 
			
		||||
            pa_log_debug("got write EINVAL, next successful read should fix MTU");
 | 
			
		||||
            /* Drain write buffer */
 | 
			
		||||
            written = size;
 | 
			
		||||
        } else {
 | 
			
		||||
            pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
 | 
			
		||||
            /* Report error from write call */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,6 +90,10 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void
 | 
			
		|||
 | 
			
		||||
    pa_assert(t);
 | 
			
		||||
 | 
			
		||||
    /* since SCO setup is symmetric, fix write MTU to be size of last read packet */
 | 
			
		||||
    if (t->last_read_size)
 | 
			
		||||
        write_mtu = PA_MIN(t->last_read_size, write_mtu);
 | 
			
		||||
 | 
			
		||||
    /* if encoder buffer has less data than required to make complete packet */
 | 
			
		||||
    if (size < write_mtu)
 | 
			
		||||
        return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +115,11 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void
 | 
			
		|||
            pa_log_debug("Got EAGAIN on write() after POLLOUT, probably there is a temporary connection loss.");
 | 
			
		||||
            /* Drain write buffer */
 | 
			
		||||
            written = size;
 | 
			
		||||
        } else if (errno == EINVAL && t->last_read_size == 0) {
 | 
			
		||||
            /* Likely write_link_mtu is still wrong, retry after next successful read */
 | 
			
		||||
            pa_log_debug("got write EINVAL, next successful read should fix MTU");
 | 
			
		||||
            /* Drain write buffer */
 | 
			
		||||
            written = size;
 | 
			
		||||
        } else {
 | 
			
		||||
            pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
 | 
			
		||||
            /* Report error from write call */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,6 +103,7 @@ struct pa_bluetooth_transport {
 | 
			
		|||
 | 
			
		||||
    const pa_a2dp_codec *bt_codec;
 | 
			
		||||
    int stream_write_type;
 | 
			
		||||
    size_t last_read_size;
 | 
			
		||||
 | 
			
		||||
    pa_volume_t source_volume;
 | 
			
		||||
    pa_volume_t sink_volume;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -413,6 +413,9 @@ static ssize_t bt_transport_read(pa_bluetooth_transport *t, int fd, void *buffer
 | 
			
		|||
 | 
			
		||||
        pa_assert((size_t) received <= size);
 | 
			
		||||
 | 
			
		||||
        /* allow write side to find out size of last read packet */
 | 
			
		||||
        t->last_read_size = received;
 | 
			
		||||
 | 
			
		||||
        if (p_timestamp) {
 | 
			
		||||
            /* TODO: get timestamp from rtp */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue