151 lines
3.2 KiB
C++
151 lines
3.2 KiB
C++
|
#pragma once
|
||
|
|
||
|
#include "aja-props.hpp"
|
||
|
|
||
|
#include <ajantv2/includes/ntv2testpatterngen.h>
|
||
|
|
||
|
#include <ajabase/common/types.h>
|
||
|
#include <ajabase/system/thread.h>
|
||
|
|
||
|
// #define AJA_WRITE_DEBUG_WAV
|
||
|
#ifdef AJA_WRITE_DEBUG_WAV
|
||
|
#include <ajabase/common/wavewriter.h>
|
||
|
#endif
|
||
|
|
||
|
#include <deque>
|
||
|
#include <memory>
|
||
|
#include <mutex>
|
||
|
|
||
|
struct VideoFrame {
|
||
|
struct video_data frame;
|
||
|
int64_t frameNum;
|
||
|
size_t size;
|
||
|
};
|
||
|
|
||
|
struct AudioFrames {
|
||
|
struct audio_data frames;
|
||
|
size_t offset;
|
||
|
size_t size;
|
||
|
};
|
||
|
|
||
|
using VideoQueue = std::deque<VideoFrame>;
|
||
|
using AudioQueue = std::deque<AudioFrames>;
|
||
|
|
||
|
class CNTV2Card; // forward decl
|
||
|
|
||
|
class AJAOutput {
|
||
|
public:
|
||
|
enum {
|
||
|
// min queue sizes computed in AJAOutput
|
||
|
kVideoQueueMaxSize = 15,
|
||
|
kAudioQueueMaxSize =
|
||
|
96, // ~(48000 / 1024 samples per audio_frame) * 2sec
|
||
|
};
|
||
|
|
||
|
AJAOutput(CNTV2Card *card, const std::string &cardID,
|
||
|
const std::string &outputID, UWord deviceIndex,
|
||
|
const NTV2DeviceID deviceID);
|
||
|
|
||
|
~AJAOutput();
|
||
|
|
||
|
CNTV2Card *GetCard();
|
||
|
|
||
|
void Initialize(const OutputProps &props);
|
||
|
|
||
|
void SetOBSOutput(obs_output_t *output);
|
||
|
obs_output_t *GetOBSOutput();
|
||
|
|
||
|
void SetOutputProps(const OutputProps &props);
|
||
|
OutputProps GetOutputProps() const;
|
||
|
|
||
|
void GenerateTestPattern(NTV2VideoFormat vf, NTV2PixelFormat pf,
|
||
|
NTV2TestPatternSelect pattern);
|
||
|
|
||
|
void QueueVideoFrame(struct video_data *frame, size_t size);
|
||
|
void QueueAudioFrames(struct audio_data *frames, size_t size);
|
||
|
void ClearVideoQueue();
|
||
|
void ClearAudioQueue();
|
||
|
size_t VideoQueueSize();
|
||
|
size_t AudioQueueSize();
|
||
|
|
||
|
bool HaveEnoughAudio(size_t needAudioSize);
|
||
|
void DMAAudioFromQueue(NTV2AudioSystem audioSys);
|
||
|
void DMAVideoFromQueue();
|
||
|
|
||
|
void CreateThread(bool enable = false);
|
||
|
void StopThread();
|
||
|
bool ThreadRunning();
|
||
|
static void OutputThread(AJAThread *thread, void *ctx);
|
||
|
|
||
|
std::string mCardID;
|
||
|
std::string mOutputID;
|
||
|
UWord mDeviceIndex;
|
||
|
NTV2DeviceID mDeviceID;
|
||
|
|
||
|
uint32_t mAudioPlayCursor;
|
||
|
uint32_t mAudioWriteCursor;
|
||
|
uint32_t mAudioWrapAddress;
|
||
|
uint32_t mAudioRate;
|
||
|
|
||
|
uint64_t mAudioQueueSamples;
|
||
|
uint64_t mAudioWriteSamples;
|
||
|
uint64_t mAudioPlaySamples;
|
||
|
|
||
|
uint32_t mNumCardFrames;
|
||
|
uint32_t mFirstCardFrame;
|
||
|
uint32_t mLastCardFrame;
|
||
|
uint32_t mWriteCardFrame;
|
||
|
uint32_t mPlayCardFrame;
|
||
|
uint32_t mPlayCardNext;
|
||
|
uint32_t mFrameRateNum;
|
||
|
uint32_t mFrameRateDen;
|
||
|
|
||
|
uint64_t mVideoQueueFrames;
|
||
|
uint64_t mVideoWriteFrames;
|
||
|
uint64_t mVideoPlayFrames;
|
||
|
|
||
|
uint64_t mFirstVideoTS;
|
||
|
uint64_t mFirstAudioTS;
|
||
|
uint64_t mLastVideoTS;
|
||
|
uint64_t mLastAudioTS;
|
||
|
|
||
|
int64_t mVideoDelay;
|
||
|
int64_t mAudioDelay;
|
||
|
int64_t mAudioVideoSync;
|
||
|
int64_t mAudioAdjust;
|
||
|
int64_t mLastStatTime;
|
||
|
#ifdef AJA_WRITE_DEBUG_WAV
|
||
|
AJAWavWriter *mWaveWriter;
|
||
|
#endif
|
||
|
|
||
|
private:
|
||
|
void calculate_card_frame_indices(uint32_t numFrames, NTV2DeviceID id,
|
||
|
NTV2Channel channel,
|
||
|
NTV2VideoFormat vf,
|
||
|
NTV2PixelFormat pf);
|
||
|
|
||
|
uint32_t get_frame_count();
|
||
|
|
||
|
void dma_audio_samples(NTV2AudioSystem audioSys, uint32_t *data,
|
||
|
size_t size);
|
||
|
|
||
|
CNTV2Card *mCard;
|
||
|
|
||
|
OutputProps mOutputProps;
|
||
|
|
||
|
NTV2TestPatternBuffer mTestPattern;
|
||
|
|
||
|
bool mIsRunning;
|
||
|
bool mAudioStarted;
|
||
|
|
||
|
AJAThread mRunThread;
|
||
|
mutable std::mutex mVideoLock;
|
||
|
mutable std::mutex mAudioLock;
|
||
|
mutable std::mutex mRunThreadLock;
|
||
|
|
||
|
std::unique_ptr<VideoQueue> mVideoQueue;
|
||
|
std::unique_ptr<AudioQueue> mAudioQueue;
|
||
|
|
||
|
obs_output_t *mOBSOutput;
|
||
|
};
|