Fix was_unmuted_ in AudioRendererImpl
This CL fixes how the was_unmuted_ property on the AudioRenderImpl is set. For some audio streams (e.g. autoplaying ads), the volume of the media player is set to 1 before the media is muted and played via autoplay. The audio should only be considered as "unmuted" if the volume is set to a non-zero value when the AudioRendererImpl is in a "Playing" state. The comment in pipeline_impl.cc says that "Calling SetVolume() before Initialize() allows renderers to optimize for power by avoiding initialization of audio output until necessary", suggesting that the calls to SetVolume() before the audio is played is expected and required. Bug: 1192903 Change-Id: Ifcf442ac2a9c35dff1bff2787dfd98d8c464720f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3011843 Commit-Queue: Evan Liu <evliu@google.com> Reviewed-by: Dale Curtis <dalecurtis@chromium.org> Cr-Commit-Position: refs/heads/master@{#900144}
This commit is contained in:
@ -136,7 +136,7 @@ void AudioRendererImpl::StartRendering_Locked() {
|
||||
lock_.AssertAcquired();
|
||||
|
||||
sink_playing_ = true;
|
||||
|
||||
was_unmuted_ = was_unmuted_ || volume_ != 0;
|
||||
base::AutoUnlock auto_unlock(lock_);
|
||||
if (volume_ || !null_sink_)
|
||||
sink_->Play();
|
||||
@ -731,7 +731,13 @@ void AudioRendererImpl::OnWaiting(WaitingReason reason) {
|
||||
|
||||
void AudioRendererImpl::SetVolume(float volume) {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
was_unmuted_ = was_unmuted_ || volume != 0;
|
||||
|
||||
// Only consider audio as unmuted if the volume is set to a non-zero value
|
||||
// when the state is kPlaying.
|
||||
if (state_ == kPlaying) {
|
||||
was_unmuted_ = was_unmuted_ || volume != 0;
|
||||
}
|
||||
|
||||
if (state_ == kUninitialized || state_ == kInitializing) {
|
||||
volume_ = volume;
|
||||
return;
|
||||
|
@ -108,6 +108,7 @@ class MEDIA_EXPORT AudioRendererImpl
|
||||
void OnResume() override;
|
||||
|
||||
void SetPlayDelayCBForTesting(PlayDelayCBForTesting cb);
|
||||
bool was_unmuted_for_testing() const { return was_unmuted_; }
|
||||
|
||||
private:
|
||||
friend class AudioRendererImplTest;
|
||||
|
@ -1686,4 +1686,44 @@ TEST_F(AudioRendererImplTest, HighLatencyHint) {
|
||||
EXPECT_EQ(buffer_playback_threshold().value, high_latency_playback_threshold);
|
||||
}
|
||||
|
||||
TEST_F(AudioRendererImplTest, PlayUnmuted) {
|
||||
// Setting the volume to a non-zero value does not count as unmuted until the
|
||||
// audio is played.
|
||||
EXPECT_EQ(renderer_->was_unmuted_for_testing(), 0);
|
||||
renderer_->SetVolume(1);
|
||||
EXPECT_EQ(renderer_->was_unmuted_for_testing(), 0);
|
||||
|
||||
Initialize();
|
||||
Preroll();
|
||||
StartTicking();
|
||||
EXPECT_EQ(renderer_->was_unmuted_for_testing(), 1);
|
||||
}
|
||||
|
||||
TEST_F(AudioRendererImplTest, UnmuteWhilePlaying) {
|
||||
ConfigureWithMockSink(hardware_params_);
|
||||
EXPECT_CALL(*mock_sink_, SetVolume(0));
|
||||
renderer_->SetVolume(0);
|
||||
EXPECT_EQ(renderer_->was_unmuted_for_testing(), 0);
|
||||
|
||||
EXPECT_CALL(*mock_sink_, Start());
|
||||
EXPECT_CALL(*mock_sink_, Play());
|
||||
Initialize();
|
||||
Preroll();
|
||||
StartTicking();
|
||||
EXPECT_EQ(renderer_->was_unmuted_for_testing(), 0);
|
||||
|
||||
EXPECT_CALL(*mock_sink_, SetVolume(1));
|
||||
renderer_->SetVolume(1);
|
||||
EXPECT_EQ(renderer_->was_unmuted_for_testing(), 1);
|
||||
|
||||
// Muting should pause the sink.
|
||||
EXPECT_CALL(*mock_sink_, SetVolume(0));
|
||||
EXPECT_CALL(*mock_sink_, Pause());
|
||||
renderer_->SetVolume(0);
|
||||
EXPECT_EQ(renderer_->was_unmuted_for_testing(), 1);
|
||||
|
||||
StopTicking();
|
||||
EXPECT_CALL(*mock_sink_, Stop());
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
|
Reference in New Issue
Block a user