decklink-device.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include <sstream>
  2. #include "decklink-device.hpp"
  3. #include <util/threading.h>
  4. DeckLinkDevice::DeckLinkDevice(IDeckLink *device_) : device(device_)
  5. {
  6. }
  7. DeckLinkDevice::~DeckLinkDevice(void)
  8. {
  9. for (DeckLinkDeviceMode *mode : inputModes)
  10. delete mode;
  11. for (DeckLinkDeviceMode *mode : outputModes)
  12. delete mode;
  13. }
  14. ULONG DeckLinkDevice::AddRef()
  15. {
  16. return os_atomic_inc_long(&refCount);
  17. }
  18. ULONG DeckLinkDevice::Release()
  19. {
  20. long ret = os_atomic_dec_long(&refCount);
  21. if (ret == 0)
  22. delete this;
  23. return ret;
  24. }
  25. bool DeckLinkDevice::Init()
  26. {
  27. ComPtr<IDeckLinkAttributes> attributes;
  28. const HRESULT result = device->QueryInterface(IID_IDeckLinkAttributes,
  29. (void **)&attributes);
  30. if (result == S_OK) {
  31. decklink_bool_t detectable = false;
  32. if (attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection,
  33. &detectable) == S_OK && !!detectable) {
  34. DeckLinkDeviceMode *mode = new DeckLinkDeviceMode(
  35. "Auto",
  36. MODE_ID_AUTO);
  37. inputModes.push_back(mode);
  38. inputModeIdMap[MODE_ID_AUTO] = mode;
  39. }
  40. }
  41. // Find input modes
  42. ComPtr<IDeckLinkInput> input;
  43. if (device->QueryInterface(IID_IDeckLinkInput, (void **) &input) == S_OK) {
  44. IDeckLinkDisplayModeIterator *modeIterator;
  45. if (input->GetDisplayModeIterator(&modeIterator) == S_OK) {
  46. IDeckLinkDisplayMode *displayMode;
  47. long long modeId = 1;
  48. while (modeIterator->Next(&displayMode) == S_OK) {
  49. if (displayMode == nullptr)
  50. continue;
  51. DeckLinkDeviceMode *mode =
  52. new DeckLinkDeviceMode(displayMode, modeId);
  53. inputModes.push_back(mode);
  54. inputModeIdMap[modeId] = mode;
  55. displayMode->Release();
  56. ++modeId;
  57. }
  58. modeIterator->Release();
  59. }
  60. }
  61. // find output modes
  62. ComPtr<IDeckLinkOutput> output;
  63. if (device->QueryInterface(IID_IDeckLinkOutput, (void **) &output) == S_OK) {
  64. IDeckLinkDisplayModeIterator *modeIterator;
  65. if (output->GetDisplayModeIterator(&modeIterator) == S_OK) {
  66. IDeckLinkDisplayMode *displayMode;
  67. long long modeId = 1;
  68. while (modeIterator->Next(&displayMode) == S_OK) {
  69. if (displayMode == nullptr)
  70. continue;
  71. DeckLinkDeviceMode *mode =
  72. new DeckLinkDeviceMode(displayMode, modeId);
  73. outputModes.push_back(mode);
  74. outputModeIdMap[modeId] = mode;
  75. displayMode->Release();
  76. ++modeId;
  77. }
  78. modeIterator->Release();
  79. }
  80. }
  81. // get keyer support
  82. attributes->GetFlag(BMDDeckLinkSupportsExternalKeying, &supportsExternalKeyer);
  83. attributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &supportsInternalKeyer);
  84. decklink_string_t decklinkModelName;
  85. decklink_string_t decklinkDisplayName;
  86. if (device->GetModelName(&decklinkModelName) != S_OK)
  87. return false;
  88. DeckLinkStringToStdString(decklinkModelName, name);
  89. if (device->GetDisplayName(&decklinkDisplayName) != S_OK)
  90. return false;
  91. DeckLinkStringToStdString(decklinkDisplayName, displayName);
  92. hash = displayName;
  93. if (result != S_OK)
  94. return true;
  95. int64_t channels;
  96. /* Intensity Shuttle for Thunderbolt return 2; however, it supports 8 channels */
  97. if (name == "Intensity Shuttle Thunderbolt")
  98. maxChannel = 8;
  99. else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels, &channels) == S_OK)
  100. maxChannel = (int32_t)channels;
  101. else
  102. maxChannel = 2;
  103. /* http://forum.blackmagicdesign.com/viewtopic.php?f=12&t=33967
  104. * BMDDeckLinkTopologicalID for older devices
  105. * BMDDeckLinkPersistentID for newer ones */
  106. int64_t value;
  107. if (attributes->GetInt(BMDDeckLinkPersistentID, &value) != S_OK &&
  108. attributes->GetInt(BMDDeckLinkTopologicalID, &value) != S_OK)
  109. return true;
  110. std::ostringstream os;
  111. os << value << "_" << name;
  112. hash = os.str();
  113. return true;
  114. }
  115. bool DeckLinkDevice::GetInput(IDeckLinkInput **input)
  116. {
  117. if (device->QueryInterface(IID_IDeckLinkInput, (void**)input) != S_OK)
  118. return false;
  119. return true;
  120. }
  121. bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output)
  122. {
  123. if (device->QueryInterface(IID_IDeckLinkOutput, (void**)output) != S_OK)
  124. return false;
  125. return true;
  126. }
  127. bool DeckLinkDevice::GetKeyer(IDeckLinkKeyer **deckLinkKeyer)
  128. {
  129. if (device->QueryInterface(IID_IDeckLinkKeyer, (void**)deckLinkKeyer) != S_OK)
  130. {
  131. fprintf(stderr, "Could not obtain the IDeckLinkKeyer interface\n");
  132. return false;
  133. }
  134. return true;
  135. }
  136. void DeckLinkDevice::SetKeyerMode(int newKeyerMode)
  137. {
  138. keyerMode = newKeyerMode;
  139. }
  140. int DeckLinkDevice::GetKeyerMode(void)
  141. {
  142. return keyerMode;
  143. }
  144. DeckLinkDeviceMode *DeckLinkDevice::FindInputMode(long long id)
  145. {
  146. return inputModeIdMap[id];
  147. }
  148. DeckLinkDeviceMode *DeckLinkDevice::FindOutputMode(long long id)
  149. {
  150. return outputModeIdMap[id];
  151. }
  152. const std::string& DeckLinkDevice::GetDisplayName(void)
  153. {
  154. return displayName;
  155. }
  156. const std::string& DeckLinkDevice::GetHash(void) const
  157. {
  158. return hash;
  159. }
  160. const std::vector<DeckLinkDeviceMode *>& DeckLinkDevice::GetInputModes(void) const
  161. {
  162. return inputModes;
  163. }
  164. const std::vector<DeckLinkDeviceMode *>& DeckLinkDevice::GetOutputModes(void) const
  165. {
  166. return outputModes;
  167. }
  168. const bool DeckLinkDevice::GetSupportsExternalKeyer(void) const
  169. {
  170. return supportsExternalKeyer;
  171. }
  172. const bool DeckLinkDevice::GetSupportsInternalKeyer(void) const
  173. {
  174. return supportsInternalKeyer;
  175. }
  176. const std::string& DeckLinkDevice::GetName(void) const
  177. {
  178. return name;
  179. }
  180. int32_t DeckLinkDevice::GetMaxChannel(void) const
  181. {
  182. return maxChannel;
  183. }