1
0

decklink-device-discovery.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include "decklink-device-discovery.hpp"
  2. #include "decklink-device.hpp"
  3. #include <util/threading.h>
  4. DeckLinkDeviceDiscovery::DeckLinkDeviceDiscovery()
  5. {
  6. discovery.Set(CreateDeckLinkDiscoveryInstance());
  7. if (discovery == nullptr)
  8. blog(LOG_INFO, "No blackmagic support");
  9. }
  10. DeckLinkDeviceDiscovery::~DeckLinkDeviceDiscovery(void)
  11. {
  12. if (discovery != nullptr) {
  13. if (initialized)
  14. discovery->UninstallDeviceNotifications();
  15. for (DeckLinkDevice *device : devices)
  16. device->Release();
  17. }
  18. }
  19. bool DeckLinkDeviceDiscovery::Init(void)
  20. {
  21. HRESULT result = E_FAIL;
  22. if (initialized)
  23. return false;
  24. if (discovery != nullptr)
  25. result = discovery->InstallDeviceNotifications(this);
  26. initialized = result == S_OK;
  27. if (!initialized)
  28. blog(LOG_DEBUG, "Failed to start search for DeckLink devices");
  29. return initialized;
  30. }
  31. DeckLinkDevice *DeckLinkDeviceDiscovery::FindByHash(const char *hash)
  32. {
  33. DeckLinkDevice *ret = nullptr;
  34. deviceMutex.lock();
  35. for (DeckLinkDevice *device : devices) {
  36. if (device->GetHash().compare(hash) == 0) {
  37. ret = device;
  38. ret->AddRef();
  39. break;
  40. }
  41. }
  42. deviceMutex.unlock();
  43. return ret;
  44. }
  45. HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceArrived(IDeckLink *device)
  46. {
  47. DeckLinkDevice *newDev = new DeckLinkDevice(device);
  48. if (!newDev->Init()) {
  49. delete newDev;
  50. return S_OK;
  51. }
  52. std::lock_guard<std::recursive_mutex> lock(deviceMutex);
  53. devices.push_back(newDev);
  54. for (DeviceChangeInfo &cb : callbacks)
  55. cb.callback(cb.param, newDev, true);
  56. return S_OK;
  57. }
  58. HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceRemoved(IDeckLink *device)
  59. {
  60. std::lock_guard<std::recursive_mutex> lock(deviceMutex);
  61. for (size_t i = 0; i < devices.size(); i++) {
  62. if (devices[i]->IsDevice(device)) {
  63. for (DeviceChangeInfo &cb : callbacks)
  64. cb.callback(cb.param, devices[i], false);
  65. devices[i]->Release();
  66. devices.erase(devices.begin() + i);
  67. break;
  68. }
  69. }
  70. return S_OK;
  71. }
  72. ULONG STDMETHODCALLTYPE DeckLinkDeviceDiscovery::AddRef(void)
  73. {
  74. return os_atomic_inc_long(&refCount);
  75. }
  76. HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::QueryInterface(REFIID iid, LPVOID *ppv)
  77. {
  78. HRESULT result = E_NOINTERFACE;
  79. *ppv = nullptr;
  80. CFUUIDBytes unknown = CFUUIDGetUUIDBytes(IUnknownUUID);
  81. if (memcmp(&iid, &unknown, sizeof(REFIID)) == 0) {
  82. *ppv = this;
  83. AddRef();
  84. result = S_OK;
  85. } else if (memcmp(&iid, &IID_IDeckLinkDeviceNotificationCallback, sizeof(REFIID)) == 0) {
  86. *ppv = (IDeckLinkDeviceNotificationCallback *)this;
  87. AddRef();
  88. result = S_OK;
  89. }
  90. return result;
  91. }
  92. ULONG STDMETHODCALLTYPE DeckLinkDeviceDiscovery::Release(void)
  93. {
  94. const long newRefCount = os_atomic_dec_long(&refCount);
  95. if (newRefCount == 0) {
  96. delete this;
  97. return 0;
  98. }
  99. return newRefCount;
  100. }