summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-08-09 16:22:06 +0200
committerwm4 <wm4@nowhere>2016-08-09 17:09:29 +0200
commiteab92cec60d92e0de2ea53d4d01052f4d7acc5d5 (patch)
treecb6202b24b7407283dd5f28e650d3fc869a7e33d
parent3759a3f40bed92b161342532445718906f903234 (diff)
downloadmpv-eab92cec60d92e0de2ea53d4d01052f4d7acc5d5.tar.bz2
mpv-eab92cec60d92e0de2ea53d4d01052f4d7acc5d5.tar.xz
player: add --audio-stream-silence
Completely insane that this has to be done. Crap for compensating HDMI crap.
-rw-r--r--DOCS/man/options.rst11
-rw-r--r--audio/out/ao.c2
-rw-r--r--audio/out/ao.h2
-rw-r--r--audio/out/internal.h1
-rw-r--r--audio/out/pull.c8
-rw-r--r--options/options.c1
-rw-r--r--options/options.h1
-rw-r--r--player/audio.c3
8 files changed, 27 insertions, 2 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 456c3c3f94..344b77bf3a 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -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
---------
diff --git a/audio/out/ao.c b/audio/out/ao.c
index 0647067e50..cf66e0c64b 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -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
diff --git a/audio/out/ao.h b/audio/out/ao.h
index 3c16cef0e5..3b187e7355 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -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 {
diff --git a/audio/out/internal.h b/audio/out/internal.h
index 88160bbeb6..518661c2bd 100644
--- a/audio/out/internal.h
+++ b/audio/out/internal.h
@@ -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
diff --git a/audio/out/pull.c b/audio/out/pull.c
index 89805809b7..2175a58db0 100644
--- a/audio/out/pull.c
+++ b/audio/out/pull.c
@@ -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;
}
diff --git a/options/options.c b/options/options.c
index 9fd853ffda..833568659f 100644
--- a/options/options.c
+++ b/options/options.c
@@ -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),
diff --git a/options/options.h b/options/options.h
index ef72865f56..2aff254fbd 100644
--- a/options/options.h
+++ b/options/options.h
@@ -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;
diff --git a/player/audio.c b/player/audio.c
index e186a375b6..1f0fe9d0a0 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -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);