aja-output.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #pragma once
  2. #include "aja-props.hpp"
  3. #include <ajantv2/includes/ntv2testpatterngen.h>
  4. #include <ajabase/common/types.h>
  5. #include <ajabase/system/thread.h>
  6. // #define AJA_WRITE_DEBUG_WAV
  7. #ifdef AJA_WRITE_DEBUG_WAV
  8. #include <ajabase/common/wavewriter.h>
  9. #endif
  10. #include <deque>
  11. #include <memory>
  12. #include <mutex>
  13. struct VideoFrame {
  14. struct video_data frame;
  15. int64_t frameNum;
  16. size_t size;
  17. };
  18. struct AudioFrames {
  19. struct audio_data frames;
  20. size_t offset;
  21. size_t size;
  22. };
  23. using VideoQueue = std::deque<VideoFrame>;
  24. using AudioQueue = std::deque<AudioFrames>;
  25. class CNTV2Card; // forward decl
  26. class AJAOutput {
  27. public:
  28. enum {
  29. // min queue sizes computed in AJAOutput
  30. kVideoQueueMaxSize = 15,
  31. kAudioQueueMaxSize =
  32. 96, // ~(48000 / 1024 samples per audio_frame) * 2sec
  33. };
  34. AJAOutput(CNTV2Card *card, const std::string &cardID,
  35. const std::string &outputID, UWord deviceIndex,
  36. const NTV2DeviceID deviceID);
  37. ~AJAOutput();
  38. CNTV2Card *GetCard();
  39. void Initialize(const OutputProps &props);
  40. void SetOBSOutput(obs_output_t *output);
  41. obs_output_t *GetOBSOutput();
  42. void SetOutputProps(const OutputProps &props);
  43. OutputProps GetOutputProps() const;
  44. void GenerateTestPattern(NTV2VideoFormat vf, NTV2PixelFormat pf,
  45. NTV2TestPatternSelect pattern);
  46. void QueueVideoFrame(struct video_data *frame, size_t size);
  47. void QueueAudioFrames(struct audio_data *frames, size_t size);
  48. void ClearVideoQueue();
  49. void ClearAudioQueue();
  50. size_t VideoQueueSize();
  51. size_t AudioQueueSize();
  52. bool HaveEnoughAudio(size_t needAudioSize);
  53. void DMAAudioFromQueue(NTV2AudioSystem audioSys);
  54. void DMAVideoFromQueue();
  55. void CreateThread(bool enable = false);
  56. void StopThread();
  57. bool ThreadRunning();
  58. static void OutputThread(AJAThread *thread, void *ctx);
  59. std::string mCardID;
  60. std::string mOutputID;
  61. UWord mDeviceIndex;
  62. NTV2DeviceID mDeviceID;
  63. uint32_t mAudioPlayCursor;
  64. uint32_t mAudioWriteCursor;
  65. uint32_t mAudioWrapAddress;
  66. uint32_t mAudioRate;
  67. uint64_t mAudioQueueSamples;
  68. uint64_t mAudioWriteSamples;
  69. uint64_t mAudioPlaySamples;
  70. uint32_t mNumCardFrames;
  71. uint32_t mFirstCardFrame;
  72. uint32_t mLastCardFrame;
  73. uint32_t mWriteCardFrame;
  74. uint32_t mPlayCardFrame;
  75. uint32_t mPlayCardNext;
  76. uint32_t mFrameRateNum;
  77. uint32_t mFrameRateDen;
  78. uint64_t mVideoQueueFrames;
  79. uint64_t mVideoWriteFrames;
  80. uint64_t mVideoPlayFrames;
  81. uint64_t mFirstVideoTS;
  82. uint64_t mFirstAudioTS;
  83. uint64_t mLastVideoTS;
  84. uint64_t mLastAudioTS;
  85. int64_t mVideoDelay;
  86. int64_t mAudioDelay;
  87. int64_t mAudioVideoSync;
  88. int64_t mAudioAdjust;
  89. int64_t mLastStatTime;
  90. #ifdef AJA_WRITE_DEBUG_WAV
  91. AJAWavWriter *mWaveWriter;
  92. #endif
  93. private:
  94. void calculate_card_frame_indices(uint32_t numFrames, NTV2DeviceID id,
  95. NTV2Channel channel,
  96. NTV2VideoFormat vf,
  97. NTV2PixelFormat pf);
  98. uint32_t get_frame_count();
  99. void dma_audio_samples(NTV2AudioSystem audioSys, uint32_t *data,
  100. size_t size);
  101. CNTV2Card *mCard;
  102. OutputProps mOutputProps;
  103. NTV2TestPatternBuffer mTestPattern;
  104. bool mIsRunning;
  105. bool mAudioStarted;
  106. AJAThread mRunThread;
  107. mutable std::mutex mVideoLock;
  108. mutable std::mutex mAudioLock;
  109. mutable std::mutex mRunThreadLock;
  110. std::unique_ptr<VideoQueue> mVideoQueue;
  111. std::unique_ptr<AudioQueue> mAudioQueue;
  112. obs_output_t *mOBSOutput;
  113. };