From patchwork Mon Sep 30 15:22:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 15423 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id BE62D44A81C for ; Mon, 30 Sep 2019 18:22:31 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 997406800A8; Mon, 30 Sep 2019 18:22:31 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f174.google.com (mail-pg1-f174.google.com [209.85.215.174]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 31FF7688162 for ; Mon, 30 Sep 2019 18:22:25 +0300 (EEST) Received: by mail-pg1-f174.google.com with SMTP id i14so7556882pgt.11 for ; Mon, 30 Sep 2019 08:22:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=hI/DFBmHF6llnXXt5Q8QcbpMLHKPTQ42rvYo/UqPnEs=; b=H3odcFq7IlRh3yOgL1OvysmeMbS/8qmcpP1AqivWBOZV7khbEIKyHSu3z0GM+ISFOa TGLYV5g3tQFDTlvyf+GG0p3x35hoWWRPb0PO/PsJ16oeJJ/i4dGoGgbenWOnG3RXrZDx QQd2n0MgsWPUZV3q/wnpnAcGkkskm6KQBof1dlBnnhbchbiWYj8CqxlXVx17DqIe9sU8 ltFBKhySOKvYClXTjQiOBySoXrsGYfgt93WywH48MHtI9SRtX9rQ6VlcfBs84uEFvdUf 7V5BIDDbwyDp6jTRmdi91EIAsvjY8jcNhvBYCSm0MYeuyH3dCeSCKp+X9I4jky+NEwX5 gTng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=hI/DFBmHF6llnXXt5Q8QcbpMLHKPTQ42rvYo/UqPnEs=; b=qXZ48LG+TvM7Ito17sDFyKkuljWPFP4citk5tyXsmFSpbjnr5dw168Bnu/CZitshD/ 7LTDXT0p26W+/sAsiPF3kyEJF07lx5C5y8Otyg/Zs3GhUASHB420bwEzOxBAz7miH6ni mKnvukT4nshiFmmJsDSJOcd5t7KNCV4YLnAw3VK9sNfYbVy2W9sHBsNsN7kUh4mXB7Dh lVCoGCf0vxVmuiKrAcjLuCveet1BjXszkmGWcKjUb+w9vdpYaVtnYZs6W+9reD5BuLjB Fo0t3mTg3mBD3WZi3w4yDo2z7kU0wyaS6BaaT6oftpG4TofjG1s0aToQwDScaJ0vktCp GTuQ== X-Gm-Message-State: APjAAAXX2cnN1wkcs3nyz5zQ9XNv/5JPr/C4VhQXEByKT5uV+o0BYlFa zvK+aiARKHWAW8En8xAQKhLSSpzC X-Google-Smtp-Source: APXvYqyiBCTsPcocx7HqDVAF50DhCNDfbJAcZz2+JPLkpa2SZY+XElWZzHocY3YR6oxWst61fbAmuA== X-Received: by 2002:a63:7556:: with SMTP id f22mr25209441pgn.222.1569856943264; Mon, 30 Sep 2019 08:22:23 -0700 (PDT) Received: from vpn.localdomain ([47.90.99.151]) by smtp.gmail.com with ESMTPSA id b11sm14462410pgr.20.2019.09.30.08.22.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 30 Sep 2019 08:22:22 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Mon, 30 Sep 2019 23:22:18 +0800 Message-Id: <20190930152218.6860-1-lance.lmwang@gmail.com> X-Mailer: git-send-email 2.9.5 Subject: [FFmpeg-devel] [PATCH v1] avfilter/vf_freezedetect: add force_discard option to force discard freeze/non-freeze frame X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Limin Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang How to tested it, please try with the following command: ./ffmpeg -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:f=0" -f null - frame= 150 fps=0.0 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed= 232x ./ffmpeg -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:f=-1" -f null - frame= 120 fps=0.0 q=-0.0 Lsize=N/A time=00:00:04.00 bitrate=N/A speed= 211x ./ffmpeg -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30,freezedetect=d=1:f=1" -f null - frame= 30 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.00 bitrate=N/A speed=93.9x Signed-off-by: Limin Wang --- doc/filters.texi | 10 ++++++++++ libavfilter/vf_freezedetect.c | 23 ++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/doc/filters.texi b/doc/filters.texi index 6ed1c8fa75..2be8b93c53 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -10678,6 +10678,8 @@ 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 freeze/non-freezee frames instead of +report by metadata. The filter accepts the following options: @@ -10689,6 +10691,14 @@ 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 force_discard, f +Set force to discard or keep freeze frame. + 0: do nothing +-1: discard non-freeze frame + 1: discard freeze frame + +Default is 0 @end table @anchor{frei0r} diff --git a/libavfilter/vf_freezedetect.c b/libavfilter/vf_freezedetect.c index cc086afee6..fc08c235f7 100644 --- a/libavfilter/vf_freezedetect.c +++ b/libavfilter/vf_freezedetect.c @@ -45,6 +45,9 @@ typedef struct FreezeDetectContext { double noise; int64_t duration; ///< minimum duration of frozen frame until notification + + int force_discard; ///< 0: no discard, -1: discard non-freeze frame, 1: discard freeze frame + int drop_count; } FreezeDetectContext; #define OFFSET(x) offsetof(FreezeDetectContext, x) @@ -56,6 +59,8 @@ 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 }, + { "f", "set frame discard", OFFSET(force_discard), AV_OPT_TYPE_INT, {.i64=0}, -1, 1, V|F }, + { "force_discard", "set frame discard", OFFSET(force_discard), AV_OPT_TYPE_INT, {.i64=0}, -1, 1, V|F }, {NULL} }; @@ -115,6 +120,7 @@ static int config_input(AVFilterLink *inlink) if (!s->sad) return AVERROR(EINVAL); + s->drop_count = 0; return 0; } @@ -184,10 +190,22 @@ static int activate(AVFilterContext *ctx) set_meta(s, frame, "lavfi.freezedetect.freeze_end", av_ts2timestr(frame->pts, &inlink->time_base)); } s->frozen = frozen; + if ( s->force_discard > 0 && frozen) + s->drop_count++; + else if ( s->force_discard < 0 && frozen && s->drop_count < 0) { + s->drop_count = 0; + } + } else { + if ( s->force_discard < 0) + s->drop_count--; } } if (!frozen) { + if (s->force_discard > 0) { + s->drop_count = 0; + } else if ( s->force_discard < 0) + s->drop_count--; av_frame_free(&s->reference_frame); s->reference_frame = av_frame_clone(frame); s->reference_n = s->n; @@ -196,7 +214,10 @@ static int activate(AVFilterContext *ctx) return AVERROR(ENOMEM); } } - return ff_filter_frame(outlink, frame); + if (s->drop_count > 0 || s->drop_count < 0) { + av_frame_free(&frame); + } else + return ff_filter_frame(outlink, frame); } FF_FILTER_FORWARD_STATUS(inlink, outlink);