xref: /aosp_15_r20/external/libwebm/common/vp9_level_stats.h (revision 103e46e4cd4b6efcf6001f23fa8665fb110abf8d)
1*103e46e4SHarish Mahendrakar // Copyright (c) 2016 The WebM project authors. All Rights Reserved.
2*103e46e4SHarish Mahendrakar //
3*103e46e4SHarish Mahendrakar // Use of this source code is governed by a BSD-style license
4*103e46e4SHarish Mahendrakar // that can be found in the LICENSE file in the root of the source
5*103e46e4SHarish Mahendrakar // tree. An additional intellectual property rights grant can be found
6*103e46e4SHarish Mahendrakar // in the file PATENTS.  All contributing project authors may
7*103e46e4SHarish Mahendrakar // be found in the AUTHORS file in the root of the source tree.
8*103e46e4SHarish Mahendrakar #ifndef LIBWEBM_COMMON_VP9_LEVEL_STATS_H_
9*103e46e4SHarish Mahendrakar #define LIBWEBM_COMMON_VP9_LEVEL_STATS_H_
10*103e46e4SHarish Mahendrakar 
11*103e46e4SHarish Mahendrakar #include <limits>
12*103e46e4SHarish Mahendrakar #include <queue>
13*103e46e4SHarish Mahendrakar #include <utility>
14*103e46e4SHarish Mahendrakar 
15*103e46e4SHarish Mahendrakar #include "common/vp9_header_parser.h"
16*103e46e4SHarish Mahendrakar 
17*103e46e4SHarish Mahendrakar namespace vp9_parser {
18*103e46e4SHarish Mahendrakar 
19*103e46e4SHarish Mahendrakar const int kMaxVp9RefFrames = 8;
20*103e46e4SHarish Mahendrakar 
21*103e46e4SHarish Mahendrakar // Defined VP9 levels. See http://www.webmproject.org/vp9/profiles/ for
22*103e46e4SHarish Mahendrakar // detailed information on VP9 levels.
23*103e46e4SHarish Mahendrakar const int kNumVp9Levels = 14;
24*103e46e4SHarish Mahendrakar enum Vp9Level {
25*103e46e4SHarish Mahendrakar   LEVEL_UNKNOWN = 0,
26*103e46e4SHarish Mahendrakar   LEVEL_1 = 10,
27*103e46e4SHarish Mahendrakar   LEVEL_1_1 = 11,
28*103e46e4SHarish Mahendrakar   LEVEL_2 = 20,
29*103e46e4SHarish Mahendrakar   LEVEL_2_1 = 21,
30*103e46e4SHarish Mahendrakar   LEVEL_3 = 30,
31*103e46e4SHarish Mahendrakar   LEVEL_3_1 = 31,
32*103e46e4SHarish Mahendrakar   LEVEL_4 = 40,
33*103e46e4SHarish Mahendrakar   LEVEL_4_1 = 41,
34*103e46e4SHarish Mahendrakar   LEVEL_5 = 50,
35*103e46e4SHarish Mahendrakar   LEVEL_5_1 = 51,
36*103e46e4SHarish Mahendrakar   LEVEL_5_2 = 52,
37*103e46e4SHarish Mahendrakar   LEVEL_6 = 60,
38*103e46e4SHarish Mahendrakar   LEVEL_6_1 = 61,
39*103e46e4SHarish Mahendrakar   LEVEL_6_2 = 62
40*103e46e4SHarish Mahendrakar };
41*103e46e4SHarish Mahendrakar 
42*103e46e4SHarish Mahendrakar struct Vp9LevelRow {
43*103e46e4SHarish Mahendrakar   Vp9Level level;
44*103e46e4SHarish Mahendrakar   int64_t max_luma_sample_rate;
45*103e46e4SHarish Mahendrakar   int64_t max_luma_picture_size;
46*103e46e4SHarish Mahendrakar   int64_t max_luma_picture_breadth;
47*103e46e4SHarish Mahendrakar   double average_bitrate;
48*103e46e4SHarish Mahendrakar   double max_cpb_size;
49*103e46e4SHarish Mahendrakar   double compression_ratio;
50*103e46e4SHarish Mahendrakar   int max_tiles;
51*103e46e4SHarish Mahendrakar   int min_altref_distance;
52*103e46e4SHarish Mahendrakar   int max_ref_frames;
53*103e46e4SHarish Mahendrakar };
54*103e46e4SHarish Mahendrakar 
55*103e46e4SHarish Mahendrakar // Class to determine the VP9 level of a VP9 bitstream.
56*103e46e4SHarish Mahendrakar class Vp9LevelStats {
57*103e46e4SHarish Mahendrakar  public:
58*103e46e4SHarish Mahendrakar   static const Vp9LevelRow Vp9LevelTable[kNumVp9Levels];
59*103e46e4SHarish Mahendrakar 
Vp9LevelStats()60*103e46e4SHarish Mahendrakar   Vp9LevelStats()
61*103e46e4SHarish Mahendrakar       : frames(0),
62*103e46e4SHarish Mahendrakar         displayed_frames(0),
63*103e46e4SHarish Mahendrakar         start_ns_(-1),
64*103e46e4SHarish Mahendrakar         end_ns_(-1),
65*103e46e4SHarish Mahendrakar         duration_ns_(-1),
66*103e46e4SHarish Mahendrakar         max_luma_picture_size_(0),
67*103e46e4SHarish Mahendrakar         max_luma_picture_breadth_(0),
68*103e46e4SHarish Mahendrakar         current_luma_size_(0),
69*103e46e4SHarish Mahendrakar         max_luma_size_(0),
70*103e46e4SHarish Mahendrakar         max_luma_end_ns_(0),
71*103e46e4SHarish Mahendrakar         max_luma_sample_rate_grace_percent_(1.5),
72*103e46e4SHarish Mahendrakar         first_altref(true),
73*103e46e4SHarish Mahendrakar         frames_since_last_altref(0),
74*103e46e4SHarish Mahendrakar         minimum_altref_distance(std::numeric_limits<int>::max()),
75*103e46e4SHarish Mahendrakar         min_altref_end_ns(0),
76*103e46e4SHarish Mahendrakar         max_cpb_window_size_(0),
77*103e46e4SHarish Mahendrakar         max_cpb_window_end_ns_(0),
78*103e46e4SHarish Mahendrakar         current_cpb_size_(0),
79*103e46e4SHarish Mahendrakar         max_cpb_size_(0),
80*103e46e4SHarish Mahendrakar         max_cpb_start_ns_(0),
81*103e46e4SHarish Mahendrakar         max_cpb_end_ns_(0),
82*103e46e4SHarish Mahendrakar         total_compressed_size_(0),
83*103e46e4SHarish Mahendrakar         total_uncompressed_bits_(0),
84*103e46e4SHarish Mahendrakar         frames_refreshed_(0),
85*103e46e4SHarish Mahendrakar         max_frames_refreshed_(0),
86*103e46e4SHarish Mahendrakar         max_column_tiles_(0),
87*103e46e4SHarish Mahendrakar         estimate_last_frame_duration_(true) {}
88*103e46e4SHarish Mahendrakar 
89*103e46e4SHarish Mahendrakar   ~Vp9LevelStats() = default;
90*103e46e4SHarish Mahendrakar   Vp9LevelStats(Vp9LevelStats&& other) = delete;
91*103e46e4SHarish Mahendrakar   Vp9LevelStats(const Vp9LevelStats& other) = delete;
92*103e46e4SHarish Mahendrakar   Vp9LevelStats& operator=(Vp9LevelStats&& other) = delete;
93*103e46e4SHarish Mahendrakar   Vp9LevelStats& operator=(const Vp9LevelStats& other) = delete;
94*103e46e4SHarish Mahendrakar 
95*103e46e4SHarish Mahendrakar   // Collects stats on a VP9 frame. The frame must already be parsed by
96*103e46e4SHarish Mahendrakar   // |parser|. |time_ns| is the start time of the frame in nanoseconds.
97*103e46e4SHarish Mahendrakar   void AddFrame(const Vp9HeaderParser& parser, int64_t time_ns);
98*103e46e4SHarish Mahendrakar 
99*103e46e4SHarish Mahendrakar   // Returns the current VP9 level. All of the video frames should have been
100*103e46e4SHarish Mahendrakar   // processed with AddFrame before calling this function.
101*103e46e4SHarish Mahendrakar   Vp9Level GetLevel() const;
102*103e46e4SHarish Mahendrakar 
103*103e46e4SHarish Mahendrakar   // Returns the maximum luma samples (pixels) per second. The Alt-Ref frames
104*103e46e4SHarish Mahendrakar   // are taken into account, therefore this number may be larger than the
105*103e46e4SHarish Mahendrakar   // display luma samples per second
106*103e46e4SHarish Mahendrakar   int64_t GetMaxLumaSampleRate() const;
107*103e46e4SHarish Mahendrakar 
108*103e46e4SHarish Mahendrakar   // The maximum frame size (width * height) in samples.
109*103e46e4SHarish Mahendrakar   int64_t GetMaxLumaPictureSize() const;
110*103e46e4SHarish Mahendrakar 
111*103e46e4SHarish Mahendrakar   // The maximum frame breadth (max of width and height) in samples.
112*103e46e4SHarish Mahendrakar   int64_t GetMaxLumaPictureBreadth() const;
113*103e46e4SHarish Mahendrakar 
114*103e46e4SHarish Mahendrakar   // The average bitrate of the video in kbps.
115*103e46e4SHarish Mahendrakar   double GetAverageBitRate() const;
116*103e46e4SHarish Mahendrakar 
117*103e46e4SHarish Mahendrakar   // The largest data size for any 4 consecutive frames in kilobits.
118*103e46e4SHarish Mahendrakar   double GetMaxCpbSize() const;
119*103e46e4SHarish Mahendrakar 
120*103e46e4SHarish Mahendrakar   // The ratio of total bytes decompressed over total bytes compressed.
121*103e46e4SHarish Mahendrakar   double GetCompressionRatio() const;
122*103e46e4SHarish Mahendrakar 
123*103e46e4SHarish Mahendrakar   // The maximum number of VP9 column tiles.
124*103e46e4SHarish Mahendrakar   int GetMaxColumnTiles() const;
125*103e46e4SHarish Mahendrakar 
126*103e46e4SHarish Mahendrakar   // The minimum distance in frames between two consecutive alternate reference
127*103e46e4SHarish Mahendrakar   // frames.
128*103e46e4SHarish Mahendrakar   int GetMinimumAltrefDistance() const;
129*103e46e4SHarish Mahendrakar 
130*103e46e4SHarish Mahendrakar   // The maximum number of reference frames that had to be stored.
131*103e46e4SHarish Mahendrakar   int GetMaxReferenceFrames() const;
132*103e46e4SHarish Mahendrakar 
133*103e46e4SHarish Mahendrakar   // Sets the duration of the video stream in nanoseconds. If the duration is
134*103e46e4SHarish Mahendrakar   // not explictly set by this function then this class will use end - start
135*103e46e4SHarish Mahendrakar   // as the duration.
set_duration(int64_t time_ns)136*103e46e4SHarish Mahendrakar   void set_duration(int64_t time_ns) { duration_ns_ = time_ns; }
max_luma_sample_rate_grace_percent()137*103e46e4SHarish Mahendrakar   double max_luma_sample_rate_grace_percent() const {
138*103e46e4SHarish Mahendrakar     return max_luma_sample_rate_grace_percent_;
139*103e46e4SHarish Mahendrakar   }
set_max_luma_sample_rate_grace_percent(double percent)140*103e46e4SHarish Mahendrakar   void set_max_luma_sample_rate_grace_percent(double percent) {
141*103e46e4SHarish Mahendrakar     max_luma_sample_rate_grace_percent_ = percent;
142*103e46e4SHarish Mahendrakar   }
estimate_last_frame_duration()143*103e46e4SHarish Mahendrakar   bool estimate_last_frame_duration() const {
144*103e46e4SHarish Mahendrakar     return estimate_last_frame_duration_;
145*103e46e4SHarish Mahendrakar   }
146*103e46e4SHarish Mahendrakar 
147*103e46e4SHarish Mahendrakar   // If true try to estimate the last frame's duration if the stream's duration
148*103e46e4SHarish Mahendrakar   // is not set or the stream's duration equals the last frame's timestamp.
set_estimate_last_frame_duration(bool flag)149*103e46e4SHarish Mahendrakar   void set_estimate_last_frame_duration(bool flag) {
150*103e46e4SHarish Mahendrakar     estimate_last_frame_duration_ = flag;
151*103e46e4SHarish Mahendrakar   }
152*103e46e4SHarish Mahendrakar 
153*103e46e4SHarish Mahendrakar  private:
154*103e46e4SHarish Mahendrakar   int frames;
155*103e46e4SHarish Mahendrakar   int displayed_frames;
156*103e46e4SHarish Mahendrakar 
157*103e46e4SHarish Mahendrakar   int64_t start_ns_;
158*103e46e4SHarish Mahendrakar   int64_t end_ns_;
159*103e46e4SHarish Mahendrakar   int64_t duration_ns_;
160*103e46e4SHarish Mahendrakar 
161*103e46e4SHarish Mahendrakar   int64_t max_luma_picture_size_;
162*103e46e4SHarish Mahendrakar   int64_t max_luma_picture_breadth_;
163*103e46e4SHarish Mahendrakar 
164*103e46e4SHarish Mahendrakar   // This is used to calculate the maximum number of luma samples per second.
165*103e46e4SHarish Mahendrakar   // The first value is the luma picture size and the second value is the time
166*103e46e4SHarish Mahendrakar   // in nanoseconds of one frame.
167*103e46e4SHarish Mahendrakar   std::queue<std::pair<int64_t, int64_t>> luma_window_;
168*103e46e4SHarish Mahendrakar   int64_t current_luma_size_;
169*103e46e4SHarish Mahendrakar   int64_t max_luma_size_;
170*103e46e4SHarish Mahendrakar   int64_t max_luma_end_ns_;
171*103e46e4SHarish Mahendrakar 
172*103e46e4SHarish Mahendrakar   // MaxLumaSampleRate = (ExampleFrameRate + ExampleFrameRate /
173*103e46e4SHarish Mahendrakar   // MinimumAltrefDistance) * MaxLumaPictureSize. For levels 1-4
174*103e46e4SHarish Mahendrakar   // ExampleFrameRate / MinimumAltrefDistance is non-integer, so using a sliding
175*103e46e4SHarish Mahendrakar   // window of one frame to calculate MaxLumaSampleRate may have frames >
176*103e46e4SHarish Mahendrakar   // (ExampleFrameRate + ExampleFrameRate / MinimumAltrefDistance) in the
177*103e46e4SHarish Mahendrakar   // window. In order to address this issue, a grace percent of 1.5 was added.
178*103e46e4SHarish Mahendrakar   double max_luma_sample_rate_grace_percent_;
179*103e46e4SHarish Mahendrakar 
180*103e46e4SHarish Mahendrakar   bool first_altref;
181*103e46e4SHarish Mahendrakar   int frames_since_last_altref;
182*103e46e4SHarish Mahendrakar   int minimum_altref_distance;
183*103e46e4SHarish Mahendrakar   int64_t min_altref_end_ns;
184*103e46e4SHarish Mahendrakar 
185*103e46e4SHarish Mahendrakar   // This is used to calculate the maximum number of compressed bytes for four
186*103e46e4SHarish Mahendrakar   // consecutive frames. The first value is the compressed frame size and the
187*103e46e4SHarish Mahendrakar   // second value is the time in nanoseconds of one frame.
188*103e46e4SHarish Mahendrakar   std::queue<std::pair<int64_t, int64_t>> cpb_window_;
189*103e46e4SHarish Mahendrakar   int64_t max_cpb_window_size_;
190*103e46e4SHarish Mahendrakar   int64_t max_cpb_window_end_ns_;
191*103e46e4SHarish Mahendrakar   int64_t current_cpb_size_;
192*103e46e4SHarish Mahendrakar   int64_t max_cpb_size_;
193*103e46e4SHarish Mahendrakar   int64_t max_cpb_start_ns_;
194*103e46e4SHarish Mahendrakar   int64_t max_cpb_end_ns_;
195*103e46e4SHarish Mahendrakar 
196*103e46e4SHarish Mahendrakar   int64_t total_compressed_size_;
197*103e46e4SHarish Mahendrakar   int64_t total_uncompressed_bits_;
198*103e46e4SHarish Mahendrakar   int frames_refreshed_;
199*103e46e4SHarish Mahendrakar   int max_frames_refreshed_;
200*103e46e4SHarish Mahendrakar 
201*103e46e4SHarish Mahendrakar   int max_column_tiles_;
202*103e46e4SHarish Mahendrakar 
203*103e46e4SHarish Mahendrakar   bool estimate_last_frame_duration_;
204*103e46e4SHarish Mahendrakar };
205*103e46e4SHarish Mahendrakar 
206*103e46e4SHarish Mahendrakar }  // namespace vp9_parser
207*103e46e4SHarish Mahendrakar 
208*103e46e4SHarish Mahendrakar #endif  // LIBWEBM_COMMON_VP9_LEVEL_STATS_H_
209