Commit c4db771a authored by Dale Curtis's avatar Dale Curtis

Make authorization timeout provided to AudioOutputDevice configurable.

This is part 2/4 CLs to move the <audio>/<video> elements off of
a synchronous API that can lead to renderer hangs and premature
audio renderer errors.

Specifically this will allow us to create AudioRendererMixerInputs
with an authorization timeout of zero when the asynchronous API
is the only one in use.

BUG=905506
TEST=compiles.
R=olka

Change-Id: I298550db1e7bac9b73033566c17cff8f1d2252b3
Reviewed-on: https://chromium-review.googlesource.com/c/1347146
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarOlga Sharonova <olka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612400}
parent 203bcc58
......@@ -29,6 +29,7 @@ namespace content {
AudioDeviceFactory* AudioDeviceFactory::factory_ = nullptr;
namespace {
#if defined(OS_WIN) || defined(OS_MACOSX) || \
(defined(OS_LINUX) && !defined(OS_CHROMEOS))
// Due to driver deadlock issues on Windows (http://crbug/422522) there is a
......@@ -36,21 +37,25 @@ namespace {
// In this case we will time out, to avoid renderer hang forever waiting for
// device authorization (http://crbug/615589). This will result in "no audio".
// There are also cases when authorization takes too long on Mac and Linux.
const int64_t kMaxAuthorizationTimeoutMs = 10000;
constexpr int64_t kMaxAuthorizationTimeoutMs = 10000;
#else
const int64_t kMaxAuthorizationTimeoutMs = 0; // No timeout.
constexpr int64_t kMaxAuthorizationTimeoutMs = 0; // No timeout.
#endif
base::TimeDelta GetDefaultAuthTimeout() {
// Set authorization request timeout at 80% of renderer hung timeout,
// but no more than kMaxAuthorizationTimeout.
return base::TimeDelta::FromMilliseconds(
std::min(kHungRendererDelayMs * 8 / 10, kMaxAuthorizationTimeoutMs));
}
scoped_refptr<media::AudioOutputDevice> NewOutputDevice(
int render_frame_id,
const media::AudioSinkParameters& params) {
const media::AudioSinkParameters& params,
base::TimeDelta auth_timeout) {
auto device = base::MakeRefCounted<media::AudioOutputDevice>(
AudioOutputIPCFactory::get()->CreateAudioOutputIPC(render_frame_id),
AudioOutputIPCFactory::get()->io_task_runner(), params,
// Set authorization request timeout at 80% of renderer hung timeout,
// but no more than kMaxAuthorizationTimeout.
base::TimeDelta::FromMilliseconds(
std::min(kHungRendererDelayMs * 8 / 10, kMaxAuthorizationTimeoutMs)));
AudioOutputIPCFactory::get()->io_task_runner(), params, auth_timeout);
device->RequestDeviceAuthorization();
return device;
}
......@@ -102,7 +107,8 @@ scoped_refptr<media::AudioRendererSink>
AudioDeviceFactory::NewAudioRendererMixerSink(
int render_frame_id,
const media::AudioSinkParameters& params) {
return NewFinalAudioRendererSink(render_frame_id, params);
return NewFinalAudioRendererSink(render_frame_id, params,
GetDefaultAuthTimeout());
}
// static
......@@ -127,7 +133,8 @@ AudioDeviceFactory::NewAudioRendererSink(
UMA_HISTOGRAM_BOOLEAN("Media.Audio.Render.SinkCache.UsedForSinkCreation",
false);
return NewFinalAudioRendererSink(render_frame_id, params);
return NewFinalAudioRendererSink(render_frame_id, params,
GetDefaultAuthTimeout());
}
// static
......@@ -195,15 +202,17 @@ AudioDeviceFactory::~AudioDeviceFactory() {
scoped_refptr<media::AudioRendererSink>
AudioDeviceFactory::NewFinalAudioRendererSink(
int render_frame_id,
const media::AudioSinkParameters& params) {
const media::AudioSinkParameters& params,
base::TimeDelta auth_timeout) {
if (factory_) {
scoped_refptr<media::AudioRendererSink> sink =
factory_->CreateFinalAudioRendererSink(render_frame_id, params);
factory_->CreateFinalAudioRendererSink(render_frame_id, params,
auth_timeout);
if (sink)
return sink;
}
return NewOutputDevice(render_frame_id, params);
return NewOutputDevice(render_frame_id, params, auth_timeout);
}
} // namespace content
......@@ -99,10 +99,12 @@ class CONTENT_EXPORT AudioDeviceFactory {
// on the default implementation.
// Creates a final sink in the rendering pipeline, which represents the actual
// output device.
// output device. |auth_timeout| is the authorization timeout allowed for the
// underlying AudioOutputDevice instance; a timeout of zero means no timeout.
virtual scoped_refptr<media::AudioRendererSink> CreateFinalAudioRendererSink(
int render_frame_id,
const media::AudioSinkParameters& params) = 0;
const media::AudioSinkParameters& params,
base::TimeDelta auth_timeout) = 0;
virtual scoped_refptr<media::AudioRendererSink> CreateAudioRendererSink(
SourceType source_type,
......@@ -126,7 +128,8 @@ class CONTENT_EXPORT AudioDeviceFactory {
static scoped_refptr<media::AudioRendererSink> NewFinalAudioRendererSink(
int render_frame_id,
const media::AudioSinkParameters& params);
const media::AudioSinkParameters& params,
base::TimeDelta auth_timeout);
DISALLOW_COPY_AND_ASSIGN(AudioDeviceFactory);
};
......
......@@ -46,10 +46,11 @@ class MockAudioDeviceFactory : public AudioDeviceFactory {
// These methods are just mocked because tests currently don't need them to be
// implemented.
MOCK_METHOD2(CreateFinalAudioRendererSink,
MOCK_METHOD3(CreateFinalAudioRendererSink,
scoped_refptr<media::AudioRendererSink>(
int render_frame_id,
const media::AudioSinkParameters& params));
const media::AudioSinkParameters& params,
base::TimeDelta auth_timeout));
MOCK_METHOD3(CreateAudioRendererSink,
scoped_refptr<media::AudioRendererSink>(
SourceType source_type,
......
......@@ -88,10 +88,11 @@ class RendererWebAudioDeviceImplTest
scoped_refptr<media::AudioCapturerSource>(
int,
const media::AudioSourceParameters&));
MOCK_METHOD2(CreateFinalAudioRendererSink,
scoped_refptr<media::AudioRendererSink>(
int,
const media::AudioSinkParameters&));
MOCK_METHOD3(
CreateFinalAudioRendererSink,
scoped_refptr<media::AudioRendererSink>(int,
const media::AudioSinkParameters&,
base::TimeDelta));
MOCK_METHOD3(CreateSwitchableAudioRendererSink,
scoped_refptr<media::SwitchableAudioRendererSink>(
SourceType,
......
......@@ -91,10 +91,11 @@ class WebRtcAudioRendererTest : public testing::Test,
scoped_refptr<media::AudioCapturerSource>(
int,
const media::AudioSourceParameters&));
MOCK_METHOD2(CreateFinalAudioRendererSink,
scoped_refptr<media::AudioRendererSink>(
int,
const media::AudioSinkParameters&));
MOCK_METHOD3(
CreateFinalAudioRendererSink,
scoped_refptr<media::AudioRendererSink>(int,
const media::AudioSinkParameters&,
base::TimeDelta));
MOCK_METHOD3(CreateSwitchableAudioRendererSink,
scoped_refptr<media::SwitchableAudioRendererSink>(
SourceType,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment