From patchwork Sat Jul 4 19:45:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manolis Stamatogiannakis X-Patchwork-Id: 20809 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 3214744AB7B for ; Sat, 4 Jul 2020 22:46:52 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1071D68AF17; Sat, 4 Jul 2020 22:46:52 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C723C689D23 for ; Sat, 4 Jul 2020 22:46:45 +0300 (EEST) Received: by mail-ej1-f54.google.com with SMTP id lx13so19260561ejb.4 for ; Sat, 04 Jul 2020 12:46:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=97dBolQfRs2ZF3CDdieHcwMwT+hBqVUuE9CiNN8nuxM=; b=B4ecOq4RjASjmo0UJWxApknXjFKxhaWGodVrS7p4xk8mq6B7d2bOFcqwzUWWLC7Uoq X8W7miAeKHuPqo7s7xmc40sfW2StzYdt2aXmeucLNMytonh3t1LwdbKVnb2VevI+qbVB ppzCjQaXfowM3CEPPjpqn5VOA2X89ELeH789ndK1MyQMlIFwj4u1VPzlzjngrnZOucTX MXA+Xc9W6J4Pfi+T9kQ9H6cZMDe/JVOIXeA+J9kLki14mPJm8UWRWf0B3GhJ002KG7AU 7Fp599tklMlvccPe2LHx5II+xEJWERl+BQdYFqy7gP1kKR84tyftI3DFIW1NsEqaBif/ meew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=97dBolQfRs2ZF3CDdieHcwMwT+hBqVUuE9CiNN8nuxM=; b=aftA7Hss4j5nDKBh+ybpCg4QkxdRGtSart7wFIcPVvkZ9cN3iQMLit6w7u1s8wHl7b C6c9FvgxTouk06LZkEvEthVbbBtv8xf6HXa9xQR6Zhyy2JiVlzze1yCvnB927GN+jjh7 Dy+79XzCSDi3eTNcvIHdsKjYeNBW8eVNAOAKxpt5dIIxGle7m3f9NUxT/hlf+OYumQ1Q qeQkOK8doB/iXm6Y5iyqgZtD7KMBrguW95Vj/YcDIHxWIo5UtkIh2rQLDVruWx16+ofZ LGsEvYSMmKDjkTAv+Xrw2Y96Ktr0/WnpJoQawdlcp0ycZNZhzTCpLP+tCaAcH1EoBJAp m+YQ== X-Gm-Message-State: AOAM533/v4p/+Ku/bdtoziGPljkfoJjJFm6AERF6/g52aIqRkpvGhn3q kcF1d4shRz5DdYZFxv76cTY9fembTug= X-Google-Smtp-Source: ABdhPJxVswlaYcoGWRnNhBQY9BhaMhEMBqHdUTXVfRXDKSEmsOoYKcnpXxgsog4SMbqhh6B6WuFlpQ== X-Received: by 2002:a17:906:a242:: with SMTP id bi2mr32338700ejb.243.1593892004568; Sat, 04 Jul 2020 12:46:44 -0700 (PDT) Received: from wasteland.vu.local ([145.108.189.179]) by smtp.gmail.com with ESMTPSA id 92sm17398018edg.78.2020.07.04.12.46.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jul 2020 12:46:44 -0700 (PDT) From: Manolis Stamatogiannakis To: ffmpeg-devel@ffmpeg.org Date: Sat, 4 Jul 2020 21:45:43 +0200 Message-Id: <20200704194543.1738-1-mstamat@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200508111355.28343-1-mstamat@gmail.com> References: <20200508111355.28343-1-mstamat@gmail.com> Subject: [FFmpeg-devel] [PATCH] avfilter/vf_subtitles: add shift option X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Manolis Stamatogiannakis MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 --- doc/filters.texi | 8 ++++++++ libavfilter/vf_subtitles.c | 23 +++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index ad2448acb2..c962ac55b0 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -17935,6 +17935,9 @@ The filter accepts the following 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 @@ -17991,6 +17994,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 1bd42391e0..125fbd9ac7 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; @@ -103,6 +104,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_DEBUG, "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"); @@ -267,6 +273,7 @@ static const AVOption subtitles_options[] = { {"stream_index", "set stream index", OFFSET(stream_index), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS}, {"si", "set stream index", OFFSET(stream_index), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS}, {"force_style", "force subtitle style", OFFSET(force_style), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS}, + {"shift", "shift subtitles timing", OFFSET(shift), AV_OPT_TYPE_DURATION, {.i64 = 0}, INT64_MIN, INT64_MAX, FLAGS }, {NULL}, }; @@ -297,7 +304,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; @@ -448,6 +455,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx) av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; + nskip = 0; while (av_read_frame(fmt, &pkt) >= 0) { int i, got_subtitle; AVSubtitle sub = {0}; @@ -458,8 +466,17 @@ 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)); + 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) @@ -472,6 +489,8 @@ static av_cold int init_subtitles(AVFilterContext *ctx) } } } + +pkt_end: av_packet_unref(&pkt); avsubtitle_free(&sub); }