mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
e64ce83182
commit
cc9973f4e0
|
@ -469,6 +469,8 @@ void uninit_sub(struct MPContext *mpctx, int order);
|
|||
void uninit_sub_all(struct MPContext *mpctx);
|
||||
void update_osd_msg(struct MPContext *mpctx);
|
||||
void update_subtitles(struct MPContext *mpctx);
|
||||
void init_sub_renderer(struct MPContext *mpctx);
|
||||
void uninit_sub_renderer(struct MPContext *mpctx);
|
||||
|
||||
// timeline/tl_matroska.c
|
||||
void build_ordered_chapter_timeline(struct MPContext *mpctx);
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include "demux/demux.h"
|
||||
#include "stream/stream.h"
|
||||
#include "stream/resolve/resolve.h"
|
||||
#include "sub/ass_mp.h"
|
||||
#include "sub/dec_sub.h"
|
||||
#include "sub/find_subfiles.h"
|
||||
#include "video/decode/dec_video.h"
|
||||
|
@ -735,81 +734,6 @@ static void open_subtitles_from_resolve(struct MPContext *mpctx)
|
|||
}
|
||||
}
|
||||
|
||||
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 HAVE_LIBASS
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void uninit_libass(struct MPContext *mpctx)
|
||||
{
|
||||
#if HAVE_LIBASS
|
||||
if (mpctx->ass_renderer)
|
||||
ass_renderer_done(mpctx->ass_renderer);
|
||||
mpctx->ass_renderer = NULL;
|
||||
ass_clear_fonts(mpctx->ass_library);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void init_sub_renderer(struct MPContext *mpctx)
|
||||
{
|
||||
#if HAVE_LIBASS
|
||||
uninit_libass(mpctx);
|
||||
|
||||
mpctx->ass_renderer = ass_renderer_init(mpctx->ass_library);
|
||||
if (mpctx->ass_renderer) {
|
||||
mp_ass_configure_fonts(mpctx->ass_renderer, mpctx->opts->sub_text_style,
|
||||
mpctx->global, mpctx->ass_log);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct mp_resolve_result *resolve_url(const char *filename,
|
||||
struct mpv_global *global)
|
||||
{
|
||||
|
@ -981,11 +905,6 @@ static void play_current_file(struct MPContext *mpctx)
|
|||
load_per_file_options(mpctx->mconfig, mpctx->playing->params,
|
||||
mpctx->playing->num_params);
|
||||
|
||||
#if HAVE_LIBASS
|
||||
if (opts->ass_style_override)
|
||||
ass_set_style_overrides(mpctx->ass_library, opts->ass_force_style_list);
|
||||
#endif
|
||||
|
||||
mpctx->audio_delay = opts->audio_delay;
|
||||
mpctx->max_frames = opts->play_frames;
|
||||
|
||||
|
@ -1093,10 +1012,6 @@ goto_reopen_demuxer: ;
|
|||
if (mpctx->timeline)
|
||||
timeline_set_part(mpctx, mpctx->timeline_part, true);
|
||||
|
||||
add_subtitle_fonts_from_sources(mpctx);
|
||||
// libass seems to misbehave if fonts are changed while a renderer
|
||||
// exists, so we (re)create the renderer after fonts are set.
|
||||
init_sub_renderer(mpctx);
|
||||
|
||||
open_subtitles_from_options(mpctx);
|
||||
open_subtitles_from_resolve(mpctx);
|
||||
|
@ -1141,6 +1056,8 @@ goto_reopen_demuxer: ;
|
|||
"Displaying attached picture. Use --no-audio-display to prevent this.\n");
|
||||
}
|
||||
|
||||
init_sub_renderer(mpctx);
|
||||
|
||||
#if HAVE_ENCODING
|
||||
if (mpctx->encode_lavc_ctx && mpctx->current_track[0][STREAM_VIDEO])
|
||||
encode_lavc_expect_stream(mpctx->encode_lavc_ctx, AVMEDIA_TYPE_VIDEO);
|
||||
|
@ -1242,7 +1159,7 @@ terminate_playback:
|
|||
uninit_audio_chain(mpctx);
|
||||
uninit_video_chain(mpctx);
|
||||
uninit_sub_all(mpctx);
|
||||
uninit_libass(mpctx);
|
||||
//uninit_sub_renderer(mpctx);
|
||||
uninit_demuxer(mpctx);
|
||||
uninit_stream(mpctx);
|
||||
if (!opts->fixed_vo)
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "audio/mixer.h"
|
||||
#include "demux/demux.h"
|
||||
#include "stream/stream.h"
|
||||
#include "sub/ass_mp.h"
|
||||
#include "sub/osd.h"
|
||||
#include "video/decode/dec_video.h"
|
||||
#include "video/out/vo.h"
|
||||
|
@ -134,11 +133,6 @@ void mp_destroy(struct MPContext *mpctx)
|
|||
|
||||
osd_free(mpctx->osd);
|
||||
|
||||
#if HAVE_LIBASS
|
||||
if (mpctx->ass_library)
|
||||
ass_library_done(mpctx->ass_library);
|
||||
#endif
|
||||
|
||||
if (mpctx->opts->use_terminal && terminal_initialized) {
|
||||
terminal_uninit();
|
||||
terminal_initialized = false;
|
||||
|
@ -408,10 +402,7 @@ int mp_initialize(struct MPContext *mpctx)
|
|||
if (opts->use_terminal && opts->consolecontrols && terminal_initialized)
|
||||
terminal_setup_getch(mpctx->input);
|
||||
|
||||
#if HAVE_LIBASS
|
||||
mpctx->ass_log = mp_log_new(mpctx, mpctx->global->log, "!libass");
|
||||
mpctx->ass_library = mp_ass_init(mpctx->global, mpctx->ass_log);
|
||||
#else
|
||||
#if !HAVE_LIBASS
|
||||
MP_WARN(mpctx, "Compiled without libass.\n");
|
||||
MP_WARN(mpctx, "There will be no OSD and no text subtitles.\n");
|
||||
#endif
|
||||
|
|
94
player/sub.c
94
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++) {
|
||||
|
|
Loading…
Reference in New Issue