AJA NTV2 SDK  18.0.0.2122
NTV2 SDK 18.0.0.2122
ntv2burn4kquadrant.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2burn4kquadrant.h"
9 #include "ntv2devicescanner.h"
10 #include "ntv2formatdescriptor.h"
11 #include "ajabase/common/types.h"
12 #include "ajabase/system/process.h"
13 #include <iostream>
14 
15 using namespace std;
16 
17 
18 
20 
21  : mConfig (inConfig),
22  mPlayThread (AJAThread()),
23  mCaptureThread (AJAThread()),
24  mInputAudioSystem (NTV2_AUDIOSYSTEM_1),
25  mOutputAudioSystem (NTV2_AUDIOSYSTEM_1),
26  mSingleDevice (false),
27  mGlobalQuit (false)
28 {
29  CNTV2DemoCommon::SetDefaultPageSize(); // Set host-specific page size
30 
31  if (mConfig.fDeviceSpec == mConfig.fDeviceSpec2)
32  mSingleDevice = true;
33 
34 } // constructor
35 
36 
38 {
39  // Stop my capture and playout threads, then destroy them...
40  Quit ();
41 
42  // Unsubscribe from input vertical event...
43  mInputDevice.UnsubscribeInputVerticalEvent (mConfig.fInputChannel);
44  mOutputDevice.UnsubscribeOutputVerticalEvent (mConfig.fOutputChannel);
45 
46  mInputDevice.SetTaskMode (mInputSavedTaskMode); // Restore prior service level
47  mInputDevice.ReleaseStreamForApplication (kDemoAppSignature, int32_t(AJAProcess::GetPid())); // Release the device
48 
49  if (!mSingleDevice)
50  {
51  mOutputDevice.SetTaskMode (mOutputSavedTaskMode); // Restore prior service level
52  mOutputDevice.ReleaseStreamForApplication (kDemoAppSignature, int32_t(AJAProcess::GetPid())); // Release the device
53  }
54 
55 } // destructor
56 
57 
59 {
60  // Set the global 'quit' flag, and wait for the threads to go inactive...
61  mGlobalQuit = true;
62 
63  while (mPlayThread.Active())
64  AJATime::Sleep(10);
65 
66  while (mCaptureThread.Active())
67  AJATime::Sleep(10);
68 
69 } // Quit
70 
71 
73 {
75 
76  // Open the device...
78  {cerr << "## ERROR: Input device '" << mConfig.fDeviceSpec << "' not found" << endl; return AJA_STATUS_OPEN;}
79 
80  // Store the input device ID in a member because it will be used frequently...
81  mInputDeviceID = mInputDevice.GetDeviceID ();
82  if (!mInputDevice.features().CanDo4KVideo())
83  {cerr << "## ERROR: Input device '" << mConfig.fDeviceSpec << "' cannot do 4K/UHD video" << endl; return AJA_STATUS_UNSUPPORTED;}
84 
85  if (!mInputDevice.IsDeviceReady (false))
86  {cerr << "## ERROR: Input device '" << mConfig.fDeviceSpec << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
87 
88  // Output device:
90  {cerr << "## ERROR: Output device '" << mConfig.fDeviceSpec2 << "' not found" << endl; return AJA_STATUS_OPEN;}
91 
92  // Store the output device ID in a member because it will be used frequently...
93  mOutputDeviceID = mOutputDevice.GetDeviceID ();
94  if (!mOutputDevice.features().CanDo4KVideo())
95  {cerr << "## ERROR: Output device '" << mConfig.fDeviceSpec2 << "' cannot do 4K/UHD video" << endl; return AJA_STATUS_UNSUPPORTED;}
96 
97  if (!mOutputDevice.IsDeviceReady(false))
98  {cerr << "## ERROR: Output device '" << mConfig.fDeviceSpec2 << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
99 
100  if (mSingleDevice)
101  {
102  if (mInputDevice.features().GetNumFrameStores() < 8)
103  {cerr << "## ERROR: Single device '" << mConfig.fDeviceSpec2 << "' requires 8 video channels" << endl; return AJA_STATUS_UNSUPPORTED;}
104  mOutputAudioSystem = NTV2_AUDIOSYSTEM_5;
105  mConfig.fOutputChannel = NTV2_CHANNEL5;
106  }
107 
108  if (!mInputDevice.AcquireStreamForApplication (kDemoAppSignature, static_cast<int32_t>(AJAProcess::GetPid())))
109  {cerr << "## ERROR: Input device '" << mConfig.fDeviceSpec << "' is in use by another application" << endl; return AJA_STATUS_BUSY;}
110  mInputDevice.GetTaskMode (mInputSavedTaskMode); // Save the current state before changing it
111  mInputDevice.SetTaskMode (NTV2_OEM_TASKS); // Since this is an OEM demo, use the OEM service level
112 
113  if (!mSingleDevice)
114  {
115  if (!mOutputDevice.AcquireStreamForApplication (kDemoAppSignature, static_cast <int32_t>(AJAProcess::GetPid())))
116  {cerr << "## ERROR: Output device '" << mConfig.fDeviceSpec2 << "' is in use by another application" << endl; return AJA_STATUS_BUSY;}
117 
118  mOutputDevice.GetTaskMode (mOutputSavedTaskMode); // Save the current state before changing it
119  mOutputDevice.SetTaskMode (NTV2_OEM_TASKS); // Since this is an OEM demo, use the OEM service level
120  }
121 
122  if (mInputDevice.features().CanDoMultiFormat())
123  mInputDevice.SetMultiFormatMode (false);
124  if (mOutputDevice.features().CanDoMultiFormat())
125  mOutputDevice.SetMultiFormatMode (false);
126 
127  // Sometimes other applications disable some or all of the frame buffers, so turn them all on here...
128  switch (mInputDevice.features().GetNumFrameStores())
129  {
130  case 8: mInputDevice.EnableChannel (NTV2_CHANNEL8);
131  mInputDevice.EnableChannel (NTV2_CHANNEL7);
132  mInputDevice.EnableChannel (NTV2_CHANNEL6);
133  mInputDevice.EnableChannel (NTV2_CHANNEL5);
134  /* FALLTHRU */
135  case 4: mInputDevice.EnableChannel (NTV2_CHANNEL4);
136  mInputDevice.EnableChannel (NTV2_CHANNEL3);
137  /* FALLTHRU */
138  case 2: mInputDevice.EnableChannel (NTV2_CHANNEL2);
139  /* FALLTHRU */
140  case 1: mInputDevice.EnableChannel (NTV2_CHANNEL1);
141  break;
142  }
143 
144  if (!mSingleDevice) // Don't do this twice if Input & Output devices are same device!
145  switch (mOutputDevice.features().GetNumFrameStores())
146  {
147  case 8: mOutputDevice.EnableChannel (NTV2_CHANNEL8);
148  mOutputDevice.EnableChannel (NTV2_CHANNEL7);
149  mOutputDevice.EnableChannel (NTV2_CHANNEL6);
150  mOutputDevice.EnableChannel (NTV2_CHANNEL5);
151  /* FALLTHRU */
152  case 4: mOutputDevice.EnableChannel (NTV2_CHANNEL4);
153  mOutputDevice.EnableChannel (NTV2_CHANNEL3);
154  /* FALLTHRU */
155  case 2: mOutputDevice.EnableChannel (NTV2_CHANNEL2);
156  /* FALLTHRU */
157  case 1: mOutputDevice.EnableChannel (NTV2_CHANNEL1);
158  break;
159  }
160 
161  // Set up the video and audio...
162  status = SetupInputVideo();
163  if (AJA_FAILURE (status))
164  return status;
165 
166  status = SetupOutputVideo();
167  if (AJA_FAILURE (status))
168  return status;
169 
170  status = SetupInputAudio();
171  if (AJA_FAILURE (status))
172  return status;
173 
174  status = SetupOutputAudio();
175  if (AJA_FAILURE (status))
176  return status;
177 
178  // Set up the circular buffers...
179  status = SetupHostBuffers();
180  if (AJA_FAILURE(status))
181  return status;
182 
183  // Set up the signal routing...
186 
187  // Lastly, prepare my AJATimeCodeBurn instance...
189  mFormatDesc.numPixels,
190  mFormatDesc.numLines);
191  // Ready to go...
192  #if defined(_DEBUG)
193  cerr << mConfig;
194  if (mInputDevice.IsRemote())
195  cerr << "Input Device Desc: " << mInputDevice.GetDescription() << endl;
196  if (mOutputDevice.IsRemote())
197  cerr << "Output Device Desc: " << mOutputDevice.GetDescription() << endl;
198  cerr << endl;
199  #endif // not _DEBUG
200  BURNINFO("Configuration: " << mConfig);
201  return AJA_STATUS_SUCCESS;
202 
203 } // Init
204 
205 
207 {
208  // Set the video format to match the incoming video format.
209  // Does the device support the desired input source?
210  // Since this is a 4k Quadrant example, look at one of the inputs and deduce the 4k geometry from the quadrant geometry...
211 
212  // Determine the input video signal format, and set the device's reference source to that input.
213  // If you want to look at one of the quadrants, say on the HDMI output, then lock to one of the
214  // inputs (this assumes all quadrants are timed)...
215 
216  // First, enable all of the necessary interrupts, and subscribe to the interrupts for the channel to be used...
217  mInputDevice.EnableInputInterrupt (mConfig.fInputChannel);
218  mInputDevice.SubscribeInputVerticalEvent (mConfig.fInputChannel);
219 
220  // Turn multiformat off for this demo -- all multiformat devices will follow channel 1 configuration...
221 
222  // For devices with bi-directional SDI connectors, their transmitter must be turned off before we can read a format...
223  if (mInputDevice.features().HasBiDirectionalSDI())
224  {
225  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL1, false);
226  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL2, false);
227  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL3, false);
228  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL4, false);
229  AJATime::Sleep(1000);
230  }
231 
232  mVideoFormat = NTV2_FORMAT_UNKNOWN;
233  mVideoFormat = mInputDevice.GetInputVideoFormat (NTV2_INPUTSOURCE_SDI1);
234  mInputDevice.SetReference (NTV2_REFERENCE_INPUT1);
235 
236  if (mVideoFormat == NTV2_FORMAT_UNKNOWN)
237  return AJA_STATUS_NOINPUT; // Sorry, can't handle this format
238 
239  // Set the device format to the input format detected...
240  CNTV2DemoCommon::Get4KInputFormat (mVideoFormat);
241  mInputDevice.SetVideoFormat (mVideoFormat);
242 
243  // Set the frame buffer pixel format for all the channels on the device
244  // (assuming the device supports that pixel format -- otherwise default to 8-bit YCbCr)...
245  if (!mInputDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
247 
248  // ...and set all buffers pixel format...
249  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL1, mConfig.fPixelFormat);
250  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL2, mConfig.fPixelFormat);
251  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL3, mConfig.fPixelFormat);
252  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL4, mConfig.fPixelFormat);
253 
254  mInputDevice.SetEnableVANCData (false, false);
255 
256  // Now that the video is set up, get information about the current frame geometry...
257  mFormatDesc = NTV2FormatDescriptor (mVideoFormat, mConfig.fPixelFormat);
258  return AJA_STATUS_SUCCESS;
259 
260 } // SetupInputVideo
261 
262 
264 {
265  // We turned off the transmit for the capture device, so now turn them on for the playback device...
266  if (mOutputDevice.features().HasBiDirectionalSDI())
267  {
268  // Devices having bidirectional SDI must be set to "transmit"...
269  if (mSingleDevice)
270  {
271  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL5, true);
272  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL6, true);
273  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL7, true);
274  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL8, true);
275  }
276  else
277  {
278  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL1, true);
279  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL2, true);
280  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL3, true);
281  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL4, true);
282  }
283  }
284 
285  // Set the video format to match the incoming video format...
286  mOutputDevice.SetVideoFormat (mVideoFormat);
287  mOutputDevice.SetReference (NTV2_REFERENCE_FREERUN);
288 
289  if (mVideoFormat == NTV2_FORMAT_UNKNOWN)
290  return AJA_STATUS_NOINPUT; // Sorry, can't handle this format
291 
292  // Set the frame buffer pixel format for all the channels on the device
293  // (assuming the device supports that pixel format -- otherwise default to 8-bit YCbCr)...
294  if (!mOutputDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
296 
297  // ...and set the pixel format for all frame stores...
298  if (mSingleDevice)
299  {
300  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL5, mConfig.fPixelFormat);
301  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL6, mConfig.fPixelFormat);
302  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL7, mConfig.fPixelFormat);
303  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL8, mConfig.fPixelFormat);
304  }
305  else
306  {
307  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL1, mConfig.fPixelFormat);
308  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL2, mConfig.fPixelFormat);
309  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL3, mConfig.fPixelFormat);
310  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL4, mConfig.fPixelFormat);
311  }
312 
313  // Set all frame buffers to playback
314  if (mSingleDevice)
315  {
316  mOutputDevice.SetMode (NTV2_CHANNEL5, NTV2_MODE_DISPLAY);
317  mOutputDevice.SetMode (NTV2_CHANNEL6, NTV2_MODE_DISPLAY);
318  mOutputDevice.SetMode (NTV2_CHANNEL7, NTV2_MODE_DISPLAY);
319  mOutputDevice.SetMode (NTV2_CHANNEL8, NTV2_MODE_DISPLAY);
320  }
321  else
322  {
323  mOutputDevice.SetMode (NTV2_CHANNEL1, NTV2_MODE_DISPLAY);
324  mOutputDevice.SetMode (NTV2_CHANNEL2, NTV2_MODE_DISPLAY);
325  mOutputDevice.SetMode (NTV2_CHANNEL3, NTV2_MODE_DISPLAY);
326  mOutputDevice.SetMode (NTV2_CHANNEL4, NTV2_MODE_DISPLAY);
327  }
328 
329  // Subscribe the output interrupt (it's enabled by default).
330  // If using a single-device, then subscribe the output channel to
331  // channel 5's interrupts, otherwise channel 1's...
332  if (mSingleDevice)
333  {
334  mOutputDevice.EnableOutputInterrupt (NTV2_CHANNEL5);
336  }
337  else
338  {
339  mOutputDevice.EnableOutputInterrupt(NTV2_CHANNEL1);
341  }
342 
343  mOutputDevice.SetEnableVANCData (false, false);
344 
345  return AJA_STATUS_SUCCESS;
346 
347 } // SetupOutputVideo
348 
349 
351 {
352  // We will be capturing and playing back with audio system 1.
353  // First, determine how many channels the device is capable of capturing or playing out...
354  const uint16_t numberOfAudioChannels (mInputDevice.features().GetMaxAudioChannels());
355 
356  // Have the input audio system grab audio from the designated input source...
358 
359  mInputDevice.SetNumberAudioChannels (numberOfAudioChannels, mInputAudioSystem);
360  mInputDevice.SetAudioRate (NTV2_AUDIO_48K, mInputAudioSystem);
361 
362  // How big should the on-device audio buffer be? 1MB? 2MB? 4MB? 8MB?
363  // For this demo, 4MB will work best across all platforms (Windows, Mac & Linux)...
364  mInputDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mInputAudioSystem);
365 
366  // Loopback mode is used to play whatever audio appears in the input signal when
367  // it's connected directly to an output (i.e., "end-to-end" mode). If loopback is
368  // left enabled, the video will lag the audio as video frames get briefly delayed
369  // in our ring buffer. Audio, therefore, needs to come out of the (buffered) frame
370  // data being played, so loopback must be turned off...
371  mInputDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, mInputAudioSystem);
372 
373  return AJA_STATUS_SUCCESS;
374 
375 } // SetupInputAudio
376 
377 
379 {
380  // Audio system 1 will be used to capture and playback audio.
381  // First, determine how many channels the device is capable of capturing or playing out...
382  const uint16_t numberOfAudioChannels (mOutputDevice.features().GetMaxAudioChannels());
383 
384  mOutputDevice.SetNumberAudioChannels (numberOfAudioChannels, mOutputAudioSystem);
385  mOutputDevice.SetAudioRate (NTV2_AUDIO_48K, mOutputAudioSystem);
386 
387  // AJA recommends using a 4MB on-device audio buffer...
388  mOutputDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mOutputAudioSystem);
389 
390  // Finally, set up the output audio embedders...
391  if (mSingleDevice)
392  {
393  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL5, mOutputAudioSystem);
394  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL6, mOutputAudioSystem);
395  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL7, mOutputAudioSystem);
396  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL8, mOutputAudioSystem);
397  }
398  else
399  {
400  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL1, mOutputAudioSystem);
401  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL2, mOutputAudioSystem);
402  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL3, mOutputAudioSystem);
403  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL4, mOutputAudioSystem);
404  }
405 
406  //
407  // Loopback mode is used to play whatever audio appears in the input signal when
408  // it's connected directly to an output (i.e., "end-to-end" mode). If loopback is
409  // left enabled, the video will lag the audio as video frames get briefly delayed
410  // in our ring buffer. Audio, therefore, needs to come out of the (buffered) frame
411  // data being played, so loopback must be turned off...
412  //
413  mOutputDevice.SetAudioLoopBack(NTV2_AUDIO_LOOPBACK_OFF, mOutputAudioSystem);
414 
415  return AJA_STATUS_SUCCESS;
416 
417 } // SetupAudio
418 
419 
421 {
422  CNTV2DemoCommon::SetDefaultPageSize(); // Set host-specific page size
423 
424  // Let my circular buffer know when it's time to quit...
425  mFrameDataRing.SetAbortFlag (&mGlobalQuit);
426 
427  // Determine video buffer size...
428  const ULWord vidBuffSizeBytes (mFormatDesc.GetVideoWriteSize(ULWord(NTV2Buffer::DefaultPageSize())));
429 
430  // Allocate and add each in-host NTV2FrameData to my mFrameDataRing...
431  mHostBuffers.reserve(CIRCULAR_BUFFER_SIZE);
432  while (mHostBuffers.size() < CIRCULAR_BUFFER_SIZE)
433  {
434  mHostBuffers.push_back(NTV2FrameData()); // Make a new NTV2FrameData...
435  NTV2FrameData & frameData (mHostBuffers.back()); // ...and get a reference to it
436 
437  // Allocate a page-aligned video buffer (if handling video)...
438  if (!mConfig.fSuppressVideo)
439  if (!frameData.fVideoBuffer.Allocate (vidBuffSizeBytes, /*pageAligned*/true))
440  {
441  BURNFAIL("Failed to allocate " << xHEX0N(vidBuffSizeBytes,8) << "-byte video buffer");
442  return AJA_STATUS_MEMORY;
443  }
444 
445  // Allocate a page-aligned audio buffer (if handling audio)...
446  if (mConfig.WithAudio())
447  if (!frameData.fAudioBuffer.Allocate (NTV2_AUDIOSIZE_MAX, /*pageAligned*/true))
448  {
449  BURNFAIL("Failed to allocate " << xHEX0N(NTV2_AUDIOSIZE_MAX,8) << "-byte audio buffer");
450  return AJA_STATUS_MEMORY;
451  }
452  if (frameData.AudioBuffer())
453  frameData.fAudioBuffer.Fill(ULWord(0));
454 
455  // Add this NTV2FrameData to the ring...
456  mFrameDataRing.Add(&frameData);
457  } // for each NTV2FrameData
458 
459  return AJA_STATUS_SUCCESS;
460 
461 } // SetupHostBuffers
462 
463 
465 {
466  // Since this is only a 4k example, we will route all inputs to framebuffers
467  // and color space convert when necessary...
468  mInputDevice.ClearRouting ();
469  if(IsRGBFormat(mConfig.fPixelFormat))
470  {
475 
480  }
481  else
482  {
487  }
488 
489 } // RouteInputSignal
490 
491 
493 {
494  // Since this is only a 4k example, route all framebuffers to SDI outputs, and colorspace convert when necessary...
495  if (!mSingleDevice)
496  mOutputDevice.ClearRouting ();
497  if (!mSingleDevice)
498  {
499  if (::IsRGBFormat (mConfig.fPixelFormat))
500  {
505 
510  }
511  else
512  {
517  }
518  }
519  else
520  {
521  if (::IsRGBFormat (mConfig.fPixelFormat))
522  {
527 
532  }
533  else
534  {
539  }
540  }
541 
542 } // RouteOutputSignal
543 
544 
546 {
547  // Start the playout and capture threads...
548  StartPlayThread ();
550 
551  return AJA_STATUS_SUCCESS;
552 
553 } // Run
554 
555 
556 
558 
559 // This is where we will start the play thread
561 {
562  // Create and start the playout thread...
563  mPlayThread.Attach(PlayThreadStatic, this);
565  mPlayThread.Start();
566 
567 } // StartPlayThread
568 
569 
570 // The playout thread function
571 void NTV2Burn4KQuadrant::PlayThreadStatic (AJAThread * pThread, void * pContext) // static
572 { (void) pThread;
573  // Grab the NTV2Burn4K instance pointer from the pContext parameter,
574  // then call its PlayFrames method...
575  NTV2Burn4KQuadrant * pApp(reinterpret_cast<NTV2Burn4KQuadrant*>(pContext));
576  pApp->PlayFrames();
577 
578 } // PlayThreadStatic
579 
580 
582 {
583  const ULWord acOptions (AUTOCIRCULATE_WITH_RP188);
584  ULWord goodXfers(0), badXfers(0), starves(0), noRoomWaits(0);
585  AUTOCIRCULATE_TRANSFER outputXferInfo;
586  AUTOCIRCULATE_STATUS outputStatus;
587 
588  if (mSingleDevice)
589  {
590  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL5);
591  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL6);
592  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL7);
593  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL8);
594  }
595  else
596  {
597  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL1);
598  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL2);
599  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL3);
600  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL4);
601  }
602  mOutputDevice.WaitForOutputVerticalInterrupt(mConfig.fOutputChannel, 4); // Let it stop
603  BURNNOTE("Thread started");
604 
605  // Initialize AutoCirculate...
606  if (!mOutputDevice.AutoCirculateInitForOutput (mConfig.fOutputChannel, mConfig.fOutputFrames, mOutputAudioSystem, acOptions))
607  {BURNFAIL("AutoCirculateInitForOutput failed"); mGlobalQuit = true;}
608 
609  while (!mGlobalQuit)
610  {
611  mOutputDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outputStatus);
612 
613  // Check if there's room for another frame on the card...
614  if (outputStatus.CanAcceptMoreOutputFrames())
615  {
616  // Device has at least one free frame buffer that can be filled.
617  // Wait for the next frame in our ring to become ready to "consume"...
618  NTV2FrameData * pFrameData (mFrameDataRing.StartConsumeNextBuffer());
619  if (!pFrameData)
620  {starves++; continue;} // Producer thread isn't producing frames fast enough
621 
622  // Transfer the timecode-burned frame to the device for playout...
623  outputXferInfo.SetVideoBuffer (pFrameData->VideoBuffer(), pFrameData->VideoBufferSize());
624  if (pFrameData->AudioBuffer())
625  outputXferInfo.SetAudioBuffer(pFrameData->AudioBuffer(), pFrameData->AudioBufferSize());
626  outputXferInfo.SetOutputTimeCode(pFrameData->Timecode(NTV2_TCINDEX_SDI1), NTV2_TCINDEX_SDI1);
627  outputXferInfo.SetOutputTimeCode(pFrameData->Timecode(NTV2_TCINDEX_SDI1_LTC), NTV2_TCINDEX_SDI1_LTC);
628 
629  // Transfer the frame to the device for eventual playout...
630  if (mOutputDevice.AutoCirculateTransfer (mConfig.fOutputChannel, outputXferInfo))
631  goodXfers++;
632  else
633  badXfers++;
634 
635  if (goodXfers == 3) // Start AutoCirculate playout once 3 frames are buffered on the device...
636  mOutputDevice.AutoCirculateStart(mConfig.fOutputChannel);
637 
638  // Signal that the frame has been "consumed"...
639  mFrameDataRing.EndConsumeNextBuffer();
640  continue; // Back to top of while loop
641  } // if CanAcceptMoreOutputFrames
642 
643  // Wait for one or more buffers to become available on the device, which should occur at next VBI...
644  noRoomWaits++;
645  mOutputDevice.WaitForOutputVerticalInterrupt(mConfig.fOutputChannel);
646  } // loop til quit signaled
647 
648  // Stop AutoCirculate...
649  mOutputDevice.AutoCirculateStop(mConfig.fOutputChannel);
650  BURNNOTE("Thread completed: " << DEC(goodXfers) << " xfers, " << DEC(badXfers) << " failed, "
651  << DEC(starves) << " ring starves, " << DEC(noRoomWaits) << " device starves");
652 } // PlayFrames
653 
654 
656 
657 
658 
660 //
661 // This is where the capture thread gets started
662 //
664 {
665  // Create and start the capture thread...
666  mCaptureThread.Attach(CaptureThreadStatic, this);
667  mCaptureThread.SetPriority(AJA_ThreadPriority_High);
668  mCaptureThread.Start();
669 
670 } // StartCaptureThread
671 
672 
673 //
674 // The static capture thread function
675 //
676 void NTV2Burn4KQuadrant::CaptureThreadStatic (AJAThread * pThread, void * pContext) // static
677 { (void) pThread;
678  // Grab the NTV2Burn4K instance pointer from the pContext parameter,
679  // then call its CaptureFrames method...
680  NTV2Burn4KQuadrant * pApp (reinterpret_cast<NTV2Burn4KQuadrant*>(pContext));
681  pApp->CaptureFrames();
682 } // CaptureThreadStatic
683 
684 
685 //
686 // Repeatedly captures frames until told to stop
687 //
689 {
690  AUTOCIRCULATE_TRANSFER inputXferInfo;
691  ULWord goodXfers(0), badXfers(0), ringFulls(0), devWaits(0);
692  BURNNOTE("Thread started");
693 
694  mInputDevice.AutoCirculateStop (NTV2_CHANNEL1);
695  mInputDevice.AutoCirculateStop (NTV2_CHANNEL2);
696  mInputDevice.AutoCirculateStop (NTV2_CHANNEL3);
697  mInputDevice.AutoCirculateStop (NTV2_CHANNEL4);
698  AJATime::Sleep (1000);
699 
700  // Enable analog LTC input (some LTC inputs are shared with reference input)
701  mInputDevice.SetLTCInputEnable (true);
702 
703  // Set all sources to capture embedded LTC (Use 1 for VITC1)
704  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL1, 0);
705  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL2, 0);
706  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL3, 0);
707  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL4, 0);
708 
709  // Initialize AutoCirculate...
710  if (!mInputDevice.AutoCirculateInitForInput (mConfig.fInputChannel, // channel
711  mConfig.fInputFrames, // frame range
712  mInputAudioSystem, // audio system
713  AUTOCIRCULATE_WITH_RP188)) // flags
714  {BURNFAIL("AutoCirculateInitForInput failed"); mGlobalQuit = true;}
715  else
716  // Start AutoCirculate running...
717  mInputDevice.AutoCirculateStart (mConfig.fInputChannel);
718 
719  while (!mGlobalQuit)
720  {
721  AUTOCIRCULATE_STATUS acStatus;
722  mInputDevice.AutoCirculateGetStatus (mConfig.fInputChannel, acStatus);
723 
724  if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
725  {
726  // At this point, there's at least one fully-formed frame available in the device's frame buffer
727  // memory waiting to be transferred to the host. Reserve an NTV2FrameData to fill ("produce"),
728  // and use it in the next frame transferred from the device...
729  NTV2FrameData * pFrameData (mFrameDataRing.StartProduceNextBuffer ());
730  if (!pFrameData)
731  {ringFulls++; continue;} // Ring full -- consumer thread isn't consuming frames fast enough
732 
733  inputXferInfo.SetVideoBuffer(pFrameData->VideoBuffer(), pFrameData->VideoBufferSize());
734  if (pFrameData->AudioBuffer())
735  inputXferInfo.SetAudioBuffer(pFrameData->AudioBuffer(), pFrameData->AudioBufferSize());
736 
737  // Transfer the frame from the device into our host buffers...
738  if (mInputDevice.AutoCirculateTransfer (mConfig.fInputChannel, inputXferInfo)) goodXfers++;
739  else badXfers++;
740 
741  // Remember the amount, in bytes, of captured audio & anc data...
742  pFrameData->fNumAudioBytes = pFrameData->AudioBuffer() ? inputXferInfo.GetCapturedAudioByteCount() : 0;
743 
744  // Get a timecode to use for burn-in...
745  NTV2_RP188 thisFrameTC;
746  inputXferInfo.GetInputTimeCodes (pFrameData->fTimecodes, mConfig.fInputChannel);
747  if (!pFrameData->HasValidTimecode(mConfig.fTimecodeSource))
748  { // Invent a timecode (based on frame count)...
749  const NTV2FrameRate ntv2FrameRate (::GetNTV2FrameRateFromVideoFormat (mVideoFormat));
750  const TimecodeFormat tcFormat (CNTV2DemoCommon::NTV2FrameRate2TimecodeFormat(ntv2FrameRate));
751  const CRP188 inventedTC (inputXferInfo.GetTransferStatus().GetProcessedFrameCount(), 0, 0, 10, tcFormat);
752  inventedTC.GetRP188Reg(thisFrameTC);
753  }
754  CRP188 tc(thisFrameTC);
755  string tcStr;
756  tc.GetRP188Str(tcStr);
757 
758  // While this NTV2FrameData's buffers are locked, "burn" timecode into the raster...
759  mTCBurner.BurnTimeCode (pFrameData->VideoBuffer(), tcStr.c_str(), 80);
760 
761  // Signal that we're done "producing" this frame, making it available for future "consumption"...
762  mFrameDataRing.EndProduceNextBuffer();
763  } // if A/C running and frame(s) are available for transfer
764  else
765  {
766  // Either AutoCirculate is not running, or there were no frames available on the device to transfer.
767  // Rather than waste CPU cycles spinning, waiting until a frame becomes available, it's far more
768  // efficient to wait for the next input vertical interrupt event to get signaled...
769  devWaits++;
770  mInputDevice.WaitForInputVerticalInterrupt (mConfig.fInputChannel);
771  }
772  } // loop til quit signaled
773 
774  // Stop AutoCirculate...
775  mInputDevice.AutoCirculateStop (mConfig.fInputChannel);
776  BURNNOTE("Thread completed: " << DEC(goodXfers) << " xfers, " << DEC(badXfers) << " failed, "
777  << DEC(ringFulls) << " ring full(s), " << DEC(devWaits) << " device waits");
778 
779 } // CaptureFrames
780 
781 
783 
784 
786 {
787  mInputDevice.AutoCirculateGetStatus (mConfig.fInputChannel, inputStatus);
788  mOutputDevice.AutoCirculateGetStatus(mConfig.fOutputChannel, outputStatus);
789 
790 } // GetACStatus
791 
792 
794 {
795  switch (inInputSource)
796  {
797  case NTV2_INPUTSOURCE_SDI1: return kRegRP188InOut1DBB; // reg 29
798  case NTV2_INPUTSOURCE_SDI2: return kRegRP188InOut2DBB; // reg 64
799  case NTV2_INPUTSOURCE_SDI3: return kRegRP188InOut3DBB; // reg 268
800  case NTV2_INPUTSOURCE_SDI4: return kRegRP188InOut4DBB; // reg 273
801  default: return 0;
802  } // switch on input source
803 
804 } // GetRP188RegisterForInput
805 
806 
808 {
809  bool result (false);
811  ULWord regValue (0);
812 
813  //
814  // Bit 16 of the RP188 DBB register will be set if there is timecode embedded in the input signal...
815  //
816  if (regNum && mInputDevice.ReadRegister(regNum, regValue) && regValue & BIT(16))
817  result = true;
818  return result;
819 
820 } // InputSignalHasTimecode
ULWord GetVideoWriteSize(ULWord inPageSize=4096UL) const
NTV2FrameRate GetNTV2FrameRateFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:3630
virtual bool SetTaskMode(const NTV2TaskMode inMode)
Sets the device&#39;s task mode.
virtual void CaptureFrames(void)
Repeatedly captures frames using AutoCirculate (until global quit flag set).
Declares common types used in the ajabase library.
virtual bool SetAudioLoopBack(const NTV2AudioLoopBack inMode, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Enables or disables NTV2AudioLoopBack mode for the given NTV2AudioSystem.
Definition: ntv2audio.cpp:300
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...
virtual void Quit(void)
Gracefully stops me from running.
AJAStatus Add(FrameDataPtr pInFrameData)
Appends a new frame buffer to me, increasing my frame storage capacity by one frame.
virtual bool InputSignalHasTimecode(void)
Returns true if the current input signal has timecode embedded in it; otherwise returns false...
#define BIT(_x_)
Definition: ajatypes.h:578
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 GetCapturedAudioByteCount(void) const
virtual bool IsDeviceReady(const bool inCheckValid=(0))
static uint64_t GetPid()
Definition: process.cpp:35
#define AJA_FAILURE(_status_)
Definition: types.h:373
static void CaptureThreadStatic(AJAThread *pThread, void *pContext)
This is the capture thread&#39;s static callback function that gets called when the capture thread runs...
virtual AJAStatus SetPriority(AJAThreadPriority priority)
Definition: thread.cpp:133
static void PlayThreadStatic(AJAThread *pThread, void *pContext)
This is the playout thread&#39;s static callback function that gets called when the playout thread runs...
FrameDataPtr StartConsumeNextBuffer(void)
The thread that&#39;s responsible for processing incoming frames – the consumer – calls this function t...
Obtain audio samples from the audio that&#39;s embedded in the video HANC.
Definition: ntv2enums.h:2007
if(!(riid==IID_IUnknown) &&!(riid==IID_IClassFactory))
Definition: dllentry.cpp:196
bool CanAcceptMoreOutputFrames(void) const
bool SetOutputTimeCode(const NTV2_RP188 &inTimecode, const NTV2TCIndex inTCIndex=NTV2_TCINDEX_SDI1)
Intended for playout, sets one element of my acOutputTimeCodes member.
virtual void RouteOutputSignal(void)
Sets up board routing for playout.
virtual void StartPlayThread(void)
Starts my playout thread.
Definition: json.hpp:5362
virtual bool SetAudioRate(const NTV2AudioRate inRate, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the NTV2AudioRate for the given Audio System.
Definition: ntv2audio.cpp:205
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...
virtual void RouteInputSignal(void)
Sets up board routing for capture.
#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.
std::string fDeviceSpec2
Second AJA device to use (Burn4KQuadrant or BurnBoardToBoard only)
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:148
virtual AJAStatus SetupOutputVideo(void)
Sets up everything I need for playing 4K video.
virtual bool EnableOutputInterrupt(const NTV2Channel channel=NTV2_CHANNEL1)
Allows the CNTV2Card instance to wait for and respond to output vertical blanking interrupts originat...
virtual bool SetMultiFormatMode(const bool inEnable)
Enables or disables multi-format (per channel) device operation. If enabled, each device channel can ...
This identifies the 5th Audio System.
Definition: ntv2enums.h:3901
Identifies the 2nd SDI video input.
Definition: ntv2enums.h:1270
virtual bool ClearRouting(void)
Removes all existing signal path connections between any and all widgets on the AJA device...
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
NTV2ACFrameRange fOutputFrames
Playout frame count or range.
This struct replaces the old RP188_STRUCT.
#define NTV2_AUDIOSIZE_MAX
virtual bool IsRemote(void) const
ULWord numPixels
Width – total number of pixels per line.
virtual bool Active()
Definition: thread.cpp:116
virtual bool GetTaskMode(NTV2TaskMode &outMode)
Retrieves the device&#39;s current task mode.
virtual bool SetAudioSystemInputSource(const NTV2AudioSystem inAudioSystem, const NTV2AudioSource inAudioSource, const NTV2EmbeddedAudioInput inEmbeddedInput)
Sets the audio source for the given NTV2AudioSystem on the device.
Definition: ntv2audio.cpp:485
NTV2PixelFormat fPixelFormat
The pixel format to use.
static AJA_PixelFormat GetAJAPixelFormat(const NTV2PixelFormat inFormat)
NTV2Channel fOutputChannel
The output channel to use.
NTV2FrameRate
Identifies a particular video frame rate.
Definition: ntv2enums.h:412
virtual bool SetLTCInputEnable(const bool inEnable)
Enables or disables the ability for the device to read analog LTC on the reference input connector...
Header file for the NTV2Burn4KQuadrant demonstration class.
Playout (output) mode, which reads from device SDRAM.
Definition: ntv2enums.h:1241
virtual std::string GetDescription(void) const
Definition: ntv2card.cpp:139
virtual AJAStatus SetupInputAudio(void)
Sets up everything I need for capturing audio.
virtual bool SetMode(const NTV2Channel inChannel, const NTV2Mode inNewValue, const bool inIsRetail=(!(0)))
Determines if a given FrameStore on the AJA device will be used to capture or playout video...
static TimecodeFormat NTV2FrameRate2TimecodeFormat(const NTV2FrameRate inFrameRate)
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...
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.
const AUTOCIRCULATE_TRANSFER_STATUS & GetTransferStatus(void) const
Returns a constant reference to my AUTOCIRCULATE_TRANSFER_STATUS.
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 SetRP188SourceFilter(const NTV2Channel inSDIInput, const UWord inFilterValue)
Sets the RP188 DBB filter for the given SDI input.
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 ...
ULWord GetProcessedFrameCount(void) const
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...
Identifies the 3rd SDI video input.
Definition: ntv2enums.h:1271
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...
static size_t DefaultPageSize(void)
virtual bool SetSDIOutputAudioSystem(const NTV2Channel inSDIOutputConnector, const NTV2AudioSystem inAudioSystem)
Sets the device&#39;s NTV2AudioSystem that will provide audio for the given SDI output&#39;s audio embedder...
virtual AJAStatus Run(void)
Runs me.
Embeds silence (zeroes) into the data stream.
Definition: ntv2enums.h:2030
Configures an NTV2Burn or NTV2FieldBurn instance.
Specifies channel or FrameStore 8 (or the 8th item).
Definition: ntv2enums.h:1366
AJA_EXPORT bool RenderTimeCodeFont(AJA_PixelFormat pixelFormat, uint32_t numPixels, uint32_t numLines)
Specifies channel or FrameStore 2 (or the 2nd item).
Definition: ntv2enums.h:1360
virtual NTV2DeviceID GetDeviceID(void)
Specifies the SDI In 1 connector.
Definition: ntv2enums.h:1457
Declares the CNTV2DeviceScanner class.
Identifies the 4th SDI video input.
Definition: ntv2enums.h:1272
static ULWord GetRP188RegisterForInput(const NTV2InputSource inInputSource)
Returns the RP188 DBB register number to use for the given NTV2InputSource.
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...
std::string fDeviceSpec
The AJA device to use.
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 Connect(const NTV2InputCrosspointID inInputXpt, const NTV2OutputCrosspointID inOutputXpt, const bool inValidate=(0))
Connects the given widget signal input (sink) to the given widget signal output (source).
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...
NTV2InputSource
Identifies a specific video input source.
Definition: ntv2enums.h:1262
Instances of me can capture 4K/UHD video from one 4-channel AJA device, burn timecode into one quadra...
bool IsRGBFormat(const NTV2FrameBufferFormat format)
Definition: ntv2utils.cpp:5410
This object specifies the information that will be transferred to or from the AJA device in the CNTV2...
virtual bool SetAudioBufferSize(const NTV2AudioBufferSize inValue, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Changes the size of the audio buffer that is used for a given Audio System in the AJA device...
Definition: ntv2audio.cpp:249
#define BURNNOTE(_expr_)
#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 ...
bool WithAudio(void) const
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))
ULWord numLines
Height – total number of lines.
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 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.
NTV2ACFrameRange fInputFrames
Ingest frame count or range.
bool fSuppressVideo
If true, suppress video; otherwise include video.
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)
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
virtual bool AutoCirculateInitForOutput(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 playout, designating a contiguous block of frame buffers on the...
#define xHEX0N(__x__, __n__)
virtual bool SetEnableVANCData(const bool inVANCenabled, const bool inTallerVANC, const NTV2Standard inStandard, const NTV2FrameGeometry inGeometry, const NTV2Channel inChannel=NTV2_CHANNEL1)
virtual AJAStatus SetupOutputAudio(void)
Sets up everything I need for playing audio.
TimecodeFormat
Definition: ntv2rp188.h:22
Declares the NTV2FormatDescriptor class.
AJA_EXPORT bool BurnTimeCode(void *pBaseVideoAddress, const std::string &inTimeCodeStr, const uint32_t inYPercent)
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 AJAStatus SetupHostBuffers(void)
Sets up my circular buffers.
bool HasAvailableInputFrame(void) const
Specifies channel or FrameStore 4 (or the 4th item).
Definition: ntv2enums.h:1362
NTV2Channel fInputChannel
The input channel to use.
Specifies channel or FrameStore 5 (or the 5th item).
Definition: ntv2enums.h:1363
virtual AJAStatus SetupInputVideo(void)
Sets up everything I need for capturing 4K video.
NTV2TCIndex fTimecodeSource
Timecode source to use.
bool GetRP188Reg(RP188_STRUCT &outRP188) const
Definition: ntv2rp188.cpp:1241
bool IsRunning(void) const
virtual void PlayFrames(void)
Repeatedly plays out frames using AutoCirculate (until global quit flag set).
SDI 1 embedded ATC LTC.
Definition: ntv2enums.h:3958
static size_t SetDefaultPageSize(void)
#define BURNFAIL(_expr_)
NTV2Burn4KQuadrant(const BurnConfig &inConfig)
Constructs me using the given configuration settings.
Specifies channel or FrameStore 6 (or the 6th item).
Definition: ntv2enums.h:1364
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 BURNINFO(_expr_)
#define AUTOCIRCULATE_WITH_RP188
Use this to AutoCirculate with RP188.
Specifies channel or FrameStore 7 (or the 7th item).
Definition: ntv2enums.h:1365
bool GetRP188Str(std::string &sRP188) const
Definition: ntv2rp188.cpp:918
bool SetAudioBuffer(ULWord *pInAudioBuffer, const ULWord inAudioByteCount)
Sets my audio buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Identifies the 1st SDI video input.
Definition: ntv2enums.h:1269
virtual bool SetNumberAudioChannels(const ULWord inNumChannels, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the number of audio channels to be concurrently captured or played for a given Audio System on t...
Definition: ntv2audio.cpp:146
virtual void StartCaptureThread(void)
Starts my capture thread.
SDI 1 embedded VITC.
Definition: ntv2enums.h:3954
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 ...
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
virtual void GetACStatus(AUTOCIRCULATE_STATUS &outInputStatus, AUTOCIRCULATE_STATUS &outOutputStatus)
Provides status information about my input (capture) and output (playout) processes.
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:223
virtual bool EnableChannel(const NTV2Channel inChannel)
Enables the given FrameStore.