mirror of
https://github.com/mpv-player/mpv
synced 2024-12-11 17:37:23 +00:00
8e7cf4bc99
In my opinion, we shouldn't use atomics at all, but ok. This switches the mpv code to use C11 stdatomic.h, and for compilers that don't support stdatomic.h yet, we emulate the subset used by mpv using the builtins commonly provided by gcc and clang. This supersedes an earlier similar attempt by Kovensky. That attempt unfortunately relied on a big copypasted freebsd header (which also depended on much more highly compiler-specific functionality, defined reserved symbols, etc.), so it had to be NIH'ed. Some issues: - C11 says default initialization of atomics "produces a valid state", but it's not sure whether the stored value is really 0. But we rely on this. - I'm pretty sure our use of the __atomic... builtins is/was incorrect. We don't use atomic load/store intrinsics, and access stuff directly. - Our wrapper actually does stricter typechecking than the stdatomic.h implementation by gcc 4.9. We make the atomic types incompatible with normal types by wrapping them into structs. (The FreeBSD wrapper does the same.) - I couldn't test on MinGW.
106 lines
3.6 KiB
C
Executable File
106 lines
3.6 KiB
C
Executable File
/*
|
|
* 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 General Public License as published by
|
|
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef MP_AO_WASAPI_H_
|
|
#define MP_AO_WASAPI_H_
|
|
|
|
#define COBJMACROS 1
|
|
#define _WIN32_WINNT 0x600
|
|
|
|
#include <audioclient.h>
|
|
#include <audiopolicy.h>
|
|
#include <mmdeviceapi.h>
|
|
#include <avrt.h>
|
|
|
|
#include "compat/atomics.h"
|
|
|
|
typedef struct wasapi_state {
|
|
struct mp_log *log;
|
|
HANDLE threadLoop;
|
|
|
|
/* Init phase */
|
|
int init_ret;
|
|
HANDLE init_done;
|
|
int share_mode;
|
|
|
|
HANDLE hUninit;
|
|
|
|
/* volume control */
|
|
DWORD vol_hw_support, status;
|
|
float audio_volume;
|
|
float previous_volume;
|
|
float initial_volume;
|
|
|
|
/* Buffers */
|
|
size_t buffer_block_size; /* Size of each block in bytes */
|
|
REFERENCE_TIME
|
|
minRequestedDuration; /* minimum wasapi buffer block size, in 100-nanosecond units */
|
|
REFERENCE_TIME
|
|
defaultRequestedDuration; /* default wasapi default block size, in 100-nanosecond units */
|
|
UINT32 bufferFrameCount; /* wasapi buffer block size, number of frames, frame size at format.nBlockAlign */
|
|
|
|
/* WASAPI handles, owned by other thread */
|
|
IMMDevice *pDevice;
|
|
IAudioClient *pAudioClient;
|
|
IAudioRenderClient *pRenderClient;
|
|
ISimpleAudioVolume *pAudioVolume;
|
|
IAudioEndpointVolume *pEndpointVolume;
|
|
IAudioSessionControl *pSessionControl;
|
|
HANDLE hFeed; /* wasapi event */
|
|
HANDLE hForceFeed; /* forces writing a buffer (e.g. before audio_resume) */
|
|
HANDLE hFeedDone; /* set only after a hForceFeed */
|
|
HANDLE hTask; /* AV thread */
|
|
DWORD taskIndex; /* AV task ID */
|
|
WAVEFORMATEXTENSIBLE format;
|
|
|
|
/* WASAPI proxy handles, for Single-Threaded Apartment communication.
|
|
One is needed for each object that's accessed by a different thread. */
|
|
IAudioClient *pAudioClientProxy;
|
|
ISimpleAudioVolume *pAudioVolumeProxy;
|
|
IAudioEndpointVolume *pEndpointVolumeProxy;
|
|
IAudioSessionControl *pSessionControlProxy;
|
|
|
|
/* Streams used to marshal the proxy objects. The thread owning the actual objects
|
|
needs to marshal proxy objects into these streams, and the thread that wants the
|
|
proxies unmarshals them from here. */
|
|
IStream *sAudioClient;
|
|
IStream *sAudioVolume;
|
|
IStream *sEndpointVolume;
|
|
IStream *sSessionControl;
|
|
|
|
/* WASAPI internal clock information, for estimating delay */
|
|
IAudioClock *pAudioClock;
|
|
UINT64 clock_frequency; /* scale for the "samples" returned by the clock */
|
|
atomic_ullong sample_count; /* the amount of samples per channel written to a GetBuffer buffer */
|
|
LARGE_INTEGER qpc_frequency; /* frequency of windows' high resolution timer */
|
|
|
|
int opt_exclusive;
|
|
int opt_list;
|
|
char *opt_device;
|
|
|
|
/* We still need to support XP, don't use these functions directly, blob owned by main thread */
|
|
struct {
|
|
HMODULE hAvrt;
|
|
HANDLE (WINAPI *pAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
|
|
WINBOOL (WINAPI *pAvRevertMmThreadCharacteristics)(HANDLE);
|
|
} VistaBlob;
|
|
} wasapi_state;
|
|
|
|
#endif
|