OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "base/memory/weak_ptr.h" | |
6 #include "base/run_loop.h" | |
7 #include "base/threading/thread_task_runner_handle.h" | |
8 #include "content/public/renderer/media_stream_audio_sink.h" | |
9 #include "content/renderer/media/html_audio_element_capturer_source.h" | |
10 #include "content/renderer/media/media_stream_audio_track.h" | |
11 #include "media/audio/null_audio_sink.h" | |
12 #include "media/base/audio_parameters.h" | |
13 #include "media/base/fake_audio_render_callback.h" | |
14 #include "media/blink/webaudiosourceprovider_impl.h" | |
15 #include "testing/gmock/include/gmock/gmock.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 #include "third_party/WebKit/public/platform/WebString.h" | |
18 #include "third_party/WebKit/public/web/WebHeap.h" | |
19 | |
20 using ::testing::_; | |
21 using ::testing::AllOf; | |
22 using ::testing::InSequence; | |
23 using ::testing::Mock; | |
24 using ::testing::Property; | |
25 | |
26 namespace content { | |
27 | |
28 static const int kNumChannelsForTest = 1; | |
29 static const int kBufferDurationMs = 10; | |
30 | |
31 static const int kAudioTrackSampleRate = 48000; | |
32 static const int kAudioTrackSamplesPerBuffer = | |
33 kAudioTrackSampleRate * kBufferDurationMs / | |
34 base::Time::kMillisecondsPerSecond; | |
35 | |
36 ACTION_P(RunClosure, closure) { | |
37 closure.Run(); | |
38 } | |
39 | |
40 // | |
41 class MockMediaStreamAudioSink final : public MediaStreamAudioSink { | |
42 public: | |
43 MockMediaStreamAudioSink() : MediaStreamAudioSink() {} | |
44 ~MockMediaStreamAudioSink() = default; | |
45 | |
46 MOCK_METHOD1(OnSetFormat, void(const media::AudioParameters& params)); | |
47 MOCK_METHOD2(OnData, | |
48 void(const media::AudioBus& audio_bus, | |
49 base::TimeTicks estimated_capture_time)); | |
50 | |
51 DISALLOW_COPY_AND_ASSIGN(MockMediaStreamAudioSink); | |
52 }; | |
53 | |
54 // This test needs to bundle together plenty of objects, namely: | |
55 // - a WebAudioSourceProviderImpl, which in turn needs an Audio Sink, in this | |
56 // case a NullAudioSink. This is needed to plug HTMLAudioElementCapturerSource | |
57 // and inject audio. | |
58 // - a WebMediaStreamSource, that owns the HTMLAudioElementCapturerSource under | |
59 // test, and a WebMediaStreamAudioTrack, that the class under test needs to | |
60 // connect to in order to operate correctly. This class has an inner content | |
61 // MediaStreamAudioTrack. | |
62 // - finally, a MockMediaStreamAudioSink to observe captured audio frames, and | |
63 // that plugs into the former MediaStreamAudioTrack. | |
64 class HTMLAudioElementCapturerSourceTest : public testing::Test { | |
65 public: | |
66 HTMLAudioElementCapturerSourceTest() | |
67 : fake_callback_(0.1), | |
68 audio_source_(new media::WebAudioSourceProviderImpl( | |
69 new media::NullAudioSink(base::ThreadTaskRunnerHandle::Get()))) {} | |
70 | |
71 void SetUp() final { | |
72 const media::AudioParameters params( | |
73 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | |
74 media::GuessChannelLayout(kNumChannelsForTest), | |
75 kAudioTrackSampleRate /* sample_rate */, 16 /* bits_per_sample */, | |
76 kAudioTrackSamplesPerBuffer /* frames_per_buffer */); | |
77 audio_source_->Initialize(params, &fake_callback_); | |
78 | |
79 blink_audio_source_.initialize(blink::WebString::fromUTF8("audio_id"), | |
80 blink::WebMediaStreamSource::TypeAudio, | |
81 blink::WebString::fromUTF8("audio_track"), | |
82 false /* remote */); | |
83 blink_audio_track_.initialize(blink_audio_source_.id(), | |
84 blink_audio_source_); | |
85 | |
86 // |blink_audio_source_| takes ownership of HtmlAudioElementCapturerSource. | |
87 blink_audio_source_.setExtraData( | |
88 new HtmlAudioElementCapturerSource(audio_source_.get())); | |
89 ASSERT_TRUE(source()->ConnectToTrack(blink_audio_track_)); | |
90 } | |
91 | |
92 void TearDown() override { | |
93 blink_audio_track_.reset(); | |
94 blink_audio_source_.reset(); | |
95 blink::WebHeap::collectAllGarbageForTesting(); | |
96 } | |
97 | |
98 HtmlAudioElementCapturerSource* source() const { | |
99 return static_cast<HtmlAudioElementCapturerSource*>( | |
100 MediaStreamAudioSource::From(blink_audio_source_)); | |
101 } | |
102 | |
103 MediaStreamAudioTrack* track() const { | |
104 return MediaStreamAudioTrack::From(blink_audio_track_); | |
105 } | |
106 | |
107 int InjectAudio(media::AudioBus* audio_bus) { | |
108 return audio_source_->RenderForTesting(audio_bus); | |
109 } | |
110 | |
111 protected: | |
112 const base::MessageLoop message_loop_; | |
113 | |
114 blink::WebMediaStreamSource blink_audio_source_; | |
115 blink::WebMediaStreamTrack blink_audio_track_; | |
116 | |
117 media::FakeAudioRenderCallback fake_callback_; | |
118 scoped_refptr<media::WebAudioSourceProviderImpl> audio_source_; | |
119 }; | |
120 | |
121 // Constructs and destructs all objects. This is a non trivial sequence. | |
122 TEST_F(HTMLAudioElementCapturerSourceTest, ConstructAndDestruct) { | |
123 } | |
124 | |
125 // This test verifies that Audio can be properly captured when injected in the | |
126 // WebAudioSourceProviderImpl. | |
127 TEST_F(HTMLAudioElementCapturerSourceTest, CaptureAudio) { | |
128 InSequence s; | |
129 | |
130 base::RunLoop run_loop; | |
131 base::Closure quit_closure = run_loop.QuitClosure(); | |
132 | |
133 MockMediaStreamAudioSink sink; | |
134 track()->AddSink(&sink); | |
135 EXPECT_CALL(sink, OnSetFormat(_)).Times(1); | |
136 EXPECT_CALL( | |
137 sink, | |
138 OnData(AllOf(Property(&media::AudioBus::channels, kNumChannelsForTest), | |
139 Property(&media::AudioBus::frames, | |
140 kAudioTrackSamplesPerBuffer)), | |
141 _)) | |
142 .Times(1) | |
143 .WillOnce(RunClosure(quit_closure)); | |
144 | |
145 std::unique_ptr<media::AudioBus> bus = media::AudioBus::Create( | |
146 kNumChannelsForTest, kAudioTrackSamplesPerBuffer); | |
147 InjectAudio(bus.get()); | |
148 run_loop.Run(); | |
149 | |
150 track()->Stop(); | |
151 track()->RemoveSink(&sink); | |
152 } | |
153 | |
154 } // namespace content | |
OLD | NEW |