From patchwork Mon May 8 13:41:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thilo Borgmann X-Patchwork-Id: 41552 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:dca6:b0:f3:34fa:f187 with SMTP id ky38csp2334927pzb; Mon, 8 May 2023 06:41:54 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6QKOUSGHApwCTPz/eDoOUb5VUfVPeJ+rscgqX5PDDsXSS26rGi6lthreUXY0EBd1ClgrBL X-Received: by 2002:a17:907:320a:b0:88a:1ea9:a5ea with SMTP id xg10-20020a170907320a00b0088a1ea9a5eamr8634575ejb.65.1683553314291; Mon, 08 May 2023 06:41:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683553314; cv=none; d=google.com; s=arc-20160816; b=YdVlYK2AYb2AVXFYVGqC/neS1jFAa1aQD9EXLihLJcvdwGFjCyUJcihkZNIMbRpR6G zCqpHR69YEnjZAMfY6YjIw5/LXvjDtPVIDB2R/EIDFMl4sywE5c30zG2c+3TO77VwH/8 c4pgrvqmQ6a2bTFwZ7W3BGuBLWNLjgUpPsBiW9Ga01xd2291VAq/O568b4Bpy4yfRoml EoZWegvLm072s61UZWL27PqyW62gEcDx7H+YcJcVpoIvE47qWV8l3tiNKfAl6K2XFtCn yUSJ0tACckhGKl1Qm01PEhwuXgcc2joMn1jX5tomkR3D4l/oLyBADI813LvbWQQq8ejh Jvrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=eAbHt9nsB3n6IE/RUA6hRgjdRkwltldtv5b7jerBSq4=; b=XznN15kE/dE9xS5Lb/dvPoJ6io+MZIQVwRdU8pkxVgbIyY9JfEQNZgx5nc6cVptQ/l 4pw00ko0wG6mmfbS2Qjxh42DMTsk6qf6DDW+b86ceQnWDT2vksiZyS+qwDmHgKUK68d+ 6jVeShCCKZXsKDS4EcL6zCjYTtLRuBCEI9vxv/+v9+FtO1p8QZApNGAtX9yOEzJKR2VR 77+G88UTL53jTBUZm5hagYsXsSLRc69yh7beTp8N5N0eLIv+UM3pCPzc/E7TEtHW2Sbh //d+lwGwcToDAvMyUGTHmQ+3wapiU332P7lwzfQG+DbbCcbjTMiOfH+UGkaSbiCbJ2bX 3W7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@mail.de header.s=mailde202009 header.b=0WTOEMRA; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mail.de Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gv32-20020a1709072be000b0095f071fb512si5149295ejc.266.2023.05.08.06.41.53; Mon, 08 May 2023 06:41:54 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@mail.de header.s=mailde202009 header.b=0WTOEMRA; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mail.de Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C1FB968C06A; Mon, 8 May 2023 16:41:50 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from shout01.mail.de (shout01.mail.de [62.201.172.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5036668BFCB for ; Mon, 8 May 2023 16:41:43 +0300 (EEST) Received: from postfix01.mail.de (postfix01.bt.mail.de [10.0.121.125]) by shout01.mail.de (Postfix) with ESMTP id E22D1A08E1 for ; Mon, 8 May 2023 15:41:42 +0200 (CEST) Received: from smtp03.mail.de (smtp03.bt.mail.de [10.0.121.213]) by postfix01.mail.de (Postfix) with ESMTP id C9AAC80172 for ; Mon, 8 May 2023 15:41:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mail.de; s=mailde202009; t=1683553302; bh=nCrK25WTyaegKkXGeR4IkxsHF3Ffiox3KIpDiJ0wl6w=; h=From:To:Subject:Date:Message-Id:From:To:CC:Subject:Reply-To; b=0WTOEMRA+pKE9E1eUP5cnddzpUsU5nTvQPUvG3Qmh9hn1RYq2tRgq8OGfOxunEoyf pdYkOaz06YWMl2/Y5SnNdL3hiC5Mn9k3hTDsSyoxwgezZQYovdjh+zNxp775BxT1hC GzP28Qt/IVMXTGanN5AFOmX2YoIc73wsjueN1nFBgN7zcJcB5U/0wroCExko7R8jrH 8em59Es8eok3Z+j8iVFMuKZdxfHCidgpQa9qwTpjvd2Fy7n00tTXeIadntqKgMdJWM SKJrBNVj16haYKwRVVXGjNedu2I2zAb4O3LS/g+6dcVsN0KhMJWaP4WJ13q6mNBgMR N2kLhZgikxsxw== Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtp03.mail.de (Postfix) with ESMTPSA id 5F4B5A0358 for ; Mon, 8 May 2023 15:41:42 +0200 (CEST) From: Thilo Borgmann To: ffmpeg-devel@ffmpeg.org Date: Mon, 8 May 2023 15:41:41 +0200 Message-Id: <20230508134141.19901-1-thilo.borgmann@mail.de> MIME-Version: 1.0 X-purgate: clean X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate-type: clean X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate: clean X-purgate-size: 4638 X-purgate-ID: 154282::1683553302-4F7FC647-4A7A2614/0/0 Subject: [FFmpeg-devel] [PATCH v2] avfilter/vf_mpdecimate: Add option to keep the first N similar frames before dropping X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: aXDsgRDK7o6L This allows for decimating large similar portions of a video while preserving small ones. --- doc/filters.texi | 7 +++++++ libavfilter/version.h | 2 +- libavfilter/vf_mpdecimate.c | 19 +++++++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 9a0fe9c0a1..d3f6f20014 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -17646,6 +17646,13 @@ number of previous sequentially dropped frames. Default value is 0. +@item keep +Set the maximum number of consecutive similar frames to ignore before to start dropping them. +If the value is 0, the frame is dropped disregarding the +number of previous sequentially similar frames. + +Default value is 0. + @item hi @item lo @item frac diff --git a/libavfilter/version.h b/libavfilter/version.h index 0050874108..4dc176dc55 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFILTER_VERSION_MINOR 7 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c index 71f673cb64..d1e046fc32 100644 --- a/libavfilter/vf_mpdecimate.c +++ b/libavfilter/vf_mpdecimate.c @@ -46,6 +46,9 @@ typedef struct DecimateContext { int drop_count; ///< if positive: number of frames sequentially dropped ///< if negative: number of sequential frames which were not dropped + int max_keep_count; ///< number of similar frames to ignore before to start dropping them + int keep_count; ///< number of similar frames already ignored + int hsub, vsub; ///< chroma subsampling values AVFrame *ref; ///< reference picture av_pixelutils_sad_fn sad; ///< sum of absolute difference function @@ -57,6 +60,8 @@ typedef struct DecimateContext { static const AVOption mpdecimate_options[] = { { "max", "set the maximum number of consecutive dropped frames (positive), or the minimum interval between dropped frames (negative)", OFFSET(max_drop_count), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGS }, + { "keep", "set the number of similar consecutive frames to be kept before starting to drop similar frames", + OFFSET(max_keep_count), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, FLAGS }, { "hi", "set high dropping threshold", OFFSET(hi), AV_OPT_TYPE_INT, {.i64=64*12}, INT_MIN, INT_MAX, FLAGS }, { "lo", "set low dropping threshold", OFFSET(lo), AV_OPT_TYPE_INT, {.i64=64*5}, INT_MIN, INT_MAX, FLAGS }, { "frac", "set fraction dropping threshold", OFFSET(frac), AV_OPT_TYPE_FLOAT, {.dbl=0.33}, 0, 1, FLAGS }, @@ -112,6 +117,12 @@ static int decimate_frame(AVFilterContext *ctx, DecimateContext *decimate = ctx->priv; int plane; + if (decimate->max_keep_count > 0 && + decimate->keep_count > -1 && + decimate->keep_count < decimate->max_keep_count) { + decimate->keep_count++; + return 0; + } if (decimate->max_drop_count > 0 && decimate->drop_count >= decimate->max_drop_count) return 0; @@ -196,20 +207,24 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *cur) if (decimate->ref && decimate_frame(inlink->dst, cur, decimate->ref)) { decimate->drop_count = FFMAX(1, decimate->drop_count+1); + decimate->keep_count = -1; // do not keep any more frames until non-similar frames are detected } else { av_frame_free(&decimate->ref); decimate->ref = cur; decimate->drop_count = FFMIN(-1, decimate->drop_count-1); + if (decimate->keep_count < 0) // re-enable counting similiar frames to ignore before dropping + decimate->keep_count = 0; if ((ret = ff_filter_frame(outlink, av_frame_clone(cur))) < 0) return ret; } av_log(inlink->dst, AV_LOG_DEBUG, - "%s pts:%s pts_time:%s drop_count:%d\n", + "%s pts:%s pts_time:%s drop_count:%d keep_count:%d\n", decimate->drop_count > 0 ? "drop" : "keep", av_ts2str(cur->pts), av_ts2timestr(cur->pts, &inlink->time_base), - decimate->drop_count); + decimate->drop_count, + decimate->keep_count); if (decimate->drop_count > 0) av_frame_free(&cur);