diff --git a/api/audio_options.cc b/api/audio_options.cc index 6832bbe294..aca1fe80db 100644 --- a/api/audio_options.cc +++ b/api/audio_options.cc @@ -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(); } diff --git a/api/audio_options.h b/api/audio_options.h index 7d933ae649..48dd628ecd 100644 --- a/api/audio_options.h +++ b/api/audio_options.h @@ -83,6 +83,10 @@ struct RTC_EXPORT AudioOptions { absl::optional audio_network_adaptor; // Config string for audio network adaptor. absl::optional 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 init_recording_on_send; }; } // namespace cricket diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 0a8d3da8c2..536df8e22b 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -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_); - // InitRecording() may return an error if the ADM is already recording. - if (!engine()->adm()->RecordingIsInitialized() && + // 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. + !engine()->adm()->RecordingIsInitialized() && !engine()->adm()->Recording()) { if (engine()->adm()->InitRecording() != 0) { RTC_LOG(LS_WARNING) << "Failed to initialize recording"; diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc index 97e46b2159..2770a0d7bd 100644 --- a/media/engine/webrtc_voice_engine_unittest.cc +++ b/media/engine/webrtc_voice_engine_unittest.cc @@ -305,9 +305,15 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { 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 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 channel( + engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), options, + webrtc::CryptoOptions())); + + channel->SetSend(true); +} + TEST_P(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) { EXPECT_TRUE(SetupSendStream()); EXPECT_CALL(*adm_, BuiltInAECIsAvailable()) diff --git a/sdk/media_constraints.cc b/sdk/media_constraints.cc index 08bd9dc66c..3cc08b2799 100644 --- a/sdk/media_constraints.cc +++ b/sdk/media_constraints.cc @@ -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(constraints, + MediaConstraints::kInitAudioRecordingOnSend, + &options->init_recording_on_send); } bool CopyConstraintsIntoOfferAnswerOptions( diff --git a/sdk/media_constraints.h b/sdk/media_constraints.h index fd95a60235..f41ad25e65 100644 --- a/sdk/media_constraints.h +++ b/sdk/media_constraints.h @@ -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