UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
vidcap_state_aja Class Reference
Collaboration diagram for vidcap_state_aja:
Collaboration graph

Classes

struct  mAudio
 

Public Member Functions

 vidcap_state_aja (unordered_map< string, string > const &parameters, int audioFlags)
 
virtual ~vidcap_state_aja ()
 
struct video_frame * grab (struct audio_frame **audio)
 
void Init ()
 
void Quit ()
 
AJAStatus Run ()
 

Private Member Functions

virtual void CaptureFrames (void)
 
void EnableInput (NTV2InputSource source)
 
NTV2VideoFormat GetVideoFormatFromInputSource ()
 
bool IsInput3Gb (const NTV2InputSource inputSource)
 
AJAStatus SetupAudio ()
 
AJAStatus SetupHDMI ()
 
void SetupHostBuffers ()
 
AJAStatus SetupVideo ()
 
virtual void StartProducerThread (void)
 Starts my frame consumer thread.
 

Static Private Member Functions

static void ProducerThreadStatic (vidcap_state_aja *pContext)
 

Private Attributes

uint32_t mAudioBufferSize {}
 My video buffer size, in bytes.
 
uint32_t mAudioInLastAddress {}
 My record of the location of the last audio sample captured.
 
NTV2AudioSource mAudioSource {}
 
NTV2AudioSystem mAudioSystem {NTV2_AUDIOSYSTEM_1}
 The input source I'm using.
 
bool mbFixedReference {false}
 
bool mCheckFor4K {false}
 
bool mClearRouting {false}
 
CNTV2Card mDevice
 
NTV2DeviceID mDeviceID {}
 
unsigned int mDeviceIndex {0}
 
int mFrames {0}
 
bool mGlobalQuit {false}
 
NTV2Channel mInputChannel {NTV2_CHANNEL_INVALID}
 Used to restore prior every-frame task mode.
 
bool mInputIsRGB
 SDI Input is in RGB otherwise YCbCr.
 
NTV2InputSource mInputSource {NTV2_INPUTSOURCE_SDI1}
 Wide VANC?
 
int mMaxAudioChannels {0}
 
shared_ptr< uint32_t > mOutputAudioFrame
 
size_t mOutputAudioFrameSize {}
 
shared_ptr< video_frame > mOutputFrame
 
mutex mOutputFrameLock
 
condition_variable mOutputFrameReady
 
NTV2FrameBufferFormat mPixelFormat {NTV2_FBF_INVALID}
 My video format.
 
video_frame_pool mPool {0, aligned_data_allocator()}
 My producer thread object – does the frame capturing.
 
thread mProducerThread
 My audio buffer size, in bytes.
 
bool mProgressive {false}
 
NTV2EveryFrameTaskMode mSavedTaskMode {}
 My device identifier.
 
chrono::system_clock::time_point mT0 {chrono::system_clock::now()}
 
NTV2TCIndex mTimeCodeSource {}
 Time code source.
 
NTV2VANCMode mVancMode {}
 My pixel format.
 
uint32_t mVideoBufferSize {}
 The audio system I'm using.
 
NTV2VideoFormat mVideoFormat {NTV2_FORMAT_UNKNOWN}
 My input channel.
 
bool mWideVanc {}
 VANC enabled?
 

Detailed Description

Definition at line 164 of file aja.cpp.

Constructor & Destructor Documentation

◆ vidcap_state_aja()

vidcap_state_aja::vidcap_state_aja ( unordered_map< string, string > const & parameters,
int audioFlags )

Definition at line 223 of file aja.cpp.

224{
225 bool colorSpaceSet = false; // explicitly set input color spec
226
227 for (auto const &it : parameters) {
228 if (it.first == "progressive") {
229 mProgressive = true;
230 } else if (it.first == "4K" || it.first == "4k") {
231 mCheckFor4K = true;
232 } else if (it.first == "clear-routing") {
233 mClearRouting = true;
234 } else if (it.first == "device") {
235 mDeviceIndex = stol(it.second, nullptr, 10);
236 } else if (it.first == "channel") {
237 mInputChannel = (NTV2Channel) (atoi(it.second.c_str()) - 1);
238 } else if (it.first == "codec") {
239 if (get_codec_from_name(it.second.c_str()) == VIDEO_CODEC_NONE) {
240 throw string("Unknown codec " + it.second + "!");
241 }
242 mPixelFormat = NTV2_FBF_INVALID;
243 for (auto const &c : ugaja::codec_map) {
244 if (c.second == get_codec_from_name(it.second.c_str())) {
245 mPixelFormat = c.first;
246 break;
247 }
248 }
249 if (mPixelFormat == NTV2_FBF_INVALID) {
250 throw string("Cannoc map " + it.second + " to AJA codec!");
251 }
252 } else if (it.first == "connection") {
253 NTV2InputSource source = NTV2InputSource();
254 while (source != NTV2_INPUTSOURCE_INVALID) {
255 if (NTV2InputSourceToString(source, true) == it.second) {
257 break;
258 }
259 // should be this, but GetNTV2InputSourceForIndex knows only SDIs
260 //source = ::GetNTV2InputSourceForIndex(::GetIndexForNTV2InputSource(source) + 1);
261 source = (NTV2InputSource) ((int) source + 1);
262 }
263 if (source == NTV2_INPUTSOURCE_INVALID) {
264 throw string("Unknown source " + it.second + "!");
265 }
266 } else if (it.first == "format") {
267 NTV2VideoFormat format = NTV2VideoFormat();
268 while (format != NTV2_MAX_NUM_VIDEO_FORMATS) {
269 if (NTV2VideoFormatToString(format) == it.second) {
270 mVideoFormat = format;
271 break;
272 }
273 format = (NTV2VideoFormat) ((int) format + 1);
274 }
275 if (format == NTV2_MAX_NUM_VIDEO_FORMATS) {
276 throw string("Unknown format " + it.second + "!");
277 }
278 } else if (it.first == "RGB") {
279 if (colorSpaceSet && mInputIsRGB != true) {
280 throw string("Both RGB and YUV input specified!") + it.first;
281 }
282 colorSpaceSet = true;
283 mInputIsRGB = true;
284 } else if (it.first == "YUV") {
285 if (colorSpaceSet && mInputIsRGB != false) {
286 throw string("Both RGB and YUV input specified!") + it.first;
287 }
288 colorSpaceSet = true;
289 mInputIsRGB = false;
290 } else {
291 throw string("Unknown option: ") + it.first;
292 }
293 }
294
295 if (!NTV2_INPUT_SOURCE_IS_SDI(mInputSource) && mInputChannel == NTV2_CHANNEL_INVALID) {
296 LOG(LOG_LEVEL_NOTICE) << MOD_NAME "Non-SDI source detected - we will use "
297 "probably channel 1. Consider passing \"channel\" option (see help).\n";
298 }
299
300 if (mPixelFormat == NTV2_FBF_INVALID) {
301 if (colorSpaceSet && mInputIsRGB) {
302 mPixelFormat = NTV2_FBF_ABGR;
303 } else {
304 mPixelFormat = NTV2_FBF_8BIT_YCBCR;
305 }
306 }
307
308 if (!colorSpaceSet) {
309 mInputIsRGB = IsRGBFormat(mPixelFormat);
310 }
311
312 if (audioFlags & VIDCAP_FLAG_AUDIO_EMBEDDED) {
313 // this maps according to mInputSource - EMBEDDED (SDI), HDMI or ANALOG
314 mAudioSource = NTV2InputSourceToAudioSource(mInputSource);
315 } else if (audioFlags & VIDCAP_FLAG_AUDIO_AESEBU) {
316 mAudioSource = NTV2_AUDIO_AES;
317 } else if (audioFlags & VIDCAP_FLAG_AUDIO_ANALOG) {
318 mAudioSource = NTV2_AUDIO_ANALOG;
319 } else {
320 mAudioSource = NTV2_AUDIO_SOURCE_INVALID;
321 }
322
323 Init();
324}
codec_t get_codec_from_name(const char *name)
bool mProgressive
Definition aja.cpp:193
bool mCheckFor4K
Definition aja.cpp:201
NTV2InputSource mInputSource
Wide VANC?
Definition aja.cpp:182
bool mClearRouting
Definition aja.cpp:203
NTV2Channel mInputChannel
Used to restore prior every-frame task mode.
Definition aja.cpp:177
NTV2AudioSource mAudioSource
Definition aja.cpp:198
unsigned int mDeviceIndex
Definition aja.cpp:173
NTV2VideoFormat mVideoFormat
My input channel.
Definition aja.cpp:178
bool mInputIsRGB
SDI Input is in RGB otherwise YCbCr.
Definition aja.cpp:204
void Init()
Definition aja.cpp:330
NTV2FrameBufferFormat mPixelFormat
My video format.
Definition aja.cpp:179
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG(level)
Definition debug.h:313
static const std::map< NTV2FrameBufferFormat, codec_t > codec_map
struct _source source
Definition rtp.c:206
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
#define MOD_NAME
Definition aja.cpp:110
#define VIDCAP_FLAG_AUDIO_AESEBU
AES/EBU audio.
#define VIDCAP_FLAG_AUDIO_ANALOG
(balanced) analog audio
#define VIDCAP_FLAG_AUDIO_EMBEDDED
HD-SDI embedded audio.

