0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 13:08:50 +02:00
obs-studio/plugins/win-wasapi/enum-wasapi.cpp
jp9000 348588254c Add WASAPI audio capture
- Add WASAPI audio capture for windows, input and output

 - Check for null pointer in os_dlopen

 - Add exception-safe 'WinHandle' and 'CoTaskMemPtr' helper classes that
   will automatically call CloseHandle on handles and call CoTaskMemFree
   on certain types of memory returned from windows functions

 - Changed the wide <-> MBS/UTF8 conversion functions so that you use
   buffers (like these functions are *supposed* to behave), and changed
   the ones that allocate to a different naming scheme to be safe
2014-03-04 07:07:13 -07:00

94 lines
2.1 KiB
C++

#include "enum-wasapi.hpp"
#include <util/base.h>
#include <util/platform.h>
#include <util/windows/HRError.hpp>
#include <util/windows/ComPtr.hpp>
#include <util/windows/CoTaskMemPtr.hpp>
using namespace std;
string GetDeviceName(IMMDevice *device)
{
string device_name;
ComPtr<IPropertyStore> store;
HRESULT res;
if (SUCCEEDED(device->OpenPropertyStore(STGM_READ, store.Assign()))) {
PROPVARIANT nameVar;
PropVariantInit(&nameVar);
res = store->GetValue(PKEY_Device_FriendlyName, &nameVar);
if (SUCCEEDED(res)) {
size_t size;
size = os_wcs_to_utf8(nameVar.pwszVal, 0, nullptr);
if (size) {
device_name.resize(size);
os_wcs_to_utf8(nameVar.pwszVal, size,
&device_name[0]);
}
}
}
return device_name;
}
void GetWASAPIAudioDevices_(vector<AudioDeviceInfo> &devices, bool input)
{
ComPtr<IMMDeviceEnumerator> enumerator;
ComPtr<IMMDeviceCollection> collection;
UINT count;
HRESULT res;
res = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator),
(void**)enumerator.Assign());
if (!res)
throw HRError("Failed to create enumerator", res);
res = enumerator->EnumAudioEndpoints(input ? eCapture : eRender,
DEVICE_STATE_ACTIVE, collection.Assign());
if (!res)
throw HRError("Failed to enumerate devices", res);
res = collection->GetCount(&count);
if (FAILED(res))
throw HRError("Failed to get device count", res);
for (UINT i = 0; i < count; i++) {
ComPtr<IMMDevice> device;
CoTaskMemPtr<WCHAR> w_id;
AudioDeviceInfo info;
size_t size;
res = collection->Item(i, device.Assign());
if (FAILED(res))
continue;
res = device->GetId(&w_id);
if (FAILED(res) || !w_id || !*w_id)
continue;
info.name = GetDeviceName(device);
size = os_wcs_to_utf8(w_id, 0, nullptr);
info.id.resize(size);
os_wcs_to_utf8(w_id, size, &info.id[0]);
}
}
void GetWASAPIAudioDevices(vector<AudioDeviceInfo> &devices, bool input)
{
devices.clear();
try {
GetWASAPIAudioDevices_(devices, input);
} catch (HRError error) {
blog(LOG_ERROR, "[GetWASAPIAudioDevices] %s: %lX",
error.str, error.hr);
}
}