summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_wasapi.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 20:36:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 20:36:56 +0000
commit51de1d8436100f725f3576aefa24a2bd2057bc28 (patch)
treec6d1d5264b6d40a8d7ca34129f36b7d61e188af3 /audio/out/ao_wasapi.h
parentInitial commit. (diff)
downloadmpv-51de1d8436100f725f3576aefa24a2bd2057bc28.tar.xz
mpv-51de1d8436100f725f3576aefa24a2bd2057bc28.zip
Adding upstream version 0.37.0.upstream/0.37.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'audio/out/ao_wasapi.h')
-rw-r--r--audio/out/ao_wasapi.h116
1 files changed, 116 insertions, 0 deletions
diff --git a/audio/out/ao_wasapi.h b/audio/out/ao_wasapi.h
new file mode 100644
index 0000000..17b8f7a
--- /dev/null
+++ b/audio/out/ao_wasapi.h
@@ -0,0 +1,116 @@
+/*
+ * This file is part of mpv.
+ *
+ * Original author: Jonathan Yong <10walls@gmail.com>
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MP_AO_WASAPI_H_
+#define MP_AO_WASAPI_H_
+
+#include <stdatomic.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <windows.h>
+#include <mmdeviceapi.h>
+#include <audioclient.h>
+#include <audiopolicy.h>
+#include <endpointvolume.h>
+
+#include "common/msg.h"
+#include "osdep/windows_utils.h"
+#include "internal.h"
+#include "ao.h"
+
+typedef struct change_notify {
+ IMMNotificationClient client; // this must be first in the structure!
+ IMMDeviceEnumerator *pEnumerator; // object where client is registered
+ LPWSTR monitored; // Monitored device
+ bool is_hotplug;
+ struct ao *ao;
+} change_notify;
+
+HRESULT wasapi_change_init(struct ao* ao, bool is_hotplug);
+void wasapi_change_uninit(struct ao* ao);
+
+enum wasapi_thread_state {
+ WASAPI_THREAD_FEED = 0,
+ WASAPI_THREAD_RESUME,
+ WASAPI_THREAD_RESET,
+ WASAPI_THREAD_SHUTDOWN
+};
+
+typedef struct wasapi_state {
+ struct mp_log *log;
+
+ bool init_ok; // status of init phase
+ // Thread handles
+ HANDLE hInitDone; // set when init is complete in audio thread
+ HANDLE hAudioThread; // the audio thread itself
+ HANDLE hWake; // thread wakeup event
+ atomic_int thread_state; // enum wasapi_thread_state (what to do on wakeup)
+ struct mp_dispatch_queue *dispatch; // for volume/mute/session display
+
+ // for setting the audio thread priority
+ HANDLE hTask;
+
+ // ID of the device to use
+ LPWSTR deviceID;
+ // WASAPI object handles owned and used by audio thread
+ IMMDevice *pDevice;
+ IAudioClient *pAudioClient;
+ IAudioRenderClient *pRenderClient;
+
+ // WASAPI internal clock information, for estimating delay
+ IAudioClock *pAudioClock;
+ atomic_ullong sample_count; // samples per channel written by GetBuffer
+ UINT64 clock_frequency; // scale for position returned by GetPosition
+ LARGE_INTEGER qpc_frequency; // frequency of Windows' high resolution timer
+
+ // WASAPI control
+ IAudioSessionControl *pSessionControl; // setting the stream title
+ IAudioEndpointVolume *pEndpointVolume; // exclusive mode volume/mute
+ ISimpleAudioVolume *pAudioVolume; // shared mode volume/mute
+ DWORD vol_hw_support; // is hardware volume supported for exclusive-mode?
+
+ // ao options
+ int opt_exclusive;
+
+ // format info
+ WAVEFORMATEXTENSIBLE format;
+ AUDCLNT_SHAREMODE share_mode; // AUDCLNT_SHAREMODE_EXCLUSIVE / SHARED
+ UINT32 bufferFrameCount; // number of frames in buffer
+ struct ao_convert_fmt convert_format;
+
+ change_notify change;
+} wasapi_state;
+
+char *mp_PKEY_to_str_buf(char *buf, size_t buf_size, const PROPERTYKEY *pkey);
+#define mp_PKEY_to_str(pkey) mp_PKEY_to_str_buf((char[42]){0}, 42, (pkey))
+
+void wasapi_list_devs(struct ao *ao, struct ao_device_list *list);
+bstr wasapi_get_specified_device_string(struct ao *ao);
+LPWSTR wasapi_find_deviceID(struct ao *ao);
+
+bool wasapi_thread_init(struct ao *ao);
+void wasapi_thread_uninit(struct ao *ao);
+
+#define EXIT_ON_ERROR(hres) \
+ do { if (FAILED(hres)) { goto exit_label; } } while(0)
+#define SAFE_DESTROY(unk, release) \
+ do { if ((unk) != NULL) { release; (unk) = NULL; } } while(0)
+
+#endif