References ultragrid::aja::codec_map, get_codec_from_name(), Init(), LOG, LOG_LEVEL_NOTICE, mAudioSource, mCheckFor4K, mClearRouting, mDeviceIndex, mInputChannel, mInputIsRGB, mInputSource, MOD_NAME, mPixelFormat, mProgressive, mVideoFormat, VIDCAP_FLAG_AUDIO_AESEBU, VIDCAP_FLAG_AUDIO_ANALOG, VIDCAP_FLAG_AUDIO_EMBEDDED, and VIDEO_CODEC_NONE.

Here is the call graph for this function:

◆ ~vidcap_state_aja()

vidcap_state_aja::~vidcap_state_aja ( )
virtual

Definition at line 391 of file aja.cpp.

391 {
392 // Unsubscribe from input vertical event...
393 CHECK(mDevice.UnsubscribeInputVerticalEvent (mInputChannel));
394
395 CHECK(mDevice.SetEveryFrameServices (mSavedTaskMode)); // Restore previous service level
396#ifndef _MSC_VER
397 CHECK(mDevice.ReleaseStreamForApplication (app, static_cast <uint32_t> (getpid()))); // Release the device
398#endif
399
400 mOutputFrame = NULL;
401 free(mAudio.data);
402}
NTV2EveryFrameTaskMode mSavedTaskMode
My device identifier.
Definition aja.cpp:176
CNTV2Card mDevice
Definition aja.cpp:174
shared_ptr< video_frame > mOutputFrame
Definition aja.cpp:188
#define CHECK(cmd)
Definition aja.cpp:135
static const ULWord app
Definition aja.cpp:162

References app, CHECK, mDevice, mInputChannel, mOutputFrame, and mSavedTaskMode.

Member Function Documentation

◆ CaptureFrames()

void vidcap_state_aja::CaptureFrames ( void )
privatevirtual

Definition at line 817 of file aja.cpp.

818{
819 uint32_t currentInFrame = mInputChannel * 2; // Will ping-pong between 0 and 1
820
821 uint32_t currentAudioInAddress = 0;
822 uint32_t audioReadOffset = 0;
823 uint32_t audioInWrapAddress = 0;
824 uint32_t audioOutWrapAddress = 0;
825 uint32_t audioBytesCaptured = 0;
826 NTV2FieldID fieldID = NTV2_VIDEO_FORMAT_HAS_PROGRESSIVE_PICTURE(mVideoFormat) ? NTV2_FIELD0 : NTV2_FIELD1;
827
828 CHECK(mDevice.GetAudioReadOffset (audioReadOffset, mAudioSystem));
829 CHECK(mDevice.GetAudioWrapAddress (audioOutWrapAddress, mAudioSystem));
830
831 // Wait to make sure the next two SDK calls will be made during the same frame...
832 CHECK(mDevice.WaitForInputFieldID (fieldID, mInputChannel));
833
834 currentInFrame ^= 1;
835 CHECK(mDevice.SetInputFrame (mInputChannel, currentInFrame));
836
837 // Wait until the hardware starts filling the new buffers, and then start audio
838 // capture as soon as possible to match the video...
839 CHECK(mDevice.WaitForInputFieldID (fieldID, mInputChannel));
840 CHECK(mDevice.StartAudioInput(mAudioSystem));
841
842 mAudioInLastAddress = audioReadOffset;
843 audioInWrapAddress = audioOutWrapAddress + audioReadOffset;
844
845 currentInFrame ^= 1;
846 CHECK(mDevice.SetInputFrame (mInputChannel, currentInFrame));
847
848 while (!mGlobalQuit) {
849 uint32_t *pHostAudioBuffer = NULL;
850 // Wait until the input has completed capturing a frame...
851 CHECK(mDevice.WaitForInputFieldID (fieldID, mInputChannel));
852
853 if (mAudioSource != NTV2_AUDIO_SOURCE_INVALID) {
854 pHostAudioBuffer = reinterpret_cast <uint32_t *> (aligned_malloc(NTV2_AUDIOSIZE_MAX, AJA_PAGE_SIZE));
855 // Read the audio position registers as close to the interrupt as possible...
856 CHECK(mDevice.ReadAudioLastIn (currentAudioInAddress, NTV2AudioSystem(mInputChannel)));
857 currentAudioInAddress &= ~0x7f; // Force 128 B alignment (originally there was 4 bytes)
858 currentAudioInAddress += audioReadOffset;
859
860 if (((currentAudioInAddress + (audioInWrapAddress - audioReadOffset) - mAudioInLastAddress)
861 % (audioInWrapAddress - audioReadOffset)) > NTV2_AUDIOSIZE_MAX) {
862 LOG(LOG_LEVEL_WARNING) << MOD_NAME "Discarding audio samples!\n";
863 mAudioInLastAddress = (currentAudioInAddress + audioInWrapAddress - NTV2_AUDIOSIZE_MAX) % audioInWrapAddress;
864 }
865
866 if (currentAudioInAddress < mAudioInLastAddress) {
867 // Audio address has wrapped around the end of the buffer.
868 // Do the calculations and transfer from the last address to the end of the buffer...
869 audioBytesCaptured = audioInWrapAddress - mAudioInLastAddress;
870
871 CHECK(mDevice.DMAReadAudio (mAudioSystem, pHostAudioBuffer, mAudioInLastAddress, audioBytesCaptured));
872
873 // Transfer the new samples from the start of the buffer to the current address...
874 CHECK(mDevice.DMAReadAudio (mAudioSystem, &pHostAudioBuffer [audioBytesCaptured / sizeof (uint32_t)],
875 audioReadOffset, currentAudioInAddress - audioReadOffset));
876
877 audioBytesCaptured += currentAudioInAddress - audioReadOffset;
878 } else {
879 audioBytesCaptured = currentAudioInAddress - mAudioInLastAddress;
880
881 // No wrap, so just perform a linear DMA from the buffer...
882 CHECK(mDevice.DMAReadAudio (mAudioSystem, pHostAudioBuffer, mAudioInLastAddress, audioBytesCaptured));
883 }
884
885 mAudioInLastAddress = currentAudioInAddress;
886 }
887
888 // Flip sense of the buffers again to refer to the buffers that the hardware isn't using (i.e. the off-screen buffers)...
889 currentInFrame ^= 1;
890
891 shared_ptr<video_frame> out = mPool.get_frame();
892 // DMA the new frame to system memory...
893 CHECK(mDevice.DMAReadFrame (currentInFrame, reinterpret_cast<uint32_t *>(out->tiles[0].data), mVideoBufferSize));
894 if (out->color_spec == R12L) {
895 shared_ptr<video_frame> converted = mPool.get_frame();
896 vc_copylineR12AtoR12L((unsigned char *) converted->tiles[0].data, (unsigned char *) out->tiles[0].data, out->tiles[0].data_len, 0, 0, 0);
897 out = std::move(converted);
898 }
899
900 if (log_level >= LOG_LEVEL_DEBUG) {
901 NTV2_RP188 timecodeValue;
902 string timeCodeString;
903 // Use the embedded input time code...
904 CHECK(mDevice.GetRP188Data (mInputChannel, timecodeValue));
905 CRP188 inputRP188Info (timecodeValue);
906 CHECK(inputRP188Info.GetRP188Str (timeCodeString));
907 LOG(LOG_LEVEL_DEBUG) << "AJA: Captured frame with timecode: " << timeCodeString << '\n';
908 }
909
910 // Check for dropped frames by ensuring the hardware has not started to process
911 // the buffers that were just filled....
912 uint32_t readBackIn;
913 CHECK(mDevice.GetInputFrame (mInputChannel, readBackIn));
914
915 if (readBackIn == currentInFrame) {
917 << MOD_NAME
918 << "## WARNING: Drop detected: current in "
919 << currentInFrame << ", readback in " << readBackIn
920 << "\n";
921 }
922
923 // Tell the hardware which buffers to start using at the beginning of the next frame...
924 CHECK(mDevice.SetInputFrame (mInputChannel, currentInFrame));
925
926 unique_lock<mutex> lk(mOutputFrameLock);
927 mOutputFrame = std::move(out);
928 mOutputAudioFrame = shared_ptr<uint32_t>(pHostAudioBuffer, aligned_free);
929 mOutputAudioFrameSize = audioBytesCaptured;
930 lk.unlock();
931 mOutputFrameReady.notify_one();
932 } // loop til quit signaled
933} // CaptureFrames
void vc_copylineR12AtoR12L(unsigned char *__restrict dst, const unsigned char *__restrict src, int dstlen, int rshift, int gshift, int bshift)
size_t mOutputAudioFrameSize
Definition aja.cpp:190
shared_ptr< uint32_t > mOutputAudioFrame
Definition aja.cpp:189
uint32_t mVideoBufferSize
The audio system I'm using.
Definition aja.cpp:184
mutex mOutputFrameLock
Definition aja.cpp:191
NTV2AudioSystem mAudioSystem
The input source I'm using.
Definition aja.cpp:183
video_frame_pool mPool
My producer thread object – does the frame capturing.
Definition aja.cpp:187
condition_variable mOutputFrameReady
Definition aja.cpp:192
uint32_t mAudioInLastAddress
My record of the location of the last audio sample captured.
Definition aja.cpp:202
bool mGlobalQuit
Definition aja.cpp:205
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
volatile int log_level
Definition debug.cpp:65
static void * aligned_malloc(size_t size, size_t alignment)
#define aligned_free
std::shared_ptr< video_frame > get_frame()
@ R12L
RGB 12-bit packed, little-endian.
Definition types.h:74
#define NTV2_AUDIOSIZE_MAX
Definition aja.cpp:106

