Would it be possible to have a quick review for this patch? It is pretty straightforward.
Plus, this is its second submission. It already includes the requested changes from the first time (~1y ago). Thanks in advance, Manolis On Sun, 4 Jul 2021 at 18:13, Manolis Stamatogiannakis <msta...@gmail.com> wrote: > Allows shifting of subtitle display times to align them with the video. > This avoids having to rewrite the subtitle file in order to display > subtitles correctly when input is seeked (-ss). > Also handy for minor subtitle timing corrections without rewriting the > subtitles file. > > Signed-off-by: Manolis Stamatogiannakis <msta...@gmail.com> > --- > doc/filters.texi | 11 ++++++++ > libavfilter/vf_subtitles.c | 55 +++++++++++++++++++++++++++++++++----- > 2 files changed, 59 insertions(+), 7 deletions(-) > > diff --git a/doc/filters.texi b/doc/filters.texi > index 61c4cfc150..eebf455692 100644 > --- a/doc/filters.texi > +++ b/doc/filters.texi > @@ -19474,6 +19474,9 @@ Common @ref{subtitles}/@ref{ass} filter options: > @item filename, f > Set the filename of the subtitle file to read. It must be specified. > > +@item shift > +Shift subtitles timings by the specified amount. > + > @item original_size > Specify the size of the original video, the video for which the ASS file > was composed. For the syntax of this option, check the > @@ -19487,6 +19490,9 @@ These fonts will be used in addition to whatever > the font provider uses. > > @item alpha > Process alpha channel, by default alpha channel is untouched. > + > +@item shift > +Shift subtitles timings by the specified amount. > @end table > > Additional options for @ref{subtitles} filter: > @@ -19533,6 +19539,11 @@ To make the subtitles stream from @file{sub.srt} > appear in 80% transparent blue > subtitles=sub.srt:force_style='Fontname=DejaVu > Serif,PrimaryColour=&HCCFF0000' > @end example > > +To re-sync subtitles after seeking the input e.g. with @code{-ss 20:20}, > use: > +@example > +subtitles=filename=sub.srt:shift='-20\:20' > +@end example > + > @section super2xsai > > Scale the input by 2x and smooth using the Super2xSaI (Scale and > diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c > index ab32e1b7f3..2c7ce267e1 100644 > --- a/libavfilter/vf_subtitles.c > +++ b/libavfilter/vf_subtitles.c > @@ -52,6 +52,7 @@ typedef struct AssContext { > char *filename; > char *fontsdir; > char *charenc; > + int64_t shift; > char *force_style; > int stream_index; > int alpha; > @@ -66,11 +67,12 @@ typedef struct AssContext { > #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM > > #define COMMON_OPTIONS \ > - {"filename", "set the filename of file to read", > OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, > FLAGS }, \ > - {"f", "set the filename of file to read", > OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, > FLAGS }, \ > - {"original_size", "set the size of the original video (used to scale > fonts)", OFFSET(original_w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, > FLAGS }, \ > - {"fontsdir", "set the directory containing the fonts to read", > OFFSET(fontsdir), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, > FLAGS }, \ > - {"alpha", "enable processing of alpha channel", > OFFSET(alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, > 0, 1, FLAGS }, \ > + {"filename", "set the filename of file to read", > OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, > 0, 0, FLAGS }, \ > + {"f", "set the filename of file to read", > OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, > 0, 0, FLAGS }, \ > + {"original_size", "set the size of the original video (used to scale > fonts)", OFFSET(original_w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, > 0, 0, FLAGS }, \ > + {"fontsdir", "set the directory containing the fonts to read", > OFFSET(fontsdir), AV_OPT_TYPE_STRING, {.str = NULL}, > 0, 0, FLAGS }, \ > + {"alpha", "enable processing of alpha channel", > OFFSET(alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, > 0, 1, FLAGS }, \ > + {"shift", "shift subtitles timing", > OFFSET(shift), AV_OPT_TYPE_DURATION, {.i64 = 0 }, > INT64_MIN, INT64_MAX, FLAGS }, \ > > /* libass supports a log level ranging from 0 to 7 */ > static const int ass_libavfilter_log_level_map[] = { > @@ -103,6 +105,11 @@ static av_cold int init(AVFilterContext *ctx) > return AVERROR(EINVAL); > } > > + if (ass->shift != 0) { > + ass->shift = av_rescale_q(ass->shift, AV_TIME_BASE_Q, > av_make_q(1, 1000)); > + av_log(ctx, AV_LOG_INFO, "Shifting subtitles by %0.3fsec.\n", > ass->shift/1000.0); > + } > + > ass->library = ass_library_init(); > if (!ass->library) { > av_log(ctx, AV_LOG_ERROR, "Could not initialize libass.\n"); > @@ -228,6 +235,8 @@ AVFILTER_DEFINE_CLASS(ass); > > static av_cold int init_ass(AVFilterContext *ctx) > { > + int eid, nskip; > + ASS_Event *event; > AssContext *ass = ctx->priv; > int ret = init(ctx); > > @@ -244,6 +253,25 @@ static av_cold int init_ass(AVFilterContext *ctx) > ass->filename); > return AVERROR(EINVAL); > } > + > + /* Shift subtitles. */ > + nskip = 0; > + for (eid = 0; eid < ass->track->n_events; eid++) { > + event = &ass->track->events[eid]; > + event->Start += ass->shift; > + if (event->Start + event->Duration < 0) { > + ass_free_event(ass->track, eid); > + nskip++; > + continue; > + } else if (nskip > 0) { > + av_log(ctx, AV_LOG_INFO, "Skipped %d subtitles out of time > range.\n", nskip); > + memmove(event - nskip, event, (ass->track->n_events - eid) * > sizeof(ASS_Event)); > + ass->track->n_events -= nskip; > + eid -= nskip; > + nskip = 0; > + } > + } > + > return 0; > } > > @@ -298,7 +326,7 @@ AVFILTER_DEFINE_CLASS(subtitles); > > static av_cold int init_subtitles(AVFilterContext *ctx) > { > - int j, ret, sid; > + int j, ret, sid, nskip; > int k = 0; > AVDictionary *codec_opts = NULL; > AVFormatContext *fmt = NULL; > @@ -449,6 +477,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx) > ass_process_codec_private(ass->track, > dec_ctx->subtitle_header, > dec_ctx->subtitle_header_size); > + nskip = 0; > while (av_read_frame(fmt, &pkt) >= 0) { > int i, got_subtitle; > AVSubtitle sub = {0}; > @@ -459,8 +488,18 @@ static av_cold int init_subtitles(AVFilterContext > *ctx) > av_log(ctx, AV_LOG_WARNING, "Error decoding: %s > (ignored)\n", > av_err2str(ret)); > } else if (got_subtitle) { > - const int64_t start_time = av_rescale_q(sub.pts, > AV_TIME_BASE_Q, av_make_q(1, 1000)); > + /* Shift subtitles. */ > + const int64_t start_time = av_rescale_q(sub.pts, > AV_TIME_BASE_Q, av_make_q(1, 1000)) + ass->shift; > const int64_t duration = sub.end_display_time; > + > + if (start_time + duration < 0) { > + nskip++; > + goto pkt_end; > + } else if (nskip > 0) { > + av_log(ctx, AV_LOG_INFO, "Skipped %d subtitles out of > time range.\n", nskip); > + nskip = 0; > + } > + > for (i = 0; i < sub.num_rects; i++) { > char *ass_line = sub.rects[i]->ass; > if (!ass_line) > @@ -470,6 +509,8 @@ static av_cold int init_subtitles(AVFilterContext *ctx) > } > } > } > + > +pkt_end: > av_packet_unref(&pkt); > avsubtitle_free(&sub); > } > -- > 2.17.1 > > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".