// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "content/renderer/media/mock_media_constraint_factory.h" #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" #include "content/renderer/media/webrtc_audio_capturer.h" #include "content/renderer/media/webrtc_local_audio_source_provider.h" #include "content/renderer/media/webrtc_local_audio_track.h" #include "media/audio/audio_parameters.h" #include "media/base/audio_bus.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" namespace content { class WebRtcLocalAudioSourceProviderTest : public testing::Test { protected: virtual void SetUp() OVERRIDE { source_params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, 1, 0, 48000, 16, 480); sink_params_.Reset( media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_STEREO, 2, 0, 44100, 16, WebRtcLocalAudioSourceProvider::kWebAudioRenderBufferSize); const int length = source_params_.frames_per_buffer() * source_params_.channels(); source_data_.reset(new int16[length]); sink_bus_ = media::AudioBus::Create(sink_params_); MockMediaConstraintFactory constraint_factory; scoped_refptr capturer( WebRtcAudioCapturer::CreateCapturer( -1, StreamDeviceInfo(), constraint_factory.CreateWebMediaConstraints(), NULL, NULL)); scoped_refptr adapter( WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); scoped_ptr native_track( new WebRtcLocalAudioTrack(adapter, capturer, NULL)); blink::WebMediaStreamSource audio_source; audio_source.initialize(base::UTF8ToUTF16("dummy_source_id"), blink::WebMediaStreamSource::TypeAudio, base::UTF8ToUTF16("dummy_source_name")); blink_track_.initialize(blink::WebString::fromUTF8("audio_track"), audio_source); blink_track_.setExtraData(native_track.release()); source_provider_.reset(new WebRtcLocalAudioSourceProvider(blink_track_)); source_provider_->SetSinkParamsForTesting(sink_params_); source_provider_->OnSetFormat(source_params_); } media::AudioParameters source_params_; scoped_ptr source_data_; media::AudioParameters sink_params_; scoped_ptr sink_bus_; blink::WebMediaStreamTrack blink_track_; scoped_ptr source_provider_; }; TEST_F(WebRtcLocalAudioSourceProviderTest, VerifyDataFlow) { // Point the WebVector into memory owned by |sink_bus_|. blink::WebVector audio_data( static_cast(sink_bus_->channels())); for (size_t i = 0; i < audio_data.size(); ++i) audio_data[i] = sink_bus_->channel(i); // Enable the |source_provider_| by asking for data. This will inject // source_params_.frames_per_buffer() of zero into the resampler since there // no available data in the FIFO. source_provider_->provideInput(audio_data, sink_params_.frames_per_buffer()); EXPECT_TRUE(sink_bus_->channel(0)[0] == 0); // Set the value of source data to be 1. const int length = source_params_.frames_per_buffer() * source_params_.channels(); std::fill(source_data_.get(), source_data_.get() + length, 1); // Deliver data to |source_provider_|. source_provider_->OnData(source_data_.get(), source_params_.sample_rate(), source_params_.channels(), source_params_.frames_per_buffer()); // Consume the first packet in the resampler, which contains only zero. // And the consumption of the data will trigger pulling the real packet from // the source provider FIFO into the resampler. // Note that we need to count in the provideInput() call a few lines above. for (int i = sink_params_.frames_per_buffer(); i < source_params_.frames_per_buffer(); i += sink_params_.frames_per_buffer()) { sink_bus_->Zero(); source_provider_->provideInput(audio_data, sink_params_.frames_per_buffer()); EXPECT_DOUBLE_EQ(0.0, sink_bus_->channel(0)[0]); EXPECT_DOUBLE_EQ(0.0, sink_bus_->channel(1)[0]); } // Prepare the second packet for featching. source_provider_->OnData(source_data_.get(), source_params_.sample_rate(), source_params_.channels(), source_params_.frames_per_buffer()); // Verify the packets. for (int i = 0; i < source_params_.frames_per_buffer(); i += sink_params_.frames_per_buffer()) { sink_bus_->Zero(); source_provider_->provideInput(audio_data, sink_params_.frames_per_buffer()); EXPECT_GT(sink_bus_->channel(0)[0], 0); EXPECT_GT(sink_bus_->channel(1)[0], 0); EXPECT_DOUBLE_EQ(sink_bus_->channel(0)[0], sink_bus_->channel(1)[0]); } } TEST_F(WebRtcLocalAudioSourceProviderTest, DeleteSourceProviderBeforeStoppingTrack) { source_provider_.reset(); // Stop the audio track. WebRtcLocalAudioTrack* native_track = static_cast( MediaStreamTrack::GetTrack(blink_track_)); native_track->Stop(); } TEST_F(WebRtcLocalAudioSourceProviderTest, StopTrackBeforeDeletingSourceProvider) { // Stop the audio track. WebRtcLocalAudioTrack* native_track = static_cast( MediaStreamTrack::GetTrack(blink_track_)); native_track->Stop(); // Delete the source provider. source_provider_.reset(); } } // namespace content