Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: media/capture/webm_muxer_unittest.cc

Issue 1710713002: Move media/capture/webm_muxer* to media/muxers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moving webm_muxer* going to media/muxers, cleaning up DEPS Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/capture/webm_muxer.cc ('k') | media/media.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include "base/bind.h"
9 #include "base/location.h"
10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "media/audio/audio_parameters.h"
14 #include "media/base/channel_layout.h"
15 #include "media/base/video_frame.h"
16 #include "media/capture/webm_muxer.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using ::testing::_;
21 using ::testing::AllOf;
22 using ::testing::AnyNumber;
23 using ::testing::AtLeast;
24 using ::testing::Eq;
25 using ::testing::InSequence;
26 using ::testing::Mock;
27 using ::testing::Not;
28 using ::testing::Sequence;
29 using ::testing::TestWithParam;
30 using ::testing::ValuesIn;
31 using ::testing::WithArgs;
32
33 namespace media {
34
35 struct kTestParams {
36 VideoCodec codec;
37 size_t num_video_tracks;
38 size_t num_audio_tracks;
39 };
40
41 class WebmMuxerTest : public TestWithParam<kTestParams> {
42 public:
43 WebmMuxerTest()
44 : webm_muxer_(GetParam().codec,
45 GetParam().num_video_tracks,
46 GetParam().num_audio_tracks,
47 base::Bind(&WebmMuxerTest::WriteCallback,
48 base::Unretained(this))),
49 last_encoded_length_(0),
50 accumulated_position_(0) {
51 EXPECT_EQ(webm_muxer_.Position(), 0);
52 const mkvmuxer::int64 kRandomNewPosition = 333;
53 EXPECT_EQ(webm_muxer_.Position(kRandomNewPosition), -1);
54 EXPECT_FALSE(webm_muxer_.Seekable());
55 }
56
57 MOCK_METHOD1(WriteCallback, void(base::StringPiece));
58
59 void SaveEncodedDataLen(const base::StringPiece& encoded_data) {
60 last_encoded_length_ = encoded_data.size();
61 accumulated_position_ += encoded_data.size();
62 }
63
64 mkvmuxer::int64 GetWebmMuxerPosition() const {
65 return webm_muxer_.Position();
66 }
67
68 mkvmuxer::Segment::Mode GetWebmSegmentMode() const {
69 return webm_muxer_.segment_.mode();
70 }
71
72 mkvmuxer::int32 WebmMuxerWrite(const void* buf, mkvmuxer::uint32 len) {
73 return webm_muxer_.Write(buf, len);
74 }
75
76 WebmMuxer webm_muxer_;
77
78 size_t last_encoded_length_;
79 int64_t accumulated_position_;
80
81 private:
82 DISALLOW_COPY_AND_ASSIGN(WebmMuxerTest);
83 };
84
85 // Checks that the WriteCallback is called with appropriate params when
86 // WebmMuxer::Write() method is called.
87 TEST_P(WebmMuxerTest, Write) {
88 const base::StringPiece encoded_data("abcdefghijklmnopqrstuvwxyz");
89
90 EXPECT_CALL(*this, WriteCallback(encoded_data));
91 WebmMuxerWrite(encoded_data.data(), encoded_data.size());
92
93 EXPECT_EQ(GetWebmMuxerPosition(), static_cast<int64_t>(encoded_data.size()));
94 }
95
96 // This test sends two frames and checks that the WriteCallback is called with
97 // appropriate params in both cases.
98 TEST_P(WebmMuxerTest, OnEncodedVideoTwoFrames) {
99 if (GetParam().num_audio_tracks > 0)
100 return;
101
102 const gfx::Size frame_size(160, 80);
103 const scoped_refptr<VideoFrame> video_frame =
104 VideoFrame::CreateBlackFrame(frame_size);
105 const std::string encoded_data("abcdefghijklmnopqrstuvwxyz");
106
107 EXPECT_CALL(*this, WriteCallback(_))
108 .Times(AtLeast(1))
109 .WillRepeatedly(
110 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen)));
111 webm_muxer_.OnEncodedVideo(video_frame,
112 make_scoped_ptr(new std::string(encoded_data)),
113 base::TimeTicks::Now(),
114 false /* keyframe */);
115
116 // First time around WriteCallback() is pinged a number of times to write the
117 // Matroska header, but at the end it dumps |encoded_data|.
118 EXPECT_EQ(last_encoded_length_, encoded_data.size());
119 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_);
120 EXPECT_GE(GetWebmMuxerPosition(), static_cast<int64_t>(last_encoded_length_));
121 EXPECT_EQ(GetWebmSegmentMode(), mkvmuxer::Segment::kLive);
122
123 const int64_t begin_of_second_block = accumulated_position_;
124 EXPECT_CALL(*this, WriteCallback(_))
125 .Times(AtLeast(1))
126 .WillRepeatedly(
127 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen)));
128 webm_muxer_.OnEncodedVideo(video_frame,
129 make_scoped_ptr(new std::string(encoded_data)),
130 base::TimeTicks::Now(),
131 false /* keyframe */);
132
133 // The second time around the callbacks should include a SimpleBlock header,
134 // namely the track index, a timestamp and a flags byte, for a total of 6B.
135 EXPECT_EQ(last_encoded_length_, encoded_data.size());
136 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_);
137 const uint32_t kSimpleBlockSize = 6u;
138 EXPECT_EQ(static_cast<int64_t>(begin_of_second_block + kSimpleBlockSize +
139 encoded_data.size()),
140 accumulated_position_);
141 }
142
143 TEST_P(WebmMuxerTest, OnEncodedAudioTwoFrames) {
144 if (GetParam().num_video_tracks > 0)
145 return;
146
147 const int sample_rate = 48000;
148 const int bits_per_sample = 16;
149 const int frames_per_buffer = 480;
150 media::AudioParameters audio_params(
151 media::AudioParameters::Format::AUDIO_PCM_LOW_LATENCY,
152 media::CHANNEL_LAYOUT_MONO, sample_rate, bits_per_sample,
153 frames_per_buffer);
154
155 const std::string encoded_data("abcdefghijklmnopqrstuvwxyz");
156
157 EXPECT_CALL(*this, WriteCallback(_))
158 .Times(AtLeast(1))
159 .WillRepeatedly(
160 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen)));
161 webm_muxer_.OnEncodedAudio(audio_params,
162 make_scoped_ptr(new std::string(encoded_data)),
163 base::TimeTicks::Now());
164
165 // First time around WriteCallback() is pinged a number of times to write the
166 // Matroska header, but at the end it dumps |encoded_data|.
167 EXPECT_EQ(last_encoded_length_, encoded_data.size());
168 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_);
169 EXPECT_GE(GetWebmMuxerPosition(), static_cast<int64_t>(last_encoded_length_));
170 EXPECT_EQ(GetWebmSegmentMode(), mkvmuxer::Segment::kLive);
171
172 const int64_t begin_of_second_block = accumulated_position_;
173 EXPECT_CALL(*this, WriteCallback(_))
174 .Times(AtLeast(1))
175 .WillRepeatedly(
176 WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen)));
177 webm_muxer_.OnEncodedAudio(audio_params,
178 make_scoped_ptr(new std::string(encoded_data)),
179 base::TimeTicks::Now());
180
181 // The second time around the callbacks should include a SimpleBlock header,
182 // namely the track index, a timestamp and a flags byte, for a total of 6B.
183 EXPECT_EQ(last_encoded_length_, encoded_data.size());
184 EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_);
185 const uint32_t kSimpleBlockSize = 6u;
186 EXPECT_EQ(static_cast<int64_t>(begin_of_second_block + kSimpleBlockSize +
187 encoded_data.size()),
188 accumulated_position_);
189 }
190
191 // This test verifies that when video data comes before audio data, we save the
192 // encoded video frames and add it to the video track when audio data arrives.
193 TEST_P(WebmMuxerTest, VideoIsStoredWhileWaitingForAudio) {
194 // This test is only relevant if we have both kinds of tracks.
195 if (GetParam().num_video_tracks == 0 || GetParam().num_audio_tracks == 0)
196 return;
197
198 // First send a video keyframe
199 const gfx::Size frame_size(160, 80);
200 const scoped_refptr<VideoFrame> video_frame =
201 VideoFrame::CreateBlackFrame(frame_size);
202 const std::string encoded_video("thisisanencodedvideopacket");
203 webm_muxer_.OnEncodedVideo(video_frame,
204 make_scoped_ptr(new std::string(encoded_video)),
205 base::TimeTicks::Now(), true /* keyframe */);
206 // A few encoded non key frames.
207 const int kNumNonKeyFrames = 2;
208 for (int i = 0; i < kNumNonKeyFrames; ++i) {
209 webm_muxer_.OnEncodedVideo(video_frame,
210 make_scoped_ptr(new std::string(encoded_video)),
211 base::TimeTicks::Now(), false /* keyframe */);
212 }
213
214 // Send some audio. The header will be written and muxing will proceed
215 // normally.
216 const int sample_rate = 48000;
217 const int bits_per_sample = 16;
218 const int frames_per_buffer = 480;
219 media::AudioParameters audio_params(
220 media::AudioParameters::Format::AUDIO_PCM_LOW_LATENCY,
221 media::CHANNEL_LAYOUT_MONO, sample_rate, bits_per_sample,
222 frames_per_buffer);
223 const std::string encoded_audio("thisisanencodedaudiopacket");
224
225 // We should first get the encoded video frames, then the encoded audio frame.
226 Sequence s;
227 EXPECT_CALL(*this, WriteCallback(Eq(encoded_video)))
228 .Times(1 + kNumNonKeyFrames)
229 .InSequence(s);
230 EXPECT_CALL(*this, WriteCallback(Eq(encoded_audio))).Times(1).InSequence(s);
231 // We'll also get lots of other header-related stuff.
232 EXPECT_CALL(*this, WriteCallback(
233 AllOf(Not(Eq(encoded_video)), Not(Eq(encoded_audio)))))
234 .Times(AnyNumber());
235 webm_muxer_.OnEncodedAudio(audio_params,
236 make_scoped_ptr(new std::string(encoded_audio)),
237 base::TimeTicks::Now());
238 }
239
240 const kTestParams kTestCases[] = {
241 // TODO: consider not enumerating every combination by hand.
242 {kCodecVP8, 1 /* num_video_tracks */, 0 /*num_audio_tracks*/},
243 {kCodecVP8, 0, 1},
244 {kCodecVP8, 1, 1},
245 {kCodecVP9, 1, 0},
246 {kCodecVP9, 0, 1},
247 {kCodecVP9, 1, 1},
248 };
249
250 INSTANTIATE_TEST_CASE_P(, WebmMuxerTest, ValuesIn(kTestCases));
251
252 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/webm_muxer.cc ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698