From patchwork Fri May 1 04:04:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jim DeLaHunt X-Patchwork-Id: 19413 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 5ABA0449800 for ; Fri, 1 May 2020 07:05:13 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2D54A68C7BF; Fri, 1 May 2020 07:05:13 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from bonobo.elm.relay.mailchannels.net (bonobo.elm.relay.mailchannels.net [23.83.212.22]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 89D7C68BBC8 for ; Fri, 1 May 2020 07:05:06 +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 8E6A43212A1; Fri, 1 May 2020 04:05:03 +0000 (UTC) Received: from pdx1-sub0-mail-a8.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 81E99321316; Fri, 1 May 2020 04:05:02 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jdlh@jdlh.com Received: from pdx1-sub0-mail-a8.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); Fri, 01 May 2020 04:05:03 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jdlh@jdlh.com X-MailChannels-Auth-Id: dreamhost X-Arch-Relation: 3c4121c904ce1acb_1588305903297_1732700468 X-MC-Loop-Signature: 1588305903297:3087201853 X-MC-Ingress-Time: 1588305903297 Received: from pdx1-sub0-mail-a8.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a8.g.dreamhost.com (Postfix) with ESMTP id 39A867FF81; Thu, 30 Apr 2020 21:05:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=jdlh.com; h=from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-type:content-transfer-encoding; s=jdlh.com; bh=0z5CMaoz qbw6lZzdOq/Tu/I/x7s=; b=B/SpJjL7iwFkd4x6ry8pnaacJ7l6dmmoB2H+Mqoc miU1UfumXnTLDAfY5KfOzAjAxo+e8/EtVZXQ0CryU/kXws2XIJurRIR3OsP2ZFh3 j1VpuHaqa2Y0H9EyGkimjFbXTqPzHklSb0C6inNRJWL0VG5EZJlp5pfgpjrTcIUQ XR4= 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-a8.g.dreamhost.com (Postfix) with ESMTPSA id DCA0C7FF7F; Thu, 30 Apr 2020 21:05:01 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a8 From: list+ffmpeg-dev@jdlh.com To: ffmpeg-devel@ffmpeg.org Date: Thu, 30 Apr 2020 21:04:12 -0700 Message-Id: <20200501040412.16472-2-list+ffmpeg-dev@jdlh.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200427061747.48843-1-list+ffmpeg-dev@jdlh.com> References: <20200427061747.48843-1-list+ffmpeg-dev@jdlh.com> MIME-Version: 1.0 X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: 0 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduhedrieeigdejiecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucggtfgfnhhsuhgsshgtrhhisggvpdfftffgtefojffquffvnecuuegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfgggtgfesthekredtredtjeenucfhrhhomheplhhishhtodhffhhmphgvghdquggvvhesjhgulhhhrdgtohhmnecuggftrfgrthhtvghrnhephfetheduledtieefgefhueefheejteeghfelteelhfeluefftdeuleetudfgtdfgnecukfhppedvudeirdduledrudejledrudeigeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehlohgtrghlhhhoshhtrdhlohgtrghlughomhgrihhnpdhinhgvthepvdduiedrudelrddujeelrdduieegpdhrvghtuhhrnhdqphgrthhhpehlihhsthdofhhfmhhpvghgqdguvghvsehjughlhhdrtghomhdpmhgrihhlfhhrohhmpehlihhsthdofhhfmhhpvghgqdguvghvsehjughlhhdrtghomhdpnhhrtghpthhtohepfhhrohhmodhffhhmphgvghdquggvvhesjhgulhhhrdgtohhm Subject: [FFmpeg-devel] [PATCH v2] doc/filters.texi: complete rewrite of fps filter doc, v2. 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" From: Jim DeLaHunt Fix unclear wording and spelling mistakes based on review. Reduce overall word count by 11%. Ready for patch review. No other docs, and no executable code, are changed. Signed-off-by: Jim DeLaHunt --- doc/filters.texi | 157 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 138 insertions(+), 19 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index d19fd346ae..0d7d15c448 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11194,25 +11194,30 @@ 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. +Make a new video from the frames and presentation time stamps (PTSs) of the +input. The new video has a specified constant frame rate, and new PTSs. It +generally keeps frames from the old video, but might repeat or drop some frames. +You can choose the method for rounding from input PTS to output PTS. This +affects which frames @var{fps} keeps, repeats, or drops. It accepts the following parameters: @table @option @item fps -The desired output frame rate. The default is @code{25}. +The output frame rate, in frames per second. May 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. +A time, in seconds from the start of the input stream, which @var{fps} converts +to an input starting PTS and an output starting PTS. If set, +@var{fps} drops input frames which have PTSs less than the input starting +PTS. If not set, the input and output starting PTSs 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 PTSs from input PTSs. +If the calculated output PTS is not exactly an integer, then the value +determines which neighbouring integer value @var{fps} selects. Possible values are: @table @option @@ -11225,43 +11230,157 @@ round towards -infinity @item up round towards +infinity @item near -round to nearest +round to nearest (midpoints round 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 a final input PTS, which @var{fps} converts to an output PTS limit. +@var{fps} drops any input frames with a PTS at or after this limit. 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. + @item pass -Pass through last frame if input duration has not been reached yet. +Round the ending input PTS using @code{up}. This might make @ref{fps} include +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}]]. -See also the @ref{setpts} filter. +@var{fps} makes an output video with consecutive integer PTSs, and with a +time base set to the inverse of the given frame rate. @var{fps} keeps, repeats, +or drops input frames, in sequence, to the output video. It does so according +to their input PTSs, as converted to seconds (via the input time base), +then rounded to output PTSs. + +@var{fps} sets output PTSs in terms of a timeline which starts at +zero. For any output frame, the integer PTS multiplied by the time base +gives a value in seconds on that timeline. If the @var{start_time} +parameter is not set, or is zero, the first output frame's PTS is zero. +Otherwise, the first PTS is the output starting PTS calculated +from the @var{start_time} parameter. + +@var{fps} interprets input PTSs in terms of the same timeline. It +multiplies each input frame's PTS by the input time base, to get a value +in seconds on the timeline. It rounds that value to an integer output PTS. +For example, if the input video has a frame rate of 30 fps, a time base +of 1/30 seconds, and a first frame with a PTS of 300, then @var{fps} treats that +first frame as occurring 10 seconds (= 300 * 1/30) 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 the input. For example, you can set @code{start_time} to 0, to pad the +beginning with repeats 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 does not pad or trim +starting frames, as long as they contain PTSs. + +See also the @ref{setpts} and @var{settb} filters. + +@subsection Details + +@var{fps} outputs exactly one frame for each output PTS. If there is +exactly one input frame with an input PTS which converts to the current output +PTS, @var{fps} keeps (outputs) that frame. If there are multiple frames which +convert to the same output PTS, @var{fps} outputs the final frame of that +group, and drops the previous frames. + +If the input frame PTS converts to an output PTS later than the current +output PTS, @var{fps} repeats the previously output frame as the current frame. +When this happens for the first input frame, @var{fps} "pads" — outputs +repetitions of — that first frame until the output PTS reaches the value +converted from that first frame's input PTS. + +@var{fps} always drops input frames which have no PTS set, regardless +of the @var{start_time} parameter. + +The @var{frame rate} value must be zero or greater. It may be provided in a +variety of forms. Each form is converted into a rational number, with an +integer numerator and denominator. + +@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}. The denominator must be non-zero. + +@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 on the timeline, where one input PTS and one +output PTS occur at the same moment. It calculates other PTSs as time offsets +from this sync point. This affects the details of rounding. If @var{start_time} +is set, then @var{fps} uses it to calculate input and output PTSs, and makes +them the sync point. Otherwise, input and output PTS 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 PTSs literally. If the increment +of PTS between frames varies along the video, @var{fps} treats those frames as +happening at varying time intervals. + +An input video with PTSs starting past zero might yield unexpected results. +Suppose the input PTSs start at 300, and say that converts to 10 seconds. +Then @var{fps} repeats the first frame 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 PTSs converted from +10 seconds on the timeline. It no longer repeats the first frame. And, it starts +the output PTS at a 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 to make a video with a frame rate of 25 frames per +second, from an input video with any frame rate: @example fps=fps=25 @end example - +The output frames have PTSs of 0, 1, 2, etc. The frame rate is @code{25/1}. The +time base is @code{1/25}. @item -Sets the fps to 24, using abbreviation and rounding method to round to nearest: +Make 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 +Clean up a video with varying time between frames, and dropped frames. +The input video is supposed to have an NTSC standard frame rate of 29.97 frames +per second, and the time base is @code{3003/90000}, but the PTSs increment +variably at slightly more and less than that rate. The recorder dropped some +frames, but the PTSs still reflect when the remaining frames were captured. +@example +fps=fps=30/1.001:round=near +@end example +The output PTSs are 0, 1001, 2002, etc. The time between frames is exact. +The output frame rate is @code{30000/1001}. The time base is @code{1001/30000}. +Where frames were dropped by the recorder, @var{fps} repeated frames to fill +the gaps. + @end itemize @section framepack