From 1b9370ff92a7fdf347d087db7c29bf682abadb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= Date: Wed, 18 Sep 2019 21:26:05 +0300 Subject: sub/lavc_conv: switch to the newer "ass" subtitle decoding mode Existing since 2016, this removes timestamps from the lines, and gives more precision in the timestamps (1:1000). --- sub/lavc_conv.c | 14 ++++++++++++-- sub/sd.h | 3 ++- sub/sd_ass.c | 10 ++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/sub/lavc_conv.c b/sub/lavc_conv.c index 75c127cc82..7077116180 100644 --- a/sub/lavc_conv.c +++ b/sub/lavc_conv.c @@ -85,6 +85,7 @@ struct lavc_conv *lavc_conv_create(struct mp_log *log, const char *codec_name, goto error; if (mp_lavc_set_extradata(avctx, extradata, extradata_len) < 0) goto error; + av_dict_set(&opts, "sub_text_format", "ass", 0); if (strcmp(codec_name, "eia_608") == 0) av_dict_set(&opts, "real_time", "1", 0); if (avcodec_open2(avctx, codec, &opts) < 0) @@ -227,8 +228,11 @@ static int parse_webvtt(AVPacket *in, AVPacket *pkt) #endif -// Return a NULL-terminated list of ASS event lines. -char **lavc_conv_decode(struct lavc_conv *priv, struct demux_packet *packet) +// Return a NULL-terminated list of ASS event lines and have +// the AVSubtitle display PTS and duration set to input +// double variables. +char **lavc_conv_decode(struct lavc_conv *priv, struct demux_packet *packet, + double *sub_pts, double *sub_duration) { AVCodecContext *avctx = priv->avctx; AVPacket pkt; @@ -254,6 +258,12 @@ char **lavc_conv_decode(struct lavc_conv *priv, struct demux_packet *packet) if (ret < 0) { MP_ERR(priv, "Error decoding subtitle\n"); } else if (got_sub) { + *sub_pts = packet->pts + mp_pts_from_av(priv->cur.start_display_time, + &avctx->time_base); + *sub_duration = mp_pts_from_av(priv->cur.end_display_time - + priv->cur.start_display_time, + &avctx->time_base); + for (int i = 0; i < priv->cur.num_rects; i++) { if (priv->cur.rects[i]->w > 0 && priv->cur.rects[i]->h > 0) MP_WARN(priv, "Ignoring bitmap subtitle.\n"); diff --git a/sub/sd.h b/sub/sd.h index 8c975959a8..0c4dd3465b 100644 --- a/sub/sd.h +++ b/sub/sd.h @@ -46,7 +46,8 @@ struct lavc_conv; 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); -char **lavc_conv_decode(struct lavc_conv *priv, struct demux_packet *packet); +char **lavc_conv_decode(struct lavc_conv *priv, struct demux_packet *packet, + double *sub_pts, double *sub_duration); void lavc_conv_reset(struct lavc_conv *priv); void lavc_conv_uninit(struct lavc_conv *priv); diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 1cecfe3215..d3eee38a45 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -241,13 +241,19 @@ static void decode(struct sd *sd, struct demux_packet *packet) } packet->duration = UNKNOWN_DURATION; } - char **r = lavc_conv_decode(ctx->converter, packet); + double sub_pts = 0; + double sub_duration = 0; + char **r = lavc_conv_decode(ctx->converter, packet, &sub_pts, + &sub_duration); + for (int n = 0; r && r[n]; n++) { char *ass_line = r[n]; if (sd->opts->sub_filter_SDH) ass_line = filter_SDH(sd, track->event_format, 0, ass_line, 0); if (ass_line) - ass_process_data(track, ass_line, strlen(ass_line)); + ass_process_chunk(track, ass_line, strlen(ass_line), + llrint(sub_pts * 1000), + llrint(sub_duration * 1000)); if (sd->opts->sub_filter_SDH) talloc_free(ass_line); } -- cgit v1.2.3