wasapi-enum-devices.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "../../obs-internal.h"
  2. #include "wasapi-output.h"
  3. #include <propsys.h>
  4. #ifdef __MINGW32__
  5. #ifdef DEFINE_PROPERTYKEY
  6. #undef DEFINE_PROPERTYKEY
  7. #endif
  8. #define DEFINE_PROPERTYKEY(id, a, b, c, d, e, f, g, h, i, j, k, l) \
  9. const PROPERTYKEY id = { { a,b,c, { d,e,f,g,h,i,j,k, } }, l };
  10. DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, \
  11. 0xa45c254e, 0xdf1c, 0x4efd, 0x80, \
  12. 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
  13. #else
  14. #include <functiondiscoverykeys_devpkey.h>
  15. #endif
  16. static bool get_device_info(obs_enum_audio_device_cb cb, void *data,
  17. IMMDeviceCollection *collection, UINT idx)
  18. {
  19. IPropertyStore *store = NULL;
  20. IMMDevice *device = NULL;
  21. PROPVARIANT name_var;
  22. char utf8_name[512];
  23. WCHAR *w_id = NULL;
  24. char utf8_id[512];
  25. bool cont = true;
  26. HRESULT hr;
  27. hr = collection->lpVtbl->Item(collection, idx, &device);
  28. if (FAILED(hr)) {
  29. goto fail;
  30. }
  31. hr = device->lpVtbl->GetId(device, &w_id);
  32. if (FAILED(hr)) {
  33. goto fail;
  34. }
  35. hr = device->lpVtbl->OpenPropertyStore(device, STGM_READ, &store);
  36. if (FAILED(hr)) {
  37. goto fail;
  38. }
  39. PropVariantInit(&name_var);
  40. hr = store->lpVtbl->GetValue(store, &PKEY_Device_FriendlyName,
  41. &name_var);
  42. if (FAILED(hr)) {
  43. goto fail;
  44. }
  45. os_wcs_to_utf8(w_id, 0, utf8_id, 512);
  46. os_wcs_to_utf8(name_var.pwszVal, 0, utf8_name, 512);
  47. cont = cb(data, utf8_name, utf8_id);
  48. fail:
  49. safe_release(store);
  50. safe_release(device);
  51. if (w_id)
  52. CoTaskMemFree(w_id);
  53. return cont;
  54. }
  55. void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb,
  56. void *data)
  57. {
  58. IMMDeviceEnumerator *enumerator = NULL;
  59. IMMDeviceCollection *collection = NULL;
  60. UINT count;
  61. HRESULT hr;
  62. hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
  63. &IID_IMMDeviceEnumerator, &enumerator);
  64. if (FAILED(hr)) {
  65. goto fail;
  66. }
  67. hr = enumerator->lpVtbl->EnumAudioEndpoints(enumerator, eRender,
  68. DEVICE_STATE_ACTIVE, &collection);
  69. if (FAILED(hr)) {
  70. goto fail;
  71. }
  72. hr = collection->lpVtbl->GetCount(collection, &count);
  73. if (FAILED(hr)) {
  74. goto fail;
  75. }
  76. for (UINT i = 0; i < count; i++) {
  77. if (!get_device_info(cb, data, collection, i)) {
  78. break;
  79. }
  80. }
  81. fail:
  82. safe_release(enumerator);
  83. safe_release(collection);
  84. }