From 4bf9c0b123665a61315d3e7160f8bc48e34dc1b9 Mon Sep 17 00:00:00 2001 From: "henrika@google.com" Date: Thu, 23 Jun 2011 09:44:59 +0000 Subject: [PATCH] Adds sanity checks related to IAudioCaptureClient::GetBuffer. Review URL: http://webrtc-codereview.appspot.com/45006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@120 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../Windows/audio_device_windows_core.cc | 49 ++++++++++++++++--- .../Windows/audio_device_windows_core.h | 14 ++++-- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/modules/audio_device/main/source/Windows/audio_device_windows_core.cc b/modules/audio_device/main/source/Windows/audio_device_windows_core.cc index 3b1ae1591..37c791161 100644 --- a/modules/audio_device/main/source/Windows/audio_device_windows_core.cc +++ b/modules/audio_device/main/source/Windows/audio_device_windows_core.cc @@ -3602,12 +3602,12 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread() // Find out how much capture data is available // - hr = _ptrCaptureClient->GetBuffer( - &pData, // packet which is ready to be read by used - &framesAvailable, // #frames in the captured packet (can be zero) - &flags, // support flags (check) - &recPos, // device position of first audio frame in data packet - &recTime); // value of performance counter at the time of recording the first audio frame + hr = _ptrCaptureClient->GetBuffer(&pData, // packet which is ready to be read by used + &framesAvailable, // #frames in the captured packet (can be zero) + &flags, // support flags (check) + &recPos, // device position of first audio frame in data packet + &recTime); // value of performance counter at the time of recording the first audio frame + if (SUCCEEDED(hr)) { if (AUDCLNT_S_BUFFER_EMPTY == hr) @@ -3619,12 +3619,21 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread() if (flags & AUDCLNT_BUFFERFLAGS_SILENT) { + // Treat all of the data in the packet as silence and ignore the actual data values. WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "AUDCLNT_BUFFERFLAGS_SILENT"); + pData = NULL; } assert(framesAvailable != 0); - CopyMemory(&syncBuffer[syncBufIndex*_recAudioFrameSize], pData, framesAvailable*_recAudioFrameSize); + if (pData) + { + CopyMemory(&syncBuffer[syncBufIndex*_recAudioFrameSize], pData, framesAvailable*_recAudioFrameSize); + } + else + { + ZeroMemory(&syncBuffer[syncBufIndex*_recAudioFrameSize], framesAvailable*_recAudioFrameSize); + } assert(syncBufferSize >= (syncBufIndex*_recAudioFrameSize)+framesAvailable*_recAudioFrameSize); // Release the capture buffer @@ -3724,6 +3733,8 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread() // of the failed GetBuffer calls. If GetBuffer returns this error repeatedly, the client // can start a new processing loop after shutting down the current client by calling // IAudioClient::Stop, IAudioClient::Reset, and releasing the audio client. + WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, + "IAudioCaptureClient::GetBuffer returned AUDCLNT_E_BUFFER_ERROR, hr = 0x%08X", hr); goto Exit; } @@ -4385,7 +4396,7 @@ void AudioDeviceWindowsCore::_TraceCOMError(HRESULT hr) const WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "Core Audio method failed (hr=0x%x)", hr); StringCchPrintf(buf, MAXERRORLENGTH, TEXT("Error details: ")); StringCchCat(buf, MAXERRORLENGTH, errorText); - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", buf); + WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", WideToUTF8(buf)); } // ---------------------------------------------------------------------------- @@ -4435,6 +4446,28 @@ void AudioDeviceWindowsCore::_Get44kHzDrift() } } +// ---------------------------------------------------------------------------- +// WideToUTF8 +// ---------------------------------------------------------------------------- + +char* AudioDeviceWindowsCore::WideToUTF8(const TCHAR* src) const { +#ifdef UNICODE + const size_t kStrLen = sizeof(_str); + memset(_str, 0, kStrLen); + // Get required size (in bytes) to be able to complete the conversion. + int required_size = WideCharToMultiByte(CP_UTF8, 0, src, -1, _str, 0, 0, 0); + if (required_size <= kStrLen) + { + // Process the entire input string, including the terminating null char. + if (WideCharToMultiByte(CP_UTF8, 0, src, -1, _str, kStrLen, 0, 0) == 0) + memset(_str, 0, kStrLen); + } + return _str; +#else + return const_cast(src); +#endif +} + } // namespace webrtc #endif // WEBRTC_WINDOWS_CORE_AUDIO_BUILD diff --git a/modules/audio_device/main/source/Windows/audio_device_windows_core.h b/modules/audio_device/main/source/Windows/audio_device_windows_core.h index 3e1416898..8f9f6fbeb 100644 --- a/modules/audio_device/main/source/Windows/audio_device_windows_core.h +++ b/modules/audio_device/main/source/Windows/audio_device_windows_core.h @@ -162,11 +162,11 @@ public: virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); private: // avrt function pointers - PAvRevertMmThreadCharacteristics _PAvRevertMmThreadCharacteristics; - PAvSetMmThreadCharacteristicsA _PAvSetMmThreadCharacteristicsA; - PAvSetMmThreadPriority _PAvSetMmThreadPriority; + PAvRevertMmThreadCharacteristics _PAvRevertMmThreadCharacteristics; + PAvSetMmThreadCharacteristicsA _PAvSetMmThreadCharacteristicsA; + PAvSetMmThreadPriority _PAvSetMmThreadPriority; HMODULE _avrtLibrary; - bool _winSupportAvrt; + bool _winSupportAvrt; private: // thread functions static DWORD WINAPI WSAPICaptureThread(LPVOID context); @@ -205,6 +205,10 @@ private: void _Get44kHzDrift(); + // Converts from wide-char to UTF-8 if UNICODE is defined. + // Does nothing if UNICODE is undefined. + char* WideToUTF8(const TCHAR* src) const; + private: AudioDeviceBuffer* _ptrAudioBuffer; CriticalSectionWrapper& _critSect; @@ -297,6 +301,8 @@ private: WebRtc_UWord16 _playBufDelayFixed; WebRtc_UWord16 _newMicLevel; + + mutable char _str[512]; }; #endif // #if (_MSC_VER >= 1400)