sub: rewrite auto-forced-only support

- No longer has a fake "option" used only internally (which didn't always get propagated properly)
- Always overrideable during playback
This commit is contained in:
rcombs 2021-05-27 00:56:41 -05:00 committed by sfan5
parent 991a2f79ce
commit ba7cc07106
10 changed files with 32 additions and 14 deletions

View File

@ -2865,6 +2865,10 @@ Property list
``yes``/true if the track has the forced flag set in the file,
``no``/false or unavailable otherwise.
``track-list/N/auto-forced-only``
``yes``/true if the track was autoselected in forced-only mode,
``no``/false or unavailable otherwise.
``track-list/N/codec``
The codec name used by this track, for example ``h264``. Unavailable
in some rare cases.

View File

@ -82,7 +82,6 @@ struct mp_subtitle_opts {
float sub_fps;
float sub_speed;
int forced_subs_only;
int forced_subs_only_current;
bool stretch_dvd_subs;
bool stretch_image_subs;
bool image_subs_video_res;

View File

@ -137,6 +137,7 @@ struct track {
// Current subtitle state (or cached state if selected==false).
struct dec_sub *d_sub;
bool forced_only_def;
// Current decoding state (NULL if selected==false)
struct mp_decoder_wrapper *dec;

View File

@ -591,6 +591,7 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
struct track *forced_pick = NULL;
for (int n = 0; n < mpctx->num_tracks; n++) {
struct track *track = mpctx->tracks[n];
track->forced_only_def = false;
if (track->type != type)
continue;
if (track->user_tid == tid) {
@ -639,9 +640,16 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
pick = NULL;
if (pick && !opts->autoload_files && pick->is_external)
pick = NULL;
if (pick && type == STREAM_SUB && prefer_forced && !pick->forced_track &&
opts->subs_rend->forced_subs_only == -1)
opts->subs_rend->forced_subs_only_current = 1;
if (pick && type == STREAM_SUB && prefer_forced && !pick->forced_track) {
// If the codec is DVD or PGS, we can display it in forced-only mode.
// This isn't really meaningful for other codecs, so we'll just pick nothing.
if (pick->stream &&
!strcmp(pick->stream->codec->codec, "dvd_subtitle") ||
!strcmp(pick->stream->codec->codec, "hdmv_pgs_subtitle"))
pick->forced_only_def = 1;
else
pick = NULL;
}
cleanup:
talloc_free(langs);
return pick;
@ -1639,8 +1647,6 @@ static void play_current_file(struct MPContext *mpctx)
if (reinit_complex_filters(mpctx, false) < 0)
goto terminate_playback;
opts->subs_rend->forced_subs_only_current = (opts->subs_rend->forced_subs_only == 1) ? 1 : 0;
for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
for (int i = 0; i < num_ptracks[t]; i++) {
struct track *sel = NULL;

View File

@ -169,7 +169,7 @@ static bool init_subdec(struct MPContext *mpctx, struct track *track)
if (!track->demuxer || !track->stream)
return false;
track->d_sub = sub_create(mpctx->global, track->stream,
track->d_sub = sub_create(mpctx->global, track,
get_all_attachments(mpctx),
get_order(mpctx, track));
if (!track->d_sub)

View File

@ -69,6 +69,8 @@ struct dec_sub {
struct sd *sd;
struct demux_packet *new_segment;
bool forced_only_def;
};
static void update_subtitle_speed(struct dec_sub *sub)
@ -142,6 +144,7 @@ static struct sd *init_decoder(struct dec_sub *sub)
.attachments = sub->attachments,
.codec = sub->codec,
.preload_ok = true,
.forced_only_def = sub->forced_only_def,
};
if (sd->driver->init(sd) >= 0)
@ -160,18 +163,18 @@ static struct sd *init_decoder(struct dec_sub *sub)
// do not need to acquire locks.
// Ownership of attachments goes to the callee, and is released with
// talloc_free() (even on failure).
struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
struct dec_sub *sub_create(struct mpv_global *global, struct track *track,
struct attachment_list *attachments, int order)
{
assert(sh && sh->type == STREAM_SUB);
assert(track->stream && track->stream->type == STREAM_SUB);
struct dec_sub *sub = talloc(NULL, struct dec_sub);
*sub = (struct dec_sub){
.log = mp_log_new(sub, global->log, "sub"),
.global = global,
.opts_cache = m_config_cache_alloc(sub, global, &mp_subtitle_sub_opts),
.sh = sh,
.codec = sh->codec,
.sh = track->stream,
.codec = track->stream->codec,
.attachments = talloc_steal(sub, attachments),
.play_dir = 1,
.order = order,
@ -179,6 +182,7 @@ struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
.last_vo_pts = MP_NOPTS_VALUE,
.start = MP_NOPTS_VALUE,
.end = MP_NOPTS_VALUE,
.forced_only_def = track->forced_only_def,
};
sub->opts = sub->opts_cache->opts;
mpthread_mutex_init_recursive(&sub->lock);

View File

@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "player/core.h"
#include "osd.h"
struct sh_stream;
@ -36,7 +37,7 @@ struct attachment_list {
int num_entries;
};
struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
struct dec_sub *sub_create(struct mpv_global *global, struct track *track,
struct attachment_list *attachments, int order);
void sub_destroy(struct dec_sub *sub);

View File

@ -24,6 +24,8 @@ struct sd {
// Set to false as soon as the decoder discards old subtitle events.
// (only needed if sd_functions.accept_packets_in_advance == false)
bool preload_ok;
bool forced_only_def;
};
struct sd_functions {

View File

@ -543,7 +543,7 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim,
// Currently no supported text sub formats support a distinction between forced
// and unforced lines, so we just assume everything's unforced and discard everything.
// If we ever see a format that makes this distinction, we can add support here.
if (opts->forced_subs_only_current)
if (opts->forced_subs_only == 1 || (opts->forced_subs_only && sd->forced_only_def))
goto done;
double scale = dim.display_par;

View File

@ -195,7 +195,8 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
MP_ERR(sd, "unsupported subtitle type from libavcodec\n");
continue;
}
if (!(r->flags & AV_SUBTITLE_FLAG_FORCED) && opts->forced_subs_only_current)
if (!(r->flags & AV_SUBTITLE_FLAG_FORCED) && (opts->forced_subs_only == 1 ||
(opts->forced_subs_only && sd->forced_only_def)))
continue;
if (r->w <= 0 || r->h <= 0)
continue;