diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index 343585fc5e0b2db653c3234084c8e05508d6f047..e8b5431caf16327ac6b201e67b52867ccd28dbeb 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -214,42 +214,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
     return 0;
 }
 
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
-    AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *outpicref = NULL, *for_next_filter;
-    int ret = 0;
-
-    if (inpicref->perms & AV_PERM_PRESERVE) {
-        outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE,
-                                        outlink->w, outlink->h);
-        if (!outpicref)
-            return AVERROR(ENOMEM);
-
-        avfilter_copy_buffer_ref_props(outpicref, inpicref);
-        outpicref->video->w = outlink->w;
-        outpicref->video->h = outlink->h;
-    } else {
-        outpicref = avfilter_ref_buffer(inpicref, ~0);
-        if (!outpicref)
-            return AVERROR(ENOMEM);
-    }
-
-    for_next_filter = avfilter_ref_buffer(outpicref, ~0);
-    if (for_next_filter)
-        ret = ff_start_frame(outlink, for_next_filter);
-    else
-        ret = AVERROR(ENOMEM);
-
-    if (ret < 0) {
-        avfilter_unref_bufferp(&outpicref);
-        return ret;
-    }
-
-    outlink->out_buf = outpicref;
-    return 0;
-}
-
 static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
 {
     return 0;
@@ -296,7 +260,7 @@ AVFilter avfilter_vf_delogo = {
     .inputs    = (const AVFilterPad[]) {{ .name             = "default",
                                           .type             = AVMEDIA_TYPE_VIDEO,
                                           .get_video_buffer = ff_null_get_video_buffer,
-                                          .start_frame      = start_frame,
+                                          .start_frame      = ff_inplace_start_frame,
                                           .draw_slice       = null_draw_slice,
                                           .end_frame        = end_frame,
                                           .min_perms        = AV_PERM_WRITE | AV_PERM_READ,
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 52dcb7092fc9f1d3a23b6461adec492098757840..f8896b5e574e4f1c71797f6d930fee7a7b44e24e 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -180,41 +180,6 @@ static int config_input(AVFilterLink *inlink)
     return 0;
 }
 
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
-    AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *outpicref = NULL, *for_next_filter;
-    int ret = 0;
-
-    if (inpicref->perms & AV_PERM_PRESERVE) {
-        outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
-        if (!outpicref)
-            return AVERROR(ENOMEM);
-
-        avfilter_copy_buffer_ref_props(outpicref, inpicref);
-        outpicref->video->w = outlink->w;
-        outpicref->video->h = outlink->h;
-    } else {
-        outpicref = avfilter_ref_buffer(inpicref, ~0);
-        if (!outpicref)
-            return AVERROR(ENOMEM);
-    }
-
-    for_next_filter = avfilter_ref_buffer(outpicref, ~0);
-    if (for_next_filter)
-        ret = ff_start_frame(outlink, for_next_filter);
-    else
-        ret = AVERROR(ENOMEM);
-
-    if (ret < 0) {
-        avfilter_unref_bufferp(&outpicref);
-        return ret;
-    }
-
-    outlink->out_buf = outpicref;
-    return 0;
-}
-
 static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
 {
     return 0;
@@ -261,7 +226,7 @@ AVFilter avfilter_vf_gradfun = {
     .inputs    = (const AVFilterPad[]) {{ .name             = "default",
                                           .type             = AVMEDIA_TYPE_VIDEO,
                                           .config_props     = config_input,
-                                          .start_frame      = start_frame,
+                                          .start_frame      = ff_inplace_start_frame,
                                           .draw_slice       = null_draw_slice,
                                           .end_frame        = end_frame,
                                           .min_perms        = AV_PERM_READ, },
diff --git a/libavfilter/video.c b/libavfilter/video.c
index 6e5063778a37678e74e6d4a5252b728698e75e35..ebbbc346bc7f157ec086178df189427cdd5c6711 100644
--- a/libavfilter/video.c
+++ b/libavfilter/video.c
@@ -168,6 +168,42 @@ int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
     return ff_start_frame(link->dst->outputs[0], buf_out);
 }
 
+// for filters that support (but don't require) outpic==inpic
+int ff_inplace_start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *outpicref = NULL, *for_next_filter;
+    int ret = 0;
+
+    if ((inpicref->perms & AV_PERM_WRITE) && !(inpicref->perms & AV_PERM_PRESERVE)) {
+        outpicref = avfilter_ref_buffer(inpicref, ~0);
+        if (!outpicref)
+            return AVERROR(ENOMEM);
+    } else {
+        outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        if (!outpicref)
+            return AVERROR(ENOMEM);
+
+        avfilter_copy_buffer_ref_props(outpicref, inpicref);
+        outpicref->video->w = outlink->w;
+        outpicref->video->h = outlink->h;
+    }
+
+    for_next_filter = avfilter_ref_buffer(outpicref, ~0);
+    if (for_next_filter)
+        ret = ff_start_frame(outlink, for_next_filter);
+    else
+        ret = AVERROR(ENOMEM);
+
+    if (ret < 0) {
+        avfilter_unref_bufferp(&outpicref);
+        return ret;
+    }
+
+    outlink->out_buf = outpicref;
+    return 0;
+}
+
 static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
 {
     AVFilterLink *outlink = NULL;
diff --git a/libavfilter/video.h b/libavfilter/video.h
index ef4a1a9c326bedd1b25a2fb0aad6246990acfc09..348240c6e62ba57c28650bb993af8ec45713bef6 100644
--- a/libavfilter/video.h
+++ b/libavfilter/video.h
@@ -39,6 +39,7 @@ AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w
 AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
                                        int w, int h);
 
+int ff_inplace_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
 int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref);
 int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir);
 int ff_null_end_frame(AVFilterLink *link);