mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
Those properties are set as reference sample rate and channels number for A2DP configuration selecting.
155 lines
3.1 KiB
C
155 lines
3.1 KiB
C
/*
|
|
* BlueALSA - bluez-a2dp.c
|
|
* Copyright (c) 2016-2017 Arkadiusz Bokowy
|
|
*
|
|
* This file is a part of bluez-alsa.
|
|
*
|
|
* This project is licensed under the terms of the MIT license.
|
|
*
|
|
*/
|
|
|
|
#include "a2dp-codecs.h"
|
|
|
|
int a2dp_codec_select_config(const struct a2dp_codec_config configs[], size_t n,
|
|
uint32_t cap, int preferred_value)
|
|
{
|
|
size_t i;
|
|
int *scores, res;
|
|
unsigned int max_priority;
|
|
|
|
if (n == 0)
|
|
return -EINVAL;
|
|
|
|
scores = calloc(n, sizeof(int));
|
|
if (scores == NULL)
|
|
return -errno;
|
|
|
|
max_priority = configs[0].priority;
|
|
for (i = 1; i < n; ++i) {
|
|
if (configs[i].priority > max_priority)
|
|
max_priority = configs[i].priority;
|
|
}
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
if (!(configs[i].config & cap)) {
|
|
scores[i] = -1;
|
|
continue;
|
|
}
|
|
if (configs[i].value == preferred_value)
|
|
scores[i] = 100 * (max_priority + 1);
|
|
else if (configs[i].value > preferred_value)
|
|
scores[i] = 10 * (max_priority + 1);
|
|
else
|
|
scores[i] = 1;
|
|
|
|
scores[i] *= configs[i].priority + 1;
|
|
}
|
|
|
|
res = 0;
|
|
for (i = 1; i < n; ++i) {
|
|
if (scores[i] > scores[res])
|
|
res = i;
|
|
}
|
|
|
|
if (scores[res] < 0)
|
|
res = -EINVAL;
|
|
|
|
free(scores);
|
|
return res;
|
|
}
|
|
|
|
bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id,
|
|
const void *caps, size_t caps_size,
|
|
const struct a2dp_codec_audio_info *info)
|
|
{
|
|
uint8_t config[A2DP_MAX_CAPS_SIZE];
|
|
int res;
|
|
|
|
if (codec_id != codec->codec_id)
|
|
return false;
|
|
|
|
if (caps == NULL)
|
|
return false;
|
|
|
|
res = codec->select_config(codec, 0, caps, caps_size, info, NULL, config);
|
|
if (res < 0)
|
|
return false;
|
|
|
|
return ((size_t)res == caps_size);
|
|
}
|
|
|
|
#if ENABLE_MP3
|
|
const a2dp_mpeg_t bluez_a2dp_mpeg = {
|
|
.layer =
|
|
MPEG_LAYER_MP1 |
|
|
MPEG_LAYER_MP2 |
|
|
MPEG_LAYER_MP3,
|
|
.crc = 1,
|
|
.channel_mode =
|
|
MPEG_CHANNEL_MODE_MONO |
|
|
MPEG_CHANNEL_MODE_DUAL_CHANNEL |
|
|
MPEG_CHANNEL_MODE_STEREO |
|
|
MPEG_CHANNEL_MODE_JOINT_STEREO,
|
|
.mpf = 1,
|
|
.frequency =
|
|
MPEG_SAMPLING_FREQ_16000 |
|
|
MPEG_SAMPLING_FREQ_22050 |
|
|
MPEG_SAMPLING_FREQ_24000 |
|
|
MPEG_SAMPLING_FREQ_32000 |
|
|
MPEG_SAMPLING_FREQ_44100 |
|
|
MPEG_SAMPLING_FREQ_48000,
|
|
.bitrate =
|
|
MPEG_BIT_RATE_VBR |
|
|
MPEG_BIT_RATE_320000 |
|
|
MPEG_BIT_RATE_256000 |
|
|
MPEG_BIT_RATE_224000 |
|
|
MPEG_BIT_RATE_192000 |
|
|
MPEG_BIT_RATE_160000 |
|
|
MPEG_BIT_RATE_128000 |
|
|
MPEG_BIT_RATE_112000 |
|
|
MPEG_BIT_RATE_96000 |
|
|
MPEG_BIT_RATE_80000 |
|
|
MPEG_BIT_RATE_64000 |
|
|
MPEG_BIT_RATE_56000 |
|
|
MPEG_BIT_RATE_48000 |
|
|
MPEG_BIT_RATE_40000 |
|
|
MPEG_BIT_RATE_32000 |
|
|
MPEG_BIT_RATE_FREE,
|
|
};
|
|
#endif
|
|
|
|
extern struct a2dp_codec a2dp_codec_sbc;
|
|
extern struct a2dp_codec a2dp_codec_sbc_xq;
|
|
#if ENABLE_LDAC
|
|
extern struct a2dp_codec a2dp_codec_ldac;
|
|
#endif
|
|
#if ENABLE_AAC
|
|
extern struct a2dp_codec a2dp_codec_aac;
|
|
#endif
|
|
#if ENABLE_MP3
|
|
extern struct a2dp_codec a2dp_codec_mpeg;
|
|
#endif
|
|
#if ENABLE_APTX
|
|
extern struct a2dp_codec a2dp_codec_aptx;
|
|
extern struct a2dp_codec a2dp_codec_aptx_hd;
|
|
#endif
|
|
|
|
const struct a2dp_codec *a2dp_codec_list[] = {
|
|
#if ENABLE_LDAC
|
|
&a2dp_codec_ldac,
|
|
#endif
|
|
#if ENABLE_APTX
|
|
&a2dp_codec_aptx_hd,
|
|
&a2dp_codec_aptx,
|
|
#endif
|
|
#if ENABLE_AAC
|
|
&a2dp_codec_aac,
|
|
#endif
|
|
#if ENABLE_MP3
|
|
&a2dp_codec_mpeg,
|
|
#endif
|
|
&a2dp_codec_sbc_xq,
|
|
&a2dp_codec_sbc,
|
|
NULL,
|
|
};
|
|
const struct a2dp_codec **a2dp_codecs = a2dp_codec_list;
|