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