sub: pass all attachments to the subtitle decoder

Commit 8d4a179c made subtitle decoders pick up fonts strictly from the
same source file (i.e. the same demuxer).

It breaks some fucked up use-case, and 2 people on this earth complained
about the change because of this. Add it back.

This copies all attached fonts on each subtitle init. I considered
converting attachments to use refcounting, but it'd probably be much
more complex.

Since it's slightly harder to get a list of active demuxers with
duplicate removed, the prev_demuxer variable serves as a hack to achieve
almost the same thing, except in weird corner cases. (In which fonts
could be added twice.)
This commit is contained in:
wm4 2016-03-03 18:48:56 +01:00
parent a6f8a6977e
commit 3f60548df4
5 changed files with 44 additions and 14 deletions

View File

@ -129,6 +129,29 @@ bool update_subtitles(struct MPContext *mpctx, double video_pts)
return ok;
}
static struct attachment_list *get_all_attachments(struct MPContext *mpctx)
{
struct attachment_list *list = talloc_zero(NULL, struct attachment_list);
struct demuxer *prev_demuxer = NULL;
for (int n = 0; n < mpctx->num_tracks; n++) {
struct track *t = mpctx->tracks[n];
if (!t->demuxer || prev_demuxer == t->demuxer)
continue;
prev_demuxer = t->demuxer;
for (int i = 0; i < t->demuxer->num_attachments; i++) {
struct demux_attachment *att = &t->demuxer->attachments[i];
struct demux_attachment copy = {
.name = talloc_strdup(list, att->name),
.type = talloc_strdup(list, att->type),
.data = talloc_memdup(list, att->data, att->data_size),
.data_size = att->data_size,
};
MP_TARRAY_APPEND(list, list->entries, list->num_entries, copy);
}
}
return list;
}
static bool init_subdec(struct MPContext *mpctx, struct track *track)
{
assert(!track->d_sub);
@ -136,7 +159,8 @@ 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->demuxer, track->stream);
track->d_sub = sub_create(mpctx->global, track->stream,
get_all_attachments(mpctx));
if (!track->d_sub)
return false;

View File

@ -49,7 +49,7 @@ struct dec_sub {
struct mpv_global *global;
struct MPOpts *opts;
struct demuxer *demuxer;
struct attachment_list *attachments;
struct sh_stream *sh;
double last_pkt_pts;
@ -94,7 +94,7 @@ static struct sd *init_decoder(struct dec_sub *sub)
.log = mp_log_new(sd, sub->log, driver->name),
.opts = sub->opts,
.driver = driver,
.demuxer = sub->demuxer,
.attachments = sub->attachments,
.codec = sub->codec,
};
@ -112,10 +112,12 @@ static struct sd *init_decoder(struct dec_sub *sub)
// Thread-safety of the returned object: all functions are thread-safe,
// except sub_get_bitmaps() and sub_get_text(). Decoder backends (sd_*)
// do not need to acquire locks.
struct dec_sub *sub_create(struct mpv_global *global, struct demuxer *demuxer,
struct sh_stream *sh)
// Ownership of attachments goes to the caller, and is released with
// talloc_free() (even on failure).
struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
struct attachment_list *attachments)
{
assert(demuxer && sh && sh->type == STREAM_SUB);
assert(sh && sh->type == STREAM_SUB);
struct dec_sub *sub = talloc(NULL, struct dec_sub);
*sub = (struct dec_sub){
@ -124,7 +126,7 @@ struct dec_sub *sub_create(struct mpv_global *global, struct demuxer *demuxer,
.opts = global->opts,
.sh = sh,
.codec = sh->codec,
.demuxer = demuxer,
.attachments = talloc_steal(sub, attachments),
.last_pkt_pts = MP_NOPTS_VALUE,
.last_vo_pts = MP_NOPTS_VALUE,
.start = MP_NOPTS_VALUE,

View File

@ -6,7 +6,6 @@
#include "osd.h"
struct demuxer;
struct sh_stream;
struct mpv_global;
struct demux_packet;
@ -22,8 +21,13 @@ enum sd_ctrl {
SD_CTRL_SET_VIDEO_DEF_FPS,
};
struct dec_sub *sub_create(struct mpv_global *global, struct demuxer *demuxer,
struct sh_stream *sh);
struct attachment_list {
struct demux_attachment *entries;
int num_entries;
};
struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
struct attachment_list *attachments);
void sub_destroy(struct dec_sub *sub);
void sub_lock(struct dec_sub *sub);
void sub_unlock(struct dec_sub *sub);

View File

@ -17,7 +17,7 @@ struct sd {
const struct sd_functions *driver;
void *priv;
struct demuxer *demuxer;
struct attachment_list *attachments;
struct mp_codec_params *codec;
};

View File

@ -117,10 +117,10 @@ static void add_subtitle_fonts(struct sd *sd)
{
struct sd_ass_priv *ctx = sd->priv;
struct MPOpts *opts = sd->opts;
if (!opts->ass_enabled || !sd->demuxer)
if (!opts->ass_enabled || !sd->attachments)
return;
for (int i = 0; i < sd->demuxer->num_attachments; i++) {
struct demux_attachment *f = &sd->demuxer->attachments[i];
for (int i = 0; i < sd->attachments->num_entries; i++) {
struct demux_attachment *f = &sd->attachments->entries[i];
if (opts->use_embedded_fonts && attachment_is_font(sd->log, f))
ass_add_font(ctx->ass_library, f->name, f->data, f->data_size);
}