Skip to content

Commit

Permalink
Update after merge with master
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Nov 13, 2024
1 parent 54492bc commit 43623e9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 51 deletions.
93 changes: 42 additions & 51 deletions src/a2dp-lhdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#include <sys/ioctl.h>
#include <unistd.h>

#include <glib.h>

#include <lhdcBT.h>
#include <lhdcBT_dec.h>

Expand All @@ -44,7 +42,7 @@ static const enum ba_transport_pcm_channel a2dp_lhdc_channel_map_stereo[] = {
BA_TRANSPORT_PCM_CHANNEL_FL, BA_TRANSPORT_PCM_CHANNEL_FR,
};

static const struct a2dp_bit_mapping a2dp_lhdc_samplings[] = {
static const struct a2dp_bit_mapping a2dp_lhdc_rates[] = {
{ LHDC_SAMPLING_FREQ_44100, { 44100 } },
{ LHDC_SAMPLING_FREQ_48000, { 48000 } },
{ LHDC_SAMPLING_FREQ_96000, { 96000 } },
Expand All @@ -70,14 +68,14 @@ static int a2dp_lhdc_caps_foreach_channel_mode(
return -1;
}

static int a2dp_lhdc_caps_foreach_sampling_freq(
static int a2dp_lhdc_caps_foreach_sample_rate(
const void *capabilities,
enum a2dp_stream stream,
a2dp_bit_mapping_foreach_func func,
void *userdata) {
const a2dp_lhdc_v3_t *caps = capabilities;
if (stream == A2DP_MAIN)
return a2dp_bit_mapping_foreach(a2dp_lhdc_samplings, caps->sampling_freq, func, userdata);
return a2dp_bit_mapping_foreach(a2dp_lhdc_rates, caps->sampling_freq, func, userdata);
return -1;
}

Expand All @@ -90,23 +88,23 @@ static void a2dp_lhdc_caps_select_channel_mode(
(void)channels;
}

static void a2dp_lhdc_caps_select_sampling_freq(
static void a2dp_lhdc_caps_select_sample_rate(
void *capabilities,
enum a2dp_stream stream,
unsigned int frequency) {
unsigned int rate) {
a2dp_lhdc_v3_t *caps = capabilities;
if (stream == A2DP_MAIN)
caps->sampling_freq = a2dp_bit_mapping_lookup_value(a2dp_lhdc_samplings,
caps->sampling_freq, frequency);
caps->sampling_freq = a2dp_bit_mapping_lookup_value(a2dp_lhdc_rates,
caps->sampling_freq, rate);
}

static struct a2dp_caps_helpers a2dp_lhdc_caps_helpers = {
.intersect = a2dp_lhdc_caps_intersect,
.has_stream = a2dp_caps_has_main_stream_only,
.foreach_channel_mode = a2dp_lhdc_caps_foreach_channel_mode,
.foreach_sampling_freq = a2dp_lhdc_caps_foreach_sampling_freq,
.foreach_sample_rate = a2dp_lhdc_caps_foreach_sample_rate,
.select_channel_mode = a2dp_lhdc_caps_select_channel_mode,
.select_sampling_freq = a2dp_lhdc_caps_select_sampling_freq,
.select_sample_rate = a2dp_lhdc_caps_select_sample_rate,
};

static LHDC_VERSION_SETUP get_version(const a2dp_lhdc_v3_t *configuration) {
Expand Down Expand Up @@ -157,8 +155,9 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {
struct io_poll io = { .timeout = -1 };

const a2dp_lhdc_v3_t *configuration = &t->a2dp.configuration.lhdc_v3;
const unsigned int bit_depth = get_bit_depth(configuration);
const unsigned int channels = t_pcm->channels;
const unsigned int samplerate = t_pcm->sampling;
const unsigned int rate = t_pcm->rate;

HANDLE_LHDC_BT handle;
if ((handle = lhdcBT_get_handle(get_version(configuration))) == NULL) {
Expand All @@ -168,22 +167,13 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {

pthread_cleanup_push(PTHREAD_CLEANUP(lhdcBT_free_handle), handle);

const unsigned int bitdepth = get_bit_depth(configuration);

lhdcBT_set_hasMinBitrateLimit(handle, configuration->min_bitrate);
lhdcBT_set_max_bitrate(handle, get_max_bitrate(configuration));

struct {
uint8_t seq_num;
uint8_t latency:2;
uint8_t frames:6;
} *lhdc_media_header;

rtp_header_t *rtp_header;

if (lhdcBT_init_encoder(handle, samplerate, bitdepth, config.lhdc_eqmid,
configuration->ch_split_mode > LHDC_CH_SPLIT_MODE_NONE, 0, t->mtu_write - sizeof(*lhdc_media_header) - RTP_HEADER_LEN,
get_interval(configuration)) == -1) {
if (lhdcBT_init_encoder(handle, rate, bit_depth, config.lhdc_eqmid,
configuration->ch_split_mode > LHDC_CH_SPLIT_MODE_NONE, 0,
t->mtu_write - RTP_HEADER_LEN - sizeof(rtp_lhdc_media_header_t),
get_interval(configuration)) == -1) {
error("Couldn't initialize LHDC encoder");
goto fail_init;
}
Expand All @@ -208,13 +198,15 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail_ffb;
}

rtp_header_t *rtp_header;
rtp_lhdc_media_header_t *rtp_lhdc_media_header;
/* initialize RTP headers and get anchor for payload */
uint8_t *rtp_payload = rtp_a2dp_init(bt.data, &rtp_header,
(void **)&lhdc_media_header, sizeof(*lhdc_media_header));
(void **)&rtp_lhdc_media_header, sizeof(*rtp_lhdc_media_header));

struct rtp_state rtp = { .synced = false };
/* RTP clock frequency equal to audio sample rate */
rtp_state_init(&rtp, samplerate, samplerate);
/* RTP clock frequency equal to PCM sample rate */
rtp_state_init(&rtp, rate, rate);

uint8_t seq_num = 0;

Expand Down Expand Up @@ -263,9 +255,9 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {

rtp_state_new_frame(&rtp, rtp_header);

lhdc_media_header->seq_num = seq_num++;
lhdc_media_header->latency = 0;
lhdc_media_header->frames = frames;
rtp_lhdc_media_header->seq_number = seq_num++;
rtp_lhdc_media_header->latency = 0;
rtp_lhdc_media_header->frame_count = frames;

/* Try to get the number of bytes queued in the
* socket output buffer. */
Expand Down Expand Up @@ -337,12 +329,12 @@ void *a2dp_lhdc_dec_thread(struct ba_transport_pcm *t_pcm) {
const a2dp_lhdc_v3_t *configuration = &t->a2dp.configuration.lhdc_v3;
const size_t sample_size = BA_TRANSPORT_PCM_FORMAT_BYTES(t_pcm->format);
const unsigned int channels = t_pcm->channels;
const unsigned int samplerate = t_pcm->sampling;
const unsigned int rate = t_pcm->rate;
const unsigned int bit_depth = get_bit_depth(configuration);

tLHDCV3_DEC_CONFIG dec_config = {
.version = get_decoder_version(configuration),
.sample_rate = samplerate,
.sample_rate = rate,
.bits_depth = bit_depth,
};

Expand All @@ -365,8 +357,8 @@ void *a2dp_lhdc_dec_thread(struct ba_transport_pcm *t_pcm) {
}

struct rtp_state rtp = { .synced = false };
/* RTP clock frequency equal to audio sample rate */
rtp_state_init(&rtp, samplerate, samplerate);
/* RTP clock frequency equal to PCM sample rate */
rtp_state_init(&rtp, rate, rate);

debug_transport_pcm_thread_loop(t_pcm, "START");
for (ba_transport_pcm_state_set_running(t_pcm);;) {
Expand All @@ -380,8 +372,8 @@ void *a2dp_lhdc_dec_thread(struct ba_transport_pcm *t_pcm) {
}

const rtp_header_t *rtp_header = bt.data;
const void *lhdc_media_header;
if ((lhdc_media_header = rtp_a2dp_get_payload(rtp_header)) == NULL)
const rtp_lhdc_media_header_t *rtp_lhdc_media_header;
if ((rtp_lhdc_media_header = rtp_a2dp_get_payload(rtp_header)) == NULL)
continue;

int missing_rtp_frames = 0;
Expand All @@ -392,11 +384,10 @@ void *a2dp_lhdc_dec_thread(struct ba_transport_pcm *t_pcm) {
continue;
}

const uint8_t *rtp_payload = (uint8_t *) lhdc_media_header;
const uint8_t *rtp_payload = (uint8_t *)rtp_lhdc_media_header;
size_t rtp_payload_len = len - (rtp_payload - (uint8_t *)bt.data);

uint32_t decoded = 16 * 256 * sizeof(int32_t) * channels;

uint32_t decoded = ffb_blen_in(&pcm);
lhdcBT_dec_decode(rtp_payload, rtp_payload_len, pcm.data, &decoded, 24);

const size_t samples = decoded / sample_size;
Expand Down Expand Up @@ -442,11 +433,11 @@ static int a2dp_lhdc_configuration_select(
}

unsigned int sampling_freq = 0;
if (a2dp_lhdc_caps_foreach_sampling_freq(caps, A2DP_MAIN,
a2dp_bit_mapping_foreach_get_best_sampling_freq, &sampling_freq) != -1)
if (a2dp_lhdc_caps_foreach_sample_rate(caps, A2DP_MAIN,
a2dp_bit_mapping_foreach_get_best_sample_rate, &sampling_freq) != -1)
caps->sampling_freq = sampling_freq;
else {
error("LHDC: No supported sampling frequencies: %#x", saved.sampling_freq);
error("LHDC: No supported sample rates: %#x", saved.sampling_freq);
return errno = ENOTSUP, -1;
}

Expand All @@ -463,18 +454,18 @@ static int a2dp_lhdc_configuration_check(
/* Validate configuration against BlueALSA capabilities. */
a2dp_lhdc_caps_intersect(&conf_v, &sep->config.capabilities);

if (a2dp_bit_mapping_lookup(a2dp_lhdc_samplings, conf_v.sampling_freq) == -1) {
debug("LHDC: Invalid sampling frequency: %#x", conf->sampling_freq);
return A2DP_CHECK_ERR_SAMPLING;
if (a2dp_bit_mapping_lookup(a2dp_lhdc_rates, conf_v.sampling_freq) == -1) {
debug("LHDC: Invalid sample rate: %#x", conf->sampling_freq);
return A2DP_CHECK_ERR_RATE;
}

return A2DP_CHECK_OK;
}

static int a2dp_lhdc_transport_init(struct ba_transport *t) {

ssize_t sampling_i;
if ((sampling_i = a2dp_bit_mapping_lookup(a2dp_lhdc_samplings,
ssize_t rate_i;
if ((rate_i = a2dp_bit_mapping_lookup(a2dp_lhdc_rates,
t->a2dp.configuration.lhdc_v3.sampling_freq)) == -1)
return -1;

Expand All @@ -485,10 +476,10 @@ static int a2dp_lhdc_transport_init(struct ba_transport *t) {
}

t->a2dp.pcm.channels = 2;
t->a2dp.pcm.sampling = a2dp_lhdc_samplings[sampling_i].value;
t->a2dp.pcm.rate = a2dp_lhdc_rates[rate_i].value;

memcpy(t->a2dp.pcm.channel_map, a2dp_lhdc_channel_map_stereo,
t->a2dp.pcm.channels * sizeof(*t->a2dp.pcm.channel_map));
memcpy(t->a2dp.pcm.channel_map,
a2dp_lhdc_channel_map_stereo, sizeof(a2dp_lhdc_channel_map_stereo));

return 0;
}
Expand Down
13 changes: 13 additions & 0 deletions src/rtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ typedef struct rtp_mpeg_audio_header {
uint16_t offset;
} __attribute__ ((packed)) rtp_mpeg_audio_header_t;

/**
* LHDC media payload header. */
typedef struct rtp_lhdc_media_header {
uint8_t seq_number;
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t latency:2;
uint8_t frame_count:6;
#else
uint8_t frame_count:6;
uint8_t latency:2;
#endif
} __attribute__ ((packed)) rtp_lhdc_media_header_t;

void *rtp_a2dp_init(void *s, rtp_header_t **hdr, void **phdr, size_t phdr_size);
void *rtp_a2dp_get_payload(const rtp_header_t *hdr);

Expand Down

0 comments on commit 43623e9

Please sign in to comment.