From 004bc9526308c6bc3f51591423e88bb1adaff167 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 17 Jan 2016 16:56:32 +0100 Subject: player: refactor: eliminate MPContext.d_sub The same is going to happen to d_video and d_audio later. --- player/command.c | 3 +- player/core.h | 8 ++--- player/loadfile.c | 32 ++++++++------------ player/playloop.c | 3 +- player/sub.c | 90 +++++++++++++++++++++++++++++++++---------------------- 5 files changed, 74 insertions(+), 62 deletions(-) diff --git a/player/command.c b/player/command.c index f86926c930..4c40be2bf1 100644 --- a/player/command.c +++ b/player/command.c @@ -4564,7 +4564,8 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re case MP_CMD_SUB_SEEK: { if (!mpctx->playback_initialized) return -1; - struct dec_sub *sub = mpctx->d_sub[0]; + struct track *track = mpctx->current_track[0][STREAM_SUB]; + struct dec_sub *sub = track ? track->d_sub : NULL; double refpts = get_current_time(mpctx); if (sub && refpts != MP_NOPTS_VALUE) { double a[2]; diff --git a/player/core.h b/player/core.h index 456d463d5a..715ce74ef3 100644 --- a/player/core.h +++ b/player/core.h @@ -142,7 +142,7 @@ struct track { struct sh_stream *stream; // Current subtitle state (or cached state if selected==false). - struct dec_sub *dec_sub; + struct dec_sub *d_sub; // For external subtitles, which are read fully on init. Do not attempt // to read packets from them. @@ -261,7 +261,6 @@ typedef struct MPContext { struct dec_video *d_video; struct dec_audio *d_audio; - struct dec_sub *d_sub[2]; // Uses: accessing metadata (consider ordered chapters case, where the main // demuxer defines metadata), or special purpose demuxers like TV. @@ -517,8 +516,9 @@ void mp_load_scripts(struct MPContext *mpctx); // sub.c void reset_subtitle_state(struct MPContext *mpctx); -void reinit_subs(struct MPContext *mpctx, int order); -void uninit_sub(struct MPContext *mpctx, int order); +void reinit_sub(struct MPContext *mpctx, struct track *track); +void reinit_sub_all(struct MPContext *mpctx); +void uninit_sub(struct MPContext *mpctx, struct track *track); void uninit_sub_all(struct MPContext *mpctx); void update_osd_msg(struct MPContext *mpctx); bool update_subtitles(struct MPContext *mpctx, double video_pts); diff --git a/player/loadfile.c b/player/loadfile.c index ee555ed421..88004a0ec1 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -60,8 +60,7 @@ static void uninit_demuxer(struct MPContext *mpctx) { - assert(!mpctx->d_video && !mpctx->d_audio && - !mpctx->d_sub[0] && !mpctx->d_sub[1]); + assert(!mpctx->d_video && !mpctx->d_audio); for (int r = 0; r < NUM_PTRACKS; r++) { for (int t = 0; t < STREAM_TYPE_COUNT; t++) mpctx->current_track[r][t] = NULL; @@ -78,7 +77,7 @@ static void uninit_demuxer(struct MPContext *mpctx) mp_remove_track(mpctx, mpctx->tracks[n]); } for (int i = 0; i < mpctx->num_tracks; i++) { - sub_destroy(mpctx->tracks[i]->dec_sub); + sub_destroy(mpctx->tracks[i]->d_sub); talloc_free(mpctx->tracks[i]); } mpctx->num_tracks = 0; @@ -336,15 +335,14 @@ bool timeline_switch_to_time(struct MPContext *mpctx, double pts) track->user_tid - 1); } - if (track->dec_sub) { + if (track->d_sub) { for (int order = 0; order < 2; order++) { - if (mpctx->d_sub[order] == track->dec_sub) { - mpctx->d_sub[order] = NULL; + struct track *cur = mpctx->current_track[order][STREAM_SUB]; + if (cur && cur->d_sub == track->d_sub) osd_set_sub(mpctx->osd, OSDTYPE_SUB + order, NULL); - } } - sub_destroy(track->dec_sub); - track->dec_sub = NULL; + sub_destroy(track->d_sub); + track->d_sub = NULL; } } } @@ -579,13 +577,10 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type clear_audio_output_buffers(mpctx); uninit_audio_chain(mpctx); uninit_audio_out(mpctx); - } else if (type == STREAM_SUB) { - uninit_sub(mpctx, 0); } - } else if (order == 1) { - if (type == STREAM_SUB) - uninit_sub(mpctx, 1); } + if (type == STREAM_SUB) + uninit_sub(mpctx, current); if (current) current->selected = false; @@ -609,7 +604,7 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type } else if (type == STREAM_AUDIO && order == 0) { reinit_audio_chain(mpctx); } else if (type == STREAM_SUB && order >= 0 && order <= 2) { - reinit_subs(mpctx, order); + reinit_sub(mpctx, track); } mp_notify(mpctx, MPV_EVENT_TRACK_SWITCHED, NULL); @@ -658,7 +653,7 @@ bool mp_remove_track(struct MPContext *mpctx, struct track *track) struct demuxer *d = track->demuxer; - sub_destroy(track->dec_sub); + sub_destroy(track->d_sub); int index = 0; while (index < mpctx->num_tracks && mpctx->tracks[index] != track) @@ -1095,8 +1090,6 @@ reopen_file: assert(mpctx->demuxer == NULL); assert(mpctx->d_audio == NULL); assert(mpctx->d_video == NULL); - assert(mpctx->d_sub[0] == NULL); - assert(mpctx->d_sub[1] == NULL); if (process_open_hooks(mpctx) < 0) goto terminate_playback; @@ -1197,8 +1190,7 @@ reopen_file: reinit_video_chain(mpctx); reinit_audio_chain(mpctx); - reinit_subs(mpctx, 0); - reinit_subs(mpctx, 1); + reinit_sub_all(mpctx); MP_VERBOSE(mpctx, "Starting playback...\n"); diff --git a/player/playloop.c b/player/playloop.c index 5226103733..174318e70e 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -239,8 +239,7 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek, if (timeline_switch_to_time(mpctx, seek.amount)) { reinit_video_chain(mpctx); reinit_audio_chain(mpctx); - reinit_subs(mpctx, 0); - reinit_subs(mpctx, 1); + reinit_sub_all(mpctx); } int demuxer_style = 0; diff --git a/player/sub.c b/player/sub.c index 0633ebaea1..6635ef98fb 100644 --- a/player/sub.c +++ b/player/sub.c @@ -38,43 +38,58 @@ #include "core.h" -static void reset_subtitles(struct MPContext *mpctx, int order) +// 0: primary sub, 1: secondary sub, -1: not selected +static int get_order(struct MPContext *mpctx, struct track *track) { - if (mpctx->d_sub[order]) - sub_reset(mpctx->d_sub[order]); + for (int n = 0; n < NUM_PTRACKS; n++) { + if (mpctx->current_track[n][STREAM_SUB] == track) + return n; + } + return -1; +} + +static void reset_subtitles(struct MPContext *mpctx, struct track *track) +{ + if (track->d_sub) + sub_reset(track->d_sub); term_osd_set_subs(mpctx, NULL); } void reset_subtitle_state(struct MPContext *mpctx) { - reset_subtitles(mpctx, 0); - reset_subtitles(mpctx, 1); + for (int n = 0; n < mpctx->num_tracks; n++) { + struct dec_sub *d_sub = mpctx->tracks[n]->d_sub; + if (d_sub) + sub_reset(d_sub); + } + term_osd_set_subs(mpctx, NULL); } -void uninit_sub(struct MPContext *mpctx, int order) +void uninit_sub(struct MPContext *mpctx, struct track *track) { - if (mpctx->d_sub[order]) { - reset_subtitles(mpctx, order); - sub_select(mpctx->d_sub[order], false); - mpctx->d_sub[order] = NULL; // not destroyed - osd_set_sub(mpctx->osd, OSDTYPE_SUB + order, NULL); + if (track && track->d_sub) { + reset_subtitles(mpctx, track); + sub_select(track->d_sub, false); + int order = get_order(mpctx, track); + if (order >= 0 && order <= 1) + osd_set_sub(mpctx->osd, OSDTYPE_SUB + order, NULL); reselect_demux_streams(mpctx); } } void uninit_sub_all(struct MPContext *mpctx) { - uninit_sub(mpctx, 0); - uninit_sub(mpctx, 1); + for (int n = 0; n < mpctx->num_tracks; n++) + uninit_sub(mpctx, mpctx->tracks[n]); } -static bool update_subtitle(struct MPContext *mpctx, double video_pts, int order) +static bool update_subtitle(struct MPContext *mpctx, double video_pts, + struct track *track) { struct MPOpts *opts = mpctx->opts; - struct track *track = mpctx->current_track[order][STREAM_SUB]; - struct dec_sub *dec_sub = mpctx->d_sub[order]; + struct dec_sub *dec_sub = track ? track->d_sub : NULL; - if (!track || !dec_sub || video_pts == MP_NOPTS_VALUE) + if (!dec_sub || video_pts == MP_NOPTS_VALUE) return true; if (mpctx->vo_chain) { @@ -91,7 +106,7 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts, int order } // Handle displaying subtitles on terminal; never done for secondary subs - if (order == 0 && !mpctx->video_out) + if (mpctx->current_track[0][STREAM_SUB] == track && !mpctx->video_out) term_osd_set_subs(mpctx, sub_get_text(dec_sub, video_pts)); return true; @@ -101,34 +116,36 @@ static bool update_subtitle(struct MPContext *mpctx, double video_pts, int order // should wait for new demuxer data, and then should retry. bool update_subtitles(struct MPContext *mpctx, double video_pts) { - return update_subtitle(mpctx, video_pts, 0) & - update_subtitle(mpctx, video_pts, 1); + bool ok = true; + for (int n = 0; n < NUM_PTRACKS; n++) + ok &= update_subtitle(mpctx, video_pts, mpctx->current_track[n][STREAM_SUB]); + return ok; } static bool init_subdec(struct MPContext *mpctx, struct track *track) { struct MPOpts *opts = mpctx->opts; - assert(!track->dec_sub); + assert(!track->d_sub); if (!track->demuxer || !track->stream) return false; - track->dec_sub = sub_create(mpctx->global, track->demuxer, track->stream); - if (!track->dec_sub) + track->d_sub = sub_create(mpctx->global, track->demuxer, track->stream); + if (!track->d_sub) return false; struct mp_codec_params *v_c = mpctx->d_video ? mpctx->d_video->header->codec : NULL; double fps = v_c ? v_c->fps : 25; - sub_control(track->dec_sub, SD_CTRL_SET_VIDEO_DEF_FPS, &fps); + sub_control(track->d_sub, SD_CTRL_SET_VIDEO_DEF_FPS, &fps); // Don't do this if the file has video/audio streams. Don't do it even // if it has only sub streams, because reading packets will change the // demuxer position. if (track->is_external && !opts->sub_clear_on_seek) { demux_seek(track->demuxer, 0, SEEK_ABSOLUTE); - track->preloaded = sub_read_all_packets(track->dec_sub); + track->preloaded = sub_read_all_packets(track->d_sub); if (track->preloaded) demux_stop_thread(track->demuxer); } @@ -136,22 +153,25 @@ static bool init_subdec(struct MPContext *mpctx, struct track *track) return true; } -void reinit_subs(struct MPContext *mpctx, int order) +void reinit_sub(struct MPContext *mpctx, struct track *track) { - assert(!mpctx->d_sub[order]); - - struct track *track = mpctx->current_track[order][STREAM_SUB]; - if (!track) + if (!track || !track->stream || track->stream->type != STREAM_SUB) return; - if (!track->dec_sub && !init_subdec(mpctx, track)) { + if (!track->d_sub && !init_subdec(mpctx, track)) { error_on_track(mpctx, track); return; } - sub_select(track->dec_sub, true); - osd_set_sub(mpctx->osd, OSDTYPE_SUB + order, track->dec_sub); - sub_control(track->dec_sub, SD_CTRL_SET_TOP, &(bool){!!order}); + sub_select(track->d_sub, true); + int order = get_order(mpctx, track); + if (order >= 0 && order <= 1) + osd_set_sub(mpctx->osd, OSDTYPE_SUB + order, track->d_sub); + sub_control(track->d_sub, SD_CTRL_SET_TOP, &(bool){!!order}); +} - mpctx->d_sub[order] = track->dec_sub; +void reinit_sub_all(struct MPContext *mpctx) +{ + for (int n = 0; n < NUM_PTRACKS; n++) + reinit_sub(mpctx, mpctx->current_track[n][STREAM_SUB]); } -- cgit v1.2.3