[streaming/xcode] configurable MP3 streaming bitrate

This commit is contained in:
whatdoineed2do/Ray 2019-08-23 16:22:11 +01:00 committed by ejurgensen
parent cae790ed7e
commit 554799ebc3
10 changed files with 61 additions and 7 deletions

View File

@ -367,3 +367,16 @@ sqlite {
# but may reduce database size). Default is yes.
# vacuum = yes
}
# Streaming audio settings for remote connections (ie stream.mp3)
streaming {
# Sample rate, typically 44100 or 48000
# sample_rate = 44100
# Channels
# channels = 2
# Set the MP3 streaming bit rate (in kbps), valid options: 64 / 96 / 128 / 192 / 320
# bit_rate = 192
}

View File

@ -60,6 +60,7 @@ static cfg_opt_t sec_general[] =
#else
CFG_BOOL("high_resolution_clock", cfg_true, CFGF_NONE),
#endif
CFG_INT("streaming_bitrate", 192, CFGF_NONE),
// Hidden options
CFG_INT("db_pragma_cache_size", -1, CFGF_NONE),
CFG_STR("db_pragma_journal_mode", NULL, CFGF_NONE),
@ -186,6 +187,15 @@ static cfg_opt_t sec_mpd[] =
CFG_END()
};
/* streaming section structure */
static cfg_opt_t sec_streaming[] =
{
CFG_INT("sample_rate", 44100, CFGF_NONE),
CFG_INT("channels", 2, CFGF_NONE),
CFG_INT("bit_rate", 192, CFGF_NONE),
CFG_END()
};
/* Config file structure */
static cfg_opt_t toplvl_cfg[] =
{
@ -198,6 +208,7 @@ static cfg_opt_t toplvl_cfg[] =
CFG_SEC("spotify", sec_spotify, CFGF_NONE),
CFG_SEC("sqlite", sec_sqlite, CFGF_NONE),
CFG_SEC("mpd", sec_mpd, CFGF_NONE),
CFG_SEC("streaming", sec_streaming, CFGF_NONE),
CFG_END()
};

View File

