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