diff mbox

[FFmpeg-devel,v2] avfilter/vf_freezedetect: add discard option to force drop freezen frame

Message ID 20191008035428.19474-1-lance.lmwang@gmail.com
State New
Headers show

Commit Message

Lance Wang Oct. 8, 2019, 3:54 a.m. UTC
From: Limin Wang <lance.lmwang@gmail.com>

How to tested it, please try with the following command:
./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=0"  -f null -
frame=  150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed= 234x

./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=1"  -f null -
frame=   30 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.00 bitrate=N/A speed=59.7x

Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
---
 doc/filters.texi              | 10 ++++++++++
 libavfilter/vf_freezedetect.c |  8 +++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

Comments

Gyan Doshi Oct. 8, 2019, 4:32 a.m. UTC | #1
On 08-10-2019 09:24 AM, lance.lmwang@gmail.com wrote:
> From: Limin Wang <lance.lmwang@gmail.com>
>
> How to tested it, please try with the following command:
> ./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=0"  -f null -
> frame=  150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed= 234x
>
> ./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=1"  -f null -
> frame=   30 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.00 bitrate=N/A speed=59.7x
>
> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> ---
>   doc/filters.texi              | 10 ++++++++++
>   libavfilter/vf_freezedetect.c |  8 +++++++-
>   2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 333f502083..8aa7471f7e 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -10678,6 +10678,9 @@ timestamp of the first frame of the freeze. The
>   @code{lavfi.freezedetect.freeze_duration} and
>   @code{lavfi.freezedetect.freeze_end} metadata keys are set on the first frame
>   after the freeze.
> +In addition, you can choose to discard the freezen frames instead of report
> +by metadata. Please note the first few freezen frames (the detection interval)
> +won't be dropped for the filter doesn't buffer any frames.
>   
freezen --> frozen
You could suggest that users apply tpad at start of stream so that all 
frozen frames can be removed. Afterwards, users can trim out those added 
frames.
Test this if you add it.

>   The filter accepts the following options:
>   
> @@ -10689,6 +10692,13 @@ specified value) or as a difference ratio between 0 and 1. Default is -60dB, or
>   
>   @item duration, d
>   Set freeze duration until notification (default is 2 seconds).
> +
> +@item discard
> +Set force to discard freezen frame.
> + 0:  do nothing
> + 1:  discard freezen frame
> +
> +Default is 0
>   @end table
>   
>   @anchor{frei0r}
> diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
> index cc086afee6..cc115eb521 100644
> --- a/libavfilter/vf_freezedetect.c
> +++ b/libavfilter/vf_freezedetect.c
> @@ -45,6 +45,8 @@ typedef struct FreezeDetectContext {
>   
>       double noise;
>       int64_t duration;            ///< minimum duration of frozen frame until notification
> +
> +    int discard;                 ///< 0: no discard, 1: discard freezen frame
>   } FreezeDetectContext;
>   
>   #define OFFSET(x) offsetof(FreezeDetectContext, x)
> @@ -56,6 +58,7 @@ static const AVOption freezedetect_options[] = {
>       { "noise",               "set noise tolerance",                       OFFSET(noise),  AV_OPT_TYPE_DOUBLE,   {.dbl=0.001},     0,       1.0, V|F },
>       { "d",                   "set minimum duration in seconds",        OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F },
>       { "duration",            "set minimum duration in seconds",        OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F },
> +    { "discard",             "set frame discard flag",                 OFFSET(discard),   AV_OPT_TYPE_BOOL,     {.i64=0},         0,         1, V|F },
>   
>       {NULL}
>   };
> @@ -196,7 +199,10 @@ static int activate(AVFilterContext *ctx)
>                   return AVERROR(ENOMEM);
>               }
>           }
> -        return ff_filter_frame(outlink, frame);
> +        if (s->discard && s->frozen) {
> +            av_frame_free(&frame);
> +        } else
> +            return ff_filter_frame(outlink, frame);
>       }
>   
>       FF_FILTER_FORWARD_STATUS(inlink, outlink);

