decklink-device-discovery.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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
  46. DeckLinkDeviceDiscovery::DeckLinkDeviceArrived(IDeckLink *device)
  47. {
  48. DeckLinkDevice *newDev = new DeckLinkDevice(device);
  49. if (!newDev->Init()) {
  50. delete newDev;
  51. return S_OK;
  52. }
  53. std::lock_guard<std::recursive_mutex> lock(deviceMutex);
  54. devices.push_back(newDev);
  55. for (DeviceChangeInfo &cb : callbacks)
  56. cb.callback(cb.param, newDev, true);
  57. return S_OK;
  58. }
  59. HRESULT STDMETHODCALLTYPE
  60. DeckLinkDeviceDiscovery::DeckLinkDeviceRemoved(IDeckLink *device)
  61. {
  62. std::lock_guard<std::recursive_mutex> lock(deviceMutex);
  63. for (size_t i = 0; i < devices.size(); i++) {
  64. if (devices[i]->IsDevice(device)) {
  65. for (DeviceChangeInfo &cb : callbacks)
  66. cb.callback(cb.param, devices[i], false);
  67. devices[i]->Release();
  68. devices.erase(devices.begin() + i);
  69. break;
  70. }
  71. }
  72. return S_OK;
  73. }
  74. ULONG STDMETHODCALLTYPE DeckLinkDeviceDiscovery::AddRef(void)
  75. {
  76. return os_atomic_inc_long(&refCount);
  77. }
  78. HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::QueryInterface(REFIID iid,
  79. LPVOID *ppv)
  80. {
  81. HRESULT result = E_NOINTERFACE;
  82. *ppv = nullptr;
  83. CFUUIDBytes unknown = CFUUIDGetUUIDBytes(IUnknownUUID);
  84. if (memcmp(&iid, &unknown, sizeof(REFIID)) == 0) {
  85. *ppv = this;
  86. AddRef();
  87. result = S_OK;
  88. } else if (memcmp(&iid, &IID_IDeckLinkDeviceNotificationCallback,
  89. sizeof(REFIID)) == 0) {
  90. *ppv = (IDeckLinkDeviceNotificationCallback *)this;
  91. AddRef();
  92. result = S_OK;
  93. }
  94. return result;
  95. }
  96. ULONG STDMETHODCALLTYPE DeckLinkDeviceDiscovery::Release(void)
  97. {
  98. const long newRefCount = os_atomic_dec_long(&refCount);
  99. if (newRefCount == 0) {
  100. delete this;
  101. return 0;
  102. }
  103. return newRefCount;
  104. }