[FFmpeg-devel,v1] avfilter/vf_freezedetect: add metadata lavfi.freezedetect.mafd

Submitted by lance.lmwang@gmail.com on Oct. 10, 2019, 3:48 a.m.

Details

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

Commit Message

lance.lmwang@gmail.com Oct. 10, 2019, 3:48 a.m.
From: Limin Wang <lance.lmwang@gmail.com>

As suggested by Paul to support frozen frames discard, please refer to:
https://patchwork.ffmpeg.org/patch/15423/

You can tested with below commands:

./ffmpeg  -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect,metadata=mode=select:key=lavfi.freezedetect.mafd:value=0.01:function=greater"  -f null -
frame=    1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.03 bitrate=N/A speed=2.14x

Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
---
 doc/filters.texi              | 9 +++++++++
 libavfilter/vf_freezedetect.c | 7 +++++++
 2 files changed, 16 insertions(+)

Patch hide | download patch | download mbox

diff --git a/doc/filters.texi b/doc/filters.texi
index 55a8ebae56..cfc10c8479 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -10800,6 +10800,15 @@  timestamp of the first frame of the freeze. The
 @code{lavfi.freezedetect.freeze_end} metadata keys are set on the first frame
 after the freeze.
 
+The @code{lavfi.freezedetect.mafd} metadata key is set for all frames except the
+first reference frame. You can use it to drop frozen frames by metadata select
+mode. Note that in this way the first few frozen frames(the detection interval)
+are dropped also. An example is as follows:
+@example
+freezedetect,metadata=mode=select:key=lavfi.freezedetect.mafd:value=0.001:function=greater
+@end example
+
+
 The filter accepts the following options:
 
 @table @option
diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
index cc086afee6..3931bcfa2e 100644
--- a/libavfilter/vf_freezedetect.c
+++ b/libavfilter/vf_freezedetect.c
@@ -124,11 +124,14 @@  static av_cold void uninit(AVFilterContext *ctx)
     av_frame_free(&s->reference_frame);
 }
 
+static int set_meta(FreezeDetectContext *s, AVFrame *frame, const char *key, const char *value);
 static int is_frozen(FreezeDetectContext *s, AVFrame *reference, AVFrame *frame)
 {
     uint64_t sad = 0;
     uint64_t count = 0;
     double mafd;
+    char buf[64];
+
     for (int plane = 0; plane < 4; plane++) {
         if (s->width[plane]) {
             uint64_t plane_sad;
@@ -141,6 +144,10 @@  static int is_frozen(FreezeDetectContext *s, AVFrame *reference, AVFrame *frame)
     }
     emms_c();
     mafd = (double)sad / count / (1ULL << s->bitdepth);
+
+    snprintf(buf, sizeof(buf), "%0.5f", mafd);
+    set_meta(s, frame, "lavfi.freezedetect.mafd", buf);
+
     return (mafd <= s->noise);
 }