References aligned_free, aligned_malloc(), CHECK, video_frame_pool::get_frame(), LOG, log_level, LOG_LEVEL_DEBUG, LOG_LEVEL_WARNING, mAudioInLastAddress, mAudioSource, mAudioSystem, mDevice, mGlobalQuit, mInputChannel, MOD_NAME, mOutputAudioFrame, mOutputAudioFrameSize, mOutputFrame, mOutputFrameLock, mOutputFrameReady, mPool, mVideoBufferSize, mVideoFormat, NTV2_AUDIOSIZE_MAX, R12L, and vc_copylineR12AtoR12L().

Referenced by ProducerThreadStatic().

Here is the call graph for this function:

◆ EnableInput()

void vidcap_state_aja::EnableInput ( NTV2InputSource source)
private

Definition at line 459 of file aja.cpp.

460{
461 // Bi-directional SDI connectors need to be set to capture...
462 if (NTV2DeviceHasBiDirectionalSDI (mDeviceID) && NTV2_INPUT_SOURCE_IS_SDI (source))
463 {
464 NTV2Channel channel = ::NTV2InputSourceToChannel(source);
465 CHECK(mDevice.SetSDITransmitEnable (channel, false)); // Disable transmit mode...
466 for (unsigned ndx (0); ndx < 10; ndx++)
467 CHECK(mDevice.WaitForInputVerticalInterrupt (channel)); // ...and give the device some time to lock to a signal
468 }
469
470}
NTV2DeviceID mDeviceID
Definition aja.cpp:175

References CHECK, mDevice, and mDeviceID.

Referenced by GetVideoFormatFromInputSource().

◆ GetVideoFormatFromInputSource()

NTV2VideoFormat vidcap_state_aja::GetVideoFormatFromInputSource ( )
private

Definition at line 404 of file aja.cpp.

405{
406 NTV2VideoFormat videoFormat (NTV2_FORMAT_UNKNOWN);
407
408 switch (mInputSource)
409 {
410 case NTV2_INPUTSOURCE_SDI1:
411 case NTV2_INPUTSOURCE_SDI5:
412 {
413 NTV2InputSource source;
414 const ULWord ndx (::GetIndexForNTV2InputSource (mInputSource));
415 if (::NTV2DeviceCanDoMultiFormat (mDeviceID))
416 CHECK(mDevice.SetMultiFormatMode (true));
417 source = ::GetNTV2InputSourceForIndex (ndx + 0);
419 videoFormat = mDevice.GetInputVideoFormat(source, mProgressive);
420 NTV2Standard videoStandard (::GetNTV2StandardFromVideoFormat (videoFormat));
421 if (mCheckFor4K && (videoStandard == NTV2_STANDARD_1080p))
422 {
423 if (::NTV2DeviceCanDoMultiFormat (mDeviceID))
424 CHECK(mDevice.SetMultiFormatMode (false));
425 int i;
426 bool allSDISameInput = true;
427 NTV2VideoFormat videoFormatNext;
428 for (i = 1; i < 4; i++) {
429 source = ::GetNTV2InputSourceForIndex (ndx + i);
431 videoFormatNext = mDevice.GetInputVideoFormat (source, mProgressive);
432 if (videoFormatNext != videoFormat) {
433 allSDISameInput = false;
434 break;
435 }
436 }
437 if (allSDISameInput)
438 videoFormat = GetQuadSizedVideoFormat(videoFormat);
439 else
440 LOG(LOG_LEVEL_WARNING) << "Input " << NTV2InputSourceToString(::GetNTV2InputSourceForIndex(ndx + i), true) << " has input format " << NTV2VideoFormatToString(videoFormatNext) << " which differs from " << NTV2VideoFormatToString(videoFormat) << " on " << NTV2InputSourceToString(::GetNTV2InputSourceForIndex(ndx), true) << "!\n";
441 }
442 if (mCheckFor4K && (videoStandard != NTV2_STANDARD_1080p)) {
443 log_msg(LOG_LEVEL_WARNING, "Video format on first SDI is not 1080p!\n");
444 }
445 break;
446 }
447
448 case NTV2_NUM_INPUTSOURCES:
449 break; // indicates no source is currently selected
450
451 default:
452 videoFormat = mDevice.GetInputVideoFormat (mInputSource, mProgressive);
453 break;
454 }
455
456 return videoFormat;
457} // GetVideoFormatFromInputSource
void EnableInput(NTV2InputSource source)
Definition aja.cpp:459
void log_msg(int level, const char *format,...)
Definition debug.cpp:130

References CHECK, EnableInput(), LOG, LOG_LEVEL_WARNING, log_msg(), mCheckFor4K, mDevice, mDeviceID, mInputSource, and mProgressive.

Referenced by SetupVideo().

Here is the call graph for this function:

◆ grab()

struct video_frame * vidcap_state_aja::grab ( struct audio_frame ** audio)

Definition at line 935 of file aja.cpp.

