mirror of
https://github.com/mpv-player/mpv
synced 2025-03-20 18:28:01 +00:00
audio/out: make ao_request_reload() idempotent
This is what you would expect. Before this commit, each ao_request_reload() call would just queue a reload command, and then recreate the AO for the number of times the function was called. Instead of sending a command, introduce some sort of event retrieval mechanism. At least for the reload case, use atomics, because we're too lazy to setup an extra mutex.
This commit is contained in:
parent
7ee4e53369
commit
b021d038c2
@ -397,6 +397,22 @@ bool ao_eof_reached(struct ao *ao)
|
|||||||
return ao->api->get_eof ? ao->api->get_eof(ao) : true;
|
return ao->api->get_eof ? ao->api->get_eof(ao) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Query the AO_EVENT_*s as requested by the events parameter, and return them.
|
||||||
|
int ao_query_and_reset_events(struct ao *ao, int events)
|
||||||
|
{
|
||||||
|
int actual_events = 0;
|
||||||
|
if (atomic_load(&ao->request_reload)) // don't need to reset it
|
||||||
|
actual_events |= AO_EVENT_RELOAD;
|
||||||
|
return actual_events & events;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request that the player core destroys and recreates the AO.
|
||||||
|
void ao_request_reload(struct ao *ao)
|
||||||
|
{
|
||||||
|
atomic_store(&ao->request_reload, true);
|
||||||
|
mp_input_wakeup(ao->input_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
|
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
|
||||||
struct mp_chmap *map)
|
struct mp_chmap *map)
|
||||||
{
|
{
|
||||||
@ -409,13 +425,6 @@ bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
|
|||||||
return mp_chmap_sel_get_def(s, map, num);
|
return mp_chmap_sel_get_def(s, map, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request that the player core destroys and recreates the AO.
|
|
||||||
void ao_request_reload(struct ao *ao)
|
|
||||||
{
|
|
||||||
const char *cmd[] = {"ao_reload", NULL};
|
|
||||||
mp_input_run_cmd(ao->input_ctx, cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- The following functions just return immutable information.
|
// --- The following functions just return immutable information.
|
||||||
|
|
||||||
void ao_get_format(struct ao *ao, struct mp_audio *format)
|
void ao_get_format(struct ao *ao, struct mp_audio *format)
|
||||||
|
@ -46,6 +46,10 @@ enum aocontrol {
|
|||||||
// data might be written again, instead of closing the AO.
|
// data might be written again, instead of closing the AO.
|
||||||
#define AOPLAY_FINAL_CHUNK 1
|
#define AOPLAY_FINAL_CHUNK 1
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AO_EVENT_RELOAD = 1,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct ao_control_vol {
|
typedef struct ao_control_vol {
|
||||||
float left;
|
float left;
|
||||||
float right;
|
float right;
|
||||||
@ -85,6 +89,8 @@ void ao_pause(struct ao *ao);
|
|||||||
void ao_resume(struct ao *ao);
|
void ao_resume(struct ao *ao);
|
||||||
void ao_drain(struct ao *ao);
|
void ao_drain(struct ao *ao);
|
||||||
bool ao_eof_reached(struct ao *ao);
|
bool ao_eof_reached(struct ao *ao);
|
||||||
|
int ao_query_and_reset_events(struct ao *ao, int events);
|
||||||
|
void ao_request_reload(struct ao *ao);
|
||||||
|
|
||||||
struct ao_device_list *ao_get_device_list(struct mpv_global *global);
|
struct ao_device_list *ao_get_device_list(struct mpv_global *global);
|
||||||
void ao_print_devices(struct mpv_global *global, struct mp_log *log);
|
void ao_print_devices(struct mpv_global *global, struct mp_log *log);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "osdep/atomics.h"
|
||||||
#include "audio/out/ao.h"
|
#include "audio/out/ao.h"
|
||||||
|
|
||||||
/* global data used by ao.c and ao drivers */
|
/* global data used by ao.c and ao drivers */
|
||||||
@ -55,6 +56,8 @@ struct ao {
|
|||||||
// Used during init: if init fails, redirect to this ao
|
// Used during init: if init fails, redirect to this ao
|
||||||
char *redirect;
|
char *redirect;
|
||||||
|
|
||||||
|
atomic_bool request_reload;
|
||||||
|
|
||||||
int buffer;
|
int buffer;
|
||||||
double def_buffer;
|
double def_buffer;
|
||||||
void *api_priv;
|
void *api_priv;
|
||||||
@ -186,8 +189,6 @@ bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
|
|||||||
bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
|
bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
|
||||||
struct mp_chmap *map, int num);
|
struct mp_chmap *map, int num);
|
||||||
|
|
||||||
void ao_request_reload(struct ao *ao);
|
|
||||||
|
|
||||||
// Add a deep copy of e to the list.
|
// Add a deep copy of e to the list.
|
||||||
// Call from ao_driver->list_devs callback only.
|
// Call from ao_driver->list_devs callback only.
|
||||||
void ao_device_list_add(struct ao_device_list *list, struct ao *ao,
|
void ao_device_list_add(struct ao_device_list *list, struct ao *ao,
|
||||||
|
@ -434,6 +434,11 @@ static void do_fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
|
|||||||
struct MPOpts *opts = mpctx->opts;
|
struct MPOpts *opts = mpctx->opts;
|
||||||
struct dec_audio *d_audio = mpctx->d_audio;
|
struct dec_audio *d_audio = mpctx->d_audio;
|
||||||
|
|
||||||
|
if (mpctx->ao && ao_query_and_reset_events(mpctx->ao, AO_EVENT_RELOAD)) {
|
||||||
|
ao_reset(mpctx->ao);
|
||||||
|
uninit_audio_out(mpctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (!d_audio)
|
if (!d_audio)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1462,12 +1462,7 @@ static void reload_audio_output(struct MPContext *mpctx)
|
|||||||
{
|
{
|
||||||
if (!mpctx->ao)
|
if (!mpctx->ao)
|
||||||
return;
|
return;
|
||||||
ao_reset(mpctx->ao);
|
ao_request_reload(mpctx->ao);
|
||||||
uninit_audio_out(mpctx);
|
|
||||||
// This normally recreates the AO, although there are situations when AO
|
|
||||||
// creation is delayed; for example if there are no audio packets around,
|
|
||||||
// and the audio format is yet unknown.
|
|
||||||
reinit_audio_chain(mpctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mp_property_audio_device(void *ctx, struct m_property *prop,
|
static int mp_property_audio_device(void *ctx, struct m_property *prop,
|
||||||
|
Loading…
Reference in New Issue
Block a user