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