From d85753b79e4ce0fa7a5ddac5b2ed0cf65f7aecd8 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 27 Dec 2015 02:07:01 +0100 Subject: sub: refactor initialization Just simplify by removing parts not needed anymore. This includes merging dec_sub allocation and initialization (since things making initialization complicated were removed), or format support queries (it simply tries to create a decoder, and if that fails, tries the next one). --- sub/dec_sub.c | 144 ++++++++++++++++++++------------------------------------ sub/dec_sub.h | 9 ++-- sub/lavc_conv.c | 9 ---- sub/sd.h | 2 - sub/sd_ass.c | 7 --- sub/sd_lavc.c | 30 +++++------- 6 files changed, 66 insertions(+), 135 deletions(-) (limited to 'sub') diff --git a/sub/dec_sub.c b/sub/dec_sub.c index 1a2c170596..6733acfedc 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -48,7 +48,6 @@ struct dec_sub { struct mp_log *log; struct MPOpts *opts; - struct sd init_sd; struct sh_stream *sh; @@ -71,96 +70,57 @@ void sub_unlock(struct dec_sub *sub) pthread_mutex_unlock(&sub->lock); } -// 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 dec_sub *sub = talloc_zero(NULL, struct dec_sub); - sub->log = mp_log_new(sub, global->log, "sub"); - sub->opts = global->opts; - sub->init_sd.opts = sub->opts; - sub->init_sd.global = global; - - mpthread_mutex_init_recursive(&sub->lock); - - return sub; -} - -static void sub_uninit(struct dec_sub *sub) -{ - sub_reset(sub); - if (sub->sd) - sub->sd->driver->uninit(sub->sd); - talloc_free(sub->sd); - sub->sd = NULL; -} - void sub_destroy(struct dec_sub *sub) { if (!sub) return; - sub_uninit(sub); + sub_reset(sub); + sub->sd->driver->uninit(sub->sd); + talloc_free(sub->sd); pthread_mutex_destroy(&sub->lock); talloc_free(sub); } -bool sub_is_initialized(struct dec_sub *sub) -{ - pthread_mutex_lock(&sub->lock); - bool r = !!sub->sd; - pthread_mutex_unlock(&sub->lock); - return r; -} - -static int sub_init_decoder(struct dec_sub *sub, struct sd *sd) -{ - sd->driver = NULL; - for (int n = 0; sd_list[n]; n++) { - if (sd->sh->codec && sd_list[n]->supports_format(sd->sh->codec)) { - sd->driver = sd_list[n]; - break; - } - } - - if (!sd->driver) - return -1; - - sd->log = mp_log_new(sd, sub->log, sd->driver->name); - if (sd->driver->init(sd) < 0) - return -1; - - return 0; -} - -void sub_init(struct dec_sub *sub, struct demuxer *demuxer, struct sh_stream *sh) +// 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) { - assert(!sub->sd); - assert(sh && sh->sub); - - pthread_mutex_lock(&sub->lock); + assert(demuxer && sh && sh->sub); - sub->sh = sh; + struct mp_log *log = mp_log_new(NULL, global->log, "sub"); - struct sd init_sd = sub->init_sd; - init_sd.demuxer = demuxer; - init_sd.sh = sh; + for (int n = 0; sd_list[n]; n++) { + const struct sd_functions *driver = sd_list[n]; + struct dec_sub *sub = talloc_zero(NULL, struct dec_sub); + sub->log = talloc_steal(sub, log), + sub->opts = global->opts; + sub->sh = sh; + mpthread_mutex_init_recursive(&sub->lock); + + sub->sd = talloc(NULL, struct sd); + *sub->sd = (struct sd){ + .global = global, + .log = mp_log_new(sub->sd, sub->log, driver->name), + .opts = sub->opts, + .driver = driver, + .demuxer = demuxer, + .sh = sh, + }; - struct sd *sd = talloc(NULL, struct sd); - *sd = init_sd; + if (sh->codec && sub->sd->driver->init(sub->sd) >= 0) + return sub; - if (sub_init_decoder(sub, sd) < 0) { - if (sd->driver && sd->driver->uninit) - sd->driver->uninit(sd); - talloc_free(sd); - MP_ERR(sub, "Could not find subtitle decoder for format '%s'.\n", - sh->codec ? sh->codec : ""); - pthread_mutex_unlock(&sub->lock); - return; + ta_set_parent(log, NULL); + talloc_free(sub->sd); + talloc_free(sub); } - sub->sd = sd; - pthread_mutex_unlock(&sub->lock); + mp_err(log, "Could not find subtitle decoder for format '%s'.\n", + sh->codec ? sh->codec : ""); + talloc_free(log); + return NULL; } static struct demux_packet *recode_packet(struct mp_log *log, @@ -187,13 +147,11 @@ static struct demux_packet *recode_packet(struct mp_log *log, static void decode_chain_recode(struct dec_sub *sub, struct demux_packet *packet) { - if (sub->sd) { - struct demux_packet *recoded = NULL; - if (sub->sh && sub->sh->sub->charset) - recoded = recode_packet(sub->log, packet, sub->sh->sub->charset); - sub->sd->driver->decode(sub->sd, recoded ? recoded : packet); - talloc_free(recoded); - } + struct demux_packet *recoded = NULL; + if (sub->sh->sub->charset) + recoded = recode_packet(sub->log, packet, sub->sh->sub->charset); + sub->sd->driver->decode(sub->sd, recoded ? recoded : packet); + talloc_free(recoded); } void sub_decode(struct dec_sub *sub, struct demux_packet *packet) @@ -220,14 +178,12 @@ static void add_packet(struct packet_list *subs, struct demux_packet *pkt) // Read all packets from the demuxer and decode/add them. Returns false if // there are circumstances which makes this not possible. -bool sub_read_all_packets(struct dec_sub *sub, struct sh_stream *sh) +bool sub_read_all_packets(struct dec_sub *sub) { - assert(sh && sh->sub); - pthread_mutex_lock(&sub->lock); // Converters are assumed to always accept packets in advance - if (!(sub->sd && sub->sd->driver->accept_packets_in_advance)) { + if (!sub->sd->driver->accept_packets_in_advance) { pthread_mutex_unlock(&sub->lock); return false; } @@ -235,7 +191,7 @@ bool sub_read_all_packets(struct dec_sub *sub, struct sh_stream *sh) struct packet_list *subs = talloc_zero(NULL, struct packet_list); for (;;) { - struct demux_packet *pkt = demux_read_packet(sh); + struct demux_packet *pkt = demux_read_packet(sub->sh); if (!pkt) break; add_packet(subs, pkt); @@ -253,7 +209,7 @@ bool sub_accepts_packet_in_advance(struct dec_sub *sub) { bool res = true; pthread_mutex_lock(&sub->lock); - if (sub->sd && sub->sd->driver->accepts_packet) + if (sub->sd->driver->accepts_packet) res &= sub->sd->driver->accepts_packet(sub->sd); pthread_mutex_unlock(&sub->lock); return res; @@ -268,7 +224,7 @@ void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, double pts, struct MPOpts *opts = sub->opts; *res = (struct sub_bitmaps) {0}; - if (sub->sd && opts->sub_visibility && sub->sd->driver->get_bitmaps) + if (opts->sub_visibility && sub->sd->driver->get_bitmaps) sub->sd->driver->get_bitmaps(sub->sd, dim, pts, res); } @@ -280,7 +236,7 @@ char *sub_get_text(struct dec_sub *sub, double pts) pthread_mutex_lock(&sub->lock); struct MPOpts *opts = sub->opts; char *text = NULL; - if (sub->sd && opts->sub_visibility && sub->sd->driver->get_text) + if (opts->sub_visibility && sub->sd->driver->get_text) text = sub->sd->driver->get_text(sub->sd, pts); pthread_mutex_unlock(&sub->lock); return text; @@ -289,7 +245,7 @@ char *sub_get_text(struct dec_sub *sub, double pts) void sub_reset(struct dec_sub *sub) { pthread_mutex_lock(&sub->lock); - if (sub->sd && sub->sd->driver->reset) + if (sub->sd->driver->reset) sub->sd->driver->reset(sub->sd); pthread_mutex_unlock(&sub->lock); } @@ -297,7 +253,7 @@ void sub_reset(struct dec_sub *sub) void sub_select(struct dec_sub *sub, bool selected) { pthread_mutex_lock(&sub->lock); - if (sub->sd && sub->sd->driver->select) + if (sub->sd->driver->select) sub->sd->driver->select(sub->sd, selected); pthread_mutex_unlock(&sub->lock); } @@ -306,7 +262,7 @@ int sub_control(struct dec_sub *sub, enum sd_ctrl cmd, void *arg) { int r = CONTROL_UNKNOWN; pthread_mutex_lock(&sub->lock); - if (sub->sd && sub->sd->driver->control) + if (sub->sd->driver->control) r = sub->sd->driver->control(sub->sd, cmd, arg); pthread_mutex_unlock(&sub->lock); return r; diff --git a/sub/dec_sub.h b/sub/dec_sub.h index e202438777..56db5bc519 100644 --- a/sub/dec_sub.h +++ b/sub/dec_sub.h @@ -22,16 +22,13 @@ enum sd_ctrl { SD_CTRL_SET_VIDEO_DEF_FPS, }; -struct dec_sub *sub_create(struct mpv_global *global); +struct dec_sub *sub_create(struct mpv_global *global, struct demuxer *demuxer, + struct sh_stream *sh); void sub_destroy(struct dec_sub *sub); void sub_lock(struct dec_sub *sub); void sub_unlock(struct dec_sub *sub); -void sub_init(struct dec_sub *sub, struct demuxer *demuxer, struct sh_stream *sh); - -bool sub_is_initialized(struct dec_sub *sub); - -bool sub_read_all_packets(struct dec_sub *sub, struct sh_stream *sh); +bool sub_read_all_packets(struct dec_sub *sub); bool sub_accepts_packet_in_advance(struct dec_sub *sub); void sub_decode(struct dec_sub *sub, struct demux_packet *packet); void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, double pts, diff --git a/sub/lavc_conv.c b/sub/lavc_conv.c index 7e2ed4ef25..b244240d7c 100644 --- a/sub/lavc_conv.c +++ b/sub/lavc_conv.c @@ -49,15 +49,6 @@ static const char *get_lavc_format(const char *format) return format; } -bool lavc_conv_supports_format(const char *format) -{ - format = get_lavc_format(format); - enum AVCodecID cid = mp_codec_to_av_codec_id(format); - AVCodec *codec = avcodec_find_decoder(cid); - const AVCodecDescriptor *desc = avcodec_descriptor_get(cid); - return codec && desc && desc->type == AVMEDIA_TYPE_SUBTITLE; -} - // Disable style definitions generated by the libavcodec converter. // We always want the user defined style instead. static void disable_styles(bstr header) diff --git a/sub/sd.h b/sub/sd.h index 26f9d4149f..5945b00483 100644 --- a/sub/sd.h +++ b/sub/sd.h @@ -24,7 +24,6 @@ struct sd { struct sd_functions { const char *name; bool accept_packets_in_advance; - bool (*supports_format)(const char *format); int (*init)(struct sd *sd); void (*decode)(struct sd *sd, struct demux_packet *packet); void (*reset)(struct sd *sd); @@ -40,7 +39,6 @@ struct sd_functions { }; struct lavc_conv; -bool lavc_conv_supports_format(const char *format); struct lavc_conv *lavc_conv_create(struct mp_log *log, const char *codec_name, char *extradata, int extradata_len); char *lavc_conv_get_extradata(struct lavc_conv *priv); diff --git a/sub/sd_ass.c b/sub/sd_ass.c index d798b1f4f4..564a62133d 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -125,12 +125,6 @@ static void add_subtitle_fonts(struct sd *sd) } } -static bool supports_format(const char *format) -{ - return (format && strcmp(format, "ass") == 0) || - lavc_conv_supports_format(format); -} - static void enable_output(struct sd *sd, bool enable) { struct sd_ass_priv *ctx = sd->priv; @@ -633,7 +627,6 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg) const struct sd_functions sd_ass = { .name = "ass", .accept_packets_in_advance = true, - .supports_format = supports_format, .init = init, .decode = decode, .get_bitmaps = get_bitmaps, diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index 86aaf4fda9..d9b9f507e7 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -64,21 +64,6 @@ struct sd_lavc_priv { int num_seekpoints; }; -static bool supports_format(const char *format) -{ - enum AVCodecID cid = mp_codec_to_av_codec_id(format); - // Supported codecs must be known to decode to paletted bitmaps - switch (cid) { - case AV_CODEC_ID_DVB_SUBTITLE: - case AV_CODEC_ID_HDMV_PGS_SUBTITLE: - case AV_CODEC_ID_XSUB: - case AV_CODEC_ID_DVD_SUBTITLE: - return true; - default: - return false; - } -} - static void get_resolution(struct sd *sd, int wh[2]) { struct sd_lavc_priv *priv = sd->priv; @@ -110,8 +95,20 @@ static void get_resolution(struct sd *sd, int wh[2]) static int init(struct sd *sd) { - struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv); enum AVCodecID cid = mp_codec_to_av_codec_id(sd->sh->codec); + + // Supported codecs must be known to decode to paletted bitmaps + switch (cid) { + case AV_CODEC_ID_DVB_SUBTITLE: + case AV_CODEC_ID_HDMV_PGS_SUBTITLE: + case AV_CODEC_ID_XSUB: + case AV_CODEC_ID_DVD_SUBTITLE: + break; + default: + return -1; + } + + struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv); AVCodecContext *ctx = NULL; AVCodec *sub_codec = avcodec_find_decoder(cid); if (!sub_codec) @@ -467,7 +464,6 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg) const struct sd_functions sd_lavc = { .name = "lavc", - .supports_format = supports_format, .init = init, .decode = decode, .get_bitmaps = get_bitmaps, -- cgit v1.2.3