summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-10-03 19:57:49 +0200
committerwm4 <wm4@nowhere>2014-10-03 23:05:09 +0200
commit9d5d031b6d23402a465618892a40b7af6d4e3c28 (patch)
tree143f43c4b002ec74f7172038e58409723647d892
parent9570976255083c1ec32add62613c52ad98fa28c8 (diff)
downloadmpv-9d5d031b6d23402a465618892a40b7af6d4e3c28.tar.bz2
mpv-9d5d031b6d23402a465618892a40b7af6d4e3c28.tar.xz
player: remove central uninit_player() function and flags mess
Each subsystem (or similar thing) had an INITIALIZED_ flag assigned. The main use of this was that you could pass a bitmask of these flags to uninit_player(). Except in some situations where you wanted to uninitialize nearly everything, this wasn't really useful. Moreover, it was quite annoying that subsystems had most of the code in a specific file, but the uninit code in loadfile.c (because that's where uninit_player() was implemented). Simplify all this. Remove the flags; e.g. instead of testing for the INITIALIZED_AO flag, test whether mpctx->ao is set. Move uninit code to separate functions, e.g. uninit_audio_out().
-rw-r--r--player/audio.c49
-rw-r--r--player/command.c4
-rw-r--r--player/core.h24
-rw-r--r--player/loadfile.c229
-rw-r--r--player/main.c5
-rw-r--r--player/osd.c3
-rw-r--r--player/playloop.c14
-rw-r--r--player/sub.c51
-rw-r--r--player/video.c32
9 files changed, 184 insertions, 227 deletions
diff --git a/player/audio.c b/player/audio.c
index 69510ae205..e8fa4f3592 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -142,21 +142,45 @@ void reset_audio_state(struct MPContext *mpctx)
mpctx->audio_status = mpctx->d_audio ? STATUS_SYNCING : STATUS_EOF;
}
+void uninit_audio_out(struct MPContext *mpctx)
+{
+ if (mpctx->ao) {
+ // Note: with gapless_audio, stop_play is not correctly set
+ if (mpctx->opts->gapless_audio || mpctx->stop_play == AT_END_OF_FILE)
+ ao_drain(mpctx->ao);
+ ao_uninit(mpctx->ao);
+ }
+ mpctx->ao = NULL;
+ talloc_free(mpctx->ao_decoder_fmt);
+ mpctx->ao_decoder_fmt = NULL;
+}
+
+void uninit_audio_chain(struct MPContext *mpctx)
+{
+ if (mpctx->d_audio) {
+ mixer_uninit_audio(mpctx->mixer);
+ audio_uninit(mpctx->d_audio);
+ mpctx->d_audio = NULL;
+ talloc_free(mpctx->ao_buffer);
+ mpctx->ao_buffer = NULL;
+ mpctx->audio_status = STATUS_EOF;
+ reselect_demux_streams(mpctx);
+ }
+}
+
void reinit_audio_chain(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
struct track *track = mpctx->current_track[0][STREAM_AUDIO];
struct sh_stream *sh = track ? track->stream : NULL;
if (!sh) {
- uninit_player(mpctx, INITIALIZED_AO);
+ uninit_audio_out(mpctx);
goto no_audio;
}
mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
- if (!(mpctx->initialized_flags & INITIALIZED_ACODEC)) {
- mpctx->initialized_flags |= INITIALIZED_ACODEC;
- assert(!mpctx->d_audio);
+ if (!mpctx->d_audio) {
mpctx->d_audio = talloc_zero(NULL, struct dec_audio);
mpctx->d_audio->log = mp_log_new(mpctx->d_audio, mpctx->log, "!ad");
mpctx->d_audio->global = mpctx->global;
@@ -188,16 +212,15 @@ void reinit_audio_chain(struct MPContext *mpctx)
}
// Weak gapless audio: drain AO on decoder format changes
- if (mpctx->ao_decoder_fmt && (mpctx->initialized_flags & INITIALIZED_AO) &&
- !mp_audio_config_equals(mpctx->ao_decoder_fmt, &in_format) &&
- opts->gapless_audio < 0)
+ if (mpctx->ao_decoder_fmt && mpctx->ao && opts->gapless_audio < 0 &&
+ !mp_audio_config_equals(mpctx->ao_decoder_fmt, &in_format))
{
- uninit_player(mpctx, INITIALIZED_AO);
+ uninit_audio_out(mpctx);
}
struct af_stream *afs = mpctx->d_audio->afilter;
- if (mpctx->initialized_flags & INITIALIZED_AO) {
+ if (mpctx->ao) {
ao_get_format(mpctx->ao, &afs->output);
} else {
afs->output = (struct mp_audio){0};
@@ -219,8 +242,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
goto init_error;
}
- if (!(mpctx->initialized_flags & INITIALIZED_AO)) {
- mpctx->initialized_flags |= INITIALIZED_AO;
+ if (!mpctx->ao) {
afs->initialized = 0; // do it again
mp_chmap_remove_useless_channels(&afs->output.channels,
@@ -260,7 +282,8 @@ void reinit_audio_chain(struct MPContext *mpctx)
return;
init_error:
- uninit_player(mpctx, INITIALIZED_ACODEC | INITIALIZED_AO);
+ uninit_audio_chain(mpctx);
+ uninit_audio_out(mpctx);
no_audio:
mp_deselect_track(mpctx, track);
if (track)
@@ -466,7 +489,7 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
* while displaying video, then doing the output format switch.
*/
if (mpctx->opts->gapless_audio < 1)
- uninit_player(mpctx, INITIALIZED_AO);
+ uninit_audio_out(mpctx);
reinit_audio_chain(mpctx);
mpctx->sleeptime = 0;
return; // retry on next iteration
diff --git a/player/command.c b/player/command.c
index 9818385abc..8d4e3170a9 100644
--- a/player/command.c
+++ b/player/command.c
@@ -1686,10 +1686,10 @@ static int mp_property_hwdec(void *ctx, struct m_property *prop,
int new = *(int *)arg;
if (current == new)
return M_PROPERTY_OK;
- if (!(mpctx->initialized_flags & INITIALIZED_VCODEC))
+ if (!mpctx->d_video)
return M_PROPERTY_ERROR;
double last_pts = mpctx->last_vo_pts;
- uninit_player(mpctx, INITIALIZED_VCODEC);
+ uninit_video_chain(mpctx);
opts->hwdec_api = new;
reinit_video_chain(mpctx);
if (last_pts != MP_NOPTS_VALUE)
diff --git a/player/core.h b/player/core.h
index cff468c0cd..bcd0116bd4 100644
--- a/player/core.h
+++ b/player/core.h
@@ -29,19 +29,6 @@
// definitions used internally by the core player code
-#define INITIALIZED_VO 1
-#define INITIALIZED_AO 2
-#define INITIALIZED_PLAYBACK 16
-#define INITIALIZED_LIBASS 32
-#define INITIALIZED_STREAM 64
-#define INITIALIZED_DEMUXER 512
-#define INITIALIZED_ACODEC 1024
-#define INITIALIZED_VCODEC 2048
-#define INITIALIZED_SUB 4096
-#define INITIALIZED_SUB2 8192
-#define INITIALIZED_ALL 0xFFFF
-
-
enum stop_play_reason {
KEEP_PLAYING = 0, // must be 0, numeric values of others do not matter
AT_END_OF_FILE, // file has ended, prepare to play next
@@ -194,7 +181,7 @@ typedef struct MPContext {
char *filename; // always the same as playing->filename (or NULL)
struct mp_resolve_result *resolve_result;
enum stop_play_reason stop_play;
- unsigned int initialized_flags; // which subsystems have been initialized
+ bool playback_initialized; // playloop can be run/is running
// Return code to use with PT_QUIT
enum exit_reason quit_player_rc;
@@ -368,6 +355,8 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts);
double written_audio_pts(struct MPContext *mpctx);
void clear_audio_output_buffers(struct MPContext *mpctx);
void set_playback_speed(struct MPContext *mpctx, double new_speed);
+void uninit_audio_out(struct MPContext *mpctx);
+void uninit_audio_chain(struct MPContext *mpctx);
// configfiles.c
void mp_parse_cfgfiles(struct MPContext *mpctx);
@@ -407,6 +396,7 @@ struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction,
void mp_set_playlist_entry(struct MPContext *mpctx, struct playlist_entry *e);
void mp_play_files(struct MPContext *mpctx);
void update_demuxer_properties(struct MPContext *mpctx);
+void reselect_demux_streams(struct MPContext *mpctx);
// main.c
int mpv_main(int argc, char *argv[]);
@@ -473,8 +463,10 @@ void mp_load_scripts(struct MPContext *mpctx);
// sub.c
void reset_subtitle_state(struct MPContext *mpctx);
void reset_subtitles(struct MPContext *mpctx, int order);
-void uninit_subs(struct demuxer *demuxer);
+void uninit_stream_sub_decoders(struct demuxer *demuxer);
void reinit_subs(struct MPContext *mpctx, int order);
+void uninit_sub(struct MPContext *mpctx, int order);
+void uninit_sub_all(struct MPContext *mpctx);
void update_osd_msg(struct MPContext *mpctx);
void update_subtitles(struct MPContext *mpctx);
@@ -492,5 +484,7 @@ int reinit_video_filters(struct MPContext *mpctx);
void write_video(struct MPContext *mpctx, double endpts);
void mp_force_video_refresh(struct MPContext *mpctx);
void update_fps(struct MPContext *mpctx);
+void uninit_video_out(struct MPContext *mpctx);
+void uninit_video_chain(struct MPContext *mpctx);
#endif /* MPLAYER_MP_CORE_H */
diff --git a/player/loadfile.c b/player/loadfile.c
index 23d6a4aeb4..5cd77efc1f 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -60,133 +60,44 @@
#include "command.h"
#include "libmpv/client.h"
-static void reselect_demux_streams(struct MPContext *mpctx);
-
-static void uninit_sub(struct MPContext *mpctx, int order)
+static void uninit_demuxer(struct MPContext *mpctx)
{
- mpctx->d_sub[order] = NULL; // Note: not free'd.
- int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
- osd_set_sub(mpctx->osd, obj, NULL);
- reset_subtitles(mpctx, order);
- reselect_demux_streams(mpctx);
+ assert(!mpctx->d_video && !mpctx->d_audio &&
+ !mpctx->d_sub[0] && !mpctx->d_sub[1]);
+ for (int i = 0; i < mpctx->num_tracks; i++) {
+ talloc_free(mpctx->tracks[i]);
+ }
+ mpctx->num_tracks = 0;
+ for (int r = 0; r < NUM_PTRACKS; r++) {
+ for (int t = 0; t < STREAM_TYPE_COUNT; t++)
+ mpctx->current_track[r][t] = NULL;
+ }
+ mpctx->master_demuxer = NULL;
+ for (int i = 0; i < mpctx->num_sources; i++) {
+ uninit_stream_sub_decoders(mpctx->sources[i]);
+ struct demuxer *demuxer = mpctx->sources[i];
+ struct stream *stream = demuxer->stream;
+ free_demuxer(demuxer);
+ if (stream != mpctx->stream)
+ free_stream(stream);
+ }
+ talloc_free(mpctx->sources);
+ mpctx->sources = NULL;
+ mpctx->demuxer = NULL;
+ mpctx->num_sources = 0;
+ talloc_free(mpctx->timeline);
+ mpctx->timeline = NULL;
+ mpctx->num_timeline_parts = 0;
+ talloc_free(mpctx->chapters);
+ mpctx->chapters = NULL;
+ mpctx->num_chapters = 0;
+ mpctx->video_offset = 0;
}
-void uninit_player(struct MPContext *mpctx, unsigned int mask)
+static void uninit_stream(struct MPContext *mpctx)
{
- struct MPOpts *opts = mpctx->opts;
-
- mask &= mpctx->initialized_flags;
-
- MP_DBG(mpctx, "\n*** uninit(0x%X)\n", mask);
-
- if (mask & INITIALIZED_ACODEC) {
- mpctx->initialized_flags &= ~INITIALIZED_ACODEC;
- mixer_uninit_audio(mpctx->mixer);
- audio_uninit(mpctx->d_audio);
- mpctx->d_audio = NULL;
- talloc_free(mpctx->ao_buffer);
- mpctx->ao_buffer = NULL;
- mpctx->audio_status = STATUS_EOF;
- reselect_demux_streams(mpctx);
- }
-
- if (mask & INITIALIZED_SUB) {
- mpctx->initialized_flags &= ~INITIALIZED_SUB;
- uninit_sub(mpctx, 0);
- }
- if (mask & INITIALIZED_SUB2) {
- mpctx->initialized_flags &= ~INITIALIZED_SUB2;
- uninit_sub(mpctx, 1);
- }
-
- if (mask & INITIALIZED_LIBASS) {
- mpctx->initialized_flags &= ~INITIALIZED_LIBASS;
-#if HAVE_LIBASS
- if (mpctx->ass_renderer)
- ass_renderer_done(mpctx->ass_renderer);
- mpctx->ass_renderer = NULL;
- ass_clear_fonts(mpctx->ass_library);
-#endif
- }
-
- if (mask & INITIALIZED_VCODEC) {
- mpctx->initialized_flags &= ~INITIALIZED_VCODEC;
- reset_video_state(mpctx);
- if (mpctx->d_video)
- video_uninit(mpctx->d_video);
- mpctx->d_video = NULL;
- mpctx->video_status = STATUS_EOF;
- mpctx->sync_audio_to_video = false;
- reselect_demux_streams(mpctx);
- }
-
- if (mask & INITIALIZED_DEMUXER) {
- mpctx->initialized_flags &= ~INITIALIZED_DEMUXER;
- assert(!(mpctx->initialized_flags &
- (INITIALIZED_VCODEC | INITIALIZED_ACODEC |
- INITIALIZED_SUB2 | INITIALIZED_SUB)));
- for (int i = 0; i < mpctx->num_tracks; i++) {
- talloc_free(mpctx->tracks[i]);
- }
- mpctx->num_tracks = 0;
- for (int r = 0; r < NUM_PTRACKS; r++) {
- for (int t = 0; t < STREAM_TYPE_COUNT; t++)
- mpctx->current_track[r][t] = NULL;
- }
- assert(!mpctx->d_video && !mpctx->d_audio &&
- !mpctx->d_sub[0] && !mpctx->d_sub[1]);
- mpctx->master_demuxer = NULL;
- for (int i = 0; i < mpctx->num_sources; i++) {
- uninit_subs(mpctx->sources[i]);
- struct demuxer *demuxer = mpctx->sources[i];
- struct stream *stream = demuxer->stream;
- free_demuxer(demuxer);
- if (stream != mpctx->stream)
- free_stream(stream);
- }
- talloc_free(mpctx->sources);
- mpctx->sources = NULL;
- mpctx->demuxer = NULL;
- mpctx->num_sources = 0;
- talloc_free(mpctx->timeline);
- mpctx->timeline = NULL;
- mpctx->num_timeline_parts = 0;
- talloc_free(mpctx->chapters);
- mpctx->chapters = NULL;
- mpctx->num_chapters = 0;
- mpctx->video_offset = 0;
- }
-
- // kill the cache process:
- if (mask & INITIALIZED_STREAM) {
- mpctx->initialized_flags &= ~INITIALIZED_STREAM;
- if (mpctx->stream)
- free_stream(mpctx->stream);
- mpctx->stream = NULL;
- }
-
- if (mask & INITIALIZED_VO) {
- mpctx->initialized_flags &= ~INITIALIZED_VO;
- vo_destroy(mpctx->video_out);
- mpctx->video_out = NULL;
- }
-
- if (mask & INITIALIZED_AO) {
- struct ao *ao = mpctx->ao;
- mpctx->initialized_flags &= ~INITIALIZED_AO;
- if (ao) {
- // Note: with gapless_audio, stop_play is not correctly set
- if (opts->gapless_audio || mpctx->stop_play == AT_END_OF_FILE)
- ao_drain(ao);
- ao_uninit(ao);
- }
- mpctx->ao = NULL;
- talloc_free(mpctx->ao_decoder_fmt);
- mpctx->ao_decoder_fmt = NULL;
- }
-
- if (mask & INITIALIZED_PLAYBACK)
- mpctx->initialized_flags &= ~INITIALIZED_PLAYBACK;
+ free_stream(mpctx->stream);
+ mpctx->stream = NULL;
}
#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
@@ -283,7 +194,7 @@ static bool need_init_seek(struct demuxer *demux)
// can be important, because reading from a demuxer stream (e.g. during init)
// will implicitly discard interleaved packets from unselected streams.
// Also initializes position for external streams.
-static void reselect_demux_streams(struct MPContext *mpctx)
+void reselect_demux_streams(struct MPContext *mpctx)
{
// Note: we assume that all demuxer streams are covered by the track list.
for (int t = 0; t < mpctx->num_tracks; t++) {
@@ -345,7 +256,13 @@ bool timeline_set_part(struct MPContext *mpctx, int i, bool force)
enum stop_play_reason orig_stop_play = mpctx->stop_play;
if (!mpctx->d_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_ACODEC | INITIALIZED_SUB | INITIALIZED_SUB2);
+ uninit_audio_chain(mpctx);
+ uninit_video_chain(mpctx);
+ uninit_sub_all(mpctx);
+ if (!mpctx->opts->fixed_vo)
+ uninit_video_out(mpctx);
+ if (!mpctx->opts->gapless_audio)
+ uninit_audio_out(mpctx);
mpctx->stop_play = orig_stop_play;
if (mpctx->demuxer) {
@@ -580,19 +497,19 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type
if (order == 0) {
if (type == STREAM_VIDEO) {
- int uninit = INITIALIZED_VCODEC;
- if (!mpctx->opts->force_vo)
- uninit |= mpctx->opts->fixed_vo && track ? 0 : INITIALIZED_VO;
- uninit_player(mpctx, uninit);
+ uninit_video_chain(mpctx);
+ if (!mpctx->opts->fixed_vo || !track)
+ handle_force_window(mpctx, false);
} else if (type == STREAM_AUDIO) {
clear_audio_output_buffers(mpctx);
- uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC);
+ uninit_audio_chain(mpctx);
+ uninit_audio_out(mpctx);
} else if (type == STREAM_SUB) {
- uninit_player(mpctx, INITIALIZED_SUB);
+ uninit_sub(mpctx, 0);
}
} else if (order == 1) {
if (type == STREAM_SUB)
- uninit_player(mpctx, INITIALIZED_SUB2);
+ uninit_sub(mpctx, 1);
}
if (current)
@@ -870,18 +787,26 @@ static void add_subtitle_fonts_from_sources(struct MPContext *mpctx)
#endif
}
+static void uninit_libass(struct MPContext *mpctx)
+{
+#if HAVE_LIBASS
+ if (mpctx->ass_renderer)
+ ass_renderer_done(mpctx->ass_renderer);
+ mpctx->ass_renderer = NULL;
+ ass_clear_fonts(mpctx->ass_library);
+#endif
+}
+
static void init_sub_renderer(struct MPContext *mpctx)
{
#if HAVE_LIBASS
- assert(!(mpctx->initialized_flags & INITIALIZED_LIBASS));
- assert(!mpctx->ass_renderer);
+ uninit_libass(mpctx);
mpctx->ass_renderer = ass_renderer_init(mpctx->ass_library);
if (mpctx->ass_renderer) {
mp_ass_configure_fonts(mpctx->ass_renderer, mpctx->opts->sub_text_style,
mpctx->global, mpctx->ass_log);
}
- mpctx->initialized_flags |= INITIALIZED_LIBASS;
#endif
}
@@ -1093,7 +1018,6 @@ static void play_current_file(struct MPContext *mpctx)
mp_process_input(mpctx);
goto terminate_playback;
}
- mpctx->initialized_flags |= INITIALIZED_STREAM;
if (opts->stream_dump && opts->stream_dump[0]) {
stream_dump(mpctx);
@@ -1127,8 +1051,6 @@ goto_reopen_demuxer: ;
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, mpctx->demuxer);
- mpctx->initialized_flags |= INITIALIZED_DEMUXER;
-
if (mpctx->demuxer->playlist) {
int entry_stream_flags =
(mpctx->demuxer->stream->safe_origin ? 0 : STREAM_SAFE_ONLY) |
@@ -1276,7 +1198,7 @@ goto_reopen_demuxer: ;
if (mpctx->opts->pause)
pause_player(mpctx);
- mpctx->initialized_flags |= INITIALIZED_PLAYBACK;
+ mpctx->playback_initialized = true;
mp_notify(mpctx, MPV_EVENT_FILE_LOADED, NULL);
playback_start = mp_time_sec();
@@ -1288,9 +1210,11 @@ goto_reopen_demuxer: ;
if (mpctx->stop_play == PT_RELOAD_DEMUXER) {
mpctx->stop_play = KEEP_PLAYING;
- uninit_player(mpctx, INITIALIZED_ALL -
- (INITIALIZED_PLAYBACK | INITIALIZED_STREAM |
- (opts->fixed_vo ? INITIALIZED_VO : 0)));
+ mpctx->playback_initialized = false;
+ uninit_audio_chain(mpctx);
+ uninit_video_chain(mpctx);
+ uninit_sub_all(mpctx);
+ uninit_demuxer(mpctx);
goto goto_reopen_demuxer;
}
@@ -1315,15 +1239,18 @@ terminate_playback:
MP_INFO(mpctx, "\n");
// time to uninit all, except global stuff:
- int uninitialize_parts = INITIALIZED_ALL;
- if (opts->fixed_vo)
- uninitialize_parts -= INITIALIZED_VO;
- if ((opts->gapless_audio && mpctx->stop_play == AT_END_OF_FILE) ||
- mpctx->encode_lavc_ctx)
- uninitialize_parts -= INITIALIZED_AO;
- uninit_player(mpctx, uninitialize_parts);
-
- // xxx handle this as INITIALIZED_CONFIG?
+ uninit_audio_chain(mpctx);
+ uninit_video_chain(mpctx);
+ uninit_sub_all(mpctx);
+ uninit_libass(mpctx);
+ uninit_demuxer(mpctx);
+ uninit_stream(mpctx);
+ if (!opts->fixed_vo)
+ uninit_video_out(mpctx);
+ if (!(opts->gapless_audio && mpctx->stop_play == AT_END_OF_FILE) &&
+ !mpctx->encode_lavc_ctx)
+ uninit_audio_out(mpctx);
+
if (mpctx->stop_play != PT_RESTART)
m_config_restore_backups(mpctx->mconfig);
diff --git a/player/main.c b/player/main.c
index ff3b8ab7fe..2a05d3b4f4 100644
--- a/player/main.c
+++ b/player/main.c
@@ -118,8 +118,8 @@ static void shutdown_clients(struct MPContext *mpctx)
void mp_destroy(struct MPContext *mpctx)
{
- if (mpctx->initialized)
- uninit_player(mpctx, INITIALIZED_ALL);
+ uninit_audio_out(mpctx);
+ uninit_video_out(mpctx);
#if HAVE_ENCODING
encode_lavc_finish(mpctx->encode_lavc_ctx);
@@ -439,7 +439,6 @@ int mp_initialize(struct MPContext *mpctx)
return -1;
}
mpctx->mouse_cursor_visible = true;
- mpctx->initialized_flags |= INITIALIZED_VO;
}
// Lua user scripts (etc.) can call arbitrary functions. Load them at a point
diff --git a/player/osd.c b/player/osd.c
index 15cceab95f..2d15c9b904 100644
--- a/player/osd.c
+++ b/player/osd.c
@@ -156,8 +156,7 @@ static void print_status(struct MPContext *mpctx)
if (!opts->use_terminal)
return;
- if (opts->quiet || !(mpctx->initialized_flags & INITIALIZED_PLAYBACK) ||
- !mpctx->playing_msg_shown)
+ if (opts->quiet || !mpctx->playback_initialized || !mpctx->playing_msg_shown)
{
term_osd_set_status(mpctx, "");
return;
diff --git a/player/playloop.c b/player/playloop.c
index de1165e963..5cefcb8ac5 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -789,17 +789,18 @@ static void handle_chapter_change(struct MPContext *mpctx)
// Execute a forceful refresh of the VO window, if it hasn't had a valid frame
// for a while. The problem is that a VO with no valid frame (vo->hasframe==0)
// doesn't redraw video and doesn't OSD interaction. So screw it, hard.
+// It also closes the VO if force_window or video display is not active.
void handle_force_window(struct MPContext *mpctx, bool reconfig)
{
// Don't interfere with real video playback
if (mpctx->d_video)
return;
- struct vo *vo = mpctx->video_out;
- if (!vo)
- return;
+ if (!mpctx->opts->force_vo)
+ uninit_video_out(mpctx);
- if (!vo->config_ok || reconfig) {
+ if (mpctx->video_out && (!mpctx->video_out->config_ok || reconfig)) {
+ struct vo *vo = mpctx->video_out;
MP_INFO(mpctx, "Creating non-video VO window.\n");
// Pick whatever works
int config_format = 0;
@@ -974,10 +975,7 @@ void idle_loop(struct MPContext *mpctx)
{
if (need_reinit) {
mp_notify(mpctx, MPV_EVENT_IDLE, NULL);
- int uninit = INITIALIZED_AO;
- if (!mpctx->opts->force_vo)
- uninit |= INITIALIZED_VO;
- uninit_player(mpctx, uninit);
+ uninit_audio_out(mpctx);
handle_force_window(mpctx, true);
mpctx->sleeptime = 0;
need_reinit = false;
diff --git a/player/sub.c b/player/sub.c
index 8f5f8ad8ac..6d2c5f06a5 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -38,7 +38,7 @@
#include "core.h"
-void uninit_subs(struct demuxer *demuxer)
+void uninit_stream_sub_decoders(struct demuxer *demuxer)
{
for (int i = 0; i < demuxer->num_streams; i++) {
struct sh_stream *sh = demuxer->streams[i];
@@ -49,6 +49,23 @@ void uninit_subs(struct demuxer *demuxer)
}
}
+void uninit_sub(struct MPContext *mpctx, int order)
+{
+ if (mpctx->d_sub[order]) {
+ mpctx->d_sub[order] = NULL; // Note: not free'd.
+ int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
+ osd_set_sub(mpctx->osd, obj, NULL);
+ reset_subtitles(mpctx, order);
+ reselect_demux_streams(mpctx);
+ }
+}
+
+void uninit_sub_all(struct MPContext *mpctx)
+{
+ uninit_sub(mpctx, 0);
+ uninit_sub(mpctx, 1);
+}
+
// When reading subtitles from a demuxer, and we read video or audio from the
// demuxer, we should not explicitly read subtitle packets. (With external
// subs, we have to.)
@@ -85,17 +102,13 @@ void reset_subtitle_state(struct MPContext *mpctx)
static void update_subtitle(struct MPContext *mpctx, int order)
{
struct MPOpts *opts = mpctx->opts;
- if (order == 0) {
- if (!(mpctx->initialized_flags & INITIALIZED_SUB))
- return;
- } else {
- if (!(mpctx->initialized_flags & INITIALIZED_SUB2))
- return;
- }
-
struct track *track = mpctx->current_track[order][STREAM_SUB];
struct dec_sub *dec_sub = mpctx->d_sub[order];
- assert(track && dec_sub);
+
+ if (!track)
+ return;
+
+ assert(dec_sub);
int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
if (mpctx->d_video) {
@@ -190,30 +203,20 @@ void reinit_subs(struct MPContext *mpctx, int order)
struct MPOpts *opts = mpctx->opts;
struct track *track = mpctx->current_track[order][STREAM_SUB];
int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
- int init_flag = order ? INITIALIZED_SUB2 : INITIALIZED_SUB;
- assert(!(mpctx->initialized_flags & init_flag));
+ assert(!mpctx->d_sub[order]);
struct sh_stream *sh = track ? track->stream : NULL;
if (!sh)
return;
- if (!sh->sub->dec_sub) {
- assert(!mpctx->d_sub[order]);
+ // The decoder is cached in the stream header in order to make ordered
+ // chapters work better.
+ if (!sh->sub->dec_sub)
sh->sub->dec_sub = sub_create(mpctx->global);
- }
-
- assert(!mpctx->d_sub[order] || sh->sub->dec_sub == mpctx->d_sub[order]);
-
- // The decoder is kept in the stream header in order to make ordered
- // chapters work well.
mpctx->d_sub[order] = sh->sub->dec_sub;
- mpctx->initialized_flags |= init_flag;
-
struct dec_sub *dec_sub = mpctx->d_sub[order];
- assert(dec_sub);
-
reinit_subdec(mpctx, track, dec_sub);
struct osd_sub_state state = {
diff --git a/player/video.c b/player/video.c
index 80acbf7b72..c4acb0734e 100644
--- a/player/video.c
+++ b/player/video.c
@@ -229,10 +229,29 @@ void reset_video_state(struct MPContext *mpctx)
mpctx->video_status = mpctx->d_video ? STATUS_SYNCING : STATUS_EOF;
}
+void uninit_video_out(struct MPContext *mpctx)
+{
+ uninit_video_chain(mpctx);
+ if (mpctx->video_out)
+ vo_destroy(mpctx->video_out);
+ mpctx->video_out = NULL;
+}
+
+void uninit_video_chain(struct MPContext *mpctx)
+{
+ if (mpctx->d_video) {
+ reset_video_state(mpctx);
+ video_uninit(mpctx->d_video);
+ mpctx->d_video = NULL;
+ mpctx->video_status = STATUS_EOF;
+ mpctx->sync_audio_to_video = false;
+ reselect_demux_streams(mpctx);
+ }
+}
+
int reinit_video_chain(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
- assert(!(mpctx->initialized_flags & INITIALIZED_VCODEC));
assert(!mpctx->d_video);
struct track *track = mpctx->current_track[0][STREAM_VIDEO];
struct sh_stream *sh = track ? track->stream : NULL;
@@ -245,7 +264,7 @@ int reinit_video_chain(struct MPContext *mpctx)
sh->video->fps);
//================== Init VIDEO (codec & libvo) ==========================
- if (!opts->fixed_vo || !(mpctx->initialized_flags & INITIALIZED_VO)) {
+ if (!opts->fixed_vo || !mpctx->video_out) {
mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input,
mpctx->osd,
mpctx->encode_lavc_ctx);
@@ -255,7 +274,6 @@ int reinit_video_chain(struct MPContext *mpctx)
goto err_out;
}
mpctx->mouse_cursor_visible = true;
- mpctx->initialized_flags |= INITIALIZED_VO;
}
update_window_title(mpctx, true);
@@ -268,7 +286,6 @@ int reinit_video_chain(struct MPContext *mpctx)
d_video->header = sh;
d_video->fps = sh->video->fps;
d_video->vo = mpctx->video_out;
- mpctx->initialized_flags |= INITIALIZED_VCODEC;
vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, &d_video->hwdec_info);
@@ -307,7 +324,7 @@ int reinit_video_chain(struct MPContext *mpctx)
err_out:
no_video:
- uninit_player(mpctx, INITIALIZED_VCODEC | (opts->force_vo ? 0 : INITIALIZED_VO));
+ uninit_video_chain(mpctx);
if (track)
mp_deselect_track(mpctx, track);
handle_force_window(mpctx, true);
@@ -811,10 +828,7 @@ void write_video(struct MPContext *mpctx, double endpts)
error:
MP_FATAL(mpctx, "Could not initialize video chain.\n");
- int uninit = INITIALIZED_VCODEC;
- if (!opts->force_vo)
- uninit |= INITIALIZED_VO;
- uninit_player(mpctx, uninit);
+ uninit_video_chain(mpctx);
if (!mpctx->current_track[STREAM_AUDIO])
mpctx->stop_play = PT_NEXT_ENTRY;
mpctx->error_playing = true;