Gyan
Lance Wang Oct. 8, 2019, 5:28 a.m. UTC | #2
On Tue, Oct 08, 2019 at 10:02:25AM +0530, Gyan wrote:
> 
> 
> On 08-10-2019 09:24 AM, lance.lmwang@gmail.com wrote:
> >From: Limin Wang <lance.lmwang@gmail.com>
> >
> >How to tested it, please try with the following command:
> >./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=0"  -f null -
> >frame=  150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed= 234x
> >
> >./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=1"  -f null -
> >frame=   30 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.00 bitrate=N/A speed=59.7x
> >
> >Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> >---
> >  doc/filters.texi              | 10 ++++++++++
> >  libavfilter/vf_freezedetect.c |  8 +++++++-
> >  2 files changed, 17 insertions(+), 1 deletion(-)
> >
> >diff --git a/doc/filters.texi b/doc/filters.texi
> >index 333f502083..8aa7471f7e 100644
> >--- a/doc/filters.texi
> >+++ b/doc/filters.texi
> >@@ -10678,6 +10678,9 @@ timestamp of the first frame of the freeze. The
> >  @code{lavfi.freezedetect.freeze_duration} and
> >  @code{lavfi.freezedetect.freeze_end} metadata keys are set on the first frame
> >  after the freeze.
> >+In addition, you can choose to discard the freezen frames instead of report
> >+by metadata. Please note the first few freezen frames (the detection interval)
> >+won't be dropped for the filter doesn't buffer any frames.
> freezen --> frozen

OK, will fix it.

> You could suggest that users apply tpad at start of stream so that
> all frozen frames can be removed. Afterwards, users can trim out
> those added frames.
> Test this if you add it.

I'm not familar with tpad and trim filter yet, anyway, it's not easy to
use it. If you think it's useful to remove all frozen frames, I prefer
to sumit another patch to fix it with frame cached.

> 
> >  The filter accepts the following options:
> >@@ -10689,6 +10692,13 @@ specified value) or as a difference ratio between 0 and 1. Default is -60dB, or
> >  @item duration, d
> >  Set freeze duration until notification (default is 2 seconds).
> >+
> >+@item discard
> >+Set force to discard freezen frame.
> >+ 0:  do nothing
> >+ 1:  discard freezen frame
> >+
> >+Default is 0
> >  @end table
> >  @anchor{frei0r}
> >diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
> >index cc086afee6..cc115eb521 100644
> >--- a/libavfilter/vf_freezedetect.c
> >+++ b/libavfilter/vf_freezedetect.c
> >@@ -45,6 +45,8 @@ typedef struct FreezeDetectContext {
> >      double noise;
> >      int64_t duration;            ///< minimum duration of frozen frame until notification
> >+
> >+    int discard;                 ///< 0: no discard, 1: discard freezen frame
> >  } FreezeDetectContext;
> >  #define OFFSET(x) offsetof(FreezeDetectContext, x)
> >@@ -56,6 +58,7 @@ static const AVOption freezedetect_options[] = {
> >      { "noise",               "set noise tolerance",                       OFFSET(noise),  AV_OPT_TYPE_DOUBLE,   {.dbl=0.001},     0,       1.0, V|F },
> >      { "d",                   "set minimum duration in seconds",        OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F },
> >      { "duration",            "set minimum duration in seconds",        OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F },
> >+    { "discard",             "set frame discard flag",                 OFFSET(discard),   AV_OPT_TYPE_BOOL,     {.i64=0},         0,         1, V|F },
> >      {NULL}
> >  };
> >@@ -196,7 +199,10 @@ static int activate(AVFilterContext *ctx)
> >                  return AVERROR(ENOMEM);
> >              }
> >          }
> >-        return ff_filter_frame(outlink, frame);
> >+        if (s->discard && s->frozen) {
> >+            av_frame_free(&frame);
> >+        } else
> >+            return ff_filter_frame(outlink, frame);
> >      }
> >      FF_FILTER_FORWARD_STATUS(inlink, outlink);
> 
> Gyan
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Gyan Doshi Oct. 8, 2019, 5:42 a.m. UTC | #3
On 08-10-2019 10:58 AM, Limin Wang wrote:
> On Tue, Oct 08, 2019 at 10:02:25AM +0530, Gyan wrote:
>>
>> On 08-10-2019 09:24 AM, lance.lmwang@gmail.com wrote:
>>> From: Limin Wang <lance.lmwang@gmail.com>
>>>
>>> How to tested it, please try with the following command:
>>> ./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=0"  -f null -
>>> frame=  150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed= 234x
>>>
>>> ./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=1"  -f null -
>>> frame=   30 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.00 bitrate=N/A speed=59.7x
>>>
>>> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
>>> ---
>>>   doc/filters.texi              | 10 ++++++++++
>>>   libavfilter/vf_freezedetect.c |  8 +++++++-
>>>   2 files changed, 17 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/doc/filters.texi b/doc/filters.texi
>>> index 333f502083..8aa7471f7e 100644
>>> --- a/doc/filters.texi
>>> +++ b/doc/filters.texi
>>> @@ -10678,6 +10678,9 @@ timestamp of the first frame of the freeze. The
>>>   @code{lavfi.freezedetect.freeze_duration} and
>>>   @code{lavfi.freezedetect.freeze_end} metadata keys are set on the first frame
>>>   after the freeze.
>>> +In addition, you can choose to discard the freezen frames instead of report
>>> +by metadata. Please note the first few freezen frames (the detection interval)
>>> +won't be dropped for the filter doesn't buffer any frames.
>> freezen --> frozen
> OK, will fix it.
>
>> You could suggest that users apply tpad at start of stream so that
>> all frozen frames can be removed. Afterwards, users can trim out
>> those added frames.
>> Test this if you add it.
> I'm not familar with tpad and trim filter yet, anyway, it's not easy to
> use it. If you think it's useful to remove all frozen frames, I prefer
> to sumit another patch to fix it with frame cached.

