Skip to content

Commit

Permalink
audio: fix stream-silence with push AOs (somewhat)
Browse files Browse the repository at this point in the history
--audio-stream-silence is a shitty feature compensating for awful
consumer garbage, that mutes PCM at first to check whether it's
compressed audio, using formats advocated and owned by malicious patent
troll companies (who spend more money on their lawyers than paying any
technicians), wrapped in a wasteful way to make it constant bitrate
using a standard whose text is not freely available, and only rude users
want it. This feature has been carelessly broken, because it's
complicated and stupid. What would Jesus do? If not getting an aneurysm,
or pushing over tables with expensive A/V receivers on top of them, he'd
probably fix the feature. So let's take inspiration from Jesus Christ
himself, and do something as dumb as wasting some of our limited
lifetime on this incredibly stupid fucking shit.

This is tricky, because state changes like end-of-audio are supposed to
be driven by the AO driver, while playing silence precludes this. But it
seems code paths for "untimed" AOs can be reused.

But there are still problems. For example, underruns will just happen
normally (and stop audio streaming), because we don't have a separate
heuristic to check whether the buffer is "low enough" (as a consequence
of a network stall, but before the audio output itself underruns).
  • Loading branch information
wm4 committed Sep 3, 2020
1 parent b5c2253 commit 1643cb8
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
5 changes: 5 additions & 0 deletions DOCS/man/options.rst
Expand Up @@ -2116,6 +2116,11 @@ Audio

Not all AOs support this.

.. admonition:: Warning

This modifies certain subtle player behavior, like A/V-sync and underrun
handling. Enabling this option is strongly discouraged.

``--audio-wait-open=<secs>``
This makes sense for use with ``--audio-stream-silence=yes``. If this option
is given, the player will wait for the given amount of seconds after opening
Expand Down
15 changes: 10 additions & 5 deletions audio/out/buffer.c
Expand Up @@ -95,7 +95,7 @@ static void get_dev_state(struct ao *ao, struct mp_pcm_state *state)
{
struct buffer_state *p = ao->buffer_state;

if (p->paused && p->playing) {
if (p->paused && p->playing && !ao->stream_silence) {
*state = p->prepause_state;
return;
}
Expand Down Expand Up @@ -527,6 +527,11 @@ bool init_buffer_post(struct ao *ao)
}
}

if (ao->stream_silence) {
MP_WARN(ao, "The --audio-stream-silence option is set. This will break "
"certain player behavior.\n");
}

return true;
}

Expand Down Expand Up @@ -557,7 +562,7 @@ static bool ao_play_data(struct ao *ao)
{
struct buffer_state *p = ao->buffer_state;

if (!(p->playing && (!p->paused || ao->stream_silence)))
if ((!p->playing || p->paused) && !ao->stream_silence)
return false;

struct mp_pcm_state state;
Expand Down Expand Up @@ -624,8 +629,8 @@ static bool ao_play_data(struct ao *ao)
eof:
MP_VERBOSE(ao, "audio end or underrun\n");
// Normal AOs signal EOF on underrun, untimed AOs never signal underruns.
if (ao->untimed || !state.playing) {
p->streaming = false;
if (ao->untimed || !state.playing || ao->stream_silence) {
p->streaming = state.playing && !ao->untimed;
p->playing = false;
}
ao->wakeup_cb(ao->wakeup_ctx);
Expand All @@ -649,7 +654,7 @@ static void *playthread(void *arg)
// Wait until the device wants us to write more data to it.
// Fallback to guessing.
double timeout = INFINITY;
if (p->streaming && !p->paused && !retry) {
if (p->streaming && !retry && (!p->paused || ao->stream_silence)) {
// Wake up again if half of the audio buffer has been played.
// Since audio could play at a faster or slower pace, wake up twice
// as often as ideally needed.
Expand Down

0 comments on commit 1643cb8

Please sign in to comment.