936{
937 if (mGlobalQuit) {
938 return NULL;
939 }
940
941 struct video_frame *ret;
942
943 unique_lock<mutex> lk(mOutputFrameLock);
944 if (mOutputFrameReady.wait_for(lk, chrono::milliseconds(100), [this]{return mOutputFrame != NULL;}) == false) {
945 return NULL;
946 }
947
948 ret = mOutputFrame.get();
949 ret->callbacks.dispose_udata = new shared_ptr<video_frame>(mOutputFrame);
950 static auto dispose = [](video_frame *f) { delete static_cast<shared_ptr<video_frame> *>(f->callbacks.dispose_udata); };
951 ret->callbacks.dispose = dispose;
952
953 mOutputFrame = NULL;
954
955 if (mOutputAudioFrame) {
956 for (int i = 0; i < mAudio.ch_count; ++i) {
957 remux_channel(mAudio.data, (char *) mOutputAudioFrame.get(), mAudio.bps, mOutputAudioFrameSize, mMaxAudioChannels, mAudio.ch_count, i, i);
958 }
959 mAudio.data_len = mOutputAudioFrameSize / mMaxAudioChannels * mAudio.ch_count;
960 mOutputAudioFrame = NULL;
961 *audio = &mAudio;
962 } else {
963 *audio = NULL;
964 }
965
966 lk.unlock();
967
968 mFrames += 1;
969
970 chrono::system_clock::time_point now = chrono::system_clock::now();
971 double seconds = chrono::duration_cast<chrono::microseconds>(now - mT0).count() / 1000000.0;
972
973 if (seconds >= 5) {
974 LOG(LOG_LEVEL_INFO) << MOD_NAME "" << mFrames << " frames in "
975 << seconds << " seconds = " << mFrames / seconds << " FPS\n";
976 mT0 = now;
977 mFrames = 0;
978 }
979
980 return ret;
981}
struct audio_frame ** audio
chrono::system_clock::time_point mT0
Definition aja.cpp:194
int mMaxAudioChannels
Definition aja.cpp:197
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
void(* dispose)(struct video_frame *)
Definition types.h:245
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
struct video_frame_callbacks callbacks
Definition types.h:324
void remux_channel(char *out, const char *in, int bps, int in_len, int in_stream_channels, int out_stream_channels, int pos_in_stream, int pos_out_stream)
Definition utils.cpp:352

References audio, video_frame::callbacks, video_frame_callbacks::dispose, video_frame_callbacks::dispose_udata, LOG, LOG_LEVEL_INFO, mFrames, mGlobalQuit, mMaxAudioChannels, MOD_NAME, mOutputAudioFrame, mOutputAudioFrameSize, mOutputFrame, mOutputFrameLock, mOutputFrameReady, mT0, and remux_channel().

Here is the call graph for this function:

◆ Init()

void vidcap_state_aja::Init ( )

Definition at line 330 of file aja.cpp.

331{
332 AJAStatus status (AJA_STATUS_SUCCESS);
333
334 // Open the device...
335 CNTV2DeviceScanner deviceScanner;
336
337 // Any AJA devices out there?
338 if (deviceScanner.GetNumDevices () == 0)
339 throw string("No devices found!");
340
341 if (mDeviceIndex >= deviceScanner.GetNumDevices ()) {
342 throw string("Device index exceeds number of available devices!");
343 }
344
345 // Using a reference to the discovered device list,
346 // and the index number of the device of interest (mDeviceIndex),
347 // get information about that particular device...
348 if (!mDevice.Open (mDeviceIndex))
349 throw string("Unable to open device.");
350
351 if (mClearRouting) {
352 CHECK_OK(mDevice.ClearRouting(), "ClearRouting", NOOP);
353 }
354
355 ULWord fourcc = app;
356#ifndef _MSC_VER
357 if (get_commandline_param("aja-fourcc")) {
358 const char *fcc_req = get_commandline_param("aja-fourcc");
359 char fcc_s[4] = "";
360 // trim or pad with spaces
361 memcpy(fcc_s, fcc_req, min<int>(strlen(fcc_req), 4));
362 fourcc = AJA_FOURCC(fcc_s[0], fcc_s[1], fcc_s[2], fcc_s[3]);
363 }
364
365 if (!mDevice.AcquireStreamForApplication (fourcc, static_cast <uint32_t> (getpid())))
366 throw string("Cannot aquire stream.");
367#endif
368
369 CHECK(mDevice.GetEveryFrameServices (mSavedTaskMode)); // Save the current state before we change it
370 CHECK(mDevice.SetEveryFrameServices (NTV2_OEM_TASKS));
371
372 // Keep the device ID handy as it will be used frequently...
373 mDeviceID = mDevice.GetDeviceID ();
374
375 // Set up the video and audio...
376 status = SetupVideo ();
377 if (AJA_FAILURE (status))
378 throw string("Cannot setup video. Err = ") + to_string(status);
379
380 status = SetupAudio ();
381 if (AJA_FAILURE (status))
382 throw string("Cannot setup audio. Err = ") + to_string(status);
383
384 // Set up the circular buffers, the device signal routing, and both playout and capture Auto Circulate...
386
387 // This is for the timecode that we will burn onto the image...
388 //NTV2FormatDescriptor fd = GetFormatDescriptor (GetNTV2StandardFromVideoFormat (mVideoFormat), mPixelFormat, mVancEnabled, Is2KFormat (mVideoFormat), mWideVanc);
389}
AJAStatus SetupAudio()
Definition aja.cpp:699
AJAStatus SetupVideo()
Definition aja.cpp:557
void SetupHostBuffers()
Definition aja.cpp:753
const char * get_commandline_param(const char *key)
Definition host.cpp:894
#define CHECK_OK(cmd, msg, action_failed)
Definition aja.cpp:127
#define NOOP
Definition aja.cpp:132

References app, CHECK, CHECK_OK, get_commandline_param(), mClearRouting, mDevice, mDeviceID, mDeviceIndex, mSavedTaskMode, NOOP, SetupAudio(), SetupHostBuffers(), and SetupVideo().

Referenced by vidcap_state_aja().

Here is the call graph for this function:

◆ IsInput3Gb()

bool vidcap_state_aja::IsInput3Gb ( const NTV2InputSource inputSource)
private

Definition at line 983 of file aja.cpp.

984{
985 bool is3Gb (false);
986
987 CHECK(mDevice.GetSDIInput3GbPresent (is3Gb, ::NTV2InputSourceToChannel (inputSource)));
988
989 return is3Gb;
990}

References CHECK, and mDevice.

Referenced by SetupVideo().

◆ ProducerThreadStatic()

void vidcap_state_aja::ProducerThreadStatic ( vidcap_state_aja * pContext)
staticprivate

Definition at line 811 of file aja.cpp.

812{
813 pContext->CaptureFrames ();
814
815} // ProducerThreadStatic
virtual void CaptureFrames(void)
Definition aja.cpp:817

References CaptureFrames().

Referenced by StartProducerThread().

Here is the call graph for this function:

◆ Quit()

void vidcap_state_aja::Quit ( )

Definition at line 789 of file aja.cpp.

790{
791 // Set the global 'quit' flag, and wait for the threads to go inactive...
792 mGlobalQuit = true;
793
794 mProducerThread.join();
795
796 // Don't leave the audio system active after we exit
797 CHECK(mDevice.StopAudioInput(mAudioSystem));
798} // Quit
thread mProducerThread
My audio buffer size, in bytes.
Definition aja.cpp:186

References CHECK, mAudioSystem, mDevice, mGlobalQuit, and mProducerThread.

Referenced by vidcap_aja_done().

◆ Run()

AJAStatus vidcap_state_aja::Run ( )

Definition at line 774 of file aja.cpp.

775{
776 // Check that there's a valid input to capture
777 if (mDevice.GetInputVideoFormat(mInputSource, mProgressive) ==
778 NTV2_FORMAT_UNKNOWN) {
779 MSG(WARNING, "## WARNING: No video signal present on the "
780 "input connector\n");
781 }
782
783 // Start the playout and capture threads...
785
786 return AJA_STATUS_SUCCESS;
787}
virtual void StartProducerThread(void)
Starts my frame consumer thread.
Definition aja.cpp:803
#define MSG(l, fmt,...)
Definition debug.h:96

References mDevice, mInputSource, mProgressive, MSG, and StartProducerThread().

Referenced by vidcap_aja_init().

Here is the call graph for this function:

◆ SetupAudio()

AJAStatus vidcap_state_aja::SetupAudio ( void )
private

Definition at line 699 of file aja.cpp.

