Re: [FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-08-01 Thread Cosmin Stejerean
On Jul 27, 2023, at 4:13 AM, Anton Khirnov  wrote:

Quoting Tomas Härdin (2023-07-26)
tis 2023-07-25 klockan 14:09 -0300 skrev James Almer:
Signed-off-by: James Almer 
---
Now inserting a filter into the graph.

This looks useful for MXF

+    { "apply_cropping",   HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT |
OPT_INPUT,    { .off =
OFFSET(apply_cropping) },
+    "Apply frame cropping instead of exporting it" },

Hm. Can this be applied automatically for ffplay? When transcoding I
expect the typical use case is to not crop and to carry the metadata
over.

Why? We do apply decoder cropping by default. There's also no guarantee
that your container will be able to write it, so it seems better to
apply it by default.


I agree. I see this similar to rotation. And edit lists.

For remuxing we want to keep the metadata and have the muxer write it, but if 
we're going to transcode anyway we should simplify the stream (apply rotation, 
apply cropping, keep only visible frames, etc) and write out something as 
simple as possible. Anyone that doesn't want this can opt out of it like opting 
out of autorotation.

Not doing this means compatibility is worse when downstream players inevitably 
don't handle something properly (edit lists are still a mess in terms of 
compatibility for example). And of potentially displaying content that the user 
did not intend to be displayed.

- Cosmin
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-07-31 Thread Tomas Härdin
tor 2023-07-27 klockan 08:59 -0300 skrev James Almer:
> On 7/27/2023 8:13 AM, Anton Khirnov wrote:
> > Quoting Tomas Härdin (2023-07-26)
> > > tis 2023-07-25 klockan 14:09 -0300 skrev James Almer:
> > > > Signed-off-by: James Almer 
> > > > ---
> > > > Now inserting a filter into the graph.
> > > 
> > > This looks useful for MXF
> > > 
> > > > +    { "apply_cropping",   HAS_ARG | OPT_BOOL | OPT_SPEC |
> > > > +  OPT_EXPERT |
> > > > OPT_INPUT,    { .off =
> > > > OFFSET(apply_cropping) },
> > > > +    "Apply frame cropping instead of exporting it" },
> > > 
> > > Hm. Can this be applied automatically for ffplay? When
> > > transcoding I
> > > expect the typical use case is to not crop and to carry the
> > > metadata
> > > over.
> > 
> > Why? We do apply decoder cropping by default. There's also no
> > guarantee
> > that your container will be able to write it, so it seems better to
> > apply it by default.

Not necessarily. Doing this by default may break some downstream
projects. The relevant metadata must be deleted if this is done, so
that the cropping isn't done twice when you get to playout.

> I agree. In a transcoding scenario you want to apply the container
> level 
> cropping since it's defining a subrectangle with the actual content 
> meant for display, so why force the encoder handle pixels that were 
> meant to be discarded to being with, potentially ruining encoding 
> quality for neighboring pixels?
> 
> For codec copy scenarios though, the side data is going to be copied,
> so 
> Tomas' idea of having muxers report they support writing it is good 
> either way.

My main concern is not losing pixels if we can avoid it, even if those
pixels are invisible. On the other hand, when transcoding, we could go
with always cropping unless the user requests otherwise. This has the
benefit of essence dimensions not changing with container. Also less
work for the encoder. But again, this is a behavior change that may
break things downstream.

Basically what I'm suggesting is that ffplay behave as playout. We
could have ffmpeg behave similarly but we should keep in mind this may
break some workflows.

/Tomas
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-07-27 Thread James Almer

On 7/27/2023 8:13 AM, Anton Khirnov wrote:

Quoting Tomas Härdin (2023-07-26)

tis 2023-07-25 klockan 14:09 -0300 skrev James Almer:

Signed-off-by: James Almer 
---
Now inserting a filter into the graph.


This looks useful for MXF


+    { "apply_cropping",   HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT |
OPT_INPUT,    { .off =
OFFSET(apply_cropping) },
+    "Apply frame cropping instead of exporting it" },


Hm. Can this be applied automatically for ffplay? When transcoding I
expect the typical use case is to not crop and to carry the metadata
over.


