From patchwork Tue Oct 3 12:26:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Petrov X-Patchwork-Id: 44111 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1204:b0:15d:8365:d4b8 with SMTP id v4csp2016565pzf; Tue, 3 Oct 2023 05:27:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEbLHvmpFjv+d1MMZDXVgI/k5HD2+Ob3IWllMVCLjK29p+HazijU0dIv5YqRtvMoXBWFgD2 X-Received: by 2002:aa7:d90f:0:b0:531:5126:cd5e with SMTP id a15-20020aa7d90f000000b005315126cd5emr12711515edr.34.1696336024691; Tue, 03 Oct 2023 05:27:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696336024; cv=none; d=google.com; s=arc-20160816; b=v/O4zKOdztlF1c/y43wYtpj+OYO4nNQtZfkA5rVTQF0RnN2sSb5qzLA7EDiev7CIiW mm9a5IvuOw0AOrDj4OFDaThS2Neqqn0nnHT+qQ/IYmbPzrK1TTIYOrRjQinzjIyl7kZP 4OLf9DLx1V4PfLSQmKFU3AFx6EjoWWGYKK1GVneUYdjDJz+6TM/+12fFokYbMPozqVna SOOcGYzkJslhJ9KH4ckhp32rOKE2KDNbGuiswhexMO1MTqH/VzfW7KnNLMvAW7aPhcSz QNPeg16Lb2kFy44E+jd/0XSJgPLp0hOCHqnvJ/ifLiFmHfJeekvzp/A8XCYn1EpRxucW 4nLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:to :message-id:date:from:mime-version:dkim-signature:delivered-to; bh=PHFfKIP+soJwoS/ZFZN8I+FWsbzk8tiryaj0T7xW+gw=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=udVekFdMWu84t3Q62ELpAQY3+L9DasyMEDVX5DQKhwuMGXXL7nPfPukqvvXXNCzq0L AVQv304xlgr5jVdVCswyR0eMQaRDDtUkVH6mMWKpS+xZCizHGIkPcIZx0cDNNxT10Eod wh1QKu8I3rnUI/p4cVISarjiuHli3iDFUFni+ZPNyOLusbfgqfrvDEc1GR3JxW9OzLls vYo5LkxQ6WL2oEQhBKqY+ko1XFI6ZtMB0FsnKFvTT8gPZHYUcsM9N7L3zl7j1bxj5MtQ jcx5jUy0oqI3PkPFOdbm6u7KwjyAZBPyPckiATxomq93hTOMLHAJ9Q/N3X/qvBlSgB53 lYpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=Q1C4wUYM; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id u17-20020aa7d891000000b00531190124ddsi568526edq.188.2023.10.03.05.27.02; Tue, 03 Oct 2023 05:27:04 -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=@gmail.com header.s=20230601 header.b=Q1C4wUYM; 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=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7D93868CB0E; Tue, 3 Oct 2023 15:26:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id EC9B568CB0E for ; Tue, 3 Oct 2023 15:26:51 +0300 (EEST) Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-578d791dd91so610345a12.0 for ; Tue, 03 Oct 2023 05:26:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696336010; x=1696940810; darn=ffmpeg.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=u8zMkWmxgOpUBTx5ruDcvyt4uSL27/ODtqloTOFmZ6o=; b=Q1C4wUYMDCiL9PJnn2ImfYMwQaLJYmZupelITvYxrfQnWeoyitKottCtBcrYwT135A WPeBuFHv8Gsy9Iz1TBXIphaw4HgIikUq85PAyo4aLtr41fUM3kG7yzPCsfMi8TP1WzIW Bnrs4MdDaAL5eebJCivG7G1ZTHM7LxDhscIJRTSu8ww4yRVXoFKIhhLtah+RQCkemPFI RhlYkFF9/nh99VjGfwlK3EZqtmi4xLZrVmoW6YnVcGgYsAHP2YDS9tIeci4bESDRAlPe /tYvG1/STfglDqLwGmfiCovEF3pB7IXqimeuzdbC8RGo5wJLi5MB+7ilche+Wq/SJv9D zwpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696336010; x=1696940810; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=u8zMkWmxgOpUBTx5ruDcvyt4uSL27/ODtqloTOFmZ6o=; b=ox009C/Exy2w7biaYi7FInK/b/yd5ZZoYgsZP3QcRsS1Y+0lk5sSbl7bYFtNUi3jBm esawep8d8kGzqifeexrPu+ebVdkbdx+YgFQdbgJbEb/m/KTR8JPrxIM/Xiq6u6X1/dXi D7KlNt/gt7aNoNhjFKFnLxAnS97d11JbJkyLbLPdSthB6SMW4c1i5qJmfF/VI7C5UFpt UKuyyONhhgZ/HxBHp4iIV5OvmYcRBwGLy4+uouVPiW+WGmjYhfOKyXZcqZV3bFdxDkZ1 FT/zmQswfKm6VXpnDsvb8hjipDSIp/Eeo/hBvF0Q4SARugUsy63bZbiyStDRXA996qUZ vkUg== X-Gm-Message-State: AOJu0Yx4bR6LSkZww8PRkkDQzCSZ+9is0J55rM0ymFU98XfEzorq9zPe 8wWz1cmvXlgPa67sA79gAwxJ7DtoJZfcG4azedt6exIM3b0= X-Received: by 2002:a17:90a:d985:b0:273:83ac:5eb9 with SMTP id d5-20020a17090ad98500b0027383ac5eb9mr3943603pjv.4.1696336009732; Tue, 03 Oct 2023 05:26:49 -0700 (PDT) MIME-Version: 1.0 From: Vladimir Petrov Date: Tue, 3 Oct 2023 15:26:38 +0300 Message-ID: To: ffmpeg-devel@ffmpeg.org X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Subject: [FFmpeg-devel] avfilter/vf_decimate: Improve decimation factor precision 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: Es1RtmBtdh0x Currently, decimate video filter supports dropping of only single frame per cycle, limiting the range of available framerate decimation factors. Now, adding a new option 'dropcount' allows increasing of drop count, so more fractional factors could be chosen. Also added an option 'spread' to set percentage of dropped frame metrics spreading to adjanced frames. Bigger value of 'spread' option means that non-duplicate frames will be distributed more evenly to output. Especially, this is useful in case of static scenes to avoid skipping of large frame sequences, i.e. to avoid jumpy motion. Added a new option 'compat' (compatibility with the old behaviour / 2nd patch). When set to 'true', no metrics recalculation will be done when marking a new frame to be dropped. In case of scene change detection, the last one per batch will be prioritized, instead of the best one. In mixed mode, checking for interlaced frames will be omited. Compatibility option is intended to keep matching with the original VIVTC VDecimate filter code. Rules to drop frames are as follow: First priority drops will be duplicate frames, in ascending order by their 'maxbdiff' metrics. If these are not enough and have scene change, then will be dropped first frames of the new scene. If all these are insufficient, then will drop some frames with less 'maxbdiff' metrics. The logic (with 'dropcount=1') corresponds to the current behaviour. Examples below (both converts 29.97 fps 3:2 pulldown content mixed with interlaced content to 23.976 fps video): 1. Deinterlace after decimation. fieldmatch=order=tff:mode=pcn:field=top:combmatch=full,decimate=mixed=1,bwdif=parity=tff:deint=1,fps=30000/1001 2. Deinterlace before decimation. fieldmatch=order=tff:mode=pcn:field=top:combmatch=full,bwdif=parity=tff:deint=1,fps=60000/1001,decimate=mixed=0:cycle=10:dropcount=6:compat=0 From bdd5688d3c2811923895e31c886dd805e44c2ac6 Mon Sep 17 00:00:00 2001 From: Vladimir Petrov Date: Sat, 23 Sep 2023 17:41:58 +0300 Subject: [PATCH 2/2] avfilter/vf_decimate: Add compatibility option Adds compatibility with the old behaviour. Added a new option 'compat'. When set to 'true', no metrics recalculation will be done when marking a new frame to be dropped. In case of scene change detection, the last one per batch will be prioritized, instead of the best one. In mixed mode, checking for interlaced frames will be omited. Signed-off-by: Vladimir Petrov --- doc/filters.texi | 9 +++++++++ libavfilter/vf_decimate.c | 14 +++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index eef76d71b0..5954299713 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11441,6 +11441,15 @@ Set whether or not chroma is considered in the metric calculations. Default is Set whether or not the input only partially contains content to be decimated. Default is @code{false}. If enabled video output stream will be in variable frame rate. + +@item compat +Set compatibility with the old behaviour. When set to @code{true}, no metrics +recalculation will be done when marking a new frame to be dropped. In case of +scene change detection, the last one per batch will be prioritized, instead of +the best one. In mixed mode, checking for interlaced frames will be omited. +In order to get smoother motion and more accurate scene change detection, +please set this to @code{false}. +Default is @code{true}. @end table @section deconvolve diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c index 67896eaa0d..5ab953f985 100644 --- a/libavfilter/vf_decimate.c +++ b/libavfilter/vf_decimate.c @@ -70,6 +70,7 @@ typedef struct DecimateContext { int ppsrc; int chroma; int mixed; + int compat; } DecimateContext; #define OFFSET(x) offsetof(DecimateContext, x) @@ -86,6 +87,7 @@ static const AVOption decimate_options[] = { { "ppsrc", "mark main input as a pre-processed input and activate clean source input stream", OFFSET(ppsrc), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { "chroma", "set whether or not chroma is considered in the metric calculations", OFFSET(chroma), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { "mixed", "set whether or not the input only partially contains content to be decimated", OFFSET(mixed), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "compat", "set compatibility with old behaviour", OFFSET(compat), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { NULL } }; @@ -243,7 +245,7 @@ static int best_sc_idx(const DecimateContext* const dm) if (0 <= ret) { for (i = ret + 1; dm->cycle > i && dm->queue[i].frame; i++) { - if (!dm->queue[i].drop && dm->queue[i].totdiff > dm->queue[ret].totdiff) + if (!dm->queue[i].drop && dm->queue[i].totdiff > (dm->compat ? dm->scthresh : dm->queue[ret].totdiff)) ret = i; } } @@ -266,7 +268,7 @@ static void update_frame_metrics(DecimateContext *dm, const int idx_p, const int if (!f1) { dm->queue[idx_nxt].maxbdiff = INT64_MAX; dm->queue[idx_nxt].totdiff = INT64_MAX; - } else if (dm->mixed && ((AV_FRAME_FLAG_INTERLACED & f1->flags) || (f2 && (AV_FRAME_FLAG_INTERLACED & f2->flags)))) { + } else if (!dm->compat && dm->mixed && ((AV_FRAME_FLAG_INTERLACED & f1->flags) || (f2 && (AV_FRAME_FLAG_INTERLACED & f2->flags)))) { dm->queue[idx_nxt].maxbdiff = INT64_MAX - 1; dm->queue[idx_nxt].totdiff = 0; } else if (f2) { @@ -346,13 +348,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } else { idx_prv = prev_frame_idx(dm, idx_drop); idx_nxt = next_frame_idx(dm, idx_drop); - update_frame_metrics(dm, idx_prv, idx_nxt, idx_drop); + if (!dm->compat) + update_frame_metrics(dm, idx_prv, idx_nxt, idx_drop); mark_drop_frame(dm, idx_drop, drop_case); } } } av_frame_free(&dm->last); - idx_prv = prev_frame_idx(dm, dm->cycle); + idx_prv = dm->compat ? (dm->cycle - 1) : prev_frame_idx(dm, dm->cycle); if (0 <= idx_prv && dm->queue[idx_prv].frame) dm->last = av_frame_clone(dm->queue[idx_prv].frame); } else { @@ -367,7 +370,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } else { idx_prv = prev_frame_idx(dm, idx_drop); idx_nxt = next_frame_idx(dm, idx_drop); - update_frame_metrics(dm, idx_prv, idx_nxt, idx_drop); + if (!dm->compat) + update_frame_metrics(dm, idx_prv, idx_nxt, idx_drop); mark_drop_frame(dm, idx_drop, 4); } } -- 2.39.2