700{
701 if (mAudioSource == NTV2_AUDIO_SOURCE_INVALID) {
702 LOG(LOG_LEVEL_INFO) << MOD_NAME "Audio capture disabled.\n";
703 return AJA_STATUS_SUCCESS;
704 }
705 // Have the audio system capture audio from the designated device input...
706 CHECK_OK(mDevice.SetAudioSystemInputSource(mAudioSystem, mAudioSource, ::NTV2InputSourceToEmbeddedAudioInput(mInputSource)), string("Cannot set audio input source: ") + NTV2AudioSourceToString(mAudioSource), NOOP);
707
708 mMaxAudioChannels = ::NTV2DeviceGetMaxAudioChannels (mDeviceID);
710 if (mMaxAudioChannels < mAudio.ch_count) {
711 LOG(LOG_LEVEL_ERROR) << MOD_NAME "Invalid number of capture channels requested. Requested " <<
712 mAudio.ch_count << ", maximum " << mMaxAudioChannels << "\n";
713 return AJA_STATUS_FAIL;
714 }
715 if (!mDevice.SetNumberAudioChannels (mMaxAudioChannels, NTV2InputSourceToAudioSystem(mInputSource))) {
716 LOG(LOG_LEVEL_ERROR) << MOD_NAME "Unable to set channel count!\n";
717 return AJA_STATUS_FAIL;
718 }
719 CHECK(mDevice.SetAudioRate (NTV2_AUDIO_48K, NTV2InputSourceToAudioSystem(mInputSource)));
720
721 // How big should the on-device audio buffer be? 1MB? 2MB? 4MB? 8MB?
722 // For this demo, 4MB will work best across all platforms (Windows, Mac & Linux)...
723 CHECK(mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, NTV2InputSourceToAudioSystem(mInputSource)));
724
725 //
726 // Loopback mode plays whatever audio appears in the input signal when it's
727 // connected directly to an output (i.e., "end-to-end" mode). If loopback is
728 // left enabled, the video will lag the audio as video frames get briefly delayed
729 // in our ring buffer. Audio, therefore, needs to come out of the (buffered) fram
730 // data being played, so loopback must be turned off...
731 //
732 CHECK(mDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, mAudioSystem));
733
734 // Reset both the input and output sides of the audio system so that the buffer
735 // pointers are reset to zero and inhibited from advancing.
736 CHECK(mDevice.StopAudioInput(mAudioSystem));
737
738 // Ensure that the audio system will capture samples when the reset is removed
739 CHECK(mDevice.SetAudioCaptureEnable (mAudioSystem, true));
740
741 mAudio.bps = 4;
742 mAudio.sample_rate = 48000;
743 mAudio.data = (char *) malloc(NTV2_AUDIOSIZE_MAX);
744 mAudio.max_size = NTV2_AUDIOSIZE_MAX;
745
746#ifndef _MSC_VER
747 LOG(LOG_LEVEL_NOTICE) << "AJA audio capture initialized successfully: " << audio_desc_from_frame(&mAudio) << "\n";
748#endif
749
750 return AJA_STATUS_SUCCESS;
751} // SetupAudio
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define DEFAULT_AUDIO_CAPTURE_CHANNELS
Definition host.h:89
struct audio_desc audio_desc_from_frame(const struct audio_frame *frame)
Definition utils.cpp:196
unsigned int * aja_audio_capture_channels
Definition aja.cpp:118

References aja_audio_capture_channels, audio_desc_from_frame(), CHECK, CHECK_OK, DEFAULT_AUDIO_CAPTURE_CHANNELS, LOG, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, mAudioSource, mAudioSystem, mDevice, mDeviceID, mInputSource, mMaxAudioChannels, MOD_NAME, NOOP, and NTV2_AUDIOSIZE_MAX.

Referenced by Init().

Here is the call graph for this function:

◆ SetupHDMI()

AJAStatus vidcap_state_aja::SetupHDMI ( )
private

Definition at line 475 of file aja.cpp.

476{
477 NTV2LHIHDMIColorSpace hdmiColor (NTV2_LHIHDMIColorSpaceRGB);
478 CHECK_RET_FAIL(mDevice.GetHDMIInputColor (hdmiColor, mInputChannel));
479 if (!mbFixedReference)
480 CHECK_RET_FAIL(mDevice.SetReference (::NTV2InputSourceToReferenceSource(mInputSource)));
481
482 // configure hdmi with 2.0 support
483 if (NTV2_IS_4K_VIDEO_FORMAT (mVideoFormat) && !mDevice.features().CanDoHDMIQuadRasterConversion()) {
484 // Set two sample interleave
485 CHECK_RET_FAIL(mDevice.SetTsiFrameEnable(true, mInputChannel));
486
487 for (unsigned offset = 0; offset < 2; ++offset) {
488 NTV2Channel channel = (NTV2Channel) ((int) mInputChannel + offset);
489 CHECK_RET_FAIL(mDevice.EnableChannel (channel));
490 CHECK_RET_FAIL(mDevice.SetMode (channel, NTV2_MODE_CAPTURE));
491 CHECK_RET_FAIL(mDevice.SetFrameBufferFormat (channel, mPixelFormat));
492 }
493
494 for (unsigned offset = 0; offset < 4; ++offset) {
495 if ((hdmiColor == NTV2_LHIHDMIColorSpaceYCbCr && IsRGBFormat(mPixelFormat))
496 || (hdmiColor == NTV2_LHIHDMIColorSpaceRGB && !IsRGBFormat(mPixelFormat))) {
497 NTV2Channel channel = (NTV2Channel) ((int) mInputChannel + offset);
498 CHECK_RET_FAIL(mDevice.Connect (::GetCSCInputXptFromChannel (channel),
499 ::GetInputSourceOutputXpt (mInputSource, false/*isSDI_DS2*/,
500 hdmiColor == NTV2_LHIHDMIColorSpaceRGB /*isHDMI_RGB*/, offset/*hdmiQuadrant*/)));
501 CHECK_RET_FAIL(mDevice.Connect (GetTSIMuxInputXptFromChannel((NTV2Channel) offset, false/* inLinkB */), GetCSCOutputXptFromChannel (channel, false/* inIsKey */, hdmiColor != NTV2_LHIHDMIColorSpaceRGB /* inIsRGB */)));
502 } else {
503 CHECK_RET_FAIL(mDevice.Connect (GetTSIMuxInputXptFromChannel((NTV2Channel) offset, false/* inLinkB */), ::GetInputSourceOutputXpt (mInputSource, false/*isSDI_DS2*/, hdmiColor == NTV2_LHIHDMIColorSpaceRGB /*isHDMI_RGB*/, offset /*hdmiQuadrant*/)));
504 }
505 }
506
507 for (unsigned offset = 0; offset < 4; ++offset) {
508 CHECK_RET_FAIL(mDevice.Connect(GetFrameBufferInputXptFromChannel((NTV2Channel) (offset / 2) /* inChannel */, offset % 2 == 1 /* inIsBInput */),
509 GetTSIMuxOutputXptFromChannel((NTV2Channel) (offset / 2), offset % 2 == 1 /* inLinkB */)));
510 }
511 } else if (NTV2_IS_4K_VIDEO_FORMAT (mVideoFormat) && mDevice.features().CanDoHDMIQuadRasterConversion()) {
512 CHECK_RET_FAIL(mDevice.SetTsiFrameEnable(false, mInputChannel));
513 for (unsigned offset = 0; offset < 4; ++offset) {
514 NTV2Channel channel = (NTV2Channel) ((int) mInputChannel + offset);
515 CHECK_RET_FAIL(mDevice.EnableChannel (channel));
516 CHECK_RET_FAIL(mDevice.SetMode (channel, NTV2_MODE_CAPTURE));
517 CHECK_RET_FAIL(mDevice.SetFrameBufferFormat (channel, mPixelFormat));
518 if ((hdmiColor == NTV2_LHIHDMIColorSpaceYCbCr && IsRGBFormat(mPixelFormat))
519 || (hdmiColor == NTV2_LHIHDMIColorSpaceRGB && !IsRGBFormat(mPixelFormat))) {
520 CHECK_RET_FAIL(mDevice.Connect (::GetCSCInputXptFromChannel (channel),
521 ::GetInputSourceOutputXpt (mInputSource, false/*isSDI_DS2*/, hdmiColor == NTV2_LHIHDMIColorSpaceRGB /*isHDMI_RGB*/, channel /*hdmiQuadrant*/)));
522 CHECK_RET_FAIL(mDevice.Connect (::GetFrameBufferInputXptFromChannel (channel),
523 ::GetCSCOutputXptFromChannel (channel, false/*isKey*/, hdmiColor != NTV2_LHIHDMIColorSpaceRGB /*isRGB*/)));
524 } else {
525 CHECK_RET_FAIL(mDevice.Connect (::GetFrameBufferInputXptFromChannel (channel),
526 ::GetInputSourceOutputXpt (mInputSource, false/*isSDI_DS2*/, hdmiColor == NTV2_LHIHDMIColorSpaceRGB /*isHDMI_RGB*/, channel /*hdmiQuadrant*/)));
527 }
528 } // loop once for each channel (4 times for 4K/UHD)
529 } else {
530 CHECK_RET_FAIL(mDevice.EnableChannel (mInputChannel));
531 CHECK_RET_FAIL(mDevice.SetMode (mInputChannel, NTV2_MODE_CAPTURE));
532 CHECK_RET_FAIL(mDevice.SetFrameBufferFormat (mInputChannel, mPixelFormat));
533 if ((hdmiColor == NTV2_LHIHDMIColorSpaceYCbCr && IsRGBFormat(mPixelFormat))
534 || (hdmiColor == NTV2_LHIHDMIColorSpaceRGB && !IsRGBFormat(mPixelFormat))) {
535 CHECK_RET_FAIL(mDevice.Connect (::GetCSCInputXptFromChannel (mInputChannel),
536 ::GetInputSourceOutputXpt (mInputSource, false/*isSDI_DS2*/, hdmiColor == NTV2_LHIHDMIColorSpaceRGB /*isHDMI_RGB*/, 0/*hdmiQuadrant*/)));
537 CHECK_RET_FAIL(mDevice.Connect (::GetFrameBufferInputXptFromChannel (mInputChannel),
538 ::GetCSCOutputXptFromChannel (mInputChannel, false/*isKey*/, hdmiColor != NTV2_LHIHDMIColorSpaceRGB /*isRGB*/)));
539 } else {
540 CHECK_RET_FAIL(mDevice.Connect (::GetFrameBufferInputXptFromChannel (mInputChannel),
541 ::GetInputSourceOutputXpt (mInputSource, false/*isSDI_DS2*/, hdmiColor == NTV2_LHIHDMIColorSpaceRGB /*isHDMI_RGB*/, 0/*hdmiQuadrant*/)));
542 }
543 }
544
545 // configure the qrc if present
546 if (NTV2DeviceGetHDMIVersion(mDeviceID) == 2) {
547 if (NTV2_IS_4K_VIDEO_FORMAT (mVideoFormat)) {
548 CHECK_RET_FAIL(mDevice.SetHDMIV2Mode (NTV2_HDMI_V2_4K_CAPTURE));
549 } else {
550 CHECK_RET_FAIL(mDevice.SetHDMIV2Mode (NTV2_HDMI_V2_HDSD_BIDIRECTIONAL));
551 }
552 }
553
554 return AJA_STATUS_SUCCESS;
555}
bool mbFixedReference
Definition aja.cpp:200
static __device__ const float offset
Definition cuda_dxt.cu:139
#define CHECK_RET_FAIL(cmd)
Definition aja.cpp:134

