From patchwork Tue Oct 29 17:00:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 16018 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 26A5C449295 for ; Tue, 29 Oct 2019 19:01:19 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0F2C268B0F5; Tue, 29 Oct 2019 19:01:19 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1DCEA68B0E7 for ; Tue, 29 Oct 2019 19:01:12 +0200 (EET) Received: by mail-wm1-f67.google.com with SMTP id 11so3441657wmk.0 for ; Tue, 29 Oct 2019 10:01:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=U9OjYpJQ7vHADJsOZOtkHh6RjAaytJkLtGZvPaUSerw=; b=A5pHiMjA0/+50JsVDLAiC0z89A/UtKzo/qFclOaQ+6dTzMpKhn3njT6OxqtzIlrbgE /iD9A4x/sEWFOVy2TSgbWiWfYdrgls/cLuF2m0CuBMwEu8Ld6/wppAEhr4bGJ51b5jdE 3/fBr+gsy8JAVAA6kNDQuQD8neD7Jkdwc/xDJR1yB0QSvylnBYPfZbNKustF5D0SJmS3 VnSoUJ0Zv/LuLv2lvIBv3mBehCzlHL+JHEt4vPKDsQk7Tdn56+PSknthKb096pWTO/xu pk/2tUTX92JDXDxHHCp2j6Fbe58/E2uWM91Sg+/N2pgI41HXQCsGd4kOy+Hu6T7YLJnp Wisw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=U9OjYpJQ7vHADJsOZOtkHh6RjAaytJkLtGZvPaUSerw=; b=W3DE6yD5uXPWpmfGroG+MV7Da9KXcObD/YPDmE9jhQSzlAoNdCST7JRhdnQly6mjKu jrx78LNWjinJ/VR/GQUrRE20LBwKlEToF1aMGEjz09H3tG7B9+2/1x8HcPqhWWo55nzr 19a6zmY4yQAH+fqjA73PYB09S7qe3ON662nn6dQ0MR2TCDqiMwia08LrjKHpWSiQyNvA ol+ZOVs/DGnohiho5+DoUADhtM4h2yaEZLs63Ul/iDSr7RTeM6U+hriZGtDxxqlau/zx o+YevIc8f6DAy9ISqsnbStALNsFd11gV2Y3g1igPrZpPjqz4psi9qjVv5EQbaFQdX8UQ nA/w== X-Gm-Message-State: APjAAAVqbSMZ2aJ/M2FGbd+F6FyBCEgnWECcp95YGt/HKXrauO9Xy2h4 giZ+KauCmDzLzSm9MX9E8SdzUhzcTRA= X-Google-Smtp-Source: APXvYqwTxChwhFY7KUJiP0RGXW/OV6jHwsfcCIt51lYhCuAxemstQDXuUNcUx37aui09BZsCaEr+Cw== X-Received: by 2002:a7b:cbc5:: with SMTP id n5mr5179226wmi.65.1572368468300; Tue, 29 Oct 2019 10:01:08 -0700 (PDT) Received: from localhost.localdomain ([212.15.160.218]) by smtp.gmail.com with ESMTPSA id u21sm3070140wmj.22.2019.10.29.10.01.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2019 10:01:07 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Tue, 29 Oct 2019 18:00:57 +0100 Message-Id: <20191029170057.6116-3-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191029170057.6116-1-onemda@gmail.com> References: <20191029170057.6116-1-onemda@gmail.com> Subject: [FFmpeg-devel] [PATCH 3/3] avfilter/vf_fps: add option to change way how frames are duplicated 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Default behaviour is unchanged, and that is always rounding down when picking which frame to clone. Signed-off-by: Paul B Mahol --- doc/filters.texi | 19 +++++++++++++++++++ libavfilter/vf_fps.c | 23 ++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 1e815bf940..6b5bf53c6d 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -10740,6 +10740,25 @@ The default is @code{round}. @item input Pick output frame rate from input if it is available. The default is disabled. Useful to change input to constant frame rate without needing to know input frame rate. + +@item frames +Frames picking rounding method when duplicating frames. + +Possible values are: +@table @option +@item zero +round towards 0 +@item inf +round away from 0 +@item down +round towards -infinity +@item up +round towards +infinity +@item near +round to nearest +@end table +The default is @code{down}. + @end table Alternatively, the options can be specified as a flat string: diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 993a6be1b9..3e6f9265af 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -49,6 +49,8 @@ typedef struct FPSContext { AVRational framerate; ///< target framerate int rounding; ///< AVRounding method for timestamps + int frames_rounding; ///< AVRounding method for cloning frames + int eof_action; ///< action performed for last frame in FIFO /* Set during outlink configuration */ @@ -89,6 +91,7 @@ static const AVOption fps_options[] = { { "round", "round similar to other frames", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ROUND }, 0, 0, V|F, "eof_action" }, { "pass", "pass through last frame", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, 0, 0, V|F, "eof_action" }, { "input", "use input framerate if available", OFFSET(input), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, V|F }, + { "frames", "set rounding method for frames", OFFSET(frames_rounding), AV_OPT_TYPE_INT, { .i64 = AV_ROUND_DOWN }, 0, 5, V|F, "round" }, { NULL } }; @@ -252,13 +255,27 @@ static int write_frame(AVFilterContext *ctx, FPSContext *s, AVFilterLink *outlin *again = 1; return 0; - /* Output a copy of the first buffered frame */ + /* Output a copy of the buffered frame depending on frames rounding */ } else { - frame = av_frame_clone(s->frames[0]); + int index; + + if (s->frames_count < 2) { + index = 0; + } else { + switch (s->frames_rounding) { + case AV_ROUND_ZERO: index = (s->next_pts - s->frames[0]->pts) >= 0 ? 0 : 1; break; + case AV_ROUND_INF: index = (s->next_pts - s->frames[0]->pts) <= 0 ? 0 : 1; break; + case AV_ROUND_DOWN: index = 0; break; + case AV_ROUND_UP: index = (s->next_pts - s->frames[0]->pts) != 0 ? 1 : 0; break; + case AV_ROUND_NEAR_INF: index = (s->next_pts - s->frames[0]->pts) > (s->frames[1]->pts - s->frames[0]->pts) / 2 ? 1 : 0; break; + } + } + + frame = av_frame_clone(s->frames[index]); if (!frame) return AVERROR(ENOMEM); // Make sure Closed Captions will not be duplicated - av_frame_remove_side_data(s->frames[0], AV_FRAME_DATA_A53_CC); + av_frame_remove_side_data(s->frames[index], AV_FRAME_DATA_A53_CC); frame->pts = s->next_pts++; av_log(ctx, AV_LOG_DEBUG, "Writing frame with pts %"PRId64" to pts %"PRId64"\n",