diff --git a/NEWS b/NEWS
index b71c605e6e663fa86a9ba7739c350fe34be1f815..cd7591e273391441ecebd90fd493b4ce6a4193c9 100644
--- a/NEWS
+++ b/NEWS
@@ -2073,6 +2073,7 @@ Video Filters:
  * Improvements on the transform filter, to support 10bits and RGB formats
  * Revival of the openCV and openCV example filters
  * ARM NEON acceleration of chroma filters
+ * New crop filter without picture copy
 
 Stream Output:
  * Extended support for recording, notably for MKV and AVI
diff --git a/modules/video_filter/Makefile.am b/modules/video_filter/Makefile.am
index 85b8e3ae9ae58fb8a782c58c79a6416c4bc23cd1..c7fe5e0694a964289ee84d45cffd49e4d402c96d 100644
--- a/modules/video_filter/Makefile.am
+++ b/modules/video_filter/Makefile.am
@@ -34,6 +34,7 @@ libhqdn3d_plugin_la_SOURCES = video_filter/hqdn3d.c video_filter/hqdn3d.h
 libhqdn3d_plugin_la_LIBADD = $(LIBM)
 libinvert_plugin_la_SOURCES = video_filter/invert.c
 libmagnify_plugin_la_SOURCES = video_filter/magnify.c
+libformatcrop_plugin_la_SOURCES = video_filter/formatcrop.c
 libmirror_plugin_la_SOURCES = video_filter/mirror.c
 libmotionblur_plugin_la_SOURCES = video_filter/motionblur.c
 libmotiondetect_plugin_la_SOURCES = video_filter/motiondetect.c
@@ -86,6 +87,7 @@ video_filter_LTLIBRARIES = \
 	libgaussianblur_plugin.la \
 	libinvert_plugin.la \
 	libmagnify_plugin.la \
+	libformatcrop_plugin.la \
 	libmirror_plugin.la \
 	libmotionblur_plugin.la \
 	libmotiondetect_plugin.la \
