diff options
Diffstat (limited to 'core/mplayer.c')
-rw-r--r-- | core/mplayer.c | 343 |
1 files changed, 197 insertions, 146 deletions
diff --git a/core/mplayer.c b/core/mplayer.c index 3e14abc499..d3872442ee 100644 --- a/core/mplayer.c +++ b/core/mplayer.c @@ -63,6 +63,7 @@ #include <errno.h> +#include "core/mpv_global.h" #include "core/mp_msg.h" #include "av_log.h" @@ -230,7 +231,7 @@ static double rel_time_to_abs(struct MPContext *mpctx, struct m_rel_time t, static double get_play_end_pts(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (opts->play_end.type) { return rel_time_to_abs(mpctx, opts->play_end, MP_NOPTS_VALUE); } else if (opts->play_length.type) { @@ -440,7 +441,7 @@ static void uninit_subs(struct demuxer *demuxer) void uninit_player(struct MPContext *mpctx, unsigned int mask) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; mask &= mpctx->initialized_flags; @@ -548,8 +549,9 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) } static MP_NORETURN void exit_player(struct MPContext *mpctx, - enum exit_reason how, int rc) + enum exit_reason how) { + int rc; uninit_player(mpctx, INITIALIZED_ALL); #ifdef CONFIG_ENCODING @@ -563,7 +565,7 @@ static MP_NORETURN void exit_player(struct MPContext *mpctx, timeEndPeriod(1); #endif - mp_input_uninit(mpctx->input, &mpctx->opts.input); + mp_input_uninit(mpctx->input); osd_free(mpctx->osd); @@ -575,20 +577,41 @@ static MP_NORETURN void exit_player(struct MPContext *mpctx, if (how != EXIT_NONE) { const char *reason; switch (how) { - case EXIT_QUIT: reason = "Quit"; break; - case EXIT_EOF: reason = "End of file"; break; - case EXIT_ERROR: reason = "Fatal error"; break; - default: abort(); + case EXIT_SOMENOTPLAYED: + case EXIT_PLAYED: + reason = "End of file"; + break; + case EXIT_NOTPLAYED: + reason = "No files played"; + break; + case EXIT_ERROR: + reason = "Fatal error"; + break; + default: + reason = "Quit"; } mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "\nExiting... (%s)\n", reason); } + if (mpctx->has_quit_custom_rc) { + rc = mpctx->quit_custom_rc; + } else { + switch (how) { + case EXIT_ERROR: + rc = 1; break; + case EXIT_NOTPLAYED: + rc = 2; break; + case EXIT_SOMENOTPLAYED: + rc = 3; break; + default: + rc = 0; + } + } + // must be last since e.g. mp_msg uses option values // that will be freed by this. - if (mpctx->mconfig) - m_config_free(mpctx->mconfig); - mpctx->mconfig = NULL; + mp_msg_uninit(mpctx->global); talloc_free(mpctx); #ifdef CONFIG_COCOA @@ -611,21 +634,21 @@ static void mk_config_dir(char *subdir) talloc_free(tmp); } -static int cfg_include(struct m_config *conf, char *filename) +static int cfg_include(struct m_config *conf, char *filename, int flags) { - return m_config_parse_config_file(conf, filename); + return m_config_parse_config_file(conf, filename, flags); } #define DEF_CONFIG "# Write your default config options here!\n\n\n" static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; char *conffile; int conffile_fd; if (!opts->load_config) return true; - if (!m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf") < 0) + if (!m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf", 0) < 0) return false; mk_config_dir(NULL); if ((conffile = mp_find_user_config_file("config")) == NULL) @@ -639,7 +662,7 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf) write(conffile_fd, DEF_CONFIG, sizeof(DEF_CONFIG) - 1); close(conffile_fd); } - if (m_config_parse_config_file(conf, conffile) < 0) + if (m_config_parse_config_file(conf, conffile, 0) < 0) return false; talloc_free(conffile); } @@ -661,11 +684,11 @@ static void load_per_protocol_config(m_config_t *conf, const char * const file) sprintf(protocol, "%s%s", PROFILE_CFG_PROTOCOL, file); protocol[strlen(PROFILE_CFG_PROTOCOL) + strlen(file) - strlen(str)] = '\0'; - p = m_config_get_profile(conf, protocol); + p = m_config_get_profile0(conf, protocol); if (p) { mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Loading protocol-related profile '%s'\n", protocol); - m_config_set_profile(conf, p); + m_config_set_profile(conf, p, M_SETOPT_BACKUP); } } @@ -684,11 +707,11 @@ static void load_per_extension_config(m_config_t *conf, const char * const file) sprintf(extension, PROFILE_CFG_EXTENSION); strncat(extension, ++str, 7); - p = m_config_get_profile(conf, extension); + p = m_config_get_profile0(conf, extension); if (p) { mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Loading extension-related profile '%s'\n", extension); - m_config_set_profile(conf, p); + m_config_set_profile(conf, p, M_SETOPT_BACKUP); } } @@ -704,16 +727,16 @@ static void load_per_output_config(m_config_t *conf, char *cfg, char *out) return; sprintf(profile, "%s%s", cfg, out); - p = m_config_get_profile(conf, profile); + p = m_config_get_profile0(conf, profile); if (p) { mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Loading extension-related profile '%s'\n", profile); - m_config_set_profile(conf, p); + m_config_set_profile(conf, p, M_SETOPT_BACKUP); } } /** - * Tries to load a config file + * Tries to load a config file (in file local mode) * @return 0 if file was not found, 1 otherwise */ static int try_load_config(m_config_t *conf, const char *file) @@ -721,7 +744,7 @@ static int try_load_config(m_config_t *conf, const char *file) if (!mp_path_exists(file)) return 0; mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Loading config '%s'\n", file); - m_config_parse_config_file(conf, file); + m_config_parse_config_file(conf, file, M_SETOPT_BACKUP); return 1; } @@ -876,8 +899,10 @@ static void load_per_file_options(m_config_t *conf, struct playlist_param *params, int params_count) { - for (int n = 0; n < params_count; n++) - m_config_set_option(conf, params[n].name, params[n].value); + for (int n = 0; n < params_count; n++) { + m_config_set_option_ext(conf, params[n].name, params[n].value, + M_SETOPT_BACKUP); + } } /* When demux performs a blocking operation (network connection or @@ -1036,7 +1061,7 @@ static void vo_update_window_title(struct MPContext *mpctx) { if (!mpctx->video_out) return; - char *title = mp_property_expand_string(mpctx, mpctx->opts.wintitle); + char *title = mp_property_expand_string(mpctx, mpctx->opts->wintitle); if (!mpctx->video_out->window_title || strcmp(title, mpctx->video_out->window_title)) { @@ -1077,7 +1102,7 @@ static int get_term_width(void) static void write_status_line(struct MPContext *mpctx, const char *line) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (opts->slave_mode) { mp_msg(MSGT_STATUSLINE, MSGL_STATUS, "%s\n", line); } else if (erase_to_end_of_line) { @@ -1092,7 +1117,7 @@ static void write_status_line(struct MPContext *mpctx, const char *line) static void print_status(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; sh_video_t * const sh_video = mpctx->sh_video; vo_update_window_title(mpctx); @@ -1124,12 +1149,12 @@ static void print_status(struct MPContext *mpctx) // Playback position double cur = get_current_time(mpctx); - sadd_hhmmssff(&line, cur, mpctx->opts.osd_fractions); + sadd_hhmmssff(&line, cur, mpctx->opts->osd_fractions); double len = get_time_length(mpctx); if (len >= 0) { saddf(&line, " / "); - sadd_hhmmssff(&line, len, mpctx->opts.osd_fractions); + sadd_hhmmssff(&line, len, mpctx->opts->osd_fractions); } sadd_percentage(&line, get_percent_pos(mpctx)); @@ -1265,7 +1290,7 @@ void rm_osd_msg(struct MPContext *mpctx, int id) static mp_osd_msg_t *get_osd_msg(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; mp_osd_msg_t *msg, *prev, *last = NULL; double now = mp_time_sec(); double diff; @@ -1324,7 +1349,7 @@ static mp_osd_msg_t *get_osd_msg(struct MPContext *mpctx) void set_osd_bar(struct MPContext *mpctx, int type, const char *name, double min, double max, double val) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (opts->osd_level < 1 || !opts->osd_bar_visible) return; @@ -1377,7 +1402,7 @@ static void set_osd_bar_chapters(struct MPContext *mpctx, int type) void set_osd_function(struct MPContext *mpctx, int osd_function) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; mpctx->osd_function = osd_function; mpctx->osd_function_visible = mp_time_sec() + opts->osd_duration / 1000.0; @@ -1412,10 +1437,10 @@ static void saddf_osd_function_sym(char **buffer, int sym) static void sadd_osd_status(char **buffer, struct MPContext *mpctx, bool full) { - bool fractions = mpctx->opts.osd_fractions; + bool fractions = mpctx->opts->osd_fractions; int sym = mpctx->osd_function; if (!sym) { - if (mpctx->paused_for_cache && !mpctx->opts.pause) { + if (mpctx->paused_for_cache && !mpctx->opts->pause) { sym = OSD_CLOCK; } else if (mpctx->paused || mpctx->step_frames) { sym = OSD_PAUSE; @@ -1424,7 +1449,7 @@ static void sadd_osd_status(char **buffer, struct MPContext *mpctx, bool full) } } saddf_osd_function_sym(buffer, sym); - char *custom_msg = mpctx->opts.osd_status_msg; + char *custom_msg = mpctx->opts->osd_status_msg; if (custom_msg && full) { char *text = mp_property_expand_string(mpctx, custom_msg); *buffer = talloc_strdup_append(*buffer, text); @@ -1453,19 +1478,19 @@ static void add_seek_osd_messages(struct MPContext *mpctx) } if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_TEXT) { mp_osd_msg_t *msg = add_osd_msg(mpctx, OSD_MSG_TEXT, 1, - mpctx->opts.osd_duration); + mpctx->opts->osd_duration); msg->show_position = true; } if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_CHAPTER_TEXT) { char *chapter = chapter_display_name(mpctx, get_current_chapter(mpctx)); - set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, mpctx->opts.osd_duration, + set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, mpctx->opts->osd_duration, "Chapter: %s", chapter); talloc_free(chapter); } if ((mpctx->add_osd_seek_info & OSD_SEEK_INFO_EDITION) && mpctx->master_demuxer) { - set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, mpctx->opts.osd_duration, + set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, mpctx->opts->osd_duration, "Playing edition %d of %d.", mpctx->master_demuxer->edition + 1, mpctx->master_demuxer->num_editions); @@ -1484,7 +1509,7 @@ static void add_seek_osd_messages(struct MPContext *mpctx) static void update_osd_msg(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; struct osd_state *osd = mpctx->osd; add_seek_osd_messages(mpctx); @@ -1537,7 +1562,7 @@ 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; + struct MPOpts *opts = mpctx->opts; int new_srate; if (af_control_any_rev(sh_audio->afilter, AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET, @@ -1551,7 +1576,7 @@ static int build_afilter_chain(struct MPContext *mpctx) new_srate = 8000; if (new_srate > 192000) new_srate = 192000; - opts->playback_speed = (float)new_srate / sh_audio->samplerate; + opts->playback_speed = (double)new_srate / sh_audio->samplerate; } } return init_audio_filters(sh_audio, new_srate, @@ -1560,7 +1585,7 @@ static int build_afilter_chain(struct MPContext *mpctx) static int recreate_audio_filters(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; assert(mpctx->sh_audio); // init audio filters: @@ -1605,7 +1630,7 @@ int reinit_audio_filters(struct MPContext *mpctx) void reinit_audio_chain(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; init_demux_stream(mpctx, STREAM_AUDIO); if (!mpctx->sh_audio) { uninit_player(mpctx, INITIALIZED_VOL | INITIALIZED_AO); @@ -1651,8 +1676,9 @@ void reinit_audio_chain(struct MPContext *mpctx) mpctx->initialized_flags |= INITIALIZED_AO; mp_chmap_remove_useless_channels(&ao_channels, &opts->audio_output_channels); - mpctx->ao = ao_init_best(opts, mpctx->input, mpctx->encode_lavc_ctx, - ao_srate, ao_format, ao_channels); + mpctx->ao = ao_init_best(mpctx->global, mpctx->input, + mpctx->encode_lavc_ctx, ao_srate, ao_format, + ao_channels); struct ao *ao = mpctx->ao; if (!ao) { mp_tmsg(MSGT_CPLAYER, MSGL_ERR, @@ -1722,7 +1748,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 / mpctx->ao->bps; + a_pts -= buffered_output * mpctx->opts->playback_speed / mpctx->ao->bps; return a_pts + mpctx->video_offset; } @@ -1733,7 +1759,7 @@ double playing_audio_pts(struct MPContext *mpctx) double pts = written_audio_pts(mpctx); if (pts == MP_NOPTS_VALUE) return pts; - return pts - mpctx->opts.playback_speed *ao_get_delay(mpctx->ao); + return pts - mpctx->opts->playback_speed * ao_get_delay(mpctx->ao); } // When reading subtitles from a demuxer, and we read video or audio from the @@ -1763,7 +1789,7 @@ static void reset_subtitles(struct MPContext *mpctx) static void update_subtitles(struct MPContext *mpctx, double refpts_tl) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (!(mpctx->initialized_flags & INITIALIZED_SUB)) return; @@ -1818,7 +1844,7 @@ static void update_subtitles(struct MPContext *mpctx, double refpts_tl) static int check_framedrop(struct MPContext *mpctx, double frame_time) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; // check for frame-drop: if (mpctx->sh_audio && !mpctx->ao->untimed && !demux_stream_eof(mpctx->sh_audio->gsh)) @@ -1833,7 +1859,7 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time) && !mpctx->restart_playback) { mpctx->drop_frame_cnt++; mpctx->dropped_frames++; - return mpctx->opts.frame_dropping; + return mpctx->opts->frame_dropping; } else mpctx->dropped_frames = 0; } @@ -1844,7 +1870,7 @@ static double timing_sleep(struct MPContext *mpctx, double time_frame) { // assume kernel HZ=100 for softsleep, works with larger HZ but with // unnecessarily high CPU usage - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; double margin = opts->softsleep ? 0.011 : 0; while (time_frame > margin) { mp_sleep_us(1000000 * (time_frame - margin)); @@ -1904,7 +1930,7 @@ static void set_dvdsub_fake_extradata(struct dec_sub *dec_sub, struct stream *st static void reinit_subs(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; struct track *track = mpctx->current_track[STREAM_SUB]; assert(!(mpctx->initialized_flags & INITIALIZED_SUB)); @@ -1984,7 +2010,7 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type, if (type == STREAM_VIDEO) { uninit_player(mpctx, INITIALIZED_VCODEC | - (mpctx->opts.fixed_vo && track ? 0 : INITIALIZED_VO)); + (mpctx->opts->fixed_vo && track ? 0 : INITIALIZED_VO)); } else if (type == STREAM_AUDIO) { uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC | INITIALIZED_VOL); } else if (type == STREAM_SUB) { @@ -1995,13 +2021,13 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type, int user_tid = track ? track->user_tid : -2; if (type == STREAM_VIDEO) { - mpctx->opts.video_id = user_tid; + mpctx->opts->video_id = user_tid; reinit_video_chain(mpctx); } else if (type == STREAM_AUDIO) { - mpctx->opts.audio_id = user_tid; + mpctx->opts->audio_id = user_tid; reinit_audio_chain(mpctx); } else if (type == STREAM_SUB) { - mpctx->opts.sub_id = user_tid; + mpctx->opts->sub_id = user_tid; reinit_subs(mpctx); } @@ -2059,7 +2085,7 @@ bool mp_remove_track(struct MPContext *mpctx, struct track *track) */ static void adjust_sync(struct MPContext *mpctx, double frame_time) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (!mpctx->sh_audio || mpctx->syncing_audio) return; @@ -2088,7 +2114,7 @@ static int write_to_ao(struct MPContext *mpctx, void *data, int len, int flags, if (mpctx->paused) return 0; struct ao *ao = mpctx->ao; - double bps = ao->bps / mpctx->opts.playback_speed; + double bps = ao->bps / mpctx->opts->playback_speed; ao->pts = pts; int played = ao_play(mpctx->ao, data, len, flags); if (played > 0) { @@ -2105,7 +2131,7 @@ static int write_to_ao(struct MPContext *mpctx, void *data, int len, int flags, static int audio_start_sync(struct MPContext *mpctx, int playsize) { struct ao *ao = mpctx->ao; - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; sh_audio_t * const sh_audio = mpctx->sh_audio; int res; @@ -2190,7 +2216,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize) static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; struct ao *ao = mpctx->ao; int playsize; int playflags = 0; @@ -2225,7 +2251,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts) * implementation would require draining buffered old-format audio * while displaying video, then doing the output format switch. */ - if (!mpctx->opts.gapless_audio) + if (!mpctx->opts->gapless_audio) uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_VOL); reinit_audio_chain(mpctx); return -1; @@ -2287,7 +2313,7 @@ static void update_fps(struct MPContext *mpctx) static void recreate_video_filters(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; struct sh_video *sh_video = mpctx->sh_video; assert(sh_video); @@ -2320,10 +2346,10 @@ int reinit_video_filters(struct MPContext *mpctx) int reinit_video_chain(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; assert(!(mpctx->initialized_flags & INITIALIZED_VCODEC)); init_demux_stream(mpctx, STREAM_VIDEO); - sh_video_t * const sh_video = mpctx->sh_video; + sh_video_t *sh_video = mpctx->sh_video; if (!sh_video) { uninit_player(mpctx, INITIALIZED_VO); goto no_video; @@ -2346,7 +2372,7 @@ int reinit_video_chain(struct MPContext *mpctx) double ar = -1.0; //================== Init VIDEO (codec & libvo) ========================== if (!opts->fixed_vo || !(mpctx->initialized_flags & INITIALIZED_VO)) { - mpctx->video_out = init_best_video_out(&opts->vo, mpctx->input, + mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input, mpctx->encode_lavc_ctx); if (!mpctx->video_out) { mp_tmsg(MSGT_CPLAYER, MSGL_FATAL, "Error opening/initializing " @@ -2358,6 +2384,11 @@ int reinit_video_chain(struct MPContext *mpctx) &(bool){false}); } mpctx->initialized_flags |= INITIALIZED_VO; + + // dynamic allocation only to make stheader.h lighter + talloc_free(sh_video->hwdec_info); + sh_video->hwdec_info = talloc_zero(sh_video, struct mp_hwdec_info); + vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, sh_video->hwdec_info); } vo_update_window_title(mpctx); @@ -2408,7 +2439,7 @@ no_video: // frame. This can go wrong in all sorts of ways, so use sparingly. void mp_force_video_refresh(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; // If not paused, the next frame should come soon enough. if (opts->pause && mpctx->last_vo_pts != MP_NOPTS_VALUE) @@ -2497,7 +2528,7 @@ static struct demux_packet *video_read_frame(struct MPContext *mpctx) float frame_time = sh_video->fps > 0 ? 1.0f / sh_video->fps : 0; // override frame_time for variable/unknown FPS formats: - if (!mpctx->opts.force_fps) { + if (!mpctx->opts->force_fps) { double next_pts = demux_get_next_pts(sh_video->gsh); double d = next_pts == MP_NOPTS_VALUE ? sh_video->last_pts - pts1 : next_pts - sh_video->last_pts; @@ -2569,7 +2600,7 @@ static double update_video_attached_pic(struct MPContext *mpctx) static void determine_frame_pts(struct MPContext *mpctx) { struct sh_video *sh_video = mpctx->sh_video; - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (opts->user_pts_assoc_mode) sh_video->pts_assoc_mode = opts->user_pts_assoc_mode; @@ -2603,7 +2634,7 @@ static double update_video(struct MPContext *mpctx, double endpts) struct vo *video_out = mpctx->video_out; sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ, mpctx->osd); // for vf_sub - if (!mpctx->opts.correct_pts) + if (!mpctx->opts->correct_pts) return update_video_nocorrect_pts(mpctx); if (sh_video->gsh->attached_picture) @@ -2694,7 +2725,7 @@ static double update_video(struct MPContext *mpctx, double endpts) void pause_player(struct MPContext *mpctx) { - mpctx->opts.pause = 1; + mpctx->opts->pause = 1; if (mpctx->video_out) vo_control(mpctx->video_out, VOCTRL_RESTORE_SCREENSAVER, NULL); @@ -2717,15 +2748,15 @@ void pause_player(struct MPContext *mpctx) if (mpctx->num_sources) print_status(mpctx); - if (!mpctx->opts.quiet) + if (!mpctx->opts->quiet) mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_PAUSED\n"); } void unpause_player(struct MPContext *mpctx) { - mpctx->opts.pause = 0; + mpctx->opts->pause = 0; - if (mpctx->video_out && mpctx->opts.stop_screensaver) + if (mpctx->video_out && mpctx->opts->stop_screensaver) vo_control(mpctx->video_out, VOCTRL_KILL_SCREENSAVER, NULL); if (!mpctx->paused) @@ -2828,7 +2859,7 @@ static bool timeline_set_part(struct MPContext *mpctx, int i, bool force) enum stop_play_reason orig_stop_play = mpctx->stop_play; if (!mpctx->sh_video && mpctx->stop_play == KEEP_PLAYING) mpctx->stop_play = AT_END_OF_FILE; // let audio uninit drain data - uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts.fixed_vo ? 0 : INITIALIZED_VO) | (mpctx->opts.gapless_audio ? 0 : INITIALIZED_AO) | INITIALIZED_VOL | INITIALIZED_ACODEC | INITIALIZED_SUB); + uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts->fixed_vo ? 0 : INITIALIZED_VO) | (mpctx->opts->gapless_audio ? 0 : INITIALIZED_AO) | INITIALIZED_VOL | INITIALIZED_ACODEC | INITIALIZED_SUB); mpctx->stop_play = orig_stop_play; mpctx->demuxer = n->source; @@ -2872,7 +2903,7 @@ static double timeline_set_from_time(struct MPContext *mpctx, double pts, static int seek(MPContext *mpctx, struct seek_params seek, bool timeline_fallthrough) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; uint64_t prev_seek_ts = mpctx->vo_pts_history_seek_ts; if (!mpctx->demuxer) @@ -3109,7 +3140,7 @@ double get_current_pos_ratio(struct MPContext *mpctx, bool use_range) double start = get_start_time(mpctx); double len = get_time_length(mpctx); if (use_range) { - double startpos = rel_time_to_abs(mpctx, mpctx->opts.play_start, + double startpos = rel_time_to_abs(mpctx, mpctx->opts->play_start, MP_NOPTS_VALUE); double endpos = get_play_end_pts(mpctx); if (endpos == MP_NOPTS_VALUE || endpos > start + len) @@ -3132,9 +3163,9 @@ double get_current_pos_ratio(struct MPContext *mpctx, bool use_range) ans = av_clipf((double)(fpos - demuxer->movi_start) / size, 0, 1); } if (use_range) { - if (mpctx->opts.play_frames > 0) + if (mpctx->opts->play_frames > 0) ans = max(ans, 1.0 - - mpctx->max_frames / (double) mpctx->opts.play_frames); + mpctx->max_frames / (double) mpctx->opts->play_frames); } return ans; } @@ -3262,7 +3293,7 @@ static void update_avsync(struct MPContext *mpctx) mpctx->last_av_difference = a_pos - mpctx->video_pts - mpctx->audio_delay; if (mpctx->time_frame > 0) mpctx->last_av_difference += - mpctx->time_frame * mpctx->opts.playback_speed; + mpctx->time_frame * mpctx->opts->playback_speed; if (a_pos == MP_NOPTS_VALUE || mpctx->video_pts == MP_NOPTS_VALUE) mpctx->last_av_difference = MP_NOPTS_VALUE; if (mpctx->last_av_difference > 0.5 && mpctx->drop_frame_cnt > 50 @@ -3274,7 +3305,7 @@ static void update_avsync(struct MPContext *mpctx) static void handle_pause_on_low_cache(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; int cache = mp_get_cache_percent(mpctx); bool idle = mp_get_cache_idle(mpctx); if (mpctx->paused && mpctx->paused_for_cache) { @@ -3317,7 +3348,7 @@ static double get_wakeup_period(struct MPContext *mpctx) static void run_playloop(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; bool full_audio_buffers = false; bool audio_left = false, video_left = false; double endpts = get_play_end_pts(mpctx); @@ -3376,6 +3407,7 @@ static void run_playloop(struct MPContext *mpctx) mpctx->current_track[STREAM_VIDEO] = NULL; if (!mpctx->current_track[STREAM_AUDIO]) mpctx->stop_play = PT_NEXT_ENTRY; + mpctx->error_playing = true; break; } video_left = frame_time >= 0; @@ -3560,7 +3592,7 @@ static void run_playloop(struct MPContext *mpctx) double a_pos = 0; if (mpctx->sh_audio) { a_pos = (written_audio_pts(mpctx) - - mpctx->opts.playback_speed * buffered_audio); + mpctx->opts->playback_speed * buffered_audio); } mpctx->playback_pts = a_pos; print_status(mpctx); @@ -3834,7 +3866,7 @@ static struct track *select_track(struct MPContext *mpctx, if (pick && !select_fallback && !pick->is_external && !match_lang(langs, pick->lang) && !pick->default_track) pick = NULL; - if (pick && pick->attached_picture && !mpctx->opts.audio_display) + if (pick && pick->attached_picture && !mpctx->opts->audio_display) pick = NULL; return pick; } @@ -3843,7 +3875,7 @@ static struct track *select_track(struct MPContext *mpctx, // code resets track selection if the new file has a different track layout. static void check_previous_track_selection(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (!mpctx->track_layout_hash) return; @@ -3852,11 +3884,11 @@ static void check_previous_track_selection(struct MPContext *mpctx) if (strcmp(h, mpctx->track_layout_hash) != 0) { // Reset selection, but only if they're not "auto" or "off". if (opts->video_id >= 0) - mpctx->opts.video_id = -1; + mpctx->opts->video_id = -1; if (opts->audio_id >= 0) - mpctx->opts.audio_id = -1; + mpctx->opts->audio_id = -1; if (opts->sub_id >= 0) - mpctx->opts.sub_id = -1; + mpctx->opts->sub_id = -1; talloc_free(mpctx->track_layout_hash); mpctx->track_layout_hash = NULL; } @@ -3872,10 +3904,10 @@ static int read_keys(void *ctx, int fd) static void init_input(struct MPContext *mpctx) { - mpctx->input = mp_input_init(&mpctx->opts.input, mpctx->opts.load_config); - if (mpctx->opts.slave_mode) + mpctx->input = mp_input_init(mpctx->opts); + if (mpctx->opts->slave_mode) mp_input_add_cmd_fd(mpctx->input, 0, USE_FD0_CMD_SELECT, MP_INPUT_SLAVE_CMD_FUNC, NULL); - else if (mpctx->opts.consolecontrols) + else if (mpctx->opts->consolecontrols) mp_input_add_key_fd(mpctx->input, 0, 1, read_keys, NULL, mpctx->input); // Set the libstream interrupt callback stream_set_interrupt_callback(mp_input_check_interrupt, mpctx->input); @@ -3890,12 +3922,12 @@ static void open_subtitles_from_options(struct MPContext *mpctx) // after reading video params we should load subtitles because // we know fps so now we can adjust subtitle time to ~6 seconds AST // check .sub - if (mpctx->opts.sub_name) { - for (int i = 0; mpctx->opts.sub_name[i] != NULL; ++i) - mp_add_subtitles(mpctx, mpctx->opts.sub_name[i], 0); + if (mpctx->opts->sub_name) { + for (int i = 0; mpctx->opts->sub_name[i] != NULL; ++i) + mp_add_subtitles(mpctx, mpctx->opts->sub_name[i], 0); } - if (mpctx->opts.sub_auto) { // auto load sub file ... - char **tmp = find_text_subtitles(&mpctx->opts, mpctx->filename); + if (mpctx->opts->sub_auto) { // auto load sub file ... + char **tmp = find_text_subtitles(mpctx->opts, mpctx->filename); int nsub = MP_TALLOC_ELEMS(tmp); for (int i = 0; i < nsub; i++) { struct track *track = mp_add_subtitles(mpctx, tmp[i], 1); @@ -3910,13 +3942,13 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename, char *demuxer_name, int stream_cache, enum stream_type filter) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; if (!filename) return NULL; char *disp_filename = filename; if (strncmp(disp_filename, "memory://", 9) == 0) disp_filename = "memory://"; // avoid noise - struct stream *stream = stream_open(filename, &mpctx->opts); + struct stream *stream = stream_open(filename, mpctx->opts); if (!stream) goto err_out; stream_enable_cache_percent(&stream, stream_cache, @@ -3927,7 +3959,7 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename, .ass_library = mpctx->ass_library, // demux_libass requires it }; struct demuxer *demuxer = - demux_open(stream, demuxer_name, ¶ms, &mpctx->opts); + demux_open(stream, demuxer_name, ¶ms, mpctx->opts); if (!demuxer) { free_stream(stream); goto err_out; @@ -3961,21 +3993,21 @@ err_out: static void open_audiofiles_from_options(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; open_external_file(mpctx, opts->audio_stream, opts->audio_demuxer_name, opts->audio_stream_cache, STREAM_AUDIO); } struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename, int noerr) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; return open_external_file(mpctx, filename, opts->sub_demuxer_name, 0, STREAM_SUB); } static void open_subtitles_from_resolve(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; struct mp_resolve_result *res = mpctx->resolve_result; if (!res) return; @@ -4018,12 +4050,12 @@ static void print_timeline(struct MPContext *mpctx) static void add_subtitle_fonts_from_sources(struct MPContext *mpctx) { #ifdef CONFIG_ASS - if (mpctx->opts.ass_enabled) { + if (mpctx->opts->ass_enabled) { for (int j = 0; j < mpctx->num_sources; j++) { struct demuxer *d = mpctx->sources[j]; for (int i = 0; i < d->num_attachments; i++) { struct demux_attachment *att = d->attachments + i; - if (mpctx->opts.use_embedded_fonts && attachment_is_font(att)) + if (mpctx->opts->use_embedded_fonts && attachment_is_font(att)) ass_add_font(mpctx->ass_library, att->name, att->data, att->data_size); } @@ -4036,7 +4068,7 @@ static void add_subtitle_fonts_from_sources(struct MPContext *mpctx) mpctx->osd->ass_renderer = ass_renderer_init(mpctx->osd->ass_library); if (mpctx->osd->ass_renderer) mp_ass_configure_fonts(mpctx->osd->ass_renderer, - mpctx->opts.sub_text_style); + mpctx->opts->sub_text_style); #endif } @@ -4054,7 +4086,7 @@ static struct mp_resolve_result *resolve_url(const char *filename, static void idle_loop(struct MPContext *mpctx) { // ================= idle loop (STOP state) ========================= - while (mpctx->opts.player_idle_mode && !mpctx->playlist->current + while (mpctx->opts->player_idle_mode && !mpctx->playlist->current && mpctx->stop_play != PT_QUIT) { uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_VO); @@ -4069,7 +4101,7 @@ static void idle_loop(struct MPContext *mpctx) static void stream_dump(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; char *filename = opts->stream_dump; stream_t *stream = mpctx->stream; assert(stream && filename); @@ -4100,7 +4132,7 @@ static void stream_dump(struct MPContext *mpctx) // Handle initialization and deinitialization. static void play_current_file(struct MPContext *mpctx) { - struct MPOpts *opts = &mpctx->opts; + struct MPOpts *opts = mpctx->opts; mpctx->stop_play = 0; mpctx->filename = NULL; @@ -4117,8 +4149,6 @@ static void play_current_file(struct MPContext *mpctx) mpctx->add_osd_seek_info &= OSD_SEEK_INFO_EDITION; - m_config_enter_file_local(mpctx->mconfig); - load_per_protocol_config(mpctx->mconfig, mpctx->filename); load_per_extension_config(mpctx->mconfig, mpctx->filename); load_per_file_config(mpctx->mconfig, mpctx->filename, opts->use_filedir_conf); @@ -4140,9 +4170,9 @@ static void play_current_file(struct MPContext *mpctx) for (int n = 0; opts->reset_options[n]; n++) { const char |