AJA NTV2 SDK  18.0.0.2122
NTV2 SDK 18.0.0.2122
ntv2capture.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 //#define AJA_RAW_AUDIO_RECORD // Uncomment to record captured raw audio into binary data file
9 //#define AJA_WAV_AUDIO_RECORD // Uncomment to record captured audio into WAV file
10 #include "ntv2capture.h"
11 #include "ntv2devicescanner.h"
12 #include "ntv2utils.h"
13 #include "ntv2devicefeatures.h"
14 #include "ajabase/system/process.h"
15 #include <iterator> // for inserter
16 #include <fstream> // for ofstream
17 
18 using namespace std;
19 
20 #define NTV2_BUFFER_LOCK
21 
22 
24 
26  : mConsumerThread (AJAThread()),
27  mProducerThread (AJAThread()),
28  mDeviceID (DEVICE_ID_NOTFOUND),
29  mConfig (inConfig),
31  mSavedTaskMode (NTV2_DISABLE_TASKS),
32  mAudioSystem (inConfig.fWithAudio ? NTV2_AUDIOSYSTEM_1 : NTV2_AUDIOSYSTEM_INVALID),
33  mHostBuffers (),
34  mAVCircularBuffer (),
35  mGlobalQuit (false)
36 {
37 } // constructor
38 
39 
41 {
42  // Stop my capture and consumer threads, then destroy them...
43  Quit();
44 
45  // Unsubscribe from VBI events...
48 
49 } // destructor
50 
51 
52 void NTV2Capture::Quit (void)
53 {
54  // Set the global 'quit' flag, and wait for the threads to go inactive...
55  mGlobalQuit = true;
56 
57  while (mConsumerThread.Active())
58  AJATime::Sleep(10);
59 
60  while (mProducerThread.Active())
61  AJATime::Sleep(10);
62 
63  // Restore some of the device's former state...
64  if (!mConfig.fDoMultiFormat)
65  {
67  mDevice.SetTaskMode(mSavedTaskMode); // Restore prior task mode
68  }
69 
70 } // Quit
71 
72 
74 {
76 
77  // Open the device...
79  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not found" << endl; return AJA_STATUS_OPEN;}
80 
81  if (!mDevice.IsDeviceReady())
82  {cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
83 
84  mDeviceID = mDevice.GetDeviceID(); // Keep the device ID handy, as it's used frequently
85  const bool isKonaHDMI (mDevice.features().GetNumHDMIVideoInputs() > 1);
86  const NTV2IOKinds inputType (isKonaHDMI ? NTV2_IOKINDS_HDMI : NTV2_IOKINDS_SDI);
87  if (!mDevice.features().CanDoCapture())
88  {cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' is playback-only" << endl; return AJA_STATUS_FEATURE;}
89 
90  if (!mDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
91  { cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' doesn't support '"
92  << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat, true) << "' ("
93  << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat, false) << ", " << DEC(mConfig.fPixelFormat) << ")" << endl;
95  }
96 
97  ULWord appSignature (0);
98  int32_t appPID (0);
99  mDevice.GetStreamingApplication (appSignature, appPID); // Who currently "owns" the device?
100  mDevice.GetTaskMode(mSavedTaskMode); // Save the current device state
101  if (!mConfig.fDoMultiFormat)
102  {
104  {
105  cerr << "## ERROR: Unable to acquire '" << mDevice.GetDisplayName() << "' because another app (pid " << appPID << ") owns it" << endl;
106  return AJA_STATUS_BUSY; // Another app is using the device
107  }
108  }
109  mDevice.SetTaskMode(NTV2_OEM_TASKS); // Prevent interference from AJA retail services
110 
111  if (mDevice.features().CanDoMultiFormat())
112  mDevice.SetMultiFormatMode(mConfig.fDoMultiFormat);
113 
114  // This demo permits input source and channel to be specified independently.
116  mConfig.fInputChannel = NTV2_CHANNEL1; // Neither -i or -c specified: default to Ch1
118  mConfig.fInputChannel = ::NTV2InputSourceToChannel(mConfig.fInputSource); // Only -i specified: use that channel
120  mConfig.fInputSource = ::NTV2ChannelToInputSource ( mConfig.fInputChannel, inputType); // Only -c specified: use that input source
121  // On KonaHDMI, map specified SDI input to equivalent HDMI input...
122  if (isKonaHDMI && NTV2_INPUT_SOURCE_IS_SDI(mConfig.fInputSource))
124  if (!mDevice.features().CanDoInputSource(mConfig.fInputSource))
125  {
126  cerr << "## ERROR: No such input '" << ::NTV2InputSourceToString(mConfig.fInputSource, /*compact?*/true)
127  << "' on '" << mDevice.GetDisplayName() << "'" << endl;
128  return AJA_STATUS_UNSUPPORTED;
129  }
130  if (mConfig.fWithAnc && !mDevice.features().CanDoCustomAnc())
131  {cerr << "## ERROR: Anc capture requested, but '" << mDevice.GetDisplayName() << "' has no anc extractors"; return AJA_STATUS_UNSUPPORTED;}
132 
133  // Set up the video and audio...
134  status = SetupVideo();
135  if (AJA_FAILURE(status))
136  return status;
137 
138  if (mConfig.fWithAudio)
139  status = SetupAudio();
140  if (AJA_FAILURE(status))
141  return status;
142 
143  // Set up the circular buffers, the device signal routing, and both playout and capture AutoCirculate...
145  if (!RouteInputSignal())
146  return AJA_STATUS_FAIL;
147 
148  #if defined(_DEBUG)
149  cerr << mConfig;
150  if (mDevice.IsRemote())
151  cerr << "Device Description: " << mDevice.GetDescription() << endl;
152  cerr << endl;
153  #endif // defined(_DEBUG)
154  return AJA_STATUS_SUCCESS;
155 
156 } // Init
157 
158 
160 {
161  // Enable the FrameStore we intend to use...
162  mDevice.EnableChannel(mConfig.fInputChannel);
163 
164  // Enable and subscribe to VBIs (critical on Windows)...
165  mDevice.EnableInputInterrupt(mConfig.fInputChannel);
168 
169  // If the device supports bi-directional SDI and the requested input is SDI,
170  // ensure the SDI connector(s) are configured to receive...
172  {
173  mDevice.SetSDITransmitEnable (mConfig.fInputChannel, false); // Set SDI connector(s) to receive
174  mDevice.WaitForOutputVerticalInterrupt (NTV2_CHANNEL1, 10); // Wait 10 VBIs to allow reciever to lock
175  }
176 
177  // Determine the input video signal format...
178  mVideoFormat = mDevice.GetInputVideoFormat(mConfig.fInputSource);
179  if (mVideoFormat == NTV2_FORMAT_UNKNOWN)
180  {cerr << "## ERROR: No input signal or unknown format" << endl; return AJA_STATUS_NOINPUT;}
181  if (!mDevice.features().CanDoVideoFormat(mVideoFormat))
182  {
183  cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' cannot handle " << ::NTV2VideoFormatToString(mVideoFormat) << endl;
184  return AJA_STATUS_UNSUPPORTED; // Device can't handle this format
185  }
186  if (NTV2_IS_4K_VIDEO_FORMAT(mVideoFormat) || NTV2_IS_QUAD_QUAD_FORMAT(mVideoFormat))
187  {
188  cerr << "## ERROR: 'ntv2capture' cannot handle " << ::NTV2VideoFormatToString(mVideoFormat)
189  << " input signal -- try 'ntv2capture4k' or 'ntv2capture8k' demo" << endl;
190  return AJA_STATUS_UNSUPPORTED; // This demo can't handle this format
191  }
192  CAPNOTE(::NTV2VideoFormatToString(mVideoFormat) << " detected on " << ::NTV2InputSourceToString(mConfig.fInputSource,true) << " on " << mDevice.GetDisplayName());
193  mFormatDesc = NTV2FormatDescriptor(mVideoFormat, mConfig.fPixelFormat);
194 
195  // Setting SDI output clock timing/reference is unimportant for capture-only apps...
196  if (!mConfig.fDoMultiFormat) // ...if not sharing the device...
197  mDevice.SetReference(NTV2_REFERENCE_FREERUN); // ...let it free-run
198 
199  // Set the device video format to whatever was detected at the input...
200  mDevice.SetVideoFormat (mVideoFormat, false, false, mConfig.fInputChannel);
201  mDevice.SetVANCMode (NTV2_VANCMODE_OFF, mConfig.fInputChannel); // Disable VANC
202 
203  // Set the frame buffer pixel format for the FrameStore to be used on the device...
204  mDevice.SetFrameBufferFormat (mConfig.fInputChannel, mConfig.fPixelFormat);
205  return AJA_STATUS_SUCCESS;
206 
207 } // SetupVideo
208 
209 
211 {
212  // In multiformat mode, base the audio system on the channel...
213  if (mConfig.fDoMultiFormat)
214  if (mDevice.features().GetNumAudioSystems() > 1)
215  if (UWord(mConfig.fInputChannel) < mDevice.features().GetNumAudioSystems())
216  mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fInputChannel);
217 
218  NTV2AudioSystemSet audSystems (::NTV2MakeAudioSystemSet (mAudioSystem, 1));
219  CNTV2DemoCommon::ConfigureAudioSystems (mDevice, mConfig, audSystems);
220  return AJA_STATUS_SUCCESS;
221 
222 } // SetupAudio
223 
224 
226 {
227  // Let my circular buffer know when it's time to quit...
228  mAVCircularBuffer.SetAbortFlag(&mGlobalQuit);
229 
230  ULWord F1AncSize(0), F2AncSize(0);
231  if (mConfig.fWithAnc)
232  { // Use the max anc size stipulated by the AncFieldOffset VReg values...
233  ULWord F1OffsetFromEnd(0), F2OffsetFromEnd(0);
234  mDevice.ReadRegister(kVRegAncField1Offset, F1OffsetFromEnd); // # bytes from end of 8MB/16MB frame
235  mDevice.ReadRegister(kVRegAncField2Offset, F2OffsetFromEnd); // # bytes from end of 8MB/16MB frame
236  // Based on the offsets, calculate the max anc capacity
237  F1AncSize = F2OffsetFromEnd > F1OffsetFromEnd ? 0 : F1OffsetFromEnd - F2OffsetFromEnd;
238  F2AncSize = F2OffsetFromEnd > F1OffsetFromEnd ? F2OffsetFromEnd - F1OffsetFromEnd : F2OffsetFromEnd;
239  }
240 
241  // Allocate and add each in-host NTV2FrameData to my circular buffer member variable...
242  const size_t audioBufferSize (NTV2_AUDIOSIZE_MAX);
243  mHostBuffers.reserve(size_t(CIRCULAR_BUFFER_SIZE));
244  while (mHostBuffers.size() < size_t(CIRCULAR_BUFFER_SIZE))
245  {
246  mHostBuffers.push_back(NTV2FrameData());
247  NTV2FrameData & frameData(mHostBuffers.back());
248  frameData.fVideoBuffer.Allocate(mFormatDesc.GetVideoWriteSize());
249  frameData.fAudioBuffer.Allocate(NTV2_IS_VALID_AUDIO_SYSTEM(mAudioSystem) ? audioBufferSize : 0);
250  frameData.fAncBuffer.Allocate(F1AncSize);
251  frameData.fAncBuffer2.Allocate(F2AncSize);
252  mAVCircularBuffer.Add(&frameData);
253 
254 #ifdef NTV2_BUFFER_LOCK
255  // Page lock the memory
256  if (frameData.fVideoBuffer)
257  mDevice.DMABufferLock(frameData.fVideoBuffer, true);
258  if (frameData.fAudioBuffer)
259  mDevice.DMABufferLock(frameData.fAudioBuffer, true);
260  if (frameData.fAncBuffer)
261  mDevice.DMABufferLock(frameData.fAncBuffer, true);
262 #endif
263  } // for each NTV2FrameData
264 
265 } // SetupHostBuffers
266 
267 
269 {
273 
274  const bool isInputRGB (inputColorSpace == NTV2_LHIHDMIColorSpaceRGB);
276 
277  return CNTV2DemoCommon::GetInputRouting (connections, mConfig, isInputRGB)
278  && mDevice.ApplySignalRoute(connections, !mConfig.fDoMultiFormat);
279 
280 } // RouteInputSignal
281 
282 
284 {
285  // Start the playout and capture threads...
288  return AJA_STATUS_SUCCESS;
289 
290 } // Run
291 
292 
294 
295 // This starts the consumer thread
297 {
298  // Create and start the consumer thread...
299  mConsumerThread.Attach(ConsumerThreadStatic, this);
300  mConsumerThread.SetPriority(AJA_ThreadPriority_High);
301  mConsumerThread.Start();
302 
303 } // StartConsumerThread
304 
305 
306 // The consumer thread function
307 void NTV2Capture::ConsumerThreadStatic (AJAThread * pThread, void * pContext) // static
308 {
309  (void) pThread;
310 
311  // Grab the NTV2Capture instance pointer from the pContext parameter,
312  // then call its ConsumeFrames method...
313  NTV2Capture * pApp (reinterpret_cast<NTV2Capture*>(pContext));
314  pApp->ConsumeFrames();
315 
316 } // ConsumerThreadStatic
317 
318 
320 {
321  CAPNOTE("Thread started");
322  AJA_NTV2_AUDIO_RECORD_BEGIN // Active when AJA_RAW_AUDIO_RECORD or AJA_WAV_AUDIO_RECORD defined
323  uint64_t ancTally(0);
324  ofstream * pOFS(mConfig.fAncDataFilePath.empty() ? AJA_NULL : new ofstream(mConfig.fAncDataFilePath.c_str(), ios::binary));
325  while (!mGlobalQuit)
326  {
327  // Wait for the next frame to become ready to "consume"...
328  NTV2FrameData * pFrameData(mAVCircularBuffer.StartConsumeNextBuffer());
329  if (pFrameData)
330  {
331  // Do something useful with the frame data...
332  // . . . . . . . . . . . .
333  // . . . . . . . . . . . .
334  // . . . . . . . . . . . .
335  AJA_NTV2_AUDIO_RECORD_DO // Active when AJA_RAW_AUDIO_RECORD or AJA_WAV_AUDIO_RECORD defined
336  if (pOFS && !ancTally++)
337  cerr << "Writing raw anc to '" << mConfig.fAncDataFilePath << "', "
338  << DEC(pFrameData->AncBufferSize() + pFrameData->AncBuffer2Size())
339  << " bytes per frame" << endl;
340  if (pOFS && pFrameData->AncBuffer())
341  pOFS->write(pFrameData->AncBuffer(), streamsize(pFrameData->AncBufferSize()));
342  if (pOFS && pFrameData->AncBuffer2())
343  pOFS->write(pFrameData->AncBuffer2(), streamsize(pFrameData->AncBuffer2Size()));
344 
345  // Now release and recycle the buffer...
346  mAVCircularBuffer.EndConsumeNextBuffer();
347  } // if pFrameData
348  } // loop til quit signaled
349  if (pOFS)
350  {delete pOFS; cerr << "Wrote " << DEC(ancTally) << " frames of raw anc data" << endl;}
351  AJA_NTV2_AUDIO_RECORD_END // Active when AJA_RAW_AUDIO_RECORD or AJA_WAV_AUDIO_RECORD defined
352  CAPNOTE("Thread completed, will exit");
353 
354 } // ConsumeFrames
355 
356 
358 
359 // This starts the capture (producer) thread
361 {
362  // Create and start the capture thread...
363  mProducerThread.Attach(ProducerThreadStatic, this);
364  mProducerThread.SetPriority(AJA_ThreadPriority_High);
365  mProducerThread.Start();
366 
367 } // StartProducerThread
368 
369 
370 // The capture thread function
371 void NTV2Capture::ProducerThreadStatic (AJAThread * pThread, void * pContext) // static
372 {
373  (void) pThread;
374 
375  // Grab the NTV2Capture instance pointer from the pContext parameter,
376  // then call its CaptureFrames method...
377  NTV2Capture * pApp (reinterpret_cast<NTV2Capture*>(pContext));
378  pApp->CaptureFrames ();
379 
380 } // ProducerThreadStatic
381 
382 
384 {
385  AUTOCIRCULATE_TRANSFER inputXfer; // AutoCirculate input transfer info
386  NTV2AudioChannelPairs nonPcmPairs, oldNonPcmPairs;
387  ULWord acOptions (AUTOCIRCULATE_WITH_RP188), overruns(0);
388  UWord sdiSpigot (UWord(::NTV2InputSourceToChannel(mConfig.fInputSource)));
389  if (mConfig.fWithAnc)
390  acOptions |= AUTOCIRCULATE_WITH_ANC;
391 
392  CAPNOTE("Thread started");
393 
394  // Initialize and start capture AutoCirculate...
395  mDevice.AutoCirculateStop(mConfig.fInputChannel); // Just in case
396  if (!mDevice.AutoCirculateInitForInput (mConfig.fInputChannel, mConfig.fFrames, mAudioSystem, acOptions))
397  mGlobalQuit = true;
398  if (!mGlobalQuit && !mDevice.AutoCirculateStart(mConfig.fInputChannel))
399  mGlobalQuit = true;
400 
401  // Ingest frames til Quit signaled...
402  while (!mGlobalQuit)
403  {
404  AUTOCIRCULATE_STATUS acStatus;
405  mDevice.AutoCirculateGetStatus (mConfig.fInputChannel, acStatus);
406 
407  if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
408  {
409  // At this point, there's at least one fully-formed frame available in the device's
410  // frame buffer to transfer to the host. Reserve an NTV2FrameData to "produce", and
411  // use it in the next transfer from the device...
412  NTV2FrameData * pFrameData (mAVCircularBuffer.StartProduceNextBuffer());
413  if (!pFrameData)
414  continue;
415 
416  NTV2FrameData & frameData (*pFrameData);
417  inputXfer.SetVideoBuffer (frameData.VideoBuffer(), frameData.VideoBufferSize());
418  if (acStatus.WithAudio())
419  inputXfer.SetAudioBuffer (frameData.AudioBuffer(), frameData.AudioBufferSize());
420  if (acStatus.WithCustomAnc())
421  inputXfer.SetAncBuffers (frameData.AncBuffer(), frameData.AncBufferSize(),
422  frameData.AncBuffer2(), frameData.AncBuffer2Size());
423 
424  // Transfer video/audio/anc from the device into our host buffers...
425  mDevice.AutoCirculateTransfer (mConfig.fInputChannel, inputXfer);
426 
427  // Remember the actual amount of audio captured...
428  if (acStatus.WithAudio())
429  frameData.fNumAudioBytes = inputXfer.GetCapturedAudioByteCount();
430 
431  // If capturing Anc, clear stale anc data from the anc buffers...
432  if (acStatus.WithCustomAnc() && frameData.AncBuffer())
433  { bool overrun(false);
434  mDevice.AncExtractGetBufferOverrun (sdiSpigot, overrun);
435  if (overrun)
436  {overruns++; CAPWARN(overruns << " anc overrun(s)");}
437  frameData.fNumAncBytes = inputXfer.GetCapturedAncByteCount(/*isF2*/false);
438  NTV2Buffer stale (frameData.fAncBuffer.GetHostAddress(frameData.fNumAncBytes),
439  frameData.fAncBuffer.GetByteCount() - frameData.fNumAncBytes);
440  stale.Fill(uint8_t(0));
441  }
442  if (acStatus.WithCustomAnc() && frameData.AncBuffer2())
443  {
444  frameData.fNumAnc2Bytes = inputXfer.GetCapturedAncByteCount(/*isF2*/true);
445  NTV2Buffer stale (frameData.fAncBuffer2.GetHostAddress(frameData.fNumAnc2Bytes),
446  frameData.fAncBuffer2.GetByteCount() - frameData.fNumAnc2Bytes);
447  stale.Fill(uint8_t(0));
448  }
449 
450  // Grab all valid timecodes that were captured...
451  inputXfer.GetInputTimeCodes (frameData.fTimecodes, mConfig.fInputChannel, /*ValidOnly*/ true);
452 
453  if (acStatus.WithAudio())
454  // Look for PCM/NonPCM changes in the audio stream...
455  if (mDevice.GetInputAudioChannelPairsWithoutPCM (mConfig.fInputChannel, nonPcmPairs))
456  {
457  NTV2AudioChannelPairs becomingNonPCM, becomingPCM;
458  set_difference (oldNonPcmPairs.begin(), oldNonPcmPairs.end(), nonPcmPairs.begin(), nonPcmPairs.end(), inserter(becomingPCM, becomingPCM.begin()));
459  set_difference (nonPcmPairs.begin(), nonPcmPairs.end(), oldNonPcmPairs.begin(), oldNonPcmPairs.end(), inserter(becomingNonPCM, becomingNonPCM.begin()));
460  if (!becomingNonPCM.empty())
461  CAPNOTE("Audio channel pair(s) '" << becomingNonPCM << "' now non-PCM");
462  if (!becomingPCM.empty())
463  CAPNOTE("Audio channel pair(s) '" << becomingPCM << "' now PCM");
464  oldNonPcmPairs = nonPcmPairs;
465  }
466 
467  // Signal that we're done "producing" the frame, making it available for future "consumption"...
468  mAVCircularBuffer.EndProduceNextBuffer();
469  } // if A/C running and frame(s) are available for transfer
470  else
471  {
472  // Either AutoCirculate is not running, or there were no frames available on the device to transfer.
473  // Rather than waste CPU cycles spinning, waiting until a frame becomes available, it's far more
474  // efficient to wait for the next input vertical interrupt event to get signaled...
476  }
477 
478  // Log SDI input CRC/VPID/TRS errors...
480  {
481  NTV2SDIInStatistics sdiStats;
482  NTV2SDIInputStatus inputStatus;
483  if (mDevice.ReadSDIStatistics(sdiStats))
484  {
485  sdiStats.GetSDIInputStatus(inputStatus, UWord(::GetIndexForNTV2InputSource(mConfig.fInputSource)));
486  if (!inputStatus.mLocked)
487  CAPWARN(inputStatus);
488  }
489  }
490  } // loop til quit signaled
491 
492  // Stop AutoCirculate...
493  mDevice.AutoCirculateStop(mConfig.fInputChannel);
494  CAPNOTE("Thread completed, will exit");
495 
496 } // CaptureFrames
497 
498 
499 void NTV2Capture::GetACStatus (ULWord & outGoodFrames, ULWord & outDroppedFrames, ULWord & outBufferLevel)
500 {
501  AUTOCIRCULATE_STATUS status;
502  mDevice.AutoCirculateGetStatus(mConfig.fInputChannel, status);
503  outGoodFrames = status.GetProcessedFrameCount();
504  outDroppedFrames = status.GetDroppedFrameCount();
505  outBufferLevel = status.GetBufferLevel();
506 }
NTV2Channel NTV2InputSourceToChannel(const NTV2InputSource inInputSource)
Converts a given NTV2InputSource to its equivalent NTV2Channel value.
Definition: ntv2utils.cpp:5047
Anc Field2 byte offset from end of frame buffer (GUMP on all boards except RTP for SMPTE2022/IP) ...
ULWord GetVideoWriteSize(ULWord inPageSize=4096UL) const
virtual bool SetTaskMode(const NTV2TaskMode inMode)
Sets the device&#39;s task mode.
Instances of me capture frames in real time from a video signal provided to an input of an AJA device...
Definition: ntv2capture.h:19
For devices that support it (see NTV2DeviceCanDoSDIErrorChecks ), this struct reports SDI input error...
Specifies SDI input/output kinds.
Definition: ntv2enums.h:1292
bool Allocate(const size_t inByteCount, const bool inPageAligned=false)
Allocates (or re-allocates) my user-space storage using the given byte count. I assume full responsib...
Specifies the device&#39;s internal clock.
Definition: ntv2enums.h:1459
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=(0))
Sets the device&#39;s clock reference source. See Video Output Clocking & Synchronization for more inform...
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
bool WithCustomAnc(void) const
AJAStatus Add(FrameDataPtr pInFrameData)
Appends a new frame buffer to me, increasing my frame storage capacity by one frame.
Declares the NTV2Capture class.
ULWord AncBuffer2Size(void) const
virtual bool SetVideoFormat(const NTV2VideoFormat inVideoFormat, const bool inIsAJARetail=(!(0)), const bool inKeepVancSettings=(0), const NTV2Channel inChannel=NTV2_CHANNEL1)
Configures the AJA device to handle a specific video format.
AJAStatus
Definition: types.h:380
ULWord VideoBufferSize(void) const
bool fDoMultiFormat
If true, use multi-format/multi-channel mode, if device supports it; otherwise normal mode...
ULWord GetCapturedAudioByteCount(void) const
virtual bool IsDeviceReady(const bool inCheckValid=(0))
ULWord AudioBufferSize(void) const
static uint64_t GetPid()
Definition: process.cpp:35
ULWord GetBufferLevel(void) const
virtual AJAStatus SetupVideo(void)
Sets up everything I need for capturing video.
#define AJA_FAILURE(_status_)
Definition: types.h:373
NTV2InputSource NTV2ChannelToInputSource(const NTV2Channel inChannel, const NTV2IOKinds inKinds=NTV2_IOKINDS_SDI)
Definition: ntv2utils.cpp:5132
ULWord GetByteCount(void) const
bool WithAudio(void) const
#define NTV2_IS_4K_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:783
NTV2AudioSystemSet NTV2MakeAudioSystemSet(const NTV2AudioSystem inFirstAudioSystem, const UWord inCount=1)
virtual AJAStatus SetPriority(AJAThreadPriority priority)
Definition: thread.cpp:133
Specifies HDMI input/output kinds.
Definition: ntv2enums.h:1293
virtual bool GetInputAudioChannelPairsWithoutPCM(const NTV2Channel inSDIInputConnector, NTV2AudioChannelPairs &outChannelPairs)
For the given SDI input (specified as a channel number), returns the set of audio channel pairs that ...
Definition: ntv2audio.cpp:1587
FrameDataPtr StartConsumeNextBuffer(void)
The thread that&#39;s responsible for processing incoming frames – the consumer – calls this function t...
bool fWithAnc
If true, also capture Anc.
virtual AJAStatus SetupAudio(void)
Sets up everything I need for capturing audio.
ULWord fNumAudioBytes
Actual number of captured audio bytes.
Definition: json.hpp:5362
virtual AJAStatus Start()
Definition: thread.cpp:91
virtual bool EnableInputInterrupt(const NTV2Channel channel=NTV2_CHANNEL1)
Allows the CNTV2Card instance to wait for and respond to input vertical blanking interrupts originati...
virtual bool SubscribeInputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Causes me to be notified when an input vertical blanking interrupt occurs on the given input channel...
void EndConsumeNextBuffer(void)
The consumer thread calls this function to signal that it has finished processing the frame it obtain...
#define false
uint32_t ULWord
Definition: ajatypes.h:223
virtual bool AutoCirculateGetStatus(const NTV2Channel inChannel, AUTOCIRCULATE_STATUS &outStatus)
Returns the current AutoCirculate status for the given channel.
virtual bool SetFrameBufferFormat(NTV2Channel inChannel, NTV2FrameBufferFormat inNewFormat, bool inIsAJARetail=(!(0)), NTV2HDRXferChars inXferChars=NTV2_VPID_TC_SDR_TV, NTV2HDRColorimetry inColorimetry=NTV2_VPID_Color_Rec709, NTV2HDRLuminance inLuminance=NTV2_VPID_Luminance_YCbCr)
Sets the frame buffer format for the given FrameStore on the AJA device.
mVideoFormat
Definition: ntv2vcam.cpp:801
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:148
bool CanDoInputSource(const NTV2InputSource inSrc)
virtual bool SetMultiFormatMode(const bool inEnable)
Enables or disables multi-format (per channel) device operation. If enabled, each device channel can ...
virtual bool GetHDMIInputColor(NTV2LHIHDMIColorSpace &outValue, const NTV2Channel inHDMIInput=NTV2_CHANNEL1)
Answers with the current colorspace for the given HDMI input.
Definition: ntv2hdmi.cpp:70
std::set< NTV2AudioChannelPair > NTV2AudioChannelPairs
A set of distinct NTV2AudioChannelPair values.
virtual AJAStatus Run(void)
Runs me.
ULWord GetProcessedFrameCount(void) const
bool fWithAudio
If true, also capture Audio.
virtual bool RouteInputSignal(void)
Sets up device routing for capture.
virtual void GetACStatus(ULWord &outGoodFrames, ULWord &outDroppedFrames, ULWord &outBufferLevel)
Provides status information about my input (capture) process.
int32_t appPID(0)
Anc Field1 byte offset from end of frame buffer (GUMP on all boards except RTP for SMPTE2022/IP) ...
#define NTV2_AUDIOSIZE_MAX
NTV2Channel fInputChannel
The device channel to use.
virtual bool IsRemote(void) const
virtual bool Active()
Definition: thread.cpp:116
static void ConsumerThreadStatic(AJAThread *pThread, void *pContext)
This is the consumer thread&#39;s static callback function that gets called when the consumer thread runs...
bool Fill(const T &inValue)
Fills me with the given scalar value.
virtual bool GetTaskMode(NTV2TaskMode &outMode)
Retrieves the device&#39;s current task mode.
#define AJA_NTV2_AUDIO_RECORD_END
std::string NTV2InputSourceToString(const NTV2InputSource inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7377
0: Disabled (never recommended): device configured exclusively by client application(s).
virtual void CaptureFrames(void)
Repeatedly captures frames using AutoCirculate (until global quit flag set).
virtual std::string GetDescription(void) const
Definition: ntv2card.cpp:139
std::string fAncDataFilePath
Optional path to Anc binary data file.
This class is used to configure an NTV2Capture instance.
ULWord AncBufferSize(void) const
virtual bool UnsubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Unregisters me so I&#39;m no longer notified when an output VBI is signaled on the given output channel...
Invalid or "not found".
Definition: ntv2enums.h:98
static bool GetFirstDeviceFromArgument(const std::string &inArgument, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the AJA device that matches a command li...
virtual bool SetSDITransmitEnable(const NTV2Channel inChannel, const bool inEnable)
Sets the specified bidirectional SDI connector to act as an input or an output.
virtual void StartProducerThread(void)
Starts my capture thread.
#define NTV2_INPUT_SOURCE_IS_HDMI(_inpSrc_)
Definition: ntv2enums.h:1281
virtual bool AutoCirculateTransfer(const NTV2Channel inChannel, AUTOCIRCULATE_TRANSFER &transferInfo)
Transfers all or part of a frame as specified in the given AUTOCIRCULATE_TRANSFER object to/from the ...
virtual bool AcquireStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Reserves exclusive use of the AJA device for a given process, preventing other processes on the host ...
virtual bool DMABufferLock(const NTV2Buffer &inBuffer, bool inMap=(0), bool inRDMA=(0))
Page-locks the given host buffer to reduce transfer time and CPU usage of DMA transfers.
Definition: ntv2dma.cpp:429
NTV2Buffer & AncBuffer2(void)
#define AJA_NULL
Definition: ajatypes.h:167
NTV2LHIHDMIColorSpace inputColorSpace(NTV2_LHIHDMIColorSpaceYCbCr)
void SetAbortFlag(const bool *pAbortFlag)
Tells me the boolean variable I should monitor such that when it gets set to "true" will cause any th...
virtual std::string GetDisplayName(void)
Answers with this device&#39;s display name.
Definition: ntv2card.cpp:88
NTV2Buffer & AncBuffer(void)
virtual NTV2VideoFormat GetInputVideoFormat(const NTV2InputSource inVideoSource=NTV2_INPUTSOURCE_SDI1, const bool inIsProgressive=(0))
Returns the video format of the signal that is present on the given input source. ...
Describes a video frame for a given video standard or format and pixel format, including the total nu...
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
2: OEM (recommended): device configured by client application(s) with some driver involvement...
virtual bool ApplySignalRoute(const CNTV2SignalRouter &inRouter, const bool inReplace=(0))
Applies the given routing table to the AJA device.
ULWord GetIndexForNTV2InputSource(const NTV2InputSource inValue)
Definition: ntv2utils.cpp:5274
NTV2XptConnections connections
Definition: ntv2vcam.cpp:1011
std::set< NTV2AudioSystem > NTV2AudioSystemSet
A set of distinct NTV2AudioSystem values. New in SDK 16.2.
std::string NTV2VideoFormatToString(const NTV2VideoFormat inValue, const bool inUseFrameRate=false)
Definition: ntv2utils.cpp:6746
NTV2Buffer & VideoBuffer(void)
ULWord GetDroppedFrameCount(void) const
NTV2Buffer fAncBuffer
Host ancillary data buffer.
#define AUTOCIRCULATE_WITH_ANC
Use this to AutoCirculate with ancillary data.
virtual NTV2DeviceID GetDeviceID(void)
ULWord fNumAnc2Bytes
Actual number of captured F2 anc bytes.
virtual void Quit(void)
Gracefully stops me from running.
Definition: ntv2capture.cpp:52
Declares the CNTV2DeviceScanner class.
NTV2Buffer fAncBuffer2
Additional "F2" host anc buffer.
virtual bool ReadRegister(const ULWord inRegNum, ULWord &outValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0)
Reads all or part of the 32-bit contents of a specific register (real or virtual) on the AJA device...
virtual bool AutoCirculateStop(const NTV2Channel inChannel, const bool inAbort=(0))
Stops AutoCirculate for the given channel, and releases the on-device frame buffers that were allocat...
#define NTV2_IS_VALID_CHANNEL(__x__)
Definition: ntv2enums.h:1371
Declares the AJAProcess class.
Describes a user-space buffer on the host computer. I have an address and a length, plus some optional attributes (allocated by SDK?, page-aligned? etc.).
virtual bool UnsubscribeInputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Unregisters me so I&#39;m no longer notified when an input VBI is signaled on the given input channel...
ULWord fNumAncBytes
Actual number of captured F1 anc bytes.
NTV2Buffer & AudioBuffer(void)
This object specifies the information that will be transferred to or from the AJA device in the CNTV2...
bool GetSDIInputStatus(NTV2SDIInputStatus &outStatus, const UWord inSDIInputIndex0=0)
Answers with the NTV2SDIInputStatus for the given SDI input spigot.
NTV2InputSource fInputSource
The device input connector to use.
#define DEC(__x__)
virtual void ConsumeFrames(void)
Repeatedly consumes frames from the circular buffer (until global quit flag set). ...
void EndProduceNextBuffer(void)
The producer thread calls this function to signal that it has finished populating the frame it obtain...
This identifies the first Audio System.
Definition: ntv2enums.h:3897
virtual void SetupHostBuffers(void)
Sets up my circular buffers.
virtual bool WaitForOutputVerticalInterrupt(const NTV2Channel inChannel=NTV2_CHANNEL1, UWord inRepeatCount=1)
Efficiently sleeps the calling thread/process until the next one or more field (interlaced video) or ...
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1284
static const size_t CIRCULAR_BUFFER_SIZE(10)
Number of NTV2FrameData&#39;s in our ring.
static const ULWord kDemoAppSignature((((uint32_t)( 'D'))<< 24)|(((uint32_t)( 'E'))<< 16)|(((uint32_t)( 'M'))<< 8)|(((uint32_t)( 'O'))<< 0))
Declares numerous NTV2 utility functions.
virtual AJAStatus Attach(AJAThreadFunction *pThreadFunction, void *pUserContext)
Definition: thread.cpp:169
FrameDataPtr StartProduceNextBuffer(void)
The thread that&#39;s responsible for providing frames – the producer – calls this function to populate...
bool GetInputTimeCodes(NTV2TimeCodeList &outValues) const
Intended for capture, answers with the timecodes captured in my acTransferStatus member&#39;s acFrameStam...
static void ProducerThreadStatic(AJAThread *pThread, void *pContext)
This is the capture thread&#39;s static callback function that gets called when the capture thread runs...
#define NTV2_IS_QUAD_QUAD_FORMAT(__f__)
Definition: ntv2enums.h:819
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
uint16_t UWord
Definition: ajatypes.h:221
virtual bool AncExtractGetBufferOverrun(const UWord inSDIInput, bool &outIsOverrun, const UWord inField=0)
Answers whether or not the given SDI input&#39;s Anc extractor reached its buffer limits. (Call NTV2DeviceCanDoCustomAnc to determine if the device supports Anc extractor firmware.)
Definition: ntv2anc.cpp:1016
#define CAPWARN(_expr_)
Specifies channel or FrameStore 1 (or the first item).
Definition: ntv2enums.h:1359
virtual bool AutoCirculateStart(const NTV2Channel inChannel, const ULWord64 inStartTime=0)
Starts AutoCirculating the specified channel that was previously initialized by CNTV2Card::AutoCircul...
bool CanDoFrameBufferFormat(const NTV2PixelFormat inPF)
ULWord appSignature(0)
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
NTV2ACFrameRange fFrames
AutoCirculate frame count or range.
NTV2PixelFormat fPixelFormat
Pixel format to use.
static bool GetInputRouting(NTV2XptConnections &outConnections, const CaptureConfig &inConfig, const bool isInputRGB=(0))
Answers with the crosspoint connections needed to implement the given capture configuration.
#define NTV2_IS_VALID_AUDIO_SYSTEM(__x__)
Definition: ntv2enums.h:3914
bool SetAncBuffers(ULWord *pInANCBuffer, const ULWord inANCByteCount, ULWord *pInANCF2Buffer=NULL, const ULWord inANCF2ByteCount=0)
Sets my ancillary data buffers for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
std::string NTV2FrameBufferFormatToString(const NTV2FrameBufferFormat inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:6936
I encapsulate the video, audio and anc host buffers used in the AutoCirculate demos. I&#39;m a more modern version of the AVDataBuffer.
virtual void StartConsumerThread(void)
Starts my frame consumer thread.
NTV2Buffer fVideoBuffer
Host video buffer.
NTV2AudioSystem NTV2ChannelToAudioSystem(const NTV2Channel inChannel)
Converts the given NTV2Channel value into its equivalent NTV2AudioSystem.
Definition: ntv2utils.cpp:4869
bool HasAvailableInputFrame(void) const
static bool ConfigureAudioSystems(CNTV2Card &inDevice, const CaptureConfig &inConfig, const NTV2AudioSystemSet inAudioSystems)
Configures capture audio systems.
bool IsRunning(void) const
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
Definition: ntv2capture.cpp:73
std::string fDeviceSpec
The AJA device to use.
std::map< NTV2InputXptID, NTV2OutputXptID > NTV2XptConnections
This is used by the CNTV2Card::ReadSDIStatistics function.
#define AJA_NTV2_AUDIO_RECORD_DO
ULWord GetCapturedAncByteCount(const bool inField2=false) const
bool CanDoVideoFormat(const NTV2VideoFormat inVF)
virtual bool AutoCirculateInitForInput(const NTV2Channel inChannel, const UWord inFrameCount=7, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_INVALID, const ULWord inOptionFlags=0, const UByte inNumChannels=1, const UWord inStartFrameNumber=0, const UWord inEndFrameNumber=0)
Prepares for subsequent AutoCirculate ingest, designating a contiguous block of frame buffers on the ...
#define AUTOCIRCULATE_WITH_RP188
Use this to AutoCirculate with RP188.
#define NTV2_INPUT_SOURCE_IS_SDI(_inpSrc_)
Definition: ntv2enums.h:1283
void * GetHostAddress(const ULWord inByteOffset, const bool inFromEnd=false) const
bool SetAudioBuffer(ULWord *pInAudioBuffer, const ULWord inAudioByteCount)
Sets my audio buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
NTV2Capture(const CaptureConfig &inConfig)
Constructs me using the given settings.
Definition: ntv2capture.cpp:25
bool mLocked
If true, a valid SDI transport was detected in the received data stream. If false, at least 15 consecutive lines in the received stream had TRS errors.
#define CAPNOTE(_expr_)
virtual bool SetVANCMode(const NTV2VANCMode inVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Sets the VANC mode for the given FrameStore.
#define AJA_NTV2_AUDIO_RECORD_BEGIN
virtual bool GetStreamingApplication(ULWord &outAppType, int32_t &outProcessID)
Answers with the four-CC type and process ID of the application that currently "owns" the AJA device ...
NTV2TimeCodes fTimecodes
Map of TC indexes to NTV2_RP188 values.
Declares device capability functions.
virtual bool WaitForInputVerticalInterrupt(const NTV2Channel inChannel=NTV2_CHANNEL1, UWord inRepeatCount=1)
Efficiently sleeps the calling thread/process until the next one or more field (interlaced video) or ...
This identifies the mode in which there are no VANC lines in the frame buffer.
Definition: ntv2enums.h:3799
bool SetVideoBuffer(ULWord *pInVideoBuffer, const ULWord inVideoByteCount)
Sets my video buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
virtual bool ReadSDIStatistics(NTV2SDIInStatistics &outStats)
For devices that support it (see the NTV2DeviceCanDoSDIErrorChecks function in "ntv2devicefeatures.h"), this function fetches the SDI statistics for all SDI input spigots.
NTV2LHIHDMIColorSpace
Definition: ntv2enums.h:3678
virtual ~NTV2Capture()
Definition: ntv2capture.cpp:40
ULWord NTV2IOKinds
Definition: ntv2enums.h:1310
virtual bool EnableChannel(const NTV2Channel inChannel)
Enables the given FrameStore.