diff --git a/modules/video_filter/formatcrop.c b/modules/video_filter/formatcrop.c
new file mode 100644
index 0000000000000000000000000000000000000000..78d1e41705004490f66afcc1355586bf66ea1636
--- /dev/null
+++ b/modules/video_filter/formatcrop.c
@@ -0,0 +1,194 @@
+/*****************************************************************************
+ * formatcrop.c
+ *****************************************************************************
+ * Copyright (C) 2021 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <limits.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_filter.h>
+#include <vlc_picture.h>
+
+/**
+ * This filter crops the input pictures by adjusting the format (offsets and
+ * size) without any copy (contrary to croppadd).
+ */
+
+#define CFG_PREFIX "formatcrop-"
+static const char *const filter_options[] = {
+    "top", "bottom", "left", "right", NULL,
+};
+
+#define CROPTOP_TEXT N_("Pixels to crop from top")
+#define CROPTOP_LONGTEXT \
+    N_("Number of pixels to crop from the top of the image.")
+
+#define CROPBOTTOM_TEXT N_("Pixels to crop from bottom")
+#define CROPBOTTOM_LONGTEXT \
+    N_("Number of pixels to crop from the bottom of the image.")
+
+#define CROPLEFT_TEXT N_("Pixels to crop from left")
+#define CROPLEFT_LONGTEXT \
+    N_("Number of pixels to crop from the left of the image.")
+
+#define CROPRIGHT_TEXT N_("Pixels to crop from right")
+#define CROPRIGHT_LONGTEXT \
+    N_("Number of pixels to crop from the right of the image.")
+
+struct sys {
+    unsigned x;
+    unsigned y;
+    unsigned width;
+    unsigned height;
+};
+
+#define IDX_TOP 0
+#define IDX_LEFT 1
+#define IDX_BOTTOM 2
+#define IDX_RIGHT 3
+
+struct transform {
+    unsigned idx_top;
+    unsigned idx_left;
+    /* idx_bottom is idx_top XOR 2
+       idx_right is idx_left XOR 2 */
+};
+
+static const struct transform transforms[8] = {
+    [ORIENT_TOP_LEFT]     = { IDX_TOP,    IDX_LEFT },
+    [ORIENT_TOP_RIGHT]    = { IDX_TOP,    IDX_RIGHT },
+    [ORIENT_BOTTOM_LEFT]  = { IDX_BOTTOM, IDX_LEFT },
+    [ORIENT_BOTTOM_RIGHT] = { IDX_BOTTOM, IDX_RIGHT },
+    [ORIENT_LEFT_TOP]     = { IDX_LEFT,   IDX_TOP },
+    [ORIENT_LEFT_BOTTOM]  = { IDX_LEFT,   IDX_BOTTOM },
+    [ORIENT_RIGHT_TOP]    = { IDX_RIGHT,  IDX_TOP },
+    [ORIENT_RIGHT_BOTTOM] = { IDX_RIGHT,  IDX_BOTTOM },
+};
+
+static picture_t *
+Filter(filter_t *filter, picture_t *pic)
+{
+    struct sys *sys = filter->p_sys;
+
+    if (!pic)
+        return NULL;
+
+    picture_t *out = picture_Clone(pic);
+    if (!out)
+        return NULL;
+    picture_CopyProperties(out, pic);
+
+    picture_Release(pic);
+
+    video_format_t *fmt = &out->format;
+    fmt->i_x_offset = sys->x;
+    fmt->i_y_offset = sys->y;
+    fmt->i_visible_width = sys->width;
+    fmt->i_visible_height = sys->height;
+
+    return out;
+}
+
+static void
+Close(filter_t *filter)
+{
+    struct sys *sys = filter->p_sys;
+    free(sys);
+}
+
+static int
+Open(filter_t *filter)
+{
+    config_ChainParse(filter, CFG_PREFIX, filter_options, filter->p_cfg);
+    unsigned top = var_InheritInteger(filter, CFG_PREFIX "top");
+    unsigned bottom = var_InheritInteger(filter, CFG_PREFIX "bottom");
+    unsigned left = var_InheritInteger(filter, CFG_PREFIX "left");
+    unsigned right = var_InheritInteger(filter, CFG_PREFIX "right");
+
+    video_format_t *fmt = &filter->fmt_in.video;
+    video_orientation_t orientation = fmt->orientation;
+
+    /* In the same order as IDX_ constants values */
+    unsigned crop[] = { top, left, bottom, right };
+
+    /* Transform from picture crop to physical crop (with orientation) */
+    const struct transform *tx = &transforms[orientation];
+    unsigned crop_top = crop[tx->idx_top];
+    unsigned crop_left = crop[tx->idx_left];
+    unsigned crop_bottom = crop[tx->idx_top ^ 2];
+    unsigned crop_right = crop[tx->idx_left ^ 2];
+
+    if (crop_top + crop_bottom >= fmt->i_visible_height)
+    {
+        msg_Err(filter, "Vertical crop (top=%u, bottom=%u) "
+                        "greater than the picture height (%u)\n",
+                        crop_top, crop_bottom, fmt->i_visible_height);
+        return VLC_EGENERIC;
+    }
+
+    if (crop_left + crop_right >= fmt->i_visible_width)
+    {
+        msg_Err(filter, "Horizontal crop (left=%u, right=%u) "
+                        "greater than the picture width (%u)\n",
+                        crop_left, crop_right, fmt->i_visible_width);
+        return VLC_EGENERIC;
+    }
+
+    struct sys *sys = malloc(sizeof(*sys));
+    if (!sys)
+        return VLC_EGENERIC;
+
+    filter->p_sys = sys;
+
+    sys->x = fmt->i_x_offset + crop_left;
+    sys->y = fmt->i_y_offset + crop_top;
+    sys->width = fmt->i_visible_width - crop_left - crop_right;
+    sys->height = fmt->i_visible_height - crop_top - crop_bottom;
+
+    static const struct vlc_filter_operations filter_ops =
+    {
+        .filter_video = Filter,
+        .close = Close,
+    };
+    filter->ops = &filter_ops;
+
+    return VLC_SUCCESS;
+}
+
+vlc_module_begin()
+    set_shortname("formatcrop")
+    set_description(N_("Video cropping filter"))
+    set_callback_video_filter(Open)
+
+    set_category(CAT_VIDEO)
+    set_subcategory(SUBCAT_VIDEO_VFILTER);
+
+    add_integer_with_range(CFG_PREFIX "top", 0, 0, INT_MAX,
+                           CROPTOP_TEXT, CROPTOP_LONGTEXT)
+    add_integer_with_range(CFG_PREFIX "bottom", 0, 0, INT_MAX,
+                           CROPBOTTOM_TEXT, CROPTOP_LONGTEXT)
+    add_integer_with_range(CFG_PREFIX "left", 0, 0, INT_MAX,
+                           CROPLEFT_TEXT, CROPTOP_LONGTEXT)
+    add_integer_with_range(CFG_PREFIX "right", 0, 0, INT_MAX,
+                           CROPRIGHT_TEXT, CROPTOP_LONGTEXT)
+vlc_module_end()
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5b31464ddd56e5a1a80210325eea1af39bd87bf1..73ee32bff713f20201b9281a97ceda207a52a660 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1301,6 +1301,7 @@ modules/video_filter/edgedetection.c
 modules/video_filter/erase.c
 modules/video_filter/extract.c
 modules/video_filter/fps.c
+modules/video_filter/formatcrop.c
 modules/video_filter/freeze.c
 modules/video_filter/gaussianblur.c
 modules/video_filter/gradfun.c