References CHECK_RET_FAIL, mbFixedReference, mDevice, mDeviceID, mInputChannel, mInputSource, mPixelFormat, mVideoFormat, and offset.

Referenced by SetupVideo().

◆ SetupHostBuffers()

void vidcap_state_aja::SetupHostBuffers ( void )
private

Definition at line 753 of file aja.cpp.

754{
755 mVancMode = NTV2_VANCMODE_OFF;
756 mWideVanc = false;
757 CHECK(mDevice.GetVANCMode (mVancMode));
758 mVideoBufferSize = GetVideoWriteSize (mVideoFormat, mPixelFormat, mVancMode);
760
761 interlacing_t interlacing = NTV2_VIDEO_FORMAT_HAS_PROGRESSIVE_PICTURE(mVideoFormat) ? PROGRESSIVE : INTERLACED_MERGED;
762 video_desc desc{GetDisplayWidth(mVideoFormat), GetDisplayHeight(mVideoFormat),
764 GetFramesPerSecond(GetNTV2FrameRateFromVideoFormat(mVideoFormat)),
765 interlacing,
766 1};
768
769#ifndef _MSC_VER
770 LOG(LOG_LEVEL_NOTICE) << "Detected input video mode: " << desc << "\n";
771#endif
772} // SetupHostBuffers
struct video_desc desc
uint32_t mAudioBufferSize
My video buffer size, in bytes.
Definition aja.cpp:185
bool mWideVanc
VANC enabled?
Definition aja.cpp:181
NTV2VANCMode mVancMode
My pixel format.
Definition aja.cpp:180
void reconfigure(struct video_desc new_desc, size_t new_size=SIZE_MAX)
interlacing_t
Definition types.h:163
@ PROGRESSIVE
progressive frame
Definition types.h:164
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
Definition types.h:167

References CHECK, ultragrid::aja::codec_map, desc, INTERLACED_MERGED, LOG, LOG_LEVEL_NOTICE, mAudioBufferSize, mDevice, mPixelFormat, mPool, mVancMode, mVideoBufferSize, mVideoFormat, mWideVanc, NTV2_AUDIOSIZE_MAX, PROGRESSIVE, and video_frame_pool::reconfigure().

Referenced by Init().

Here is the call graph for this function:

◆ SetupVideo()

AJAStatus vidcap_state_aja::SetupVideo ( )
private

Definition at line 557 of file aja.cpp.

