56 Commits

Author SHA1 Message Date
Seungha Yang
0f4bddc9a9 wasapi2: Add support for format negotiation
Enumerate supported formats during open so that src/sink can
report them via get_caps(). The format is then fixated and
initialized on acquire(), allowing users to select their
preferred format

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:28 +00:00
Seungha Yang
d9279a5145 wasapi2: Enumerate supported shared mode formats
... and report it via device provider property

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:28 +00:00
Seungha Yang
c97ed1e6f6 wasapi2: Workaround for S24_32LE format mismatch
Since Windows 24bit-in-32bit format is not supported
by GStreamer (Windows one is MSB-aligned), converts format
in ringbuffer using SSE2.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:28 +00:00
Seungha Yang
0d94713288 wasapi2: Demote S24_32LE in exclusive-mode format ordering
Some endpoints accept 24-bit in 32-bit PCM (S24_32LE) in exclusive mode
but playback at very low volume. Until the root cause is identified,
push S24_32LE to the end of the candidate list

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:27 +00:00
Seungha Yang
f2aabd6a71 wasapi2: Add support for exclusive mode device switching
Because of APO/OS mixer bypass in exclusive mode, we should
convert samples if new device has different format.
The conversion with additional buffering is implemented in this patch

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:26 +00:00
Seungha Yang
4257cd8546 wasapi2: Fix process loopback device init
Fix AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM flag usage

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:26 +00:00
Seungha Yang
18b5398960 wasapi2: Add support for exclusive mode
Add "exclusive" property and try exclusive mode streaming

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:25 +00:00
Seungha Yang
370499875c wasapi2: Probe exclusive mode formats
... and report it via device provider props

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9586>
2025-08-22 22:10:25 +00:00
Seungha Yang
7a48a0036f wasapi2: Warm up capture audio client on open
If the endpoint is idle, the first IAudioClient::Start() call
may take a long time to return. Start/stop the capture client
on open to reduce latency of subsequent Start() calls.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9553>
2025-08-14 12:38:41 +00:00
Seungha Yang
cb7dcff69e wasapi2sink: Do not push too large preroll buffer to endpoint
To avoid startup glitches, a silent buffer is pushed to
render endpoint, but pushing too large silent buffer will
introduce unnecessary latency. Limit it to a single period worth data.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9553>
2025-08-14 12:38:41 +00:00
Seungha Yang
42758aac2c wasapi2: Tone down activation fail log
If there's no endpoint available, that failure is expected error

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9521>
2025-08-11 12:29:52 +00:00
Seungha Yang
e0146536ab wasapi2: Pass correct data flow value to GetDefaultAudioEndpoint()
Respect requested data flow value

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9521>
2025-08-11 12:29:51 +00:00
Seungha Yang
1cba38145f wasapi2: Fix default render device probing
Fixing typo

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9517>
2025-08-08 18:39:51 +00:00
Seungha Yang
6af0ea60c1 wasapi2: Always fallback to MMDevice if default device is unavailable
Automatic stream routing supported virtual device may not be
available for some reason, but can try default MMdevice

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9468>
2025-08-05 13:40:29 +00:00
Seungha Yang
2769f8ff44 wasapi2: Always probe default audio endpoint info
Regardless of GetActivateResult() return code, fill default
device information to device provider props

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9468>
2025-08-05 13:40:29 +00:00
Seungha Yang
fedced4017 wasapi2: Handle GetActivateResult failure
Even if GetActivateResult() succeeded, activation result can fail.
Checks output HRESULT code as well

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9468>
2025-08-05 13:40:29 +00:00
Seungha Yang
7651662fc9 wasapi2deviceprovider: Log device update details
... and add wasapi2deviceprovider debug category

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9468>
2025-08-05 13:40:29 +00:00
Seungha Yang
7d6d49a888 wasapi2enumerator: Retry on IMMDevice::Activate failure
Since the sequence of IMMDeviceEnumerator::EnumAudioEndpoints()
followed by IMMDevice::Activate() is not atomic, Activate() may fail
if the enumerated device becomes invalidated before probing.
In such cases, retry device probing

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9468>
2025-08-05 13:40:29 +00:00
Seungha Yang
df95f95206 wasapi2enumerator: Avoid racy device probing
IMMDeviceEnumerator may fire a series of callbacks even for a single
device plug/unplug event. To avoid redundant probing, start device
enumeration only after no further callbacks are received for 100ms.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9468>
2025-08-05 13:40:29 +00:00
Seungha Yang
e515b1aee8 wasapi2enumerator: Log IMMNotificationClient callback details
... and add wasapi2enumerator debug category

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9468>
2025-08-05 13:40:28 +00:00
Seungha Yang
0d2157e801 wasapi2: Add continue-on-error property
If enabled, wasapi2src/sink will post a warning message instead of an error,
when device failures occur, such as open failure, I/O error,
or device removal.
The element will continue to produce/consume audio buffers and behave as if
a capture/render device were active, allowing pipeline to keep running even when
no audio endpoint is available

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9326>
2025-07-24 17:04:53 +00:00
Seungha Yang
37637d9611 wasapi2: Use 48kHz default sample rate
That's most common default value

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9326>
2025-07-24 17:04:53 +00:00
Seungha Yang
fc861119ed wasapi2deviceprovider: Probe device form factor and enumerator name
Adding form factor and enumerator information to device property struct

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9326>
2025-07-24 17:04:53 +00:00
Seungha Yang
9dbc7a491e wasapi2: Add support for dynamic device switch
Ringbuffer implementation is re-written to support "device" property
change in playing state

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9326>
2025-07-24 17:04:53 +00:00
Seungha Yang
7c4b87cc33 wasapi2: Fix various MinGW build warnings
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9307>
2025-07-02 18:18:18 +00:00
Seungha Yang
df45c088ad waapi2: Remove unused WinRT deps and implementations
Removing unused WinRT API based implementations

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9307>
2025-07-02 18:18:18 +00:00
Seungha Yang
0b3108cb3c wasapi2: Port to IMMDevice based device selection
Because of a couple of issues reported related to WinRT device
enumeration, porting to IMMDevice device id based device selection.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4311
Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3936
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9307>
2025-07-02 18:18:18 +00:00
Seungha Yang
ba41200c96 wasapi2: Implement IMMDeviceEnumerator based enumerator
... and merge wasapi2{capture,render}deviceprovider into single
wasapi2deviceprovider since we can enumerate input/output audio
devices at once using IMMDeviceEnumerator

