AJA NTV2 SDK  18.1.0.2439
NTV2 SDK 18.1.0.2439
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  { if (aja::lower(mConfig.fDeviceSpec) != "list" && mConfig.fDeviceSpec != "?")
79  cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not found" << endl;
80  return AJA_STATUS_OPEN;
81  }
82  if (!mInputDevice.features().CanDo4KVideo())
83  {cerr << "## ERROR: Input device '" << mInputDevice.GetDescription() << "' cannot do 4K/UHD video" << endl; return AJA_STATUS_UNSUPPORTED;}
84  if (!mInputDevice.IsDeviceReady (false))
85  {cerr << "## ERROR: Input device '" << mInputDevice.GetDescription() << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
86 
87  // Output device:
89  {cerr << "## ERROR: Output device '" << mConfig.fDeviceSpec2 << "' not found" << endl; return AJA_STATUS_OPEN;}
90  if (!mOutputDevice.features().CanDo4KVideo())
91  {cerr << "## ERROR: Output device '" << mOutputDevice.GetDescription() << "' cannot do 4K/UHD video" << endl; return AJA_STATUS_UNSUPPORTED;}
92  if (!mOutputDevice.IsDeviceReady(false))
93  {cerr << "## ERROR: Output device '" << mOutputDevice.GetDescription() << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
94 
95  if (mSingleDevice)
96  {
97  if (mInputDevice.features().GetNumFrameStores() < 8)
98  {cerr << "## ERROR: Single device '" << mOutputDevice.GetDescription() << "' requires 8 video channels" << endl; return AJA_STATUS_UNSUPPORTED;}
99  mOutputAudioSystem = NTV2_AUDIOSYSTEM_5;
100  mConfig.fOutputChannel = NTV2_CHANNEL5;
101  }
102 
103  if (!mInputDevice.AcquireStreamForApplication (kDemoAppSignature, static_cast<int32_t>(AJAProcess::GetPid())))
104  {cerr << "## ERROR: Input device '" << mInputDevice.GetDescription() << "' is in use by another application" << endl; return AJA_STATUS_BUSY;}
105  mInputDevice.GetTaskMode(mInputSavedTaskMode); // Save the current state before changing it
106  mInputDevice.SetTaskMode(NTV2_OEM_TASKS); // Since this is an OEM demo, use the OEM service level
107 
108  if (!mSingleDevice)
109  {
110  if (!mOutputDevice.AcquireStreamForApplication (kDemoAppSignature, static_cast <int32_t>(AJAProcess::GetPid())))
111  {cerr << "## ERROR: Output device '" << mOutputDevice.GetDescription() << "' is in use by another application" << endl; return AJA_STATUS_BUSY;}
112 
113  mOutputDevice.GetTaskMode(mOutputSavedTaskMode); // Save the current state before changing it
114  mOutputDevice.SetTaskMode(NTV2_OEM_TASKS); // Since this is an OEM demo, use the OEM service level
115  }
116 
117  if (mInputDevice.features().CanDoMultiFormat())
118  mInputDevice.SetMultiFormatMode (false);
119  if (mOutputDevice.features().CanDoMultiFormat())
120  mOutputDevice.SetMultiFormatMode (false);
121 
122  // Sometimes other applications disable some or all of the frame buffers, so turn them all on here...
123  switch (mInputDevice.features().GetNumFrameStores())
124  {
125  case 8: mInputDevice.EnableChannel (NTV2_CHANNEL8);
126  mInputDevice.EnableChannel (NTV2_CHANNEL7);
127  mInputDevice.EnableChannel (NTV2_CHANNEL6);
128  mInputDevice.EnableChannel (NTV2_CHANNEL5);
129  /* FALLTHRU */
130  case 4: mInputDevice.EnableChannel (NTV2_CHANNEL4);
131  mInputDevice.EnableChannel (NTV2_CHANNEL3);
132  /* FALLTHRU */
133  case 2: mInputDevice.EnableChannel (NTV2_CHANNEL2);
134  /* FALLTHRU */
135  case 1: mInputDevice.EnableChannel (NTV2_CHANNEL1);
136  break;
137  }
138 
139  if (!mSingleDevice) // Don't do this twice if Input & Output devices are same device!
140  switch (mOutputDevice.features().GetNumFrameStores())
141  {
142  case 8: mOutputDevice.EnableChannel (NTV2_CHANNEL8);
143  mOutputDevice.EnableChannel (NTV2_CHANNEL7);
144  mOutputDevice.EnableChannel (NTV2_CHANNEL6);
145  mOutputDevice.EnableChannel (NTV2_CHANNEL5);
146  /* FALLTHRU */
147  case 4: mOutputDevice.EnableChannel (NTV2_CHANNEL4);
148  mOutputDevice.EnableChannel (NTV2_CHANNEL3);
149  /* FALLTHRU */
150  case 2: mOutputDevice.EnableChannel (NTV2_CHANNEL2);
151  /* FALLTHRU */
152  case 1: mOutputDevice.EnableChannel (NTV2_CHANNEL1);
153  break;
154  }
155 
156  // Set up the video and audio...
157  status = SetupInputVideo();
158  if (AJA_FAILURE (status))
159  return status;
160 
161  status = SetupOutputVideo();
162  if (AJA_FAILURE (status))
163  return status;
164 
165  status = SetupInputAudio();
166  if (AJA_FAILURE (status))
167  return status;
168 
169  status = SetupOutputAudio();
170  if (AJA_FAILURE (status))
171  return status;
172 
173  // Set up the circular buffers...
174  status = SetupHostBuffers();
175  if (AJA_FAILURE(status))
176  return status;
177 
178  // Set up the signal routing...
181 
182  // Lastly, prepare my AJATimeCodeBurn instance...
183  mTCBurner.RenderTimeCodeFont (CNTV2DemoCommon::GetAJAPixelFormat (mConfig.fPixelFormat), mFormatDesc.numPixels, mFormatDesc.numLines);
184  // Ready to go...
185  #if defined(_DEBUG)
186  cerr << mConfig
187  << "Input Device: " << mInputDevice.GetDescription() << endl
188  << "Output Device: " << mOutputDevice.GetDescription() << endl
189  << endl;
190  #endif // not _DEBUG
191  BURNINFO("Configuration: " << mConfig);
192  return AJA_STATUS_SUCCESS;
193 
194 } // Init
195 
196 
198 {
199  // Set the video format to match the incoming video format.
200  // Does the device support the desired input source?
201  // Since this is a 4k Quadrant example, look at one of the inputs and deduce the 4k geometry from the quadrant geometry...
202 
203  // Determine the input video signal format, and set the device's reference source to that input.
204  // If you want to look at one of the quadrants, say on the HDMI output, then lock to one of the
205  // inputs (this assumes all quadrants are timed)...
206 
207  // First, enable all of the necessary interrupts, and subscribe to the interrupts for the channel to be used...
208  mInputDevice.EnableInputInterrupt (mConfig.fInputChannel);
209  mInputDevice.SubscribeInputVerticalEvent (mConfig.fInputChannel);
210 
211  // Turn multiformat off for this demo -- all multiformat devices will follow channel 1 configuration...
212 
213  // For devices with bi-directional SDI connectors, their transmitter must be turned off before we can read a format...
214  if (mInputDevice.features().HasBiDirectionalSDI())
215  {
216  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL1, false);
217  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL2, false);
218  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL3, false);
219  mInputDevice.SetSDITransmitEnable (NTV2_CHANNEL4, false);
220  AJATime::Sleep(1000);
221  }
222 
223  mVideoFormat = NTV2_FORMAT_UNKNOWN;
224  mVideoFormat = mInputDevice.GetInputVideoFormat (NTV2_INPUTSOURCE_SDI1);
225  mInputDevice.SetReference (NTV2_REFERENCE_INPUT1);
226 
227  if (mVideoFormat == NTV2_FORMAT_UNKNOWN)
228  return AJA_STATUS_NOINPUT; // Sorry, can't handle this format
229 
230  // Set the device format to the input format detected...
231  CNTV2DemoCommon::Get4KInputFormat (mVideoFormat);
232  mInputDevice.SetVideoFormat (mVideoFormat);
233 
234  // Set the frame buffer pixel format for all the channels on the device
235  // (assuming the device supports that pixel format -- otherwise default to 8-bit YCbCr)...
236  if (!mInputDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
238 
239  // ...and set all buffers pixel format...
240  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL1, mConfig.fPixelFormat);
241  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL2, mConfig.fPixelFormat);
242  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL3, mConfig.fPixelFormat);
243  mInputDevice.SetFrameBufferFormat (NTV2_CHANNEL4, mConfig.fPixelFormat);
244 
245  mInputDevice.SetEnableVANCData (false, false);
246 
247  // Now that the video is set up, get information about the current frame geometry...
248  mFormatDesc = NTV2FormatDescriptor (mVideoFormat, mConfig.fPixelFormat);
249  return AJA_STATUS_SUCCESS;
250 
251 } // SetupInputVideo
252 
253 
255 {
256  // We turned off the transmit for the capture device, so now turn them on for the playback device...
257  if (mOutputDevice.features().HasBiDirectionalSDI())
258  {
259  // Devices having bidirectional SDI must be set to "transmit"...
260  if (mSingleDevice)
261  {
262  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL5, true);
263  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL6, true);
264  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL7, true);
265  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL8, true);
266  }
267  else
268  {
269  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL1, true);
270  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL2, true);
271  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL3, true);
272  mOutputDevice.SetSDITransmitEnable (NTV2_CHANNEL4, true);
273  }
274  }
275 
276  // Set the video format to match the incoming video format...
277  mOutputDevice.SetVideoFormat (mVideoFormat);
278  mOutputDevice.SetReference (NTV2_REFERENCE_FREERUN);
279 
280  if (mVideoFormat == NTV2_FORMAT_UNKNOWN)
281  return AJA_STATUS_NOINPUT; // Sorry, can't handle this format
282 
283  // Set the frame buffer pixel format for all the channels on the device
284  // (assuming the device supports that pixel format -- otherwise default to 8-bit YCbCr)...
285  if (!mOutputDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
287 
288  // ...and set the pixel format for all frame stores...
289  if (mSingleDevice)
290  {
291  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL5, mConfig.fPixelFormat);
292  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL6, mConfig.fPixelFormat);
293  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL7, mConfig.fPixelFormat);
294  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL8, mConfig.fPixelFormat);
295  }
296  else
297  {
298  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL1, mConfig.fPixelFormat);
299  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL2, mConfig.fPixelFormat);
300  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL3, mConfig.fPixelFormat);
301  mOutputDevice.SetFrameBufferFormat (NTV2_CHANNEL4, mConfig.fPixelFormat);
302  }
303 
304  // Set all frame buffers to playback
305  if (mSingleDevice)
306  {
307  mOutputDevice.SetMode (NTV2_CHANNEL5, NTV2_MODE_DISPLAY);
308  mOutputDevice.SetMode (NTV2_CHANNEL6, NTV2_MODE_DISPLAY);
309  mOutputDevice.SetMode (NTV2_CHANNEL7, NTV2_MODE_DISPLAY);
310  mOutputDevice.SetMode (NTV2_CHANNEL8, NTV2_MODE_DISPLAY);
311  }
312  else
313  {
314  mOutputDevice.SetMode (NTV2_CHANNEL1, NTV2_MODE_DISPLAY);
315  mOutputDevice.SetMode (NTV2_CHANNEL2, NTV2_MODE_DISPLAY);
316  mOutputDevice.SetMode (NTV2_CHANNEL3, NTV2_MODE_DISPLAY);
317  mOutputDevice.SetMode (NTV2_CHANNEL4, NTV2_MODE_DISPLAY);
318  }
319 
320  // Subscribe the output interrupt (it's enabled by default).
321  // If using a single-device, then subscribe the output channel to
322  // channel 5's interrupts, otherwise channel 1's...
323  if (mSingleDevice)
325  else
327 
328  mOutputDevice.SetEnableVANCData (false, false);
329 
330  return AJA_STATUS_SUCCESS;
331 
332 } // SetupOutputVideo
333 
334 
336 {
337  // We will be capturing and playing back with audio system 1.
338  // First, determine how many channels the device is capable of capturing or playing out...
339  const uint16_t numberOfAudioChannels (mInputDevice.features().GetMaxAudioChannels());
340 
341  // Have the input audio system grab audio from the designated input source...
343 
344  mInputDevice.SetNumberAudioChannels (numberOfAudioChannels, mInputAudioSystem);
345  mInputDevice.SetAudioRate (NTV2_AUDIO_48K, mInputAudioSystem);
346 
347  // How big should the on-device audio buffer be? 1MB? 2MB? 4MB? 8MB?
348  // For this demo, 4MB will work best across all platforms (Windows, Mac & Linux)...
349  mInputDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mInputAudioSystem);
350 
351  // Loopback mode is used to play whatever audio appears in the input signal when
352  // it's connected directly to an output (i.e., "end-to-end" mode). If loopback is
353  // left enabled, the video will lag the audio as video frames get briefly delayed
354  // in our ring buffer. Audio, therefore, needs to come out of the (buffered) frame
355  // data being played, so loopback must be turned off...
356  mInputDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, mInputAudioSystem);
357 
358  return AJA_STATUS_SUCCESS;
359 
360 } // SetupInputAudio
361 
362 
364 {
365  // Audio system 1 will be used to capture and playback audio.
366  // First, determine how many channels the device is capable of capturing or playing out...
367  const uint16_t numberOfAudioChannels (mOutputDevice.features().GetMaxAudioChannels());
368 
369  mOutputDevice.SetNumberAudioChannels (numberOfAudioChannels, mOutputAudioSystem);
370  mOutputDevice.SetAudioRate (NTV2_AUDIO_48K, mOutputAudioSystem);
371 
372  // AJA recommends using a 4MB on-device audio buffer...
373  mOutputDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mOutputAudioSystem);
374 
375  // Finally, set up the output audio embedders...
376  if (mSingleDevice)
377  {
378  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL5, mOutputAudioSystem);
379  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL6, mOutputAudioSystem);
380  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL7, mOutputAudioSystem);
381  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL8, mOutputAudioSystem);
382  }
383  else
384  {
385  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL1, mOutputAudioSystem);
386  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL2, mOutputAudioSystem);
387  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL3, mOutputAudioSystem);
388  mOutputDevice.SetSDIOutputAudioSystem (NTV2_CHANNEL4, mOutputAudioSystem);
389  }
390 
391  //
392  // Loopback mode is used to play whatever audio appears in the input signal when
393  // it's connected directly to an output (i.e., "end-to-end" mode). If loopback is
394  // left enabled, the video will lag the audio as video frames get briefly delayed
395  // in our ring buffer. Audio, therefore, needs to come out of the (buffered) frame
396  // data being played, so loopback must be turned off...
397  //
398  mOutputDevice.SetAudioLoopBack(NTV2_AUDIO_LOOPBACK_OFF, mOutputAudioSystem);
399 
400  return AJA_STATUS_SUCCESS;
401 
402 } // SetupAudio
403 
404 
406 {
407  CNTV2DemoCommon::SetDefaultPageSize(); // Set host-specific page size
408 
409  // Let my circular buffer know when it's time to quit...
410  mFrameDataRing.SetAbortFlag (&mGlobalQuit);
411 
412  // Determine video buffer size...
413  const ULWord vidBuffSizeBytes (mFormatDesc.GetVideoWriteSize(ULWord(NTV2Buffer::DefaultPageSize())));
414 
415  // Allocate and add each in-host NTV2FrameData to my mFrameDataRing...
416  mHostBuffers.reserve(CIRCULAR_BUFFER_SIZE);
417  while (mHostBuffers.size() < CIRCULAR_BUFFER_SIZE)
418  {
419  mHostBuffers.push_back(NTV2FrameData()); // Make a new NTV2FrameData...
420  NTV2FrameData & frameData (mHostBuffers.back()); // ...and get a reference to it
421 
422  // Allocate a page-aligned video buffer (if handling video)...
423  if (!mConfig.fSuppressVideo)
424  if (!frameData.fVideoBuffer.Allocate (vidBuffSizeBytes, /*pageAligned*/true))
425  {
426  BURNFAIL("Failed to allocate " << xHEX0N(vidBuffSizeBytes,8) << "-byte video buffer");
427  return AJA_STATUS_MEMORY;
428  }
429 
430  // Allocate a page-aligned audio buffer (if handling audio)...
431  if (mConfig.WithAudio())
432  if (!frameData.fAudioBuffer.Allocate (NTV2_AUDIOSIZE_MAX, /*pageAligned*/true))
433  {
434  BURNFAIL("Failed to allocate " << xHEX0N(NTV2_AUDIOSIZE_MAX,8) << "-byte audio buffer");
435  return AJA_STATUS_MEMORY;
436  }
437  if (frameData.AudioBuffer())
438  frameData.fAudioBuffer.Fill(ULWord(0));
439 
440  // Add this NTV2FrameData to the ring...
441  mFrameDataRing.Add(&frameData);
442  } // for each NTV2FrameData
443 
444  return AJA_STATUS_SUCCESS;
445 
446 } // SetupHostBuffers
447 
448 
450 {
451  // Since this is only a 4k example, we will route all inputs to framebuffers
452  // and color space convert when necessary...
453  mInputDevice.ClearRouting ();
454  if(IsRGBFormat(mConfig.fPixelFormat))
455  {
460 
465  }
466  else
467  {
472  }
473 
474 } // RouteInputSignal
475 
476 
478 {
479  // Since this is only a 4k example, route all framebuffers to SDI outputs, and colorspace convert when necessary...
480  if (!mSingleDevice)
481  mOutputDevice.ClearRouting ();
482  if (!mSingleDevice)
483  {
484  if (::IsRGBFormat (mConfig.fPixelFormat))
485  {
490 
495  }
496  else
497  {
502  }
503  }
504  else
505  {
506  if (::IsRGBFormat (mConfig.fPixelFormat))
507  {
512 
517  }
518  else
519  {
524  }
525  }
526 
527 } // RouteOutputSignal
528 
529 
531 {
532  // Start the playout and capture threads...
533  StartPlayThread ();
535 
536  return AJA_STATUS_SUCCESS;
537 
538 } // Run
539 
540 
541 
543 
544 // This is where we will start the play thread
546 {
547  // Create and start the playout thread...
548  mPlayThread.Attach(PlayThreadStatic, this);
550  mPlayThread.Start();
551 
552 } // StartPlayThread
553 
554 
555 // The playout thread function
556 void NTV2Burn4KQuadrant::PlayThreadStatic (AJAThread * pThread, void * pContext) // static
557 { (void) pThread;
558  // Grab the NTV2Burn4K instance pointer from the pContext parameter,
559  // then call its PlayFrames method...
560  NTV2Burn4KQuadrant * pApp(reinterpret_cast<NTV2Burn4KQuadrant*>(pContext));
561  pApp->PlayFrames();
562 
563 } // PlayThreadStatic
564 
565 
567 {
568  const ULWord acOptions (AUTOCIRCULATE_WITH_RP188);
569  ULWord goodXfers(0), badXfers(0), starves(0), noRoomWaits(0), startFrm(3);
570  AUTOCIRCULATE_TRANSFER outputXferInfo;
571  AUTOCIRCULATE_STATUS outputStatus;
572 
573  if (mSingleDevice)
574  {
575  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL5);
576  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL6);
577  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL7);
578  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL8);
579  }
580  else
581  {
582  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL1);
583  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL2);
584  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL3);
585  mOutputDevice.AutoCirculateStop (NTV2_CHANNEL4);
586  }
587  mOutputDevice.WaitForOutputVerticalInterrupt(mConfig.fOutputChannel, 4); // Let it stop
588  BURNNOTE("Thread started");
589 
590  // Initialize AutoCirculate...
591  if (!mOutputDevice.AutoCirculateInitForOutput (mConfig.fOutputChannel, mConfig.fOutputFrames, mOutputAudioSystem, acOptions))
592  {BURNFAIL("AutoCirculateInitForOutput failed"); mGlobalQuit = true;}
593  else
594  { mOutputDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outputStatus);
595  startFrm = outputStatus.GetFrameCount() - 1;
596  if (startFrm > 3)
597  startFrm = 3;
598  }
599 
600  while (!mGlobalQuit)
601  {
602  mOutputDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outputStatus);
603 
604  // Check if there's room for another frame on the card...
605  if (outputStatus.CanAcceptMoreOutputFrames())
606  {
607  // Device has at least one free frame buffer that can be filled.
608  // Wait for the next frame in our ring to become ready to "consume"...
609  NTV2FrameData * pFrameData (mFrameDataRing.StartConsumeNextBuffer());
610  if (!pFrameData)
611  {starves++; continue;} // Producer thread isn't producing frames fast enough
612 
613  // Transfer the timecode-burned frame to the device for playout...
614  outputXferInfo.SetVideoBuffer (pFrameData->VideoBuffer(), pFrameData->VideoBufferSize());
615  if (pFrameData->AudioBuffer())
616  outputXferInfo.SetAudioBuffer(pFrameData->AudioBuffer(), pFrameData->AudioBufferSize());
617  outputXferInfo.SetOutputTimeCode(pFrameData->Timecode(NTV2_TCINDEX_SDI1), NTV2_TCINDEX_SDI1);
618  outputXferInfo.SetOutputTimeCode(pFrameData->Timecode(NTV2_TCINDEX_SDI1_LTC), NTV2_TCINDEX_SDI1_LTC);
619 
620  // Transfer the frame to the device for eventual playout...
621  if (mOutputDevice.AutoCirculateTransfer (mConfig.fOutputChannel, outputXferInfo))
622  { if (++goodXfers == startFrm)
623  mOutputDevice.AutoCirculateStart(mConfig.fOutputChannel);
624  }
625  else
626  badXfers++;
627 
628  // Signal that the frame has been "consumed"...
629  mFrameDataRing.EndConsumeNextBuffer();
630  continue; // Back to top of while loop
631  } // if CanAcceptMoreOutputFrames
632 
633  // Wait for one or more buffers to become available on the device, which should occur at next VBI...
634  noRoomWaits++;
635  mOutputDevice.WaitForOutputVerticalInterrupt(mConfig.fOutputChannel);
636  } // loop til quit signaled
637 
638  // Stop AutoCirculate...
639  mOutputDevice.AutoCirculateStop(mConfig.fOutputChannel);
640  BURNNOTE("Thread completed: " << DEC(goodXfers) << " xfers, " << DEC(badXfers) << " failed, "
641  << DEC(starves) << " ring starves, " << DEC(noRoomWaits) << " device starves");
642 } // PlayFrames
643 
644 
646 
647 
648 
650 //
651 // This is where the capture thread gets started
652 //
654 {
655  // Create and start the capture thread...
656  mCaptureThread.Attach(CaptureThreadStatic, this);
657  mCaptureThread.SetPriority(AJA_ThreadPriority_High);
658  mCaptureThread.Start();
659 
660 } // StartCaptureThread
661 
662 
663 //
664 // The static capture thread function
665 //
666 void NTV2Burn4KQuadrant::CaptureThreadStatic (AJAThread * pThread, void * pContext) // static
667 { (void) pThread;
668  // Grab the NTV2Burn4K instance pointer from the pContext parameter,
669  // then call its CaptureFrames method...
670  NTV2Burn4KQuadrant * pApp (reinterpret_cast<NTV2Burn4KQuadrant*>(pContext));
671  pApp->CaptureFrames();
672 } // CaptureThreadStatic
673 
674 
675 //
676 // Repeatedly captures frames until told to stop
677 //
679 {
680  AUTOCIRCULATE_TRANSFER inputXferInfo;
681  ULWord goodXfers(0), badXfers(0), ringFulls(0), devWaits(0);
682  BURNNOTE("Thread started");
683 
684  mInputDevice.AutoCirculateStop (NTV2_CHANNEL1);
685  mInputDevice.AutoCirculateStop (NTV2_CHANNEL2);
686  mInputDevice.AutoCirculateStop (NTV2_CHANNEL3);
687  mInputDevice.AutoCirculateStop (NTV2_CHANNEL4);
688  AJATime::Sleep (1000);
689 
690  // Enable analog LTC input (some LTC inputs are shared with reference input)
691  mInputDevice.SetLTCInputEnable (true);
692 
693  // Set all sources to capture embedded LTC (Use 1 for VITC1)
694  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL1, 0);
695  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL2, 0);
696  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL3, 0);
697  mInputDevice.SetRP188SourceFilter (NTV2_CHANNEL4, 0);
698 
699  // Initialize AutoCirculate...
700  if (!mInputDevice.AutoCirculateInitForInput (mConfig.fInputChannel, // channel
701  mConfig.fInputFrames, // frame range
702  mInputAudioSystem, // audio system
703  AUTOCIRCULATE_WITH_RP188)) // flags
704  {BURNFAIL("AutoCirculateInitForInput failed"); mGlobalQuit = true;}
705  else
706  // Start AutoCirculate running...
707  mInputDevice.AutoCirculateStart (mConfig.fInputChannel);
708 
709  while (!mGlobalQuit)
710  {
711  AUTOCIRCULATE_STATUS acStatus;
712  mInputDevice.AutoCirculateGetStatus (mConfig.fInputChannel, acStatus);
713 
714  if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
715  {
716  // At this point, there's at least one fully-formed frame available in the device's frame buffer
717  // memory waiting to be transferred to the host. Reserve an NTV2FrameData to fill ("produce"),
718  // and use it in the next frame transferred from the device...
719  NTV2FrameData * pFrameData (mFrameDataRing.StartProduceNextBuffer ());
720  if (!pFrameData)
721  {ringFulls++; continue;} // Ring full -- consumer thread isn't consuming frames fast enough
722 
723  inputXferInfo.SetVideoBuffer(pFrameData->VideoBuffer(), pFrameData->VideoBufferSize());
724  if (pFrameData->AudioBuffer())
725  inputXferInfo.SetAudioBuffer(pFrameData->AudioBuffer(), pFrameData->AudioBufferSize());
726 
727  // Transfer the frame from the device into our host buffers...
728  if (mInputDevice.AutoCirculateTransfer (mConfig.fInputChannel, inputXferInfo)) goodXfers++;
729  else badXfers++;
730 
731  // Remember the amount, in bytes, of captured audio & anc data...
732  pFrameData->fNumAudioBytes = pFrameData->AudioBuffer() ? inputXferInfo.GetCapturedAudioByteCount() : 0;
733 
734  // Get a timecode to use for burn-in...
735  NTV2_RP188 thisFrameTC;
736  inputXferInfo.GetInputTimeCodes (pFrameData->fTimecodes, mConfig.fInputChannel);
737  if (!pFrameData->HasValidTimecode(mConfig.fTimecodeSource))
738  { // Invent a timecode (based on frame count)...
739  const NTV2FrameRate ntv2FrameRate (::GetNTV2FrameRateFromVideoFormat (mVideoFormat));
740  const TimecodeFormat tcFormat (CNTV2DemoCommon::NTV2FrameRate2TimecodeFormat(ntv2FrameRate));
741  const CRP188 inventedTC (inputXferInfo.GetTransferStatus().GetProcessedFrameCount(), 0, 0, 10, tcFormat);
742  inventedTC.GetRP188Reg(thisFrameTC);
743  }
744  CRP188 tc(thisFrameTC);
745  string tcStr;
746  tc.GetRP188Str(tcStr);
747 
748  // While this NTV2FrameData's buffers are locked, "burn" timecode into the raster...
749  mTCBurner.BurnTimeCode (pFrameData->VideoBuffer(), tcStr.c_str(), 80);
750 
751  // Signal that we're done "producing" this frame, making it available for future "consumption"...
752  mFrameDataRing.EndProduceNextBuffer();
753  } // if A/C running and frame(s) are available for transfer
754  else
755  {
756  // Either AutoCirculate is not running, or there were no frames available on the device to transfer.
757  // Rather than waste CPU cycles spinning, waiting until a frame becomes available, it's far more
758  // efficient to wait for the next input vertical interrupt event to get signaled...
759  devWaits++;
760  mInputDevice.WaitForInputVerticalInterrupt (mConfig.fInputChannel);
761  }
762  } // loop til quit signaled
763 
764  // Stop AutoCirculate...
765  mInputDevice.AutoCirculateStop (mConfig.fInputChannel);
766  BURNNOTE("Thread completed: " << DEC(goodXfers) << " xfers, " << DEC(badXfers) << " failed, "
767  << DEC(ringFulls) << " ring full(s), " << DEC(devWaits) << " device waits");
768 
769 } // CaptureFrames
770 
771 
773 
774 
776 {
777  mInputDevice.AutoCirculateGetStatus (mConfig.fInputChannel, inputStatus);
778  mOutputDevice.AutoCirculateGetStatus(mConfig.fOutputChannel, outputStatus);
779 
780 } // GetACStatus
781 
782 
784 {
785  switch (inInputSource)
786  {
787  case NTV2_INPUTSOURCE_SDI1: return kRegRP188InOut1DBB; // reg 29
788  case NTV2_INPUTSOURCE_SDI2: return kRegRP188InOut2DBB; // reg 64
789  case NTV2_INPUTSOURCE_SDI3: return kRegRP188InOut3DBB; // reg 268
790  case NTV2_INPUTSOURCE_SDI4: return kRegRP188InOut4DBB; // reg 273
791  default: return 0;
792  } // switch on input source
793 
794 } // GetRP188RegisterForInput
795 
796 
798 {
799  bool result (false);
801  ULWord regValue (0);
802 
803  //
804  // Bit 16 of the RP188 DBB register will be set if there is timecode embedded in the input signal...
805  //
806  if (regNum && mInputDevice.ReadRegister(regNum, regValue) && regValue & BIT(16))
807  result = true;
808  return result;
809 
810 } // 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:301
Specifies the device&#39;s internal clock.
Definition: ntv2enums.h:1464
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:496
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
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
Definition: ntv2card.h:2763
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:2012
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:206
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...
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:236
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 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:3907
Identifies the 2nd SDI video input.
Definition: ntv2enums.h:1274
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
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:486
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:416
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:1245
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)
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:1275
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...
Definition: ntv2card.h:2787
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:2035
Configures an NTV2Burn or NTV2FieldBurn instance.
Specifies channel or FrameStore 8 (or the 8th item).
Definition: ntv2enums.h:1370
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:1364
Specifies the SDI In 1 connector.
Definition: ntv2enums.h:1462
Declares the CNTV2DeviceScanner class.
Identifies the 4th SDI video input.
Definition: ntv2enums.h:1276
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 UnsubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Unregisters me so I&#39;m no longer notified when an output VBI is signaled on the given output channel...
Definition: ntv2card.h:2819
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).
NTV2InputSource
Identifies a specific video input source.
Definition: ntv2enums.h:1266
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:5414
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:250
#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:3903
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...
ULWord GetFrameCount(void) const
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:1363
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...
Definition: ntv2card.h:2837
virtual bool AutoCirculateStart(const NTV2Channel inChannel, const ULWord64 inStartTime=0)
Starts AutoCirculate streaming for the specified channel that was previously initialized by CNTV2Card...
bool CanDoFrameBufferFormat(const NTV2PixelFormat inPF)
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 playback streaming, designating a contiguous block of frame buf...
#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:1366
NTV2Channel fInputChannel
The input channel to use.
Specifies channel or FrameStore 5 (or the 5th item).
Definition: ntv2enums.h:1367
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:3964
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:1368
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 streaming, designating a contiguous block of frame buffe...
#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:1369
bool GetRP188Str(std::string &sRP188) const
Definition: ntv2rp188.cpp:918
std::string & lower(std::string &str)
Definition: common.cpp:436
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:1273
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:147
virtual void StartCaptureThread(void)
Starts my capture thread.
SDI 1 embedded VITC.
Definition: ntv2enums.h:3960
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:1365
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:227
virtual bool EnableChannel(const NTV2Channel inChannel)
Enables the given FrameStore.