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 Vp9Level level; 44 int64_t max_luma_sample_rate; 45 int64_t max_luma_picture_size; 46 int64_t max_luma_picture_breadth; 47 double average_bitrate; 48 double max_cpb_size; 49 double compression_ratio; 50 int max_tiles; 51 int min_altref_distance; 52 int max_ref_frames; 53 }; 54 55 // Class to determine the VP9 level of a VP9 bitstream. 56 class Vp9LevelStats { 57 public: 58 static const Vp9LevelRow Vp9LevelTable[kNumVp9Levels]; 59 Vp9LevelStats()60 Vp9LevelStats() 61 : frames(0), 62 displayed_frames(0), 63 start_ns_(-1), 64 end_ns_(-1), 65 duration_ns_(-1), 66 max_luma_picture_size_(0), 67 max_luma_picture_breadth_(0), 68 current_luma_size_(0), 69 max_luma_size_(0), 70 max_luma_end_ns_(0), 71 max_luma_sample_rate_grace_percent_(1.5), 72 first_altref(true), 73 frames_since_last_altref(0), 74 minimum_altref_distance(std::numeric_limits<int>::max()), 75 min_altref_end_ns(0), 76 max_cpb_window_size_(0), 77 max_cpb_window_end_ns_(0), 78 current_cpb_size_(0), 79 max_cpb_size_(0), 80 max_cpb_start_ns_(0), 81 max_cpb_end_ns_(0), 82 total_compressed_size_(0), 83 total_uncompressed_bits_(0), 84 frames_refreshed_(0), 85 max_frames_refreshed_(0), 86 max_column_tiles_(0), 87 estimate_last_frame_duration_(true) {} 88 89 ~Vp9LevelStats() = default; 90 Vp9LevelStats(Vp9LevelStats&& other) = delete; 91 Vp9LevelStats(const Vp9LevelStats& other) = delete; 92 Vp9LevelStats& operator=(Vp9LevelStats&& other) = delete; 93 Vp9LevelStats& operator=(const Vp9LevelStats& other) = delete; 94 95 // Collects stats on a VP9 frame. The frame must already be parsed by 96 // |parser|. |time_ns| is the start time of the frame in nanoseconds. 97 void AddFrame(const Vp9HeaderParser& parser, int64_t time_ns); 98 99 // Returns the current VP9 level. All of the video frames should have been 100 // processed with AddFrame before calling this function. 101 Vp9Level GetLevel() const; 102 103 // Returns the maximum luma samples (pixels) per second. The Alt-Ref frames 104 // are taken into account, therefore this number may be larger than the 105 // display luma samples per second 106 int64_t GetMaxLumaSampleRate() const; 107 108 // The maximum frame size (width * height) in samples. 109 int64_t GetMaxLumaPictureSize() const; 110 111 // The maximum frame breadth (max of width and height) in samples. 112 int64_t GetMaxLumaPictureBreadth() const; 113 114 // The average bitrate of the video in kbps. 115 double GetAverageBitRate() const; 116 117 // The largest data size for any 4 consecutive frames in kilobits. 118 double GetMaxCpbSize() const; 119 120 // The ratio of total bytes decompressed over total bytes compressed. 121 double GetCompressionRatio() const; 122 123 // The maximum number of VP9 column tiles. 124 int GetMaxColumnTiles() const; 125 126 // The minimum distance in frames between two consecutive alternate reference 127 // frames. 128 int GetMinimumAltrefDistance() const; 129 130 // The maximum number of reference frames that had to be stored. 131 int GetMaxReferenceFrames() const; 132 133 // Sets the duration of the video stream in nanoseconds. If the duration is 134 // not explictly set by this function then this class will use end - start 135 // as the duration. set_duration(int64_t time_ns)136 void set_duration(int64_t time_ns) { duration_ns_ = time_ns; } max_luma_sample_rate_grace_percent()137 double max_luma_sample_rate_grace_percent() const { 138 return max_luma_sample_rate_grace_percent_; 139 } set_max_luma_sample_rate_grace_percent(double percent)140 void set_max_luma_sample_rate_grace_percent(double percent) { 141 max_luma_sample_rate_grace_percent_ = percent; 142 } estimate_last_frame_duration()143 bool estimate_last_frame_duration() const { 144 return estimate_last_frame_duration_; 145 } 146 147 // If true try to estimate the last frame's duration if the stream's duration 148 // is not set or the stream's duration equals the last frame's timestamp. set_estimate_last_frame_duration(bool flag)149 void set_estimate_last_frame_duration(bool flag) { 150 estimate_last_frame_duration_ = flag; 151 } 152 153 private: 154 int frames; 155 int displayed_frames; 156 157 int64_t start_ns_; 158 int64_t end_ns_; 159 int64_t duration_ns_; 160 161 int64_t max_luma_picture_size_; 162 int64_t max_luma_picture_breadth_; 163 164 // This is used to calculate the maximum number of luma samples per second. 165 // The first value is the luma picture size and the second value is the time 166 // in nanoseconds of one frame. 167 std::queue<std::pair<int64_t, int64_t>> luma_window_; 168 int64_t current_luma_size_; 169 int64_t max_luma_size_; 170 int64_t max_luma_end_ns_; 171 172 // MaxLumaSampleRate = (ExampleFrameRate + ExampleFrameRate / 173 // MinimumAltrefDistance) * MaxLumaPictureSize. For levels 1-4 174 // ExampleFrameRate / MinimumAltrefDistance is non-integer, so using a sliding 175 // window of one frame to calculate MaxLumaSampleRate may have frames > 176 // (ExampleFrameRate + ExampleFrameRate / MinimumAltrefDistance) in the 177 // window. In order to address this issue, a grace percent of 1.5 was added. 178 double max_luma_sample_rate_grace_percent_; 179 180 bool first_altref; 181 int frames_since_last_altref; 182 int minimum_altref_distance; 183 int64_t min_altref_end_ns; 184 185 // This is used to calculate the maximum number of compressed bytes for four 186 // consecutive frames. The first value is the compressed frame size and the 187 // second value is the time in nanoseconds of one frame. 188 std::queue<std::pair<int64_t, int64_t>> cpb_window_; 189 int64_t max_cpb_window_size_; 190 int64_t max_cpb_window_end_ns_; 191 int64_t current_cpb_size_; 192 int64_t max_cpb_size_; 193 int64_t max_cpb_start_ns_; 194 int64_t max_cpb_end_ns_; 195 196 int64_t total_compressed_size_; 197 int64_t total_uncompressed_bits_; 198 int frames_refreshed_; 199 int max_frames_refreshed_; 200 201 int max_column_tiles_; 202 203 bool estimate_last_frame_duration_; 204 }; 205 206 } // namespace vp9_parser 207 208 #endif // LIBWEBM_COMMON_VP9_LEVEL_STATS_H_ 209