summaryrefslogtreecommitdiffstats
path: root/player/command.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-02-12 16:53:56 +0100
committerwm4 <wm4@nowhere>2015-02-12 17:17:41 +0100
commitf061befb3338c5cd6837701b4232dad48340ab6c (patch)
tree13d8526248cc5bf68fb5d563fbf4cdd6e5dcc2aa /player/command.c
parentc152c590843a192761cff585a84ce57385d83d40 (diff)
downloadmpv-f061befb3338c5cd6837701b4232dad48340ab6c.tar.bz2
mpv-f061befb3338c5cd6837701b4232dad48340ab6c.tar.xz
audio: add device change notification for hotplugging
Not very important for the command line player; but GUI applications will want to know about this. This only adds the internal API; support for specific audio outputs comes later. This reuses the ao struct as context for the hotplug event listener, similar to how the "old" device listing API did. This is probably a bit unclean and confusing. One argument got reusing it is that otherwise rewriting parts of ao_pulse would be required (because the PulseAudio API requires so damn much boilerplate). Another is that --ao-defaults is applied to the hotplug dummy ao struct, which automatically applies such defaults even to the hotplug context. Notification works through the property observation mechanism in the client API. The notification chain is a bit complicated: the AO notifies the player, which in turn notifies the clients, which in turn will actually retrieve the device list. (It still has the advantage that it's slightly cleaner, since the AO stuff doesn't need to know about client API issues.) The weird handling of atomic flags in ao.c is because we still don't require real atomics from the compiler. Otherwise we'd just use atomic bitwise operations.
Diffstat (limited to 'player/command.c')
-rw-r--r--player/command.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/player/command.c b/player/command.c
index f20e6050b4..07a9206b53 100644
--- a/player/command.c
+++ b/player/command.c
@@ -90,7 +90,7 @@ struct command_ctx {
int num_hooks;
int64_t hook_seq; // for hook_handler.seq
- struct ao_device_list *cached_ao_devices;
+ struct ao_hotplug *hotplug;
};
struct overlay {
@@ -1560,14 +1560,12 @@ static int mp_property_audio_devices(void *ctx, struct m_property *prop,
{
struct MPContext *mpctx = ctx;
struct command_ctx *cmd = mpctx->command_ctx;
- if (!cmd->cached_ao_devices)
- cmd->cached_ao_devices = ao_get_device_list(mpctx->global);
- if (!cmd->cached_ao_devices)
- return M_PROPERTY_ERROR;
- talloc_steal(cmd, cmd->cached_ao_devices);
+ if (!cmd->hotplug)
+ cmd->hotplug = ao_hotplug_create(mpctx->global, mpctx->input);
- return m_property_read_list(action, arg, cmd->cached_ao_devices->num_devices,
- get_device_entry, cmd->cached_ao_devices);
+ struct ao_device_list *list = ao_hotplug_get_device_list(cmd->hotplug);
+ return m_property_read_list(action, arg, list->num_devices,
+ get_device_entry, list);
}
static int mp_property_ao(void *ctx, struct m_property *p, int action, void *arg)
@@ -3535,6 +3533,7 @@ static const char *const *const mp_event_property_change[] = {
"demuxer-cache-duration", "demuxer-cache-idle", "paused-for-cache"),
E(MP_EVENT_WIN_RESIZE, "window-scale"),
E(MP_EVENT_WIN_STATE, "window-minimized", "display-names"),
+ E(MP_EVENT_AUDIO_DEVICES, "audio-device-list"),
};
#undef E
@@ -4819,6 +4818,7 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
void command_uninit(struct MPContext *mpctx)
{
overlay_uninit(mpctx);
+ ao_hotplug_destroy(mpctx->command_ctx->hotplug);
talloc_free(mpctx->command_ctx);
mpctx->command_ctx = NULL;
}
@@ -4868,6 +4868,11 @@ static void command_event(struct MPContext *mpctx, int event, void *arg)
// Update chapters - does nothing if something else is visible.
set_osd_bar_chapters(mpctx, OSD_BAR_SEEK);
}
+
+ // This is a bit messy: ao_hotplug wakes up the player, and then we have
+ // to recheck the state. Then the client(s) will read the property.
+ if (ctx->hotplug && ao_hotplug_check_update(ctx->hotplug))
+ mp_notify_property(mpctx, "audio-device-list");
}
void mp_notify(struct MPContext *mpctx, int event, void *arg)