[FFmpeg-devel] [PATCH v1 2/2] avfilter/vf_subtitles: Added shift option for subtitles/ass filters.
Manolis Stamatogiannakis
mstamat at gmail.com
Mon Aug 16 10:48:40 EEST 2021
Bumping this once more.
On Thu, 22 Jul 2021 at 16:19, Gyan Doshi <ffmpeg at gyani.pro> wrote:
>
>
> On 2021-07-22 00:08, Manolis Stamatogiannakis wrote:
> > Would it be possible to have a quick review for this patch? It is pretty
> > straightforward.
>
> Will test within a few days.
>
> Regards,
> Gyan
>
> >
> > 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 <mstamat at 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 <mstamat at 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.
> >>
> >> + at 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.
> >> +
> >> + at 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:
> >> + at example
> >> +subtitles=filename=sub.srt:shift='-20\:20'
> >> + at 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 at ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
>
More information about the ffmpeg-devel
mailing list