From patchwork Mon Apr 27 06:17:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim DeLaHunt X-Patchwork-Id: 19336 Delivered-To: andriy.gelman@gmail.com Received: by 2002:a25:3c87:0:0:0:0:0 with SMTP id j129csp2612820yba; Sun, 26 Apr 2020 23:18:58 -0700 (PDT) X-Google-Smtp-Source: APiQypII07qcxKFgE81PjAXga4KIb6puMJZguPW/5tb5nMHYyZWvoFAxqJkiQN4PkHn8Ddpx9HGH X-Received: by 2002:adf:cd0a:: with SMTP id w10mr25020863wrm.404.1587968338707; Sun, 26 Apr 2020 23:18:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587968338; cv=none; d=google.com; s=arc-20160816; b=L4MHrwJlDcEtNU416mIZ3U7Mhr5HZm1rdvX53VpmAbqyfJKd17Kk/EpZkPTuduw5qt xx0Uyv4cQSfNkRSjfM3+3D8MMN0wg4PWwGAh3CdM7eb9O2SKCHM+RsKsgOurC3LSKSfq 6KYmQ9RYCABP2qB8/3OqjvYBORi3ALCH7KWyETlJoLxOa2XLCfQNSSyoZTun2rwKxqcX 0ixZszzybn3+QrjZhTRlaOTjZ7RJwU2gpEP2uSaJuih451vcHee1qyQCdUB1WX28ml5G siwlejmDyntAKqa4q6IP7h3KhfUa1iEz51YRhY7zaVf76IazXp5UpoS64YynLNjs97Wq NDSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc: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=O28MqTxaOk3z7FIHP/LIzdbMcM2iYKzVRj6KzJfxyC0=; b=c2QdIcDdfZb8YXoj3p36cqnF7gXUU420sjjZLX3wXBaxURB7VilqbY/Z8abi6sRgsE 3140YsINxCHShPRSua/9Tc+rZOZqKtqhaGAg4ha11Y7n9SS8DV2qig17uZ0YCmqB4p1s ocPK/qZBKzPDlvD0iel6lHZ/COdwbrr1PBlxTWErhl/wteN6p3dJ5JMU3H+w+5u1kD/L pVSJ6FfgO8YBXMFXFGMizjvWPdayL6LRW85A5nQxxzDKZ7yrE2WXMfaIbGi0VAuIE3mM /sIVh9PygAgLQRkjaJnv8osk3Ot7QSwFpaubNDWx11bMF9JLHZDbUtN+vW3lEWPOcv9a XLbA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jdlh.com header.s=jdlh.com header.b=CFbzfsT+; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id s15si14362304wrb.275.2020.04.26.23.18.57; Sun, 26 Apr 2020 23:18:58 -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=@jdlh.com header.s=jdlh.com header.b=CFbzfsT+; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 194F868C233; Mon, 27 Apr 2020 09:18:53 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from beige.elm.relay.mailchannels.net (beige.elm.relay.mailchannels.net [23.83.212.16]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 56D0E680280 for ; Mon, 27 Apr 2020 09:18:44 +0300 (EEST) X-Sender-Id: dreamhost|x-authsender|jdlh@jdlh.com Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 610B2480EBD; Mon, 27 Apr 2020 06:18:42 +0000 (UTC) Received: from pdx1-sub0-mail-a99.g.dreamhost.com (100-96-10-11.trex.outbound.svc.cluster.local [100.96.10.11]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id A850C480B16; Mon, 27 Apr 2020 06:18:41 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jdlh@jdlh.com Received: from pdx1-sub0-mail-a99.g.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.6); Mon, 27 Apr 2020 06:18:42 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jdlh@jdlh.com X-MailChannels-Auth-Id: dreamhost X-Zesty-Well-Made: 4808f70538f9a5d2_1587968322147_1672758100 X-MC-Loop-Signature: 1587968322147:3671666815 X-MC-Ingress-Time: 1587968322147 Received: from pdx1-sub0-mail-a99.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a99.g.dreamhost.com (Postfix) with ESMTP id 557B77F16F; Sun, 26 Apr 2020 23:18:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=jdlh.com; h=from:to:cc :subject:date:message-id:mime-version:content-transfer-encoding; s=jdlh.com; bh=YqWpK2JuNydRepXKm+N7qKnoNrs=; b=CFbzfsT+8zJDsaR0 LSX9ZH+hJ6MGJkBUtssAJkVagid1ncjpdQABGnz5/mUhOKK89raqiATP/4JxJTzM 0BP7FvpBYDzmkyX1JMKxu9Y9YsCk1WJFb6ppFVNhGrLq7sFYihdanVH29w4/ary8 +X047J8cLcQ8bpl23ua11S/m4qU= Received: from localhost.localdomain (216-19-179-164.dyn.novuscom.net [216.19.179.164]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jdlh@jdlh.com) by pdx1-sub0-mail-a99.g.dreamhost.com (Postfix) with ESMTPSA id C40987F165; Sun, 26 Apr 2020 23:18:40 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a99 From: list+ffmpeg-dev@jdlh.com To: ffmpeg-devel@ffmpeg.org Date: Sun, 26 Apr 2020 23:17:47 -0700 Message-Id: <20200427061747.48843-1-list+ffmpeg-dev@jdlh.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: 0 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduhedrheekgddutdeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuggftfghnshhusghstghrihgsvgdpffftgfetoffjqffuvfenuceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgggfestdekredtredttdenucfhrhhomheplhhishhtodhffhhmphgvghdquggvvhesjhgulhhhrdgtohhmnecukfhppedvudeirdduledrudejledrudeigeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehlohgtrghlhhhoshhtrdhlohgtrghlughomhgrihhnpdhinhgvthepvdduiedrudelrddujeelrdduieegpdhrvghtuhhrnhdqphgrthhhpehlihhsthdofhhfmhhpvghgqdguvghvsehjughlhhdrtghomhdpmhgrihhlfhhrohhmpehfrhhomhdrfhhfmhhpvghgqdguvghvsehjughlhhdrtghomhdpnhhrtghpthhtohepfhhrohhmodhffhhmphgvghdquggvvhesjhgulhhhrdgtohhm Subject: [FFmpeg-devel] [PATCH] Complete rewrite of the fps video filter section. More accurate. 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: Jim DeLaHunt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: mESwy6Aj7SMG From: Jim DeLaHunt This is a complete rewrite of the documentation for the "fps" video filter. It describes the filter's behaviour more clearly and accurately. I based the rewrite on reading the source code in vf_fps.c closely. No code, or other documentation files, are touched by this change. Signed-off-by: Jim DeLaHunt --- doc/filters.texi | 167 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 149 insertions(+), 18 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 71a6787289..bd4a1ad2a9 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11139,27 +11139,34 @@ format=pix_fmts=yuv420p|yuv444p|yuv410p @anchor{fps} @section fps -Convert the video to specified constant frame rate by duplicating or dropping -frames as necessary. +Generate a video, having the specified constant frame rate, from the frames of +the input video, by copying or duplicating or dropping input frames based on +their input presentation time stamps (PTSs). The output video has new PTSs. You +can choose the method for rounding from input PTS to output PTS. It accepts the following parameters: @table @option @item fps -The desired output frame rate. The default is @code{25}. +The output frame rate, as a number of frames per second. This value can be an +integer, real, or rational number, or an abbreviation. The default is @code{25}. @item start_time -Assume the first PTS should be the given value, in seconds. This allows for -padding/trimming at the start of stream. By default, no assumption is made -about the first frame's expected PTS, so no padding or trimming is done. -For example, this could be set to 0 to pad the beginning with duplicates of -the first frame if a video stream starts after the audio stream or to trim any -frames with a negative PTS. +The time, in seconds from the start of the input stream, which is converted to +an input starting PTS value and an output starting PTS value. +If set, @var{fps} drops input frames +which have PTS values less than the input starting PTS. If not set, the input +and output starting PTS values are zero, but @var{fps} drops no input frames based +on PTS. +(See details below.) @item round -Timestamp (PTS) rounding method. +Rounding method to use when calculating output Presentation Timestamp +(PTS) integer values from input PTS values. If the calculated output PTS value +is not exactly an integer, then the method determines which of the two +neighbouring integer values to choose. -Possible values are: +Possible method names are: @table @option @item zero round towards 0 @@ -11170,43 +11177,167 @@ round towards -infinity @item up round towards +infinity @item near -round to nearest +round to nearest (and if exactly at midpoint, away from 0) @end table The default is @code{near}. @item eof_action -Action performed when reading the last frame. +Action which @var{fps} takes with the final input frame. The input video passes +in an ending input PTS, which @var{fps} converts to an ending output PTS. +@var{fps} drops any input frames with a PTS at or after this ending PTS. Possible values are: @table @option @item round -Use same timestamp rounding method as used for other frames. +Use same rounding method as for other frames, to convert the ending input PTS +to output PTS. + @item pass -Pass through last frame if input duration has not been reached yet. +Round the ending input PTS using @code{up}. This can have the effect of passing +through one last input frame. @end table + The default is @code{round}. @end table -Alternatively, the options can be specified as a flat string: +Alternatively, the options may be specified as a flat string: @var{fps}[:@var{start_time}[:@var{round}]]. +@var{fps} generates an output video with integer Presentation Time Stamp (PTS) +values which increment by one each output frame, and with a time base set to +the inverse of the given frame rate. @var{fps} copies, duplicates, or drops +input frames, in sequence, to the output video. It does so according to their +input PTS values, as converted to seconds (via the input time base), then +rounded to output PTS values. + +@var{fps} sets output PTS values in terms of a time line which starts at +zero. The integer PTS value multipled by the output time base gives a point +in seconds of that output frame on that timeline. If the @var{start_time} +parameter is not set, or is zero, the first output frame's PTS value is zero. +Otherwise, the first PTS value is the output starting PTS value calculated +from the @var{start_time} parameter. + +@var{fps} interprets input PTS values in terms of the same time line. It +multiplies the input PTS value by the input time base time, to get a frame +position in seconds on the time line. It rounds that position to an integer +output PTS value. For example, if the input video has a frame rate +of 30 fps, a time base of 1/30 seconds, and its first frame has a +PTS of 300, then @var{fps} treats that frame as occurring 10 seconds (300 * 1/30 +seconds) after the start of the video, even though it is the first frame. + +Setting a @code{start_time} value allows for padding/trimming at the +start of stream. For example, @code{start_time} could be set to 0 to pad the +beginning with duplicates of the first frame if a video stream starts after +the audio stream or to trim any frames with a negative PTS. When +@code{start_time} is not set, the @var{fps} filter makes no assumption about +the first frame's expected PTS, and does not pad or trim input frames which +have a PTS set. + See also the @ref{setpts} filter. +@subsection Details + +@var{fps} emits exactly one frame for each output PTS value. If there is +exactly one input frame with an input PTS which converts to the current output +PTS value, @var{fps} emits that frame. If there are multiple frames which +convert to the same output PTS value, @var{fps} emits the final frame of that +group, and drops the previous frames. If no input frame PTS converts to a given +output PTS value, @var{fps} emits another copy of the previously emitted frame. +When the first input frame converts to an output PTS after the first frame, then +@var{fps} emits copies of that first frame until the output PTS reaches the +converted value of that first frame's input PTS. + +@var{fps} always drops input frames which have no PTS value set, regardless +of the @var{start_time} parameter. + +The @var{frame rate} value may be provided in a variety of forms. Each form is +converted into a rational number, with an integer numerator and denominator. +Each value must be zero or greater. + +@itemize + +@item +An integer number, e.g. @code{25}. This converts to the rational number +@code{25/1}. + +@item +A real number, e.g. @code{3.14145926}. This converts to a rational number, +e.g. @code{954708/303893} + +@item +A rational number. The numerator and denominator may be either integers or real +numbers. e.g. @code{30/1.001} or @code{30000/1001}, which both convert to +@code{30000/1001}. + +@item +An abbreviation. e.g @code{ntsc} as @code{30000/1001}, +@code{ntsc-film} as @code{24000/1001}. See the complete list at +@ref{Video rate,,the "Video rate" section in the ffmpeg-utils(1) manual,ffmpeg-utils}. + +@end itemize + +@var{fps} defines a sync point, where one input PTS value is treated as occuring +at the same moment as one output PTS value. IT calcluates other PTS values +as positive or negative time offsets from this sync point. +This affects the details of how rounding works. If @var{start_time} is set, +then the input and output PTS values which @var{fps} calculates from this +become the sync point. Otherwise, input and output PTS values of zero are +the sync point. + +Note that @var{fps} does not assume that input frames are separated by exactly +1/frame_rate seconds. It takes the input PTS values literally. If the increment +of PTS between frames varies along the video, fps will treat those frames as +happening at varying time intervals. + +As a consequence, if you have a video which is supposed to be at a certain frame +rate, but in reality the frames were not always captured at the exactly right +moment, and if the input PTS values reflect that variation, then you can pass +this video through an @var{fps} filter set to the same frame rate. A @var{round} +method of @code{near} will pass through each input frame exactly once, and +the output video will have new PTS values which reflect the exact time interval +(1/frame rate) between frames. + +Because @var{fps} treats input PTS values at face value when converting them to +time on the time line, and because that time line starts at zero, an input +video with PTS values that do not start at zero might yield unexpected results. +Suppose the input PTS values start with the value 300, which converts to 10 +seconds after the sync point. Then @var{fps} will repeat the first frame of the +input video to fill the first 10 seconds of the output video. (However, +@command{ffmpeg} may suppress those repeated frames, depending on the +@option{-vsync} setting.) If you set @var{start_time} to 10 seconds, then +@var{fps} sets the sync point to the PTS values converted from the 10 second +moment on the time line. It no longer repeats the first frame. And, it starts +the output PTS at the value corresponding to 10 seconds, instead of zero. + @subsection Examples @itemize @item -A typical usage in order to set the fps to 25: +A typical usage in order to emit a video with a frame rate of 25 frames per second: @example fps=fps=25 @end example @item -Sets the fps to 24, using abbreviation and rounding method to round to nearest: +Emit a video with a frame rate of 24 frames per second, using an abbreviation, +and rounding method to round to nearest: @example fps=fps=film:round=near @end example + +@item +If an input video is supposed to have a frame rate of 29.97 frames per second +(NTSC standard), but the time base is 3003/90000, and the PTS values increment +variably at slightly more and less than that rate, this emits a video with the +same frames, but with a new time base and PTS values that increment at exactly +the NTSC rate. If some frames were dropped by the recorder, but the PTS values +still reflect when the remaining frames were captured, this will also repeat +frames to fill the gaps from the dropped frames. +@example +fps=fps=30/1.001:round=near +@end example + @end itemize @section framepack