mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-02 06:31:08 +00:00
wasapi2: Fix for device open failure on old OS
To open automatic stream routing aware device, at least Windows10 Anniversary Update is required. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1545>
This commit is contained in:
parent
b0816c4157
commit
77225c79f9
4 changed files with 92 additions and 14 deletions
|
@ -164,7 +164,7 @@ public:
|
||||||
HRESULT async_hr = S_OK;
|
HRESULT async_hr = S_OK;
|
||||||
|
|
||||||
async_hr = ActivateAudioInterfaceAsync (device_id.c_str (),
|
async_hr = ActivateAudioInterfaceAsync (device_id.c_str (),
|
||||||
__uuidof(IAudioClient3), nullptr, this, &async_op);
|
__uuidof(IAudioClient), nullptr, this, &async_op);
|
||||||
|
|
||||||
/* for debugging */
|
/* for debugging */
|
||||||
gst_wasapi2_result (async_hr);
|
gst_wasapi2_result (async_hr);
|
||||||
|
@ -590,6 +590,10 @@ gst_wasapi2_client_activate_async (GstWasapi2Client * self,
|
||||||
* Note that default device is much preferred
|
* Note that default device is much preferred
|
||||||
* See https://docs.microsoft.com/en-us/windows/win32/coreaudio/automatic-stream-routing
|
* See https://docs.microsoft.com/en-us/windows/win32/coreaudio/automatic-stream-routing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* DEVINTERFACE_AUDIO_CAPTURE and DEVINTERFACE_AUDIO_RENDER are available
|
||||||
|
* as of Windows 10 */
|
||||||
|
if (gst_wasapi2_can_automatic_stream_routing ()) {
|
||||||
if (self->device_id &&
|
if (self->device_id &&
|
||||||
g_ascii_strcasecmp (self->device_id, default_device_id.c_str ()) == 0) {
|
g_ascii_strcasecmp (self->device_id, default_device_id.c_str ()) == 0) {
|
||||||
GST_DEBUG_OBJECT (self, "Default device was requested");
|
GST_DEBUG_OBJECT (self, "Default device was requested");
|
||||||
|
@ -602,6 +606,7 @@ gst_wasapi2_client_activate_async (GstWasapi2Client * self,
|
||||||
GST_DEBUG_OBJECT (self, "device-index == zero means default device");
|
GST_DEBUG_OBJECT (self, "device-index == zero means default device");
|
||||||
use_default_device = TRUE;
|
use_default_device = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (use_default_device) {
|
if (use_default_device) {
|
||||||
target_device_id_wstring = default_device_id_wstring;
|
target_device_id_wstring = default_device_id_wstring;
|
||||||
|
@ -652,8 +657,13 @@ gst_wasapi2_client_activate_async (GstWasapi2Client * self,
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Available device count: %d", count);
|
GST_DEBUG_OBJECT (self, "Available device count: %d", count);
|
||||||
|
|
||||||
|
if (gst_wasapi2_can_automatic_stream_routing ()) {
|
||||||
/* zero is for default device */
|
/* zero is for default device */
|
||||||
device_index = 1;
|
device_index = 1;
|
||||||
|
} else {
|
||||||
|
device_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
ComPtr<IDeviceInformation> device_info;
|
ComPtr<IDeviceInformation> device_info;
|
||||||
|
@ -713,6 +723,15 @@ gst_wasapi2_client_activate_async (GstWasapi2Client * self,
|
||||||
GST_DEBUG_OBJECT (self, "device [%d] id: %s, name: %s",
|
GST_DEBUG_OBJECT (self, "device [%d] id: %s, name: %s",
|
||||||
device_index, cur_device_id.c_str (), cur_device_name.c_str ());
|
device_index, cur_device_id.c_str (), cur_device_name.c_str ());
|
||||||
|
|
||||||
|
if (self->device_index < 0 && !self->device_id) {
|
||||||
|
GST_INFO_OBJECT (self, "Select the first device, device id %s",
|
||||||
|
cur_device_id.c_str ());
|
||||||
|
target_device_id_wstring = id.GetRawBuffer (nullptr);
|
||||||
|
target_device_id = cur_device_id;
|
||||||
|
target_device_name = cur_device_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->device_id &&
|
if (self->device_id &&
|
||||||
g_ascii_strcasecmp (self->device_id, cur_device_id.c_str ()) == 0) {
|
g_ascii_strcasecmp (self->device_id, cur_device_id.c_str ()) == 0) {
|
||||||
GST_INFO_OBJECT (self,
|
GST_INFO_OBJECT (self,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "gstwasapi2util.h"
|
#include "gstwasapi2util.h"
|
||||||
#include <audioclient.h>
|
#include <audioclient.h>
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_wasapi2_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_wasapi2_debug);
|
||||||
#define GST_CAT_DEFAULT gst_wasapi2_debug
|
#define GST_CAT_DEFAULT gst_wasapi2_debug
|
||||||
|
@ -443,3 +444,49 @@ gst_wasapi2_util_parse_waveformatex (WAVEFORMATEX * format,
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_wasapi2_can_automatic_stream_routing (void)
|
||||||
|
{
|
||||||
|
#ifdef GST_WASAPI2_WINAPI_ONLY_APP
|
||||||
|
/* Assume we are on very recent OS */
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
static gboolean ret = FALSE;
|
||||||
|
static gsize version_once = 0;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&version_once)) {
|
||||||
|
OSVERSIONINFOEXW osverinfo;
|
||||||
|
typedef NTSTATUS (WINAPI fRtlGetVersion) (PRTL_OSVERSIONINFOEXW);
|
||||||
|
fRtlGetVersion *RtlGetVersion = NULL;
|
||||||
|
HMODULE hmodule = NULL;
|
||||||
|
|
||||||
|
memset (&osverinfo, 0, sizeof (OSVERSIONINFOEXW));
|
||||||
|
osverinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
|
||||||
|
|
||||||
|
hmodule = LoadLibraryW (L"ntdll.dll");
|
||||||
|
if (hmodule)
|
||||||
|
RtlGetVersion =
|
||||||
|
(fRtlGetVersion *) GetProcAddress (hmodule, "RtlGetVersion");
|
||||||
|
|
||||||
|
if (RtlGetVersion) {
|
||||||
|
RtlGetVersion (&osverinfo);
|
||||||
|
|
||||||
|
/* automatic stream routing requires Windows 10
|
||||||
|
* Anniversary Update (version 1607, build number 14393.0) */
|
||||||
|
if (osverinfo.dwMajorVersion > 10 ||
|
||||||
|
(osverinfo.dwMajorVersion == 10 && osverinfo.dwBuildNumber >= 14393))
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hmodule)
|
||||||
|
FreeLibrary (hmodule);
|
||||||
|
|
||||||
|
g_once_init_leave (&version_once, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_INFO ("Automatic stream routing support: %d", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ gboolean gst_wasapi2_util_parse_waveformatex (WAVEFORMATEX * format,
|
||||||
|
|
||||||
gchar * gst_wasapi2_util_get_error_message (HRESULT hr);
|
gchar * gst_wasapi2_util_get_error_message (HRESULT hr);
|
||||||
|
|
||||||
|
gboolean gst_wasapi2_can_automatic_stream_routing (void);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_WASAPI_UTIL_H__ */
|
#endif /* __GST_WASAPI_UTIL_H__ */
|
||||||
|
|
|
@ -83,6 +83,16 @@ if not winapi_app
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
winapi_desktop = cxx.compiles('''#include <winapifamily.h>
|
||||||
|
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
#error "not win32"
|
||||||
|
#endif''',
|
||||||
|
name: 'building for WINAPI_PARTITION_DESKTOP')
|
||||||
|
|
||||||
|
if winapi_app and not winapi_desktop
|
||||||
|
extra_args += ['-DGST_WASAPI2_WINAPI_ONLY_APP']
|
||||||
|
endif
|
||||||
|
|
||||||
win10_sdk = cxx.compiles('''#include <windows.h>
|
win10_sdk = cxx.compiles('''#include <windows.h>
|
||||||
#ifndef WDK_NTDDI_VERSION
|
#ifndef WDK_NTDDI_VERSION
|
||||||
#error "unknown Windows SDK version"
|
#error "unknown Windows SDK version"
|
||||||
|
|
Loading…
Reference in a new issue