player: add --audio-stream-silence

Completely insane that this has to be done. Crap for compensating HDMI
crap.
This commit is contained in:
wm4 2016-08-09 16:22:06 +02:00
parent 3759a3f40b
commit eab92cec60
8 changed files with 27 additions and 2 deletions

View File

@ -1341,6 +1341,17 @@ Audio
Default: 0.2 (200 ms).
``--audio-stream-silence=<yes|no>``
Cash-grab consumer audio hardware (such as A/V receivers) often ignore
initial audio sent over HDMI. This can happen every time audio over HDMI
is stopped and resumed. In order to compensate for this, you can enable
this option to not to stop and restart audio on seeks, and fill the gaps
with silence. Likewise, when pausing playback, audio is not stopped, and
silence is played while paused. Note that if no audio track is selected,
the audio device will still be closed immediately.
Not all AOs support this.
Subtitles
---------

View File

@ -183,6 +183,8 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
ao->api_priv = talloc_zero_size(ao, ao->api->priv_size);
assert(!ao->api->priv_defaults && !ao->api->options);
ao->stream_silence = flags & AO_INIT_STREAM_SILENCE;
int r = ao->driver->init(ao);
if (r < 0) {
// Silly exception for coreaudio spdif redirection

View File

@ -56,6 +56,8 @@ enum {
// Only accept multichannel configurations that are guaranteed to work
// (i.e. not sending arbitrary layouts over HDMI).
AO_INIT_SAFE_MULTICHANNEL_ONLY = 1 << 1,
// Stream silence as long as no audio is playing.
AO_INIT_STREAM_SILENCE = 1 << 2,
};
typedef struct ao_control_vol {

View File

@ -44,6 +44,7 @@ struct ao {
struct input_ctx *input_ctx;
struct mp_log *log; // Using e.g. "[ao/coreaudio]" as prefix
int init_flags; // AO_INIT_* flags
bool stream_silence; // if audio inactive, just play silence
// The device as selected by the user, usually using ao_device_desc.name
// from an entry from the list returned by driver->list_devices. If the

View File

@ -185,7 +185,7 @@ static double get_delay(struct ao *ao)
static void reset(struct ao *ao)
{
struct ao_pull_state *p = ao->api_priv;
if (ao->driver->reset)
if (!ao->stream_silence && ao->driver->reset)
ao->driver->reset(ao); // assumes the audio callback thread is stopped
set_state(ao, AO_STATE_NONE);
for (int n = 0; n < ao->num_planes; n++)
@ -195,7 +195,7 @@ static void reset(struct ao *ao)
static void pause(struct ao *ao)
{
if (ao->driver->reset)
if (!ao->stream_silence && ao->driver->reset)
ao->driver->reset(ao);
set_state(ao, AO_STATE_NONE);
}
@ -244,6 +244,10 @@ static int init(struct ao *ao)
p->buffers[n] = mp_ring_new(ao, ao->buffer * ao->sstride);
atomic_store(&p->state, AO_STATE_NONE);
assert(ao->driver->resume);
if (ao->stream_silence)
ao->driver->resume(ao);
return 0;
}

View File

@ -396,6 +396,7 @@ const m_option_t mp_opts[] = {
OPT_STRING("audio-device", audio_device, 0),
OPT_STRING("audio-client-name", audio_client_name, 0),
OPT_FLAG("audio-fallback-to-null", ao_null_fallback, 0),
OPT_FLAG("audio-stream-silence", audio_stream_silence, 0),
OPT_CHOICE("force-window", force_vo, 0,
({"no", 0}, {"yes", 1}, {"immediate", 2})),
OPT_FLAG("taskbar-progress", vo.taskbar_progress, 0),

View File

@ -87,6 +87,7 @@ typedef struct MPOpts {
char *audio_device;
char *audio_client_name;
int ao_null_fallback;
int audio_stream_silence;
int force_vo;
int softvol;
float softvol_volume;

View File

@ -382,6 +382,9 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
if (!opts->audio_output_channels.set || opts->audio_output_channels.auto_safe)
ao_flags |= AO_INIT_SAFE_MULTICHANNEL_ONLY;
if (opts->audio_stream_silence)
ao_flags |= AO_INIT_STREAM_SILENCE;
mp_chmap_sel_list(&afs->output.channels, opts->audio_output_channels.chmaps,
opts->audio_output_channels.num_chmaps);