558{
559 // Set the video format to match the incomming video format.
560 // Does the device support the desired input source?
561 if (!::NTV2DeviceCanDoInputSource (mDeviceID, mInputSource))
562 return AJA_STATUS_BAD_PARAM; // Nope
563
564 if (mInputChannel == NTV2_CHANNEL_INVALID) {
565 mInputChannel = ::NTV2InputSourceToChannel (mInputSource);
566 }
567
568 if (UWord (mInputChannel) >= ::NTV2DeviceGetNumFrameStores (mDeviceID)) {
569 ostringstream oss;
570 oss << "## ERROR: Cannot use channel '" << mInputChannel+1 << "' -- device only supports channel 1"
571 << (::NTV2DeviceGetNumFrameStores (mDeviceID) > 1 ? string (" thru ") + string (1, uint8_t (::NTV2DeviceGetNumFrameStores (mDeviceID)+'0')) : "");
572 throw runtime_error(oss.str());
573 }
574
575 // Sometimes other applications disable some or all of the frame buffers, so turn on ours now..
576 CHECK_OK(mDevice.EnableChannel (mInputChannel), "Cannot enable channel", NOOP);
577
578 // Enable and subscribe to the interrupts for the channel to be used...
579 CHECK_OK(mDevice.EnableInputInterrupt (mInputChannel), "EnableInputInterrupt failed", NOOP);
580 CHECK_OK(mDevice.SubscribeInputVerticalEvent (mInputChannel), "SubscribeInputVerticalEvent failed", NOOP);
581
582 // Set the video format to match the incomming video format.
583 // Does the device support the desired input source?
584
585 // If the device supports bi-directional SDI and the
586 // requested input is SDI, ensure the SDI direction
587 // is configured for input...
588 if (::NTV2DeviceHasBiDirectionalSDI (mDeviceID) && NTV2_INPUT_SOURCE_IS_SDI (mInputSource))
589 {
590 CHECK_OK(mDevice.SetSDITransmitEnable (mInputChannel, false), "Cannot disable SDI transmit", NOOP);
591
592 // Give the input circuit some time (~10 frames) to lock onto the input signal...
593 CHECK_OK(mDevice.WaitForInputVerticalInterrupt (mInputChannel, 10), "Cannot wait for VBI", NOOP);
594 }
595
596 if (NTV2_INPUT_SOURCE_IS_SDI (mInputSource))
597 mTimeCodeSource = ::NTV2InputSourceToTimecodeIndex(mInputSource);
598 else if (NTV2_INPUT_SOURCE_IS_ANALOG (mInputSource))
599 mTimeCodeSource = NTV2_TCINDEX_LTC1;
600 else
601 mTimeCodeSource = NTV2_TCINDEX_DEFAULT;
602
603 // Determine the input video signal format...
604 if (mVideoFormat == NTV2_FORMAT_UNKNOWN) {
606 if (mVideoFormat == NTV2_FORMAT_UNKNOWN)
607 {
608 LOG(LOG_LEVEL_ERROR) << "## ERROR: No input signal or unknown format\n";
609 return AJA_STATUS_NOINPUT; // Sorry, can't handle this format
610 }
611 LOG(LOG_LEVEL_INFO) << MOD_NAME "Detected input signal: " << NTV2VideoFormatToString(mVideoFormat) << "\n";
612 }
613
614 mAudioSystem = ::NTV2ChannelToAudioSystem(mInputChannel);
615
616 // Set the device video format to whatever we detected at the input...
617 CHECK(mDevice.SetVideoFormat (mVideoFormat, false, false, mInputChannel));
618
619 // Set the frame buffer pixel format for all the channels on the device
620 // (assuming it supports that pixel format -- otherwise default to 8-bit YCbCr)...
621 if (!::NTV2DeviceCanDoFrameBufferFormat (mDeviceID, mPixelFormat))
622 mPixelFormat = NTV2_FBF_8BIT_YCBCR;
623
624 // Set the pixel format for both device frame buffers...
625 CHECK(mDevice.SetFrameBufferFormat (mInputChannel, mPixelFormat));
626
627 // Enable and subscribe to the interrupts for the channel to be used...
628 CHECK(mDevice.EnableInputInterrupt (mInputChannel));
629 CHECK(mDevice.SubscribeInputVerticalEvent (mInputChannel));
630
631 // Tell the hardware which buffers to use until the main worker thread runs
632 CHECK(mDevice.SetInputFrame (mInputChannel, 0));
633
634 // Set the Frame Store modes
635 CHECK(mDevice.SetMode (mInputChannel, NTV2_MODE_CAPTURE));
636
637 CHECK(mDevice.SetReference (NTV2_REFERENCE_FREERUN));
638
639 if (NTV2_INPUT_SOURCE_IS_SDI (mInputSource)) {
640 for (unsigned offset (0); offset < 4; offset++) {
641 NTV2Channel SDIChannel = (NTV2Channel) ((int) NTV2InputSourceToChannel (mInputSource) + offset);
642 NTV2Channel channel = (NTV2Channel) ((int) mInputChannel + offset);
643
644 if (mInputIsRGB) {
645 CHECK(mDevice.Connect (::GetDLInInputXptFromChannel(channel, false), ::GetSDIInputOutputXptFromChannel (SDIChannel, false))); // SDIIn ==> DLIn
646 CHECK(mDevice.Connect (::GetDLInInputXptFromChannel(channel, true), ::GetSDIInputOutputXptFromChannel (SDIChannel, true))); // SDIIn ==> DLIn
647 }
648
649 if (IsRGBFormat(mPixelFormat) && !mInputIsRGB) { // convert YUV->RGB
650 CHECK(mDevice.Connect (::GetCSCInputXptFromChannel (channel), ::GetSDIInputOutputXptFromChannel (SDIChannel)));
651 CHECK(mDevice.Connect (::GetFrameBufferInputXptFromChannel (channel), ::GetCSCOutputXptFromChannel (SDIChannel, false/*isKey*/, true/*isRGB*/)));
652 } else if (IsRGBFormat(mPixelFormat) && mInputIsRGB) { // RGB->RGB
653 CHECK(mDevice.Connect (::GetFrameBufferInputXptFromChannel (channel), ::GetDLInOutputXptFromChannel(SDIChannel))); // DLOut ==> FBRGB
654 } else if (!IsRGBFormat(mPixelFormat) && !mInputIsRGB) { // YUV->YUV
655 CHECK(mDevice.Connect (::GetFrameBufferInputXptFromChannel (channel), ::GetSDIInputOutputXptFromChannel (SDIChannel)));
656 } else { // RGB->YUV
657 CHECK(mDevice.Connect (::GetCSCInputXptFromChannel (channel), ::GetDLInOutputXptFromChannel(SDIChannel)));
658 CHECK(mDevice.Connect (::GetFrameBufferInputXptFromChannel (channel), ::GetCSCOutputXptFromChannel (SDIChannel, false/*isKey*/, true/*isRGB*/)));
659 }
660
661 CHECK(mDevice.SetFrameBufferFormat (channel, mPixelFormat));
662 CHECK(mDevice.EnableChannel (channel));
663 CHECK(mDevice.SetSDIInLevelBtoLevelAConversion (SDIChannel, IsInput3Gb (mInputSource) && !mInputIsRGB ? true : false));
664 if (!NTV2_IS_4K_VIDEO_FORMAT (mVideoFormat))
665 break;
666 CHECK(mDevice.Set4kSquaresEnable(true, mInputChannel));
667 }
668 } else if (NTV2_INPUT_SOURCE_IS_ANALOG(mInputSource)) {
669 //mDevice.SetTsiFrameEnable(false, NTV2_CHANNEL1);
670
671 if (IsRGBFormat(mPixelFormat)) {
672 CHECK(mDevice.Connect (::GetCSCInputXptFromChannel (mInputChannel), NTV2_XptAnalogIn));
673 CHECK(mDevice.Connect (::GetFrameBufferInputXptFromChannel (mInputChannel), ::GetCSCOutputXptFromChannel (mInputChannel, false/*isKey*/, true/*isRGB*/)));
674 } else {
675 CHECK(mDevice.Connect (::GetFrameBufferInputXptFromChannel (NTV2Channel (mInputChannel)), NTV2_XptAnalogIn));
676 }
677 CHECK(mDevice.SetFrameBufferFormat (mInputChannel, mPixelFormat));
678 if (!mbFixedReference)
679 CHECK(mDevice.SetReference (NTV2_REFERENCE_ANALOG_INPUT));
680 } else if (NTV2_IS_VALID_VIDEO_FORMAT (mVideoFormat)) {
681 SetupHDMI();
682 } else {
683 LOG(LOG_LEVEL_WARNING) << "## DEBUG: NTV2FrameGrabber::SetupInput: Bad mInputSource switch value " << ::NTV2InputSourceToChannelSpec (mInputSource);
684 }
685
686 // Enable and subscribe to the interrupts for the channel to be used...
687 CHECK(mDevice.EnableInputInterrupt (mInputChannel));
688 CHECK(mDevice.SubscribeInputVerticalEvent (mInputChannel));
689
691 MSG(ERROR, "Cannot find valid mapping from AJA pixel format to "
692 "UltraGrid\n");
693 return AJA_STATUS_NOINPUT;
694 }
695
696 return AJA_STATUS_SUCCESS;
697}
AJAStatus SetupHDMI()
Definition aja.cpp:475
NTV2TCIndex mTimeCodeSource
Time code source.
Definition aja.cpp:199
NTV2VideoFormat GetVideoFormatFromInputSource()
Definition aja.cpp:404
bool IsInput3Gb(const NTV2InputSource inputSource)
Definition aja.cpp:983

References CHECK, CHECK_OK, ultragrid::aja::codec_map, GetVideoFormatFromInputSource(), IsInput3Gb(), LOG, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, mAudioSystem, mbFixedReference, mDevice, mDeviceID, mInputChannel, mInputIsRGB, mInputSource, MOD_NAME, mPixelFormat, MSG, mTimeCodeSource, mVideoFormat, NOOP, offset, and SetupHDMI().

Referenced by Init().

Here is the call graph for this function:

◆ StartProducerThread()

void vidcap_state_aja::StartProducerThread ( void )
privatevirtual

Starts my frame consumer thread.

