decklink-device-instance.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #pragma once
  2. #define LOG(level, message, ...) \
  3. blog(level, "%s: " message, "decklink", ##__VA_ARGS__)
  4. #include <obs-module.h>
  5. #include <media-io/video-scaler.h>
  6. #include "decklink-device.hpp"
  7. #include "OBSVideoFrame.h"
  8. #include <atomic>
  9. #include <mutex>
  10. #include <vector>
  11. class AudioRepacker;
  12. class DecklinkBase;
  13. template<typename T>
  14. class RenderDelegate : public IDeckLinkVideoOutputCallback {
  15. private:
  16. std::atomic<unsigned long> m_refCount = 1;
  17. T *m_pOwner;
  18. ~RenderDelegate();
  19. public:
  20. RenderDelegate(T *pOwner);
  21. // IUnknown
  22. virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
  23. LPVOID *ppv);
  24. virtual ULONG STDMETHODCALLTYPE AddRef();
  25. virtual ULONG STDMETHODCALLTYPE Release();
  26. // IDeckLinkVideoOutputCallback
  27. virtual HRESULT STDMETHODCALLTYPE
  28. ScheduledFrameCompleted(IDeckLinkVideoFrame *completedFrame,
  29. BMDOutputFrameCompletionResult result);
  30. virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped();
  31. };
  32. class DeckLinkDeviceInstance : public IDeckLinkInputCallback {
  33. protected:
  34. ComPtr<IDeckLinkConfiguration> deckLinkConfiguration;
  35. struct obs_source_frame2 currentFrame;
  36. struct obs_source_audio currentPacket;
  37. struct obs_source_cea_708 currentCaptions;
  38. DecklinkBase *decklink = nullptr;
  39. DeckLinkDevice *device = nullptr;
  40. DeckLinkDeviceMode *mode = nullptr;
  41. BMDVideoConnection videoConnection;
  42. BMDAudioConnection audioConnection;
  43. BMDDisplayMode displayMode = bmdModeNTSC;
  44. BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
  45. video_colorspace colorSpace = VIDEO_CS_DEFAULT;
  46. video_colorspace activeColorSpace = VIDEO_CS_DEFAULT;
  47. video_range_type colorRange = VIDEO_RANGE_DEFAULT;
  48. ComPtr<IDeckLinkInput> input;
  49. ComPtr<IDeckLinkOutput> output;
  50. volatile long refCount = 1;
  51. int64_t audioOffset = 0;
  52. uint64_t nextAudioTS = 0;
  53. uint64_t lastVideoTS = 0;
  54. AudioRepacker *audioRepacker = nullptr;
  55. speaker_layout channelFormat = SPEAKERS_STEREO;
  56. bool swap;
  57. bool allow10Bit;
  58. OBSVideoFrame *convertFrame = nullptr;
  59. std::mutex frameDataMutex;
  60. std::vector<uint8_t> frameData;
  61. BMDTimeValue frameDuration;
  62. BMDTimeScale frameTimescale;
  63. size_t totalFramesScheduled;
  64. ComPtr<RenderDelegate<DeckLinkDeviceInstance>> renderDelegate;
  65. void FinalizeStream();
  66. void SetupVideoFormat(DeckLinkDeviceMode *mode_);
  67. void HandleAudioPacket(IDeckLinkAudioInputPacket *audioPacket,
  68. const uint64_t timestamp);
  69. void HandleVideoFrame(IDeckLinkVideoInputFrame *videoFrame,
  70. const uint64_t timestamp);
  71. public:
  72. DeckLinkDeviceInstance(DecklinkBase *decklink, DeckLinkDevice *device);
  73. virtual ~DeckLinkDeviceInstance();
  74. inline DeckLinkDevice *GetDevice() const { return device; }
  75. inline long long GetActiveModeId() const
  76. {
  77. return mode ? mode->GetId() : 0;
  78. }
  79. inline BMDPixelFormat GetActivePixelFormat() const
  80. {
  81. return pixelFormat;
  82. }
  83. inline video_colorspace GetActiveColorSpace() const
  84. {
  85. return colorSpace;
  86. }
  87. inline video_range_type GetActiveColorRange() const
  88. {
  89. return colorRange;
  90. }
  91. inline speaker_layout GetActiveChannelFormat() const
  92. {
  93. return channelFormat;
  94. }
  95. inline bool GetActiveSwapState() const { return swap; }
  96. inline BMDVideoConnection GetVideoConnection() const
  97. {
  98. return videoConnection;
  99. }
  100. inline BMDAudioConnection GetAudioConnection() const
  101. {
  102. return audioConnection;
  103. }
  104. inline DeckLinkDeviceMode *GetMode() const { return mode; }
  105. bool StartCapture(DeckLinkDeviceMode *mode, bool allow10Bit,
  106. BMDVideoConnection bmdVideoConnection,
  107. BMDAudioConnection bmdAudioConnection);
  108. bool StopCapture(void);
  109. bool StartOutput(DeckLinkDeviceMode *mode_);
  110. bool StopOutput(void);
  111. HRESULT STDMETHODCALLTYPE
  112. VideoInputFrameArrived(IDeckLinkVideoInputFrame *videoFrame,
  113. IDeckLinkAudioInputPacket *audioPacket);
  114. HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(
  115. BMDVideoInputFormatChangedEvents events,
  116. IDeckLinkDisplayMode *newMode,
  117. BMDDetectedVideoInputFormatFlags detectedSignalFlags);
  118. ULONG STDMETHODCALLTYPE AddRef(void);
  119. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv);
  120. ULONG STDMETHODCALLTYPE Release(void);
  121. void UpdateVideoFrame(video_data *frame);
  122. void ScheduleVideoFrame(IDeckLinkVideoFrame *frame);
  123. void WriteAudio(audio_data *frames);
  124. void HandleCaptionPacket(IDeckLinkAncillaryPacket *packet,
  125. const uint64_t timestamp);
  126. };