Why? We do apply decoder cropping by default. There's also no guarantee
that your container will be able to write it, so it seems better to
apply it by default.


I agree. In a transcoding scenario you want to apply the container level 
cropping since it's defining a subrectangle with the actual content 
meant for display, so why force the encoder handle pixels that were 
meant to be discarded to being with, potentially ruining encoding 
quality for neighboring pixels?


For codec copy scenarios though, the side data is going to be copied, so 
Tomas' idea of having muxers report they support writing it is good 
either way.

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-07-27 Thread Anton Khirnov
Quoting Tomas Härdin (2023-07-26)
> tis 2023-07-25 klockan 14:09 -0300 skrev James Almer:
> > Signed-off-by: James Almer 
> > ---
> > Now inserting a filter into the graph.
> 
> This looks useful for MXF
> 
> > +    { "apply_cropping",   HAS_ARG | OPT_BOOL | OPT_SPEC |
> > +  OPT_EXPERT |
> > OPT_INPUT,    { .off =
> > OFFSET(apply_cropping) },
> > +    "Apply frame cropping instead of exporting it" },
> 
> Hm. Can this be applied automatically for ffplay? When transcoding I
> expect the typical use case is to not crop and to carry the metadata
> over.

Why? We do apply decoder cropping by default. There's also no guarantee
that your container will be able to write it, so it seems better to
apply it by default.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-07-27 Thread Tomas Härdin
ons 2023-07-26 klockan 19:11 -0300 skrev James Almer:
> On 7/26/2023 6:42 PM, Tomas Härdin wrote:
> > tis 2023-07-25 klockan 14:09 -0300 skrev James Almer:
> > > Signed-off-by: James Almer 
> > > ---
> > > Now inserting a filter into the graph.
> > 
> > This looks useful for MXF
> > 
> > > +    { "apply_cropping",   HAS_ARG | OPT_BOOL | OPT_SPEC |
> > > +  OPT_EXPERT |
> > > OPT_INPUT,    { .off =
> > > OFFSET(apply_cropping) },
> > > +    "Apply frame cropping instead of exporting it" },
> > 
> > Hm. Can this be applied automatically for ffplay? When transcoding
> > I
> > expect the typical use case is to not crop and to carry the
> > metadata
> > over. MXF -> MOV for example. But when playing I expect one just
> > wants
> > to see the display rectangle.
> 
> You want it to be disabled by default on ffmpeg but enabled in
> ffplay?

Yeah that seems like it'd be most user friendly. Then 3rd party
developers can look at ffplay to see how to apply it in their own
players. mpv and vlc come to mind

