summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-03-07 15:24:32 +0100
committerwm4 <wm4@nowhere>2014-03-09 00:19:31 +0100
commit41f2b26d11e81095a0d8d370480e0d2459208070 (patch)
tree1b665e392be25795b8fade6d0487609f73ac90d2
parent74b7001500c0901b095986fafe7dca3e5c23c7f2 (diff)
downloadmpv-41f2b26d11e81095a0d8d370480e0d2459208070.tar.bz2
mpv-41f2b26d11e81095a0d8d370480e0d2459208070.tar.xz
audio/out: make ao struct opaque
We want to move the AO to its own thread. There's no technical reason for making the ao struct opaque to do this. But it helps us sleep at night, because we can control access to shared state better.
-rw-r--r--audio/mixer.c12
-rw-r--r--audio/out/ao.c38
-rw-r--r--audio/out/ao.h69
-rw-r--r--audio/out/ao_alsa.c1
-rw-r--r--audio/out/ao_coreaudio.c1
-rw-r--r--audio/out/ao_coreaudio_properties.h2
-rw-r--r--audio/out/ao_coreaudio_utils.h1
-rw-r--r--audio/out/ao_dsound.c1
-rw-r--r--audio/out/ao_jack.c1
-rw-r--r--audio/out/ao_lavc.c1
-rw-r--r--audio/out/ao_null.c1
-rw-r--r--audio/out/ao_openal.c1
-rw-r--r--audio/out/ao_oss.c1
-rw-r--r--audio/out/ao_pcm.c1
-rw-r--r--audio/out/ao_portaudio.c1
-rw-r--r--audio/out/ao_pulse.c1
-rw-r--r--audio/out/ao_rsound.c1
-rw-r--r--audio/out/ao_sdl.c1
-rw-r--r--audio/out/ao_sndio.c1
-rw-r--r--audio/out/ao_wasapi.c1
-rw-r--r--audio/out/internal.h76
-rw-r--r--player/audio.c98
-rw-r--r--player/core.h5
-rw-r--r--player/loadfile.c6
-rw-r--r--player/playloop.c11
-rw-r--r--player/video.c2
26 files changed, 218 insertions, 117 deletions
diff --git a/audio/mixer.c b/audio/mixer.c
index a9759976a2..34a1722c80 100644
--- a/audio/mixer.c
+++ b/audio/mixer.c
@@ -210,7 +210,7 @@ void mixer_setbalance(struct mixer *mixer, float val)
if (af_control_any_rev(mixer->af, AF_CONTROL_SET_PAN_BALANCE, &val))
return;
- if (val == 0 || mixer->ao->channels.num < 2)
+ if (val == 0)
return;
if (!(af_pan_balance = af_add(mixer->af, "pan", NULL))) {
@@ -243,8 +243,9 @@ static void probe_softvol(struct mixer *mixer)
{
if (mixer->opts->softvol == SOFTVOL_AUTO) {
// No system-wide volume => fine with AO volume control.
- mixer->softvol = !(mixer->ao->per_application_mixer ||
- mixer->ao->no_persistent_volume);
+ mixer->softvol =
+ ao_control(mixer->ao, AOCONTROL_HAS_TEMP_VOLUME, 0) != 1 &&
+ ao_control(mixer->ao, AOCONTROL_HAS_PER_APP_VOLUME, 0) != 1;
} else {
mixer->softvol = mixer->opts->softvol == SOFTVOL_YES;
}
@@ -275,9 +276,10 @@ static void restore_volume(struct mixer *mixer)
int force_mute = -1;
const char *prev_driver = mixer->driver;
- mixer->driver = mixer->softvol ? "softvol" : ao->driver->name;
+ mixer->driver = mixer->softvol ? "softvol" : ao_get_name(ao);
- bool restore = mixer->softvol || ao->no_persistent_volume;
+ bool restore
+ = mixer->softvol || ao_control(ao, AOCONTROL_HAS_TEMP_VOLUME, 0) == 1;
// Restore old parameters if volume won't survive reinitialization.
// But not if volume scale is possibly different.
diff --git a/audio/out/ao.c b/audio/out/ao.c
index 02415b0f2d..b77d401d64 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -25,7 +25,9 @@
#include "config.h"
#include "ao.h"
+#include "internal.h"
#include "audio/format.h"
+#include "audio/audio.h"
#include "options/options.h"
#include "options/m_config.h"
@@ -231,8 +233,15 @@ int ao_play(struct ao *ao, void **data, int samples, int flags)
int ao_control(struct ao *ao, enum aocontrol cmd, void *arg)
{
- if (ao->driver->control)
- return ao->driver->control(ao, cmd, arg);
+ switch (cmd) {
+ case AOCONTROL_HAS_TEMP_VOLUME:
+ return !ao->no_persistent_volume;
+ case AOCONTROL_HAS_PER_APP_VOLUME:
+ return !!ao->per_application_mixer;
+ default:
+ if (ao->driver->control)
+ return ao->driver->control(ao, cmd, arg);
+ }
return CONTROL_UNKNOWN;
}
@@ -307,3 +316,28 @@ bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
{
return mp_chmap_sel_get_def(s, map, num);
}
+
+// --- The following functions just return immutable information.
+
+void ao_get_format(struct ao *ao, struct mp_audio *format)
+{
+ *format = (struct mp_audio){0};
+ mp_audio_set_format(format, ao->format);
+ mp_audio_set_channels(format, &ao->channels);
+ format->rate = ao->samplerate;
+}
+
+const char *ao_get_name(struct ao *ao)
+{
+ return ao->driver->name;
+}
+
+const char *ao_get_description(struct ao *ao)
+{
+ return ao->driver->description;
+}
+
+bool ao_untimed(struct ao *ao)
+{
+ return ao->untimed;
+}
diff --git a/audio/out/ao.h b/audio/out/ao.h
index 73a7cdfa61..152490aacc 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -36,6 +36,8 @@ enum aocontrol {
AOCONTROL_SET_MUTE,
// Has char* as argument, which contains the desired stream title.
AOCONTROL_UPDATE_STREAM_TITLE,
+ AOCONTROL_HAS_TEMP_VOLUME,
+ AOCONTROL_HAS_PER_APP_VOLUME,
};
// If set, then the queued audio data is the last. Note that after a while, new
@@ -48,64 +50,20 @@ typedef struct ao_control_vol {
} ao_control_vol_t;
struct ao;
-
-struct ao_driver {
- // If true, use with encoding only.
- bool encode;
- // Name used for --ao.
- const char *name;
- // Description shown with --ao=help.
- const char *description;
- // Init the device using ao->format/ao->channels/ao->samplerate. If the
- // device doesn't accept these parameters, you can attempt to negotiate
- // fallback parameters, and set the ao format fields accordingly.
- int (*init)(struct ao *ao);
- // See ao_control() etc. in ao.c
- int (*control)(struct ao *ao, enum aocontrol cmd, void *arg);
- void (*uninit)(struct ao *ao, bool cut_audio);
- void (*reset)(struct ao*ao);
- int (*get_space)(struct ao *ao);
- int (*play)(struct ao *ao, void **data, int samples, int flags);
- float (*get_delay)(struct ao *ao);
- void (*pause)(struct ao *ao);
- void (*resume)(struct ao *ao);
-
- // For option parsing (see vo.h)
- int priv_size;
- const void *priv_defaults;
- const struct m_option *options;
-};
-
-/* global data used by mplayer and plugins */
-struct ao {
- int samplerate;
- struct mp_chmap channels;
- int format; // one of AF_FORMAT_...
- int bps; // bytes per second
- int sstride; // size of a sample on each plane
- // (format_size*num_channels/num_planes)
- double pts; // some mplayer.c state (why is this here?)
- struct mp_audio_buffer *buffer; // queued audio; passed to play() later
- int buffer_playable_samples;// part of the part of the buffer the AO hasn't
- // accepted yet with play()
- bool probing; // if true, don't fail loudly on init
- bool untimed; // don't assume realtime playback
- bool no_persistent_volume; // the AO does the equivalent of af_volume
- bool per_application_mixer; // like above, but volume persists (per app)
- const struct ao_driver *driver;
- void *priv;
- struct encode_lavc_context *encode_lavc_ctx;
- struct MPOpts *opts;
- struct input_ctx *input_ctx;
- struct mp_log *log; // Using e.g. "[ao/coreaudio]" as prefix
-};
-
struct mpv_global;
+struct input_ctx;
+struct encode_lavc_context;
+struct mp_audio;
+
struct ao *ao_init_best(struct mpv_global *global,
struct input_ctx *input_ctx,
struct encode_lavc_context *encode_lavc_ctx,
int samplerate, int format, struct mp_chmap channels);
void ao_uninit(struct ao *ao, bool cut_audio);
+void ao_get_format(struct ao *ao, struct mp_audio *format);
+const char *ao_get_name(struct ao *ao);
+const char *ao_get_description(struct ao *ao);
+bool ao_untimed(struct ao *ao);
int ao_play(struct ao *ao, void **data, int samples, int flags);
int ao_control(struct ao *ao, enum aocontrol cmd, void *arg);
double ao_get_delay(struct ao *ao);
@@ -114,11 +72,4 @@ void ao_reset(struct ao *ao);
void ao_pause(struct ao *ao);
void ao_resume(struct ao *ao);
-int ao_play_silence(struct ao *ao, int samples);
-
-bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
- struct mp_chmap *map);
-bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
- struct mp_chmap *map, int num);
-
#endif /* MPLAYER_AUDIO_OUT_H */
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index 2237c4dd59..d50757bdfd 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -46,6 +46,7 @@
#include <alsa/asoundlib.h>
#include "ao.h"
+#include "internal.h"
#include "audio/format.h"
#include "audio/reorder_ch.h"
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index ba95fa728d..36be7c5872 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -37,6 +37,7 @@
#include "config.h"
#include "ao.h"
+#include "internal.h"
#include "audio/format.h"
#include "osdep/timer.h"
#include "options/m_option.h"
diff --git a/audio/out/ao_coreaudio_properties.h b/audio/out/ao_coreaudio_properties.h
index ee7f83e6b7..e48b75871e 100644
--- a/audio/out/ao_coreaudio_properties.h
+++ b/audio/out/ao_coreaudio_properties.h
@@ -21,6 +21,8 @@
#include <AudioToolbox/AudioToolbox.h>
+#include "internal.h"
+
// CoreAudio names are way too verbose
#define ca_sel AudioObjectPropertySelector
#define ca_scope AudioObjectPropertyScope
diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h
index cf69248b47..0aca2f7c62 100644
--- a/audio/out/ao_coreaudio_utils.h
+++ b/audio/out/ao_coreaudio_utils.h
@@ -24,6 +24,7 @@
#include <stdbool.h>
#include "common/msg.h"
#include "audio/out/ao.h"
+#include "internal.h"
#define CA_CFSTR_ENCODING kCFStringEncodingASCII
diff --git a/audio/out/ao_dsound.c b/audio/out/ao_dsound.c
index 26c7bb83ed..ce7346fbdb 100644
--- a/audio/out/ao_dsound.c
+++ b/audio/out/ao_dsound.c
@@ -38,6 +38,7 @@
#include "config.h"
#include "audio/format.h"
#include "ao.h"
+#include "internal.h"
#include "audio/reorder_ch.h"
#include "common/msg.h"
#include "osdep/timer.h"
diff --git a/audio/out/ao_jack.c b/audio/out/ao_jack.c
index 72235a2d48..5b142f2d06 100644
--- a/audio/out/ao_jack.c
+++ b/audio/out/ao_jack.c
@@ -32,6 +32,7 @@
#include "common/msg.h"
#include "ao.h"
+#include "internal.h"
#include "audio/format.h"
#include "osdep/timer.h"
#include "options/m_option.h"
diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c
index 9a2df7be22..7d31f63ec9 100644
--- a/audio/out/ao_lavc.c
+++ b/audio/out/ao_lavc.c
@@ -36,6 +36,7 @@
#include "audio/fmt-conversion.h"
#include "talloc.h"
#include "ao.h"
+#include "internal.h"
#include "common/msg.h"
#include "common/encode_lavc.h"
diff --git a/audio/out/ao_null.c b/audio/out/ao_null.c
index 7c912d94a4..7caee039e0 100644
--- a/audio/out/ao_null.c
+++ b/audio/out/ao_null.c
@@ -34,6 +34,7 @@
#include "common/msg.h"
#include "audio/format.h"
#include "ao.h"
+#include "internal.h"
struct priv {
bool paused;
diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c
index 3cb8ba5149..8cc29db689 100644
--- a/audio/out/ao_openal.c
+++ b/audio/out/ao_openal.c
@@ -38,6 +38,7 @@
#include "common/msg.h"
#include "ao.h"
+#include "internal.h"
#include "audio/format.h"
#include "osdep/timer.h"
#include "options/m_option.h"
diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c
index 574fcf6beb..a1bf0feefc 100644
--- a/audio/out/ao_oss.c
+++ b/audio/out/ao_oss.c
@@ -49,6 +49,7 @@
#include "audio/format.h"
#include "ao.h"
+#include "internal.h"
struct priv {
int audio_fd;
diff --git a/audio/out/ao_pcm.c b/audio/out/ao_pcm.c
index 14548d3be3..5824f7ce99 100644
--- a/audio/out/ao_pcm.c
+++ b/audio/out/ao_pcm.c
@@ -34,6 +34,7 @@
#include "audio/format.h"
#include "audio/reorder_ch.h"
#include "ao.h"
+#include "internal.h"
#include "common/msg.h"
#ifdef __MINGW32__
diff --git a/audio/out/ao_portaudio.c b/audio/out/ao_portaudio.c
index 8b7e3041cd..c3ba343485 100644
--- a/audio/out/ao_portaudio.c
+++ b/audio/out/ao_portaudio.c
@@ -31,6 +31,7 @@
#include "common/msg.h"
#include "misc/ring.h"
#include "ao.h"
+#include "internal.h"
struct priv {
PaStream *stream;
diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c
index fc93c40871..12fca17dd6 100644
--- a/audio/out/ao_pulse.c
+++ b/audio/out/ao_pulse.c
@@ -31,6 +31,7 @@
#include "audio/format.h"
#include "common/msg.h"
#include "ao.h"
+#include "internal.h"
#include "input/input.h"
#define PULSE_CLIENT_NAME "mpv"
diff --git a/audio/out/ao_rsound.c b/audio/out/ao_rsound.c
index 6bd99030a1..ef81c621da 100644
--- a/audio/out/ao_rsound.c
+++ b/audio/out/ao_rsound.c
@@ -33,6 +33,7 @@
#include "osdep/timer.h"
#include "audio/format.h"
#include "ao.h"
+#include "internal.h"
struct priv {
rsound_t *rd;
diff --git a/audio/out/ao_sdl.c b/audio/out/ao_sdl.c
index ac1fd6febb..acb959b101 100644
--- a/audio/out/ao_sdl.c
+++ b/audio/out/ao_sdl.c
@@ -23,6 +23,7 @@
#include "audio/format.h"
#include "talloc.h"
#include "ao.h"
+#include "internal.h"
#include "common/msg.h"
#include "options/m_option.h"
#include "osdep/timer.h"
diff --git a/audio/out/ao_sndio.c b/audio/out/ao_sndio.c
index 75ea5d095b..c200b906ab 100644
--- a/audio/out/ao_sndio.c
+++ b/audio/out/ao_sndio.c
@@ -27,6 +27,7 @@
#include "audio/format.h"
#include "ao.h"
+#include "internal.h"
struct priv {
struct sio_hdl *hdl;
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index 39199159b3..bb00849adb 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -35,6 +35,7 @@
#include "common/msg.h"
#include "misc/ring.h"
#include "ao.h"
+#include "internal.h"
#include "compat/atomics.h"
#ifndef PKEY_Device_FriendlyName
diff --git a/audio/out/internal.h b/audio/out/internal.h
new file mode 100644
index 0000000000..5cb12886a7
--- /dev/null
+++ b/audio/out/internal.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MP_AO_INTERNAL_H_
+#define MP_AO_INTERNAL_H_
+
+/* global data used by ao.c and ao drivers */
+struct ao {
+ int samplerate;
+ struct mp_chmap channels;
+ int format; // one of AF_FORMAT_...
+ int bps; // bytes per second
+ int sstride; // size of a sample on each plane
+ // (format_size*num_channels/num_planes)
+ bool probing; // if true, don't fail loudly on init
+ bool untimed; // don't assume realtime playback
+ bool no_persistent_volume; // the AO does the equivalent of af_volume
+ bool per_application_mixer; // like above, but volume persists (per app)
+ const struct ao_driver *driver;
+ void *priv;
+ struct encode_lavc_context *encode_lavc_ctx;
+ struct MPOpts *opts;
+ struct input_ctx *input_ctx;
+ struct mp_log *log; // Using e.g. "[ao/coreaudio]" as prefix
+};
+
+struct ao_driver {
+ // If true, use with encoding only.
+ bool encode;
+ // Name used for --ao.
+ const char *name;
+ // Description shown with --ao=help.
+ const char *description;
+ // Init the device using ao->format/ao->channels/ao->samplerate. If the
+ // device doesn't accept these parameters, you can attempt to negotiate
+ // fallback parameters, and set the ao format fields accordingly.
+ int (*init)(struct ao *ao);
+ // See ao_control() etc. in ao.c
+ int (*control)(struct ao *ao, enum aocontrol cmd, void *arg);
+ void (*uninit)(struct ao *ao, bool cut_audio);
+ void (*reset)(struct ao*ao);
+ int (*get_space)(struct ao *ao);
+ int (*play)(struct ao *ao, void **data, int samples, int flags);
+ float (*get_delay)(struct ao *ao);
+ void (*pause)(struct ao *ao);
+ void (*resume)(struct ao *ao);
+
+ // For option parsing (see vo.h)
+ int priv_size;
+ const void *priv_defaults;
+ const struct m_option *options;
+};
+
+// These functions can be called by AOs. They don't lock the AO.
+int ao_play_silence(struct ao *ao, int samples);
+bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
+ struct mp_chmap *map);
+bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
+ struct mp_chmap *map, int num);
+
+#endif
diff --git a/player/audio.c b/player/audio.c
index 984243b639..c6e7411e2a 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -45,7 +45,6 @@
static int build_afilter_chain(struct MPContext *mpctx)
{
struct dec_audio *d_audio = mpctx->d_audio;
- struct ao *ao = mpctx->ao;
struct MPOpts *opts = mpctx->opts;
if (!d_audio)
@@ -54,13 +53,16 @@ static int build_afilter_chain(struct MPContext *mpctx)
struct mp_audio in_format;
mp_audio_buffer_get_format(d_audio->decode_buffer, &in_format);
+ struct mp_audio out_format;
+ ao_get_format(mpctx->ao, &out_format);
+
int new_srate;
if (af_control_any_rev(d_audio->afilter, AF_CONTROL_SET_PLAYBACK_SPEED,
&opts->playback_speed))
new_srate = in_format.rate;
else {
new_srate = in_format.rate * opts->playback_speed;
- if (new_srate != ao->samplerate) {
+ if (new_srate != out_format.rate) {
// limits are taken from libaf/af_resample.c
if (new_srate < 8000)
new_srate = 8000;
@@ -70,7 +72,7 @@ static int build_afilter_chain(struct MPContext *mpctx)
}
}
return audio_init_filters(d_audio, new_srate,
- &ao->samplerate, &ao->channels, &ao->format);
+ &out_format.rate, &out_format.channels, &out_format.format);
}
static int recreate_audio_filters(struct MPContext *mpctx)
@@ -135,9 +137,11 @@ void reinit_audio_chain(struct MPContext *mpctx)
int ao_format = opts->audio_output_format;
struct mp_chmap ao_channels = {0};
if (mpctx->initialized_flags & INITIALIZED_AO) {
- ao_srate = mpctx->ao->samplerate;
- ao_format = mpctx->ao->format;
- ao_channels = mpctx->ao->channels;
+ struct mp_audio out_format;
+ ao_get_format(mpctx->ao, &out_format);
+ ao_srate = out_format.rate;
+ ao_format = out_format.format;
+ ao_channels = out_format.channels;
} else {
// Automatic downmix
if (mp_chmap_is_stereo(&opts->audio_output_channels) &&
@@ -172,14 +176,16 @@ void reinit_audio_chain(struct MPContext *mpctx)
goto init_error;
}
- ao->buffer = mp_audio_buffer_create(ao);
- mp_audio_buffer_reinit_fmt(ao->buffer, ao->format, &ao->channels,
- ao->samplerate);
+ struct mp_audio fmt;
+ ao_get_format(ao, &fmt);
- char *s = mp_audio_fmt_to_str(ao->samplerate, &ao->channels, ao->format);
- MP_INFO(mpctx, "AO: [%s] %s\n", ao->driver->name, s);
+ mpctx->ao_buffer = mp_audio_buffer_create(ao);
+ mp_audio_buffer_reinit(mpctx->ao_buffer, &fmt);
+
+ char *s = mp_audio_config_to_str(&fmt);
+ MP_INFO(mpctx, "AO: [%s] %s\n", ao_get_name(ao), s);
talloc_free(s);
- MP_VERBOSE(mpctx, "AO: Description: %s\n", ao->driver->description);
+ MP_VERBOSE(mpctx, "AO: Description: %s\n", ao_get_description(ao));
update_window_title(mpctx, true);
}
@@ -228,7 +234,7 @@ double written_audio_pts(struct MPContext *mpctx)
// Data that was ready for ao but was buffered because ao didn't fully
// accept everything to internal buffers yet
- buffered_output += mp_audio_buffer_seconds(mpctx->ao->buffer);
+ buffered_output += mp_audio_buffer_seconds(mpctx->ao_buffer);
// Filters divide audio length by playback_speed, so multiply by it
// to get the length in original units without speedup or slowdown
@@ -252,11 +258,13 @@ static int write_to_ao(struct MPContext *mpctx, struct mp_audio *data, int flags
if (mpctx->paused)
return 0;
struct ao *ao = mpctx->ao;
- ao->pts = pts;
+ struct mp_audio out_format;
+ ao_get_format(ao, &out_format);
+ mpctx->ao_pts = pts;
#if HAVE_ENCODING
- encode_lavc_set_audio_pts(mpctx->encode_lavc_ctx, ao->pts);
+ encode_lavc_set_audio_pts(mpctx->encode_lavc_ctx, mpctx->ao_pts);
#endif
- double real_samplerate = ao->samplerate / mpctx->opts->playback_speed;
+ double real_samplerate = out_format.rate / mpctx->opts->playback_speed;
int played = ao_play(mpctx->ao, data->planes, data->samples, flags);
assert(played <= data->samples);
if (played > 0) {
@@ -264,7 +272,7 @@ static int write_to_ao(struct MPContext *mpctx, struct mp_audio *data, int flags
mpctx->delay += played / real_samplerate;
// Keep correct pts for remaining data - could be used to flush
// remaining buffer when closing ao.
- ao->pts += played / real_samplerate;
+ mpctx->ao_pts += played / real_samplerate;
return played;
}
return 0;
@@ -274,7 +282,7 @@ static int write_silence_to_ao(struct MPContext *mpctx, int samples, int flags,
double pts)
{
struct mp_audio tmp = {0};
- mp_audio_buffer_get_format(mpctx->ao->buffer, &tmp);
+ mp_audio_buffer_get_format(mpctx->ao_buffer, &tmp);
tmp.samples = samples;
char *p = talloc_size(NULL, tmp.samples * tmp.sstride);
for (int n = 0; n < tmp.num_planes; n++)
@@ -295,15 +303,18 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
assert(d_audio);
+ struct mp_audio out_format;
+ ao_get_format(ao, &out_format);
+
// Timing info may not be set without
- res = audio_decode(d_audio, ao->buffer, 1);
+ res = audio_decode(d_audio, mpctx->ao_buffer, 1);
if (res < 0)
return res;
int samples;
bool did_retry = false;
double written_pts;
- double real_samplerate = ao->samplerate / opts->playback_speed;
+ double real_samplerate = out_format.rate / opts->playback_speed;
bool hrseek = mpctx->hrseek_active; // audio only hrseek
mpctx->hrseek_active = false;
while (1) {
@@ -320,7 +331,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
if (written_pts <= 1 && d_audio->pts == MP_NOPTS_VALUE) {
if (!did_retry) {
// Try to read more data to see packets that have pts
- res = audio_decode(d_audio, ao->buffer, ao->samplerate);
+ res = audio_decode(d_audio, mpctx->ao_buffer, out_format.rate);
if (res < 0)
return res;
did_retry = true;
@@ -338,16 +349,16 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
mpctx->syncing_audio = false;
int skip_samples = -samples;
int a = MPMIN(skip_samples, MPMAX(playsize, 2500));
- res = audio_decode(d_audio, ao->buffer, a);
- if (skip_samples <= mp_audio_buffer_samples(ao->buffer)) {
- mp_audio_buffer_skip(ao->buffer, skip_samples);
- ao->buffer_playable_samples = 0;
+ res = audio_decode(d_audio, mpctx->ao_buffer, a);
+ if (skip_samples <= mp_audio_buffer_samples(mpctx->ao_buffer)) {
+ mp_audio_buffer_skip(mpctx->ao_buffer, skip_samples);
+ mpctx->ao_buffer_playable_samples = 0;
if (res < 0)
return res;
- return audio_decode(d_audio, ao->buffer, playsize);
+ return audio_decode(d_audio, mpctx->ao_buffer, playsize);
}
- mp_audio_buffer_clear(ao->buffer);
- ao->buffer_playable_samples = 0;
+ mp_audio_buffer_clear(mpctx->ao_buffer);
+ mpctx->ao_buffer_playable_samples = 0;
if (res < 0)
return res;
}
@@ -357,15 +368,15 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
if (samples >= playsize) {
/* This case could fall back to the one below with
* samples = playsize, but then silence would keep accumulating
- * in ao->buffer if the AO accepts less data than it asks for
+ * in ao_buffer if the AO accepts less data than it asks for
* in playsize. */
write_silence_to_ao(mpctx, playsize, 0,
written_pts - samples / real_samplerate);
return ASYNC_PLAY_DONE;
}
mpctx->syncing_audio = false;
- mp_audio_buffer_prepend_silence(ao->buffer, samples);
- return audio_decode(d_audio, ao->buffer, playsize);
+ mp_audio_buffer_prepend_silence(mpctx->ao_buffer, samples);
+ return audio_decode(d_audio, mpctx->ao_buffer, playsize);
}
int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
@@ -378,8 +389,10 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
bool signal_eof = false;
bool partial_fill = false;
struct dec_audio *d_audio = mpctx->d_audio;
+ struct mp_audio out_format;
+ ao_get_format(ao, &out_format);
// Can't adjust the start of audio with spdif pass-through.
- bool modifiable_audio_format = !(ao->format & AF_FORMAT_SPECIAL_MASK);
+ bool modifiable_audio_format = !(out_format.format & AF_FORMAT_SPECIAL_MASK);
assert(d_audio);
@@ -400,7 +413,7 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
if (mpctx->syncing_audio || mpctx->hrseek_active)
res = audio_start_sync(mpctx, playsize);
else
- res = audio_decode(d_audio, ao->buffer, playsize);
+ res = audio_decode(d_audio, mpctx->ao_buffer, playsize);
if (res < 0) { // EOF, error or format change
if (res == -2) {
@@ -420,7 +433,7 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
if (endpts != MP_NOPTS_VALUE) {
double samples = (endpts - written_audio_pts(mpctx) - mpctx->audio_delay)
- * ao->samplerate / opts->playback_speed;
+ * out_format.rate / opts->playback_speed;
if (playsize > samples) {
playsize = MPMAX(samples, 0);
audio_eof = true;
@@ -428,8 +441,8 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
}
}
- if (playsize > mp_audio_buffer_samples(ao->buffer)) {
- playsize = mp_audio_buffer_samples(ao->buffer);
+ if (playsize > mp_audio_buffer_samples(mpctx->ao_buffer)) {
+ playsize = mp_audio_buffer_samples(mpctx->ao_buffer);
partial_fill = true;
}
if (!playsize)
@@ -445,17 +458,18 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
}
}
- assert(ao->buffer_playable_samples <= mp_audio_buffer_samples(ao->buffer));
+ assert(mpctx->ao_buffer_playable_samples <=
+ mp_audio_buffer_samples(mpctx->ao_buffer));
struct mp_audio data;
- mp_audio_buffer_peek(ao->buffer, &data);
+ mp_audio_buffer_peek(mpctx->ao_buffer, &data);
data.samples = MPMIN(data.samples, playsize);
int played = write_to_ao(mpctx, &data, playflags, written_audio_pts(mpctx));
assert(played >= 0 && played <= data.samples);
- ao->buffer_playable_samples = playsize - played;
+ mpctx->ao_buffer_playable_samples = playsize - played;
if (played > 0) {
- mp_audio_buffer_skip(ao->buffer, played);
+ mp_audio_buffer_skip(mpctx->ao_buffer, played);
} else if (!mpctx->paused && audio_eof && ao_get_delay(ao) < .04) {
// Sanity check to avoid hanging in case current ao doesn't output
// partial chunks and doesn't check for AOPLAY_FINAL_CHUNK
@@ -470,8 +484,8 @@ void clear_audio_output_buffers(struct MPContext *mpctx)
{
if (mpctx->ao) {
ao_reset(mpctx->ao);
- mp_audio_buffer_clear(mpctx->ao->buffer);
- mpctx->ao->buffer_playable_samples = 0;
+ mp_audio_buffer_clear(mpctx->ao_buffer);
+ mpctx->ao_buffer_playable_samples = 0;
}
}
diff --git a/player/core.h b/player/core.h
index fd9be5bcd4..5e60568c97 100644
--- a/player/core.h
+++ b/player/core.h
@@ -223,6 +223,11 @@ typedef struct MPContext