xref: /aosp_15_r20/external/libwebm/common/vp9_header_parser_tests.cc (revision 103e46e4cd4b6efcf6001f23fa8665fb110abf8d)
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 #include "common/vp9_header_parser.h"
9*103e46e4SHarish Mahendrakar 
10*103e46e4SHarish Mahendrakar #include <string>
11*103e46e4SHarish Mahendrakar 
12*103e46e4SHarish Mahendrakar #include "gtest/gtest.h"
13*103e46e4SHarish Mahendrakar 
14*103e46e4SHarish Mahendrakar #include "common/hdr_util.h"
15*103e46e4SHarish Mahendrakar #include "mkvparser/mkvparser.h"
16*103e46e4SHarish Mahendrakar #include "mkvparser/mkvreader.h"
17*103e46e4SHarish Mahendrakar #include "testing/test_util.h"
18*103e46e4SHarish Mahendrakar 
19*103e46e4SHarish Mahendrakar namespace {
20*103e46e4SHarish Mahendrakar 
21*103e46e4SHarish Mahendrakar class Vp9HeaderParserTests : public ::testing::Test {
22*103e46e4SHarish Mahendrakar  public:
Vp9HeaderParserTests()23*103e46e4SHarish Mahendrakar   Vp9HeaderParserTests() : is_reader_open_(false), segment_(NULL) {}
24*103e46e4SHarish Mahendrakar 
~Vp9HeaderParserTests()25*103e46e4SHarish Mahendrakar   ~Vp9HeaderParserTests() override {
26*103e46e4SHarish Mahendrakar     CloseReader();
27*103e46e4SHarish Mahendrakar     if (segment_ != NULL) {
28*103e46e4SHarish Mahendrakar       delete segment_;
29*103e46e4SHarish Mahendrakar       segment_ = NULL;
30*103e46e4SHarish Mahendrakar     }
31*103e46e4SHarish Mahendrakar   }
32*103e46e4SHarish Mahendrakar 
CloseReader()33*103e46e4SHarish Mahendrakar   void CloseReader() {
34*103e46e4SHarish Mahendrakar     if (is_reader_open_) {
35*103e46e4SHarish Mahendrakar       reader_.Close();
36*103e46e4SHarish Mahendrakar     }
37*103e46e4SHarish Mahendrakar     is_reader_open_ = false;
38*103e46e4SHarish Mahendrakar   }
39*103e46e4SHarish Mahendrakar 
CreateAndLoadSegment(const std::string & filename,int expected_doc_type_ver)40*103e46e4SHarish Mahendrakar   void CreateAndLoadSegment(const std::string& filename,
41*103e46e4SHarish Mahendrakar                             int expected_doc_type_ver) {
42*103e46e4SHarish Mahendrakar     filename_ = test::GetTestFilePath(filename);
43*103e46e4SHarish Mahendrakar     ASSERT_EQ(0, reader_.Open(filename_.c_str()));
44*103e46e4SHarish Mahendrakar     is_reader_open_ = true;
45*103e46e4SHarish Mahendrakar     pos_ = 0;
46*103e46e4SHarish Mahendrakar     mkvparser::EBMLHeader ebml_header;
47*103e46e4SHarish Mahendrakar     ebml_header.Parse(&reader_, pos_);
48*103e46e4SHarish Mahendrakar     ASSERT_EQ(1, ebml_header.m_version);
49*103e46e4SHarish Mahendrakar     ASSERT_EQ(1, ebml_header.m_readVersion);
50*103e46e4SHarish Mahendrakar     ASSERT_STREQ("webm", ebml_header.m_docType);
51*103e46e4SHarish Mahendrakar     ASSERT_EQ(expected_doc_type_ver, ebml_header.m_docTypeVersion);
52*103e46e4SHarish Mahendrakar     ASSERT_EQ(2, ebml_header.m_docTypeReadVersion);
53*103e46e4SHarish Mahendrakar     ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, segment_));
54*103e46e4SHarish Mahendrakar     ASSERT_FALSE(HasFailure());
55*103e46e4SHarish Mahendrakar     ASSERT_GE(0, segment_->Load());
56*103e46e4SHarish Mahendrakar   }
57*103e46e4SHarish Mahendrakar 
CreateAndLoadSegment(const std::string & filename)58*103e46e4SHarish Mahendrakar   void CreateAndLoadSegment(const std::string& filename) {
59*103e46e4SHarish Mahendrakar     CreateAndLoadSegment(filename, 4);
60*103e46e4SHarish Mahendrakar   }
61*103e46e4SHarish Mahendrakar 
62*103e46e4SHarish Mahendrakar   // Load a corrupted segment with no expectation of correctness.
CreateAndLoadInvalidSegment(const std::string & filename)63*103e46e4SHarish Mahendrakar   void CreateAndLoadInvalidSegment(const std::string& filename) {
64*103e46e4SHarish Mahendrakar     filename_ = test::GetTestFilePath(filename);
65*103e46e4SHarish Mahendrakar     ASSERT_EQ(0, reader_.Open(filename_.c_str()));
66*103e46e4SHarish Mahendrakar     is_reader_open_ = true;
67*103e46e4SHarish Mahendrakar     pos_ = 0;
68*103e46e4SHarish Mahendrakar     mkvparser::EBMLHeader ebml_header;
69*103e46e4SHarish Mahendrakar     ebml_header.Parse(&reader_, pos_);
70*103e46e4SHarish Mahendrakar     ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, segment_));
71*103e46e4SHarish Mahendrakar     ASSERT_GE(0, segment_->Load());
72*103e46e4SHarish Mahendrakar   }
73*103e46e4SHarish Mahendrakar 
ProcessTheFrames(bool invalid_bitstream)74*103e46e4SHarish Mahendrakar   void ProcessTheFrames(bool invalid_bitstream) {
75*103e46e4SHarish Mahendrakar     unsigned char* data = NULL;
76*103e46e4SHarish Mahendrakar     size_t data_len = 0;
77*103e46e4SHarish Mahendrakar     const mkvparser::Tracks* const parser_tracks = segment_->GetTracks();
78*103e46e4SHarish Mahendrakar     ASSERT_TRUE(parser_tracks != NULL);
79*103e46e4SHarish Mahendrakar     const mkvparser::Cluster* cluster = segment_->GetFirst();
80*103e46e4SHarish Mahendrakar     ASSERT_TRUE(cluster != NULL);
81*103e46e4SHarish Mahendrakar 
82*103e46e4SHarish Mahendrakar     while ((cluster != NULL) && !cluster->EOS()) {
83*103e46e4SHarish Mahendrakar       const mkvparser::BlockEntry* block_entry;
84*103e46e4SHarish Mahendrakar       long status = cluster->GetFirst(block_entry);  // NOLINT
85*103e46e4SHarish Mahendrakar       ASSERT_EQ(0, status);
86*103e46e4SHarish Mahendrakar 
87*103e46e4SHarish Mahendrakar       while ((block_entry != NULL) && !block_entry->EOS()) {
88*103e46e4SHarish Mahendrakar         const mkvparser::Block* const block = block_entry->GetBlock();
89*103e46e4SHarish Mahendrakar         ASSERT_TRUE(block != NULL);
90*103e46e4SHarish Mahendrakar         const long long trackNum = block->GetTrackNumber();  // NOLINT
91*103e46e4SHarish Mahendrakar         const mkvparser::Track* const parser_track =
92*103e46e4SHarish Mahendrakar             parser_tracks->GetTrackByNumber(
93*103e46e4SHarish Mahendrakar                 static_cast<unsigned long>(trackNum));  // NOLINT
94*103e46e4SHarish Mahendrakar         ASSERT_TRUE(parser_track != NULL);
95*103e46e4SHarish Mahendrakar         const long long track_type = parser_track->GetType();  // NOLINT
96*103e46e4SHarish Mahendrakar 
97*103e46e4SHarish Mahendrakar         if (track_type == mkvparser::Track::kVideo) {
98*103e46e4SHarish Mahendrakar           const int frame_count = block->GetFrameCount();
99*103e46e4SHarish Mahendrakar 
100*103e46e4SHarish Mahendrakar           for (int i = 0; i < frame_count; ++i) {
101*103e46e4SHarish Mahendrakar             const mkvparser::Block::Frame& frame = block->GetFrame(i);
102*103e46e4SHarish Mahendrakar 
103*103e46e4SHarish Mahendrakar             if (static_cast<size_t>(frame.len) > data_len) {
104*103e46e4SHarish Mahendrakar               delete[] data;
105*103e46e4SHarish Mahendrakar               data = new unsigned char[frame.len];
106*103e46e4SHarish Mahendrakar               ASSERT_TRUE(data != NULL);
107*103e46e4SHarish Mahendrakar               data_len = static_cast<size_t>(frame.len);
108*103e46e4SHarish Mahendrakar             }
109*103e46e4SHarish Mahendrakar             ASSERT_FALSE(frame.Read(&reader_, data));
110*103e46e4SHarish Mahendrakar             ASSERT_EQ(parser_.ParseUncompressedHeader(data, data_len),
111*103e46e4SHarish Mahendrakar                       !invalid_bitstream);
112*103e46e4SHarish Mahendrakar           }
113*103e46e4SHarish Mahendrakar         }
114*103e46e4SHarish Mahendrakar 
115*103e46e4SHarish Mahendrakar         status = cluster->GetNext(block_entry, block_entry);
116*103e46e4SHarish Mahendrakar         ASSERT_EQ(0, status);
117*103e46e4SHarish Mahendrakar       }
118*103e46e4SHarish Mahendrakar 
119*103e46e4SHarish Mahendrakar       cluster = segment_->GetNext(cluster);
120*103e46e4SHarish Mahendrakar     }
121*103e46e4SHarish Mahendrakar     delete[] data;
122*103e46e4SHarish Mahendrakar   }
123*103e46e4SHarish Mahendrakar 
124*103e46e4SHarish Mahendrakar  protected:
125*103e46e4SHarish Mahendrakar   mkvparser::MkvReader reader_;
126*103e46e4SHarish Mahendrakar   bool is_reader_open_;
127*103e46e4SHarish Mahendrakar   mkvparser::Segment* segment_;
128*103e46e4SHarish Mahendrakar   std::string filename_;
129*103e46e4SHarish Mahendrakar   long long pos_;  // NOLINT
130*103e46e4SHarish Mahendrakar   vp9_parser::Vp9HeaderParser parser_;
131*103e46e4SHarish Mahendrakar };
132*103e46e4SHarish Mahendrakar 
TEST_F(Vp9HeaderParserTests,VideoOnlyFile)133*103e46e4SHarish Mahendrakar TEST_F(Vp9HeaderParserTests, VideoOnlyFile) {
134*103e46e4SHarish Mahendrakar   ASSERT_NO_FATAL_FAILURE(CreateAndLoadSegment("test_stereo_left_right.webm"));
135*103e46e4SHarish Mahendrakar   ProcessTheFrames(false);
136*103e46e4SHarish Mahendrakar   EXPECT_EQ(256, parser_.width());
137*103e46e4SHarish Mahendrakar   EXPECT_EQ(144, parser_.height());
138*103e46e4SHarish Mahendrakar   EXPECT_EQ(1, parser_.column_tiles());
139*103e46e4SHarish Mahendrakar   EXPECT_EQ(0, parser_.frame_parallel_mode());
140*103e46e4SHarish Mahendrakar }
141*103e46e4SHarish Mahendrakar 
TEST_F(Vp9HeaderParserTests,Muxed)142*103e46e4SHarish Mahendrakar TEST_F(Vp9HeaderParserTests, Muxed) {
143*103e46e4SHarish Mahendrakar   ASSERT_NO_FATAL_FAILURE(
144*103e46e4SHarish Mahendrakar       CreateAndLoadSegment("bbb_480p_vp9_opus_1second.webm", 4));
145*103e46e4SHarish Mahendrakar   ProcessTheFrames(false);
146*103e46e4SHarish Mahendrakar   EXPECT_EQ(854, parser_.width());
147*103e46e4SHarish Mahendrakar   EXPECT_EQ(480, parser_.height());
148*103e46e4SHarish Mahendrakar   EXPECT_EQ(2, parser_.column_tiles());
149*103e46e4SHarish Mahendrakar   EXPECT_EQ(1, parser_.frame_parallel_mode());
150*103e46e4SHarish Mahendrakar }
151*103e46e4SHarish Mahendrakar 
TEST_F(Vp9HeaderParserTests,Invalid)152*103e46e4SHarish Mahendrakar TEST_F(Vp9HeaderParserTests, Invalid) {
153*103e46e4SHarish Mahendrakar   const char* files[] = {
154*103e46e4SHarish Mahendrakar       "invalid/invalid_vp9_bitstream-bug_1416.webm",
155*103e46e4SHarish Mahendrakar       "invalid/invalid_vp9_bitstream-bug_1417.webm",
156*103e46e4SHarish Mahendrakar   };
157*103e46e4SHarish Mahendrakar 
158*103e46e4SHarish Mahendrakar   for (int i = 0; i < static_cast<int>(sizeof(files) / sizeof(files[0])); ++i) {
159*103e46e4SHarish Mahendrakar     SCOPED_TRACE(files[i]);
160*103e46e4SHarish Mahendrakar     ASSERT_NO_FATAL_FAILURE(CreateAndLoadInvalidSegment(files[i]));
161*103e46e4SHarish Mahendrakar     ProcessTheFrames(true);
162*103e46e4SHarish Mahendrakar     CloseReader();
163*103e46e4SHarish Mahendrakar     delete segment_;
164*103e46e4SHarish Mahendrakar     segment_ = NULL;
165*103e46e4SHarish Mahendrakar   }
166*103e46e4SHarish Mahendrakar }
167*103e46e4SHarish Mahendrakar 
TEST_F(Vp9HeaderParserTests,API)168*103e46e4SHarish Mahendrakar TEST_F(Vp9HeaderParserTests, API) {
169*103e46e4SHarish Mahendrakar   vp9_parser::Vp9HeaderParser parser;
170*103e46e4SHarish Mahendrakar   uint8_t data;
171*103e46e4SHarish Mahendrakar   EXPECT_FALSE(parser.ParseUncompressedHeader(NULL, 0));
172*103e46e4SHarish Mahendrakar   EXPECT_FALSE(parser.ParseUncompressedHeader(NULL, 10));
173*103e46e4SHarish Mahendrakar   EXPECT_FALSE(parser.ParseUncompressedHeader(&data, 0));
174*103e46e4SHarish Mahendrakar }
175*103e46e4SHarish Mahendrakar 
176*103e46e4SHarish Mahendrakar }  // namespace
177*103e46e4SHarish Mahendrakar 
main(int argc,char * argv[])178*103e46e4SHarish Mahendrakar int main(int argc, char* argv[]) {
179*103e46e4SHarish Mahendrakar   ::testing::InitGoogleTest(&argc, argv);
180*103e46e4SHarish Mahendrakar   return RUN_ALL_TESTS();
181*103e46e4SHarish Mahendrakar }
182