Yes, the filter should remove all frozen frames. That it doesn't, is a 
current limitation.
If the limitation can be removed internally, that is preferable to 
external workarounds.

Gyan
Paul B Mahol Oct. 8, 2019, 7:42 a.m. UTC | #4
On 10/8/19, lance.lmwang@gmail.com <lance.lmwang@gmail.com> wrote:
> From: Limin Wang <lance.lmwang@gmail.com>
>
> How to tested it, please try with the following command:
> ./ffmpeg  -f lavfi -i
> "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=0"  -f
> null -
> frame=  150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed=
> 234x
>
> ./ffmpeg  -f lavfi -i
> "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=1"  -f
> null -
> frame=   30 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.00 bitrate=N/A
> speed=59.7x
>
> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> ---
>  doc/filters.texi              | 10 ++++++++++
>  libavfilter/vf_freezedetect.c |  8 +++++++-
>  2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 333f502083..8aa7471f7e 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -10678,6 +10678,9 @@ timestamp of the first frame of the freeze. The
>  @code{lavfi.freezedetect.freeze_duration} and
>  @code{lavfi.freezedetect.freeze_end} metadata keys are set on the first
> frame
>  after the freeze.
> +In addition, you can choose to discard the freezen frames instead of report
> +by metadata. Please note the first few freezen frames (the detection
> interval)
> +won't be dropped for the filter doesn't buffer any frames.

This is no go. You can not claim one and do something else completely
differently.

If you want to drop frozen frames it should drop all frozen frames.
If you want to trim frozen frames it should trim all frozen frames.


