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