> For the latter, something like:
> 
> > diff --git a/fftools/ffplay.c b/fftools/ffplay.c
> > index 5212ad053e..217fc3e45a 100644
> > --- a/fftools/ffplay.c
> > +++ b/fftools/ffplay.c
> > @@ -36,6 +36,7 @@
> >  #include "libavutil/eval.h"
> >  #include "libavutil/mathematics.h"
> >  #include "libavutil/pixdesc.h"
> > +#include "libavutil/intreadwrite.h"
> >  #include "libavutil/imgutils.h"
> >  #include "libavutil/dict.h"
> >  #include "libavutil/fifo.h"
> > @@ -346,6 +347,7 @@ static const char **vfilters_list = NULL;
> >  static int nb_vfilters = 0;
> >  static char *afilters = NULL;
> >  static int autorotate = 1;
> > +static int apply_cropping = 1;
> >  static int find_stream_info = 1;
> >  static int filter_nbthreads = 0;
> > 
> > @@ -1922,6 +1924,27 @@ static int
> > configure_video_filters(AVFilterGraph *graph, VideoState *is, const
> > c
> >  }
> >  }
> > 
> > +    if (apply_cropping) {
> > +    size_t cropping_size;
> > +    uint8_t *cropping = av_stream_get_side_data(is->video_st,
> > AV_PKT_DATA_FRAME_CROPPING, _size);
> > +
> > +    if (cropping && cropping_size == sizeof(uint32_t) * 4) {
> > +    char crop_buf[64];
> > +    int top    = AV_RL32(cropping +  0);
> > +    int bottom = AV_RL32(cropping +  4);
> > +    int left   = AV_RL32(cropping +  8);
> > +    int right  = AV_RL32(cropping + 12);
> > +
> > +    if (top < 0 || bottom < 0 || left < 0 || right < 0)  {
> > +    ret = AVERROR(EINVAL);
> > +    goto fail;
> > +    }
> > +
> > +    snprintf(crop_buf, sizeof(crop_buf), "w=iw-%d-%d:h=ih-
> > %d-%d", left, right, top, bottom);
> > +    INSERT_FILT("crop", crop_buf);
> > +    }
> > +    }
> > +
> >  if ((ret = configure_filtergraph(graph, vfilters, filt_src,
> > last_filter)) < 0)
> >  goto fail;
> > 
> > @@ -3593,6 +3616,7 @@ static const OptionDef options[] = {
> >  { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {
> > _codec_name }, "force subtitle decoder", "decoder_name" },
> >  { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {   
> > _codec_name }, "force video decoder",    "decoder_name" },
> >  { "autorotate", OPT_BOOL, {  }, "automatically
> > rotate video", "" },
> > +    { "apply_cropping", OPT_BOOL, { _cropping }, "apply
> > frame cropping", "" },
> >  { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, {
> > _stream_info },
> >  "read and decode the streams to fill missing information
> > with heuristics" },
> >  { "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, {
> > _nbthreads }, "number of filter threads per graph" },
> 
> Would do it, but i don't know if this affects the AVCodecContext
> option 
> of the same name too or not (to apply or not bitstream level
> cropping, 
> like the h264 one, which is obviously enabled by default).

Right, there's multiple levels of cropping

> To have it disabled on ffmpeg by default, i think the following would
> work (on top of this patch):
> 
> > diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
> > index 1209cf2046..a37c136cf9 100644
> > --- a/fftools/ffmpeg_demux.c
> > +++ b/fftools/ffmpeg_demux.c
> > @@ -1086,10 +1086,11 @@ static int ist_add(const OptionsContext *o,
> > Demuxer *d, AVStream *st)
> >  ist->autorotate = 1;
> >  MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
> > 
> > -    ist->apply_cropping = 1;
> > +    ist->apply_cropping = -1;
> >  MATCH_PER_STREAM_OPT(apply_cropping, i, ist->apply_cropping,
> > ic, st);
> > 
> > -    av_dict_set_int(>g->codec_opts, "apply_cropping", ist-
> > >apply_cropping, 0);
> > +    if (ist->apply_cropping >= 0)
> > +    av_dict_set_int(>g->codec_opts, "apply_cropping", ist-
> > >apply_cropping, 0);
> > 
> >  MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
> >  if (codec_tag) {
> > diff --git a/fftools/ffmpeg_filter.c 

Re: [FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-07-26 Thread James Almer

On 7/26/2023 6:42 PM, Tomas Härdin wrote:

tis 2023-07-25 klockan 14:09 -0300 skrev James Almer:

Signed-off-by: James Almer 
---
Now inserting a filter into the graph.


This looks useful for MXF


+    { "apply_cropping",   HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT |
OPT_INPUT,    { .off =
OFFSET(apply_cropping) },
+    "Apply frame cropping instead of exporting it" },


Hm. Can this be applied automatically for ffplay? When transcoding I
expect the typical use case is to not crop and to carry the metadata
over. MXF -> MOV for example. But when playing I expect one just wants
to see the display rectangle.


You want it to be disabled by default on ffmpeg but enabled in ffplay?

For the latter, something like:


diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index 5212ad053e..217fc3e45a 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -36,6 +36,7 @@
 #include "libavutil/eval.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/dict.h"
 #include "libavutil/fifo.h"
@@ -346,6 +347,7 @@ static const char **vfilters_list = NULL;
 static int nb_vfilters = 0;
 static char *afilters = NULL;
 static int autorotate = 1;
+static int apply_cropping = 1;
 static int find_stream_info = 1;
 static int filter_nbthreads = 0;

@@ -1922,6 +1924,27 @@ static int configure_video_filters(AVFilterGraph *graph, 
VideoState *is, const c
 }
 }

+if (apply_cropping) {
+size_t cropping_size;
+uint8_t *cropping = av_stream_get_side_data(is->video_st, 
AV_PKT_DATA_FRAME_CROPPING, _size);
+
+if (cropping && cropping_size == sizeof(uint32_t) * 4) {
+char crop_buf[64];
+int top= AV_RL32(cropping +  0);
+int bottom = AV_RL32(cropping +  4);
+int left   = AV_RL32(cropping +  8);
+int right  = AV_RL32(cropping + 12);
+
+if (top < 0 || bottom < 0 || left < 0 || right < 0)  {
+ret = AVERROR(EINVAL);
+goto fail;
+}
+
+snprintf(crop_buf, sizeof(crop_buf), "w=iw-%d-%d:h=ih-%d-%d", 
left, right, top, bottom);
+INSERT_FILT("crop", crop_buf);
+}
+}
+
 if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) 
< 0)
 goto fail;

@@ -3593,6 +3616,7 @@ static const OptionDef options[] = {
 { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { _codec_name }, "force subtitle 
decoder", "decoder_name" },
 { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {_codec_name }, "force video 
decoder","decoder_name" },
 { "autorotate", OPT_BOOL, {  }, "automatically rotate video", 
"" },
+{ "apply_cropping", OPT_BOOL, { _cropping }, "apply frame cropping", 
"" },
 { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { 
_stream_info },
 "read and decode the streams to fill missing information with 
heuristics" },
 { "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, { _nbthreads }, 
"number of filter threads per graph" },


Would do it, but i don't know if this affects the AVCodecContext option 
of the same name too or not (to apply or not bitstream level cropping, 
like the h264 one, which is obviously enabled by default).


To have it disabled on ffmpeg by default, i think the following would 
work (on top of this patch):



diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 1209cf2046..a37c136cf9 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -1086,10 +1086,11 @@ static int ist_add(const OptionsContext *o, Demuxer *d, 
AVStream *st)
 ist->autorotate = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);

-ist->apply_cropping = 1;
+ist->apply_cropping = -1;
 MATCH_PER_STREAM_OPT(apply_cropping, i, ist->apply_cropping, ic, st);

-av_dict_set_int(>g->codec_opts, "apply_cropping", ist->apply_cropping, 
0);
+if (ist->apply_cropping >= 0)
+av_dict_set_int(>g->codec_opts, "apply_cropping", 
ist->apply_cropping, 0);

 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 8cadb4732c..5df52ef718 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -1419,7 +1419,7 @@ static int configure_input_video_filter(FilterGraph *fg, 
InputFilter *ifilter,
 return ret;
 }

-if (ist->apply_cropping && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
+if (ist->apply_cropping > 0 && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
 size_t cropping_size;
 uint8_t *cropping = av_stream_get_side_data(ist->st, 
AV_PKT_DATA_FRAME_CROPPING, _size);



And actually work fine with the AVCodecContext option.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org

Re: [FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-07-26 Thread Tomas Härdin
tis 2023-07-25 klockan 14:09 -0300 skrev James Almer:
> Signed-off-by: James Almer 
> ---
> Now inserting a filter into the graph.

This looks useful for MXF

> +    { "apply_cropping",   HAS_ARG | OPT_BOOL | OPT_SPEC |
> +  OPT_EXPERT |
> OPT_INPUT,    { .off =
> OFFSET(apply_cropping) },
> +    "Apply frame cropping instead of exporting it" },

Hm. Can this be applied automatically for ffplay? When transcoding I
expect the typical use case is to not crop and to carry the metadata
over. MXF -> MOV for example. But when playing I expect one just wants
to see the display rectangle.

/Tomas
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 5/5] fftools/ffmpeg: support applying container level cropping

2023-07-25 Thread James Almer
Signed-off-by: James Almer 
---
Now inserting a filter into the graph.

 fftools/ffmpeg.h|  3 +++
 fftools/ffmpeg_demux.c  |  6 ++
 fftools/ffmpeg_enc.c| 19 +++
 fftools/ffmpeg_filter.c | 22 ++
 fftools/ffmpeg_opt.c|  3 +++
 5 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index d53181e427..bb6d510f10 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -154,6 +154,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *apply_cropping;
+intnb_apply_cropping;
 
 /* output options */
 StreamMap *stream_maps;
@@ -347,6 +349,7 @@ typedef struct InputStream {
 int top_field_first;
 
 int autorotate;
+int apply_cropping;
 
 int fix_sub_duration;
 
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 48edbd7f6b..1209cf2046 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -48,6 +48,7 @@ static const char *const opt_name_hwaccels[]  
= {"hwaccel", NULL
 static const char *const opt_name_hwaccel_devices[]   = 
{"hwaccel_device", NULL};
 static const char *const opt_name_hwaccel_output_formats[]= 
{"hwaccel_output_format", NULL};
 static const char *const opt_name_autorotate[]= {"autorotate", 
NULL};
+static const char *const opt_name_apply_cropping[]= 
{"apply_cropping", NULL};
 static const char *const opt_name_display_rotations[] = 
{"display_rotation", NULL};
 static const char *const opt_name_display_hflips[]= 
{"display_hflip", NULL};
 static const char *const opt_name_display_vflips[]= 
{"display_vflip", NULL};
@@ -1085,6 +1086,11 @@ static int ist_add(const OptionsContext *o, Demuxer *d, 
AVStream *st)
 ist->autorotate = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
 
+ist->apply_cropping = 1;
+MATCH_PER_STREAM_OPT(apply_cropping, i, ist->apply_cropping, ic, st);
+
+av_dict_set_int(>g->codec_opts, "apply_cropping", ist->apply_cropping, 
0);
+
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
 uint32_t tag = strtol(codec_tag, , 0);
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 96424272bf..cd30986344 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -448,14 +448,17 @@ int enc_open(OutputStream *ost, AVFrame *frame)
 int i;
 for (i = 0; i < ist->st->nb_side_data; i++) {
 AVPacketSideData *sd = >st->side_data[i];
-if (sd->type != AV_PKT_DATA_CPB_PROPERTIES) {
-uint8_t *dst = av_stream_new_side_data(ost->st, sd->type, 
sd->size);
-if (!dst)
-return AVERROR(ENOMEM);
-memcpy(dst, sd->data, sd->size);
-if (ist->autorotate && sd->type == AV_PKT_DATA_DISPLAYMATRIX)
-av_display_rotation_set((int32_t *)dst, 0);
-}
+uint8_t *dst;
+if (sd->type == AV_PKT_DATA_CPB_PROPERTIES)
+continue;
+if (ist->apply_cropping && sd->type == AV_PKT_DATA_FRAME_CROPPING)
+continue;
+dst = av_stream_new_side_data(ost->st, sd->type, sd->size);
+if (!dst)
+return AVERROR(ENOMEM);
+memcpy(dst, sd->data, sd->size);
+if (ist->autorotate && sd->type == AV_PKT_DATA_DISPLAYMATRIX)
+av_display_rotation_set((int32_t *)dst, 0);
 }
 }
 
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 925b5116cc..8cadb4732c 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -31,6 +31,7 @@
 #include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/display.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/pixfmt.h"
@@ -1418,6 +1419,27 @@ static int configure_input_video_filter(FilterGraph *fg, 
InputFilter *ifilter,
 return ret;
 }
 
+if (ist->apply_cropping && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
+size_t cropping_size;
+uint8_t *cropping = av_stream_get_side_data(ist->st, 
AV_PKT_DATA_FRAME_CROPPING, _size);
+
+if (cropping && cropping_size == sizeof(uint32_t) * 4) {
+char crop_buf[64];
+int top= AV_RL32(cropping +  0);
+int bottom = AV_RL32(cropping +  4);
+int left   = AV_RL32(cropping +  8);
+int right  = AV_RL32(cropping + 12);
+
+if (top < 0 || bottom < 0 || left < 0 || right < 0)
+return AVERROR(EINVAL);
+
+snprintf(crop_buf, sizeof(crop_buf), "w=iw-%d-%d:h=ih-%d-%d", 
left, right, top, bottom);
+ret = insert_filter(_filter, _idx, "crop", crop_buf);
+if (ret < 0)