>
>  The filter accepts the following options:
>
> @@ -10689,6 +10692,13 @@ specified value) or as a difference ratio between 0
> and 1. Default is -60dB, or
>
>  @item duration, d
>  Set freeze duration until notification (default is 2 seconds).
> +
> +@item discard
> +Set force to discard freezen frame.
> + 0:  do nothing
> + 1:  discard freezen frame
> +
> +Default is 0
>  @end table
>
>  @anchor{frei0r}
> diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
> index cc086afee6..cc115eb521 100644
> --- a/libavfilter/vf_freezedetect.c
> +++ b/libavfilter/vf_freezedetect.c
> @@ -45,6 +45,8 @@ typedef struct FreezeDetectContext {
>
>      double noise;
>      int64_t duration;            ///< minimum duration of frozen frame
> until notification
> +
> +    int discard;                 ///< 0: no discard, 1: discard freezen
> frame
>  } FreezeDetectContext;
>
>  #define OFFSET(x) offsetof(FreezeDetectContext, x)
> @@ -56,6 +58,7 @@ static const AVOption freezedetect_options[] = {
>      { "noise",               "set noise tolerance",
> OFFSET(noise),  AV_OPT_TYPE_DOUBLE,   {.dbl=0.001},     0,       1.0, V|F },
>      { "d",                   "set minimum duration in seconds",
> OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F
> },
>      { "duration",            "set minimum duration in seconds",
> OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F
> },
> +    { "discard",             "set frame discard flag",
> OFFSET(discard),   AV_OPT_TYPE_BOOL,     {.i64=0},         0,         1, V|F
> },
>
>      {NULL}
>  };
> @@ -196,7 +199,10 @@ static int activate(AVFilterContext *ctx)
>                  return AVERROR(ENOMEM);
>              }
>          }
> -        return ff_filter_frame(outlink, frame);
> +        if (s->discard && s->frozen) {
> +            av_frame_free(&frame);
> +        } else
> +            return ff_filter_frame(outlink, frame);
>      }
>
>      FF_FILTER_FORWARD_STATUS(inlink, outlink);
> --
> 2.21.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Paul B Mahol Oct. 8, 2019, 8:03 a.m. UTC | #5
On 10/8/19, Paul B Mahol <onemda@gmail.com> wrote:
> On 10/8/19, lance.lmwang@gmail.com <lance.lmwang@gmail.com> wrote:
>> From: Limin Wang <lance.lmwang@gmail.com>
>>
>> How to tested it, please try with the following command:
>> ./ffmpeg  -f lavfi -i
>> "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=0"
>> -f
>> null -
>> frame=  150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed=
>> 234x
>>
>> ./ffmpeg  -f lavfi -i
>> "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:discard=1"
>> -f
>> null -
>> frame=   30 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.00 bitrate=N/A
>> speed=59.7x
>>
>> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
>> ---
>>  doc/filters.texi              | 10 ++++++++++
>>  libavfilter/vf_freezedetect.c |  8 +++++++-
>>  2 files changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/doc/filters.texi b/doc/filters.texi
>> index 333f502083..8aa7471f7e 100644
>> --- a/doc/filters.texi
>> +++ b/doc/filters.texi
>> @@ -10678,6 +10678,9 @@ timestamp of the first frame of the freeze. The
>>  @code{lavfi.freezedetect.freeze_duration} and
>>  @code{lavfi.freezedetect.freeze_end} metadata keys are set on the first
>> frame
>>  after the freeze.
>> +In addition, you can choose to discard the freezen frames instead of
>> report
>> +by metadata. Please note the first few freezen frames (the detection
>> interval)
>> +won't be dropped for the filter doesn't buffer any frames.
>
> This is no go. You can not claim one and do something else completely
> differently.
>
> If you want to drop frozen frames it should drop all frozen frames.
> If you want to trim frozen frames it should trim all frozen frames.

Also you can already drop frames with metadata filter and its select mode.

something like freezedetect,metadata=mode=select:key=lavfi.freezedetect.freeze_amount:value=some_frozen_amount:function=greater

You just need to export frozen value from freezedetect filter for each
output frame metadata.

