mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-05 13:29:57 -05:00
bluetooth: Fix usage of MTU, buffer sizes and return values of encode/decode methods
Add explanation why minimal bitpool value is used in SBC codec as initial bitpool value for A2DP source. Set buffer size for reading/writing from/to A2DP socket to exact link MTU value. This would ensure that A2DP codec does not produce larger packet as maximal possible size which can be sent. Because A2DP socket is of SOCK_SEQPACKET type, it is guaranteed that we do not read two packets via one read/recvmsg call. Properly check for all return values of encode/encode methods of A2DP codec functions. They may fail at different levels. Also encode or decode API method may return zero length buffer (e.g. because of algorithmic delay of codec), so do not fail in this case.
This commit is contained in:
parent
3929798a53
commit
018b38ec39
3 changed files with 67 additions and 31 deletions
|
|
@ -426,7 +426,11 @@ static void *init(bool for_encoding, bool for_backchannel, const uint8_t *config
|
|||
sbc_info->min_bitpool = config->min_bitpool;
|
||||
sbc_info->max_bitpool = config->max_bitpool;
|
||||
|
||||
/* Set minimum bitpool for source to get the maximum possible block_size */
|
||||
/* Set minimum bitpool for source to get the maximum possible block_size
|
||||
* in get_block_size() function. This block_size is length of buffer used
|
||||
* for decoded audio data and so is inversely proportional to frame length
|
||||
* which depends on bitpool value. Bitpool is controlled by other side from
|
||||
* range [min_bitpool, max_bitpool]. */
|
||||
sbc_info->initial_bitpool = for_encoding ? sbc_info->max_bitpool : sbc_info->min_bitpool;
|
||||
|
||||
set_params(sbc_info);
|
||||
|
|
@ -480,9 +484,10 @@ static void reset(void *codec_info) {
|
|||
|
||||
static size_t get_block_size(void *codec_info, size_t link_mtu) {
|
||||
struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
|
||||
size_t rtp_size = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
|
||||
size_t frame_count = (link_mtu - rtp_size) / sbc_info->frame_length;
|
||||
|
||||
return (link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
|
||||
/ sbc_info->frame_length * sbc_info->codesize;
|
||||
return frame_count * sbc_info->codesize;
|
||||
}
|
||||
|
||||
static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
|
||||
|
|
@ -536,8 +541,12 @@ static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t
|
|||
|
||||
if (PA_UNLIKELY(encoded <= 0)) {
|
||||
pa_log_error("SBC encoding error (%li)", (long) encoded);
|
||||
*processed = p - input_buffer;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (PA_UNLIKELY(written < 0)) {
|
||||
pa_log_error("SBC encoding error (%li)", (long) written);
|
||||
break;
|
||||
}
|
||||
|
||||
pa_assert_fp((size_t) encoded <= to_encode);
|
||||
|
|
@ -559,6 +568,11 @@ static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t
|
|||
pa_log_debug("Using SBC codec implementation: %s", pa_strnull(sbc_get_implementation_info(&sbc_info->sbc)));
|
||||
} PA_ONCE_END;
|
||||
|
||||
if (PA_UNLIKELY(frame_count == 0)) {
|
||||
*processed = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write it to the fifo */
|
||||
memset(output_buffer, 0, sizeof(*header) + sizeof(*payload));
|
||||
header->v = 2;
|
||||
|
|
@ -595,7 +609,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_
|
|||
d = output_buffer;
|
||||
to_write = output_size;
|
||||
|
||||
while (PA_LIKELY(to_decode > 0)) {
|
||||
while (PA_LIKELY(to_decode > 0 && to_write > 0)) {
|
||||
size_t written;
|
||||
ssize_t decoded;
|
||||
|
||||
|
|
@ -606,8 +620,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_
|
|||
|
||||
if (PA_UNLIKELY(decoded <= 0)) {
|
||||
pa_log_error("SBC decoding error (%li)", (long) decoded);
|
||||
*processed = p - input_buffer;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset frame length, it can be changed due to bitpool change */
|
||||
|
|
@ -616,6 +629,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_
|
|||
pa_assert_fp((size_t) decoded <= to_decode);
|
||||
pa_assert_fp((size_t) decoded == sbc_info->frame_length);
|
||||
|
||||
pa_assert_fp((size_t) written <= to_write);
|
||||
pa_assert_fp((size_t) written == sbc_info->codesize);
|
||||
|
||||
p += decoded;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue