Chromium Code Reviews| Index: media/audio/win/core_audio_util_win.cc |
| diff --git a/media/audio/win/core_audio_util_win.cc b/media/audio/win/core_audio_util_win.cc |
| index 2c262b4e72d37026199881a3fdaae3ef37601964..ff59782c8a5c12f1e9924319904b3ba0cb25373b 100644 |
| --- a/media/audio/win/core_audio_util_win.cc |
| +++ b/media/audio/win/core_audio_util_win.cc |
| @@ -138,7 +138,7 @@ AUDCLNT_SHAREMODE CoreAudioUtil::GetShareMode() { |
| } |
| int CoreAudioUtil::NumberOfActiveDevices(EDataFlow data_flow) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| // Create the IMMDeviceEnumerator interface. |
| ScopedComPtr<IMMDeviceEnumerator> device_enumerator = |
| CreateDeviceEnumerator(); |
| @@ -166,7 +166,7 @@ int CoreAudioUtil::NumberOfActiveDevices(EDataFlow data_flow) { |
| } |
| ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IMMDeviceEnumerator> device_enumerator; |
| HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), |
| NULL, |
| @@ -181,7 +181,7 @@ ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() { |
| ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, |
| ERole role) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IMMDevice> endpoint_device; |
| // Create the IMMDeviceEnumerator interface. |
| @@ -216,7 +216,7 @@ ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, |
| ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDevice( |
| const std::string& device_id) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IMMDevice> endpoint_device; |
| // Create the IMMDeviceEnumerator interface. |
| @@ -235,7 +235,7 @@ ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDevice( |
| } |
| HRESULT CoreAudioUtil::GetDeviceName(IMMDevice* device, AudioDeviceName* name) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| // Retrieve unique name of endpoint device. |
| // Example: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}". |
| @@ -270,7 +270,7 @@ HRESULT CoreAudioUtil::GetDeviceName(IMMDevice* device, AudioDeviceName* name) { |
| } |
| std::string CoreAudioUtil::GetFriendlyName(const std::string& device_id) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IMMDevice> audio_device = CreateDevice(device_id); |
| if (!audio_device) |
| return std::string(); |
| @@ -286,7 +286,7 @@ std::string CoreAudioUtil::GetFriendlyName(const std::string& device_id) { |
| bool CoreAudioUtil::DeviceIsDefault(EDataFlow flow, |
| ERole role, |
| std::string device_id) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IMMDevice> device = CreateDefaultDevice(flow, role); |
| if (!device) |
| return false; |
| @@ -304,7 +304,7 @@ bool CoreAudioUtil::DeviceIsDefault(EDataFlow flow, |
| } |
| EDataFlow CoreAudioUtil::GetDataFlow(IMMDevice* device) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IMMEndpoint> endpoint; |
| HRESULT hr = device->QueryInterface(endpoint.Receive()); |
| if (FAILED(hr)) { |
| @@ -323,7 +323,7 @@ EDataFlow CoreAudioUtil::GetDataFlow(IMMDevice* device) { |
| ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient( |
| IMMDevice* audio_device) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| // Creates and activates an IAudioClient COM object given the selected |
| // endpoint device. |
| @@ -338,7 +338,7 @@ ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient( |
| ScopedComPtr<IAudioClient> CoreAudioUtil::CreateDefaultClient( |
| EDataFlow data_flow, ERole role) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IMMDevice> default_device(CreateDefaultDevice(data_flow, role)); |
| return (default_device ? CreateClient(default_device) : |
| ScopedComPtr<IAudioClient>()); |
| @@ -346,7 +346,7 @@ ScopedComPtr<IAudioClient> CoreAudioUtil::CreateDefaultClient( |
| HRESULT CoreAudioUtil::GetSharedModeMixFormat( |
| IAudioClient* client, WAVEFORMATPCMEX* format) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedCoMem<WAVEFORMATPCMEX> format_pcmex; |
| HRESULT hr = client->GetMixFormat( |
| reinterpret_cast<WAVEFORMATEX**>(&format_pcmex)); |
| @@ -371,10 +371,23 @@ HRESULT CoreAudioUtil::GetSharedModeMixFormat( |
| return hr; |
| } |
| +HRESULT CoreAudioUtil::GetDefaultSharedModeMixFormat( |
| + EDataFlow data_flow, ERole role, WAVEFORMATPCMEX* format) { |
|
tommi (sloooow) - chröme
2013/01/31 16:18:24
indent
henrika (OOO until Aug 14)
2013/02/01 10:55:56
Done.
|
| + DCHECK(IsSupported()); |
| + ScopedComPtr<IAudioClient> client; |
|
tommi (sloooow) - chröme
2013/01/31 16:18:24
pass CreateDefaultClient to the constructor
henrika (OOO until Aug 14)
2013/02/01 10:55:56
Done.
|
| + client = CreateDefaultClient(data_flow, role); |
| + if (!client) { |
| + // Map NULL-pointer to new error code which can be different from the |
| + // actual error code. The exact value is not important here. |
| + return AUDCLNT_E_ENDPOINT_CREATE_FAILED; |
| + } |
| + return CoreAudioUtil::GetSharedModeMixFormat(client, format); |
| +} |
| + |
| bool CoreAudioUtil::IsFormatSupported(IAudioClient* client, |
| AUDCLNT_SHAREMODE share_mode, |
| const WAVEFORMATPCMEX* format) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| ScopedCoMem<WAVEFORMATEXTENSIBLE> closest_match; |
| HRESULT hr = client->IsFormatSupported( |
| share_mode, reinterpret_cast<const WAVEFORMATEX*>(format), |
| @@ -398,7 +411,7 @@ bool CoreAudioUtil::IsFormatSupported(IAudioClient* client, |
| HRESULT CoreAudioUtil::GetDevicePeriod(IAudioClient* client, |
| AUDCLNT_SHAREMODE share_mode, |
| REFERENCE_TIME* device_period) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| // Get the period of the engine thread. |
| REFERENCE_TIME default_period = 0; |
| @@ -417,7 +430,7 @@ HRESULT CoreAudioUtil::GetDevicePeriod(IAudioClient* client, |
| HRESULT CoreAudioUtil::GetPreferredAudioParameters( |
| IAudioClient* client, AudioParameters* params) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| WAVEFORMATPCMEX format; |
| HRESULT hr = GetSharedModeMixFormat(client, &format); |
| if (FAILED(hr)) |
| @@ -468,8 +481,7 @@ HRESULT CoreAudioUtil::GetPreferredAudioParameters( |
| HRESULT CoreAudioUtil::GetPreferredAudioParameters( |
| EDataFlow data_flow, ERole role, AudioParameters* params) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| - |
| + DCHECK(IsSupported()); |
| ScopedComPtr<IAudioClient> client = CreateDefaultClient(data_flow, role); |
| if (!client) { |
| // Map NULL-pointer to new error code which can be different from the |
| @@ -483,8 +495,7 @@ HRESULT CoreAudioUtil::SharedModeInitialize(IAudioClient* client, |
| const WAVEFORMATPCMEX* format, |
| HANDLE event_handle, |
| size_t* endpoint_buffer_size) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| - |
| + DCHECK(IsSupported()); |
| DWORD stream_flags = AUDCLNT_STREAMFLAGS_NOPERSIST; |
| // Enable event-driven streaming if a valid event handle is provided. |
| @@ -538,7 +549,7 @@ HRESULT CoreAudioUtil::SharedModeInitialize(IAudioClient* client, |
| ScopedComPtr<IAudioRenderClient> CoreAudioUtil::CreateRenderClient( |
| IAudioClient* client) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| // Get access to the IAudioRenderClient interface. This interface |
| // enables us to write output data to a rendering endpoint buffer. |
| @@ -549,40 +560,12 @@ ScopedComPtr<IAudioRenderClient> CoreAudioUtil::CreateRenderClient( |
| DVLOG(1) << "IAudioClient::GetService: " << std::hex << hr; |
| return ScopedComPtr<IAudioRenderClient>(); |
| } |
| - |
| - // TODO(henrika): verify that this scheme is the same for shared mode and |
| - // exclusive mode streams. |
| - |
| - // Avoid start-up glitches by filling up the endpoint buffer with "silence" |
| - // before starting the stream. |
| - UINT32 endpoint_buffer_size = 0; |
| - hr = client->GetBufferSize(&endpoint_buffer_size); |
| - DVLOG_IF(1, FAILED(hr)) << "IAudioClient::GetBufferSize: " << std::hex << hr; |
| - |
| - BYTE* data = NULL; |
| - hr = audio_render_client->GetBuffer(endpoint_buffer_size, &data); |
| - DVLOG_IF(1, FAILED(hr)) << "IAudioRenderClient::GetBuffer: " |
| - << std::hex << hr; |
| - if (SUCCEEDED(hr)) { |
| - // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to |
| - // explicitly write silence data to the rendering buffer. |
| - hr = audio_render_client->ReleaseBuffer(endpoint_buffer_size, |
| - AUDCLNT_BUFFERFLAGS_SILENT); |
| - DVLOG_IF(1, FAILED(hr)) << "IAudioRenderClient::ReleaseBuffer: " |
| - << std::hex << hr; |
| - } |
| - |
| - // Sanity check: verify that the endpoint buffer is filled with silence. |
| - UINT32 num_queued_frames = 0; |
| - client->GetCurrentPadding(&num_queued_frames); |
| - DCHECK(num_queued_frames == endpoint_buffer_size); |
| - |
| return audio_render_client; |
| } |
| ScopedComPtr<IAudioCaptureClient> CoreAudioUtil::CreateCaptureClient( |
| IAudioClient* client) { |
| - DCHECK(CoreAudioUtil::IsSupported()); |
| + DCHECK(IsSupported()); |
| // Get access to the IAudioCaptureClient interface. This interface |
| // enables us to read input data from a capturing endpoint buffer. |
| @@ -596,4 +579,30 @@ ScopedComPtr<IAudioCaptureClient> CoreAudioUtil::CreateCaptureClient( |
| return audio_capture_client; |
| } |
| +bool CoreAudioUtil::FillRenderEndpointBufferWithSilence( |
| + IAudioClient* client, IAudioRenderClient* render_client) { |
| + DCHECK(IsSupported()); |
| + |
| + UINT32 endpoint_buffer_size = 0; |
| + if (FAILED(client->GetBufferSize(&endpoint_buffer_size))) |
| + return false; |
| + |
| + UINT32 num_queued_frames = 0; |
| + if (FAILED(client->GetCurrentPadding(&num_queued_frames))) |
| + return false; |
| + |
| + BYTE* data = NULL; |
| + int num_frames_to_fill = endpoint_buffer_size - num_queued_frames; |
| + if (FAILED(render_client->GetBuffer(num_frames_to_fill, &data))) |
| + return false; |
| + |
| + // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to |
| + // explicitly write silence data to the rendering buffer. |
| + DVLOG(2) << "filling up " << num_frames_to_fill << " frames with silence"; |
| + if (FAILED(render_client->ReleaseBuffer(num_frames_to_fill, |
|
tommi (sloooow) - chröme
2013/01/31 16:18:24
return SUCCEEDED(render_client->ReleaseBuffer(...)
henrika (OOO until Aug 14)
2013/02/01 10:55:56
Done.
|
| + AUDCLNT_BUFFERFLAGS_SILENT))) |
| + return false; |
| + return true; |
| +} |
| + |
| } // namespace media |