summaryrefslogtreecommitdiffstats
path: root/audio
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 /audio
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.
Diffstat (limited to 'audio')
-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
21 files changed, 147 insertions, 66 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