Add an option to avoid early initialization of audio capture
This can cause issues on Android S if this initialization happens when the app doesn't have permission to access the microphone. Bug: b/197461765 Change-Id: Iebccff9d15f5bb12a7b2c78e1c373e379b37a127 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/246104 Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Commit-Queue: Xavier Lepaul <xalep@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35689}
This commit is contained in:
parent
a3361ff2f5
commit
1e12f2a800
@ -65,6 +65,7 @@ void AudioOptions::SetAll(const AudioOptions& change) {
|
||||
SetFrom(&combined_audio_video_bwe, change.combined_audio_video_bwe);
|
||||
SetFrom(&audio_network_adaptor, change.audio_network_adaptor);
|
||||
SetFrom(&audio_network_adaptor_config, change.audio_network_adaptor_config);
|
||||
SetFrom(&init_recording_on_send, change.init_recording_on_send);
|
||||
}
|
||||
|
||||
bool AudioOptions::operator==(const AudioOptions& o) const {
|
||||
@ -92,7 +93,8 @@ bool AudioOptions::operator==(const AudioOptions& o) const {
|
||||
tx_agc_limiter == o.tx_agc_limiter &&
|
||||
combined_audio_video_bwe == o.combined_audio_video_bwe &&
|
||||
audio_network_adaptor == o.audio_network_adaptor &&
|
||||
audio_network_adaptor_config == o.audio_network_adaptor_config;
|
||||
audio_network_adaptor_config == o.audio_network_adaptor_config &&
|
||||
init_recording_on_send == o.init_recording_on_send;
|
||||
}
|
||||
|
||||
std::string AudioOptions::ToString() const {
|
||||
@ -126,6 +128,7 @@ std::string AudioOptions::ToString() const {
|
||||
ToStringIfSet(&result, "tx_agc_limiter", tx_agc_limiter);
|
||||
ToStringIfSet(&result, "combined_audio_video_bwe", combined_audio_video_bwe);
|
||||
ToStringIfSet(&result, "audio_network_adaptor", audio_network_adaptor);
|
||||
ToStringIfSet(&result, "init_recording_on_send", init_recording_on_send);
|
||||
result << "}";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
@ -83,6 +83,10 @@ struct RTC_EXPORT AudioOptions {
|
||||
absl::optional<bool> audio_network_adaptor;
|
||||
// Config string for audio network adaptor.
|
||||
absl::optional<std::string> audio_network_adaptor_config;
|
||||
// Pre-initialize the ADM for recording when starting to send. Default to
|
||||
// true.
|
||||
// TODO(webrtc:13566): Remove this option. See issue for details.
|
||||
absl::optional<bool> init_recording_on_send;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -1862,13 +1862,15 @@ void WebRtcVoiceMediaChannel::SetSend(bool send) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply channel specific options, and initialize the ADM for recording (this
|
||||
// may take time on some platforms, e.g. Android).
|
||||
// Apply channel specific options.
|
||||
if (send) {
|
||||
engine()->ApplyOptions(options_);
|
||||
|
||||
// Initialize the ADM for recording (this may take time on some platforms,
|
||||
// e.g. Android).
|
||||
if (options_.init_recording_on_send.value_or(true) &&
|
||||
// InitRecording() may return an error if the ADM is already recording.
|
||||
if (!engine()->adm()->RecordingIsInitialized() &&
|
||||
!engine()->adm()->RecordingIsInitialized() &&
|
||||
!engine()->adm()->Recording()) {
|
||||
if (engine()->adm()->InitRecording() != 0) {
|
||||
RTC_LOG(LS_WARNING) << "Failed to initialize recording";
|
||||
|
||||
@ -305,9 +305,15 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam<bool> {
|
||||
void SetSend(bool enable) {
|
||||
ASSERT_TRUE(channel_);
|
||||
if (enable) {
|
||||
EXPECT_CALL(*adm_, RecordingIsInitialized()).WillOnce(Return(false));
|
||||
EXPECT_CALL(*adm_, Recording()).WillOnce(Return(false));
|
||||
EXPECT_CALL(*adm_, InitRecording()).WillOnce(Return(0));
|
||||
EXPECT_CALL(*adm_, RecordingIsInitialized())
|
||||
.Times(::testing::AtMost(1))
|
||||
.WillOnce(Return(false));
|
||||
EXPECT_CALL(*adm_, Recording())
|
||||
.Times(::testing::AtMost(1))
|
||||
.WillOnce(Return(false));
|
||||
EXPECT_CALL(*adm_, InitRecording())
|
||||
.Times(::testing::AtMost(1))
|
||||
.WillOnce(Return(0));
|
||||
}
|
||||
channel_->SetSend(enable);
|
||||
}
|
||||
@ -3122,6 +3128,34 @@ TEST_P(WebRtcVoiceEngineTestFake, SetAudioOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(WebRtcVoiceEngineTestFake, InitRecordingOnSend) {
|
||||
EXPECT_CALL(*adm_, RecordingIsInitialized()).WillOnce(Return(false));
|
||||
EXPECT_CALL(*adm_, Recording()).WillOnce(Return(false));
|
||||
EXPECT_CALL(*adm_, InitRecording()).Times(1);
|
||||
|
||||
std::unique_ptr<cricket::VoiceMediaChannel> channel(
|
||||
engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
|
||||
cricket::AudioOptions(),
|
||||
webrtc::CryptoOptions()));
|
||||
|
||||
channel->SetSend(true);
|
||||
}
|
||||
|
||||
TEST_P(WebRtcVoiceEngineTestFake, SkipInitRecordingOnSend) {
|
||||
EXPECT_CALL(*adm_, RecordingIsInitialized()).Times(0);
|
||||
EXPECT_CALL(*adm_, Recording()).Times(0);
|
||||
EXPECT_CALL(*adm_, InitRecording()).Times(0);
|
||||
|
||||
cricket::AudioOptions options;
|
||||
options.init_recording_on_send = false;
|
||||
|
||||
std::unique_ptr<cricket::VoiceMediaChannel> channel(
|
||||
engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), options,
|
||||
webrtc::CryptoOptions()));
|
||||
|
||||
channel->SetSend(true);
|
||||
}
|
||||
|
||||
TEST_P(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
|
||||
EXPECT_TRUE(SetupSendStream());
|
||||
EXPECT_CALL(*adm_, BuiltInAECIsAvailable())
|
||||
|
||||
@ -106,6 +106,8 @@ const char MediaConstraints::kTypingNoiseDetection[] =
|
||||
const char MediaConstraints::kAudioMirroring[] = "googAudioMirroring";
|
||||
const char MediaConstraints::kAudioNetworkAdaptorConfig[] =
|
||||
"googAudioNetworkAdaptorConfig";
|
||||
const char MediaConstraints::kInitAudioRecordingOnSend[] =
|
||||
"InitAudioRecordingOnSend";
|
||||
|
||||
// Constraint keys for CreateOffer / CreateAnswer defined in W3C specification.
|
||||
const char MediaConstraints::kOfferToReceiveAudio[] = "OfferToReceiveAudio";
|
||||
@ -211,6 +213,9 @@ void CopyConstraintsIntoAudioOptions(const MediaConstraints* constraints,
|
||||
if (options->audio_network_adaptor_config) {
|
||||
options->audio_network_adaptor = true;
|
||||
}
|
||||
ConstraintToOptional<bool>(constraints,
|
||||
MediaConstraints::kInitAudioRecordingOnSend,
|
||||
&options->init_recording_on_send);
|
||||
}
|
||||
|
||||
bool CopyConstraintsIntoOfferAnswerOptions(
|
||||
|
||||
@ -67,7 +67,8 @@ class MediaConstraints {
|
||||
static const char kTypingNoiseDetection[]; // googTypingNoiseDetection
|
||||
static const char kAudioMirroring[]; // googAudioMirroring
|
||||
static const char
|
||||
kAudioNetworkAdaptorConfig[]; // goodAudioNetworkAdaptorConfig
|
||||
kAudioNetworkAdaptorConfig[]; // googAudioNetworkAdaptorConfig
|
||||
static const char kInitAudioRecordingOnSend[]; // InitAudioRecordingOnSend;
|
||||
|
||||
// Constraint keys for CreateOffer / CreateAnswer
|
||||
// Specified by the W3C PeerConnection spec
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user