xref: /aosp_15_r20/external/libwebm/common/vp9_level_stats_tests.cc (revision 103e46e4cd4b6efcf6001f23fa8665fb110abf8d)
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 #include "common/vp9_level_stats.h"
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "gtest/gtest.h"
15 
16 #include "common/hdr_util.h"
17 #include "common/vp9_header_parser.h"
18 #include "mkvparser/mkvparser.h"
19 #include "mkvparser/mkvreader.h"
20 #include "testing/test_util.h"
21 
22 namespace {
23 
24 // TODO(fgalligan): Refactor this test with other test files in this directory.
25 class Vp9LevelStatsTests : public ::testing::Test {
26  public:
Vp9LevelStatsTests()27   Vp9LevelStatsTests() : is_reader_open_(false) {}
28 
~Vp9LevelStatsTests()29   ~Vp9LevelStatsTests() override { CloseReader(); }
30 
CloseReader()31   void CloseReader() {
32     if (is_reader_open_) {
33       reader_.Close();
34     }
35     is_reader_open_ = false;
36   }
37 
CreateAndLoadSegment(const std::string & filename,int expected_doc_type_ver)38   void CreateAndLoadSegment(const std::string& filename,
39                             int expected_doc_type_ver) {
40     ASSERT_NE(0u, filename.length());
41     filename_ = test::GetTestFilePath(filename);
42     ASSERT_EQ(0, reader_.Open(filename_.c_str()));
43     is_reader_open_ = true;
44     pos_ = 0;
45     mkvparser::EBMLHeader ebml_header;
46     ebml_header.Parse(&reader_, pos_);
47     ASSERT_EQ(1, ebml_header.m_version);
48     ASSERT_EQ(1, ebml_header.m_readVersion);
49     ASSERT_STREQ("webm", ebml_header.m_docType);
50     ASSERT_EQ(expected_doc_type_ver, ebml_header.m_docTypeVersion);
51     ASSERT_EQ(2, ebml_header.m_docTypeReadVersion);
52     mkvparser::Segment* temp;
53     ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, temp));
54     segment_.reset(temp);
55     ASSERT_FALSE(HasFailure());
56     ASSERT_GE(0, segment_->Load());
57   }
58 
CreateAndLoadSegment(const std::string & filename)59   void CreateAndLoadSegment(const std::string& filename) {
60     CreateAndLoadSegment(filename, 4);
61   }
62 
ProcessTheFrames()63   void ProcessTheFrames() {
64     std::vector<uint8_t> data;
65     size_t data_len = 0;
66     const mkvparser::Tracks* const parser_tracks = segment_->GetTracks();
67     ASSERT_TRUE(parser_tracks != NULL);
68     const mkvparser::Cluster* cluster = segment_->GetFirst();
69     ASSERT_TRUE(cluster);
70 
71     while ((cluster != NULL) && !cluster->EOS()) {
72       const mkvparser::BlockEntry* block_entry;
73       long status = cluster->GetFirst(block_entry);  // NOLINT
74       ASSERT_EQ(0, status);
75 
76       while ((block_entry != NULL) && !block_entry->EOS()) {
77         const mkvparser::Block* const block = block_entry->GetBlock();
78         ASSERT_TRUE(block != NULL);
79         const long long trackNum = block->GetTrackNumber();  // NOLINT
80         const mkvparser::Track* const parser_track =
81             parser_tracks->GetTrackByNumber(
82                 static_cast<unsigned long>(trackNum));  // NOLINT
83         ASSERT_TRUE(parser_track != NULL);
84         const long long track_type = parser_track->GetType();  // NOLINT
85 
86         if (track_type == mkvparser::Track::kVideo) {
87           const int frame_count = block->GetFrameCount();
88           const long long time_ns = block->GetTime(cluster);  // NOLINT
89 
90           for (int i = 0; i < frame_count; ++i) {
91             const mkvparser::Block::Frame& frame = block->GetFrame(i);
92             if (static_cast<size_t>(frame.len) > data.size()) {
93               data.resize(frame.len);
94               data_len = static_cast<size_t>(frame.len);
95             }
96             ASSERT_FALSE(frame.Read(&reader_, &data[0]));
97             parser_.ParseUncompressedHeader(&data[0], data_len);
98             stats_.AddFrame(parser_, time_ns);
99           }
100         }
101 
102         status = cluster->GetNext(block_entry, block_entry);
103         ASSERT_EQ(0, status);
104       }
105 
106       cluster = segment_->GetNext(cluster);
107     }
108   }
109 
110  protected:
111   mkvparser::MkvReader reader_;
112   bool is_reader_open_;
113   std::unique_ptr<mkvparser::Segment> segment_;
114   std::string filename_;
115   long long pos_;  // NOLINT
116   vp9_parser::Vp9HeaderParser parser_;
117   vp9_parser::Vp9LevelStats stats_;
118 };
119 
TEST_F(Vp9LevelStatsTests,VideoOnlyFile)120 TEST_F(Vp9LevelStatsTests, VideoOnlyFile) {
121   ASSERT_NO_FATAL_FAILURE(CreateAndLoadSegment("test_stereo_left_right.webm"));
122   ProcessTheFrames();
123   EXPECT_EQ(256, parser_.width());
124   EXPECT_EQ(144, parser_.height());
125   EXPECT_EQ(1, parser_.column_tiles());
126   EXPECT_EQ(0, parser_.frame_parallel_mode());
127 
128   EXPECT_EQ(11, stats_.GetLevel());
129   EXPECT_EQ(479232, stats_.GetMaxLumaSampleRate());
130   EXPECT_EQ(36864, stats_.GetMaxLumaPictureSize());
131   EXPECT_DOUBLE_EQ(264.03233333333333, stats_.GetAverageBitRate());
132   EXPECT_DOUBLE_EQ(147.136, stats_.GetMaxCpbSize());
133   EXPECT_DOUBLE_EQ(19.267458404715583, stats_.GetCompressionRatio());
134   EXPECT_EQ(1, stats_.GetMaxColumnTiles());
135   EXPECT_EQ(11, stats_.GetMinimumAltrefDistance());
136   EXPECT_EQ(3, stats_.GetMaxReferenceFrames());
137 
138   EXPECT_TRUE(stats_.estimate_last_frame_duration());
139   stats_.set_estimate_last_frame_duration(false);
140   EXPECT_DOUBLE_EQ(275.512, stats_.GetAverageBitRate());
141 }
142 
TEST_F(Vp9LevelStatsTests,Muxed)143 TEST_F(Vp9LevelStatsTests, Muxed) {
144   ASSERT_NO_FATAL_FAILURE(
145       CreateAndLoadSegment("bbb_480p_vp9_opus_1second.webm", 4));
146   ProcessTheFrames();
147   EXPECT_EQ(854, parser_.width());
148   EXPECT_EQ(480, parser_.height());
149   EXPECT_EQ(2, parser_.column_tiles());
150   EXPECT_EQ(1, parser_.frame_parallel_mode());
151 
152   EXPECT_EQ(30, stats_.GetLevel());
153   EXPECT_EQ(9838080, stats_.GetMaxLumaSampleRate());
154   EXPECT_EQ(409920, stats_.GetMaxLumaPictureSize());
155   EXPECT_DOUBLE_EQ(447.09394572025053, stats_.GetAverageBitRate());
156   EXPECT_DOUBLE_EQ(118.464, stats_.GetMaxCpbSize());
157   EXPECT_DOUBLE_EQ(241.17670131398313, stats_.GetCompressionRatio());
158   EXPECT_EQ(2, stats_.GetMaxColumnTiles());
159   EXPECT_EQ(9, stats_.GetMinimumAltrefDistance());
160   EXPECT_EQ(3, stats_.GetMaxReferenceFrames());
161 
162   stats_.set_estimate_last_frame_duration(false);
163   EXPECT_DOUBLE_EQ(468.38413361169108, stats_.GetAverageBitRate());
164 }
165 
TEST_F(Vp9LevelStatsTests,SetDuration)166 TEST_F(Vp9LevelStatsTests, SetDuration) {
167   ASSERT_NO_FATAL_FAILURE(CreateAndLoadSegment("test_stereo_left_right.webm"));
168   ProcessTheFrames();
169   const int64_t kDurationNano = 2080000000;  // 2.08 seconds
170   stats_.set_duration(kDurationNano);
171   EXPECT_EQ(256, parser_.width());
172   EXPECT_EQ(144, parser_.height());
173   EXPECT_EQ(1, parser_.column_tiles());
174   EXPECT_EQ(0, parser_.frame_parallel_mode());
175 
176   EXPECT_EQ(11, stats_.GetLevel());
177   EXPECT_EQ(479232, stats_.GetMaxLumaSampleRate());
178   EXPECT_EQ(36864, stats_.GetMaxLumaPictureSize());
179   EXPECT_DOUBLE_EQ(264.9153846153846, stats_.GetAverageBitRate());
180   EXPECT_DOUBLE_EQ(147.136, stats_.GetMaxCpbSize());
181   EXPECT_DOUBLE_EQ(19.267458404715583, stats_.GetCompressionRatio());
182   EXPECT_EQ(1, stats_.GetMaxColumnTiles());
183   EXPECT_EQ(11, stats_.GetMinimumAltrefDistance());
184   EXPECT_EQ(3, stats_.GetMaxReferenceFrames());
185 }
186 
187 }  // namespace
188 
main(int argc,char * argv[])189 int main(int argc, char* argv[]) {
190   ::testing::InitGoogleTest(&argc, argv);
191   return RUN_ALL_TESTS();
192 }
193