DecklinkOutput.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "DecklinkOutput.hpp"
  2. #include <util/threading.h>
  3. DeckLinkOutput::DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery_)
  4. : DecklinkBase(discovery_),
  5. output(output)
  6. {
  7. discovery->AddCallback(DeckLinkOutput::DevicesChanged, this);
  8. }
  9. DeckLinkOutput::~DeckLinkOutput(void)
  10. {
  11. discovery->RemoveCallback(DeckLinkOutput::DevicesChanged, this);
  12. Deactivate();
  13. }
  14. void DeckLinkOutput::DevicesChanged(void *param, DeckLinkDevice *device, bool)
  15. {
  16. auto *decklink = reinterpret_cast<DeckLinkOutput*>(param);
  17. std::lock_guard<std::recursive_mutex> lock(decklink->deviceMutex);
  18. blog(LOG_DEBUG, "%s", device->GetHash().c_str());
  19. }
  20. bool DeckLinkOutput::Activate(DeckLinkDevice *device, long long modeId)
  21. {
  22. std::lock_guard<std::recursive_mutex> lock(deviceMutex);
  23. DeckLinkDevice *curDevice = GetDevice();
  24. const bool same = device == curDevice;
  25. const bool isActive = instance != nullptr;
  26. if (same) {
  27. if (!isActive)
  28. return false;
  29. if (instance->GetActiveModeId() == modeId &&
  30. instance->GetActivePixelFormat() == pixelFormat &&
  31. instance->GetActiveColorSpace() == colorSpace &&
  32. instance->GetActiveColorRange() == colorRange &&
  33. instance->GetActiveChannelFormat() == channelFormat)
  34. return false;
  35. }
  36. if (isActive)
  37. instance->StopOutput();
  38. if (!same)
  39. instance.Set(new DeckLinkDeviceInstance(this, device));
  40. if (instance == nullptr)
  41. return false;
  42. DeckLinkDeviceMode *mode = GetDevice()->FindOutputMode(modeId);
  43. if (mode == nullptr) {
  44. instance = nullptr;
  45. return false;
  46. }
  47. if (!instance->StartOutput(mode)) {
  48. instance = nullptr;
  49. return false;
  50. }
  51. os_atomic_inc_long(&activateRefs);
  52. return true;
  53. }
  54. void DeckLinkOutput::Deactivate(void)
  55. {
  56. std::lock_guard<std::recursive_mutex> lock(deviceMutex);
  57. if (instance)
  58. instance->StopOutput();
  59. instance = nullptr;
  60. os_atomic_dec_long(&activateRefs);
  61. }
  62. obs_output_t *DeckLinkOutput::GetOutput(void) const
  63. {
  64. return output;
  65. }
  66. void DeckLinkOutput::DisplayVideoFrame(video_data *frame)
  67. {
  68. instance->DisplayVideoFrame(frame);
  69. }
  70. void DeckLinkOutput::WriteAudio(audio_data *frames)
  71. {
  72. instance->WriteAudio(frames);
  73. }
  74. void DeckLinkOutput::SetSize(int width, int height)
  75. {
  76. this->width = width;
  77. this->height = height;
  78. }
  79. int DeckLinkOutput::GetWidth()
  80. {
  81. return width;
  82. }
  83. int DeckLinkOutput::GetHeight()
  84. {
  85. return height;
  86. }