AJA NTV2 SDK  18.0.0.2122
NTV2 SDK 18.0.0.2122
ntv2capture4k.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 //#define AJA_RECORD_MLAUDIO // Uncomment to record captured raw multilink audio into two binary data files
9 #include "ntv2capture4k.h"
10 #include "ntv2devicescanner.h"
11 #include "ntv2utils.h"
12 #include "ntv2devicefeatures.h"
13 #include "ajabase/system/process.h"
14 
15 using namespace std;
16 
17 #define NTV2_BUFFER_LOCK
18 
19 
21 
23  : mConsumerThread (AJAThread()),
24  mProducerThread (AJAThread()),
25  mDeviceID (DEVICE_ID_NOTFOUND),
26  mConfig (inConfig),
28  mSavedTaskMode (NTV2_DISABLE_TASKS),
29  mAudioSystem (inConfig.fWithAudio ? NTV2_AUDIOSYSTEM_1 : NTV2_AUDIOSYSTEM_INVALID),
30  mHostBuffers (),
31  mAVCircularBuffer (),
32  mGlobalQuit (false),
34 {
35 } // constructor
36 
37 
39 {
40  // Stop my capture and consumer threads, then destroy them...
41  Quit();
42 
43  // Unsubscribe from VBI events...
46 
47 } // destructor
48 
49 
51 {
52  // Set the global 'quit' flag, and wait for the threads to go inactive...
53  mGlobalQuit = true;
54 
55  while (mConsumerThread.Active())
56  AJATime::Sleep(10);
57 
58  while (mProducerThread.Active())
59  AJATime::Sleep(10);
60 
61  // Restore some of the device's former state...
62  if (!mConfig.fDoMultiFormat)
63  {
65  mDevice.SetTaskMode(mSavedTaskMode); // Restore prior task mode
66  }
67 
68 } // Quit
69 
70 
72 {
74 
75  // Open the device...
77  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not found" << endl; return AJA_STATUS_OPEN;}
78 
79  if (!mDevice.IsDeviceReady())
80  {cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
81 
82  mDeviceID = mDevice.GetDeviceID(); // Keep the device ID handy, as it's used frequently
83  const bool isKonaHDMI (mDevice.features().GetNumHDMIVideoInputs() > 1);
84  if (!mDevice.features().CanDoCapture())
85  {cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' is playback-only" << endl; return AJA_STATUS_FEATURE;}
86 
87  if (!mDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
88  { cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' doesn't support '"
89  << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat, true) << "' ("
90  << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat, false) << ", " << DEC(mConfig.fPixelFormat) << ")" << endl;
92  }
93 
94  ULWord appSignature (0);
95  int32_t appPID (0);
96  mDevice.GetStreamingApplication (appSignature, appPID); // Who currently "owns" the device?
97  mDevice.GetTaskMode(mSavedTaskMode); // Save the current task mode
98  if (!mConfig.fDoMultiFormat)
99  {
101  {
102  cerr << "## ERROR: Unable to acquire '" << mDevice.GetDisplayName() << "' because another app (pid " << appPID << ") owns it" << endl;
103  return AJA_STATUS_BUSY; // Another app is using the device
104  }
105  }
106  mDevice.SetTaskMode(NTV2_OEM_TASKS); // Prevent interference from AJA retail services
107 
108  if (mDevice.features().CanDoMultiFormat())
109  mDevice.SetMultiFormatMode(mConfig.fDoMultiFormat);
110 
111  // This demo permits only the input channel/frameStore to be specified. Set the input source here...
112  const NTV2Channel origCh (mConfig.fInputChannel);
113  if (isKonaHDMI)
114  { // KonaHDMI gets special treatment...
115  if (!mConfig.fDoTSIRouting)
116  {cerr << "## ERROR: UHD/4K on '" << mDevice.GetDisplayName() << "' requires TSI: omit '--squares' option" << endl; return AJA_STATUS_BAD_PARAM;}
117  if (mConfig.fInputChannel != NTV2_CHANNEL1 && mConfig.fInputChannel != NTV2_CHANNEL3)
118  mConfig.fInputChannel = NTV2_CHANNEL3;
120  }
121  else if (mDevice.features().CanDo12gRouting())
122  {
123  mConfig.fDoTSIRouting = false; // TSI Mux/Demux built-in to FrameStores
124  if (UWord(origCh) >= mDevice.features().GetNumFrameStores())
125  {
126  cerr << "## ERROR: No such channel Ch" << DEC(origCh) << " for '" << ::NTV2DeviceIDToString(mDeviceID,true) << "'";
127  return AJA_STATUS_BAD_PARAM;
128  }
130  }
131  else if (mConfig.fDoTSIRouting)
132  { // TSI: force even ordinal NTV2Channel values...
133  if (mConfig.fInputChannel < NTV2_CHANNEL3)
134  mConfig.fInputChannel = NTV2_CHANNEL1;
135  else if (mConfig.fInputChannel < NTV2_CHANNEL5)
136  mConfig.fInputChannel = NTV2_CHANNEL3;
137  else if (mConfig.fInputChannel < NTV2_CHANNEL7)
138  mConfig.fInputChannel = NTV2_CHANNEL5;
139  else
140  mConfig.fInputChannel = NTV2_CHANNEL7;
141  }
142  else // quad mode: force Ch1 (or Ch5 on Corvid88)
144 
147 
148  if (mConfig.fInputChannel != origCh)
149  cerr << "## WARNING: Specified channel Ch" << DEC(origCh+1) << " corrected to use Ch"
150  << DEC(mConfig.fInputChannel+1) << " to work for UHD/4K on '" << mDevice.GetDisplayName() << "'" << endl;
151 
152  // Determine input connectors and frameStores to be used...
153  const UWord numSpigots (mDevice.features().CanDo12gRouting() ? 1 : (mConfig.fDoTSIRouting ? 2 : 4));
154  mActiveSDIs = ::NTV2MakeChannelSet (::NTV2InputSourceToChannel(mConfig.fInputSource), numSpigots);
155  mActiveFrameStores = ::NTV2MakeChannelSet (mConfig.fInputChannel, numSpigots);
156 
157  // Set up the video and audio...
158  status = SetupVideo();
159  if (AJA_FAILURE(status))
160  return status;
161 
162  if (mConfig.fWithAudio)
163  status = SetupAudio();
164  if (AJA_FAILURE(status))
165  return status;
166 
167  // Set up the circular buffers, the device signal routing, and both playout and capture AutoCirculate...
169  if (!RouteInputSignal())
170  return AJA_STATUS_FAIL;
171 
172  #if defined(_DEBUG)
173  cerr << mConfig << endl << "FrameStores: " << ::NTV2ChannelSetToStr(mActiveFrameStores) << endl
174  << "Inputs: " << ::NTV2ChannelSetToStr(mActiveSDIs) << endl;
175  if (mDevice.IsRemote())
176  cerr << "Device Description: " << mDevice.GetDescription() << endl << endl;
177  #endif // defined(_DEBUG)
178  return AJA_STATUS_SUCCESS;
179 
180 } // Init
181 
182 
184 {
185  // Enable the FrameStores we intend to use...
186  mDevice.EnableChannels (mActiveFrameStores, !mConfig.fDoMultiFormat); // Disable the rest if we own the device
187 
188  // Enable and subscribe to VBIs (critical on Windows)...
189  mDevice.EnableInputInterrupt(mConfig.fInputChannel);
192 
193  // If the device supports bi-directional SDI and the requested input is SDI,
194  // ensure the SDI connector(s) are configured to receive...
196  {
197  mDevice.SetSDITransmitEnable (mActiveSDIs, false); // Set SDI connector(s) to receive
198  mDevice.WaitForOutputVerticalInterrupt (NTV2_CHANNEL1, 10); // Wait 10 VBIs to allow reciever to lock
199  }
200 
201  // Determine the input video signal format...
202  mVideoFormat = mDevice.GetInputVideoFormat(mConfig.fInputSource);
203  if (mVideoFormat == NTV2_FORMAT_UNKNOWN)
204  {cerr << "## ERROR: No input signal or unknown format" << endl; return AJA_STATUS_NOINPUT;}
205  CNTV2DemoCommon::Get4KInputFormat(mVideoFormat); // Convert to 4K format
206  mFormatDesc = NTV2FormatDescriptor(mVideoFormat, mConfig.fPixelFormat);
207 
208  // Setting SDI output clock timing/reference is unimportant for capture-only apps...
209  if (!mConfig.fDoMultiFormat) // ...if not sharing the device...
210  mDevice.SetReference(NTV2_REFERENCE_FREERUN); // ...let it free-run
211 
212  // Set the device video format to whatever was detected at the input(s)...
213  mDevice.SetVideoFormat (mVideoFormat, false, false, mConfig.fInputChannel);
214  mDevice.SetVANCMode (mActiveFrameStores, NTV2_VANCMODE_OFF); // Disable VANC
215  if (mDevice.features().CanDo12gRouting() || mConfig.fDoTSIRouting)
216  mDevice.SetTsiFrameEnable (true, mConfig.fInputChannel);
217  else
218  mDevice.Set4kSquaresEnable (true, mConfig.fInputChannel);
219 
220  // Set the frame buffer pixel format for the FrameStore(s) to be used on the device...
221  mDevice.SetFrameBufferFormat (mActiveFrameStores, mConfig.fPixelFormat);
222  return AJA_STATUS_SUCCESS;
223 
224 } // SetupVideo
225 
226 
228 {
229  // In multiformat mode, base the audio system on the channel...
230  if (mConfig.fDoMultiFormat)
231  if (mDevice.features().GetNumAudioSystems() > 1)
232  if (UWord(mConfig.fInputChannel) < mDevice.features().GetNumAudioSystems())
233  mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fInputChannel);
234 
235  NTV2AudioSystemSet audSystems (::NTV2MakeAudioSystemSet (mAudioSystem, 1));
236  if (mConfig.fNumAudioLinks > 1)
237  {
238  audSystems = ::NTV2MakeAudioSystemSet (NTV2_AUDIOSYSTEM_1, NTV2_IS_4K_HFR_VIDEO_FORMAT(mVideoFormat) ? 4 : 2);
239  if (mConfig.fInputChannel != NTV2_CHANNEL1)
240  {cerr << "## ERROR: Multi-Link audio demo only intended for input Ch1, not Ch" << DEC(mConfig.fInputChannel) << endl; return AJA_STATUS_UNSUPPORTED;}
241 
242  // Enable MultiLink audio...
244  if (NTV2_IS_4K_HFR_VIDEO_FORMAT(mVideoFormat))
245  {
248  }
249  }
250  CNTV2DemoCommon::ConfigureAudioSystems (mDevice, mConfig, audSystems);
251  return AJA_STATUS_SUCCESS;
252 
253 } // SetupAudio
254 
255 
257 {
258  // Let my circular buffer know when it's time to quit...
259  mAVCircularBuffer.SetAbortFlag(&mGlobalQuit);
260 
261  ULWord F1AncSize(0), F2AncSize(0);
262  if (mConfig.fWithAnc)
263  { // Use the max anc size stipulated by the AncFieldOffset VReg values...
264  ULWord F1OffsetFromEnd(0), F2OffsetFromEnd(0);
265  mDevice.ReadRegister(kVRegAncField1Offset, F1OffsetFromEnd); // # bytes from end of 8MB/16MB frame
266  mDevice.ReadRegister(kVRegAncField2Offset, F2OffsetFromEnd); // # bytes from end of 8MB/16MB frame
267  // Based on the offsets, calculate the max anc capacity
268  F1AncSize = F2OffsetFromEnd > F1OffsetFromEnd ? 0 : F1OffsetFromEnd - F2OffsetFromEnd;
269  F2AncSize = F2OffsetFromEnd > F1OffsetFromEnd ? F2OffsetFromEnd - F1OffsetFromEnd : F2OffsetFromEnd;
270  }
271 
272  // Allocate and add each in-host NTV2FrameData to my circular buffer member variable...
273  const size_t audioBufferSize (NTV2_AUDIOSIZE_MAX * mConfig.fNumAudioLinks);
274  mHostBuffers.reserve(size_t(CIRCULAR_BUFFER_SIZE));
275  while (mHostBuffers.size() < size_t(CIRCULAR_BUFFER_SIZE))
276  {
277  mHostBuffers.push_back(NTV2FrameData());
278  NTV2FrameData & frameData(mHostBuffers.back());
279  frameData.fVideoBuffer.Allocate(mFormatDesc.GetVideoWriteSize());
280  frameData.fAudioBuffer.Allocate(NTV2_IS_VALID_AUDIO_SYSTEM(mAudioSystem) ? audioBufferSize : 0);
281  frameData.fAncBuffer.Allocate(F1AncSize);
282  frameData.fAncBuffer2.Allocate(F2AncSize);
283  mAVCircularBuffer.Add(&frameData);
284 
285 #ifdef NTV2_BUFFER_LOCK
286  // Page lock the memory
287  if (frameData.fVideoBuffer)
288  mDevice.DMABufferLock(frameData.fVideoBuffer, true);
289  if (frameData.fAudioBuffer)
290  mDevice.DMABufferLock(frameData.fAudioBuffer, true);
291  if (frameData.fAncBuffer)
292  mDevice.DMABufferLock(frameData.fAncBuffer, true);
293 #endif
294  } // for each NTV2FrameData
295 
296 } // SetupHostBuffers
297 
298 
300 {
304 
305  const bool isInputRGB (inputColorSpace == NTV2_LHIHDMIColorSpaceRGB);
307 
308  return CNTV2DemoCommon::GetInputRouting4K (connections, mConfig, mDeviceID, isInputRGB)
309  && mDevice.ApplySignalRoute(connections, !mConfig.fDoMultiFormat);
310 
311 } // RouteInputSignal
312 
313 
315 {
316  // Start the playout and capture threads...
319  return AJA_STATUS_SUCCESS;
320 
321 } // Run
322 
323 
325 
326 // This starts the consumer thread
328 {
329  // Create and start the consumer thread...
330  mConsumerThread.Attach(ConsumerThreadStatic, this);
331  mConsumerThread.SetPriority(AJA_ThreadPriority_High);
332  mConsumerThread.Start();
333 
334 } // StartConsumerThread
335 
336 
337 // The consumer thread function
338 void NTV2Capture4K::ConsumerThreadStatic (AJAThread * pThread, void * pContext) // static
339 {
340  (void) pThread;
341 
342  // Grab the NTV2Capture instance pointer from the pContext parameter,
343  // then call its ConsumeFrames method...
344  NTV2Capture4K * pApp (reinterpret_cast<NTV2Capture4K*>(pContext));
345  pApp->ConsumeFrames();
346 
347 } // ConsumerThreadStatic
348 
349 
351 {
352  CAPNOTE("Thread started");
353  AJA_NTV2_MLAUDIO_RECORD_BEGIN // Active when AJA_RECORD_MLAUDIO defined
354 
355  while (!mGlobalQuit)
356  {
357  // Wait for the next frame to become ready to "consume"...
358  NTV2FrameData * pFrameData(mAVCircularBuffer.StartConsumeNextBuffer());
359  if (pFrameData)
360  {
361  // Do something useful with the frame data...
362  // . . . . . . . . . . . .
363  // . . . . . . . . . . . .
364  // . . . . . . . . . . . .
365  AJA_NTV2_MLAUDIO_RECORD_DO // Active when AJA_RECORD_MLAUDIO defined
366 
367  // Now release and recycle the buffer...
368  mAVCircularBuffer.EndConsumeNextBuffer();
369  } // if pFrameData
370  } // loop til quit signaled
371 
372  AJA_NTV2_MLAUDIO_RECORD_END // Active when AJA_RECORD_MLAUDIO defined
373  CAPNOTE("Thread completed, will exit");
374 
375 } // ConsumeFrames
376 
377 
379 
380 // This starts the capture (producer) thread
382 {
383  // Create and start the capture thread...
384  mProducerThread.Attach(ProducerThreadStatic, this);
385  mProducerThread.SetPriority(AJA_ThreadPriority_High);
386  mProducerThread.Start();
387 
388 } // StartProducerThread
389 
390 
391 // The capture thread function
392 void NTV2Capture4K::ProducerThreadStatic (AJAThread * pThread, void * pContext) // static
393 {
394  (void) pThread;
395 
396  // Grab the NTV2Capture instance pointer from the pContext parameter,
397  // then call its CaptureFrames method...
398  NTV2Capture4K * pApp (reinterpret_cast<NTV2Capture4K*>(pContext));
399  pApp->CaptureFrames ();
400 
401 } // ProducerThreadStatic
402 
403 
405 {
406  AUTOCIRCULATE_TRANSFER inputXfer; // AutoCirculate input transfer info
407 
408  // Have AutoCirculate use 7 device frame buffers...
409  static const UWord startFrame12g[] = {0, 7, 64, 71};
410  static const UWord startFrame[] = {0, 7, 14, 21};
411  if (mDevice.features().CanDo12gRouting())
412  mConfig.fFrames.setRangeWithCount(7, startFrame12g[mConfig.fInputChannel]);
413  else // TSI or Squares
414  mConfig.fFrames.setRangeWithCount(7, startFrame[mConfig.fInputChannel / 2]);
415  CAPNOTE("Thread started");
416 
417  // Initialize and start capture AutoCirculate...
418  mDevice.AutoCirculateStop(mActiveFrameStores); // Just in case
419  if (!mDevice.AutoCirculateInitForInput (mConfig.fInputChannel, mConfig.fFrames, mAudioSystem, mACOptions))
420  mGlobalQuit = true;
421  if (!mGlobalQuit && !mDevice.AutoCirculateStart(mConfig.fInputChannel))
422  mGlobalQuit = true;
423 
424  // Ingest frames til Quit signaled...
425  while (!mGlobalQuit)
426  {
427  AUTOCIRCULATE_STATUS acStatus;
428  mDevice.AutoCirculateGetStatus (mConfig.fInputChannel, acStatus);
429 
430  if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
431  {
432  // At this point, there's at least one fully-formed frame available in the device's
433  // frame buffer to transfer to the host. Reserve an NTV2FrameData to "produce", and
434  // use it in the next transfer from the device...
435  NTV2FrameData * pFrameData (mAVCircularBuffer.StartProduceNextBuffer());
436  if (!pFrameData)
437  continue;
438 
439  NTV2FrameData & frameData (*pFrameData);
440  inputXfer.SetVideoBuffer (frameData.VideoBuffer(), frameData.VideoBufferSize());
441  if (acStatus.WithAudio())
442  inputXfer.SetAudioBuffer (frameData.AudioBuffer(), frameData.AudioBufferSize());
443  if (acStatus.WithCustomAnc())
444  inputXfer.SetAncBuffers (frameData.AncBuffer(), frameData.AncBufferSize(),
445  frameData.AncBuffer2(), frameData.AncBuffer2Size());
446 
447  // Transfer video/audio/anc from the device into our host buffers...
448  mDevice.AutoCirculateTransfer (mConfig.fInputChannel, inputXfer);
449 
450  // Remember the actual amount of audio captured...
451  if (acStatus.WithAudio())
452  frameData.fNumAudioBytes = inputXfer.GetCapturedAudioByteCount();
453 
454  // Grab all valid timecodes that were captured...
455  inputXfer.GetInputTimeCodes (frameData.fTimecodes, mConfig.fInputChannel, /*ValidOnly*/ true);
456 
457  // Signal that we're done "producing" the frame, making it available for future "consumption"...
458  mAVCircularBuffer.EndProduceNextBuffer();
459  } // if A/C running and frame(s) are available for transfer
460  else
461  {
462  // Either AutoCirculate is not running, or there were no frames available on the device to transfer.
463  // Rather than waste CPU cycles spinning, waiting until a frame becomes available, it's far more
464  // efficient to wait for the next input vertical interrupt event to get signaled...
466  }
467  } // loop til quit signaled
468 
469  // Stop AutoCirculate...
470  mDevice.AutoCirculateStop (mConfig.fInputChannel);
471  CAPNOTE("Thread completed, will exit");
472 
473 } // CaptureFrames
474 
475 
476 void NTV2Capture4K::GetACStatus (ULWord & outGoodFrames, ULWord & outDroppedFrames, ULWord & outBufferLevel)
477 {
478  AUTOCIRCULATE_STATUS status;
479  mDevice.AutoCirculateGetStatus(mConfig.fInputChannel, status);
480  outGoodFrames = status.GetProcessedFrameCount();
481  outDroppedFrames = status.GetDroppedFrameCount();
482  outBufferLevel = status.GetBufferLevel();
483 }
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.
virtual AJAStatus SetupVideo(void)
Sets up everything I need for capturing video.
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...
NTV2Capture4K(const CaptureConfig &inConfig)
Constructs me using the given settings.
std::string NTV2ChannelSetToStr(const NTV2ChannelSet &inObj, const bool inCompact=true)
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...
#define AJA_NTV2_MLAUDIO_RECORD_DO
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO3
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 3. ...
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.
Identifies the 2nd HDMI video input.
Definition: ntv2enums.h:1266
virtual bool RouteInputSignal(void)
Sets up device routing for capture.
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.
virtual bool Set4kSquaresEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 "2K quadrants" mode for the given FrameStore bank on the device...
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 void StartProducerThread(void)
Starts my capture thread.
virtual bool IsDeviceReady(const bool inCheckValid=(0))
ULWord AudioBufferSize(void) const
Declares the NTV2Capture class.
Identifies the 1st HDMI video input.
Definition: ntv2enums.h:1265
static uint64_t GetPid()
Definition: process.cpp:35
ULWord GetBufferLevel(void) const
#define AJA_FAILURE(_status_)
Definition: types.h:373
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
NTV2InputSource NTV2ChannelToInputSource(const NTV2Channel inChannel, const NTV2IOKinds inKinds=NTV2_IOKINDS_SDI)
Definition: ntv2utils.cpp:5132
bool WithAudio(void) const
NTV2AudioSystemSet NTV2MakeAudioSystemSet(const NTV2AudioSystem inFirstAudioSystem, const UWord inCount=1)
virtual AJAStatus SetPriority(AJAThreadPriority priority)
Definition: thread.cpp:133
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.
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.
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1357
mVideoFormat
Definition: ntv2vcam.cpp:801
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:148
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
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO1
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 1. ...
ULWord GetProcessedFrameCount(void) const
bool fWithAudio
If true, also capture Audio.
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
virtual bool GetTaskMode(NTV2TaskMode &outMode)
Retrieves the device&#39;s current task mode.
virtual bool EnableChannels(const NTV2ChannelSet &inChannels, const bool inDisableOthers=(0))
Enables the given FrameStore(s).
0: Disabled (never recommended): device configured exclusively by client application(s).
virtual std::string GetDescription(void) const
Definition: ntv2card.cpp:139
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 GetACStatus(ULWord &outGoodFrames, ULWord &outDroppedFrames, ULWord &outBufferLevel)
Provides status information about my input (capture) process.
#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)
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
Instances of me capture frames in real time from a video signal provided to an input of an AJA device...
Definition: ntv2capture4k.h:19
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.
#define AJA_NTV2_MLAUDIO_RECORD_END
NTV2XptConnections connections
Definition: ntv2vcam.cpp:1011
std::set< NTV2AudioSystem > NTV2AudioSystemSet
A set of distinct NTV2AudioSystem values. New in SDK 16.2.
NTV2Buffer & VideoBuffer(void)
ULWord GetDroppedFrameCount(void) const
virtual bool SetTsiFrameEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 two-sample interleave (Tsi) frame mode on the device.
#define AUTOCIRCULATE_WITH_ANC
Use this to AutoCirculate with ancillary data.
virtual NTV2DeviceID GetDeviceID(void)
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...
virtual void CaptureFrames(void)
Repeatedly captures frames using AutoCirculate (until global quit flag set).
#define NTV2_IS_4K_HFR_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:794
Declares the CNTV2DeviceScanner class.
UWord fNumAudioLinks
Number of audio links to capture.
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...
Declares the AJAProcess class.
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...
NTV2Buffer & AudioBuffer(void)
std::string NTV2DeviceIDToString(const NTV2DeviceID inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:4608
This object specifies the information that will be transferred to or from the AJA device in the CNTV2...
#define AJA_NTV2_MLAUDIO_RECORD_BEGIN
NTV2InputSource fInputSource
The device input connector to use.
#define DEC(__x__)
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 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 setRangeWithCount(const UWord inCount, const UWord inFirstFrame)
Definition: ntv2utils.h:1008
virtual void ConsumeFrames(void)
Repeatedly consumes frames from the circular buffer (until global quit flag set). ...
bool GetInputTimeCodes(NTV2TimeCodeList &outValues) const
Intended for capture, answers with the timecodes captured in my acTransferStatus member&#39;s acFrameStam...
static bool Get4KInputFormat(NTV2VideoFormat &inOutVideoFormat)
Given a video format, if all 4 inputs are the same and promotable to 4K, this function does the promo...
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
uint16_t UWord
Definition: ajatypes.h:221
Specifies channel or FrameStore 1 (or the first item).
Definition: ntv2enums.h:1359
static bool GetInputRouting4K(NTV2XptConnections &outConnections, const CaptureConfig &inConfig, const NTV2DeviceID inDevID=DEVICE_ID_INVALID, const bool isInputRGB=(0))
Answers with the crosspoint connections needed to implement the given 4K/UHD capture configuration...
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.
virtual AJAStatus SetupAudio(void)
Sets up everything I need for capturing audio.
NTV2PixelFormat fPixelFormat
Pixel format to use.
#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.
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
NTV2ChannelSet NTV2MakeChannelSet(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Specifies channel or FrameStore 5 (or the 5th item).
Definition: ntv2enums.h:1363
static bool ConfigureAudioSystems(CNTV2Card &inDevice, const CaptureConfig &inConfig, const NTV2AudioSystemSet inAudioSystems)
Configures capture audio systems.
bool IsRunning(void) const
virtual ~NTV2Capture4K()
virtual AJAStatus Run(void)
Runs me.
std::string fDeviceSpec
The AJA device to use.
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO2
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 2. ...
std::map< NTV2InputXptID, NTV2OutputXptID > NTV2XptConnections
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.
Specifies channel or FrameStore 7 (or the 7th item).
Definition: ntv2enums.h:1365
#define NTV2_INPUT_SOURCE_IS_SDI(_inpSrc_)
Definition: ntv2enums.h:1283
bool SetAudioBuffer(ULWord *pInAudioBuffer, const ULWord inAudioByteCount)
Sets my audio buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
#define CAPNOTE(_expr_)
virtual bool SetVANCMode(const NTV2VANCMode inVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Sets the VANC mode for the given FrameStore.
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 ...
virtual void Quit(void)
Gracefully stops me from running.
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.
Specifies channel or FrameStore 3 (or the 3rd item).
Definition: ntv2enums.h:1361
NTV2LHIHDMIColorSpace
Definition: ntv2enums.h:3678
virtual void StartConsumerThread(void)
Starts my frame consumer thread.
virtual void SetupHostBuffers(void)
Sets up my circular buffers.
bool fDoTSIRouting
If true, do TSI routing; otherwise squares.