microsoft / winrtc

The WinRTC project hosts everything needed to build apps with interoperable real time communications for modern Windows. It brings the power of WebRTC to modern Windows apps written in C#, C++ and VB. WinRTC enables real-time voice calling, video chat and data functionality (file transfer etc.) with web browsers via WebRTC.
347 stars 68 forks source link

Audio recording doesn't shutdown properly, cannot restart #67

Open djee-ms opened 4 years ago

djee-ms commented 4 years ago

Describe the bug Audio recording doesn't shutdown properly, and therefore cannot be restarted.

To Reproduce Steps to reproduce the behavior:

  1. Attach an audio track to an audio transceiver
  2. Establish a connection
  3. Remove the audio track from the transceiver
  4. Re-add the audio track on the transceiver

Expected behavior In step 3., audio stops being transmitted. Then in step 4. it starts again and the remote peer can hear the microphone recording again like after step 2.

Desktop (please complete the following information):

Additional context AudioDeviceWindowsCore::RecordingIsInitialized() returns false after AudioDeviceWindowsCore::StopRecording() was called, but the _audioClient is left untouched, still initialized. When the WebRTC engine calls AudioDeviceWindowsCore::StartRecording() again in step 4., the code attempts to initialize _audioClient a second time, which logically fails with AUDCLNT_E_ALREADY_INITIALIZED.

djee-ms commented 4 years ago
(audio_device_core_win.cc:1176): IAudioClient::Initialize() failed:
(audio_device_core_win.cc:94): Core Audio method failed (hr=-2004287486)
(audio_device_core_win.cc:97): Error details: 쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌쳌�蚮翽
(audio_device_impl.cc:769): output: -1
(audio_state.cc:108): webrtc::internal::AudioState::AddSendingStream: Failed to initialize recording.

Callstack:

>   mrwebrtc.dll!CaptureDeviceInternal::InitTransport() Line 1175   C++
    mrwebrtc.dll!webrtc::AudioDeviceWindowsCore::InitRecording() Line 2236  C++
    mrwebrtc.dll!webrtc::AudioDeviceModuleImpl::InitRecording() Line 768    C++
    mrwebrtc.dll!webrtc::internal::AudioState::AddSendingStream(webrtc::AudioSendStream * stream, int sample_rate_hz, unsigned __int64 num_channels) Line 103   C++
    mrwebrtc.dll!webrtc::internal::AudioSendStream::Start() Line 392    C++
    mrwebrtc.dll!cricket::WebRtcVoiceMediaChannel::WebRtcAudioSendStream::UpdateSendState() Line 982    C++
    mrwebrtc.dll!cricket::WebRtcVoiceMediaChannel::WebRtcAudioSendStream::SetSource(cricket::AudioSource * source) Line 866 C++
    mrwebrtc.dll!cricket::WebRtcVoiceMediaChannel::SetLocalSource(unsigned int ssrc, cricket::AudioSource * source) Line 1944   C++
    mrwebrtc.dll!cricket::WebRtcVoiceMediaChannel::SetAudioSend(unsigned int ssrc, bool enable, const cricket::AudioOptions * options, cricket::AudioSource * source) Line 1779 C++

Note that additionally there's an uninitialized buffer access (security) issue in the message logging. FormatMessageW() returns messageLength == 0, which leaves errorText uninitialized, from which MAXERRORLENGTH characters are read and sent to RTC_LOG (which in our library is wired to a user callback so is trivially read back).