xref: /aosp_15_r20/external/libwebm/testing/mkvmuxer_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 <stdint.h>
9 
10 #include <array>
11 #include <cstdio>
12 #include <cstring>
13 #include <iomanip>
14 #include <memory>
15 #include <ostream>
16 #include <string>
17 
18 #include "gtest/gtest.h"
19 
20 #include "common/file_util.h"
21 #include "common/libwebm_util.h"
22 #include "mkvmuxer/mkvmuxer.h"
23 #include "mkvmuxer/mkvwriter.h"
24 #include "mkvparser/mkvreader.h"
25 #include "testing/test_util.h"
26 
27 using mkvmuxer::AudioTrack;
28 using mkvmuxer::Chapter;
29 using mkvmuxer::Frame;
30 using mkvmuxer::MkvWriter;
31 using mkvmuxer::Segment;
32 using mkvmuxer::SegmentInfo;
33 using mkvmuxer::Tag;
34 using mkvmuxer::Track;
35 using mkvmuxer::VideoTrack;
36 
37 namespace test {
38 
39 // Base class containing boiler plate stuff.
40 class MuxerTest : public testing::Test {
41  public:
MuxerTest()42   MuxerTest() { Init(); }
43 
~MuxerTest()44   ~MuxerTest() { CloseWriter(); }
45 
46   // Simple init function for use by constructor. Calls made here to allow use
47   // of ASSERT_* macros-- this is necessary here because all failures in Init()
48   // are fatal, but the ASSERT_* gtest macros cannot be used in a constructor.
Init()49   void Init() {
50     ASSERT_TRUE(GetTestDataDir().length() > 0);
51     filename_ = libwebm::GetTempFileName();
52     ASSERT_GT(filename_.length(), 0u);
53     temp_file_ = libwebm::FilePtr(std::fopen(filename_.c_str(), "wb"),
54                                   libwebm::FILEDeleter());
55     ASSERT_TRUE(temp_file_.get() != nullptr);
56     writer_.reset(new MkvWriter(temp_file_.get()));
57     is_writer_open_ = true;
58     memset(dummy_data_, 0, kFrameLength);
59   }
60 
AddDummyFrameAndFinalize(int track_number)61   void AddDummyFrameAndFinalize(int track_number) {
62     EXPECT_TRUE(segment_.AddFrame(&dummy_data_[0], kFrameLength, track_number,
63                                   0, false));
64     EXPECT_TRUE(segment_.Finalize());
65   }
66 
AddVideoTrack()67   void AddVideoTrack() {
68     const int vid_track = static_cast<int>(
69         segment_.AddVideoTrack(kWidth, kHeight, kVideoTrackNumber));
70     ASSERT_EQ(kVideoTrackNumber, vid_track);
71     VideoTrack* const video =
72         dynamic_cast<VideoTrack*>(segment_.GetTrackByNumber(vid_track));
73     ASSERT_TRUE(video != NULL);
74     video->set_uid(kVideoTrackNumber);
75   }
76 
AddAudioTrack()77   void AddAudioTrack() {
78     const int aud_track = static_cast<int>(
79         segment_.AddAudioTrack(kSampleRate, kChannels, kAudioTrackNumber));
80     ASSERT_EQ(kAudioTrackNumber, aud_track);
81     AudioTrack* const audio =
82         dynamic_cast<AudioTrack*>(segment_.GetTrackByNumber(aud_track));
83     ASSERT_TRUE(audio != NULL);
84     audio->set_uid(kAudioTrackNumber);
85     audio->set_codec_id(kOpusCodecId);
86   }
87 
CloseWriter()88   void CloseWriter() {
89     if (is_writer_open_)
90       writer_->Close();
91     is_writer_open_ = false;
92   }
93 
SegmentInit(bool output_cues,bool accurate_cluster_duration,bool fixed_size_cluster_timecode)94   bool SegmentInit(bool output_cues, bool accurate_cluster_duration,
95                    bool fixed_size_cluster_timecode) {
96     if (!segment_.Init(writer_.get()))
97       return false;
98     SegmentInfo* const info = segment_.GetSegmentInfo();
99     info->set_writing_app(kAppString);
100     info->set_muxing_app(kAppString);
101     segment_.OutputCues(output_cues);
102     segment_.AccurateClusterDuration(accurate_cluster_duration);
103     segment_.UseFixedSizeClusterTimecode(fixed_size_cluster_timecode);
104     return true;
105   }
106 
107  protected:
TearDown()108   virtual void TearDown() {
109     remove(filename_.c_str());
110     testing::Test::TearDown();
111   }
112 
113   std::unique_ptr<MkvWriter> writer_;
114   bool is_writer_open_ = false;
115   Segment segment_;
116   std::string filename_;
117   libwebm::FilePtr temp_file_;
118   std::uint8_t dummy_data_[kFrameLength];
119 };
120 
TEST_F(MuxerTest,SegmentInfo)121 TEST_F(MuxerTest, SegmentInfo) {
122   EXPECT_TRUE(SegmentInit(false, false, false));
123   SegmentInfo* const info = segment_.GetSegmentInfo();
124   info->set_timecode_scale(kTimeCodeScale);
125   info->set_duration(2.345);
126   EXPECT_STREQ(kAppString, info->muxing_app());
127   EXPECT_STREQ(kAppString, info->writing_app());
128   EXPECT_EQ(static_cast<uint64_t>(kTimeCodeScale), info->timecode_scale());
129   EXPECT_DOUBLE_EQ(2.345, info->duration());
130   AddVideoTrack();
131 
132   AddDummyFrameAndFinalize(kVideoTrackNumber);
133   CloseWriter();
134 
135   EXPECT_TRUE(CompareFiles(GetTestFilePath("segment_info.webm"), filename_));
136 }
137 
TEST_F(MuxerTest,AddTracks)138 TEST_F(MuxerTest, AddTracks) {
139   EXPECT_TRUE(SegmentInit(false, false, false));
140 
141   // Add a Video Track
142   AddVideoTrack();
143   VideoTrack* const video =
144       dynamic_cast<VideoTrack*>(segment_.GetTrackByNumber(kVideoTrackNumber));
145   ASSERT_TRUE(video != NULL);
146   EXPECT_EQ(static_cast<uint64_t>(kWidth), video->width());
147   EXPECT_EQ(static_cast<uint64_t>(kHeight), video->height());
148   video->set_name(kTrackName);
149   video->set_display_width(kWidth - 10);
150   video->set_display_height(kHeight - 10);
151   video->set_frame_rate(0.5);
152   EXPECT_STREQ(kTrackName, video->name());
153   const uint64_t kDisplayWidth = kWidth - 10;
154   EXPECT_EQ(kDisplayWidth, video->display_width());
155   const uint64_t kDisplayHeight = kHeight - 10;
156   EXPECT_EQ(kDisplayHeight, video->display_height());
157   EXPECT_DOUBLE_EQ(0.5, video->frame_rate());
158   EXPECT_EQ(static_cast<uint64_t>(kVideoTrackNumber), video->uid());
159 
160   // Add an Audio Track
161   const int aud_track = static_cast<int>(
162       segment_.AddAudioTrack(kSampleRate, kChannels, kAudioTrackNumber));
163   EXPECT_EQ(kAudioTrackNumber, aud_track);
164   AudioTrack* const audio =
165       dynamic_cast<AudioTrack*>(segment_.GetTrackByNumber(aud_track));
166   EXPECT_EQ(kSampleRate, audio->sample_rate());
167   EXPECT_EQ(static_cast<uint64_t>(kChannels), audio->channels());
168   ASSERT_TRUE(audio != NULL);
169   audio->set_name(kTrackName);
170   audio->set_bit_depth(kBitDepth);
171   audio->set_uid(kAudioTrackNumber);
172   EXPECT_STREQ(kTrackName, audio->name());
173   EXPECT_EQ(static_cast<uint64_t>(kBitDepth), audio->bit_depth());
174   EXPECT_EQ(static_cast<uint64_t>(kAudioTrackNumber), audio->uid());
175 
176   AddDummyFrameAndFinalize(kVideoTrackNumber);
177   CloseWriter();
178 
179   EXPECT_TRUE(CompareFiles(GetTestFilePath("tracks.webm"), filename_));
180 }
181 
TEST_F(MuxerTest,AddChapters)182 TEST_F(MuxerTest, AddChapters) {
183   EXPECT_TRUE(SegmentInit(false, false, false));
184   AddVideoTrack();
185 
186   // Add a Chapter
187   Chapter* chapter = segment_.AddChapter();
188   EXPECT_TRUE(chapter->set_id("unit_test"));
189   chapter->set_time(segment_, 0, 1000000000);
190   EXPECT_TRUE(chapter->add_string("unit_test", "english", "us"));
191   chapter->set_uid(1);
192 
193   AddDummyFrameAndFinalize(kVideoTrackNumber);
194   CloseWriter();
195 
196   EXPECT_TRUE(CompareFiles(GetTestFilePath("chapters.webm"), filename_));
197 }
198 
TEST_F(MuxerTest,SimpleBlock)199 TEST_F(MuxerTest, SimpleBlock) {
200   EXPECT_TRUE(SegmentInit(false, false, false));
201   AddVideoTrack();
202 
203   // Valid Frame
204   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
205                                 false));
206 
207   // Valid Frame
208   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
209                                 2000000, false));
210 
211   // Invalid Frame - Non monotonically increasing timestamp
212   EXPECT_FALSE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
213                                  1, false));
214 
215   // Invalid Frame - Null pointer
216   EXPECT_FALSE(segment_.AddFrame(NULL, 0, kVideoTrackNumber, 8000000, false));
217 
218   // Invalid Frame - Invalid track number
219   EXPECT_FALSE(segment_.AddFrame(NULL, 0, kInvalidTrackNumber, 8000000, false));
220 
221   segment_.Finalize();
222   CloseWriter();
223 
224   EXPECT_TRUE(CompareFiles(GetTestFilePath("simple_block.webm"), filename_));
225 }
226 
TEST_F(MuxerTest,SimpleBlockWithAddGenericFrame)227 TEST_F(MuxerTest, SimpleBlockWithAddGenericFrame) {
228   EXPECT_TRUE(SegmentInit(false, false, false));
229   AddVideoTrack();
230 
231   Frame frame;
232   frame.Init(dummy_data_, kFrameLength);
233   frame.set_track_number(kVideoTrackNumber);
234   frame.set_is_key(false);
235 
236   // Valid Frame
237   frame.set_timestamp(0);
238   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
239 
240   // Valid Frame
241   frame.set_timestamp(2000000);
242   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
243 
244   // Invalid Frame - Non monotonically increasing timestamp
245   frame.set_timestamp(1);
246   EXPECT_FALSE(segment_.AddGenericFrame(&frame));
247 
248   // Invalid Frame - Invalid track number
249   frame.set_track_number(kInvalidTrackNumber);
250   frame.set_timestamp(8000000);
251   EXPECT_FALSE(segment_.AddGenericFrame(&frame));
252 
253   segment_.Finalize();
254   CloseWriter();
255 
256   EXPECT_TRUE(CompareFiles(GetTestFilePath("simple_block.webm"), filename_));
257 }
258 
TEST_F(MuxerTest,MetadataBlock)259 TEST_F(MuxerTest, MetadataBlock) {
260   EXPECT_TRUE(SegmentInit(false, false, false));
261   Track* const track = segment_.AddTrack(kMetadataTrackNumber);
262   track->set_uid(kMetadataTrackNumber);
263   track->set_type(kMetadataTrackType);
264   track->set_codec_id(kMetadataCodecId);
265 
266   // Valid Frame
267   EXPECT_TRUE(segment_.AddMetadata(dummy_data_, kFrameLength,
268                                    kMetadataTrackNumber, 0, 2000000));
269 
270   // Valid Frame
271   EXPECT_TRUE(segment_.AddMetadata(dummy_data_, kFrameLength,
272                                    kMetadataTrackNumber, 2000000, 6000000));
273 
274   // Invalid Frame - Non monotonically increasing timestamp
275   EXPECT_FALSE(segment_.AddMetadata(dummy_data_, kFrameLength,
276                                     kMetadataTrackNumber, 1, 2000000));
277 
278   // Invalid Frame - Null pointer
279   EXPECT_FALSE(segment_.AddMetadata(NULL, 0, kMetadataTrackNumber, 0, 8000000));
280 
281   // Invalid Frame - Invalid track number
282   EXPECT_FALSE(segment_.AddMetadata(NULL, 0, kInvalidTrackNumber, 0, 8000000));
283 
284   segment_.Finalize();
285   CloseWriter();
286 
287   EXPECT_TRUE(CompareFiles(GetTestFilePath("metadata_block.webm"), filename_));
288 }
289 
TEST_F(MuxerTest,TrackType)290 TEST_F(MuxerTest, TrackType) {
291   EXPECT_TRUE(SegmentInit(false, false, false));
292   Track* const track = segment_.AddTrack(kMetadataTrackNumber);
293   track->set_uid(kMetadataTrackNumber);
294   track->set_codec_id(kMetadataCodecId);
295 
296   // Invalid Frame - Incomplete track information (Track Type not set).
297   EXPECT_FALSE(segment_.AddMetadata(dummy_data_, kFrameLength,
298                                     kMetadataTrackNumber, 0, 2000000));
299 
300   track->set_type(kMetadataTrackType);
301 
302   // Valid Frame
303   EXPECT_TRUE(segment_.AddMetadata(dummy_data_, kFrameLength,
304                                    kMetadataTrackNumber, 0, 2000000));
305 
306   segment_.Finalize();
307   CloseWriter();
308 }
309 
TEST_F(MuxerTest,BlockWithAdditional)310 TEST_F(MuxerTest, BlockWithAdditional) {
311   EXPECT_TRUE(SegmentInit(false, false, false));
312   AddVideoTrack();
313 
314   // Valid Frame
315   EXPECT_TRUE(segment_.AddFrameWithAdditional(dummy_data_, kFrameLength,
316                                               dummy_data_, kFrameLength, 1,
317                                               kVideoTrackNumber, 0, true));
318 
319   // Valid Frame
320   EXPECT_TRUE(segment_.AddFrameWithAdditional(
321       dummy_data_, kFrameLength, dummy_data_, kFrameLength, 1,
322       kVideoTrackNumber, 2000000, false));
323 
324   // Invalid Frame - Non monotonically increasing timestamp
325   EXPECT_FALSE(segment_.AddFrameWithAdditional(dummy_data_, kFrameLength,
326                                                dummy_data_, kFrameLength, 1,
327                                                kVideoTrackNumber, 1, false));
328 
329   // Invalid Frame - Null frame pointer
330   EXPECT_FALSE(
331       segment_.AddFrameWithAdditional(NULL, 0, dummy_data_, kFrameLength, 1,
332                                       kVideoTrackNumber, 3000000, false));
333 
334   // Invalid Frame - Null additional pointer
335   EXPECT_FALSE(segment_.AddFrameWithAdditional(dummy_data_, kFrameLength, NULL,
336                                                0, 1, kVideoTrackNumber, 4000000,
337                                                false));
338 
339   // Invalid Frame - Invalid track number
340   EXPECT_FALSE(segment_.AddFrameWithAdditional(
341       dummy_data_, kFrameLength, dummy_data_, kFrameLength, 1,
342       kInvalidTrackNumber, 8000000, false));
343 
344   segment_.Finalize();
345   CloseWriter();
346 
347   EXPECT_TRUE(
348       CompareFiles(GetTestFilePath("block_with_additional.webm"), filename_));
349 }
350 
TEST_F(MuxerTest,BlockAdditionalWithAddGenericFrame)351 TEST_F(MuxerTest, BlockAdditionalWithAddGenericFrame) {
352   EXPECT_TRUE(SegmentInit(false, false, false));
353   AddVideoTrack();
354 
355   Frame frame;
356   frame.Init(dummy_data_, kFrameLength);
357   frame.AddAdditionalData(dummy_data_, kFrameLength, 1);
358   frame.set_track_number(kVideoTrackNumber);
359   frame.set_is_key(true);
360 
361   // Valid Frame
362   frame.set_timestamp(0);
363   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
364 
365   // Valid Frame
366   frame.set_timestamp(2000000);
367   frame.set_is_key(false);
368   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
369 
370   // Invalid Frame - Non monotonically increasing timestamp
371   frame.set_timestamp(1);
372   EXPECT_FALSE(segment_.AddGenericFrame(&frame));
373 
374   // Invalid Frame - Invalid track number
375   frame.set_track_number(kInvalidTrackNumber);
376   frame.set_timestamp(4000000);
377   EXPECT_FALSE(segment_.AddGenericFrame(&frame));
378 
379   segment_.Finalize();
380   CloseWriter();
381 
382   EXPECT_TRUE(
383       CompareFiles(GetTestFilePath("block_with_additional.webm"), filename_));
384 }
385 
TEST_F(MuxerTest,SegmentDurationComputation)386 TEST_F(MuxerTest, SegmentDurationComputation) {
387   EXPECT_TRUE(SegmentInit(false, false, false));
388   AddVideoTrack();
389 
390   Frame frame;
391   frame.Init(dummy_data_, kFrameLength);
392   frame.set_track_number(kVideoTrackNumber);
393   frame.set_timestamp(0);
394   frame.set_is_key(false);
395   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
396   frame.set_timestamp(2000000);
397   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
398   frame.set_timestamp(4000000);
399   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
400   frame.set_timestamp(6000000);
401   frame.set_duration(2000000);
402   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
403   segment_.Finalize();
404 
405   // SegmentInfo's duration is in timecode scale
406   EXPECT_EQ(8, segment_.GetSegmentInfo()->duration());
407 
408   CloseWriter();
409 
410   EXPECT_TRUE(
411       CompareFiles(GetTestFilePath("segment_duration.webm"), filename_));
412 }
413 
TEST_F(MuxerTest,SetSegmentDuration)414 TEST_F(MuxerTest, SetSegmentDuration) {
415   EXPECT_TRUE(SegmentInit(false, false, false));
416   AddVideoTrack();
417   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
418                                 false));
419   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
420                                 2000000, false));
421 
422   segment_.set_duration(10500.0);
423   segment_.Finalize();
424   CloseWriter();
425 
426   EXPECT_TRUE(
427       CompareFiles(GetTestFilePath("set_segment_duration.webm"), filename_));
428 }
429 
TEST_F(MuxerTest,ForceNewCluster)430 TEST_F(MuxerTest, ForceNewCluster) {
431   EXPECT_TRUE(SegmentInit(false, false, false));
432   AddVideoTrack();
433 
434   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
435                                 false));
436   segment_.ForceNewClusterOnNextFrame();
437   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
438                                 2000000, false));
439   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
440                                 4000000, false));
441   segment_.ForceNewClusterOnNextFrame();
442   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
443                                 6000000, false));
444   segment_.Finalize();
445 
446   CloseWriter();
447 
448   EXPECT_TRUE(
449       CompareFiles(GetTestFilePath("force_new_cluster.webm"), filename_));
450 }
451 
TEST_F(MuxerTest,OutputCues)452 TEST_F(MuxerTest, OutputCues) {
453   EXPECT_TRUE(SegmentInit(true, false, false));
454   AddVideoTrack();
455 
456   EXPECT_TRUE(
457       segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, true));
458   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
459                                 2000000, false));
460   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
461                                 4000000, false));
462   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
463                                 6000000, true));
464   EXPECT_TRUE(segment_.AddCuePoint(4000000, kVideoTrackNumber));
465   segment_.Finalize();
466 
467   CloseWriter();
468 
469   EXPECT_TRUE(CompareFiles(GetTestFilePath("output_cues.webm"), filename_));
470 }
471 
TEST_F(MuxerTest,CuesBeforeClusters)472 TEST_F(MuxerTest, CuesBeforeClusters) {
473   EXPECT_TRUE(SegmentInit(true, false, false));
474   AddVideoTrack();
475 
476   EXPECT_TRUE(
477       segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, true));
478   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
479                                 2000000, false));
480   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
481                                 4000000, false));
482   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
483                                 6000000, true));
484   segment_.Finalize();
485   CloseWriter();
486 #ifdef _MSC_VER
487   // Close the output file: the MS run time won't allow mkvparser::MkvReader
488   // to open a file for reading when it's still open for writing.
489   temp_file_.reset();
490 #endif
491   mkvparser::MkvReader reader;
492   ASSERT_EQ(0, reader.Open(filename_.c_str()));
493   MkvWriter cues_writer;
494   std::string cues_filename = libwebm::GetTempFileName();
495   ASSERT_GT(cues_filename.length(), 0u);
496   cues_writer.Open(cues_filename.c_str());
497   EXPECT_TRUE(segment_.CopyAndMoveCuesBeforeClusters(&reader, &cues_writer));
498   reader.Close();
499   cues_writer.Close();
500 
501   EXPECT_TRUE(CompareFiles(GetTestFilePath("cues_before_clusters.webm"),
502                            cues_filename));
503   MkvParser parser;
504   ASSERT_TRUE(ParseMkvFileReleaseParser(cues_filename, &parser));
505   int64_t cues_offset = 0;
506   ASSERT_TRUE(HasCuePoints(parser.segment, &cues_offset));
507   ASSERT_GT(cues_offset, 0);
508   ASSERT_TRUE(ValidateCues(parser.segment, parser.reader));
509   remove(cues_filename.c_str());
510 }
511 
TEST_F(MuxerTest,MaxClusterSize)512 TEST_F(MuxerTest, MaxClusterSize) {
513   EXPECT_TRUE(SegmentInit(false, false, false));
514   AddVideoTrack();
515   const uint64_t kMaxClusterSize = 20;
516   segment_.set_max_cluster_size(kMaxClusterSize);
517   EXPECT_EQ(kMaxClusterSize, segment_.max_cluster_size());
518   EXPECT_TRUE(segment_.AddFrame(dummy_data_, 1, kVideoTrackNumber, 0, false));
519   EXPECT_TRUE(
520       segment_.AddFrame(dummy_data_, 1, kVideoTrackNumber, 2000000, false));
521   EXPECT_TRUE(
522       segment_.AddFrame(dummy_data_, 1, kVideoTrackNumber, 4000000, false));
523   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
524                                 6000000, false));
525   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
526                                 8000000, false));
527   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
528                                 9000000, false));
529   segment_.Finalize();
530 
531   CloseWriter();
532 
533   EXPECT_TRUE(
534       CompareFiles(GetTestFilePath("max_cluster_size.webm"), filename_));
535 }
536 
TEST_F(MuxerTest,MaxClusterDuration)537 TEST_F(MuxerTest, MaxClusterDuration) {
538   EXPECT_TRUE(SegmentInit(false, false, false));
539   AddVideoTrack();
540   const uint64_t kMaxClusterDuration = 4000000;
541   segment_.set_max_cluster_duration(kMaxClusterDuration);
542 
543   EXPECT_EQ(kMaxClusterDuration, segment_.max_cluster_duration());
544   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
545                                 false));
546   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
547                                 2000000, false));
548   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
549                                 4000000, false));
550   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
551                                 6000000, false));
552   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
553                                 8000000, false));
554   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
555                                 9000000, false));
556   segment_.Finalize();
557 
558   CloseWriter();
559 
560   EXPECT_TRUE(
561       CompareFiles(GetTestFilePath("max_cluster_duration.webm"), filename_));
562 }
563 
TEST_F(MuxerTest,SetCuesTrackNumber)564 TEST_F(MuxerTest, SetCuesTrackNumber) {
565   const uint64_t kTrackNumber = 10;
566   EXPECT_TRUE(SegmentInit(true, false, false));
567   const uint64_t vid_track =
568       segment_.AddVideoTrack(kWidth, kHeight, kTrackNumber);
569   EXPECT_EQ(kTrackNumber, vid_track);
570   segment_.GetTrackByNumber(vid_track)->set_uid(kVideoTrackNumber);
571   EXPECT_TRUE(segment_.CuesTrack(vid_track));
572 
573   EXPECT_EQ(vid_track, segment_.cues_track());
574   EXPECT_TRUE(
575       segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber, 0, true));
576   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber,
577                                 2000000, false));
578   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber,
579                                 4000000, false));
580   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber,
581                                 6000000, true));
582   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber,
583                                 8000000, false));
584   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber,
585                                 9000000, false));
586   segment_.Finalize();
587 
588   CloseWriter();
589 
590   EXPECT_TRUE(
591       CompareFiles(GetTestFilePath("set_cues_track_number.webm"), filename_));
592 }
593 
TEST_F(MuxerTest,BlockWithDiscardPadding)594 TEST_F(MuxerTest, BlockWithDiscardPadding) {
595   EXPECT_TRUE(SegmentInit(false, false, false));
596   AddAudioTrack();
597 
598   int timecode = 1000;
599   // 12810000 == 0xc37710, should be 0-extended to avoid changing the sign.
600   // The next two should be written as 1 byte.
601   std::array<int, 3> values = {{12810000, 127, -128}};
602   for (const std::int64_t discard_padding : values) {
603     EXPECT_TRUE(segment_.AddFrameWithDiscardPadding(
604         dummy_data_, kFrameLength, discard_padding, kAudioTrackNumber, timecode,
605         true))
606         << "discard_padding: " << discard_padding;
607     timecode += 1000;
608   }
609 
610   segment_.Finalize();
611 
612   CloseWriter();
613 
614   EXPECT_TRUE(CompareFiles(GetTestFilePath("discard_padding.webm"), filename_));
615 }
616 
TEST_F(MuxerTest,AccurateClusterDuration)617 TEST_F(MuxerTest, AccurateClusterDuration) {
618   EXPECT_TRUE(SegmentInit(false, true, false));
619   AddVideoTrack();
620 
621   Frame frame;
622   frame.Init(dummy_data_, kFrameLength);
623   frame.set_track_number(kVideoTrackNumber);
624   frame.set_timestamp(0);
625   frame.set_is_key(true);
626   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
627   segment_.ForceNewClusterOnNextFrame();
628   frame.set_timestamp(2000000);
629   frame.set_is_key(false);
630   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
631   frame.set_timestamp(4000000);
632   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
633   segment_.ForceNewClusterOnNextFrame();
634   frame.set_timestamp(6000000);
635   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
636   segment_.Finalize();
637 
638   CloseWriter();
639 
640   EXPECT_TRUE(CompareFiles(GetTestFilePath("accurate_cluster_duration.webm"),
641                            filename_));
642 }
643 
644 // Tests AccurateClusterDuration flag with the duration of the very last block
645 // of the file set explicitly.
TEST_F(MuxerTest,AccurateClusterDurationExplicitLastFrameDuration)646 TEST_F(MuxerTest, AccurateClusterDurationExplicitLastFrameDuration) {
647   EXPECT_TRUE(SegmentInit(false, true, false));
648   AddVideoTrack();
649 
650   Frame frame;
651   frame.Init(dummy_data_, kFrameLength);
652   frame.set_track_number(kVideoTrackNumber);
653   frame.set_timestamp(0);
654   frame.set_is_key(true);
655   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
656   segment_.ForceNewClusterOnNextFrame();
657   frame.set_timestamp(2000000);
658   frame.set_is_key(false);
659   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
660   frame.set_timestamp(4000000);
661   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
662   segment_.ForceNewClusterOnNextFrame();
663   frame.set_timestamp(6000000);
664   frame.set_duration(2000000);
665   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
666   segment_.Finalize();
667 
668   // SegmentInfo's duration is in timecode scale
669   EXPECT_EQ(8, segment_.GetSegmentInfo()->duration());
670 
671   CloseWriter();
672 
673   EXPECT_TRUE(CompareFiles(
674       GetTestFilePath("accurate_cluster_duration_last_frame.webm"), filename_));
675 }
676 
TEST_F(MuxerTest,AccurateClusterDurationTwoTracks)677 TEST_F(MuxerTest, AccurateClusterDurationTwoTracks) {
678   EXPECT_TRUE(SegmentInit(false, true, false));
679   AddVideoTrack();
680   AddAudioTrack();
681 
682   Frame video_frame;
683   video_frame.Init(dummy_data_, kFrameLength);
684   video_frame.set_track_number(kVideoTrackNumber);
685   Frame audio_frame;
686   audio_frame.Init(dummy_data_, kFrameLength);
687   audio_frame.set_track_number(kAudioTrackNumber);
688   std::array<std::uint64_t, 2> cluster_timestamps = {{0, 40000000}};
689   for (const std::uint64_t cluster_timestamp : cluster_timestamps) {
690     // Add video and audio frames with timestamp 0.
691     video_frame.set_timestamp(cluster_timestamp);
692     video_frame.set_is_key(true);
693     EXPECT_TRUE(segment_.AddGenericFrame(&video_frame));
694     audio_frame.set_timestamp(cluster_timestamp);
695     audio_frame.set_is_key(true);
696     EXPECT_TRUE(segment_.AddGenericFrame(&audio_frame));
697 
698     // Add 3 consecutive audio frames.
699     std::array<std::uint64_t, 3> audio_timestamps = {
700         {10000000, 20000000, 30000000}};
701     for (const std::uint64_t audio_timestamp : audio_timestamps) {
702       audio_frame.set_timestamp(cluster_timestamp + audio_timestamp);
703       // Explicitly set duration for the very last audio frame.
704       if (cluster_timestamp == 40000000 && audio_timestamp == 30000000) {
705         audio_frame.set_duration(10000000);
706       }
707       EXPECT_TRUE(segment_.AddGenericFrame(&audio_frame));
708     }
709 
710     // Add a video frame with timestamp 33ms.
711     video_frame.set_is_key(false);
712     // Explicitly set duration for the very last video frame.
713     if (cluster_timestamp == 40000000) {
714       video_frame.set_duration(7000000);
715     }
716     video_frame.set_timestamp(cluster_timestamp + 33000000);
717     EXPECT_TRUE(segment_.AddGenericFrame(&video_frame));
718     segment_.ForceNewClusterOnNextFrame();
719   }
720   segment_.Finalize();
721 
722   // SegmentInfo's duration is in timecode scale
723   EXPECT_EQ(80, segment_.GetSegmentInfo()->duration());
724 
725   CloseWriter();
726 
727   EXPECT_TRUE(CompareFiles(
728       GetTestFilePath("accurate_cluster_duration_two_tracks.webm"), filename_));
729 }
730 
TEST_F(MuxerTest,AccurateClusterDurationWithoutFinalizingCluster)731 TEST_F(MuxerTest, AccurateClusterDurationWithoutFinalizingCluster) {
732   EXPECT_TRUE(SegmentInit(false, true, false));
733   AddVideoTrack();
734 
735   // Add a couple of frames and then bail out without finalizing the Segment
736   // (and thereby not finalizing the Cluster). The expectation here is that
737   // there shouldn't be any leaks. The test will fail under valgrind if there's
738   // a leak.
739   Frame video_frame;
740   video_frame.Init(dummy_data_, kFrameLength);
741   video_frame.set_track_number(kVideoTrackNumber);
742   video_frame.set_timestamp(0);
743   video_frame.set_is_key(true);
744   EXPECT_TRUE(segment_.AddGenericFrame(&video_frame));
745   video_frame.set_timestamp(33000000);
746   EXPECT_TRUE(segment_.AddGenericFrame(&video_frame));
747 
748   CloseWriter();
749 }
750 
TEST_F(MuxerTest,UseFixedSizeClusterTimecode)751 TEST_F(MuxerTest, UseFixedSizeClusterTimecode) {
752   EXPECT_TRUE(SegmentInit(false, false, true));
753   AddVideoTrack();
754 
755   Frame frame;
756   frame.Init(dummy_data_, kFrameLength);
757   frame.set_track_number(kVideoTrackNumber);
758   frame.set_timestamp(0);
759   frame.set_is_key(true);
760   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
761   segment_.ForceNewClusterOnNextFrame();
762   frame.set_timestamp(2000000);
763   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
764   segment_.ForceNewClusterOnNextFrame();
765   frame.set_timestamp(4000000);
766   EXPECT_TRUE(segment_.AddGenericFrame(&frame));
767   segment_.Finalize();
768 
769   CloseWriter();
770 
771   EXPECT_TRUE(CompareFiles(GetTestFilePath("fixed_size_cluster_timecode.webm"),
772                            filename_));
773 }
774 
TEST_F(MuxerTest,DocTypeWebm)775 TEST_F(MuxerTest, DocTypeWebm) {
776   EXPECT_TRUE(SegmentInit(false, false, false));
777   AddVideoTrack();
778   Track* const vid_track = segment_.GetTrackByNumber(kVideoTrackNumber);
779   vid_track->set_codec_id(kVP9CodecId);
780   AddDummyFrameAndFinalize(kVideoTrackNumber);
781   EXPECT_TRUE(CompareFiles(GetTestFilePath("webm_doctype.webm"), filename_));
782 }
783 
TEST_F(MuxerTest,DocTypeMatroska)784 TEST_F(MuxerTest, DocTypeMatroska) {
785   EXPECT_TRUE(SegmentInit(false, false, false));
786   AddVideoTrack();
787   Track* const vid_track = segment_.GetTrackByNumber(kVideoTrackNumber);
788   vid_track->set_codec_id("V_SOMETHING_NOT_IN_WEBM");
789   AddDummyFrameAndFinalize(kVideoTrackNumber);
790   EXPECT_TRUE(CompareFiles(GetTestFilePath("matroska_doctype.mkv"), filename_));
791 }
792 
TEST_F(MuxerTest,Colour)793 TEST_F(MuxerTest, Colour) {
794   EXPECT_TRUE(SegmentInit(false, false, false));
795   AddVideoTrack();
796 
797   mkvmuxer::PrimaryChromaticity muxer_pc(.1, .2);
798   mkvmuxer::MasteringMetadata muxer_mm;
799   muxer_mm.set_luminance_min(30.0);
800   muxer_mm.set_luminance_max(40.0);
801   ASSERT_TRUE(
802       muxer_mm.SetChromaticity(&muxer_pc, &muxer_pc, &muxer_pc, &muxer_pc));
803 
804   mkvmuxer::Colour muxer_colour;
805   muxer_colour.set_matrix_coefficients(mkvmuxer::Colour::kGbr);
806   muxer_colour.set_bits_per_channel(1);
807   muxer_colour.set_chroma_subsampling_horz(2);
808   muxer_colour.set_chroma_subsampling_vert(3);
809   muxer_colour.set_cb_subsampling_horz(4);
810   muxer_colour.set_cb_subsampling_vert(5);
811   muxer_colour.set_chroma_siting_horz(mkvmuxer::Colour::kLeftCollocated);
812   muxer_colour.set_chroma_siting_vert(mkvmuxer::Colour::kTopCollocated);
813   muxer_colour.set_range(mkvmuxer::Colour::kFullRange);
814   muxer_colour.set_transfer_characteristics(mkvmuxer::Colour::kLog);
815   muxer_colour.set_primaries(mkvmuxer::Colour::kSmpteSt4281P);
816   muxer_colour.set_max_cll(11);
817   muxer_colour.set_max_fall(12);
818   ASSERT_TRUE(muxer_colour.SetMasteringMetadata(muxer_mm));
819 
820   VideoTrack* const video_track =
821       dynamic_cast<VideoTrack*>(segment_.GetTrackByNumber(kVideoTrackNumber));
822   ASSERT_TRUE(video_track != nullptr);
823   ASSERT_TRUE(video_track->SetColour(muxer_colour));
824   ASSERT_NO_FATAL_FAILURE(AddDummyFrameAndFinalize(kVideoTrackNumber));
825 
826   MkvParser parser;
827   ASSERT_TRUE(ParseMkvFileReleaseParser(filename_, &parser));
828 
829   const mkvparser::VideoTrack* const parser_track =
830       static_cast<const mkvparser::VideoTrack*>(
831           parser.segment->GetTracks()->GetTrackByIndex(0));
832   const mkvparser::Colour* parser_colour = parser_track->GetColour();
833   ASSERT_TRUE(parser_colour != nullptr);
834   EXPECT_EQ(static_cast<long long>(muxer_colour.matrix_coefficients()),
835             parser_colour->matrix_coefficients);
836   EXPECT_EQ(static_cast<long long>(muxer_colour.bits_per_channel()),
837             parser_colour->bits_per_channel);
838   EXPECT_EQ(static_cast<long long>(muxer_colour.chroma_subsampling_horz()),
839             parser_colour->chroma_subsampling_horz);
840   EXPECT_EQ(static_cast<long long>(muxer_colour.chroma_subsampling_vert()),
841             parser_colour->chroma_subsampling_vert);
842   EXPECT_EQ(static_cast<long long>(muxer_colour.cb_subsampling_horz()),
843             parser_colour->cb_subsampling_horz);
844   EXPECT_EQ(static_cast<long long>(muxer_colour.cb_subsampling_vert()),
845             parser_colour->cb_subsampling_vert);
846   EXPECT_EQ(static_cast<long long>(muxer_colour.chroma_siting_horz()),
847             parser_colour->chroma_siting_horz);
848   EXPECT_EQ(static_cast<long long>(muxer_colour.chroma_siting_vert()),
849             parser_colour->chroma_siting_vert);
850   EXPECT_EQ(static_cast<long long>(muxer_colour.range()), parser_colour->range);
851   EXPECT_EQ(static_cast<long long>(muxer_colour.transfer_characteristics()),
852             parser_colour->transfer_characteristics);
853   EXPECT_EQ(static_cast<long long>(muxer_colour.primaries()),
854             parser_colour->primaries);
855   EXPECT_EQ(static_cast<long long>(muxer_colour.max_cll()),
856             parser_colour->max_cll);
857   EXPECT_EQ(static_cast<long long>(muxer_colour.max_fall()),
858             parser_colour->max_fall);
859 
860   const mkvparser::MasteringMetadata* const parser_mm =
861       parser_colour->mastering_metadata;
862   ASSERT_TRUE(parser_mm != nullptr);
863   EXPECT_FLOAT_EQ(muxer_mm.luminance_min(), parser_mm->luminance_min);
864   EXPECT_FLOAT_EQ(muxer_mm.luminance_max(), parser_mm->luminance_max);
865   EXPECT_FLOAT_EQ(muxer_mm.r()->x(), parser_mm->r->x);
866   EXPECT_FLOAT_EQ(muxer_mm.r()->y(), parser_mm->r->y);
867   EXPECT_FLOAT_EQ(muxer_mm.g()->x(), parser_mm->g->x);
868   EXPECT_FLOAT_EQ(muxer_mm.g()->y(), parser_mm->g->y);
869   EXPECT_FLOAT_EQ(muxer_mm.b()->x(), parser_mm->b->x);
870   EXPECT_FLOAT_EQ(muxer_mm.b()->y(), parser_mm->b->y);
871   EXPECT_FLOAT_EQ(muxer_mm.white_point()->x(), parser_mm->white_point->x);
872   EXPECT_FLOAT_EQ(muxer_mm.white_point()->y(), parser_mm->white_point->y);
873   EXPECT_TRUE(CompareFiles(GetTestFilePath("colour.webm"), filename_));
874 }
875 
TEST_F(MuxerTest,ColourPartial)876 TEST_F(MuxerTest, ColourPartial) {
877   EXPECT_TRUE(SegmentInit(false, false, false));
878   AddVideoTrack();
879   mkvmuxer::Colour muxer_colour;
880   muxer_colour.set_matrix_coefficients(
881       mkvmuxer::Colour::kBt2020NonConstantLuminance);
882 
883   VideoTrack* const video_track =
884       dynamic_cast<VideoTrack*>(segment_.GetTrackByNumber(kVideoTrackNumber));
885   ASSERT_TRUE(video_track != nullptr);
886   ASSERT_TRUE(video_track->SetColour(muxer_colour));
887   ASSERT_NO_FATAL_FAILURE(AddDummyFrameAndFinalize(kVideoTrackNumber));
888 
889   MkvParser parser;
890   ASSERT_TRUE(ParseMkvFileReleaseParser(filename_, &parser));
891 
892   const mkvparser::VideoTrack* const parser_track =
893       static_cast<const mkvparser::VideoTrack*>(
894           parser.segment->GetTracks()->GetTrackByIndex(0));
895   const mkvparser::Colour* parser_colour = parser_track->GetColour();
896   EXPECT_EQ(static_cast<long long>(muxer_colour.matrix_coefficients()),
897             parser_colour->matrix_coefficients);
898 }
899 
TEST_F(MuxerTest,Projection)900 TEST_F(MuxerTest, Projection) {
901   EXPECT_TRUE(SegmentInit(false, false, false));
902   AddVideoTrack();
903 
904   mkvmuxer::Projection muxer_proj;
905   muxer_proj.set_type(mkvmuxer::Projection::kRectangular);
906   muxer_proj.set_pose_yaw(1);
907   muxer_proj.set_pose_pitch(2);
908   muxer_proj.set_pose_roll(3);
909   const uint8_t muxer_proj_private[1] = {4};
910   const uint64_t muxer_proj_private_length = 1;
911   ASSERT_TRUE(muxer_proj.SetProjectionPrivate(&muxer_proj_private[0],
912                                               muxer_proj_private_length));
913 
914   VideoTrack* const video_track =
915       static_cast<VideoTrack*>(segment_.GetTrackByNumber(kVideoTrackNumber));
916   ASSERT_TRUE(video_track != nullptr);
917   ASSERT_TRUE(video_track->SetProjection(muxer_proj));
918   ASSERT_NO_FATAL_FAILURE(AddDummyFrameAndFinalize(kVideoTrackNumber));
919 
920   MkvParser parser;
921   ASSERT_TRUE(ParseMkvFileReleaseParser(filename_, &parser));
922 
923   const mkvparser::VideoTrack* const parser_track =
924       static_cast<const mkvparser::VideoTrack*>(
925           parser.segment->GetTracks()->GetTrackByIndex(0));
926 
927   const mkvparser::Projection* const parser_proj =
928       parser_track->GetProjection();
929   ASSERT_TRUE(parser_proj != nullptr);
930   EXPECT_FLOAT_EQ(muxer_proj.pose_yaw(), parser_proj->pose_yaw);
931   EXPECT_FLOAT_EQ(muxer_proj.pose_pitch(), parser_proj->pose_pitch);
932   EXPECT_FLOAT_EQ(muxer_proj.pose_roll(), parser_proj->pose_roll);
933   ASSERT_TRUE(parser_proj->private_data != nullptr);
934   EXPECT_EQ(static_cast<size_t>(muxer_proj.private_data_length()),
935             parser_proj->private_data_length);
936 
937   EXPECT_EQ(muxer_proj.private_data()[0], parser_proj->private_data[0]);
938   typedef mkvparser::Projection::ProjectionType ParserProjType;
939   EXPECT_EQ(static_cast<ParserProjType>(muxer_proj.type()), parser_proj->type);
940   EXPECT_TRUE(CompareFiles(GetTestFilePath("projection.webm"), filename_));
941 }
942 
TEST_F(MuxerTest,EstimateDuration)943 TEST_F(MuxerTest, EstimateDuration) {
944   EXPECT_TRUE(SegmentInit(false, false, false));
945   segment_.set_estimate_file_duration(true);
946   AddVideoTrack();
947   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
948                                 false));
949   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
950                                 2000000, false));
951   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
952                                 4000000, false));
953   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
954                                 6000000, false));
955   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
956                                 8000000, false));
957   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
958                                 9000000, false));
959   segment_.Finalize();
960 
961   CloseWriter();
962 
963   EXPECT_TRUE(
964       CompareFiles(GetTestFilePath("estimate_duration.webm"), filename_));
965 }
966 
TEST_F(MuxerTest,SetPixelWidthPixelHeight)967 TEST_F(MuxerTest, SetPixelWidthPixelHeight) {
968   EXPECT_TRUE(SegmentInit(false, false, false));
969   AddVideoTrack();
970   VideoTrack* const video_track =
971       static_cast<VideoTrack*>(segment_.GetTrackByNumber(kVideoTrackNumber));
972   ASSERT_TRUE(video_track != nullptr);
973   video_track->set_pixel_width(500);
974   video_track->set_pixel_height(650);
975 
976   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
977                                 false));
978   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber,
979                                 2000000, false));
980 
981   segment_.Finalize();
982   CloseWriter();
983 
984   EXPECT_TRUE(CompareFiles(GetTestFilePath("set_pixelwidth_pixelheight.webm"),
985                            filename_));
986 }
987 
TEST_F(MuxerTest,LongTagString)988 TEST_F(MuxerTest, LongTagString) {
989   EXPECT_TRUE(SegmentInit(false, false, false));
990   AddVideoTrack();
991   Tag* const tag = segment_.AddTag();
992   // 160 needs two bytes when varint encoded.
993   const std::string dummy_string(160, '0');
994   tag->add_simple_tag("long_tag", dummy_string.c_str());
995 
996   EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0,
997                                 false));
998 
999   segment_.Finalize();
1000   CloseWriter();
1001 
1002   EXPECT_TRUE(CompareFiles(GetTestFilePath("long_tag_string.webm"), filename_));
1003 }
1004 
1005 }  // namespace test
1006 
main(int argc,char * argv[])1007 int main(int argc, char* argv[]) {
1008   ::testing::InitGoogleTest(&argc, argv);
1009   return RUN_ALL_TESTS();
1010 }
1011