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