New upstream version 24.0.1+dfsg1

This commit is contained in:
Sebastian Ramacher 2019-09-22 23:19:10 +02:00
parent b14f9eae6d
commit 5a730d6ec3
842 changed files with 42245 additions and 33385 deletions

View file

@ -10,10 +10,22 @@
#undef DEFINE_PROPERTYKEY
#endif
#define DEFINE_PROPERTYKEY(id, a, b, c, d, e, f, g, h, i, j, k, l) \
const PROPERTYKEY id = { { a,b,c, { d,e,f,g,h,i,j,k, } }, l };
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, \
0xa45c254e, 0xdf1c, 0x4efd, 0x80, \
0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
const PROPERTYKEY id = {{a, \
b, \
c, \
{ \
d, \
e, \
f, \
g, \
h, \
i, \
j, \
k, \
}}, \
l};
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,
0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
#else
@ -22,7 +34,7 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, \
#endif
static bool get_device_info(obs_enum_audio_device_cb cb, void *data,
IMMDeviceCollection *collection, UINT idx)
IMMDeviceCollection *collection, UINT idx)
{
IPropertyStore *store = NULL;
IMMDevice *device = NULL;
@ -50,7 +62,7 @@ static bool get_device_info(obs_enum_audio_device_cb cb, void *data,
PropVariantInit(&name_var);
hr = store->lpVtbl->GetValue(store, &PKEY_Device_FriendlyName,
&name_var);
&name_var);
if (FAILED(hr)) {
goto fail;
}
@ -68,8 +80,7 @@ fail:
return cont;
}
void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb,
void *data)
void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data)
{
IMMDeviceEnumerator *enumerator = NULL;
IMMDeviceCollection *collection = NULL;
@ -77,13 +88,13 @@ void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb,
HRESULT hr;
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
&IID_IMMDeviceEnumerator, &enumerator);
&IID_IMMDeviceEnumerator, &enumerator);
if (FAILED(hr)) {
goto fail;
}
hr = enumerator->lpVtbl->EnumAudioEndpoints(enumerator, eRender,
DEVICE_STATE_ACTIVE, &collection);
hr = enumerator->lpVtbl->EnumAudioEndpoints(
enumerator, eRender, DEVICE_STATE_ACTIVE, &collection);
if (FAILED(hr)) {
goto fail;
}
@ -115,13 +126,13 @@ static void get_default_id(char **p_id)
return;
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
&IID_IMMDeviceEnumerator, &immde);
&IID_IMMDeviceEnumerator, &immde);
if (FAILED(hr)) {
goto fail;
}
hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde,
eRender, eConsole, &device);
hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde, eRender, eConsole,
&device);
if (FAILED(hr)) {
goto fail;
}

View file

