summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_wasapi_utils.c
diff options
context:
space:
mode:
authorsunpenghao <sunpenghao1997@outlook.com>2024-04-01 17:20:47 +0800
committerKacper Michajłow <kasper93@gmail.com>2024-04-19 02:28:23 +0200
commit503a0f184ca5b12acb355f3b3cf96ca0a5cda200 (patch)
treef471e2262745a95b4510debcc01c45f8ae006e82 /audio/out/ao_wasapi_utils.c
parente5d683e187d1e67fcfc944769a7c31cfcc2d0491 (diff)
downloadmpv-503a0f184ca5b12acb355f3b3cf96ca0a5cda200.tar.bz2
mpv-503a0f184ca5b12acb355f3b3cf96ca0a5cda200.tar.xz
ao_wasapi: add `--wasapi-exclusive-buffer` option
This allows users to set buffer duration in exclusive mode. We have been using the default device period as the buffer size and it is robust enough in most cases. However, on some devices there are horrible glitches after a stream reset. Unfortunately, the issue is not consistently reproducible, but using a smaller buffer size (e.g., the minimum device period) seems to resolve the problem. Fixes #13715.
Diffstat (limited to 'audio/out/ao_wasapi_utils.c')
-rw-r--r--audio/out/ao_wasapi_utils.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index 7e85f75eab..8ff6523303 100644
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -640,16 +640,25 @@ static HRESULT fix_format(struct ao *ao, bool align_hack)
struct wasapi_state *state = ao->priv;
MP_DBG(state, "IAudioClient::GetDevicePeriod\n");
- REFERENCE_TIME devicePeriod;
- HRESULT hr = IAudioClient_GetDevicePeriod(state->pAudioClient,&devicePeriod,
- NULL);
- MP_VERBOSE(state, "Device period: %.2g ms\n",
- (double) devicePeriod / 10000.0 );
+ REFERENCE_TIME defaultPeriod, minPeriod;
+ HRESULT hr = IAudioClient_GetDevicePeriod(state->pAudioClient,&defaultPeriod,
+ &minPeriod);
+ MP_VERBOSE(state, "Device period: default %lld us, minimum %lld us\n",
+ defaultPeriod / 10, minPeriod / 10);
- REFERENCE_TIME bufferDuration = devicePeriod;
+ REFERENCE_TIME bufferDuration;
if (state->share_mode == AUDCLNT_SHAREMODE_SHARED) {
// for shared mode, use integer multiple of device period close to 50ms
- bufferDuration = devicePeriod * ceil(50.0 * 10000.0 / devicePeriod);
+ bufferDuration = defaultPeriod * ceil(50.0 * 10000.0 / defaultPeriod);
+ } else if (state->opt_exclusive_buffer == 0) {
+ bufferDuration = defaultPeriod;
+ } else {
+ if (state->opt_exclusive_buffer > 0 && !align_hack) {
+ MP_VERBOSE(state, "Requested buffer duration: %d us\n",
+ state->opt_exclusive_buffer);
+ }
+ bufferDuration = MPMAX((REFERENCE_TIME) state->opt_exclusive_buffer * 10,
+ minPeriod);
}
// handle unsupported buffer size if AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED was
@@ -662,6 +671,8 @@ static HRESULT fix_format(struct ao *ao, bool align_hack)
* state->bufferFrameCount));
}
+ MP_VERBOSE(state, "Trying buffer duration %lld us\n", bufferDuration / 10);
+
REFERENCE_TIME bufferPeriod =
state->share_mode == AUDCLNT_SHAREMODE_EXCLUSIVE ? bufferDuration : 0;
@@ -694,8 +705,8 @@ static HRESULT fix_format(struct ao *ao, bool align_hack)
bufferDuration = (REFERENCE_TIME) (0.5 +
(10000.0 * 1000 / state->format.Format.nSamplesPerSec
* state->bufferFrameCount));
- MP_VERBOSE(state, "Buffer frame count: %"PRIu32" (%.2g ms)\n",
- state->bufferFrameCount, (double) bufferDuration / 10000.0 );
+ MP_VERBOSE(state, "Buffer frame count: %"PRIu32" (%lld us)\n",
+ state->bufferFrameCount, bufferDuration / 10);
hr = init_clock(state);
EXIT_ON_ERROR(hr);