From 2a7c5a1365ad194a42e3f667f85828a152544857 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sat, 9 Apr 2011 03:03:22 +0300 Subject: [PATCH] audio: change external AO interface to "ao_[method](ao, ...)" Make the outside interface of audio output handling similar to the video output one. An AO object is first created, and then methods called with ao_[methodname](ao, args...). However internally libao2/ still holds all data in globals, and trying to create multiple simultaneous AO instances won't work. --- access_mpcontext.h | 1 - command.c | 2 +- libao2/audio_out.c | 148 ++++++++++++++++++++++++++++++++------------ libao2/audio_out.h | 23 +++++-- libao2/audio_out_internal.h | 2 + mixer.c | 8 +-- mixer.h | 2 +- mp_core.h | 3 +- mplayer.c | 128 +++++++++++++++++++------------------- 9 files changed, 197 insertions(+), 120 deletions(-) diff --git a/access_mpcontext.h b/access_mpcontext.h index 23bfcfb0ce..c6c8bfeaa3 100644 --- a/access_mpcontext.h +++ b/access_mpcontext.h @@ -21,7 +21,6 @@ struct MPContext; const void *mpctx_get_video_out(struct MPContext *mpctx); -const void *mpctx_get_audio_out(struct MPContext *mpctx); void *mpctx_get_demuxer(struct MPContext *mpctx); void *mpctx_get_playtree_iter(struct MPContext *mpctx); void *mpctx_get_mixer(struct MPContext *mpctx); diff --git a/command.c b/command.c index 48f6108a2c..8aeff84e63 100644 --- a/command.c +++ b/command.c @@ -459,7 +459,7 @@ static int mp_property_percent_pos(m_option_t *prop, int action, /// Current position in seconds (RW) static int mp_property_time_pos(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!(mpctx->sh_video || (mpctx->sh_audio && mpctx->audio_out))) + if (!(mpctx->sh_video || mpctx->sh_audio)) return M_PROPERTY_UNAVAILABLE; switch(action) { diff --git a/libao2/audio_out.c b/libao2/audio_out.c index 64b39811dc..d1887c223c 100644 --- a/libao2/audio_out.c +++ b/libao2/audio_out.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "config.h" #include "audio_out.h" @@ -26,7 +27,7 @@ #include "mp_msg.h" // there are some globals: -ao_data_t ao_data={0,0,0,0,OUTBURST,-1,0}; +struct ao ao_data; char *ao_subdevice = NULL; extern const ao_functions_t audio_out_oss; @@ -132,54 +133,119 @@ void list_audio_out(void){ mp_msg(MSGT_GLOBAL, MSGL_INFO,"\n"); } -const ao_functions_t* init_best_audio_out(char** ao_list,int use_plugin,int rate,int channels,int format,int flags){ - int i; +struct ao *ao_create(void) +{ + ao_data = (struct ao){.outburst = OUTBURST, .buffersize = -1}; + return &ao_data; +} + +void ao_init(struct ao *ao, char **ao_list) +{ + struct ao backup = *ao; + + if (!ao_list) + goto try_defaults; + // first try the preferred drivers, with their optional subdevice param: - if(ao_list && ao_list[0]) - while(ao_list[0][0]){ - char* ao=ao_list[0]; + while (*ao_list) { + char *ao_name = *ao_list; + if (!*ao_name) + goto try_defaults; // empty entry means try defaults int ao_len; - free(ao_subdevice); - ao_subdevice = NULL; - ao_subdevice=strchr(ao,':'); - if(ao_subdevice){ - ao_len = ao_subdevice - ao; - ao_subdevice = strdup(&ao[ao_len + 1]); - } - else - ao_len = strlen(ao); - - mp_tmsg(MSGT_AO, MSGL_V, "Trying preferred audio driver '%.*s', options '%s'\n", - ao_len, ao, ao_subdevice ? ao_subdevice : "[none]"); - - for(i=0;audio_out_drivers[i];i++){ - const ao_functions_t* audio_out=audio_out_drivers[i]; - if(!strncmp(audio_out->info->short_name,ao,ao_len)){ - // name matches, try it - if(audio_out->init(rate,channels,format,flags)) - return audio_out; // success! - else - mp_tmsg(MSGT_AO, MSGL_WARN, "Failed to initialize audio driver '%s'\n", ao); + assert(!ao_subdevice); + ao_subdevice = strchr(ao_name, ':'); + if (ao_subdevice) { + ao_len = ao_subdevice - ao_name; + ao_subdevice = strdup(ao_subdevice + 1); + } else + ao_len = strlen(ao_name); + + mp_tmsg(MSGT_AO, MSGL_V, + "Trying preferred audio driver '%.*s', options '%s'\n", + ao_len, ao_name, ao_subdevice ? ao_subdevice : "[none]"); + + const ao_functions_t *audio_out = NULL; + for (int i = 0; audio_out_drivers[i]; i++) { + audio_out = audio_out_drivers[i]; + if (!strncmp(audio_out->info->short_name, ao_name, ao_len)) break; - } + audio_out = NULL; } - if (!audio_out_drivers[i]) // we searched through the entire list - mp_tmsg(MSGT_AO, MSGL_WARN, "No such audio driver '%.*s'\n", ao_len, ao); - // continue... + if (audio_out) { + // name matches, try it + if (audio_out->init(ao->samplerate, ao->channels, ao->format, 0)) { + ao->driver = audio_out; + ao->initialized = true; + return; + } + mp_tmsg(MSGT_AO, MSGL_WARN, + "Failed to initialize audio driver '%s'\n", ao_name); + *ao = backup; + } else + mp_tmsg(MSGT_AO, MSGL_WARN, "No such audio driver '%.*s'\n", + ao_len, ao_name); + free(ao_subdevice); + ao_subdevice = NULL; ++ao_list; - if(!(ao_list[0])) return NULL; // do NOT fallback to others - } - free(ao_subdevice); - ao_subdevice = NULL; + } + return; + try_defaults: mp_tmsg(MSGT_AO, MSGL_V, "Trying every known audio driver...\n"); // now try the rest... - for(i=0;audio_out_drivers[i];i++){ - const ao_functions_t* audio_out=audio_out_drivers[i]; -// if(audio_out->control(AOCONTROL_QUERY_FORMAT, (int)format) == CONTROL_TRUE) - if(audio_out->init(rate,channels,format,flags)) - return audio_out; // success! + for (int i = 0; audio_out_drivers[i]; i++) { + const ao_functions_t *audio_out = audio_out_drivers[i]; + if (audio_out->init(ao->samplerate, ao->channels, ao->format, 0)) { + ao->initialized = true; + ao->driver = audio_out; + return; + } + *ao = backup; } - return NULL; + return; +} + +void ao_uninit(struct ao *ao, bool drain_audio) +{ + if (ao->initialized) + ao->driver->uninit(drain_audio); + ao->initialized = false; + free(ao_subdevice); + ao_subdevice = NULL; +} + +int ao_play(struct ao *ao, void *data, int len, int flags) +{ + return ao->driver->play(data, len, flags); +} + +int ao_control(struct ao *ao, int cmd, void *arg) +{ + return ao->driver->control(cmd, arg); +} + +double ao_get_delay(struct ao *ao) +{ + return ao->driver->get_delay(); +} + +int ao_get_space(struct ao *ao) +{ + return ao->driver->get_space(); +} + +void ao_reset(struct ao *ao) +{ + ao->driver->reset(); +} + +void ao_pause(struct ao *ao) +{ + ao->driver->pause(); +} + +void ao_resume(struct ao *ao) +{ + ao->driver->resume(); } diff --git a/libao2/audio_out.h b/libao2/audio_out.h index e483a88422..8c10a47784 100644 --- a/libao2/audio_out.h +++ b/libao2/audio_out.h @@ -19,6 +19,8 @@ #ifndef MPLAYER_AUDIO_OUT_H #define MPLAYER_AUDIO_OUT_H +#include + typedef struct ao_info_s { /* driver name ("Matrox Millennium G200/G400" */ @@ -32,7 +34,7 @@ typedef struct ao_info_s } ao_info_t; /* interface towards mplayer and */ -typedef struct ao_functions_s +typedef struct ao_functions { const ao_info_t *info; int (*control)(int cmd,void *arg); @@ -47,7 +49,7 @@ typedef struct ao_functions_s } ao_functions_t; /* global data used by mplayer and plugins */ -typedef struct ao_data { +struct ao { int samplerate; int channels; int format; @@ -55,13 +57,13 @@ typedef struct ao_data { int outburst; int buffersize; int pts; -} ao_data_t; + bool initialized; + const struct ao_functions *driver; +}; extern char *ao_subdevice; -extern ao_data_t ao_data; void list_audio_out(void); -const ao_functions_t* init_best_audio_out(char** ao_list,int use_plugin,int rate,int channels,int format,int flags); // NULL terminated array of all drivers extern const ao_functions_t* const audio_out_drivers[]; @@ -88,4 +90,15 @@ typedef struct ao_control_vol_s { float right; } ao_control_vol_t; +struct ao *ao_create(void); +void ao_init(struct ao *ao, char **ao_list); +void ao_uninit(struct ao *ao, bool drain_audio); +int ao_play(struct ao *ao, void *data, int len, int flags); +int ao_control(struct ao *ao, int cmd, void *arg); +double ao_get_delay(struct ao *ao); +int ao_get_space(struct ao *ao); +void ao_reset(struct ao *ao); +void ao_pause(struct ao *ao); +void ao_resume(struct ao *ao); + #endif /* MPLAYER_AUDIO_OUT_H */ diff --git a/libao2/audio_out_internal.h b/libao2/audio_out_internal.h index 504923b162..c093be6989 100644 --- a/libao2/audio_out_internal.h +++ b/libao2/audio_out_internal.h @@ -31,6 +31,8 @@ static float get_delay(void); static void audio_pause(void); static void audio_resume(void); +extern struct ao ao_data; + #define LIBAO_EXTERN(x) const ao_functions_t audio_out_##x =\ {\ &info,\ diff --git a/mixer.c b/mixer.c index 4b9d8db1b7..d4e794d5f5 100644 --- a/mixer.c +++ b/mixer.c @@ -39,9 +39,9 @@ void mixer_getvolume(mixer_t *mixer, float *l, float *r) { ao_control_vol_t vol; *l=0; *r=0; - if(mixer->audio_out){ + if (mixer->ao) { if(soft_vol || - CONTROL_OK != mixer->audio_out->control(AOCONTROL_GET_VOLUME,&vol)) { + CONTROL_OK != ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol)) { if (!mixer->afilter) return; else { @@ -64,9 +64,9 @@ void mixer_setvolume(mixer_t *mixer, float l, float r) { ao_control_vol_t vol; vol.right=r; vol.left=l; - if(mixer->audio_out){ + if (mixer->ao) { if(soft_vol || - CONTROL_OK != mixer->audio_out->control(AOCONTROL_SET_VOLUME,&vol)) { + CONTROL_OK != ao_control(mixer->ao, AOCONTROL_SET_VOLUME, &vol)) { if (!mixer->afilter) return; else { diff --git a/mixer.h b/mixer.h index 5a2d0e5027..a524c02b26 100644 --- a/mixer.h +++ b/mixer.h @@ -28,7 +28,7 @@ extern int soft_vol; extern float soft_vol_max; typedef struct mixer_s { - const ao_functions_t *audio_out; + struct ao *ao; af_stream_t *afilter; int volstep; int muted; diff --git a/mp_core.h b/mp_core.h index bbb93bce48..733962fe0c 100644 --- a/mp_core.h +++ b/mp_core.h @@ -99,7 +99,6 @@ typedef struct MPContext { unsigned int osd_visible; int osd_function; - const ao_functions_t *audio_out; struct play_tree *playtree; struct play_tree_iter *playtree_iter; char *filename; // currently playing file @@ -124,6 +123,7 @@ typedef struct MPContext { struct demux_stream *d_video; struct demux_stream *d_sub; mixer_t mixer; + struct ao *ao; struct vo *video_out; /* We're starting playback from scratch or after a seek. Show first @@ -228,7 +228,6 @@ extern int file_filter; // These appear in options list extern int forced_subs_only; -struct ao_data; void uninit_player(struct MPContext *mpctx, unsigned int mask); void reinit_audio_chain(struct MPContext *mpctx); void init_vo_spudec(struct MPContext *mpctx); diff --git a/mplayer.c b/mplayer.c index 803bb33bd1..9ffd4a0bec 100644 --- a/mplayer.c +++ b/mplayer.c @@ -368,11 +368,6 @@ const void *mpctx_get_video_out(MPContext *mpctx) return mpctx->video_out; } -const void *mpctx_get_audio_out(MPContext *mpctx) -{ - return mpctx->audio_out; -} - void *mpctx_get_demuxer(MPContext *mpctx) { return mpctx->demuxer; @@ -710,9 +705,9 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask){ mpctx->initialized_flags&=~INITIALIZED_AO; current_module="uninit_ao"; if (mpctx->edl_muted) mixer_mute(&mpctx->mixer); - if (mpctx->audio_out) - mpctx->audio_out->uninit(mpctx->stop_play != AT_END_OF_FILE); - mpctx->audio_out=NULL; + if (mpctx->ao) + ao_uninit(mpctx->ao, mpctx->stop_play != AT_END_OF_FILE); + mpctx->ao = NULL; } current_module=NULL; @@ -1344,12 +1339,13 @@ static void print_status(struct MPContext *mpctx, double a_pos, bool at_frame) /** * \brief build a chain of audio filters that converts the input format * to the ao's format, taking into account the current playback_speed. - * \param sh_audio describes the requested input format of the chain. - * \param ao_data describes the requested output format of the chain. + * sh_audio describes the requested input format of the chain. + * ao describes the requested output format of the chain. */ -static int build_afilter_chain(struct MPContext *mpctx, sh_audio_t *sh_audio, - ao_data_t *ao_data) +static int build_afilter_chain(struct MPContext *mpctx) { + struct sh_audio *sh_audio = mpctx->sh_audio; + struct ao *ao = mpctx->ao; struct MPOpts *opts = &mpctx->opts; int new_srate; int result; @@ -1364,7 +1360,7 @@ static int build_afilter_chain(struct MPContext *mpctx, sh_audio_t *sh_audio, new_srate = sh_audio->samplerate; } else { new_srate = sh_audio->samplerate * opts->playback_speed; - if (new_srate != ao_data->samplerate) { + if (new_srate != ao->samplerate) { // limits are taken from libaf/af_resample.c if (new_srate < 8000) new_srate = 8000; @@ -1374,7 +1370,7 @@ static int build_afilter_chain(struct MPContext *mpctx, sh_audio_t *sh_audio, } } result = init_audio_filters(sh_audio, new_srate, - &ao_data->samplerate, &ao_data->channels, &ao_data->format); + &ao->samplerate, &ao->channels, &ao->format); mpctx->mixer.afilter = sh_audio->afilter; return result; } @@ -1681,6 +1677,7 @@ static void update_osd_msg(struct MPContext *mpctx) void reinit_audio_chain(struct MPContext *mpctx) { struct MPOpts *opts = &mpctx->opts; + struct ao *ao; if (!mpctx->sh_audio) return; if (!(mpctx->initialized_flags & INITIALIZED_ACODEC)) { @@ -1696,51 +1693,50 @@ void reinit_audio_chain(struct MPContext *mpctx) current_module="af_preinit"; if (!(mpctx->initialized_flags & INITIALIZED_AO)) { - ao_data.samplerate=force_srate; - ao_data.channels=0; - ao_data.format = opts->audio_output_format; + mpctx->initialized_flags |= INITIALIZED_AO; + mpctx->ao = ao_create(); + mpctx->ao->samplerate = force_srate; + mpctx->ao->format = opts->audio_output_format; } + ao = mpctx->ao; + // first init to detect best values if(!init_audio_filters(mpctx->sh_audio, // preliminary init // input: mpctx->sh_audio->samplerate, // output: - &ao_data.samplerate, &ao_data.channels, &ao_data.format)){ + &ao->samplerate, &ao->channels, &ao->format)) { mp_tmsg(MSGT_CPLAYER,MSGL_ERR, "Error at audio filter chain " "pre-init!\n"); exit_player(mpctx, EXIT_ERROR); } - if (!(mpctx->initialized_flags & INITIALIZED_AO)) { + if (!ao->initialized) { current_module="ao2_init"; - ao_data.buffersize = opts->ao_buffersize; - mpctx->audio_out = init_best_audio_out(opts->audio_driver_list, - 0, // plugin flag - ao_data.samplerate, - ao_data.channels, - ao_data.format, 0); - if(!mpctx->audio_out){ + ao->buffersize = opts->ao_buffersize; + ao_init(ao, opts->audio_driver_list); + if (!ao->initialized) { mp_tmsg(MSGT_CPLAYER,MSGL_ERR,"Could not open/initialize audio device -> no sound.\n"); goto init_error; } - mpctx->initialized_flags|=INITIALIZED_AO; mp_msg(MSGT_CPLAYER,MSGL_INFO,"AO: [%s] %dHz %dch %s (%d bytes per sample)\n", - mpctx->audio_out->info->short_name, - ao_data.samplerate, ao_data.channels, - af_fmt2str_short(ao_data.format), - af_fmt2bits(ao_data.format)/8 ); + ao->driver->info->short_name, + ao->samplerate, ao->channels, + af_fmt2str_short(ao->format), + af_fmt2bits(ao->format)/8 ); mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Description: %s\nAO: Author: %s\n", - mpctx->audio_out->info->name, mpctx->audio_out->info->author); - if(strlen(mpctx->audio_out->info->comment) > 0) - mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Comment: %s\n", mpctx->audio_out->info->comment); + ao->driver->info->name, ao->driver->info->author); + if (strlen(ao->driver->info->comment) > 0) + mp_msg(MSGT_CPLAYER, MSGL_V, "AO: Comment: %s\n", + ao->driver->info->comment); } // init audio filters: current_module="af_init"; - if(!build_afilter_chain(mpctx, mpctx->sh_audio, &ao_data)) { + if (!build_afilter_chain(mpctx)) { mp_tmsg(MSGT_CPLAYER,MSGL_ERR,"Couldn't find matching filter/ao format!\n"); goto init_error; } - mpctx->mixer.audio_out = mpctx->audio_out; + mpctx->mixer.ao = ao; mpctx->mixer.volstep = volstep; mpctx->syncing_audio = true; return; @@ -1804,7 +1800,7 @@ static double written_audio_pts(struct MPContext *mpctx) // Filters divide audio length by playback_speed, so multiply by it // to get the length in original units without speedup or slowdown - a_pts -= buffered_output * mpctx->opts.playback_speed / ao_data.bps; + a_pts -= buffered_output * mpctx->opts.playback_speed / mpctx->ao->bps; return a_pts + mpctx->video_offset; } @@ -1813,7 +1809,7 @@ static double written_audio_pts(struct MPContext *mpctx) double playing_audio_pts(struct MPContext *mpctx) { return written_audio_pts(mpctx) - mpctx->opts.playback_speed * - mpctx->audio_out->get_delay(); + ao_get_delay(mpctx->ao); } static bool is_av_sub(int type) @@ -2028,7 +2024,7 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time) { current_module = "check_framedrop"; if (mpctx->sh_audio && !mpctx->d_audio->eof) { static int dropped_frames; - float delay = opts->playback_speed*mpctx->audio_out->get_delay(); + float delay = opts->playback_speed * ao_get_delay(mpctx->ao); float d = delay-mpctx->delay; ++total_frame_cnt; // we should avoid dropping too many frames in sequence unless we @@ -2175,7 +2171,7 @@ static void mp_dvdnav_reset_stream (MPContext *ctx) { ds_free_packs(ctx->d_audio); audio_delay -= ctx->sh_audio->stream_delay; ctx->delay =- audio_delay; - ctx->audio_out->reset(); + ao_reset(ctx->ao); resync_audio_stream(ctx->sh_audio); } @@ -2296,6 +2292,7 @@ static void adjust_sync(struct MPContext *mpctx, double frame_time) #define ASYNC_PLAY_DONE -3 static int audio_start_sync(struct MPContext *mpctx, int playsize) { + struct ao *ao = mpctx->ao; struct MPOpts *opts = &mpctx->opts; sh_audio_t * const sh_audio = mpctx->sh_audio; int res; @@ -2311,14 +2308,14 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize) double written_pts = written_audio_pts(mpctx); double ptsdiff = written_pts - mpctx->video_pts - mpctx->delay - audio_delay; - bytes = ptsdiff * ao_data.bps / mpctx->opts.playback_speed; - bytes -= bytes % (ao_data.channels * af_fmt2bits(ao_data.format) / 8); + bytes = ptsdiff * ao->bps / mpctx->opts.playback_speed; + bytes -= bytes % (ao->channels * af_fmt2bits(ao->format) / 8); // ogg demuxers give packets without timing if (written_pts <= 1 && sh_audio->pts == MP_NOPTS_VALUE) { if (!did_retry) { // Try to read more data to see packets that have pts - int res = decode_audio(sh_audio, ao_data.bps); + int res = decode_audio(sh_audio, ao->bps); if (res < 0) return res; did_retry = true; @@ -2352,7 +2349,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize) return res; } int fillbyte = 0; - if ((ao_data.format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) + if ((ao->format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) fillbyte = 0x80; if (bytes >= playsize) { /* This case could fall back to the one below with @@ -2361,9 +2358,9 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize) * in playsize. */ char *p = malloc(playsize); memset(p, fillbyte, playsize); - playsize = mpctx->audio_out->play(p, playsize, 0); + playsize = ao_play(ao, p, playsize, 0); free(p); - mpctx->delay += opts->playback_speed*playsize/(double)ao_data.bps; + mpctx->delay += opts->playback_speed*playsize/(double)ao->bps; return ASYNC_PLAY_DONE; } mpctx->syncing_audio = false; @@ -2374,6 +2371,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize) static int fill_audio_out_buffers(struct MPContext *mpctx) { struct MPOpts *opts = &mpctx->opts; + struct ao *ao = mpctx->ao; unsigned int t; double tt; int playsize; @@ -2382,16 +2380,16 @@ static int fill_audio_out_buffers(struct MPContext *mpctx) bool partial_fill = false; bool format_change = false; sh_audio_t * const sh_audio = mpctx->sh_audio; - bool modifiable_audio_format = !(ao_data.format & AF_FORMAT_SPECIAL_MASK); - int unitsize = ao_data.channels * af_fmt2bits(ao_data.format) / 8; + bool modifiable_audio_format = !(ao->format & AF_FORMAT_SPECIAL_MASK); + int unitsize = ao->channels * af_fmt2bits(ao->format) / 8; current_module="play_audio"; - // all the current uses of ao_data.pts seem to be in aos that handle - // sync completely wrong; there should be no need to use ao_data.pts + // all the current uses of ao->pts seem to be in aos that handle + // sync completely wrong; there should be no need to use ao->pts // in get_space() - ao_data.pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0; - playsize = mpctx->audio_out->get_space(); + ao->pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0; + playsize = ao_get_space(ao); // Fill buffer if needed: current_module="decode_audio"; @@ -2418,7 +2416,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx) if (mpctx->timeline && modifiable_audio_format) { double endpts = mpctx->timeline[mpctx->timeline_part + 1].start; double bytes = (endpts - written_audio_pts(mpctx) + audio_delay) - * ao_data.bps / opts->playback_speed; + * ao->bps / opts->playback_speed; if (playsize > bytes) { playsize = FFMAX(bytes, 0); playflags |= AOPLAY_FINAL_CHUNK; @@ -2443,15 +2441,15 @@ static int fill_audio_out_buffers(struct MPContext *mpctx) // Is this pts value actually useful for the aos that access it? // They're obviously badly broken in the way they handle av sync; // would not having access to this make them more broken? - ao_data.pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0; - playsize = mpctx->audio_out->play(sh_audio->a_out_buffer, playsize, playflags); + ao->pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0; + playsize = ao_play(ao, sh_audio->a_out_buffer, playsize, playflags); if (playsize > 0) { sh_audio->a_out_buffer_len -= playsize; memmove(sh_audio->a_out_buffer, &sh_audio->a_out_buffer[playsize], sh_audio->a_out_buffer_len); - mpctx->delay += opts->playback_speed*playsize/(double)ao_data.bps; - } else if (audio_eof && mpctx->audio_out->get_delay() < .04) { + mpctx->delay += opts->playback_speed*playsize/(double)ao->bps; + } else if (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 mp_msg(MSGT_CPLAYER, MSGL_WARN, "Audio output truncated at end.\n"); @@ -2484,7 +2482,7 @@ static int sleep_until_near_frame(struct MPContext *mpctx, float *time_frame, *time_frame -= get_relative_time(mpctx); // reset timer if (sync_to_audio) { - float delay = mpctx->audio_out->get_delay(); + float delay = ao_get_delay(mpctx->ao); mp_dbg(MSGT_AVSYNC, MSGL_DBG2, "delay=%f\n", delay); if (opts->autosync) { @@ -2843,8 +2841,8 @@ void pause_player(struct MPContext *mpctx) if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok) vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL); - if (mpctx->audio_out && mpctx->sh_audio) - mpctx->audio_out->pause(); // pause audio, keep data if possible + if (mpctx->ao && mpctx->sh_audio) + ao_pause(mpctx->ao); // pause audio, keep data if possible } void unpause_player(struct MPContext *mpctx) @@ -2853,8 +2851,8 @@ void unpause_player(struct MPContext *mpctx) return; mpctx->paused = 0; - if (mpctx->audio_out && mpctx->sh_audio) - mpctx->audio_out->resume(); // resume audio + if (mpctx->ao && mpctx->sh_audio) + ao_resume(mpctx->ao); if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok && !mpctx->step_frames) vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video @@ -3015,7 +3013,7 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao) resync_audio_stream(mpctx->sh_audio); if (reset_ao) // stop audio, throwing away buffered data - mpctx->audio_out->reset(); + ao_reset(mpctx->ao); mpctx->sh_audio->a_buffer_len = 0; mpctx->sh_audio->a_out_buffer_len = 0; if (!mpctx->sh_video) @@ -3120,7 +3118,7 @@ static int seek(MPContext *mpctx, struct seek_params seek, mpctx->stop_play = AT_END_OF_FILE; // Clear audio from current position if (mpctx->sh_audio) { - mpctx->audio_out->reset(); + ao_reset(mpctx->ao); mpctx->sh_audio->a_buffer_len = 0; mpctx->sh_audio->a_out_buffer_len = 0; } @@ -3373,7 +3371,7 @@ static void run_playloop(struct MPContext *mpctx) && mpctx->timeline_part + 1 < mpctx->num_timeline_parts && mpctx->sh_audio) { struct timeline_part *p = mpctx->timeline + mpctx->timeline_part; - double delay = mpctx->audio_out->get_delay(); + double delay = ao_get_delay(mpctx->ao); if (!opts->gapless_audio && p->source != (p+1)->source && delay > 0.05) { mpctx->stop_play = KEEP_PLAYING; -- 2.11.4.GIT