// Copyright 2015 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MEDIA_FILTERS_VIDEO_CADENCE_ESTIMATOR_H_ #define MEDIA_FILTERS_VIDEO_CADENCE_ESTIMATOR_H_ #include <stddef.h> #include <stdint.h> #include <optional> #include <string> #include <vector> #include "base/time/time.h" #include "media/base/media_export.h" namespace media { // Estimates whether a given frame duration and render interval length have a // render cadence which would allow for optimal uniformity of displayed frame // durations over time. // // Cadence is the ideal repeating frame pattern for a group of frames; currently // VideoCadenceEstimator supports N-frame ([a1:a2:..:aN]) cadences where N <= 5. // Details on what this means are below. // // The perfect cadence of a set of frames is the ratio of the frame duration to // render interval length. I.e. for 30fps in 60Hz the cadence would be (1/30) / // (1/60) = 60 / 30 = 2. It's common that this is not an exact integer, e.g., // 29.974fps in 60Hz which would have a cadence of (1/29.974) / (1/60) = // ~2.0029. // // The perfect cadence is always a real number. All N-cadences [a1:a2:..:aN] // where aK is an integer are an approximation of the perfect cadence; i.e. the // average of [a1:..:aN] will approximately equal the perfect cadence. When N=1 // we have a 1-frame cadence, when N=2, we have a 2-frame cadence, etc. // // For single frame cadence we just round the perfect cadence (~2.0029 in the // previous example) to the nearest integer value (2 in this case; which is // denoted as a cadence of [2]). If the delta between those values is small we // can choose to render frames for the integer number of render intervals; // shortening or lengthening the actual rendered frame duration. Doing so // ensures each frame gets an optimal amount of display time. // // For N-frame cadence, the idea is similar, we just round the perfect cadence // to some K/N, where K is an integer, and distribute [floor(K/N), floor(K/N)+1] // into the cadence vector as evenly as possible. For example, 23.97fps in // 60Hz, the perfect cadence is 2.50313, we can round it to 2.5 = 5/2, and we // can then construct the cadence vector as [2:3]. // // The delta between the perfect cadence and the rounded cadence leads to drift // over time of the actual VideoFrame timestamp relative to its rendered time, // so we perform some calculations to ensure we only use a cadence when it will // take some time to drift an undesirable amount; see CalculateCadence() for // details on how this calculation is made. // // In practice this works out to the following for common setups if we use // cadence based selection: // // 29.5fps in 60Hz, ~17ms max drift => exhausted in ~1 second. // 29.9fps in 60Hz, ~17ms max drift => exhausted in ~16.4 seconds. // 24fps in 59.9Hz, ~21ms max drift => exhausted in ~12.6 seconds. // 24.9fps in 60Hz, ~20ms max drift => exhausted in ~4.0 seconds. // 59.9fps in 60Hz, ~8.3ms max drift => exhausted in ~8.2 seconds. // 24.9fps in 50Hz, ~20ms max drift => exhausted in ~20.5 seconds. // 120fps in 59.9Hz, ~8.3ms max drift => exhausted in ~8.2 seconds. // class MEDIA_EXPORT VideoCadenceEstimator { … }; } // namespace media #endif // MEDIA_FILTERS_VIDEO_CADENCE_ESTIMATOR_H_