mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-01 22:58:47 -04:00
Configure bt connection for a2dp
This commit is contained in:
parent
85a931f333
commit
b5c4d2e5f1
2 changed files with 94 additions and 14 deletions
76
src/modules/bt-rtp.h
Normal file
76
src/modules/bt-rtp.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
|
||||
struct rtp_header {
|
||||
uint8_t cc:4;
|
||||
uint8_t x:1;
|
||||
uint8_t p:1;
|
||||
uint8_t v:2;
|
||||
|
||||
uint8_t pt:7;
|
||||
uint8_t m:1;
|
||||
|
||||
uint16_t sequence_number;
|
||||
uint32_t timestamp;
|
||||
uint32_t ssrc;
|
||||
uint32_t csrc[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtp_payload {
|
||||
uint8_t frame_count:4;
|
||||
uint8_t rfa0:1;
|
||||
uint8_t is_last_fragment:1;
|
||||
uint8_t is_first_fragment:1;
|
||||
uint8_t is_fragmented:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
|
||||
struct rtp_header {
|
||||
uint8_t v:2;
|
||||
uint8_t p:1;
|
||||
uint8_t x:1;
|
||||
uint8_t cc:4;
|
||||
|
||||
uint8_t m:1;
|
||||
uint8_t pt:7;
|
||||
|
||||
uint16_t sequence_number;
|
||||
uint32_t timestamp;
|
||||
uint32_t ssrc;
|
||||
uint32_t csrc[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtp_payload {
|
||||
uint8_t is_fragmented:1;
|
||||
uint8_t is_first_fragment:1;
|
||||
uint8_t is_last_fragment:1;
|
||||
uint8_t rfa0:1;
|
||||
uint8_t frame_count:4;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#else
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
|
|
@ -44,11 +44,15 @@
|
|||
#include "module-bt-device-symdef.h"
|
||||
#include "bt-ipc.h"
|
||||
#include "bt-sbc.h"
|
||||
#include "bt-rtp.h"
|
||||
|
||||
#define DEFAULT_SINK_NAME "bluetooth_sink"
|
||||
#define BUFFER_SIZE 2048
|
||||
#define MAX_BITPOOL 64
|
||||
#define MIN_BITPOOL 2
|
||||
#define SOL_SCO 17
|
||||
#define SCO_TXBUFS 0x03
|
||||
#define SCO_RXBUFS 0x04
|
||||
|
||||
PA_MODULE_AUTHOR("Joao Paulo Rechi Vita");
|
||||
PA_MODULE_DESCRIPTION("Bluetooth audio sink and source");
|
||||
|
|
@ -244,7 +248,7 @@ static uint8_t default_bitpool(uint8_t freq, uint8_t mode) {
|
|||
|
||||
static int bt_a2dp_init(struct userdata *u) {
|
||||
sbc_capabilities_t *cap = &u->a2dp.sbc_capabilities;
|
||||
unsigned int max_bitpool, min_bitpool, rate, channels;
|
||||
unsigned int max_bitpool, min_bitpool;
|
||||
|
||||
switch (u->rate) {
|
||||
case 48000:
|
||||
|
|
@ -260,14 +264,14 @@ static int bt_a2dp_init(struct userdata *u) {
|
|||
cap->frequency = BT_SBC_SAMPLING_FREQ_16000;
|
||||
break;
|
||||
default:
|
||||
pa_log_error("Rate %d not supported", rate);
|
||||
pa_log_error("Rate %d not supported", u->rate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if (cfg->has_channel_mode)
|
||||
// cap->channel_mode = cfg->channel_mode;
|
||||
// else
|
||||
if (channels == 2) {
|
||||
if (u->channels == 2) {
|
||||
if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
|
||||
cap->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
|
||||
else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO)
|
||||
|
|
@ -364,7 +368,7 @@ static void bt_a2dp_setup(struct bt_a2dp *a2dp) {
|
|||
if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
|
||||
a2dp->sbc.mode = SBC_MODE_JOINT_STEREO;
|
||||
|
||||
a2dp->sbc.allocation = active_capabilities.allocation_method == BT_A2DP_ALLOCATION_SNR ? SBC_AM_SNR : SBC_AM_LOUDNESS;
|
||||
a2dp->sbc.allocation = (active_capabilities.allocation_method == BT_A2DP_ALLOCATION_SNR ? SBC_AM_SNR : SBC_AM_LOUDNESS);
|
||||
|
||||
switch (active_capabilities.subbands) {
|
||||
case BT_A2DP_SUBBANDS_4:
|
||||
|
|
@ -392,7 +396,7 @@ static void bt_a2dp_setup(struct bt_a2dp *a2dp) {
|
|||
|
||||
a2dp->sbc.bitpool = active_capabilities.max_bitpool;
|
||||
a2dp->codesize = sbc_get_codesize(&a2dp->sbc);
|
||||
// a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
|
||||
a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
|
||||
}
|
||||
|
||||
static int bt_setconf(struct userdata *u) {
|
||||
|
|
@ -457,7 +461,9 @@ static int bt_setconf(struct userdata *u) {
|
|||
}
|
||||
|
||||
static int bt_getstreamfd(struct userdata *u) {
|
||||
int e/*, opt_name*/;
|
||||
int e;
|
||||
// uint32_t period_count = io->buffer_size / io->period_size;
|
||||
// struct timeval t = { 0, period_count };
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
struct bt_streamstart_req *start_req = (void*) buf;
|
||||
bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf;
|
||||
|
|
@ -494,23 +500,20 @@ static int bt_getstreamfd(struct userdata *u) {
|
|||
|
||||
u->stream_fd = bt_audio_service_get_data_fd(u->audioservice_fd);
|
||||
if (u->stream_fd < 0) {
|
||||
pa_log_error("failed to get data fd");
|
||||
pa_log_error("failed to get data fd: %s (%d)",pa_cstrerror(errno), errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
// if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
|
||||
// opt_name = SO_SNDTIMEO;
|
||||
// if (setsockopt(u->stream_fd, SOL_SOCKET, opt_name, &t, sizeof(t)) < 0) {
|
||||
// pa_log_error("failed to set socket options for A2DP");
|
||||
// if (setsockopt(u->stream_fd, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t)) < 0) {
|
||||
// pa_log_error("failed to set socket options for A2DP: %s (%d)",pa_cstrerror(errno), errno);
|
||||
// return -errno;
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// opt_name = SCO_TXBUFS;
|
||||
// if (setsockopt(u->stream_fd, SOL_SCO, opt_name, &period_count, sizeof(period_count)) == 0)
|
||||
// if (setsockopt(u->stream_fd, SOL_SCO, SCO_TXBUFS, &period_count, sizeof(period_count)) == 0)
|
||||
// return 0;
|
||||
// opt_name = SO_SNDBUF;
|
||||
// if (setsockopt(u->stream_fd, SOL_SCO, opt_name, &period_count, sizeof(period_count)) == 0)
|
||||
// if (setsockopt(u->stream_fd, SOL_SCO, SO_SNDBUF, &period_count, sizeof(period_count)) == 0)
|
||||
// return 0;
|
||||
// /* FIXME : handle error codes */
|
||||
// }
|
||||
|
|
@ -703,6 +706,7 @@ int pa__init(pa_module* m) {
|
|||
u->transport = -1;
|
||||
u->offset = 0;
|
||||
u->latency = 0;
|
||||
u->a2dp.sbc_initialized = 0;
|
||||
u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC*2, TRUE, 10);
|
||||
u->mempool = pa_mempool_new(FALSE);
|
||||
pa_memchunk_reset(&u->memchunk);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue