1 // Copyright 2013 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/logging.h" 6 #include "base/strings/utf_string_conversions.h" 7 #include "content/renderer/media/mock_media_constraint_factory.h" 8 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 9 #include "content/renderer/media/webrtc_audio_capturer.h" 10 #include "content/renderer/media/webrtc_local_audio_source_provider.h" 11 #include "content/renderer/media/webrtc_local_audio_track.h" 12 #include "media/audio/audio_parameters.h" 13 #include "media/base/audio_bus.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 16 17 namespace content { 18 19 class WebRtcLocalAudioSourceProviderTest : public testing::Test { 20 protected: 21 virtual void SetUp() OVERRIDE { 22 source_params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 23 media::CHANNEL_LAYOUT_MONO, 1, 0, 48000, 16, 480); 24 sink_params_.Reset( 25 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 26 media::CHANNEL_LAYOUT_STEREO, 2, 0, 44100, 16, 27 WebRtcLocalAudioSourceProvider::kWebAudioRenderBufferSize); 28 const int length = 29 source_params_.frames_per_buffer() * source_params_.channels(); 30 source_data_.reset(new int16[length]); 31 sink_bus_ = media::AudioBus::Create(sink_params_); 32 MockMediaConstraintFactory constraint_factory; 33 scoped_refptr<WebRtcAudioCapturer> capturer( 34 WebRtcAudioCapturer::CreateCapturer( 35 -1, StreamDeviceInfo(), 36 constraint_factory.CreateWebMediaConstraints(), NULL, NULL)); 37 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( 38 WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); 39 scoped_ptr<WebRtcLocalAudioTrack> native_track( 40 new WebRtcLocalAudioTrack(adapter, capturer, NULL)); 41 blink::WebMediaStreamSource audio_source; 42 audio_source.initialize(base::UTF8ToUTF16("dummy_source_id"), 43 blink::WebMediaStreamSource::TypeAudio, 44 base::UTF8ToUTF16("dummy_source_name")); 45 blink_track_.initialize(blink::WebString::fromUTF8("audio_track"), 46 audio_source); 47 blink_track_.setExtraData(native_track.release()); 48 source_provider_.reset(new WebRtcLocalAudioSourceProvider(blink_track_)); 49 source_provider_->SetSinkParamsForTesting(sink_params_); 50 source_provider_->OnSetFormat(source_params_); 51 } 52 53 media::AudioParameters source_params_; 54 scoped_ptr<int16[]> source_data_; 55 media::AudioParameters sink_params_; 56 scoped_ptr<media::AudioBus> sink_bus_; 57 blink::WebMediaStreamTrack blink_track_; 58 scoped_ptr<WebRtcLocalAudioSourceProvider> source_provider_; 59 }; 60 61 TEST_F(WebRtcLocalAudioSourceProviderTest, VerifyDataFlow) { 62 // Point the WebVector into memory owned by |sink_bus_|. 63 blink::WebVector<float*> audio_data( 64 static_cast<size_t>(sink_bus_->channels())); 65 for (size_t i = 0; i < audio_data.size(); ++i) 66 audio_data[i] = sink_bus_->channel(i); 67 68 // Enable the |source_provider_| by asking for data. This will inject 69 // source_params_.frames_per_buffer() of zero into the resampler since there 70 // no available data in the FIFO. 71 source_provider_->provideInput(audio_data, sink_params_.frames_per_buffer()); 72 EXPECT_TRUE(sink_bus_->channel(0)[0] == 0); 73 74 // Set the value of source data to be 1. 75 const int length = 76 source_params_.frames_per_buffer() * source_params_.channels(); 77 std::fill(source_data_.get(), source_data_.get() + length, 1); 78 79 // Deliver data to |source_provider_|. 80 source_provider_->OnData(source_data_.get(), 81 source_params_.sample_rate(), 82 source_params_.channels(), 83 source_params_.frames_per_buffer()); 84 85 // Consume the first packet in the resampler, which contains only zero. 86 // And the consumption of the data will trigger pulling the real packet from 87 // the source provider FIFO into the resampler. 88 // Note that we need to count in the provideInput() call a few lines above. 89 for (int i = sink_params_.frames_per_buffer(); 90 i < source_params_.frames_per_buffer(); 91 i += sink_params_.frames_per_buffer()) { 92 sink_bus_->Zero(); 93 source_provider_->provideInput(audio_data, 94 sink_params_.frames_per_buffer()); 95 EXPECT_DOUBLE_EQ(0.0, sink_bus_->channel(0)[0]); 96 EXPECT_DOUBLE_EQ(0.0, sink_bus_->channel(1)[0]); 97 } 98 99 // Prepare the second packet for featching. 100 source_provider_->OnData(source_data_.get(), 101 source_params_.sample_rate(), 102 source_params_.channels(), 103 source_params_.frames_per_buffer()); 104 105 // Verify the packets. 106 for (int i = 0; i < source_params_.frames_per_buffer(); 107 i += sink_params_.frames_per_buffer()) { 108 sink_bus_->Zero(); 109 source_provider_->provideInput(audio_data, 110 sink_params_.frames_per_buffer()); 111 EXPECT_GT(sink_bus_->channel(0)[0], 0); 112 EXPECT_GT(sink_bus_->channel(1)[0], 0); 113 EXPECT_DOUBLE_EQ(sink_bus_->channel(0)[0], sink_bus_->channel(1)[0]); 114 } 115 } 116 117 TEST_F(WebRtcLocalAudioSourceProviderTest, 118 DeleteSourceProviderBeforeStoppingTrack) { 119 source_provider_.reset(); 120 121 // Stop the audio track. 122 WebRtcLocalAudioTrack* native_track = static_cast<WebRtcLocalAudioTrack*>( 123 MediaStreamTrack::GetTrack(blink_track_)); 124 native_track->Stop(); 125 } 126 127 TEST_F(WebRtcLocalAudioSourceProviderTest, 128 StopTrackBeforeDeletingSourceProvider) { 129 // Stop the audio track. 130 WebRtcLocalAudioTrack* native_track = static_cast<WebRtcLocalAudioTrack*>( 131 MediaStreamTrack::GetTrack(blink_track_)); 132 native_track->Stop(); 133 134 // Delete the source provider. 135 source_provider_.reset(); 136 } 137 138 } // namespace content 139