Definition at line 803 of file aja.cpp.

804{
805 // Create and start the capture thread..
807} // StartProducerThread
static void ProducerThreadStatic(vidcap_state_aja *pContext)
Definition aja.cpp:811

References mProducerThread, and ProducerThreadStatic().

Referenced by Run().

Here is the call graph for this function:

Member Data Documentation

◆ mAudioBufferSize

uint32_t vidcap_state_aja::mAudioBufferSize {}
private

My video buffer size, in bytes.

Definition at line 185 of file aja.cpp.

185{};

Referenced by SetupHostBuffers().

◆ mAudioInLastAddress

uint32_t vidcap_state_aja::mAudioInLastAddress {}
private

My record of the location of the last audio sample captured.

Definition at line 202 of file aja.cpp.

202{};

Referenced by CaptureFrames().

◆ mAudioSource

NTV2AudioSource vidcap_state_aja::mAudioSource {}
private

Definition at line 198 of file aja.cpp.

198{};

Referenced by vidcap_state_aja(), CaptureFrames(), and SetupAudio().

◆ mAudioSystem

NTV2AudioSystem vidcap_state_aja::mAudioSystem {NTV2_AUDIOSYSTEM_1}
private

The input source I'm using.

Definition at line 183 of file aja.cpp.

183{NTV2_AUDIOSYSTEM_1};

Referenced by CaptureFrames(), Quit(), SetupAudio(), and SetupVideo().

◆ mbFixedReference

bool vidcap_state_aja::mbFixedReference {false}
private

Definition at line 200 of file aja.cpp.

200{false};

Referenced by SetupHDMI(), and SetupVideo().

◆ mCheckFor4K

bool vidcap_state_aja::mCheckFor4K {false}
private

Definition at line 201 of file aja.cpp.

201{false};

Referenced by vidcap_state_aja(), and GetVideoFormatFromInputSource().

◆ mClearRouting

bool vidcap_state_aja::mClearRouting {false}
private

Definition at line 203 of file aja.cpp.

203{false};

Referenced by vidcap_state_aja(), and Init().

◆ mDevice

CNTV2Card vidcap_state_aja::mDevice
private

◆ mDeviceID

NTV2DeviceID vidcap_state_aja::mDeviceID {}
private

Definition at line 175 of file aja.cpp.

175{};

Referenced by EnableInput(), GetVideoFormatFromInputSource(), Init(), SetupAudio(), SetupHDMI(), and SetupVideo().

◆ mDeviceIndex

unsigned int vidcap_state_aja::mDeviceIndex {0}
private

Definition at line 173 of file aja.cpp.

173{0};

Referenced by vidcap_state_aja(), and Init().

◆ mFrames

int vidcap_state_aja::mFrames {0}
private

Definition at line 195 of file aja.cpp.

195{0};

Referenced by grab().

◆ mGlobalQuit

bool vidcap_state_aja::mGlobalQuit {false}
private

Definition at line 205 of file aja.cpp.

205{false};

Referenced by CaptureFrames(), grab(), and Quit().

◆ mInputChannel

NTV2Channel vidcap_state_aja::mInputChannel {NTV2_CHANNEL_INVALID}
private

Used to restore prior every-frame task mode.

Definition at line 177 of file aja.cpp.

177{NTV2_CHANNEL_INVALID};

Referenced by vidcap_state_aja(), ~vidcap_state_aja(), CaptureFrames(), SetupHDMI(), and SetupVideo().

◆ mInputIsRGB

bool vidcap_state_aja::mInputIsRGB
private

SDI Input is in RGB otherwise YCbCr.

Definition at line 204 of file aja.cpp.

Referenced by vidcap_state_aja(), and SetupVideo().

◆ mInputSource

NTV2InputSource vidcap_state_aja::mInputSource {NTV2_INPUTSOURCE_SDI1}
private

Wide VANC?

Definition at line 182 of file aja.cpp.

182{NTV2_INPUTSOURCE_SDI1};

Referenced by vidcap_state_aja(), GetVideoFormatFromInputSource(), Run(), SetupAudio(), SetupHDMI(), and SetupVideo().

◆ mMaxAudioChannels

int vidcap_state_aja::mMaxAudioChannels {0}
private

Definition at line 197 of file aja.cpp.

197{0};

Referenced by grab(), and SetupAudio().

◆ mOutputAudioFrame

shared_ptr<uint32_t> vidcap_state_aja::mOutputAudioFrame
private

Definition at line 189 of file aja.cpp.

Referenced by CaptureFrames(), and grab().

◆ mOutputAudioFrameSize

size_t vidcap_state_aja::mOutputAudioFrameSize {}
private

Definition at line 190 of file aja.cpp.

190{};

Referenced by CaptureFrames(), and grab().

◆ mOutputFrame

shared_ptr<video_frame> vidcap_state_aja::mOutputFrame
private

Definition at line 188 of file aja.cpp.

Referenced by ~vidcap_state_aja(), CaptureFrames(), and grab().

◆ mOutputFrameLock

mutex vidcap_state_aja::mOutputFrameLock
private

Definition at line 191 of file aja.cpp.

Referenced by CaptureFrames(), and grab().

◆ mOutputFrameReady

condition_variable vidcap_state_aja::mOutputFrameReady
private

Definition at line 192 of file aja.cpp.

Referenced by CaptureFrames(), and grab().

◆ mPixelFormat

NTV2FrameBufferFormat vidcap_state_aja::mPixelFormat {NTV2_FBF_INVALID}
private

My video format.

Definition at line 179 of file aja.cpp.

179{NTV2_FBF_INVALID};

Referenced by vidcap_state_aja(), SetupHDMI(), SetupHostBuffers(), and SetupVideo().

◆ mPool

video_frame_pool vidcap_state_aja::mPool {0, aligned_data_allocator()}
private

My producer thread object – does the frame capturing.

Definition at line 187 of file aja.cpp.

Referenced by CaptureFrames(), and SetupHostBuffers().

◆ mProducerThread

thread vidcap_state_aja::mProducerThread
private

My audio buffer size, in bytes.

Definition at line 186 of file aja.cpp.

Referenced by Quit(), and StartProducerThread().

◆ mProgressive

bool vidcap_state_aja::mProgressive {false}
private

Definition at line 193 of file aja.cpp.

193{false};

Referenced by vidcap_state_aja(), GetVideoFormatFromInputSource(), and Run().

◆ mSavedTaskMode

NTV2EveryFrameTaskMode vidcap_state_aja::mSavedTaskMode {}
private

My device identifier.

Definition at line 176 of file aja.cpp.

176{};

Referenced by ~vidcap_state_aja(), and Init().

◆ mT0

chrono::system_clock::time_point vidcap_state_aja::mT0 {chrono::system_clock::now()}
private

Definition at line 194 of file aja.cpp.

194{chrono::system_clock::now()};

Referenced by grab().

◆ mTimeCodeSource

NTV2TCIndex vidcap_state_aja::mTimeCodeSource {}
private

Time code source.

Definition at line 199 of file aja.cpp.

199{};

Referenced by SetupVideo().

◆ mVancMode

NTV2VANCMode vidcap_state_aja::mVancMode {}
private

My pixel format.

Definition at line 180 of file aja.cpp.

180{};

Referenced by SetupHostBuffers().

◆ mVideoBufferSize

uint32_t vidcap_state_aja::mVideoBufferSize {}
private

The audio system I'm using.

Definition at line 184 of file aja.cpp.

184{};

Referenced by CaptureFrames(), and SetupHostBuffers().

◆ mVideoFormat

NTV2VideoFormat vidcap_state_aja::mVideoFormat {NTV2_FORMAT_UNKNOWN}
private

My input channel.

Definition at line 178 of file aja.cpp.

178{NTV2_FORMAT_UNKNOWN};

Referenced by vidcap_state_aja(), CaptureFrames(), SetupHDMI(), SetupHostBuffers(), and SetupVideo().

◆ mWideVanc

bool vidcap_state_aja::mWideVanc {}
private

VANC enabled?

Definition at line 181 of file aja.cpp.

181{};

Referenced by SetupHostBuffers().


The documentation for this class was generated from the following file: