Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Unified Diff: media/audio/win/core_audio_util_win.cc

Issue 12049070: Avoids irregular OnMoreData callbacks on Windows using Core Audio (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed audio glitch at startup Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..efa796ae0c602a851a5660c2bdb77f12d63a1c4f 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,22 @@ HRESULT CoreAudioUtil::GetSharedModeMixFormat(
return hr;
}
+HRESULT CoreAudioUtil::GetDefaultSharedModeMixFormat(
+ EDataFlow data_flow, ERole role, WAVEFORMATPCMEX* format) {
+ DCHECK(IsSupported());
+ ScopedComPtr<IAudioClient> 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 +410,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 +429,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,9 +480,8 @@ HRESULT CoreAudioUtil::GetPreferredAudioParameters(
HRESULT CoreAudioUtil::GetPreferredAudioParameters(
EDataFlow data_flow, ERole role, AudioParameters* params) {
- DCHECK(CoreAudioUtil::IsSupported());
-
- ScopedComPtr<IAudioClient> client = CreateDefaultClient(data_flow, role);
+ DCHECK(IsSupported());
+ ScopedComPtr<IAudioClient> 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.
@@ -483,8 +494,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 +548,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 +559,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 +578,28 @@ 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";
+ return SUCCEEDED(render_client->ReleaseBuffer(num_frames_to_fill,
+ AUDCLNT_BUFFERFLAGS_SILENT));
+}
+
} // namespace media

Powered by Google App Engine
This is Rietveld 408576698