This is a preparation for complete porting to Win32 API

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9307>
2025-07-02 18:18:18 +00:00
Seungha Yang
420b32b953 wasapi2: Log buffer QPC position and status flags
Log all infos of IAudioCaptureClient::GetBuffer

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8859>
2025-04-17 22:44:19 +00:00
Doug Nazar
5f90a4ae67 all: Annotate *_set_property() contructor only props without free
Properties that are marked constructor only aren't required to be freed
before g_value_dup_string() as they can only be called once during construction.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8648>
2025-03-27 09:03:18 +00:00
Mathieu Duponchelle
3de86b2b97 docs: port plugins to explicit sources
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8273>
2025-01-13 19:17:13 +01:00
L. E. Segovia
4dcc4b6235 meson: Undefine any WINVER and _WIN32_WINNT entries before redefining them
Fixes Cerbero build with MinGW GCC 14, where specifying -DWINVER=0x0601 -DWINVER=0x0A00 is a hard -Werror.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7658>
2024-10-12 19:10:46 -03:00
Seungha Yang
00536ea232 wasapi2: Adjust log level in device enumeration path
Audio device at requested index might not be available, but that's
expected case when enumerating devices.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6996>
2024-06-11 11:11:30 +00:00
Seungha Yang
06b9864dae wasapi2: Fix task memory leak
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6169>
2024-02-21 21:03:32 +00:00
Seungha Yang
354af30d9f wasapi2: Respect ringbuffer buffer/latency time
Decide buffer size based on configured buffer/latency time
if low-latency is disabled, so that ringbuffer can buffer more
than minimum required size.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2870
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6141>
2024-02-20 11:37:09 +00:00
Seungha Yang
93f0135798 wasapi2: Fix choppy rendering
This reverts questionable commit 009bc15f3397252e9e3954ae4af15ffcdbdeac69
which looks completely wrong.

