Index: content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
diff --git a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
index a4295fadd2d26a48bd738f1776f8f79edfbfa243..891f2fc1f1d65cc4b70e62b4af4f6d0c3507130a 100644 |
--- a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
+++ b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
@@ -40,6 +40,7 @@ const int kAnotherRenderFrameId = 678; |
} // namespace; |
using media::AudioParameters; |
+using media::AudioLatency; |
class FakeAudioRendererSinkCache : public AudioRendererSinkCache { |
public: |
@@ -106,19 +107,16 @@ class AudioRendererMixerManagerTest : public testing::Test { |
media::AudioRendererMixer* GetMixer( |
int source_render_frame_id, |
const media::AudioParameters& params, |
+ AudioLatency::LatencyType latency, |
const std::string& device_id, |
const url::Origin& security_origin, |
media::OutputDeviceStatus* device_status) { |
- return manager_->GetMixer(source_render_frame_id, params, device_id, |
- security_origin, device_status); |
+ return manager_->GetMixer(source_render_frame_id, params, latency, |
+ device_id, security_origin, device_status); |
} |
- void ReturnMixer(int source_render_frame_id, |
- const media::AudioParameters& params, |
- const std::string& device_id, |
- const url::Origin& security_origin) { |
- return manager_->ReturnMixer(source_render_frame_id, params, device_id, |
- security_origin); |
+ void ReturnMixer(const media::AudioRendererMixer* mixer) { |
+ return manager_->ReturnMixer(mixer); |
} |
// Number of instantiated mixers. |
@@ -179,29 +177,32 @@ TEST_F(AudioRendererMixerManagerTest, GetReturnMixer) { |
// There should be no mixers outstanding to start with. |
EXPECT_EQ(0, mixer_count()); |
- media::AudioParameters params1( |
- AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
- kBitsPerChannel, kBufferSize); |
+ media::AudioParameters params1(media::AudioParameters::AUDIO_PCM_LINEAR, |
+ kChannelLayout, kSampleRate, kBitsPerChannel, |
+ kBufferSize); |
- media::AudioRendererMixer* mixer1 = GetMixer( |
- kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ media::AudioRendererMixer* mixer1 = |
+ GetMixer(kRenderFrameId, params1, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
ASSERT_TRUE(mixer1); |
EXPECT_EQ(1, mixer_count()); |
// The same parameters should return the same mixer1. |
- EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params1, kDefaultDeviceId, |
- kSecurityOrigin, nullptr)); |
+ EXPECT_EQ(mixer1, |
+ GetMixer(kRenderFrameId, params1, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr)); |
EXPECT_EQ(1, mixer_count()); |
// Return the extra mixer we just acquired. |
- ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer1); |
EXPECT_EQ(1, mixer_count()); |
media::AudioParameters params2( |
AudioParameters::AUDIO_PCM_LINEAR, kAnotherChannelLayout, kSampleRate * 2, |
kBitsPerChannel, kBufferSize * 2); |
- media::AudioRendererMixer* mixer2 = GetMixer( |
- kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ media::AudioRendererMixer* mixer2 = |
+ GetMixer(kRenderFrameId, params2, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
ASSERT_TRUE(mixer2); |
EXPECT_EQ(2, mixer_count()); |
@@ -209,9 +210,9 @@ TEST_F(AudioRendererMixerManagerTest, GetReturnMixer) { |
EXPECT_NE(mixer1, mixer2); |
// Return both outstanding mixers. |
- ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer1); |
EXPECT_EQ(1, mixer_count()); |
- ReturnMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer2); |
EXPECT_EQ(0, mixer_count()); |
} |
@@ -230,8 +231,9 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) { |
kSampleRate, |
kBitsPerChannel, |
kBufferSize); |
- media::AudioRendererMixer* mixer1 = GetMixer( |
- kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ media::AudioRendererMixer* mixer1 = |
+ GetMixer(kRenderFrameId, params1, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
ASSERT_TRUE(mixer1); |
EXPECT_EQ(1, mixer_count()); |
@@ -242,10 +244,12 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) { |
kSampleRate * 2, |
kBitsPerChannel * 2, |
kBufferSize * 2); |
- EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params2, kDefaultDeviceId, |
- kSecurityOrigin, nullptr)); |
+ media::AudioRendererMixer* mixer2 = |
+ GetMixer(kRenderFrameId, params2, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ EXPECT_EQ(mixer1, mixer2); |
EXPECT_EQ(1, mixer_count()); |
- ReturnMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer2); |
EXPECT_EQ(1, mixer_count()); |
// Modify some parameters that do matter: channel layout |
@@ -255,15 +259,16 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) { |
kBitsPerChannel, |
kBufferSize); |
ASSERT_NE(params3.channel_layout(), params1.channel_layout()); |
- |
- EXPECT_NE(mixer1, GetMixer(kRenderFrameId, params3, kDefaultDeviceId, |
- kSecurityOrigin, nullptr)); |
+ media::AudioRendererMixer* mixer3 = |
+ GetMixer(kRenderFrameId, params3, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ EXPECT_NE(mixer1, mixer3); |
EXPECT_EQ(2, mixer_count()); |
- ReturnMixer(kRenderFrameId, params3, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer3); |
EXPECT_EQ(1, mixer_count()); |
// Return final mixer. |
- ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer1); |
EXPECT_EQ(0, mixer_count()); |
} |
@@ -287,14 +292,15 @@ TEST_F(AudioRendererMixerManagerTest, CreateInput) { |
// Create two mixer inputs and ensure this doesn't instantiate any mixers yet. |
EXPECT_EQ(0, mixer_count()); |
media::FakeAudioRenderCallback callback(0); |
- scoped_refptr<media::AudioRendererMixerInput> input(manager_->CreateInput( |
- kRenderFrameId, 0, kDefaultDeviceId, kSecurityOrigin)); |
+ scoped_refptr<media::AudioRendererMixerInput> input( |
+ manager_->CreateInput(kRenderFrameId, 0, kDefaultDeviceId, |
+ kSecurityOrigin, AudioLatency::LATENCY_PLAYBACK)); |
input->Initialize(params, &callback); |
EXPECT_EQ(0, mixer_count()); |
media::FakeAudioRenderCallback another_callback(1); |
scoped_refptr<media::AudioRendererMixerInput> another_input( |
manager_->CreateInput(kAnotherRenderFrameId, 0, kDefaultDeviceId, |
- kSecurityOrigin)); |
+ kSecurityOrigin, AudioLatency::LATENCY_PLAYBACK)); |
another_input->Initialize(params, &another_callback); |
EXPECT_EQ(0, mixer_count()); |
@@ -341,29 +347,32 @@ TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) { |
// Empty device id, zero session id; |
scoped_refptr<media::AudioRendererMixerInput> input_to_default_device( |
manager_->CreateInput(kRenderFrameId, 0, // session_id |
- std::string(), kSecurityOrigin)); |
+ std::string(), kSecurityOrigin, |
+ AudioLatency::LATENCY_PLAYBACK)); |
input_to_default_device->Initialize(params, &callback); |
EXPECT_EQ(0, mixer_count()); |
// Specific device id, zero session id; |
scoped_refptr<media::AudioRendererMixerInput> input_to_matched_device( |
manager_->CreateInput(kRenderFrameId, 0, // session_id |
- kMatchedDeviceId, kSecurityOrigin)); |
+ kMatchedDeviceId, kSecurityOrigin, |
+ AudioLatency::LATENCY_PLAYBACK)); |
input_to_matched_device->Initialize(params, &callback); |
EXPECT_EQ(0, mixer_count()); |
// Specific device id, non-zero session id (to be ignored); |
scoped_refptr<media::AudioRendererMixerInput> input_to_another_device( |
manager_->CreateInput(kRenderFrameId, 1, // session id |
- kAnotherDeviceId, kSecurityOrigin)); |
+ kAnotherDeviceId, kSecurityOrigin, |
+ AudioLatency::LATENCY_PLAYBACK)); |
input_to_another_device->Initialize(params, &callback); |
EXPECT_EQ(0, mixer_count()); |
// Empty device id, non-zero session id; |
scoped_refptr<media::AudioRendererMixerInput> |
- input_to_matched_device_with_session_id( |
- manager_->CreateInput(kRenderFrameId, 2, // session id |
- std::string(), kSecurityOrigin)); |
+ input_to_matched_device_with_session_id(manager_->CreateInput( |
+ kRenderFrameId, 2, // session id |
+ std::string(), kSecurityOrigin, AudioLatency::LATENCY_PLAYBACK)); |
input_to_matched_device_with_session_id->Initialize(params, &callback); |
EXPECT_EQ(0, mixer_count()); |
@@ -410,29 +419,32 @@ TEST_F(AudioRendererMixerManagerTest, MixerDevices) { |
media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
kChannelLayout, kSampleRate, kBitsPerChannel, |
kBufferSize); |
- media::AudioRendererMixer* mixer1 = GetMixer( |
- kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ media::AudioRendererMixer* mixer1 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
ASSERT_TRUE(mixer1); |
EXPECT_EQ(1, mixer_count()); |
- media::AudioRendererMixer* mixer2 = GetMixer( |
- kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin, nullptr); |
+ media::AudioRendererMixer* mixer2 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kAnotherDeviceId, kSecurityOrigin, nullptr); |
ASSERT_TRUE(mixer2); |
EXPECT_EQ(2, mixer_count()); |
EXPECT_NE(mixer1, mixer2); |
- media::AudioRendererMixer* mixer3 = GetMixer( |
- kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2, nullptr); |
+ media::AudioRendererMixer* mixer3 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kAnotherDeviceId, kSecurityOrigin2, nullptr); |
ASSERT_TRUE(mixer3); |
EXPECT_EQ(3, mixer_count()); |
EXPECT_NE(mixer1, mixer3); |
EXPECT_NE(mixer2, mixer3); |
- ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer1); |
EXPECT_EQ(2, mixer_count()); |
- ReturnMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer2); |
EXPECT_EQ(1, mixer_count()); |
- ReturnMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2); |
+ ReturnMixer(mixer3); |
EXPECT_EQ(0, mixer_count()); |
} |
@@ -449,36 +461,40 @@ TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) { |
media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
kChannelLayout, kSampleRate, kBitsPerChannel, |
kBufferSize); |
- media::AudioRendererMixer* mixer1 = GetMixer( |
- kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ media::AudioRendererMixer* mixer1 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
ASSERT_TRUE(mixer1); |
EXPECT_EQ(1, mixer_count()); |
media::AudioRendererMixer* mixer2 = |
- GetMixer(kRenderFrameId, params, std::string(), kSecurityOrigin, nullptr); |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ std::string(), kSecurityOrigin, nullptr); |
ASSERT_TRUE(mixer2); |
EXPECT_EQ(1, mixer_count()); |
EXPECT_EQ(mixer1, mixer2); |
- media::AudioRendererMixer* mixer3 = GetMixer( |
- kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2, nullptr); |
+ media::AudioRendererMixer* mixer3 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin2, nullptr); |
ASSERT_TRUE(mixer3); |
EXPECT_EQ(1, mixer_count()); |
EXPECT_EQ(mixer1, mixer3); |
- media::AudioRendererMixer* mixer4 = GetMixer( |
- kRenderFrameId, params, std::string(), kSecurityOrigin2, nullptr); |
+ media::AudioRendererMixer* mixer4 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ std::string(), kSecurityOrigin2, nullptr); |
ASSERT_TRUE(mixer4); |
EXPECT_EQ(1, mixer_count()); |
EXPECT_EQ(mixer1, mixer4); |
- ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); |
+ ReturnMixer(mixer1); |
EXPECT_EQ(1, mixer_count()); |
- ReturnMixer(kRenderFrameId, params, std::string(), kSecurityOrigin); |
+ ReturnMixer(mixer2); |
EXPECT_EQ(1, mixer_count()); |
- ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2); |
+ ReturnMixer(mixer3); |
EXPECT_EQ(1, mixer_count()); |
- ReturnMixer(kRenderFrameId, params, std::string(), kSecurityOrigin2); |
+ ReturnMixer(mixer4); |
EXPECT_EQ(0, mixer_count()); |
} |
@@ -496,12 +512,93 @@ TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { |
media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; |
media::AudioRendererMixer* mixer = |
- GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin, |
- &device_status); |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kNonexistentDeviceId, kSecurityOrigin, &device_status); |
EXPECT_FALSE(mixer); |
EXPECT_EQ(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, device_status); |
EXPECT_EQ(0, mixer_count()); |
} |
+// Verify GetMixer() correctly deduplicate mixers basing on latency |
+// requirements. |
+TEST_F(AudioRendererMixerManagerTest, LatencyMixing) { |
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(5); |
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(5); |
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(5); |
+ |
+ EXPECT_EQ(0, mixer_count()); |
+ |
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
+ kChannelLayout, kSampleRate, kBitsPerChannel, |
+ kBufferSize); |
+ media::AudioRendererMixer* mixer1 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ ASSERT_TRUE(mixer1); |
+ EXPECT_EQ(1, mixer_count()); |
+ |
+ media::AudioRendererMixer* mixer2 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ ASSERT_TRUE(mixer2); |
+ EXPECT_EQ(mixer1, mixer2); // Same latency => same mixer. |
+ EXPECT_EQ(1, mixer_count()); |
+ |
+ media::AudioRendererMixer* mixer3 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_RTC, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ ASSERT_TRUE(mixer3); |
+ EXPECT_NE(mixer1, mixer3); |
+ EXPECT_EQ(2, mixer_count()); // Another latency => another mixer. |
+ |
+ media::AudioRendererMixer* mixer4 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_INTERACTIVE, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ ASSERT_TRUE(mixer4); |
+ EXPECT_EQ(3, mixer_count()); // Another latency => another mixer. |
+ |
+ media::AudioRendererMixer* mixer5 = |
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_EXACT_MS, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ ASSERT_TRUE(mixer5); |
+ EXPECT_EQ(4, mixer_count()); // Another latency => another mixer. |
+ |
+ media::AudioParameters params2(params); |
+ params2.set_frames_per_buffer(params.frames_per_buffer() * 2); |
+ params2.set_sample_rate(params.sample_rate() * 2); |
+ media::AudioRendererMixer* mixer6 = |
+ GetMixer(kRenderFrameId, params2, AudioLatency::LATENCY_EXACT_MS, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ ASSERT_TRUE(mixer6); |
+ // LATENCY_EXACT_MS, same buffer duraion => same mixer. |
+ EXPECT_EQ(mixer5, mixer6); |
+ EXPECT_EQ(4, mixer_count()); |
+ |
+ media::AudioParameters params3(params); |
+ params3.set_frames_per_buffer(kBufferSize * 2); |
+ media::AudioRendererMixer* mixer7 = |
+ GetMixer(kRenderFrameId, params3, AudioLatency::LATENCY_EXACT_MS, |
+ kDefaultDeviceId, kSecurityOrigin, nullptr); |
+ ASSERT_TRUE(mixer7); |
+ // LATENCY_EXACT_MS, another buffer duraion => another mixer. |
+ EXPECT_NE(mixer5, mixer7); |
+ EXPECT_EQ(5, mixer_count()); |
+ |
+ ReturnMixer(mixer1); |
+ EXPECT_EQ(5, mixer_count()); |
+ ReturnMixer(mixer2); |
+ EXPECT_EQ(4, mixer_count()); |
+ ReturnMixer(mixer3); |
+ EXPECT_EQ(3, mixer_count()); |
+ ReturnMixer(mixer4); |
+ EXPECT_EQ(2, mixer_count()); |
+ ReturnMixer(mixer5); |
+ EXPECT_EQ(2, mixer_count()); |
+ ReturnMixer(mixer6); |
+ EXPECT_EQ(1, mixer_count()); |
+ ReturnMixer(mixer7); |
+ EXPECT_EQ(0, mixer_count()); |
+} |
+ |
} // namespace content |