diff options
author | wm4 <wm4@nowhere> | 2014-10-03 22:32:16 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-10-03 23:10:18 +0200 |
commit | cc9973f4e0268bc17cf95ec39af194d0136e0c0d (patch) | |
tree | e0d65df5854f473ccc31ae13580ce64ec2b0d7db /player/sub.c | |
parent | e64ce83182db230215ab547386b1ce310025423c (diff) | |
download | mpv-cc9973f4e0268bc17cf95ec39af194d0136e0c0d.tar.bz2 mpv-cc9973f4e0268bc17cf95ec39af194d0136e0c0d.tar.xz |
player: move some libass setup code to sub.c
Also recreate ASS_Library on every file played. This means we can move
the code out of main.c as well.
Recreating the ASS_Library object has no disadvantages, because it
literally stores only the message callback, the (per-file) font
attachment as byte arrays, and the set of style overrides. Hopefully
this thing can be removed from the libass API entirely at some point.
The only reason why the player core creates the ASS_Renderer, instead
of the subtitle renderer, is because we want to cache the loaded fonts
across ordered chapter transitions, so this probably still has to stay
around for now.
Diffstat (limited to 'player/sub.c')
-rw-r--r-- | player/sub.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/player/sub.c b/player/sub.c index 6d2c5f06a5..d5f76834d3 100644 --- a/player/sub.c +++ b/player/sub.c @@ -28,8 +28,10 @@ #include "common/msg.h" #include "options/options.h" #include "common/common.h" +#include "common/global.h" #include "stream/stream.h" +#include "sub/ass_mp.h" #include "sub/dec_sub.h" #include "demux/demux.h" #include "video/mp_image.h" @@ -38,6 +40,98 @@ #include "core.h" +#if HAVE_LIBASS + +static const char *const font_mimetypes[] = { + "application/x-truetype-font", + "application/vnd.ms-opentype", + "application/x-font-ttf", + "application/x-font", // probably incorrect + NULL +}; + +static const char *const font_exts[] = {".ttf", ".ttc", ".otf", NULL}; + +static bool attachment_is_font(struct mp_log *log, struct demux_attachment *att) +{ + if (!att->name || !att->type || !att->data || !att->data_size) + return false; + for (int n = 0; font_mimetypes[n]; n++) { + if (strcmp(font_mimetypes[n], att->type) == 0) + return true; + } + // fallback: match against file extension + char *ext = strlen(att->name) > 4 ? att->name + strlen(att->name) - 4 : ""; + for (int n = 0; font_exts[n]; n++) { + if (strcasecmp(ext, font_exts[n]) == 0) { + mp_warn(log, "Loading font attachment '%s' with MIME type %s. " + "Assuming this is a broken Matroska file, which was " + "muxed without setting a correct font MIME type.\n", + att->name, att->type); + return true; + } + } + return false; +} + +static void add_subtitle_fonts_from_sources(struct MPContext *mpctx) +{ + if (mpctx->opts->ass_enabled) { + for (int j = 0; j < mpctx->num_sources; j++) { + struct demuxer *d = mpctx->sources[j]; + for (int i = 0; i < d->num_attachments; i++) { + struct demux_attachment *att = d->attachments + i; + if (mpctx->opts->use_embedded_fonts && + attachment_is_font(mpctx->log, att)) + { + ass_add_font(mpctx->ass_library, att->name, att->data, + att->data_size); + } + } + } + } +} + +void init_sub_renderer(struct MPContext *mpctx) +{ + struct MPOpts *opts = mpctx->opts; + + uninit_sub_renderer(mpctx); + + if (!mpctx->ass_log) + mpctx->ass_log = mp_log_new(mpctx, mpctx->global->log, "!libass"); + + mpctx->ass_library = mp_ass_init(mpctx->global, mpctx->ass_log); + + add_subtitle_fonts_from_sources(mpctx); + + if (opts->ass_style_override) + ass_set_style_overrides(mpctx->ass_library, opts->ass_force_style_list); + + mpctx->ass_renderer = ass_renderer_init(mpctx->ass_library); + if (mpctx->ass_renderer) { + mp_ass_configure_fonts(mpctx->ass_renderer, opts->sub_text_style, + mpctx->global, mpctx->ass_log); + } +} + +void uninit_sub_renderer(struct MPContext *mpctx) +{ + if (mpctx->ass_renderer) + ass_renderer_done(mpctx->ass_renderer); + mpctx->ass_renderer = NULL; + if (mpctx->ass_library) + ass_library_done(mpctx->ass_library); + mpctx->ass_library = NULL; +} + +#else /* HAVE_LIBASS */ + +void init_sub_renderer(struct MPContext *mpctx) {} +void uninit_sub_renderer(struct MPContext *mpctx) {} + +#endif + void uninit_stream_sub_decoders(struct demuxer *demuxer) { for (int i = 0; i < demuxer->num_streams; i++) { |