[FFmpeg-devel] [PATCH] lavf/vf_freezedetect: improve for the freeze frame detection

lance.lmwang at gmail.com lance.lmwang at gmail.com
Sat Jul 13 18:15:09 EEST 2019


From: Limin Wang <lance.lmwang at gmail.com>

I have samples failed to detect the freeze frame with the default -60dB
noise(-40dB is OK to detect),
after apply the patch, it's ok to detect. 

I run the testing with fate-suite sample for your testing:
old: 
no freeze frame detect.

with the patch:
./ffmpeg -i fate-suite/svq3/Vertical400kbit.sorenson3.mov -vf
freezedetect=n=-60dB -an -f null -
[freezedetect @ 0x7fe18a604900] lavfi.freezedetect.freeze_start: 38.7667
[freezedetect @ 0x7fe18a604900] lavfi.freezedetect.freeze_duration: 2.5
[freezedetect @ 0x7fe18a604900] lavfi.freezedetect.freeze_end: 41.2667
[freezedetect @ 0x7fe18a604900] lavfi.freezedetect.freeze_start: 41.2667

Have run make fate testing although haven't find any freezedetect checking for
the fate.

Signed-off-by: Limin Wang <lance.lmwang at gmail.com>
---
 libavfilter/vf_freezedetect.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c
index cc086af..0288fb0 100644
--- a/libavfilter/vf_freezedetect.c
+++ b/libavfilter/vf_freezedetect.c
@@ -38,7 +38,9 @@ typedef struct FreezeDetectContext {
     ptrdiff_t height[4];
     ff_scene_sad_fn sad;
     int bitdepth;
+    int nb_planes;
     AVFrame *reference_frame;
+    double prev_mafd;
     int64_t n;
     int64_t reference_n;
     int frozen;
@@ -102,13 +104,15 @@ static int config_input(AVFilterLink *inlink)
     AVFilterContext *ctx = inlink->dst;
     FreezeDetectContext *s = ctx->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
+    int vsub = pix_desc->log2_chroma_h;
 
     s->bitdepth = pix_desc->comp[0].depth;
+    s->nb_planes = av_pix_fmt_count_planes(inlink->format);
 
-    for (int plane = 0; plane < 4; plane++) {
+    for (int plane = 0; plane < s->nb_planes; plane++) {
         ptrdiff_t line_size = av_image_get_linesize(inlink->format, inlink->w, plane);
-        s->width[plane] = line_size >> (s->bitdepth > 8);
-        s->height[plane] = inlink->h >> ((plane == 1 || plane == 2) ? pix_desc->log2_chroma_h : 0);
+        s->width[plane] = line_size;
+        s->height[plane] = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
     }
 
     s->sad = ff_scene_sad_get_fn(s->bitdepth == 8 ? 8 : 16);
@@ -129,7 +133,9 @@ static int is_frozen(FreezeDetectContext *s, AVFrame *reference, AVFrame *frame)
     uint64_t sad = 0;
     uint64_t count = 0;
     double mafd;
-    for (int plane = 0; plane < 4; plane++) {
+    double diff, cmp;
+
+    for (int plane = 0; plane < s->nb_planes; plane++) {
         if (s->width[plane]) {
             uint64_t plane_sad;
             s->sad(frame->data[plane], frame->linesize[plane],
@@ -140,8 +146,12 @@ static int is_frozen(FreezeDetectContext *s, AVFrame *reference, AVFrame *frame)
         }
     }
     emms_c();
-    mafd = (double)sad / count / (1ULL << s->bitdepth);
-    return (mafd <= s->noise);
+    mafd = (double)sad /(count >> (s->bitdepth > 8));
+    diff = fabs(mafd - s->prev_mafd);
+    cmp  = av_clipf(FFMIN(mafd, diff) / 100., 0, 1);
+    s->prev_mafd = mafd;
+
+    return (cmp <= s->noise);
 }
 
 static int set_meta(FreezeDetectContext *s, AVFrame *frame, const char *key, const char *value)
-- 
2.6.4



More information about the ffmpeg-devel mailing list