From 86689f7bf23dd05b5e6b9e42e43379d52e27c338 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 15 Mar 2014 22:17:51 +0100 Subject: demux_libass: change how external ASS subtitles are loaded Instead of parsing the ASS file in demux_libass.c and trying to pass the ASS_Track to the subtitle renderer, just read all file data in demux_libass.c, and let the subtitle renderer pass the file contents to ass_process_codec_private(). (This happens to parse full files too.) Makes the code simpler, though it also relies harder on the (messy) probe logic in demux_libass.c. --- demux/demux.h | 1 - demux/demux_libass.c | 53 ++++++++++++++++++++-------------------------------- demux/stheader.h | 1 - 3 files changed, 20 insertions(+), 35 deletions(-) (limited to 'demux') diff --git a/demux/demux.h b/demux/demux.h index a8c407e7ba..2915140248 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -156,7 +156,6 @@ struct demuxer_params { struct matroska_segment_uid *matroska_wanted_uids; int matroska_wanted_segment; bool *matroska_was_valid; - struct ass_library *ass_library; bool expect_subtitle; }; diff --git a/demux/demux_libass.c b/demux/demux_libass.c index 0bbcb7c329..a528f73459 100644 --- a/demux/demux_libass.c +++ b/demux/demux_libass.c @@ -29,22 +29,26 @@ #define PROBE_SIZE (8 * 1024) -struct priv { - ASS_Track *track; -}; +static void message_callback(int level, const char *format, va_list va, void *ctx) +{ + // ignore +} static int d_check_file(struct demuxer *demuxer, enum demux_check check) { const char *user_cp = demuxer->opts->sub_cp; struct stream *s = demuxer->stream; struct mp_log *log = demuxer->log; - // Older versions of libass will behave strange if renderer and track - // library handles mismatch, so make sure everything uses a global handle. - ASS_Library *lib = demuxer->params ? demuxer->params->ass_library : NULL; - if (!lib) + + if (!demuxer->params || !demuxer->params->expect_subtitle) return -1; if (check >= DEMUX_CHECK_UNSAFE) { + ASS_Library *lib = ass_library_init(); + if (!lib) + return -1; + ass_set_message_cb(lib, message_callback, NULL); + // Probe by loading a part of the beginning of the file with libass. // Incomplete scripts are usually ok, and we hope libass is not verbose // when dealing with (from its perspective) completely broken binary @@ -62,12 +66,15 @@ static int d_check_file(struct demuxer *demuxer, enum demux_check check) if (cbuf.start == NULL) cbuf = buf; ASS_Track *track = ass_read_memory(lib, cbuf.start, cbuf.len, NULL); + bool ok = !!track; if (cbuf.start != buf.start) talloc_free(cbuf.start); talloc_free(buf.start); - if (!track) + if (track) + ass_free_track(track); + ass_library_done(lib); + if (!ok) return -1; - ass_free_track(track); } // Actually load the full thing. @@ -82,42 +89,22 @@ static int d_check_file(struct demuxer *demuxer, enum demux_check check) MP_ICONV_VERBOSE); if (cbuf.start == NULL) cbuf = buf; - ASS_Track *track = ass_read_memory(lib, cbuf.start, cbuf.len, NULL); if (cbuf.start != buf.start) - talloc_free(cbuf.start); - talloc_free(buf.start); - if (!track) - return -1; - - track->name = strdup(demuxer->filename); - - struct priv *p = talloc_ptrtype(demuxer, p); - *p = (struct priv) { - .track = track, - }; - demuxer->priv = p; + talloc_free(buf.start); + talloc_steal(demuxer, cbuf.start); struct sh_stream *sh = new_sh_stream(demuxer, STREAM_SUB); - sh->sub->track = track; sh->codec = "ass"; + sh->sub->extradata = cbuf.start; + sh->sub->extradata_len = cbuf.len; demuxer->seekable = true; return 0; } -static void d_close(struct demuxer *demuxer) -{ - struct priv *p = demuxer->priv; - if (p) { - if (p->track) - ass_free_track(p->track); - } -} - const struct demuxer_desc demuxer_desc_libass = { .name = "libass", .desc = "ASS/SSA subtitles (libass)", .open = d_check_file, - .close = d_close, }; diff --git a/demux/stheader.h b/demux/stheader.h index 573d6ac3c6..2940dc6a4d 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -91,7 +91,6 @@ typedef struct sh_sub { double frame_based; // timestamps are frame-based (and this is the // fallback framerate used for timestamps) bool is_utf8; // if false, subtitle packet charset is unknown - struct ass_track *track; // loaded by libass struct dec_sub *dec_sub; // decoder context } sh_sub_t; -- cgit v1.2.3