The GstWasapi2RingBuffer:buffer_size variable is used to
calculate available buffer size we can write
(i.e., available size = buffer_size - padding_size).
But the commit makes the size to be exactly same as buffer period.
Then, it can confuse this element as if the endpoint buffer is full on
I/O event callback (if padding size is equal to buffer period)
but it's not true.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2870
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6132>
2024-02-19 04:39:25 +00:00
Seungha Yang
b12d43bd89 wasapi2device: Ignore activation failed device
Enumerates all devices even if activation error is detected

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3090
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5599>
2023-11-06 12:28:50 +00:00
Seungha Yang
34d221dad5 wasapi2: Fix build with GST_DISABLE_GST_DEBUG
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5585>
2023-11-03 13:31:03 +00:00
Seungha Yang
745a73eece wasapi2: Don't use global volume control object
ISimpleAudioVolume controls volume of corresponding audio session
and there would be only single input/output audio session
in case of share-mode, which means that it controls audio volume of the
process. Instead, use IAudioStreamVolume interface which controls
volume of the stream.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5549>
2023-10-27 18:11:51 +00:00
Seungha Yang
ae04702d23 wasapi2: Use C++ atomic instead of GLib
Release-Acquire ordering could be faster than MemoryBarrier()

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5176>
2023-08-14 14:20:45 +00:00
Seungha Yang
c992dd2184 wasapi2ringbuffer: Don't use GLib's weak pointer implementation
GWeakRef takes global mutex. Use C++ weak_ptr which will perform
atomic operation internally.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5176>
2023-08-14 14:20:45 +00:00
Seungha Yang
289bc9c91d wasapi2: fix "device" property description
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4651>
2023-05-17 04:50:04 +00:00
Seungha Yang
c98ad6f249 wasapi2: Allows process loopback capture on Windows 10
As per MS documentation[1], it requires Windows 10 Build 20348
but it seems to be supported by old versions too

[1] https://learn.microsoft.com/en-us/windows/win32/api/audioclientactivationparams/
ns-audioclientactivationparams-audioclient_process_loopback_params

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2524
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4505>
2023-04-28 14:11:16 +00:00
Dario Marino Saccavino
07cf7b2a29 wasapi2: Add option to monitor loopback device's mute state
When loopback recording from a render device, the wasapi2src element
captures audio even if the device is muted. This change adds the
'loopback-silence-on-device-mute' property that, when set to `true`,
causes wasapi2src to inject silence in the pipeline when
the device is muted.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1306
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4337>
2023-04-07 17:19:33 +00:00
Seungha Yang
fba06cfc76 wasapi2: Fix potential crash on device activation failure
The activation object is live in COM thread already and therefore
self refcount hack is pointless.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4194>
2023-03-16 19:30:27 +00:00
Seungha Yang
983d78daa5 wasapi2src: Fix loopback capture on Windows 10 Anniversary Update
... or older. Work around an OS bug that loopback capture
device doesn't notify event.

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1738
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3782>
2023-01-26 13:31:20 +00:00
Seungha Yang
cb7958e710 wasapi2: Add support for process loopback capture
Adding loopback capture mode for specified PID.

Note that this feature requires Windows 10 build 20348
(Windows 11/Windows Server 2022 or later),
and any process loopback related properties will not be exposed
if OS does not support it.

Example launch lines:
* wasapi2src loopback-mode=include-process-tree loopback-target-pid=<PID>
 Captures audio generated by an application (specified by PID)
 and its child process
* wasapi2src loopback-mode=exclude-process-tree loopback-target-pid=<PID>
 Captures desktop audio excluding PID and its child process

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1278
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3195>
2022-10-17 23:28:48 +00:00
Thibault Saunier
6a4425e46a meson: Call pkgconfig.generate in the loop where we declare plugins dependencies
Removing some copy pasted code

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2970>
2022-09-01 21:17:35 +00:00
Seungha Yang
8fee6bf785 wasapi2: Fix initial mute/volume setting
Fix up volume/mute change flag setting

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2809>
2022-07-29 02:37:29 +09:00
Seungha Yang
77225c79f9 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>
2022-01-20 23:04:46 +09:00