mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-26 07:05:57 -05:00
[streaming/xcode] configurable MP3 streaming bitrate
This commit is contained in:
parent
cae790ed7e
commit
554799ebc3
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -31,6 +31,7 @@ struct media_quality {
|
||||
int sample_rate;
|
||||
int bits_per_sample;
|
||||
int channels;
|
||||
int bit_rate;
|
||||
};
|
||||
|
||||
struct onekeyval {
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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 ----------------------------- */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user