>
>
>>
>>  The filter accepts the following options:
>>
>> @@ -10689,6 +10692,13 @@ specified value) or as a difference ratio between
>> 0
>> and 1. Default is -60dB, or
>>
>>  @item duration, d
>>  Set freeze duration until notification (default is 2 seconds).
>> +
>> +@item discard
>> +Set force to discard freezen frame.
>> + 0:  do nothing
>> + 1:  discard freezen frame
>> +
>> +Default is 0
>>  @end table
>>
>>  @anchor{frei0r}
>> diff --git a/libavfilter/vf_freezedetect.c
>> b/libavfilter/vf_freezedetect.c
>> index cc086afee6..cc115eb521 100644
>> --- a/libavfilter/vf_freezedetect.c
>> +++ b/libavfilter/vf_freezedetect.c
>> @@ -45,6 +45,8 @@ typedef struct FreezeDetectContext {
>>
>>      double noise;
>>      int64_t duration;            ///< minimum duration of frozen frame
>> until notification
>> +
>> +    int discard;                 ///< 0: no discard, 1: discard freezen
>> frame
>>  } FreezeDetectContext;
>>
>>  #define OFFSET(x) offsetof(FreezeDetectContext, x)
>> @@ -56,6 +58,7 @@ static const AVOption freezedetect_options[] = {
>>      { "noise",               "set noise tolerance",
>> OFFSET(noise),  AV_OPT_TYPE_DOUBLE,   {.dbl=0.001},     0,       1.0, V|F
>> },
>>      { "d",                   "set minimum duration in seconds",
>> OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX,
>> V|F
>> },
>>      { "duration",            "set minimum duration in seconds",
>> OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX,
>> V|F
>> },
>> +    { "discard",             "set frame discard flag",
>> OFFSET(discard),   AV_OPT_TYPE_BOOL,     {.i64=0},         0,         1,
>> V|F
>> },
>>
>>      {NULL}
>>  };
>> @@ -196,7 +199,10 @@ static int activate(AVFilterContext *ctx)
>>                  return AVERROR(ENOMEM);
>>              }
>>          }
>> -        return ff_filter_frame(outlink, frame);
>> +        if (s->discard && s->frozen) {
>> +            av_frame_free(&frame);
>> +        } else
>> +            return ff_filter_frame(outlink, frame);
>>      }
>>
>>      FF_FILTER_FORWARD_STATUS(inlink, outlink);
>> --
>> 2.21.0
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
diff mbox

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index 333f502083..8aa7471f7e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10678,6 +10678,9 @@  timestamp of the first frame of the freeze. The
 @code{lavfi.freezedetect.freeze_duration} and
 @code{lavfi.freezedetect.freeze_end} metadata keys are set on the first frame
 after the freeze.
+In addition, you can choose to discard the freezen frames instead of report
+by metadata. Please note the first few freezen frames (the detection interval)
+won't be dropped for the filter doesn't buffer any frames.
 
 The filter accepts the following options:
 
@@ -10689,6 +10692,13 @@  specified value) or as a difference ratio between 0 and 1. Default is -60dB, or
 
 @item duration, d
 Set freeze duration until notification (default is 2 seconds).
+
+@item discard
+Set force to discard freezen frame.
+ 0:  do nothing
+ 1:  discard freezen frame
+
+Default is 0
 @end table
 
 @anchor{frei0r}
diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
index cc086afee6..cc115eb521 100644
--- a/libavfilter/vf_freezedetect.c
+++ b/libavfilter/vf_freezedetect.c
@@ -45,6 +45,8 @@  typedef struct FreezeDetectContext {
 
     double noise;
     int64_t duration;            ///< minimum duration of frozen frame until notification
+
+    int discard;                 ///< 0: no discard, 1: discard freezen frame
 } FreezeDetectContext;
 
 #define OFFSET(x) offsetof(FreezeDetectContext, x)
@@ -56,6 +58,7 @@  static const AVOption freezedetect_options[] = {
     { "noise",               "set noise tolerance",                       OFFSET(noise),  AV_OPT_TYPE_DOUBLE,   {.dbl=0.001},     0,       1.0, V|F },
     { "d",                   "set minimum duration in seconds",        OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F },
     { "duration",            "set minimum duration in seconds",        OFFSET(duration),  AV_OPT_TYPE_DURATION, {.i64=2000000},   0, INT64_MAX, V|F },
+    { "discard",             "set frame discard flag",                 OFFSET(discard),   AV_OPT_TYPE_BOOL,     {.i64=0},         0,         1, V|F },
 
     {NULL}
 };
@@ -196,7 +199,10 @@  static int activate(AVFilterContext *ctx)
                 return AVERROR(ENOMEM);
             }
         }
-        return ff_filter_frame(outlink, frame);
+        if (s->discard && s->frozen) {
+            av_frame_free(&frame);
+        } else
+            return ff_filter_frame(outlink, frame);
     }
 
     FF_FILTER_FORWARD_STATUS(inlink, outlink);