@ -1034,7 +1034,7 @@ httpd_request_parse(struct evhttp_request *req, struct httpd_uri_parsed *uri_par
void
httpd_stream_file(struct evhttp_request *req, int id)
{
struct media_quality quality = { HTTPD_STREAM_SAMPLE_RATE, HTTPD_STREAM_BPS, HTTPD_STREAM_CHANNELS };
struct media_quality quality = { HTTPD_STREAM_SAMPLE_RATE, HTTPD_STREAM_BPS, HTTPD_STREAM_CHANNELS, 0 };
struct media_file_info *mfi;
struct stream_ctx *st;
void (*stream_cb)(int fd, short event, void *arg);

View File

@ -52,6 +52,8 @@ extern struct event_base *evbase_httpd;
#define STREAMING_MP3_SAMPLE_RATE 44100
#define STREAMING_MP3_BPS 16
#define STREAMING_MP3_CHANNELS 2
#define STREAMING_MP3_BIT_RATE 192000
static int streaming_mp3_bit_rate = STREAMING_MP3_BIT_RATE;
// Linked list of mp3 streaming requests
@ -182,7 +184,7 @@ streaming_end(void)
static void
streaming_meta_cb(evutil_socket_t fd, short event, void *arg)
{
struct media_quality mp3_quality = { STREAMING_MP3_SAMPLE_RATE, STREAMING_MP3_BPS, STREAMING_MP3_CHANNELS };
struct media_quality mp3_quality = { STREAMING_MP3_SAMPLE_RATE, STREAMING_MP3_BPS, STREAMING_MP3_CHANNELS, streaming_mp3_bit_rate };
struct media_quality quality;
struct decode_ctx *decode_ctx;
int ret;
@ -204,6 +206,9 @@ streaming_meta_cb(evutil_socket_t fd, short event, void *arg)
if (!decode_ctx)
goto error;
if (quality.bit_rate)
mp3_quality.bit_rate = quality.bit_rate;
streaming_encode_ctx = transcode_encode_setup(XCODE_MP3, &mp3_quality, decode_ctx, NULL, 0, 0);
transcode_decode_cleanup(&decode_ctx);
if (!streaming_encode_ctx)
@ -618,6 +623,23 @@ streaming_init(void)
{
int ret;
streaming_mp3_bit_rate = cfg_getint(cfg_getsec(cfg, "streaming"), "bit_rate");
switch (streaming_mp3_bit_rate)
{
case 64:
case 96:
case 128:
case 192:
case 320:
streaming_mp3_bit_rate *= 1000;
break;
default:
DPRINTF(E_WARN, L_STREAMING, "streaming bit_rate=%d not 128/192/320, defaulting\n", streaming_mp3_bit_rate);
streaming_mp3_bit_rate = STREAMING_MP3_BIT_RATE;
}
DPRINTF(E_INFO, L_STREAMING, "streaming bit_rate=%d\n", streaming_mp3_bit_rate);
pthread_mutex_init(&streaming_sessions_lck, NULL);
// Non-blocking because otherwise httpd and player thread may deadlock

View File

@ -31,6 +31,7 @@ struct media_quality {
int sample_rate;
int bits_per_sample;
int channels;
int bit_rate;
};
struct onekeyval {

View File

@ -140,7 +140,7 @@ static int alsa_latency_history_size;
// We will try to play the music with the source quality, but if the card
// doesn't support that we resample to the fallback quality
static struct media_quality alsa_fallback_quality = { 44100, 16, 2 };
static struct media_quality alsa_fallback_quality = { 44100, 16, 2, 0 };
static struct media_quality alsa_last_quality;

View File

@ -446,7 +446,7 @@ static struct cast_session *cast_sessions;
static struct cast_master_session *cast_master_session;
//static struct timeval heartbeat_timeout = { HEARTBEAT_TIMEOUT, 0 };
static struct timeval reply_timeout = { REPLY_TIMEOUT, 0 };
static struct media_quality cast_quality_default = { CAST_QUALITY_SAMPLE_RATE_DEFAULT, CAST_QUALITY_BITS_PER_SAMPLE_DEFAULT, CAST_QUALITY_CHANNELS_DEFAULT };
static struct media_quality cast_quality_default = { CAST_QUALITY_SAMPLE_RATE_DEFAULT, CAST_QUALITY_BITS_PER_SAMPLE_DEFAULT, CAST_QUALITY_CHANNELS_DEFAULT, 0 };
/* ------------------------------- MISC HELPERS ----------------------------- */

View File

@ -61,7 +61,7 @@ struct fifo_buffer
static struct fifo_buffer buffer;
static struct media_quality fifo_quality = { 44100, 16, 2 };
static struct media_quality fifo_quality = { 44100, 16, 2, 0 };
static void

View File

@ -86,7 +86,7 @@ static struct pulse_session *sessions;
static uint32_t pulse_known_devices[PULSE_MAX_DEVICES];
static struct media_quality pulse_last_quality;
static struct media_quality pulse_fallback_quality = { 44100, 16, 2 };
static struct media_quality pulse_fallback_quality = { 44100, 16, 2, 0 };
// Converts from 0 - 100 to Pulseaudio's scale
static inline pa_volume_t

View File

@ -79,6 +79,7 @@ struct settings_ctx
int sample_rate;
uint64_t channel_layout;
int channels;
int bit_rate;
enum AVSampleFormat sample_format;
bool wavheader;
bool icy;
@ -262,6 +263,11 @@ init_settings(struct settings_ctx *settings, enum transcode_profile profile, str
settings->channel_layout = av_get_default_channel_layout(quality->channels);
}
if (quality && quality->bit_rate)
{
settings->bit_rate = quality->bit_rate;
}
if (quality && quality->bits_per_sample && (quality->bits_per_sample != 8 * av_get_bytes_per_sample(settings->sample_format)))
{
DPRINTF(E_LOG, L_XCODE, "Bug! Mismatch between profile and media quality\n");
@ -281,6 +287,7 @@ stream_settings_set(struct stream_ctx *s, struct settings_ctx *settings, enum AV
s->codec->channels = settings->channels;
s->codec->sample_fmt = settings->sample_format;
s->codec->time_base = (AVRational){1, settings->sample_rate};
s->codec->bit_rate = settings->bit_rate;
}
else if (type == AVMEDIA_TYPE_VIDEO)
{
@ -731,7 +738,7 @@ open_decoder(unsigned int *stream_index, struct decode_ctx *ctx, enum AVMediaTyp
if ((*stream_index < 0) || (!decoder))
{
if (!ctx->settings.silent)
DPRINTF(E_LOG, L_XCODE, "No stream data or decoder for stream #%d\n", *stream_index);
DPRINTF(E_LOG, L_XCODE, "No stream data or decoder for stream #%d\n", *stream_index);
return NULL;
}