summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-12-24 17:46:14 +0100
committerwm4 <wm4@nowhere>2013-12-24 17:46:14 +0100
commit3720b3f17d4951ab839418b5cbfd1a85eb74adba (patch)
tree819b311b4c224ba2fd3dcd0efe8008a83f2cc938 /player
parent9292f537d661af16321fd35eb0016e830594863b (diff)
downloadmpv-3720b3f17d4951ab839418b5cbfd1a85eb74adba.tar.bz2
mpv-3720b3f17d4951ab839418b5cbfd1a85eb74adba.tar.xz
player: add --secondary-sid for displaying a second subtitle stream
This is relatively hacky, but it's Christmas, so it's ok. This does two things: 1. allow selecting two subtitle tracks, and 2. include a hack that renders the second subtitle always as toptitle. See manpage additions how to use this.
Diffstat (limited to 'player')
-rw-r--r--player/command.c49
-rw-r--r--player/core.h7
-rw-r--r--player/dvdnav.c4
-rw-r--r--player/loadfile.c51
-rw-r--r--player/osd.c4
-rw-r--r--player/playloop.c6
-rw-r--r--player/sub.c125
-rw-r--r--player/video.c3
8 files changed, 166 insertions, 83 deletions
diff --git a/player/command.c b/player/command.c
index 3d15d96676..e59a2d50e8 100644
--- a/player/command.c
+++ b/player/command.c
@@ -980,14 +980,23 @@ static int mp_property_balance(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED;
}
-static struct track* track_next(struct MPContext *mpctx, enum stream_type type,
- int direction, struct track *track)
+static struct track* track_next(struct MPContext *mpctx, int order,
+ enum stream_type type, int direction,
+ struct track *track)
{
assert(direction == -1 || direction == +1);
struct track *prev = NULL, *next = NULL;
bool seen = track == NULL;
for (int n = 0; n < mpctx->num_tracks; n++) {
struct track *cur = mpctx->tracks[n];
+ // One track can be selected only one time - pretend already selected
+ // tracks don't exist.
+ for (int r = 0; r < NUM_PTRACKS; r++) {
+ if (r != order && mpctx->current_track[r][type] == cur)
+ cur = NULL;
+ }
+ if (!cur)
+ continue;
if (cur->type == type) {
if (cur == track) {
seen = true;
@@ -1005,11 +1014,12 @@ static struct track* track_next(struct MPContext *mpctx, enum stream_type type,
}
static int property_switch_track(m_option_t *prop, int action, void *arg,
- MPContext *mpctx, enum stream_type type)
+ MPContext *mpctx, int order,
+ enum stream_type type)
{
if (!mpctx->num_sources)
return M_PROPERTY_UNAVAILABLE;
- struct track *track = mpctx->current_track[0][type];
+ struct track *track = mpctx->current_track[order][type];
switch (action) {
case M_PROPERTY_GET:
@@ -1034,12 +1044,13 @@ static int property_switch_track(m_option_t *prop, int action, void *arg,
case M_PROPERTY_SWITCH: {
struct m_property_switch_arg *sarg = arg;
- mp_switch_track(mpctx, type,
- track_next(mpctx, type, sarg->inc >= 0 ? +1 : -1, track));
+ mp_switch_track_n(mpctx, order, type,
+ track_next(mpctx, order, type, sarg->inc >= 0 ? +1 : -1, track));
return M_PROPERTY_OK;
}
case M_PROPERTY_SET:
- mp_switch_track(mpctx, type, mp_track_by_tid(mpctx, type, *(int *)arg));
+ track = mp_track_by_tid(mpctx, type, *(int *)arg);
+ mp_switch_track_n(mpctx, order, type, track);
return M_PROPERTY_OK;
}
return mp_property_generic_option(prop, action, arg, mpctx);
@@ -1102,14 +1113,14 @@ static int property_list_tracks(m_option_t *prop, int action, void *arg,
static int mp_property_audio(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return property_switch_track(prop, action, arg, mpctx, STREAM_AUDIO);
+ return property_switch_track(prop, action, arg, mpctx, 0, STREAM_AUDIO);
}
/// Selected video id (RW)
static int mp_property_video(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return property_switch_track(prop, action, arg, mpctx, STREAM_VIDEO);
+ return property_switch_track(prop, action, arg, mpctx, 0, STREAM_VIDEO);
}
static struct track *find_track_by_demuxer_id(MPContext *mpctx,
@@ -1623,7 +1634,13 @@ static int property_osd_helper(m_option_t *prop, int action, void *arg,
static int mp_property_sub(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- return property_switch_track(prop, action, arg, mpctx, STREAM_SUB);
+ return property_switch_track(prop, action, arg, mpctx, 0, STREAM_SUB);
+}
+
+static int mp_property_sub2(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ return property_switch_track(prop, action, arg, mpctx, 1, STREAM_SUB);
}
/// Subtitle delay (RW)
@@ -1997,6 +2014,7 @@ static const m_option_t mp_properties[] = {
// Subs
M_OPTION_PROPERTY_CUSTOM("sid", mp_property_sub),
+ M_OPTION_PROPERTY_CUSTOM("secondary-sid", mp_property_sub2),
M_OPTION_PROPERTY_CUSTOM("sub-delay", mp_property_sub_delay),
M_OPTION_PROPERTY_CUSTOM("sub-pos", mp_property_sub_pos),
M_OPTION_PROPERTY_CUSTOM("sub-visibility", property_osd_helper),
@@ -2109,6 +2127,7 @@ static struct property_osd_display {
{ "angle", "Angle" },
// subs
{ "sub", "Subtitles" },
+ { "secondary-sid", "Secondary subtitles" },
{ "sub-pos", "Sub position" },
{ "sub-delay", "Sub delay", .osd_id = OSD_MSG_SUB_DELAY },
{ "sub-visibility", "Subtitles" },
@@ -2714,12 +2733,13 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
}
case MP_CMD_SUB_STEP:
- case MP_CMD_SUB_SEEK:
- if (mpctx->osd->dec_sub) {
+ case MP_CMD_SUB_SEEK: {
+ struct osd_object *obj = mpctx->osd->objs[OSDTYPE_SUB];
+ if (obj->dec_sub) {
double a[2];
- a[0] = mpctx->video_pts - mpctx->osd->video_offset + opts->sub_delay;
+ a[0] = mpctx->video_pts - obj->video_offset + opts->sub_delay;
a[1] = cmd->args[0].v.i;
- if (sub_control(mpctx->osd->dec_sub, SD_CTRL_SUB_STEP, a) > 0) {
+ if (sub_control(obj->dec_sub, SD_CTRL_SUB_STEP, a) > 0) {
if (cmd->id == MP_CMD_SUB_STEP) {
opts->sub_delay += a[0];
osd_changed_all(mpctx->osd);
@@ -2742,6 +2762,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
}
}
break;
+ }
case MP_CMD_OSD: {
int v = cmd->args[0].v.i;
diff --git a/player/core.h b/player/core.h
index cad18a6b36..c016dcf4f7 100644
--- a/player/core.h
+++ b/player/core.h
@@ -35,6 +35,7 @@
#define INITIALIZED_ACODEC 1024
#define INITIALIZED_VCODEC 2048
#define INITIALIZED_SUB 4096
+#define INITIALIZED_SUB2 8192
#define INITIALIZED_ALL 0xFFFF
@@ -208,7 +209,7 @@ typedef struct MPContext {
struct dec_video *d_video;
struct dec_audio *d_audio;
- struct dec_sub *d_sub;
+ 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.
@@ -439,9 +440,9 @@ void handle_force_window(struct MPContext *mpctx, bool reconfig);
void add_frame_pts(struct MPContext *mpctx, double pts);
// sub.c
-void reset_subtitles(struct MPContext *mpctx);
+void reset_subtitles(struct MPContext *mpctx, int order);
void uninit_subs(struct demuxer *demuxer);
-void reinit_subs(struct MPContext *mpctx);
+void reinit_subs(struct MPContext *mpctx, int order);
void update_osd_msg(struct MPContext *mpctx);
void update_subtitles(struct MPContext *mpctx);
diff --git a/player/dvdnav.c b/player/dvdnav.c
index e90a65e035..bc14e7c35f 100644
--- a/player/dvdnav.c
+++ b/player/dvdnav.c
@@ -222,8 +222,8 @@ void mp_nav_get_highlight(struct osd_state *osd, struct mp_osd_res res,
nav->hi_elem = sub;
int sizes[2] = {0};
- if (mpctx->d_sub)
- sub_control(mpctx->d_sub, SD_CTRL_GET_RESOLUTION, sizes);
+ if (mpctx->d_sub[0])
+ sub_control(mpctx->d_sub[0], SD_CTRL_GET_RESOLUTION, sizes);
if (sizes[0] < 1 || sizes[1] < 1) {
struct mp_image_params vid = {0};
if (mpctx->d_video)
diff --git a/player/loadfile.c b/player/loadfile.c
index 8bf29f22f3..99b669f109 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -62,6 +62,16 @@
#include "stream/dvbin.h"
#endif
+static void uninit_sub(struct MPContext *mpctx, int order)
+{
+ if (mpctx->d_sub[order])
+ sub_reset(mpctx->d_sub[order]);
+ mpctx->d_sub[order] = NULL; // Note: not free'd.
+ mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB]->dec_sub = NULL;
+ reset_subtitles(mpctx, order);
+ reselect_demux_streams(mpctx);
+}
+
void uninit_player(struct MPContext *mpctx, unsigned int mask)
{
struct MPOpts *opts = mpctx->opts;
@@ -80,12 +90,11 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_SUB) {
mpctx->initialized_flags &= ~INITIALIZED_SUB;
- if (mpctx->d_sub)
- sub_reset(mpctx->d_sub);
- mpctx->d_sub = NULL; // Note: not free'd.
- mpctx->osd->dec_sub = NULL;
- reset_subtitles(mpctx);
- reselect_demux_streams(mpctx);
+ uninit_sub(mpctx, 0);
+ }
+ if (mask & INITIALIZED_SUB2) {
+ mpctx->initialized_flags &= ~INITIALIZED_SUB2;
+ uninit_sub(mpctx, 1);
}
if (mask & INITIALIZED_LIBASS) {
@@ -110,7 +119,8 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_DEMUXER) {
mpctx->initialized_flags &= ~INITIALIZED_DEMUXER;
assert(!(mpctx->initialized_flags &
- (INITIALIZED_VCODEC | INITIALIZED_ACODEC | INITIALIZED_SUB)));
+ (INITIALIZED_VCODEC | INITIALIZED_ACODEC |
+ INITIALIZED_SUB2 | INITIALIZED_SUB)));
for (int i = 0; i < mpctx->num_tracks; i++) {
talloc_free(mpctx->tracks[i]);
}
@@ -119,7 +129,8 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
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);
+ 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]);
@@ -324,7 +335,7 @@ 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);
+ 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);
mpctx->stop_play = orig_stop_play;
mpctx->demuxer = n->source;
@@ -405,8 +416,10 @@ static struct track *add_stream_track(struct MPContext *mpctx,
track->demuxer_id = stream->demuxer_id;
// Initialize lazily selected track
demuxer_select_track(track->demuxer, stream, track->selected);
- if (track->selected)
- reinit_subs(mpctx);
+ if (mpctx->current_track[0][STREAM_SUB] == track)
+ reinit_subs(mpctx, 0);
+ if (mpctx->current_track[1][STREAM_SUB] == track)
+ reinit_subs(mpctx, 1);
return track;
}
}
@@ -605,6 +618,9 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type
} else if (type == STREAM_SUB) {
uninit_player(mpctx, INITIALIZED_SUB);
}
+ } else if (order == 1) {
+ if (type == STREAM_SUB)
+ uninit_player(mpctx, INITIALIZED_SUB2);
}
if (current)
@@ -631,9 +647,14 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type
mp_notify_property(mpctx, "aid");
} else if (type == STREAM_SUB) {
mpctx->opts->sub_id = user_tid;
- reinit_subs(mpctx);
+ reinit_subs(mpctx, 0);
mp_notify_property(mpctx, "sid");
}
+ } else if (order == 1) {
+ if (type == STREAM_SUB) {
+ mpctx->opts->sub2_id = user_tid;
+ reinit_subs(mpctx, 1);
+ }
}
talloc_free(mpctx->track_layout_hash);
@@ -1048,7 +1069,8 @@ static void play_current_file(struct MPContext *mpctx)
assert(mpctx->demuxer == NULL);
assert(mpctx->d_audio == NULL);
assert(mpctx->d_video == NULL);
- assert(mpctx->d_sub == NULL);
+ assert(mpctx->d_sub[0] == NULL);
+ assert(mpctx->d_sub[1] == NULL);
char *stream_filename = mpctx->filename;
mpctx->resolve_result = resolve_url(stream_filename, mpctx->global);
@@ -1189,7 +1211,8 @@ goto_reopen_demuxer: ;
reinit_video_chain(mpctx);
reinit_audio_chain(mpctx);
- reinit_subs(mpctx);
+ reinit_subs(mpctx, 0);
+ reinit_subs(mpctx, 1);
//==================== START PLAYING =======================
diff --git a/player/osd.c b/player/osd.c
index 607af6714e..d1af1a6e65 100644
--- a/player/osd.c
+++ b/player/osd.c
@@ -373,8 +373,8 @@ void set_osd_subtitle(struct MPContext *mpctx, const char *text)
{
if (!text)
text = "";
- if (strcmp(mpctx->osd->sub_text, text) != 0) {
- osd_set_sub(mpctx->osd, text);
+ if (strcmp(mpctx->osd->objs[OSDTYPE_SUB]->sub_text, text) != 0) {
+ osd_set_sub(mpctx->osd, mpctx->osd->objs[OSDTYPE_SUB], text);
if (!mpctx->video_out) {
rm_osd_msg(mpctx, OSD_MSG_SUB_BASE);
if (text && text[0])
diff --git a/player/playloop.c b/player/playloop.c
index dcbc1de9ba..6359803fcf 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -181,7 +181,8 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao)
clear_audio_output_buffers(mpctx);
}
- reset_subtitles(mpctx);
+ reset_subtitles(mpctx, 0);
+ reset_subtitles(mpctx, 1);
mpctx->video_pts = MP_NOPTS_VALUE;
mpctx->video_next_pts = MP_NOPTS_VALUE;
@@ -271,7 +272,8 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
if (need_reset) {
reinit_video_chain(mpctx);
reinit_audio_chain(mpctx);
- reinit_subs(mpctx);
+ reinit_subs(mpctx, 0);
+ reinit_subs(mpctx, 1);
}
int demuxer_style = 0;
diff --git a/player/sub.c b/player/sub.c
index 3593bab710..cc8f89a531 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -66,23 +66,32 @@ static bool is_interleaved(struct MPContext *mpctx, struct track *track)
return false;
}
-void reset_subtitles(struct MPContext *mpctx)
+void reset_subtitles(struct MPContext *mpctx, int order)
{
- if (mpctx->d_sub)
- sub_reset(mpctx->d_sub);
+ struct osd_object *osd_obj =
+ mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB];
+ if (mpctx->d_sub[order])
+ sub_reset(mpctx->d_sub[order]);
set_osd_subtitle(mpctx, NULL);
- osd_changed(mpctx->osd, OSDTYPE_SUB);
+ osd_set_sub(mpctx->osd, osd_obj, NULL);
}
-void update_subtitles(struct MPContext *mpctx)
+static void update_subtitle(struct MPContext *mpctx, int order)
{
struct MPOpts *opts = mpctx->opts;
- if (!(mpctx->initialized_flags & INITIALIZED_SUB))
- return;
+ if (order == 0) {
+ if (!(mpctx->initialized_flags & INITIALIZED_SUB))
+ return;
+ } else {
+ if (!(mpctx->initialized_flags & INITIALIZED_SUB2))
+ return;
+ }
- struct track *track = mpctx->current_track[0][STREAM_SUB];
- struct dec_sub *dec_sub = mpctx->d_sub;
+ struct track *track = mpctx->current_track[order][STREAM_SUB];
+ struct dec_sub *dec_sub = mpctx->d_sub[order];
assert(track && dec_sub);
+ struct osd_object *osd_obj
+ = mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB];
if (mpctx->d_video) {
struct mp_image_params params = mpctx->d_video->vf_input;
@@ -90,9 +99,9 @@ void update_subtitles(struct MPContext *mpctx)
sub_control(dec_sub, SD_CTRL_SET_VIDEO_PARAMS, &params);
}
- mpctx->osd->video_offset = track->under_timeline ? mpctx->video_offset : 0;
+ osd_obj->video_offset = track->under_timeline ? mpctx->video_offset : 0;
- double refpts_s = mpctx->playback_pts - mpctx->osd->video_offset;
+ double refpts_s = mpctx->playback_pts - osd_obj->video_offset;
double curpts_s = refpts_s + opts->sub_delay;
if (!track->preloaded && track->stream) {
@@ -125,8 +134,19 @@ void update_subtitles(struct MPContext *mpctx)
}
}
- if (!mpctx->osd->render_bitmap_subs || !mpctx->video_out)
- set_osd_subtitle(mpctx, sub_get_text(dec_sub, curpts_s));
+ // Handle displaying subtitles on terminal; never done for secondary subs
+ if (order == 0) {
+ if (!osd_obj->render_bitmap_subs || !mpctx->video_out)
+ set_osd_subtitle(mpctx, sub_get_text(dec_sub, curpts_s));
+ } else if (order == 1) {
+ osd_set_sub(mpctx->osd, osd_obj, sub_get_text(dec_sub, curpts_s));
+ }
+}
+
+void update_subtitles(struct MPContext *mpctx)
+{
+ update_subtitle(mpctx, 0);
+ update_subtitle(mpctx, 1);
}
static void set_dvdsub_fake_extradata(struct dec_sub *dec_sub, struct stream *st,
@@ -169,12 +189,42 @@ static void set_dvdsub_fake_extradata(struct dec_sub *dec_sub, struct stream *st
talloc_free(s);
}
-void reinit_subs(struct MPContext *mpctx)
+static void reinit_subdec(struct MPContext *mpctx, struct track *track,
+ struct dec_sub *dec_sub)
+{
+ if (sub_is_initialized(dec_sub))
+ return;
+
+ struct sh_video *sh_video =
+ mpctx->d_video ? mpctx->d_video->header->video : NULL;
+ int w = sh_video ? sh_video->disp_w : 0;
+ int h = sh_video ? sh_video->disp_h : 0;
+ float fps = sh_video ? sh_video->fps : 25;
+
+ set_dvdsub_fake_extradata(dec_sub, track->demuxer->stream, w, h);
+ sub_set_video_res(dec_sub, w, h);
+ sub_set_video_fps(dec_sub, fps);
+ sub_set_ass_renderer(dec_sub, mpctx->ass_library, mpctx->ass_renderer);
+ sub_init_from_sh(dec_sub, track->stream);
+
+ // 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->preloaded && track->is_external) {
+ demux_seek(track->demuxer, 0, SEEK_ABSOLUTE);
+ track->preloaded = sub_read_all_packets(dec_sub, track->stream);
+ }
+}
+
+void reinit_subs(struct MPContext *mpctx, int order)
{
struct MPOpts *opts = mpctx->opts;
- struct track *track = mpctx->current_track[0][STREAM_SUB];
+ struct track *track = mpctx->current_track[order][STREAM_SUB];
+ struct osd_object *osd_obj =
+ mpctx->osd->objs[order ? OSDTYPE_SUB2 : OSDTYPE_SUB];
+ int init_flag = order ? INITIALIZED_SUB2 : INITIALIZED_SUB;
- assert(!(mpctx->initialized_flags & INITIALIZED_SUB));
+ assert(!(mpctx->initialized_flags & init_flag));
struct sh_stream *sh = init_demux_stream(mpctx, track);
@@ -184,48 +234,33 @@ void reinit_subs(struct MPContext *mpctx)
return;
if (!sh->sub->dec_sub) {
- assert(!mpctx->d_sub);
+ assert(!mpctx->d_sub[order]);
sh->sub->dec_sub = sub_create(mpctx->global);
}
- assert(!mpctx->d_sub || sh->sub->dec_sub == mpctx->d_sub);
+ 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 = sh->sub->dec_sub;
+ mpctx->d_sub[order] = sh->sub->dec_sub;
- mpctx->initialized_flags |= INITIALIZED_SUB;
+ mpctx->initialized_flags |= init_flag;
- struct dec_sub *dec_sub = mpctx->d_sub;
+ struct dec_sub *dec_sub = mpctx->d_sub[order];
assert(dec_sub);
- if (!sub_is_initialized(dec_sub)) {
- struct sh_video *sh_video =
- mpctx->d_video ? mpctx->d_video->header->video : NULL;
- int w = sh_video ? sh_video->disp_w : 0;
- int h = sh_video ? sh_video->disp_h : 0;
- float fps = sh_video ? sh_video->fps : 25;
-
- set_dvdsub_fake_extradata(dec_sub, track->demuxer->stream, w, h);
- sub_set_video_res(dec_sub, w, h);
- sub_set_video_fps(dec_sub, fps);
- sub_set_ass_renderer(dec_sub, mpctx->ass_library, mpctx->ass_renderer);
- sub_init_from_sh(dec_sub, sh);
-
- // 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->preloaded && track->is_external) {
- demux_seek(track->demuxer, 0, SEEK_ABSOLUTE);
- track->preloaded = sub_read_all_packets(dec_sub, sh);
- }
- }
+ reinit_subdec(mpctx, track, dec_sub);
- mpctx->osd->dec_sub = dec_sub;
+ osd_obj->dec_sub = dec_sub;
// Decides whether to use OSD path or normal subtitle rendering path.
- mpctx->osd->render_bitmap_subs =
+ osd_obj->render_bitmap_subs =
opts->ass_enabled || !sub_has_get_text(dec_sub);
- reset_subtitles(mpctx);
+ // Secondary subs are rendered with the "text" renderer to transform them
+ // to toptitles.
+ if (order == 1 && sub_has_get_text(dec_sub))
+ osd_obj->render_bitmap_subs = false;
+
+ reset_subtitles(mpctx, order);
}
diff --git a/player/video.c b/player/video.c
index 9df3caa940..039248c1d0 100644
--- a/player/video.c
+++ b/player/video.c
@@ -199,7 +199,8 @@ int reinit_video_chain(struct MPContext *mpctx)
mpctx->vo_pts_history_seek_ts++;
vo_seek_reset(mpctx->video_out);
- reset_subtitles(mpctx);
+ reset_subtitles(mpctx, 0);
+ reset_subtitles(mpctx, 1);
if (opts->force_fps) {
d_video->fps = opts->force_fps;