@ -7,49 +7,45 @@
#include "wasapi-output.h"
#define ACTUALLY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID DECLSPEC_SELECTANY name \
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
EXTERN_C const GUID DECLSPEC_SELECTANY name = { \
l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}
ACTUALLY_DEFINE_GUID(CLSID_MMDeviceEnumerator,
0xBCDE0395, 0xE52F, 0x467C,
0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
ACTUALLY_DEFINE_GUID(IID_IMMDeviceEnumerator,
0xA95664D2, 0x9614, 0x4F35,
0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
ACTUALLY_DEFINE_GUID(IID_IAudioClient,
0x1CB9AD4C, 0xDBFA, 0x4C32,
0xB1, 0x78, 0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2);
ACTUALLY_DEFINE_GUID(IID_IAudioRenderClient,
0xF294ACFC, 0x3146, 0x4483,
0xA7, 0xBF, 0xAD, 0xDC, 0xA7, 0xC2, 0x60, 0xE2);
ACTUALLY_DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E,
0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
ACTUALLY_DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35, 0xA7,
0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
ACTUALLY_DEFINE_GUID(IID_IAudioClient, 0x1CB9AD4C, 0xDBFA, 0x4C32, 0xB1, 0x78,
0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2);
ACTUALLY_DEFINE_GUID(IID_IAudioRenderClient, 0xF294ACFC, 0x3146, 0x4483, 0xA7,
0xBF, 0xAD, 0xDC, 0xA7, 0xC2, 0x60, 0xE2);
struct audio_monitor {
obs_source_t *source;
IMMDevice *device;
IAudioClient *client;
obs_source_t *source;
IMMDevice *device;
IAudioClient *client;
IAudioRenderClient *render;
uint64_t last_recv_time;
uint64_t prev_video_ts;
uint64_t time_since_prev;
audio_resampler_t *resampler;
uint32_t sample_rate;
uint32_t channels;
bool source_has_video;
bool ignore;
uint64_t last_recv_time;
uint64_t prev_video_ts;
uint64_t time_since_prev;
audio_resampler_t *resampler;
uint32_t sample_rate;
uint32_t channels;
bool source_has_video;
bool ignore;
int64_t lowest_audio_offset;
struct circlebuf delay_buffer;
uint32_t delay_size;
int64_t lowest_audio_offset;
struct circlebuf delay_buffer;
uint32_t delay_size;
DARRAY(float) buf;
pthread_mutex_t playback_mutex;
DARRAY(float) buf;
pthread_mutex_t playback_mutex;
};
/* #define DEBUG_AUDIO */
static bool process_audio_delay(struct audio_monitor *monitor,
float **data, uint32_t *frames, uint64_t ts, uint32_t pad)
static bool process_audio_delay(struct audio_monitor *monitor, float **data,
uint32_t *frames, uint64_t ts, uint32_t pad)
{
obs_source_t *s = monitor->source;
uint64_t last_frame_ts = s->last_frame_ts;
@ -68,15 +64,14 @@ static bool process_audio_delay(struct audio_monitor *monitor,
circlebuf_push_back(&monitor->delay_buffer, &ts, sizeof(ts));
circlebuf_push_back(&monitor->delay_buffer, frames, sizeof(*frames));
circlebuf_push_back(&monitor->delay_buffer, *data,
*frames * blocksize);
circlebuf_push_back(&monitor->delay_buffer, *data, *frames * blocksize);
if (!monitor->prev_video_ts) {
monitor->prev_video_ts = last_frame_ts;
} else if (monitor->prev_video_ts == last_frame_ts) {
monitor->time_since_prev += (uint64_t)*frames *
1000000000ULL / (uint64_t)monitor->sample_rate;
monitor->time_since_prev += (uint64_t)*frames * 1000000000ULL /
(uint64_t)monitor->sample_rate;
} else {
monitor->time_since_prev = 0;
}
@ -86,44 +81,45 @@ static bool process_audio_delay(struct audio_monitor *monitor,
bool bad_diff;
circlebuf_peek_front(&monitor->delay_buffer, &cur_ts,
sizeof(ts));
front_ts = cur_ts -
((uint64_t)pad * 1000000000ULL /
(uint64_t)monitor->sample_rate);
sizeof(ts));
front_ts = cur_ts - ((uint64_t)pad * 1000000000ULL /
(uint64_t)monitor->sample_rate);
diff = (int64_t)front_ts - (int64_t)last_frame_ts;
bad_diff = !last_frame_ts ||
llabs(diff) > 5000000000 ||
monitor->time_since_prev > 100000000ULL;
bad_diff = !last_frame_ts || llabs(diff) > 5000000000 ||
monitor->time_since_prev > 100000000ULL;
/* delay audio if rushing */
if (!bad_diff && diff > 75000000) {
#ifdef DEBUG_AUDIO
blog(LOG_INFO, "audio rushing, cutting audio, "
"diff: %lld, delay buffer size: %lu, "
"v: %llu: a: %llu",
diff, (int)monitor->delay_buffer.size,
last_frame_ts, front_ts);
blog(LOG_INFO,
"audio rushing, cutting audio, "
"diff: %lld, delay buffer size: %lu, "
"v: %llu: a: %llu",
diff, (int)monitor->delay_buffer.size,
last_frame_ts, front_ts);
#endif
return false;
}
circlebuf_pop_front(&monitor->delay_buffer, NULL, sizeof(ts));
circlebuf_pop_front(&monitor->delay_buffer, frames,
sizeof(*frames));
sizeof(*frames));
size = *frames * blocksize;
da_resize(monitor->buf, size);
circlebuf_pop_front(&monitor->delay_buffer,
monitor->buf.array, size);
circlebuf_pop_front(&monitor->delay_buffer, monitor->buf.array,
size);
/* cut audio if dragging */
if (!bad_diff && diff < -75000000 && monitor->delay_buffer.size > 0) {
if (!bad_diff && diff < -75000000 &&
monitor->delay_buffer.size > 0) {
#ifdef DEBUG_AUDIO
blog(LOG_INFO, "audio dragging, cutting audio, "
"diff: %lld, delay buffer size: %lu, "
"v: %llu: a: %llu",
diff, (int)monitor->delay_buffer.size,
last_frame_ts, front_ts);
blog(LOG_INFO,
"audio dragging, cutting audio, "
"diff: %lld, delay buffer size: %lu, "
"v: %llu: a: %llu",
diff, (int)monitor->delay_buffer.size,
last_frame_ts, front_ts);
#endif
continue;
}
@ -136,7 +132,7 @@ static bool process_audio_delay(struct audio_monitor *monitor,
}
static void on_audio_playback(void *param, obs_source_t *source,
const struct audio_data *audio_data, bool muted)
const struct audio_data *audio_data, bool muted)
{
struct audio_monitor *monitor = param;
IAudioRenderClient *render = monitor->render;
@ -154,10 +150,10 @@ static void on_audio_playback(void *param, obs_source_t *source,
goto unlock;
}
success = audio_resampler_resample(monitor->resampler, resample_data,
&resample_frames, &ts_offset,
(const uint8_t *const *)audio_data->data,
(uint32_t)audio_data->frames);
success = audio_resampler_resample(
monitor->resampler, resample_data, &resample_frames, &ts_offset,
(const uint8_t *const *)audio_data->data,
(uint32_t)audio_data->frames);
if (!success) {
goto unlock;
}
@ -165,20 +161,20 @@ static void on_audio_playback(void *param, obs_source_t *source,
UINT32 pad = 0;
monitor->client->lpVtbl->GetCurrentPadding(monitor->client, &pad);
bool decouple_audio =
source->async_unbuffered && source->async_decoupled;
bool decouple_audio = source->async_unbuffered &&
source->async_decoupled;
if (monitor->source_has_video && !decouple_audio) {
uint64_t ts = audio_data->timestamp - ts_offset;
if (!process_audio_delay(monitor, (float**)(&resample_data[0]),
&resample_frames, ts, pad)) {
if (!process_audio_delay(monitor, (float **)(&resample_data[0]),
&resample_frames, ts, pad)) {
goto unlock;
}
}
HRESULT hr = render->lpVtbl->GetBuffer(render, resample_frames,
&output);
HRESULT hr =
render->lpVtbl->GetBuffer(render, resample_frames, &output);
if (FAILED(hr)) {
goto unlock;
}
@ -186,20 +182,19 @@ static void on_audio_playback(void *param, obs_source_t *source,
if (!muted) {
/* apply volume */
if (!close_float(vol, 1.0f, EPSILON)) {
register float *cur = (float*)resample_data[0];
register float *end = cur +
resample_frames * monitor->channels;
register float *cur = (float *)resample_data[0];
register float *end =
cur + resample_frames * monitor->channels;
while (cur < end)
*(cur++) *= vol;
}
memcpy(output, resample_data[0],
resample_frames * monitor->channels *
sizeof(float));
resample_frames * monitor->channels * sizeof(float));
}
render->lpVtbl->ReleaseBuffer(render, resample_frames,
muted ? AUDCLNT_BUFFERFLAGS_SILENT : 0);
muted ? AUDCLNT_BUFFERFLAGS_SILENT : 0);
unlock:
pthread_mutex_unlock(&monitor->playback_mutex);
@ -212,7 +207,7 @@ static inline void audio_monitor_free(struct audio_monitor *monitor)
if (monitor->source) {
obs_source_remove_audio_capture_callback(
monitor->source, on_audio_playback, monitor);
monitor->source, on_audio_playback, monitor);
}
if (monitor->client)
@ -229,11 +224,16 @@ static inline void audio_monitor_free(struct audio_monitor *monitor)
static enum speaker_layout convert_speaker_layout(DWORD layout, WORD channels)
{
switch (layout) {
case KSAUDIO_SPEAKER_2POINT1: return SPEAKERS_2POINT1;
case KSAUDIO_SPEAKER_SURROUND: return SPEAKERS_4POINT0;
case KSAUDIO_SPEAKER_4POINT1: return SPEAKERS_4POINT1;
case KSAUDIO_SPEAKER_5POINT1: return SPEAKERS_5POINT1;
case KSAUDIO_SPEAKER_7POINT1: return SPEAKERS_7POINT1;
case KSAUDIO_SPEAKER_2POINT1:
return SPEAKERS_2POINT1;
case KSAUDIO_SPEAKER_SURROUND:
return SPEAKERS_4POINT0;
case KSAUDIO_SPEAKER_4POINT1:
return SPEAKERS_4POINT1;
case KSAUDIO_SPEAKER_5POINT1:
return SPEAKERS_5POINT1;
case KSAUDIO_SPEAKER_7POINT1:
return SPEAKERS_7POINT1;
}
return (enum speaker_layout)channels;
@ -242,7 +242,7 @@ static enum speaker_layout convert_speaker_layout(DWORD layout, WORD channels)
extern bool devices_match(const char *id1, const char *id2);
static bool audio_monitor_init(struct audio_monitor *monitor,
obs_source_t *source)
obs_source_t *source)
{
IMMDeviceEnumerator *immde = NULL;
WAVEFORMATEX *wfex = NULL;
@ -275,14 +275,14 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
* Init device */
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
&IID_IMMDeviceEnumerator, (void**)&immde);
&IID_IMMDeviceEnumerator, (void **)&immde);
if (FAILED(hr)) {
return false;
}
if (strcmp(id, "default") == 0) {
hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde,
eRender, eConsole, &monitor->device);
hr = immde->lpVtbl->GetDefaultAudioEndpoint(
immde, eRender, eConsole, &monitor->device);
} else {
wchar_t w_id[512];
os_utf8_to_wcs(id, 0, w_id, 512);
@ -298,8 +298,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
* Init client */
hr = monitor->device->lpVtbl->Activate(monitor->device,
&IID_IAudioClient, CLSCTX_ALL, NULL,
(void**)&monitor->client);
&IID_IAudioClient, CLSCTX_ALL,
NULL, (void **)&monitor->client);
if (FAILED(hr)) {
goto fail;
}
@ -310,8 +310,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
}
hr = monitor->client->lpVtbl->Initialize(monitor->client,
AUDCLNT_SHAREMODE_SHARED, 0,
10000000, 0, wfex, NULL);
AUDCLNT_SHAREMODE_SHARED, 0,
10000000, 0, wfex, NULL);
if (FAILED(hr)) {
goto fail;
}
@ -319,9 +319,9 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
/* ------------------------------------------ *
* Init resampler */
const struct audio_output_info *info = audio_output_get_info(
obs->audio.audio);
WAVEFORMATEXTENSIBLE *ext = (WAVEFORMATEXTENSIBLE*)wfex;
const struct audio_output_info *info =
audio_output_get_info(obs->audio.audio);
WAVEFORMATEXTENSIBLE *ext = (WAVEFORMATEXTENSIBLE *)wfex;
struct resample_info from;
struct resample_info to;
@ -330,8 +330,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
from.format = AUDIO_FORMAT_FLOAT_PLANAR;
to.samples_per_sec = (uint32_t)wfex->nSamplesPerSec;
to.speakers = convert_speaker_layout(ext->dwChannelMask,
wfex->nChannels);
to.speakers =
convert_speaker_layout(ext->dwChannelMask, wfex->nChannels);
to.format = AUDIO_FORMAT_FLOAT;
monitor->sample_rate = (uint32_t)wfex->nSamplesPerSec;
@ -350,7 +350,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
}
hr = monitor->client->lpVtbl->GetService(monitor->client,
&IID_IAudioRenderClient, (void**)&monitor->render);
&IID_IAudioRenderClient,
(void **)&monitor->render);
if (FAILED(hr)) {
goto fail;
}
@ -381,7 +382,7 @@ static void audio_monitor_init_final(struct audio_monitor *monitor)
monitor->source_has_video =
(monitor->source->info.output_flags & OBS_SOURCE_VIDEO) != 0;
obs_source_add_audio_capture_callback(monitor->source,
on_audio_playback, monitor);
on_audio_playback, monitor);
}
struct audio_monitor *audio_monitor_create(obs_source_t *source)

View file

@ -4,21 +4,21 @@
#include <mmdeviceapi.h>
#include <audioclient.h>
#ifndef KSAUDIO_SPEAKER_2POINT1
#define KSAUDIO_SPEAKER_2POINT1 (KSAUDIO_SPEAKER_STEREO|SPEAKER_LOW_FREQUENCY)
#define KSAUDIO_SPEAKER_2POINT1 (KSAUDIO_SPEAKER_STEREO | SPEAKER_LOW_FREQUENCY)
#endif
#define KSAUDIO_SPEAKER_SURROUND_AVUTIL \
(KSAUDIO_SPEAKER_STEREO|SPEAKER_FRONT_CENTER)
(KSAUDIO_SPEAKER_STEREO | SPEAKER_FRONT_CENTER)
#ifndef KSAUDIO_SPEAKER_4POINT1
#define KSAUDIO_SPEAKER_4POINT1 (KSAUDIO_SPEAKER_SURROUND|SPEAKER_LOW_FREQUENCY)
#define KSAUDIO_SPEAKER_4POINT1 \
(KSAUDIO_SPEAKER_SURROUND | SPEAKER_LOW_FREQUENCY)
#endif
#define safe_release(ptr) \
do { \
if (ptr) { \
#define safe_release(ptr) \
do { \
if (ptr) { \
ptr->lpVtbl->Release(ptr); \
} \
} \
} while (false)