faf89d4ed1
BUG=https://bugs.chromium.org/p/webm/issues/detail?id=1206 Change-Id: I29a956871bd5aa0c7b493601ed23b44a08414d32
210 lines
6.6 KiB
C++
210 lines
6.6 KiB
C++
// 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 <limits>
|
|
#include <queue>
|
|
#include <utility>
|
|
|
|
#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<int>::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<std::pair<int64_t, int64_t>> 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<std::pair<int64_t, int64_t>> 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_
|