diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index 125fbd9ac7..09cca6aab8 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -67,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[] = {
@@ -106,7 +107,7 @@ static av_cold int init(AVFilterContext *ctx)
 
     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);
+        av_log(ctx, AV_LOG_INFO, "Shifting subtitles by %0.3fsec.\n", ass->shift/1000.0);
     }
 
     ass->library = ass_library_init();
@@ -233,6 +234,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);
 
@@ -249,6 +252,24 @@ 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;
+            nskip = 0;
+        }
+    }
+
     return 0;
 }
 
@@ -273,7 +294,6 @@ 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},
 };
 
@@ -466,6 +486,7 @@ 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) {
+                /* 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;
 
