// Copyright (c) 2016 The WebM project authors. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. #ifndef LIBWEBM_COMMON_VP9_LEVEL_STATS_H_ #define LIBWEBM_COMMON_VP9_LEVEL_STATS_H_ #include #include #include #include "common/vp9_header_parser.h" namespace vp9_parser { const int kMaxVp9RefFrames = 8; // Defined VP9 levels. See http://www.webmproject.org/vp9/profiles/ for // detailed information on VP9 levels. const int kNumVp9Levels = 14; enum Vp9Level { LEVEL_UNKNOWN = 0, LEVEL_1 = 10, LEVEL_1_1 = 11, LEVEL_2 = 20, LEVEL_2_1 = 21, LEVEL_3 = 30, LEVEL_3_1 = 31, LEVEL_4 = 40, LEVEL_4_1 = 41, LEVEL_5 = 50, LEVEL_5_1 = 51, LEVEL_5_2 = 52, LEVEL_6 = 60, LEVEL_6_1 = 61, LEVEL_6_2 = 62 }; struct Vp9LevelRow { Vp9LevelRow() = default; ~Vp9LevelRow() = default; Vp9LevelRow(Vp9LevelRow&& other) = default; Vp9LevelRow(const Vp9LevelRow& other) = default; Vp9LevelRow& operator=(Vp9LevelRow&& other) = delete; Vp9LevelRow& operator=(const Vp9LevelRow& other) = delete; Vp9Level level; int64_t max_luma_sample_rate; int64_t max_luma_picture_size; double average_bitrate; double max_cpb_size; double compresion_ratio; int max_tiles; int min_altref_distance; int max_ref_frames; }; // Class to determine the VP9 level of a VP9 bitstream. class Vp9LevelStats { public: static const Vp9LevelRow Vp9LevelTable[kNumVp9Levels]; Vp9LevelStats() : frames(0), displayed_frames(0), start_ns_(-1), end_ns_(-1), duration_ns_(-1), max_luma_picture_size_(0), current_luma_size_(0), max_luma_size_(0), max_luma_end_ns_(0), max_luma_sample_rate_grace_percent_(1.5), first_altref(true), frames_since_last_altref(0), minimum_altref_distance(std::numeric_limits::max()), min_altref_end_ns(0), max_cpb_window_size_(0), max_cpb_window_end_ns_(0), current_cpb_size_(0), max_cpb_size_(0), max_cpb_start_ns_(0), max_cpb_end_ns_(0), total_compressed_size_(0), total_uncompressed_bits_(0), frames_refreshed_(0), max_frames_refreshed_(0), max_column_tiles_(0), estimate_last_frame_duration_(true) {} ~Vp9LevelStats() = default; Vp9LevelStats(Vp9LevelStats&& other) = delete; Vp9LevelStats(const Vp9LevelStats& other) = delete; Vp9LevelStats& operator=(Vp9LevelStats&& other) = delete; Vp9LevelStats& operator=(const Vp9LevelStats& other) = delete; // Collects stats on a VP9 frame. The frame must already be parsed by // |parser|. |time_ns| is the start time of the frame in nanoseconds. void AddFrame(const Vp9HeaderParser& parser, int64_t time_ns); // Returns the current VP9 level. All of the video frames should have been // processed with AddFrame before calling this function. Vp9Level GetLevel() const; // Returns the maximum luma samples (pixels) per second. The Alt-Ref frames // are taken into account, therefore this number may be larger than the // display luma samples per second int64_t GetMaxLumaSampleRate() const; // The maximum frame size (width * height) in samples. int64_t GetMaxLumaPictureSize() const; // The average bitrate of the video in kbps. double GetAverageBitRate() const; // The largest data size for any 4 consecutive frames in kilobits. double GetMaxCpbSize() const; // The ratio of total bytes decompressed over total bytes compressed. double GetCompressionRatio() const; // The maximum number of VP9 column tiles. int GetMaxColumnTiles() const; // The minimum distance in frames between two consecutive alternate reference // frames. int GetMinimumAltrefDistance() const; // The maximum number of reference frames that had to be stored. int GetMaxReferenceFrames() const; // Sets the duration of the video stream in nanoseconds. If the duration is // not explictly set by this function then this class will use end - start // as the duration. void set_duration(int64_t time_ns) { duration_ns_ = time_ns; } double max_luma_sample_rate_grace_percent() const { return max_luma_sample_rate_grace_percent_; } void set_max_luma_sample_rate_grace_percent(double percent) { max_luma_sample_rate_grace_percent_ = percent; } bool estimate_last_frame_duration() const { return estimate_last_frame_duration_; } // If true try to estimate the last frame's duration if the stream's duration // is not set or the stream's duration equals the last frame's timestamp. void set_estimate_last_frame_duration(bool flag) { estimate_last_frame_duration_ = flag; } private: int frames; int displayed_frames; int64_t start_ns_; int64_t end_ns_; int64_t duration_ns_; int64_t max_luma_picture_size_; // This is used to calculate the maximum number of luma samples per second. // The first value is the luma picture size and the second value is the time // in nanoseconds of one frame. std::queue> luma_window_; int64_t current_luma_size_; int64_t max_luma_size_; int64_t max_luma_end_ns_; // MaxLumaSampleRate = (ExampleFrameRate + ExampleFrameRate / // MinimumAltrefDistance) * MaxLumaPictureSize. For levels 1-4 // ExampleFrameRate / MinimumAltrefDistance is non-integer, so using a sliding // window of one frame to calculate MaxLumaSampleRate may have frames > // (ExampleFrameRate + ExampleFrameRate / MinimumAltrefDistance) in the // window. In order to address this issue, a grace percent of 1.5 was added. double max_luma_sample_rate_grace_percent_; bool first_altref; int frames_since_last_altref; int minimum_altref_distance; int64_t min_altref_end_ns; // This is used to calculate the maximum number of compressed bytes for four // consecutive frames. The first value is the compressed frame size and the // second value is the time in nanoseconds of one frame. std::queue> cpb_window_; int64_t max_cpb_window_size_; int64_t max_cpb_window_end_ns_; int64_t current_cpb_size_; int64_t max_cpb_size_; int64_t max_cpb_start_ns_; int64_t max_cpb_end_ns_; int64_t total_compressed_size_; int64_t total_uncompressed_bits_; int frames_refreshed_; int max_frames_refreshed_; int max_column_tiles_; bool estimate_last_frame_duration_; }; } // namespace vp9_parser #endif // LIBWEBM_COMMON_VP9_LEVEL_STATS_H_