AJA NTV2 SDK  17.1.1.1245
NTV2 SDK 17.1.1.1245
ntv2ccgrabber.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2ccgrabber.h"
9 #include "ntv2captionrenderer.h"
10 #include "ntv2line21captioner.h"
15 #include "ntv2debug.h"
16 #include "ntv2transcode.h"
17 #include "ajabase/common/types.h"
18 #include "ajabase/system/memory.h"
19 #include <iostream>
20 #include <iomanip>
21 #include <utility> // std::rel_ops
22 #include <algorithm> // set_difference
23 #include <iterator> // for inserter
24 
25 using namespace std;
26 using namespace std::rel_ops;
27 
28 #define AsConstUBytePtr(__p__) reinterpret_cast<const UByte*>(__p__)
29 #define AsConstULWordPtr(__p__) reinterpret_cast<const ULWord*>(__p__)
30 #define AsULWordPtr(__p__) reinterpret_cast<ULWord*>(__p__)
31 #define AsUBytePtr(__p__) reinterpret_cast<UByte*>(__p__)
32 //#define NTV2_BUFFER_LOCK // Define this to use buffer locking in kernel driver
33 
34 static const ULWord kAppSignature NTV2_FOURCC ('C','C','G','R');
37 static const uint32_t MAX_ACCUM_FRAME_COUNT (30); // At least every second?
38 
39 
41 
42  : mConfig (inConfigData),
43  mCaptureThread (AJAThread()),
44  mDeviceID (DEVICE_ID_NOTFOUND),
45  mSavedTaskMode (NTV2_DISABLE_TASKS),
46  mAudioSystem (mConfig.fWithAudio ? NTV2_AUDIOSYSTEM_1 : NTV2_AUDIOSYSTEM_INVALID),
47  mVancMode (NTV2_VANCMODE_INVALID),
48  mGlobalQuit (false),
49  mSquares (false),
50  mLastOutStr (),
51  mLastOutFrame (0),
52  mErrorTally (0),
53  mCaptionDataTally (0),
54  m608Channel (mConfig.fCaptionChannel),
55  m608Mode (NTV2_CC608_CapModeUnknown),
56  m608Decoder (),
57  mVPIDInfoDS1 (0),
58  mVPIDInfoDS2 (0),
59  mInputFrameStores (),
60  mActiveSDIInputs (),
61  mActiveCSCs (),
62  mInputConnections (),
63  mHostBuffers (),
64  mCircularBuffer (),
65  mInputXferInfo (),
66  mHeadUpDisplayOn (true),
67  mOutputChannel (NTV2_CHANNEL_INVALID),
68  mPlayoutFBF (NTV2_FBF_ARGB),
69  mPlayoutThread (AJAThread()),
70  mOutputConnections ()
71 {
72  CNTV2CaptionDecoder608::Create(m608Decoder);
73  CNTV2CaptionDecoder708::Create(m708DecoderAnc);
74  CNTV2CaptionDecoder708::Create(m708DecoderVanc);
75  NTV2_ASSERT (m608Decoder && m708DecoderAnc && m708DecoderVanc);
76 
77 } // constructor
78 
79 
81 {
82  if (m608Decoder)
84 
85  // Stop my capture thread, then destroy it...
86  Quit();
87 
88  // Unsubscribe from input vertical event...
89  mDevice.UnsubscribeInputVerticalEvent(mInputFrameStores);
90 
92 
93  if (!mConfig.fDoMultiFormat)
94  {
95  mDevice.SetEveryFrameServices(mSavedTaskMode);
96  mDevice.ReleaseStreamForApplication (kAppSignature, static_cast<int32_t>(AJAProcess::GetPid()));
97  }
98 
99 } // destructor
100 
101 
103 {
104  // Set the 'quit' flag, and wait for the threads to go inactive...
105  mGlobalQuit = true;
106 
107  while (mCaptureThread.Active())
108  AJATime::Sleep(10);
109 
110  while (mPlayoutThread.Active())
111  AJATime::Sleep(10);
112 
113  if (!mConfig.fDoMultiFormat)
114  mDevice.ClearRouting();
115 
116 } // Quit
117 
118 
120 {
121  CNTV2DemoCommon::SetDefaultPageSize(); // Set host-specific page size
122 
123  // Open the device...
125  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not found" << endl; return AJA_STATUS_OPEN;}
126 
127  if (!mDevice.IsDeviceReady(false))
128  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
129 
130  mDeviceID = mDevice.GetDeviceID(); // Keep this handy because it's used frequently
131  const string deviceStr(::NTV2DeviceIDToString(mDeviceID));
132 
133  if (mConfig.fBurnCaptions)
134  {
135  if (mDevice.features().GetNumFrameStores() < 2) // Need 2+ frame stores
136  {
137  cerr << "## ERROR: Device '" << deviceStr << "' can't burn-in captions because at least 2 frame stores are required" << endl;
138  return AJA_STATUS_FAIL;
139  }
140  if (!mDevice.features().CanDoPlayback())
141  {
142  cerr << "## ERROR: Device '" << deviceStr << "' can't burn-in captions because device can only capture/ingest" << endl;
143  return AJA_STATUS_FAIL;
144  }
145  if (mDevice.features().GetNumVideoInputs() < 1 || mDevice.features().GetNumVideoOutputs() < 1) // Need 1 input & 1 output
146  {
147  cerr << "## ERROR: Device '" << deviceStr << "' can't be used -- at least 1 SDI input and 1 SDI output required" << endl;
148  return AJA_STATUS_FAIL;
149  }
150  if (!mDevice.features().GetNumMixers()) // Need 1 or more mixers
151  {
152  cerr << "## ERROR: Device '" << deviceStr << "' can't burn-in captions because a mixer/keyer widget is required" << endl;
153  return AJA_STATUS_FAIL;
154  }
155  if (!mDevice.features().CanDoFrameBufferFormat(mPlayoutFBF)) // FrameStore must handle 8-bit RGB with alpha
156  {
157  cerr << "## ERROR: Device '" << deviceStr << "' can't burn-in captions because it can't do 8-bit RGB (with alpha)" << endl;
158  return AJA_STATUS_FAIL;
159  }
160  } // if --burn
161 
162  if (!mConfig.fDoMultiFormat)
163  {
164  if (!mDevice.AcquireStreamForApplication (kAppSignature, static_cast<int32_t>(AJAProcess::GetPid())))
165  {cerr << "## ERROR: Cannot acquire -- device busy" << endl; return AJA_STATUS_BUSY;} // Some other app owns the device
166  mDevice.GetEveryFrameServices(mSavedTaskMode); // Save the current task mode
167  }
168 
169  mDevice.SetEveryFrameServices(NTV2_OEM_TASKS); // Use the OEM service level
170 
171  if (mDevice.features().CanDoMultiFormat())
172  mDevice.SetMultiFormatMode(mConfig.fDoMultiFormat);
173 
174  if (!mConfig.fUseVanc && !mDevice.features().CanDoCustomAnc()) // --vanc not specified && no anc extractors?
175  {
176  cerr << "## WARNING: Enabling VANC because no Anc extractors" << endl;
177  mConfig.fUseVanc = true;
178  }
179 
180  // Set up the input video...
181  AJAStatus status = SetupInputVideo();
182  if (AJA_FAILURE(status))
183  return status;
184 
185  // Set up the audio...
186  status = SetupAudio();
187  if (AJA_FAILURE(status))
188  return status;
189 
190  if (!m608Decoder->SubscribeChangeNotification(Caption608ChangedStatic, this))
191  {cerr << "## WARNING: SubscribeChangeNotification failed" << endl; return AJA_STATUS_FAIL;}
192  #if defined(_DEBUG)
193  cerr << mConfig << endl;
194  #endif // defined(_DEBUG)
195  return AJA_STATUS_SUCCESS;
196 
197 } // Init
198 
199 
201 {
203  mDevice.GetVANCMode (vancMode, mConfig.fInputChannel);
204  const ULWord captureBufferSize (::GetVideoWriteSize (inVideoFormat, mConfig.fPixelFormat, vancMode));
205 
207  mCircularBuffer.SetAbortFlag (&mGlobalQuit);
208 
209  // Allocate and add each NTV2FrameData to my circular buffer member variable...
210  mHostBuffers.reserve(CIRCULAR_BUFFER_SIZE);
211  while (mHostBuffers.size() < CIRCULAR_BUFFER_SIZE)
212  {
213  mHostBuffers.push_back(NTV2FrameData()); // Make a new NTV2FrameData...
214  NTV2FrameData & frameData(mHostBuffers.back()); // ...and get a reference to it
215  // Allocate a page-aligned video buffer
216  if (!frameData.fVideoBuffer.Allocate(captureBufferSize, /*pageAlign?*/true))
217  return AJA_STATUS_MEMORY;
218  if (NTV2_IS_VALID_AUDIO_SYSTEM(mAudioSystem))
219  if (!frameData.fAudioBuffer.Allocate(NTV2_AUDIOSIZE_MAX, /*pageAlign?*/true))
220  return AJA_STATUS_MEMORY;
221  // Anc data buffers --- only used if Anc extractors supported...
222  if (mDevice.features().CanDoCustomAnc())
223  {
224  if (!frameData.fAncBuffer.Allocate(NTV2_ANCSIZE_MAX, /*pageAlign?*/true))
225  return AJA_STATUS_MEMORY;
226  if (!frameData.fAncBuffer2.Allocate(NTV2_ANCSIZE_MAX, /*pageAlign?*/true))
227  return AJA_STATUS_MEMORY;
228  }
229  #if defined(NTV2_BUFFER_LOCK)
230  frameData.LockAll(mDevice);
231  #endif
232  mCircularBuffer.Add(&frameData); // Add to my circular buffer
233  } // for each NTV2FrameData
234 
235  return AJA_STATUS_SUCCESS;
236 
237 } // SetupHostBuffers
238 
239 
241 {
242  // Unlock each in-host NTV2FrameData...
243  #if defined(NTV2_BUFFER_LOCK)
244  for (size_t ndx(0); ndx < mHostBuffers.size(); ndx++)
245  {
246  NTV2FrameData & frameData(mHostBuffers.at(ndx));
247  frameData.UnlockAll(mDevice);
248  }
249  #endif // NTV2_BUFFER_LOCK
250  mHostBuffers.clear();
251  mCircularBuffer.Clear();
252  return;
253 
254 } // ReleaseHostBuffers
255 
256 
258 {
259  bool isTransmit (false);
260  const UWord numFrameStores (mDevice.features().GetNumFrameStores());
261  const NTV2DeviceID deviceID (mDevice.GetDeviceID());
262  const string deviceName (::NTV2DeviceIDToString(deviceID));
263  const string channelName (::NTV2ChannelToString(mConfig.fInputChannel, true));
264 
265  // CCGrabber is SDI only
266  // User must have specified at least --input or --channel
268  {cerr << "## ERROR: Must specify at least input source or input channel" << endl; return AJA_STATUS_FAIL;}
269  else if (!NTV2_IS_VALID_INPUT_SOURCE(mConfig.fInputSource))
271  else if (!NTV2_IS_VALID_CHANNEL(mConfig.fInputChannel))
273 
274  // Check input source
275  const string inputName (::NTV2InputSourceToString(mConfig.fInputSource,true));
276  if (!mDevice.features().CanDoInputSource(mConfig.fInputSource))
277  {cerr << "## ERROR: '" << deviceName << "' cannot grab captions from '" << inputName << "'" << endl; return AJA_STATUS_FAIL;}
279  {cerr << "## ERROR: Input '" << inputName << "' not SDI" << endl; return AJA_STATUS_FAIL;}
280 
281  // Check channel
282  if (numFrameStores < UWord(mConfig.fInputChannel+1))
283  {cerr << "## ERROR: " << deviceName << " has no " << channelName << " input" << endl; return AJA_STATUS_FAIL;}
284 
285  const NTV2Channel sdiInput(::NTV2InputSourceToChannel(mConfig.fInputSource));
286  mActiveSDIInputs.insert(sdiInput);
287  if (mDevice.features().HasBiDirectionalSDI()) // If device has bidirectional SDI connectors...
288  if (mDevice.GetSDITransmitEnable(sdiInput, isTransmit)) // ...and GetSDITransmitEnable succeeds...
289  if (isTransmit) // ...and input is set to "transmit"...
290  {
291  mDevice.SetSDITransmitEnable(sdiInput, false); // ...then disable transmit mode...
292  mDevice.WaitForOutputVerticalInterrupt(NTV2_CHANNEL1, 12); // ...and give the device some time to lock to a signal
293  } // if input SDI connector needs to switch from transmit mode
294 
296  mDevice.GetReference(refSrc);
297  if (mConfig.fBurnCaptions || (!mConfig.fBurnCaptions && !mConfig.fDoMultiFormat))
298  {
299  // Set the device output clock reference to the SDI input.
300  // This is necessary only when...
301  // - Doing caption burn-in, which requires syncing the Mixer input to the SDI input;
302  // - Routing E-E, which is only done when not doing burn-in and not doing multi-format mode.
304  mDevice.SetReference(refSrc);
305  }
306  if (mConfig.fBurnCaptions) // Caption burn-in/playout requires choosing an output channel
307  switch (mConfig.fInputChannel)
308  {
309  case NTV2_CHANNEL1: mOutputChannel = (numFrameStores == 2 || numFrameStores > 4) ? NTV2_CHANNEL2 : NTV2_CHANNEL3; break;
310  case NTV2_CHANNEL2: mOutputChannel = (numFrameStores > 4) ? NTV2_CHANNEL3 : NTV2_CHANNEL4; break;
311  case NTV2_CHANNEL3: mOutputChannel = NTV2_CHANNEL4; break;
312  case NTV2_CHANNEL4: mOutputChannel = (numFrameStores > 4) ? NTV2_CHANNEL5 : NTV2_CHANNEL3; break;
313  case NTV2_CHANNEL5: mOutputChannel = NTV2_CHANNEL6; break;
314  case NTV2_CHANNEL6: mOutputChannel = NTV2_CHANNEL7; break;
315  case NTV2_CHANNEL7: mOutputChannel = NTV2_CHANNEL8; break;
316  case NTV2_CHANNEL8: mOutputChannel = NTV2_CHANNEL7; break;
318  }
319 
320  if (!mDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
321  {cerr << "## ERROR: '" << deviceName << "' doesn't support '" << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat) << "'" << endl; return AJA_STATUS_FAIL;}
322 
323  // "Tune" the 608 decoder to the desired channel...
324  m608Decoder->SetDisplayChannel(m608Channel);
325  m708DecoderAnc->SetDisplayChannel(m608Channel);
326  m708DecoderVanc->SetDisplayChannel(m608Channel);
327 
328  cerr << "## NOTE: Using " << deviceName << " " << (mConfig.fUseVanc ? "VANC" : "AncExt") << " with spigot=" << inputName
329  << ", ref=" << ::NTV2ReferenceSourceToString(refSrc,true) << ", input=" << channelName;
330  if (mConfig.fBurnCaptions) cerr << ", output=" << ::NTV2ChannelToString(mOutputChannel,true);
331  cerr << endl;
332 
333  return AJA_STATUS_SUCCESS;
334 
335 } // SetupInputVideo
336 
337 
339 {
340  if (NTV2_IS_VALID_AUDIO_SYSTEM(mAudioSystem))
341  {
342  const UWord numAudioSystems (mDevice.features().GetNumAudioSystems());
343  if (numAudioSystems > 1 && UWord(mConfig.fInputChannel) < numAudioSystems)
344  mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fInputChannel);
345 
346  // Configure the audio system...
348  mDevice.SetNumberAudioChannels (mDevice.features().GetMaxAudioChannels(), mAudioSystem);
349  mDevice.SetAudioRate (NTV2_AUDIO_48K, mAudioSystem);
350  mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mAudioSystem);
351 
352  // Set up the output audio embedders...
353  if (mConfig.fBurnCaptions && numAudioSystems > 1)
354  {
355  if (mConfig.fDoMultiFormat)
356  {
357  UWord sdiOutput(mOutputChannel);
358  if (sdiOutput >= mDevice.features().GetNumVideoOutputs()) // Kona1 has 2 FrameStores/Channels, but only 1 SDI output
359  sdiOutput = mDevice.features().GetNumVideoOutputs() - 1;
360  mDevice.SetSDIOutputAudioSystem(NTV2Channel(sdiOutput), mAudioSystem);
361  }
362  else // Have all device outputs use the same audio system...
363  for (unsigned sdiOutput(0); sdiOutput < mDevice.features().GetNumVideoOutputs(); sdiOutput++)
364  if (!mDevice.features().HasBiDirectionalSDI()
365  || NTV2Channel(sdiOutput) != ::NTV2InputSourceToChannel(mConfig.fInputSource))
366  mDevice.SetSDIOutputAudioSystem(NTV2Channel(sdiOutput), mAudioSystem);
367  }
368 
369  // Loopback mode (E-E audio) should be enabled only when not burning-in captions (i.e. when routing E-E).
370  // If caption burn-in and loopback are enabled, output video will lag the audio, as video frames are delayed
371  // in the ring buffer.
373  }
374  return AJA_STATUS_SUCCESS;
375 
376 } // SetupAudio
377 
378 
381 
384 
385 
387 {
388  const bool isRGBFBF (::IsRGBFormat(mConfig.fPixelFormat));
389  const bool isRGBWire (mVPIDInfoDS1.IsRGBSampling());
390  const bool isSquares (!mVPIDInfoDS1.IsStandardTwoSampleInterleave());
391  const bool is4KHFR (NTV2_IS_HFR_STANDARD(::GetNTV2StandardFromVideoFormat(inVideoFormat)));
392  const NTV2Channel sdiInput (::NTV2InputSourceToChannel(mConfig.fInputSource));
393  const NTV2ChannelList frameStores (::NTV2MakeChannelList(mInputFrameStores));
394  NTV2ChannelList sdiInputs (::NTV2MakeChannelList(mActiveSDIInputs));
395  const NTV2ChannelList activeCSCs (::NTV2MakeChannelList(mActiveCSCs));
396  static const bool ShowRoutingProgress(false);
397 
398  mInputConnections.clear();
399  if (ShowRoutingProgress) mDevice.ClearRouting();
400 
401  // Route frameStore's input to sdiInput's output (possibly through CSC, if required)
402  if (isRGBFBF && isRGBWire)
403  {
404  if (isSquares) // SDIIn ==> DLIn ==> FrameStore
405  {
406  for (size_t ndx(0); ndx < sdiInputs.size(); ndx++)
407  { NTV2Channel frmSt(frameStores.at(ndx)), sdiIn(sdiInputs.at(ndx));
408  mInputConnections.insert(NTV2XptConnection(::GetDLInInputXptFromChannel(sdiIn, /*linkB?*/false),
409  ::GetSDIInputOutputXptFromChannel(sdiIn, /*DS2?*/false)));
410  mInputConnections.insert(NTV2XptConnection(::GetDLInInputXptFromChannel(sdiIn, /*linkB?*/true),
411  ::GetSDIInputOutputXptFromChannel(sdiIn, /*DS2?*/true)));
412  mInputConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(sdiIn),
413  ::GetDLInOutputXptFromChannel(frmSt)));
414  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
415  }
416  }
417  else // TSI // 2x SDIIn ==> 2x DLIn ==> 425MUX ==> RGBFrameStore
418  {
419  NTV2ChannelSet sdiIns = ::NTV2MakeChannelSet(sdiInput, UWord(2*frameStores.size()));
420  sdiInputs = ::NTV2MakeChannelList(sdiIns);
421  NTV2ChannelList tsiMuxes = CNTV2DemoCommon::GetTSIMuxesForFrameStore(mDevice, frameStores.at(0),
422  UWord(frameStores.size()*2));
423  mDevice.SetSDITransmitEnable(sdiIns, true); // Gotta do this again, since sdiInputs changed
424  for (size_t ndx(0); ndx < sdiInputs.size(); ndx++)
425  { NTV2Channel frmSt(frameStores.at(ndx/2)), tsiMux(tsiMuxes.at(ndx/2)), sdiIn(sdiInputs.at(ndx));
426  mInputConnections.insert(NTV2XptConnection(::GetDLInInputXptFromChannel(sdiIn, /*DS2?*/false),
427  ::GetSDIInputOutputXptFromChannel(sdiIn, /*DS2?*/false)));
428  mInputConnections.insert(NTV2XptConnection(::GetDLInInputXptFromChannel(sdiIn, /*DS2?*/true),
429  ::GetSDIInputOutputXptFromChannel(sdiIn, /*DS2?*/true)));
430  mInputConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux, /*lnkB?*/ndx & 1),
431  ::GetDLInOutputXptFromChannel(sdiIn)));
432  mInputConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt, /*lnkB?*/false),
433  ::GetTSIMuxOutputXptFromChannel(tsiMux,/*lnkB?*/false, /*rgb?*/true)));
434  mInputConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt, /*lnkB?*/true),
435  ::GetTSIMuxOutputXptFromChannel(tsiMux,/*lnkB?*/true, /*rgb?*/true)));
436  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
437  }
438  }
439  }
440  else if (isRGBFBF && !isRGBWire)
441  {
442  if (isSquares) // SDIIn ==> CSC ==> RGBFrameStore
443  for (size_t ndx(0); ndx < sdiInputs.size(); ndx++)
444  { NTV2Channel frmSt(frameStores.at(ndx)), sdiIn(sdiInputs.at(ndx));
445  mInputConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt),
446  ::GetCSCOutputXptFromChannel(frmSt, /*key?*/false, /*RGB?*/true)));
447  mInputConnections.insert(NTV2XptConnection(::GetCSCInputXptFromChannel(frmSt),
449  }
450  else // TSI // SDIIn ==> 2 x CSC ==> 425MUX ==> RGBFrameStore
451  {
452  NTV2ChannelSet sdiIns = ::NTV2MakeChannelSet(sdiInput, UWord(frameStores.size()));
453  sdiInputs = ::NTV2MakeChannelList(sdiIns);
455  UWord(2*sdiInputs.size()));
456  NTV2ChannelList tsiMuxes = CNTV2DemoCommon::GetTSIMuxesForFrameStore(mDevice, frameStores.at(0),
457  UWord(frameStores.size()));
458  cerr << "FrameStores: " << ::NTV2ChannelListToStr(frameStores) << endl
459  << "SDIInputs: " << ::NTV2ChannelListToStr(sdiInputs) << endl
460  << "TSIMuxers: " << ::NTV2ChannelListToStr(tsiMuxes) << endl;
461  mDevice.SetSDITransmitEnable(sdiIns, false); // Gotta do this again, since sdiIns changed
462  for (size_t ndx(0); ndx < cscs.size(); ndx++)
463  { NTV2Channel frmSt(frameStores.at(ndx/2)), sdiIn(sdiInputs.at(ndx/2)), tsiMux(tsiMuxes.at(ndx/2)),
464  csc(cscs.at(ndx));
465  mInputConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt, /*inputB?*/ndx & 1),
466  ::GetTSIMuxOutputXptFromChannel(tsiMux,/*linkB?*/ndx & 1,/*rgb?*/true)));
467  mInputConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux, /*linkB?*/ndx & 1),
468  ::GetCSCOutputXptFromChannel(csc, /*key?*/false, /*rgb?*/true)));
469  mInputConnections.insert(NTV2XptConnection(::GetCSCInputXptFromChannel(csc),
470  ::GetSDIInputOutputXptFromChannel(sdiIn, /*DS2?*/ndx & 1)));
471  }
472  }
473  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
474  }
475  else if (!isRGBFBF && isRGBWire)
476  {
477  if (isSquares) // SDIIn ==> DLIn ==> CSC ==> FrameStore
478  {
479  for (size_t ndx(0); ndx < sdiInputs.size(); ndx++)
480  { NTV2Channel frmSt(frameStores.at(ndx)), csc(activeCSCs.at(ndx)), sdi(sdiInputs.at(ndx));
481  mInputConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt, /*BInput?*/false),
483  mInputConnections.insert(NTV2XptConnection(::GetCSCInputXptFromChannel(csc),
485  mInputConnections.insert(NTV2XptConnection(::GetDLInInputXptFromChannel(sdi, /*lnkB?*/false),
486  ::GetSDIInputOutputXptFromChannel(sdi, /*DS2?*/false)));
487  mInputConnections.insert(NTV2XptConnection(::GetDLInInputXptFromChannel(sdi, /*lnkB?*/true),
488  ::GetSDIInputOutputXptFromChannel(sdi, /*DS2?*/true)));
489  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
490  }
491  }
492  else // TSI // SDIIn ==> DLIn ==> CSC ==> TSIMux ==> FrameStore
493  {
494  //TBD
495  }
496  }
497  else // SDIIn ==> YUVFrameStore
498  {
499  if (isSquares) // SDIIn ==> FrameStore
500  {
501  for (size_t ndx(0); ndx < sdiInputs.size(); ndx++)
502  { NTV2Channel frmSt(frameStores.at(ndx)), sdiIn(sdiInputs.at(ndx));
503  mInputConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt),
505  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
506  }
507  }
508  else // TSI // SDIIn (LFR: 2 x DS1&DS2, 4KHFR: 4 x DS1) ==> 425MUX ==> YUVFrameStore
509  {
510  NTV2XptConnections & mConnections(mInputConnections);
511  sdiInputs = ::NTV2MakeChannelList(sdiInputs.at(0), is4KHFR ? 4 : UWord(frameStores.size()));
512  NTV2ChannelList tsiMuxes = CNTV2DemoCommon::GetTSIMuxesForFrameStore(mDevice, frameStores.at(0),
513  UWord(frameStores.size()));
514  cerr << (is4KHFR ? "4KHFR" : "") << endl << "FrameStores: " << ::NTV2ChannelListToStr(frameStores) << endl
515  << "SDIInputs: " << ::NTV2ChannelListToStr(sdiInputs) << endl << "TSIMuxes: " << ::NTV2ChannelListToStr(tsiMuxes) << endl;
516  for (size_t ndx(0); ndx < sdiInputs.size(); ndx++)
517  { NTV2Channel frmSt(frameStores.at(is4KHFR ? ndx/2 : ndx)),
518  tsiMux(tsiMuxes.at(is4KHFR ? ndx/2 : ndx)),
519  sdiIn(sdiInputs.at(ndx));
520  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux, /*linkB?*/is4KHFR && (ndx & 1)),
521  ::GetSDIInputOutputXptFromChannel(sdiIn, /*DS2?*/false)));
522  if (!is4KHFR)
523  mConnections.insert(NTV2XptConnection(::GetTSIMuxInputXptFromChannel(tsiMux, /*linkB?*/true),
524  ::GetSDIInputOutputXptFromChannel(sdiIn, /*DS2?*/true)));
525  mConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt, /*inputB?*/is4KHFR && (ndx & 1)),
526  ::GetTSIMuxOutputXptFromChannel(tsiMux,/*linkB?*/is4KHFR && (ndx & 1))));
527  if (!is4KHFR)
528  mConnections.insert(NTV2XptConnection(::GetFrameBufferInputXptFromChannel(frmSt, /*inputB?*/true),
529  ::GetTSIMuxOutputXptFromChannel(tsiMux,/*linkB?*/true)));
530  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
531  }
532  }
533  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
534  }
535  // At this point, sdiInputs is authoritative, so update mActiveSDIInputs...
536  mActiveSDIInputs = ::NTV2MakeChannelSet(sdiInputs);
537 
538  // E-E ROUTING
539  if ((false) /* not ready for prime-time */ && !mConfig.fBurnCaptions && !mConfig.fDoMultiFormat)
540  { // Not doing caption burn-in: route E-E pass-thru...
541  NTV2ChannelList sdiOutputs;
542  if (mDevice.features().HasBiDirectionalSDI())
543  {
544  const NTV2ChannelSet allSDIs (::NTV2MakeChannelSet(NTV2_CHANNEL1, mDevice.features().GetNumVideoOutputs()));
545  NTV2ChannelSet sdiOuts;
546  set_difference (allSDIs.begin(), allSDIs.end(), // allSDIs
547  mActiveSDIInputs.begin(), mActiveSDIInputs.end(), // - mActiveSDIInputs
548  inserter(sdiOuts, sdiOuts.begin())); // ==> sdiOuts
549  sdiOutputs = ::NTV2MakeChannelList(sdiOuts);
550  cerr << "allSDIs: " << ::NTV2ChannelSetToStr(allSDIs) << endl << "actSDIIns: " << ::NTV2ChannelSetToStr(mActiveSDIInputs) << endl; // DEBUG
551  }
552  else
553  sdiOutputs = ::NTV2MakeChannelList(NTV2_CHANNEL1, mDevice.features().GetNumVideoOutputs());
554  cerr << "SDIOuts: " << ::NTV2ChannelListToStr(sdiOutputs) << endl << "SDIIns: " << ::NTV2ChannelListToStr(sdiInputs) << endl; // DEBUG
555  for (size_t sdiNdx(0); sdiNdx < sdiOutputs.size(); sdiNdx++)
556  { const NTV2Channel sdiOut(sdiOutputs.at(sdiNdx));
557  const NTV2Channel sdiIn(sdiInputs.at(sdiNdx < sdiInputs.size() ? sdiNdx : sdiInputs.size()-1));
558  if (mDevice.features().HasBiDirectionalSDI() && mActiveSDIInputs.find(sdiOut) == mActiveSDIInputs.end())
559  {
560  cerr << "Switching SDI " << (sdiOut+1) << " to output" << endl; // DEBUG
561  mDevice.SetSDITransmitEnable(sdiOut, true);
562  }
563  if (isRGBWire)
564  { // Route DLIn output to DLOut...
565  mInputConnections.insert(NTV2XptConnection(::GetDLOutInputXptFromChannel(sdiOut),
566  ::GetDLInOutputXptFromChannel(sdiIn)));
567  mInputConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut,false),
568  ::GetDLOutOutputXptFromChannel(sdiOut,false)));
569  mInputConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut,true),
570  ::GetDLOutOutputXptFromChannel(sdiOut,true)));
571  }
572  else
573  mInputConnections.insert(NTV2XptConnection(::GetSDIOutputInputXpt(sdiOut),
575  if (ShowRoutingProgress) mDevice.ApplySignalRoute(mInputConnections);
576  } // for each output spigot
577  } // if not burning captions and not multiFormat
578 
579  return mDevice.ApplySignalRoute(mInputConnections, /*replaceExistingRouting?*/!mConfig.fDoMultiFormat);
580 
581 } // RouteInputSignal
582 
583 
585 {
586  NTV2_ASSERT (!mConfig.fBurnCaptions); // Must not be burning captions
587 
588  const NTV2Channel sdiInputAsChan (::NTV2InputSourceToChannel(mConfig.fInputSource));
589  const NTV2Standard outputStandard (::GetNTV2StandardFromVideoFormat(inVideoFormat));
590  const NTV2Channel startNum (sdiInputAsChan == NTV2_CHANNEL1 ? NTV2_CHANNEL1 : NTV2_CHANNEL5);
591  const NTV2Channel endNum (sdiInputAsChan == NTV2_CHANNEL1 ? NTV2_CHANNEL5 : NTV2_MAX_NUM_CHANNELS);
592 
593  for (NTV2Channel chan(startNum); chan < endNum; chan = NTV2Channel(chan + 1))
594  {
595  if (ULWord(chan) >= mDevice.features().GetNumVideoChannels())
596  break;
597  if (chan != sdiInputAsChan)
598  if (mDevice.features().CanDoWidget(g3GSDIOutputs[chan]) || mDevice.features().CanDoWidget(gSDIOutputs[chan]))
599  mDevice.SetSDIOutputStandard(chan, outputStandard);
600  } // for each output spigot
601 
602 } // SetOutputStandards
603 
604 
606 {
607  // Start the capture thread...
608  AJAStatus result (StartCaptureThread());
609  if (AJA_FAILURE(result))
610  return result;
611 
612  AJATime::Sleep(500); // Wait a half second for the capture thread to start (or fail?)...
614 
615 } // Run
616 
617 
618 
620 
621 // Starts the capture thread
623 {
624  // Create and start the capture thread...
625  AJAStatus result (mCaptureThread.Attach(CaptureThreadStatic, this));
626  if (AJA_SUCCESS(result))
627  result = mCaptureThread.SetPriority(AJA_ThreadPriority_High);
628  if (AJA_SUCCESS(result))
629  result = mCaptureThread.Start();
630  return result;
631 
632 } // StartCaptureThread
633 
634 
635 // The capture thread function
636 void NTV2CCGrabber::CaptureThreadStatic (AJAThread * pThread, void * pContext) // static
637 {
638  (void) pThread;
639  // Grab the NTV2CCGrabber instance pointer from the pContext parameter,
640  // then call its CaptureFrames method...
641  NTV2CCGrabber * pApp (reinterpret_cast <NTV2CCGrabber *> (pContext));
642  pApp->CaptureFrames ();
643 
644 } // CaptureThreadStatic
645 
646 
647 // The capture function -- capture frames until told to quit...
649 {
650  ULWord xferTally(0), xferFails(0), noVideoTally(0), waitTally(0);
651  bool bUsingVanc (mConfig.fUseVanc); // To detect fUseVanc changes
652  CAPNOTE("Thread started");
653  NTV2_ASSERT(!mActiveSDIInputs.empty());
654 
655  // Loop until time to quit...
656  while (!mGlobalQuit)
657  {
658  NTV2PixelFormat currentPF (mConfig.fPixelFormat);
660  if (currentVF == NTV2_FORMAT_UNKNOWN)
661  break; // Quit
662 
663  // At this point, the input video format is stable.
664 
665  // Configure the input FrameStore(s): pixel format, mode...
666  mDevice.EnableChannels(mInputFrameStores);
667  mDevice.SetFrameBufferFormat(mInputFrameStores, mConfig.fPixelFormat);
668 
669  // Enable and subscribe to the interrupts for the channel to be used...
670  mDevice.EnableInputInterrupt (mInputFrameStores);
671  mDevice.SubscribeInputVerticalEvent (mInputFrameStores);
672 
673  // Set up the device signal routing...
674  RouteInputSignal(currentVF);
675 
676  // Set the device format to the input format detected, and set VANC mode...
677  mDevice.SetVideoFormat (mInputFrameStores, currentVF, /*retailMode*/false);
678  if (NTV2_IS_4K_VIDEO_FORMAT(currentVF))
679  {
680  if (mDevice.features().CanDo12gRouting())
681  mDevice.SetTsiFrameEnable(true, mConfig.fInputChannel);
682  else if (mSquares)
683  mDevice.Set4kSquaresEnable(true, mConfig.fInputChannel);
684  else
685  mDevice.SetTsiFrameEnable(true, mConfig.fInputChannel);
686  mVancMode = NTV2_VANCMODE_OFF;
687  if (mConfig.fUseVanc)
688  CAPWARN("VANC mode incompatible with 4K/UHD format");
689  }
690  else
691  mVancMode = mConfig.fUseVanc ? NTV2_VANCMODE_TALL : NTV2_VANCMODE_OFF; // "Tall" mode is sufficient to grab captions
692  mDevice.SetVANCMode(mInputFrameStores, mVancMode);
693  if (::Is8BitFrameBufferFormat(mConfig.fPixelFormat))
694  mDevice.SetVANCShiftMode (mConfig.fInputChannel, // 8-bit FBFs require VANC bit shift
696 
697  // Set up the circular buffers based on the detected currentVF...
698  AJAStatus status (SetupHostBuffers(currentVF));
699  if (AJA_FAILURE(status))
700  return;
701 
702  if (mConfig.fBurnCaptions) // If burning-in captions...
703  StartPlayThread(); // ...start a new playout thread
704  else // else E-E mode...
705  SetOutputStandards(currentVF); // ...output standard may need changing
706 
707  mDevice.AutoCirculateStop(mConfig.fInputChannel);
708  if (!mDevice.AutoCirculateInitForInput( mConfig.fInputChannel, // primary channel
709  mConfig.fFrames.count(), // numFrames (zero if specifying range)
710  mAudioSystem, // audio system
712  | (mDevice.features().CanDoCustomAnc() ? AUTOCIRCULATE_WITH_ANC : 0), // flags
713  1, // numChannels to gang
714  mConfig.fFrames.firstFrame(), mConfig.fFrames.lastFrame()))
715  {CAPFAIL("Failed to init Ch" << DEC(mConfig.fInputChannel+1) << " for input"); break;}
716 
717  // Start AutoCirculate...
718  if (!mDevice.AutoCirculateStart(mConfig.fInputChannel))
719  {CAPFAIL("Failed to start Ch" << DEC(mConfig.fInputChannel+1)); break;}
720 
721  // Process frames until signal format changes...
722  while (!mGlobalQuit)
723  {
724  AUTOCIRCULATE_STATUS acStatus;
725  mDevice.AutoCirculateGetStatus (mConfig.fInputChannel, acStatus);
726  if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
727  {
728  // At this point, there's at least one fully-formed frame available in the device's
729  // frame buffer to transfer to the host. Reserve an NTV2FrameData to "produce", and
730  // use it to store the next frame to be transferred from the device...
731  NTV2FrameData * pCaptureData (mCircularBuffer.StartProduceNextBuffer());
732  if (pCaptureData)
733  {
734  mInputXferInfo.acFrameBufferFormat = mConfig.fPixelFormat;
735  mInputXferInfo.SetBuffers (pCaptureData->VideoBuffer(), pCaptureData->VideoBufferSize(),
736  pCaptureData->AudioBuffer(), pCaptureData->AudioBufferSize(),
737  pCaptureData->AncBuffer(), pCaptureData->AncBufferSize(),
738  pCaptureData->AncBuffer2(), pCaptureData->AncBuffer2Size());
739 
740  // Transfer the frame data from the device into our host NTV2FrameData...
741  if (mDevice.AutoCirculateTransfer (mConfig.fInputChannel, mInputXferInfo))
742  {
743  xferTally++;
744  if (mConfig.fBurnCaptions)
745  mInputXferInfo.GetInputTimeCodes(pCaptureData->fTimecodes, ::NTV2InputSourceToChannel(mConfig.fInputSource)); // Captured timecodes
746 
747  // Extract closed-captioning data from the host NTV2FrameData while we have full access to it...
748  ExtractClosedCaptionData (mInputXferInfo.GetTransferStatus().GetProcessedFrameCount(), currentVF);
749  }
750  else
751  xferFails++;
752 
753  // Signal that we're done "producing" the frame, making it available for future "consumption"...
754  mCircularBuffer.EndProduceNextBuffer();
755 
756  if (!mConfig.fBurnCaptions)
757  {
758  // If no caption burn-in is taking place, there's nobody to consume the buffer.
759  // In this case, simply consume it now, thus recycling it immediately...
760  mCircularBuffer.StartConsumeNextBuffer();
761  mCircularBuffer.EndConsumeNextBuffer();
762  }
763  } // if pCaptureData != NULL
764  } // if A/C running and frame(s) are available for transfer
765  else
766  {
767  // Either AutoCirculate is not running, or there were no frames available on the device to transfer.
768  // Rather than waste CPU cycles spinning, waiting until a frame becomes available, it's far more
769  // efficient to wait for the next input vertical interrupt event to get signaled...
771  ++waitTally;
772 
773  // Did incoming video format or VPID(s) change?
774  const NTV2Channel sdiConnector (mActiveSDIInputs.empty() ? NTV2_CHANNEL1 : *(mActiveSDIInputs.begin()));
775  ULWord vpidDS1(0), vpidDS2(0);
776  if (mDevice.GetVPIDValidA(sdiConnector))
777  mDevice.ReadSDIInVPID (sdiConnector, vpidDS1, vpidDS2);
778 
779  NTV2VideoFormat newVF (mDevice.GetInputVideoFormat(mConfig.fInputSource));
780  const bool vfChanged(newVF != currentVF);
781  const bool vpidChgd(mVPIDInfoDS1.GetVPID() != vpidDS1 || mVPIDInfoDS2.GetVPID() != vpidDS2);
782  if (vfChanged || vpidChgd) // || squares != mSquares)
783  {
784  ++noVideoTally;
785  if (vfChanged)
786  CAPWARN("Input video format changed from '" << ::NTV2VideoFormatToString(currentVF)
787  << "' to '" << ::NTV2VideoFormatToString(newVF) << "'");
788  else if (vpidChgd)
789  CAPWARN("Input VPID changed: DS1 (" << xHEX0N(mVPIDInfoDS1.GetVPID(),8) << " to " << xHEX0N(vpidDS1,8)
790  << "), DS2 (" << xHEX0N(mVPIDInfoDS2.GetVPID(),8) << " to " << xHEX0N(vpidDS2,8) << ")");
791 
792  // Terminate the playout thread...
793  mCircularBuffer.StartProduceNextBuffer();
794  mCircularBuffer.EndProduceNextBuffer();
795  break; // exit frame processing loop to restart AutoCirculate
796  } // if incoming video format changed
797  } // else not running or no frames available
798 
799  // Check if pixel format change requested (user pressed P key)...
800  if (mConfig.fPixelFormat != currentPF)
801  {
802  CAPWARN("FrameStore pixel format changed from '"
803  << ::NTV2FrameBufferFormatToString(currentPF,true) << "' to '"
804  << ::NTV2FrameBufferFormatToString(mConfig.fPixelFormat,true) << "'");
805  break; // exit frame processing loop -- restart AutoCirculate
806  }
807  if (mConfig.fUseVanc != bUsingVanc)
808  {
809  CAPWARN("Vanc " << (mConfig.fUseVanc?"enabled":"disabled"));
810  bUsingVanc = mConfig.fUseVanc;
811  break; // exit frame processing loop -- restart AutoCirculate
812  }
813  } // normal frame processing loop -- loop until signal or pixel format change
814 
815  // Stop AutoCirculate...
816  mDevice.AutoCirculateStop(mConfig.fInputChannel);
817 
818  } // loop til quit signaled
819  CAPNOTE("Thread completed, " << DEC(xferTally) << " of " << DEC(xferTally+xferFails) << " frms xferred, "
820  << DEC(waitTally) << " waits, " << DEC(noVideoTally) << " sig chgs");
821 
822 } // CaptureFrames
823 
825 {
827  ULWord numConsecutiveFrames(0), MIN_NUM_CONSECUTIVE_FRAMES(6);
828  NTV2_ASSERT(!mActiveSDIInputs.empty());
829  NTV2Channel sdiConnector(*(mActiveSDIInputs.begin()));
830 
831  // Detection loop:
832  while (result == NTV2_FORMAT_UNKNOWN)
833  {
834  // Determine the input video signal format...
835  // Warning: if there's no input signal, this loop won't exit until mGlobalQuit goes true!
836  mVPIDInfoDS1.MakeInvalid(); mVPIDInfoDS2.MakeInvalid(); // Reset VPID info
837  UWord loopCount(0);
838  while (result == NTV2_FORMAT_UNKNOWN)
839  {
841  if (mGlobalQuit)
842  return NTV2_FORMAT_UNKNOWN; // Terminate if asked to do so
843 
844  const NTV2VideoFormat currVF (mDevice.GetInputVideoFormat(mConfig.fInputSource));
845  if (currVF == NTV2_FORMAT_UNKNOWN)
846  { // Wait for video signal to appear
847  if (++loopCount % 500 == 0) // Log message every minute or so at ~50ms
848  CAPDBG("Waiting for valid video signal to appear at "
849  << ::NTV2InputSourceToString(mConfig.fInputSource,true));
850  }
851  else if (numConsecutiveFrames == 0)
852  {
853  lastVF = currVF; // First valid video format to appear
854  numConsecutiveFrames++; // Start debounce counter
855  }
856  else if (numConsecutiveFrames == MIN_NUM_CONSECUTIVE_FRAMES)
857  {
858  numConsecutiveFrames = 0; // Reset for next signal outage
859  result = currVF; // Set official video format to use
860  }
861  else
862  numConsecutiveFrames = (lastVF == currVF) ? numConsecutiveFrames + 1 : 0;
863  } // loop while input video format is unstable
864 
865  // At this point, the video format is stable and valid.
866 
867  // Grab input VPID info...
868  if (mDevice.GetVPIDValidA(sdiConnector))
869  { ULWord vpidDS1(0), vpidDS2(0);
870  mDevice.ReadSDIInVPID (sdiConnector, vpidDS1, vpidDS2);
871  mVPIDInfoDS1.SetVPID(vpidDS1);
872  mVPIDInfoDS2.SetVPID(vpidDS2);
873  }
874  if (mVPIDInfoDS1.IsValid())
875  { // DS1 VPID valid ---
876  CAPNOTE(::NTV2InputSourceToString(mConfig.fInputSource,true) << " DS1: " << mVPIDInfoDS1);
877  NTV2VideoFormat vfVPID (mVPIDInfoDS1.GetVideoFormat());
878  if (mVPIDInfoDS2.IsValid())
879  CAPNOTE(::NTV2InputSourceToString(mConfig.fInputSource,true) << " DS2: " << mVPIDInfoDS2);
880  if (vfVPID != result && !mSquares)
881  {
882  CAPWARN("VPID=" << ::NTV2VideoFormatToString(vfVPID) << " != " << ::NTV2VideoFormatToString(result));
883  result = vfVPID;
884  }
885  }
886 
887  ostringstream osserr;
888  if (!mDevice.features().CanDoVideoFormat(result)) // Can this device handle this video format?
889  osserr << mDevice.GetModelName() << " can't handle " << ::NTV2VideoFormatToString(result);
890  else if (mVPIDInfoDS1.IsValid() && mVPIDInfoDS1.IsStandardTwoSampleInterleave() && !mDevice.features().CanDo425Mux())
891  osserr << mDevice.GetModelName() << " can't handle TSI";
892  if (!osserr.str().empty())
893  {
894  CAPWARN(osserr.str());
895  result = NTV2_FORMAT_UNKNOWN;
896  mDevice.WaitForInputVerticalInterrupt(mConfig.fInputChannel, 30); // Wait 30 frames
897  continue; // Retry
898  }
899 
900  CAPNOTE(::NTV2InputSourceToString(mConfig.fInputSource,true) << " video format: " << ::NTV2VideoFormatToString(result));
901  cerr << endl << "## NOTE: " << ::NTV2InputSourceToString(mConfig.fInputSource,true)
902  << " video format is " << ::NTV2VideoFormatToString(result) << endl;
903  break; // Done!
904  } // loop
905 
906  // Using 'result' & possibly mVPIDInfoDS1 & mVPIDInfoDS2 --
907  // Does this format require another SDI wire? So we should check for another SDI input?
908  // For now, use just 1 framestore, 1 SDI input, 1 CSC...
909  mDevice.DisableChannels(mInputFrameStores);
910  mInputFrameStores.clear(); mInputFrameStores.insert(mConfig.fInputChannel);
911  mActiveSDIInputs.clear(); mActiveSDIInputs.insert(sdiConnector);
912  if (NTV2_IS_4K_VIDEO_FORMAT(result))
913  {
914  mInputFrameStores = ::NTV2MakeChannelSet(mConfig.fInputChannel,
915  mVPIDInfoDS1.IsValid() && mVPIDInfoDS1.IsStandardTwoSampleInterleave() ? 2 : 4);
916  mActiveSDIInputs = ::NTV2MakeChannelSet(sdiConnector, UWord(mInputFrameStores.size()));
917  }
918  mActiveCSCs = mActiveSDIInputs;
919  CAPDBG(::NTV2VideoFormatToString(result) << ": SDIs=" << ::NTV2ChannelSetToStr(mActiveSDIInputs)
920  << " FrameStores=" << ::NTV2ChannelSetToStr(mInputFrameStores)
921  << " CSCs=" << ::NTV2ChannelSetToStr(mActiveCSCs));
922  cerr << "WaitForStableInputSignal: " << ::NTV2VideoFormatToString(result) << ": SDIIns=" << ::NTV2ChannelSetToStr(mActiveSDIInputs)
923  << " FrameStores=" << ::NTV2ChannelSetToStr(mInputFrameStores)
924  << " CSCs=" << ::NTV2ChannelSetToStr(mActiveCSCs) << endl;
925  NTV2_ASSERT(result != NTV2_FORMAT_UNKNOWN);
926  return result;
927 } // WaitForStableInputSignal
928 
929 
931 
932 
934 {
935  mConfig.fUseVanc = !mConfig.fUseVanc;
936  cerr << endl << "## NOTE: VANC frame geometry " << (mConfig.fUseVanc ? "enabled" : "disabled") << endl;
937 }
938 
939 
941 {
942  OutputMode mode (mConfig.fOutputMode);
943  mode = OutputMode(mode+1);
944  if (!IS_VALID_OutputMode(mode))
946  if (mConfig.fOutputMode != mode)
947  cerr << endl << "## NOTE: Output changed to '" << CCGrabberConfig::OutputModeToString(mode) << "'" << endl;
948  mConfig.fOutputMode = mode;
949 }
950 
952 {
953  CaptionDataSrc src (mConfig.fCaptionSrc);
954  src = CaptionDataSrc(src+1);
955  if (!IS_VALID_CaptionDataSrc(src))
957  if (mConfig.fCaptionSrc != src)
958  cerr << endl << "## NOTE: CC source changed to '" << CCGrabberConfig::CaptionDataSrcToString(src) << "'" << endl;
959  mConfig.fCaptionSrc = src;
960 }
961 
963 {
964  NTV2PixelFormat pf (mConfig.fPixelFormat);
965  do
966  {
967  pf = NTV2PixelFormat(pf+1);
968  if (pf == NTV2_FBF_LAST)
969  pf = NTV2_FBF_FIRST;
970  } while (NTV2_IS_FBF_PLANAR(pf) || !mDevice.features().CanDoFrameBufferFormat(pf));
971  if (mConfig.fPixelFormat != pf)
972  cerr << endl << "## NOTE: Pixel format changed to " << ::NTV2FrameBufferFormatToString(pf) << endl;
973  mConfig.fPixelFormat = pf;
974 }
975 
976 void NTV2CCGrabber::ExtractClosedCaptionData (const uint32_t inFrameNum, const NTV2VideoFormat inVideoFormat)
977 {
978  AJAAncillaryList ancPackets, vancPackets;
979  CaptionData captionData708Anc, captionData708Vanc, captionData608Anc, captionData608Vanc, captionDataL21Anc, captionDataL21; // The 608 caption byte pairs (one pair per field)
980  const NTV2FormatDescriptor formatDesc (inVideoFormat, mConfig.fPixelFormat, mVancMode);
981 
982  if (NTV2_IS_VANCMODE_ON(mVancMode) || mDevice.features().CanDoCustomAnc()) // Gotta have at least VANC or AncExt
983  {
984  // Get all VANC packets...
985  if (NTV2_IS_VANCMODE_ON(mVancMode))
986  {
987  AJAAncillaryList::SetFromVANCData (mInputXferInfo.acVideoBuffer, formatDesc, vancPackets, inFrameNum);
988  vancPackets.ParseAllAncillaryData();
989  }
990 
991  // Get all anc extractor packets...
992  if (mDevice.features().CanDoCustomAnc())
993  {
994  const NTV2Buffer validAncF1 (mInputXferInfo.acANCBuffer.GetHostAddress(0), mInputXferInfo.GetCapturedAncByteCount(false));
995  const NTV2Buffer validAncF2 (mInputXferInfo.acANCField2Buffer.GetHostAddress(0), mInputXferInfo.GetCapturedAncByteCount(true));
996  AJAAncillaryList::SetFromDeviceAncBuffers (validAncF1, validAncF2, ancPackets, inFrameNum);
997  ancPackets.ParseAllAncillaryData();
998  }
999 
1000  if (NTV2_IS_VANCMODE_ON(mVancMode))
1001  { // Compare with what we got from VANC lines:
1002  NTV2StringList diffs;
1003  if (!ancPackets.CompareWithInfo (diffs, vancPackets, true/*ignoreLoc*/, false /*ignoreChksum*/))
1004  {
1005  NTV2StringList lines(aja::split(diffs.at(0), "\n")); // Only log first diff
1006  CAPDBG(DEC(diffs.size()) << " VANC/AncExt diff(s): " << lines.at(0));
1007  for (size_t n(1); n < lines.size(); n++)
1008  CAPDBG(lines.at(n));
1009  }
1010  }
1011  }
1012 
1013  // Get Line21 CC data...
1014  if (NTV2_IS_SD_VIDEO_FORMAT(inVideoFormat) && (mConfig.fPixelFormat == NTV2_FBF_8BIT_YCBCR || mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR))
1015  { // Anything encoded in Line 21?
1016  ULWord line21RowOffset(0);
1017  const UByte * pLine21(AJA_NULL);
1018  formatDesc.GetLineOffsetFromSMPTELine (21, line21RowOffset);
1019  pLine21 = AsConstUBytePtr(formatDesc.GetRowAddress(mInputXferInfo.acVideoBuffer.GetHostPointer(),
1020  line21RowOffset));
1021  if (pLine21)
1022  {
1023  if (mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR) // CNTV2Line21Captioner::DecodeLine requires 8-bit YUV
1024  ::ConvertLine_v210_to_2vuy(AsConstULWordPtr(pLine21), (UByte*)(pLine21), 720); // Convert YUV10 to YUV8 in-place
1025  captionDataL21.bGotField1Data = CNTV2Line21Captioner::DecodeLine(pLine21, captionDataL21.f1_char1, captionDataL21.f1_char2);
1026  }
1027  pLine21 = AsConstUBytePtr(formatDesc.GetRowAddress(mInputXferInfo.acVideoBuffer.GetHostPointer(),
1028  line21RowOffset+1)); // F2 should be on next row
1029  if (pLine21)
1030  {
1031  if (mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR) // CNTV2Line21Captioner::DecodeLine requires 8-bit YUV
1032  ::ConvertLine_v210_to_2vuy(AsConstULWordPtr(pLine21), (UByte*)(pLine21), 720); // Convert YUV10 to YUV8 in-place
1033  captionDataL21.bGotField2Data = CNTV2Line21Captioner::DecodeLine(pLine21, captionDataL21.f2_char1, captionDataL21.f2_char2);
1034  }
1035  }
1036 
1037  // Any 608 packets (anc extractor)?
1038  if (ancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea608_Vanc, 0)) // F1
1039  {
1041  if (pkt608F1.GetPayloadData() && pkt608F1.GetPayloadByteCount() && AJA_SUCCESS(pkt608F1.ParsePayloadData()))
1042  pkt608F1.GetCEA608Bytes (captionData608Anc.f1_char1, captionData608Anc.f1_char2, captionData608Anc.bGotField1Data);
1043  }
1044  if (ancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea608_Vanc, 1)) // F2
1045  {
1047  if (pkt608F2.GetPayloadData() && pkt608F2.GetPayloadByteCount() && AJA_SUCCESS(pkt608F2.ParsePayloadData()))
1048  pkt608F2.GetCEA608Bytes(captionData608Anc.f2_char1, captionData608Anc.f2_char2, captionData608Anc.bGotField2Data);
1049  }
1050 
1051  // Any 608 packets (Vanc)?
1053  {
1055  if (pkt608F1.GetPayloadData() && pkt608F1.GetPayloadByteCount() && AJA_SUCCESS(pkt608F1.ParsePayloadData()))
1056  pkt608F1.GetCEA608Bytes (captionData608Vanc.f1_char1, captionData608Vanc.f1_char2, captionData608Vanc.bGotField1Data);
1057  }
1059  {
1061  if (pkt608F2.GetPayloadData() && pkt608F2.GetPayloadByteCount() && AJA_SUCCESS(pkt608F2.ParsePayloadData()))
1062  pkt608F2.GetCEA608Bytes(captionData608Vanc.f2_char1, captionData608Vanc.f2_char2, captionData608Vanc.bGotField2Data);
1063  }
1064 
1065  // Any 708 packets (vanc)?
1067  {
1068  AJAAncillaryData vancCEA708DataIn (vancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea708));
1069  bool hasParityErrors (false);
1070  if (vancCEA708DataIn.GetPayloadData() && vancCEA708DataIn.GetPayloadByteCount() && AJA_SUCCESS(vancCEA708DataIn.ParsePayloadData()))
1071  if (m708DecoderVanc->SetSMPTE334AncData (vancCEA708DataIn.GetPayloadData(), vancCEA708DataIn.GetPayloadByteCount()))
1072  if (m708DecoderVanc->ParseSMPTE334AncPacket(hasParityErrors))
1073  {
1074  vector<UByte> svcBlk;
1075  size_t blkSize(0), byteCount(0);
1076  int svcNum(0);
1077  bool isExtendedSvc(false);
1078  if (!hasParityErrors)
1079  captionData708Vanc = m708DecoderVanc->GetCC608CaptionData();
1080  if (m708DecoderVanc->GetNextServiceBlockInfoFromQueue (NTV2_CC708PrimaryCaptionServiceNum, blkSize, byteCount, svcNum, isExtendedSvc))
1081  m708DecoderVanc->GetNextServiceBlockFromQueue(NTV2_CC708PrimaryCaptionServiceNum, svcBlk); // Pop queued service block
1082  }
1083  }
1084  // Any 708 packets (anc extractor)?
1086  {
1087  AJAAncillaryData ancCEA708DataIn (ancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea708));
1088  bool hasParityErrors (false);
1089  if (ancCEA708DataIn.GetPayloadData() && ancCEA708DataIn.GetPayloadByteCount() && AJA_SUCCESS(ancCEA708DataIn.ParsePayloadData()))
1090  if (m708DecoderAnc->SetSMPTE334AncData (ancCEA708DataIn.GetPayloadData(), ancCEA708DataIn.GetPayloadByteCount()))
1091  if (m708DecoderAnc->ParseSMPTE334AncPacket(hasParityErrors))
1092  {
1093  vector<UByte> svcBlk;
1094  size_t blkSize(0), byteCount(0);
1095  int svcNum(0);
1096  bool isExtendedSvc(false);
1097  if (!hasParityErrors)
1098  captionData708Anc = m708DecoderAnc->GetCC608CaptionData();
1099  if (m708DecoderAnc->GetNextServiceBlockInfoFromQueue (NTV2_CC708PrimaryCaptionServiceNum, blkSize, byteCount, svcNum, isExtendedSvc))
1100  m708DecoderAnc->GetNextServiceBlockFromQueue(NTV2_CC708PrimaryCaptionServiceNum, svcBlk); // Pop queued service block
1101  }
1102  }
1103  // Any "analog" packets?
1105  {
1107  if (AJA_SUCCESS(ancEIA608DataIn.ParsePayloadData()))
1108  ancEIA608DataIn.GetCEA608Bytes(captionDataL21Anc.f1_char1, captionDataL21Anc.f1_char2, captionDataL21Anc.bGotField1Data);
1110  {
1112  if (AJA_SUCCESS(ancEIA608F2.ParsePayloadData()))
1113  ancEIA608F2.GetCEA608Bytes(captionDataL21Anc.f2_char1, captionDataL21Anc.f2_char2, captionDataL21Anc.bGotField2Data);
1114  }
1115  }
1116 
1117  // Compare CaptionData results...
1118  ostringstream ossCompare;
1119  const CaptionData * p608CaptionData(AJA_NULL);
1120  if (NTV2_IS_SD_VIDEO_FORMAT(inVideoFormat))
1121  {
1122  const CaptionData * pL21CaptionData (AJA_NULL);
1123  if (captionDataL21.HasData() && captionDataL21Anc.HasData())
1124  if (captionDataL21 != captionDataL21Anc)
1125  ossCompare << "L21Vanc != L21Anlg: " << captionDataL21 << " " << captionDataL21Anc << endl;
1126  if (captionDataL21.HasData())
1127  pL21CaptionData = &captionDataL21;
1128  else if (captionDataL21Anc.HasData())
1129  pL21CaptionData = &captionDataL21Anc;
1130  if (captionData608Anc.HasData() && pL21CaptionData)
1131  if (captionData608Anc != *pL21CaptionData)
1132  ossCompare << "608 != L21: " << captionData608Anc << " " << *pL21CaptionData << endl;
1133  if (captionData608Anc.HasData())
1134  p608CaptionData = &captionData608Anc; // 608 anc has precedence
1135  else if (pL21CaptionData)
1136  p608CaptionData = pL21CaptionData; // followed by line 21
1137  }
1138  else
1139  {
1140  if (captionData608Anc.HasData() && captionData708Anc.HasData())
1141  if (captionData608Anc != captionData708Anc)
1142  ossCompare << "608anc != 708anc: " << captionData608Anc << " " << captionData708Anc << endl;
1143  if (captionData608Vanc.HasData() && captionData708Vanc.HasData())
1144  if (captionData608Vanc != captionData708Vanc)
1145  ossCompare << "608vanc != 708vanc: " << captionData608Vanc << " " << captionData708Vanc << endl;
1146  if (captionData708Anc.HasData())
1147  p608CaptionData = &captionData708Anc; // 608-in-708anc has highest precedence
1148  else if (captionData708Vanc.HasData())
1149  p608CaptionData = &captionData708Vanc; // followed by 608-in-708vanc
1150  else if (captionData608Anc.HasData())
1151  p608CaptionData = &captionData608Anc; // followed by 608anc
1152  else if (captionData608Vanc.HasData())
1153  p608CaptionData = &captionData608Vanc; // followed by 608vanc
1154  }
1155  if (!ossCompare.str().empty())
1156  CAPDBG("CaptionData mis-compare(s): " << ossCompare.str());
1157 
1158  // Set p608CaptionData based on mConfig.fCaptionSrc...
1159  switch (mConfig.fCaptionSrc)
1160  { // captionData708Anc, captionData708Vanc, captionData608Anc, captionData608Vanc, captionDataL21Anc, captionDataL21
1161  case kCaptionDataSrc_Line21: p608CaptionData = &captionDataL21Anc; break;
1162  case kCaptionDataSrc_608FBVanc: p608CaptionData = &captionDataL21; break;
1163  case kCaptionDataSrc_708FBVanc: p608CaptionData = &captionData708Vanc; break;
1164  case kCaptionDataSrc_608Anc: p608CaptionData = &captionData608Anc; break;
1165  case kCaptionDataSrc_708Anc: p608CaptionData = &captionData708Anc; break;
1166  default: break;
1167  }
1168 
1169  if (!p608CaptionData)
1170  return; // Got nothing
1171 
1172  // This demo only handles CEA-608 captions (no Teletext, IBU, etc.)
1173  // The 608 decoder expects to be called once per frame (to implement flashing characters, smooth-scroll roll-up, etc.).
1174  // Pass the caption byte pairs to it for processing (even if captionData.HasData returns false)...
1175  m608Decoder->ProcessNew608FrameData(*p608CaptionData);
1176 
1177  DoCCOutput(inFrameNum, *p608CaptionData, inVideoFormat);
1178 
1179 } // ExtractClosedCaptionData
1180 
1181 
1182 void NTV2CCGrabber::DoCCOutput (const uint32_t inFrameNum, const CaptionData & inCCData, const NTV2VideoFormat inVideoFormat)
1183 {
1184  // Print out the caption characters...
1185  const bool isFirstTime (mLastOutFrame == 0 && inFrameNum > mLastOutFrame);
1186  char char1(0), char2(0);
1187  const bool showField2 (IsField2Line21CaptionChannel(m608Channel));
1188  const bool gotData (showField2 ? inCCData.bGotField2Data : inCCData.bGotField1Data);
1189  switch (mConfig.fOutputMode)
1190  {
1192  if (gotData)
1193  { // Can't distinguish between CC1/CC2/Tx1/Tx2 for F1 (nor CC3/CC4/Tx3/Tx4 for F2).
1194  // They'll just have to be interspersed for now...
1195  char1 = (char(showField2 ? inCCData.f2_char1 : inCCData.f1_char1) & 0x7F);
1196  char2 = (char(showField2 ? inCCData.f2_char2 : inCCData.f1_char2) & 0x7F);
1197  if (char1 >= ' ' && char1 <= '~')
1198  {
1199  if (mLastOutStr != " " || char1 != ' ')
1200  {cout << char1 << flush; mLastOutStr = string(1,char1);}
1201  if (char2 >= ' ' && char2 <= '~')
1202  {
1203  if (mLastOutStr != " " || char2 != ' ')
1204  {cout << char2 << flush; mLastOutStr = string(1,char2);}
1205  }
1206  }
1207  else if (mLastOutStr != " ")
1208  {cout << " " << flush; mLastOutStr = " ";}
1209  }
1210  break;
1212  {
1213  if (inFrameNum == (mLastOutFrame+1))
1214  {
1215  mLastOutFrame = inFrameNum;
1216  if ((mLastOutFrame - mFirstOutFrame) < MAX_ACCUM_FRAME_COUNT)
1217  break; // Don't spew yet -- keep going
1218  }
1219  const string currentScreen(m608Decoder->GetOnAirCharacters());
1220  if (currentScreen != mLastOutStr)
1221  cout << currentScreen << endl;
1222  mLastOutStr = currentScreen;
1223  mFirstOutFrame = mLastOutFrame = inFrameNum;
1224  break;
1225  }
1227  {
1228  uint16_t u16(uint16_t(uint16_t(showField2 ? inCCData.f2_char1 : inCCData.f1_char1) << 8) | uint16_t(showField2 ? inCCData.f2_char2 : inCCData.f1_char2));
1229  ostringstream oss;
1230  oss << Hex0N(u16,4);
1231  mLastOutStr.append(mLastOutStr.empty() ? "\t" : " ");
1232  mLastOutStr.append(oss.str());
1233  if (inFrameNum == (mLastOutFrame+1))
1234  { // Save for later
1235  mLastOutFrame = inFrameNum;
1236  if ((mLastOutFrame - mFirstOutFrame) < MAX_ACCUM_FRAME_COUNT)
1237  break; // Don't spew yet -- keep going
1238  }
1239  if (isFirstTime)
1240  cout << "Scenarist_SCC V1.0" << endl;
1241 
1242  string tcStr;
1243  AJATimeCode tcFirst(mFirstOutFrame);
1245  tcFirst.QueryString(tcStr, tcBase, false);
1246  cout << endl << tcStr << ":" << mLastOutStr << endl;
1247  mFirstOutFrame = mLastOutFrame = inFrameNum;
1248  mLastOutStr.clear();
1249  break;
1250  }
1251  case kOutputMode_Stats:
1252  if (inFrameNum % 60 == 0) // Every 60 frames
1253  {
1254  CNTV2CaptionDecodeChannel608Ptr chDecoder (m608Decoder->Get608ChannelDecoder(m608Decoder->GetDisplayChannel()));
1255  if (chDecoder)
1256  {
1257  const vector<uint32_t> stats (chDecoder->GetStats());
1258  AJALabelValuePairs info;
1260  for (size_t num(0); num < stats.size(); num++)
1261  {
1263  if (title.empty())
1264  break;
1265  if (!stats[num])
1266  continue;
1267  ostringstream oss; oss << DEC(stats[num]);
1268  AJASystemInfo::append(info, title, oss.str());
1269  }
1270  cout << AJASystemInfo::ToString(info) << endl;
1271  }
1272  }
1273  break;
1274  default: break;
1275  }
1276 } // DoCCOutput
1277 
1278 
1280 
1281 
1282 static const UWord gMixerNums [] = {0, 0, 1, 1, 2, 2, 3, 3};
1283 
1284 
1286 {
1287  NTV2_ASSERT (mConfig.fBurnCaptions); // Must be burning captions
1288 
1289  // Configure the output FrameStore...
1290  mDevice.EnableChannel (mOutputChannel);
1291  mDevice.SetMode (mOutputChannel, NTV2_MODE_DISPLAY);
1292  mDevice.SetFrameBufferFormat (mOutputChannel, mPlayoutFBF);
1293  mDevice.SetVideoFormat (inVideoFormat, /*retailMode?*/false, /*keepVANC?*/false, /*channel*/mOutputChannel);
1294  mDevice.SetEnableVANCData(NTV2_IS_VANCMODE_TALL(mVancMode), NTV2_IS_VANCMODE_TALLER(mVancMode), mOutputChannel);
1295 
1296  // RGB: Set up mixer to "mix" mode, FG raster "unshaped", BG raster "full raster" and VANC pass-thru from BG...
1297  const UWord mixerNumber (gMixerNums[mOutputChannel]);
1298  mDevice.SetMixerMode (mixerNumber, NTV2MIXERMODE_FOREGROUND_ON);
1301  mDevice.SetMixerVancOutputFromForeground (mixerNumber, false); // false means "use BG VANC, not FG"
1302  cerr << "## NOTE: Caption burn-in using mixer/keyer " << (mixerNumber+1) << " on " << ::NTV2ChannelToString(mOutputChannel)
1303  << ", " << ::NTV2FrameBufferFormatToString(mPlayoutFBF)
1304  << ", " << ::NTV2VideoFormatToString(inVideoFormat) << endl;
1305 
1306  return AJA_STATUS_SUCCESS;
1307 
1308 } // SetupOutputVideo
1309 
1310 
1312 {
1313  NTV2_ASSERT (mConfig.fBurnCaptions); // Must be burning captions
1314  const NTV2OutputCrosspointID frameStoreOutputRGB (::GetFrameBufferOutputXptFromChannel (mOutputChannel, true)); // true=RGB
1315  const NTV2OutputCrosspointID cscOutputYUV (::GetCSCOutputXptFromChannel (mOutputChannel));
1316  const NTV2OutputCrosspointID cscOutputKey (::GetCSCOutputXptFromChannel (mOutputChannel, true)); // true=key
1317  const NTV2OutputCrosspointID mixerOutputYUV (::GetMixerOutputXptFromChannel (mOutputChannel));
1319  const NTV2Standard outputStandard (::GetNTV2StandardFromVideoFormat (inVideoFormat));
1320  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1321  UWord connectFailures (0);
1322 
1323  if (mConfig.fDoMultiFormat)
1324  {
1325  // Multiformat --- route the one SDI output to the mixer's YUV output, and set its output standard...
1326  if (mDevice.features().HasBiDirectionalSDI())
1327  mDevice.SetSDITransmitEnable (mOutputChannel, true);
1328  if (mDevice.features().CanDoWidget(g3GSDIOutputs[mOutputChannel]) || mDevice.features().CanDoWidget(gSDIOutputs[mOutputChannel]))
1329  {
1330  if (!mDevice.Connect (::GetSDIOutputInputXpt(mOutputChannel), mixerOutputYUV, canVerify)) connectFailures++;
1331  mDevice.SetSDIOutputStandard (mOutputChannel, outputStandard);
1332  }
1333  }
1334  else
1335  {
1336  // If not multiformat: Route all SDI outputs to the mixer's YUV output...
1337  const ULWord numVideoOutputs (mDevice.features().GetNumVideoOutputs());
1338  const NTV2Channel startNum (NTV2_CHANNEL1);
1339  const NTV2Channel endNum (NTV2_CHANNEL_INVALID);
1340  const NTV2Channel sdiInputAsChan (::NTV2InputSourceToChannel(mConfig.fInputSource));
1341 
1342  for (NTV2Channel chan(startNum); chan < endNum; chan = NTV2Channel(chan + 1))
1343  {
1344  if (ULWord(chan) >= numVideoOutputs)
1345  break;
1346  if (mDevice.features().HasBiDirectionalSDI())
1347  {
1348  if (chan == sdiInputAsChan)
1349  continue; // Skip the input
1350  mDevice.SetSDITransmitEnable (chan, true);
1351  }
1352  if (mDevice.features().CanDoWidget(g3GSDIOutputs[chan]) || mDevice.features().CanDoWidget(gSDIOutputs[chan]))
1353  {
1354  if (!mDevice.Connect (::GetSDIOutputInputXpt(chan), mixerOutputYUV, canVerify)) connectFailures++;
1355  mDevice.SetSDIOutputStandard (chan, outputStandard);
1356  }
1357  } // for each output spigot
1358  }
1359 
1360  // Connect CSC video input to frame buffer's RGB output:
1361  if (!mDevice.Connect (::GetCSCInputXptFromChannel(mOutputChannel), frameStoreOutputRGB, canVerify)) connectFailures++;
1362  // Connect mixer's foreground video input to the CSC's YUV video output:
1363  if (!mDevice.Connect (::GetMixerFGInputXpt(mOutputChannel), cscOutputYUV, canVerify)) connectFailures++;
1364  // Connect mixer's foreground key input to the CSC's YUV key output:
1365  if (!mDevice.Connect (::GetMixerFGInputXpt(mOutputChannel, true), cscOutputKey, canVerify)) connectFailures++;
1366  // Connect mixer's background video input to the SDI input:
1367  if (!mDevice.Connect (::GetMixerBGInputXpt(mOutputChannel), signalInput, canVerify)) connectFailures++;
1368 
1369  if (!mConfig.fDoMultiFormat)
1370  {
1371  // Connect more outputs -- HDMI, analog, SDI monitor, etc... (Don't bother to verify these connections)
1372  if (mDevice.features().CanDoWidget(NTV2_WgtHDMIOut1))
1373  mDevice.Connect (NTV2_XptHDMIOutInput, mixerOutputYUV);
1374  if (mDevice.features().CanDoWidget(NTV2_WgtHDMIOut1v2))
1375  mDevice.Connect (NTV2_XptHDMIOutQ1Input, mixerOutputYUV);
1376  if (mDevice.features().CanDoWidget(NTV2_WgtAnalogOut1))
1377  mDevice.Connect (NTV2_XptAnalogOutInput, mixerOutputYUV);
1378  if (mDevice.features().CanDoWidget(NTV2_WgtSDIMonOut1))
1379  mDevice.Connect (::GetSDIOutputInputXpt (NTV2_CHANNEL5), mixerOutputYUV);
1380  }
1381  return connectFailures == 0;
1382 
1383 } // RouteOutputSignal
1384 
1385 
1386 // Starts the play thread
1388 {
1389  // Create and start the playout thread...
1390  NTV2_ASSERT(mConfig.fBurnCaptions);
1391  AJAStatus result (mPlayoutThread.Attach(PlayThreadStatic, this));
1392  if (AJA_SUCCESS(result))
1393  result = mPlayoutThread.SetPriority(AJA_ThreadPriority_High);
1394  if (AJA_SUCCESS(result))
1395  result = mPlayoutThread.Start();
1396  return result;
1397 
1398 } // StartPlayThread
1399 
1400 
1401 // The playout thread function
1402 void NTV2CCGrabber::PlayThreadStatic (AJAThread * pThread, void * pContext) // static
1403 {
1404  (void) pThread;
1405  // Grab the NTV2Burn instance pointer from the pContext parameter,
1406  // then call its PlayFrames method...
1407  NTV2CCGrabber * pApp (reinterpret_cast <NTV2CCGrabber *> (pContext));
1408  pApp->PlayFrames ();
1409 
1410 } // PlayThreadStatic
1411 
1412 
1414 {
1415  const NTV2VideoFormat videoFormat (mDevice.GetInputVideoFormat(mConfig.fInputSource));
1417  ULWord fbNum (10); // Bounce between frames 10 & 11
1418  const string indicators [] = {"/", "-", "\\", "|", ""};
1419  AUTOCIRCULATE_STATUS acStatus;
1420 
1421  CAPNOTE("Thread started");
1422  SetupOutputVideo (videoFormat); // Set up device output
1423  RouteOutputSignal (videoFormat); // Set up output signal routing
1424  mDevice.GetVANCMode (vancMode, mConfig.fInputChannel);
1425  if (mDevice.AutoCirculateInitForOutput (mOutputChannel, 2) && mDevice.AutoCirculateGetStatus (mOutputChannel, acStatus)) // Find out which buffers we got
1426  fbNum = ULWord(acStatus.acStartFrame); // Use them
1427  else if (mDevice.AutoCirculateGetStatus(mConfig.fInputChannel, acStatus)) // Use the frame just past the last input A/C frame
1428  fbNum = ULWord(acStatus.GetEndFrame()) + 1;
1429 
1430  const NTV2FormatDesc formatDesc (videoFormat, mPlayoutFBF, vancMode);
1431  const uint32_t bufferSizeBytes (formatDesc.GetTotalRasterBytes ());
1432  const uint32_t activeSizeBytes (formatDesc.GetVisibleRasterBytes ());
1433  ULWord pingPong (0); // Bounce between 0 and 1
1434  UWord consecSyncErrs (0);
1435  // Caption status head-up-display...
1436  static uint64_t frameTally (0);
1437  const string strVideoFormat (CNTV2DemoCommon::StripFormatString (::NTV2VideoFormatToString (videoFormat)));
1438  ULWord lastErrorTally (0);
1439 
1440  // Allocate host frame buffer for blitting captions into...
1441  NTV2Buffer hostBuffer;
1442  if (!hostBuffer.Allocate(bufferSizeBytes, /*pageAligned*/true))
1443  {cerr << "## NOTE: Caption burn-in failed -- unable to allocate " << bufferSizeBytes << "-byte caption video buffer" << endl; return;}
1444  NTV2Buffer visibleRgn (formatDesc.GetTopVisibleRowAddress(AsUBytePtr(hostBuffer.GetHostPointer())),activeSizeBytes);
1445 
1446  // Clear both device ping/pong buffers to fully transparent, all black...
1447  hostBuffer.Fill(ULWord(0));
1448  mDevice.DMAWriteFrame (fbNum + 0, AsULWordPtr(hostBuffer.GetHostPointer()), bufferSizeBytes);
1449  mDevice.DMAWriteFrame (fbNum + 1, AsULWordPtr(hostBuffer.GetHostPointer()), bufferSizeBytes);
1450  mDevice.SetOutputFrame (mOutputChannel, fbNum + pingPong);
1451  pingPong = pingPong ? 0 : 1;
1452 
1453  // Do forever (until Quit)...
1454  while (!mGlobalQuit)
1455  {
1456  // Wait for the next frame to become ready to "consume"...
1457  NTV2FrameData * pFrameData(mCircularBuffer.StartConsumeNextBuffer());
1458  if (pFrameData)
1459  {
1460  // "Burn" captions into the host buffer before it gets sent to the AJA device...
1461  m608Decoder->BurnCaptions (hostBuffer, formatDesc);
1462  m608Decoder->IdleFrame(); // This is needed for captions that flash/blink
1463 
1464  if (mHeadUpDisplayOn)
1465  {
1466  ostringstream oss;
1467  const string strCaptionChan (::NTV2Line21ChannelToStr(NTV2_IS_HD_VIDEO_FORMAT(videoFormat)
1468  ? m708DecoderAnc->GetDisplayChannel()
1469  : m608Decoder->GetDisplayChannel()));
1470  oss << indicators [mCaptionDataTally % 4] << " " << strCaptionChan << " " << frameTally++ << " "
1471  << formatDesc.GetRasterWidth() << "x" << formatDesc.GetFullRasterHeight() << (mConfig.fUseVanc ? "v" : " ") << strVideoFormat;
1472 
1473  const ULWord newErrorTally (mErrorTally);
1474  const NTV2Line21Attributes & color (lastErrorTally != newErrorTally ? kRedOnTransparentBG : kGreenOnTransparentBG);
1475  CNTV2CaptionRenderer::BurnString (oss.str(), color, hostBuffer, formatDesc, 7, 1);
1476  lastErrorTally = newErrorTally;
1477 
1478  if (!pFrameData->fTimecodes.empty())
1479  {
1480  const NTV2_RP188 & tc (pFrameData->fTimecodes.begin()->second);
1481  if (tc.IsValid() && tc.fDBB & BIT(16)) // Bit 16 will be set if this frame had timecode
1482  {
1483  CRP188 rp188(tc);
1484  CNTV2CaptionRenderer::BurnString (rp188.GetRP188CString(), kGreenOnTransparentBG, hostBuffer, formatDesc, 8, 1);
1485  }
1486  }
1487  }
1488 
1489  // Transfer the caption raster to the device, then ping-pong it into the mixer foreground...
1490  mDevice.DMAWriteFrame (fbNum + pingPong, AsULWordPtr(visibleRgn.GetHostPointer()), activeSizeBytes);
1491  mDevice.SetOutputFrame (mOutputChannel, fbNum + pingPong); // Toggle device frame buffer
1492  pingPong = pingPong ? 0 : 1; // Switch device frame numbers for next time
1493  visibleRgn.Fill(ULWord(0)); // Clear visible region of host buffer to fully-transparent, all-black again
1494 
1495  // Signal that the frame has been "consumed"...
1496  mCircularBuffer.EndConsumeNextBuffer ();
1497 
1498  // Check for format change...
1499  if (videoFormat != mDevice.GetInputVideoFormat(mConfig.fInputSource))
1500  {
1501  cerr << "## NOTE: Caption burn-in stopped due to video format change -- was " << strVideoFormat
1502  << ", now " << ::NTV2VideoFormatToString (mDevice.GetInputVideoFormat(mConfig.fInputSource)) << endl;
1503  m608Decoder->Reset(); // Don't leave captions from old video stream on-screen
1504  m708DecoderAnc->Reset();
1505  m708DecoderVanc->Reset();
1506  break;
1507  }
1508 
1509  // Check mixer sync...
1510  bool mixerSyncOK (false);
1511  mDevice.GetMixerSyncStatus (gMixerNums[mOutputChannel], mixerSyncOK);
1512  if (mixerSyncOK)
1513  consecSyncErrs = 0;
1514  else if (++consecSyncErrs > 60) // Bail if lack of mixer sync for longer than ~1 sec
1515  {cerr << "#MXSYNC#"; consecSyncErrs = 0;} // break;}
1516  } // if pPlayData
1517  } // loop til quit signaled
1518 
1519  if (mDevice.AutoCirculateGetStatus (mOutputChannel, acStatus) && !acStatus.IsStopped())
1520  mDevice.AutoCirculateStop(mOutputChannel);
1521  CAPNOTE("Thread completed, will exit");
1522 
1523 } // PlayFrames
1524 
1525 
1527 {
1528  if (m608Channel != inNewChannel)
1529  {
1530  m608Channel = inNewChannel;
1531  if (m608Decoder)
1532  m608Decoder->SetDisplayChannel(m608Channel);
1533  if (m708DecoderAnc)
1534  m708DecoderAnc->SetDisplayChannel(m608Channel);
1535  if (m708DecoderVanc)
1536  m708DecoderVanc->SetDisplayChannel(m608Channel);
1537  cerr << endl << "## NOTE: Caption display channel changed to '" << ::NTV2Line21ChannelToStr(m608Channel) << "'" << endl;
1538  }
1539 }
1540 
1541 
1543 { (void) inChangeInfo;
1544  mCaptionDataTally++;
1545 }
1546 
1547 
1548 void NTV2CCGrabber::Caption608ChangedStatic (void * pInstance, const NTV2Caption608ChangeInfo & inChangeInfo) // STATIC
1549 {
1550  NTV2CCGrabber * pGrabber(reinterpret_cast<NTV2CCGrabber*>(pInstance));
1551  if (pGrabber)
1552  pGrabber->CaptioningChanged(inChangeInfo);
1553 }
1554 
1555 
1556 string NTV2CCGrabber::GetLine21ChannelNames (string inDelimiterStr) // static
1557 {
1558  string result;
1559  for (unsigned enumVal(0); enumVal < NTV2_CC608_ChannelMax; )
1560  {
1561  result += ::NTV2Line21ChannelToStr (NTV2Line21Channel(enumVal++));
1562  if (enumVal < NTV2_CC608_ChannelMax)
1563  result += inDelimiterStr;
1564  else
1565  break;
1566  }
1567  return result;
1568 
1569 } // GetLine21ChannelNames
1570 
1571 AJALabelValuePairs CCGrabberConfig::Get (const bool inCompact) const
1572 {
1573  AJALabelValuePairs result (CaptureConfig::Get(inCompact));
1574  AJASystemInfo::append(result, "Output Mode", IS_VALID_OutputMode(fOutputMode) ? OutputModeToString(fOutputMode) : "(invalid)");
1576  AJASystemInfo::append(result, "Timecode Source", ::NTV2TCIndexToString(fTimecodeSrc, inCompact));
1577  AJASystemInfo::append(result, "Caption Channel", ::NTV2Line21ChannelToStr(fCaptionChannel, inCompact));
1578  AJASystemInfo::append(result, "Burn-In Captions", fBurnCaptions ? "Y" : "N");
1579  AJASystemInfo::append(result, "MultiFormat Mode", fDoMultiFormat ? "Y" : "N");
1580  AJASystemInfo::append(result, "Use Vanc", fUseVanc ? "Y" : "N");
1581  return result;
1582 }
1583 
1584 
1586 {
1587  string result;
1589  {
1590  result += OutputModeToString(mode);
1591  mode = OutputMode(mode+1);
1592  if (mode < kOutputMode_INVALID)
1593  result += ",";
1594  }
1595  return result;
1596 }
1597 
1599 {
1600  static const string gModeStrs[] = {"stream","screen","scc","mcc","stats",""};
1601  if (IS_VALID_OutputMode(inMode))
1602  return gModeStrs[inMode];
1603  string result;
1604  for (unsigned ndx(0); ndx < 5; )
1605  {
1606  result += gModeStrs[ndx];
1607  if (!(gModeStrs[++ndx].empty()))
1608  result += "|";
1609  }
1610  return result;
1611 }
1612 
1614 {
1615  typedef pair<string,OutputMode> StringToOutputModePair;
1616  typedef map<string,OutputMode> StringToOutputModeMap;
1617  typedef StringToOutputModeMap::const_iterator StringToOutputModeConstIter;
1618  static StringToOutputModeMap sStringToOutputModeMap;
1619  static AJALock sStringToOutputModeMapLock;
1620  if (sStringToOutputModeMap.empty())
1621  {
1622  AJAAutoLock autoLock(&sStringToOutputModeMapLock);
1624  {
1625  string outputModeStr (OutputModeToString(om));
1626  aja::lower(outputModeStr);
1627  sStringToOutputModeMap.insert(StringToOutputModePair(outputModeStr,om));
1628  }
1629  }
1630  string modeStr(inModeStr);
1631  aja::lower(aja::strip(modeStr));
1632  StringToOutputModeConstIter iter(sStringToOutputModeMap.find(modeStr));
1633  return iter != sStringToOutputModeMap.end() ? iter->second : kOutputMode_INVALID;
1634 }
1635 
1637 {
1638  string result;
1640  {
1641  result += CaptionDataSrcToString(src);
1642  src = CaptionDataSrc(src+1);
1643  if (src < kCaptionDataSrc_INVALID)
1644  result += ",";
1645  }
1646  return result;
1647 }
1648 
1650 {
1651  static const string gSrcStrs[] = {"default","line21","608vanc","708vanc","608anc","708anc",""};
1652  if (IS_VALID_CaptionDataSrc(inDataSrc))
1653  return gSrcStrs[inDataSrc];
1654  string result;
1655  for (unsigned ndx(0); ndx < 6; )
1656  {
1657  result += gSrcStrs[ndx];
1658  if (!gSrcStrs[++ndx].empty())
1659  result += "|";
1660  }
1661  return result;
1662 }
1663 
1665 {
1666  typedef pair<string,CaptionDataSrc> StringToCaptionDataSrcPair;
1667  typedef map<string,CaptionDataSrc> StringToCaptionDataSrcMap;
1668  typedef StringToCaptionDataSrcMap::const_iterator StringToCaptionDataSrcConstIter;
1669  static StringToCaptionDataSrcMap sStringToCaptionDataSrcMap;
1670  static AJALock sStringToCaptionDataSrcMapLock;
1671  if (sStringToCaptionDataSrcMap.empty())
1672  {
1673  AJAAutoLock autoLock(&sStringToCaptionDataSrcMapLock);
1675  {
1676  string captionDataSrcStr (CaptionDataSrcToString(cds));
1677  aja::lower(captionDataSrcStr);
1678  sStringToCaptionDataSrcMap.insert(StringToCaptionDataSrcPair(captionDataSrcStr,cds));
1679  }
1680  }
1681  string cdsStr(inDataSrcStr);
1682  aja::lower(aja::strip(cdsStr));
1683  StringToCaptionDataSrcConstIter iter(sStringToCaptionDataSrcMap.find(cdsStr));
1684  return iter != sStringToCaptionDataSrcMap.end() ? iter->second : kCaptionDataSrc_INVALID;
1685 }
1686 
1687 
1688 std::ostream & operator << (std::ostream & ioStrm, const CCGrabberConfig & inObj)
1689 {
1690  ioStrm << AJASystemInfo::ToString(inObj.Get());
1691  return ioStrm;
1692 }
AUTOCIRCULATE_TRANSFER::acFrameBufferFormat
NTV2FrameBufferFormat acFrameBufferFormat
Specifies the frame buffer format to change to. Ignored if AUTOCIRCULATE_WITH_FBFCHANGE option is not...
Definition: ntv2publicinterface.h:8040
CNTV2Card::SetVANCMode
virtual bool SetVANCMode(const NTV2VANCMode inVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Sets the VANC mode for the given FrameStore.
Definition: ntv2register.cpp:2640
CaptureConfig::fDoMultiFormat
bool fDoMultiFormat
If true, use multi-format/multi-channel mode, if device supports it; otherwise normal mode.
Definition: ntv2democommon.h:276
AsULWordPtr
#define AsULWordPtr(__p__)
Definition: ntv2ccgrabber.cpp:30
NTV2InputSourceToReferenceSource
NTV2ReferenceSource NTV2InputSourceToReferenceSource(const NTV2InputSource inInputSource)
Converts a given NTV2InputSource to its equivalent NTV2ReferenceSource value.
Definition: ntv2utils.cpp:5081
NTV2_CC608_Blue
@ NTV2_CC608_Blue
Definition: ntv2caption608types.h:157
NTV2ChannelSetToStr
std::string NTV2ChannelSetToStr(const NTV2ChannelSet &inObj, const bool inCompact=true)
Definition: ntv2publicinterface.cpp:3351
CNTV2Card::SetMultiFormatMode
virtual bool SetMultiFormatMode(const bool inEnable)
Enables or disables multi-format (per channel) device operation. If enabled, each device channel can ...
Definition: ntv2register.cpp:4379
CCGrabberConfig::fTimecodeSrc
NTV2TCIndex fTimecodeSrc
Timecode source to use (if any)
Definition: ntv2ccgrabber.h:67
NTV2_XptHDMIOutInput
@ NTV2_XptHDMIOutInput
Definition: ntv2enums.h:2793
GetSDIOutputInputXpt
NTV2InputXptID GetSDIOutputInputXpt(const NTV2Channel inSDIOutput, const bool inIsDS2=false)
Definition: ntv2signalrouter.cpp:942
CCGrabberConfig::StringToOutputMode
static OutputMode StringToOutputMode(const std::string &inModeStr)
Definition: ntv2ccgrabber.cpp:1613
NTV2ChannelToInputSource
NTV2InputSource NTV2ChannelToInputSource(const NTV2Channel inChannel, const NTV2IOKinds inKinds=NTV2_IOKINDS_SDI)
Definition: ntv2utils.cpp:5190
NTV2CCGrabber::SetupAudio
virtual AJAStatus SetupAudio(void)
Sets up audio for capture (and playout, if burning captions).
Definition: ntv2ccgrabber.cpp:338
NTV2InputSourceToChannel
NTV2Channel NTV2InputSourceToChannel(const NTV2InputSource inInputSource)
Converts a given NTV2InputSource to its equivalent NTV2Channel value.
Definition: ntv2utils.cpp:5105
NTV2_IS_SD_VIDEO_FORMAT
#define NTV2_IS_SD_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:707
DeviceCapabilities::CanDoVideoFormat
bool CanDoVideoFormat(const NTV2VideoFormat inVF)
Definition: ntv2devicecapabilities.h:251
NTV2_IS_VANCMODE_TALLER
#define NTV2_IS_VANCMODE_TALLER(__v__)
Definition: ntv2enums.h:3726
NTV2_FBF_ARGB
@ NTV2_FBF_ARGB
See 8-Bit ARGB, RGBA, ABGR Formats.
Definition: ntv2enums.h:212
AsUBytePtr
#define AsUBytePtr(__p__)
Definition: ntv2ccgrabber.cpp:31
GetSDIInputOutputXptFromChannel
NTV2OutputXptID GetSDIInputOutputXptFromChannel(const NTV2Channel inSDIInput, const bool inIsDS2=false)
Definition: ntv2signalrouter.cpp:893
AUTOCIRCULATE_TRANSFER::GetTransferStatus
const AUTOCIRCULATE_TRANSFER_STATUS & GetTransferStatus(void) const
Returns a constant reference to my AUTOCIRCULATE_TRANSFER_STATUS.
Definition: ntv2publicinterface.h:8324
AJATimeCode::QueryString
void QueryString(std::string &str, const AJATimeBase &timeBase, bool bDropFrame)
Definition: timecode.cpp:225
NTV2_AUDIO_LOOPBACK_OFF
@ NTV2_AUDIO_LOOPBACK_OFF
Embeds silence (zeroes) into the data stream.
Definition: ntv2enums.h:1975
GetMixerFGInputXpt
NTV2InputXptID GetMixerFGInputXpt(const NTV2Channel inChannel, const bool inIsKey=false)
Definition: ntv2signalrouter.cpp:968
NTV2ChannelListToStr
std::string NTV2ChannelListToStr(const NTV2ChannelList &inObj, const bool inCompact=true)
Definition: ntv2publicinterface.cpp:3330
NTV2_CHANNEL8
@ NTV2_CHANNEL8
Specifies channel or Frame Store 8 (or the 8th item).
Definition: ntv2enums.h:1314
NTV2MIXERINPUTCONTROL_UNSHAPED
@ NTV2MIXERINPUTCONTROL_UNSHAPED
Definition: ntv2enums.h:1725
NTV2_WgtSDIOut2
@ NTV2_WgtSDIOut2
Definition: ntv2enums.h:2866
AJAAncDataType_Cea608_Vanc
@ AJAAncDataType_Cea608_Vanc
CEA608 SD Closed Captioning (SMPTE 334 VANC packet)
Definition: ancillarydata.h:51
CAPDBG
#define CAPDBG(_expr_)
Definition: ntv2democommon.h:30
NTV2_FOURCC
#define NTV2_FOURCC(_a_, _b_, _c_, _d_)
Definition: ntv2publicinterface.h:5444
NTV2_CHANNEL2
@ NTV2_CHANNEL2
Specifies channel or Frame Store 2 (or the 2nd item).
Definition: ntv2enums.h:1308
AJA_ThreadPriority_High
@ AJA_ThreadPriority_High
Definition: thread.h:44
NTV2ACFrameRange::firstFrame
UWord firstFrame(void) const
Definition: ntv2utils.h:975
NTV2_WgtSDIMonOut1
@ NTV2_WgtSDIMonOut1
Definition: ntv2enums.h:2909
CNTV2CaptionDecoder708::Create
static bool Create(CNTV2CaptionDecoder708Ptr &outDecoder)
Creates a new CNTV2CaptionEncoder708 instance.
CNTV2Card::SetVideoFormat
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.
Definition: ntv2register.cpp:204
AUTOCIRCULATE_TRANSFER_STATUS::GetProcessedFrameCount
ULWord GetProcessedFrameCount(void) const
Definition: ntv2publicinterface.h:7923
ancillarydata_cea608_line21.h
Declares the AJAAncillaryData_Cea608_line21 class.
CNTV2Card::Set4kSquaresEnable
virtual bool Set4kSquaresEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 "2K quadrants" mode for the given FrameStore bank on the device....
Definition: ntv2register.cpp:1238
GetDLInInputXptFromChannel
NTV2InputXptID GetDLInInputXptFromChannel(const NTV2Channel inChannel, const bool inLinkB=false)
Definition: ntv2signalrouter.cpp:796
ntv2transcode.h
Declares a number of pixel format transcoder functions.
CCGrabberConfig::fOutputMode
OutputMode fOutputMode
Desired output (captionStream, Screen etc)
Definition: ntv2ccgrabber.h:65
ntv2ccgrabber.h
Header file for NTV2CCGrabber demonstration class.
CaptionData::f2_char1
UByte f2_char1
Caption Byte 1 of Field 2.
Definition: ntv2caption608types.h:662
ntv2line21captioner.h
Declares the CNTV2Line21Captioner class.
NTV2_AUDIO_BUFFER_BIG
@ NTV2_AUDIO_BUFFER_BIG
Definition: ntv2enums.h:1864
CNTV2Card::GetVPIDValidA
virtual bool GetVPIDValidA(const NTV2Channel inChannel)
Definition: ntv2regvpid.cpp:50
AJAAncillaryData_Cea608::GetCEA608Bytes
virtual AJAStatus GetCEA608Bytes(uint8_t &outByte1, uint8_t &outByte2, bool &outIsValid) const
Answers with the CEA608 payload bytes.
Definition: ancillarydata_cea608.cpp:89
CCGrabberConfig::fCaptionChannel
NTV2Line21Channel fCaptionChannel
Caption channel to monitor (defaults to CC1)
Definition: ntv2ccgrabber.h:68
NTV2FormatDescriptor
Describes a video frame for a given video standard or format and pixel format, including the total nu...
Definition: ntv2formatdescriptor.h:41
NTV2_IS_FBF_PLANAR
#define NTV2_IS_FBF_PLANAR(__s__)
Definition: ntv2enums.h:255
aja::strip
std::string & strip(std::string &str, const std::string &ws)
Definition: common.cpp:461
kCaptionDataSrc_608FBVanc
@ kCaptionDataSrc_608FBVanc
Definition: ntv2ccgrabber.h:49
types.h
Declares common types used in the ajabase library.
NTV2FormatDescriptor::GetRowAddress
const void * GetRowAddress(const void *pInStartAddress, const ULWord inRowIndex0, const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.cpp:997
NTV2FrameData
I encapsulate the video, audio and anc host buffers used in the AutoCirculate demos....
Definition: ntv2democommon.h:79
NTV2CCGrabber::SetOutputStandards
virtual void SetOutputStandards(const NTV2VideoFormat inVideoFormat)
Sets the device output standard based on the given video format.
Definition: ntv2ccgrabber.cpp:584
Is8BitFrameBufferFormat
bool Is8BitFrameBufferFormat(const NTV2FrameBufferFormat fbFormat)
Definition: ntv2utils.cpp:5484
CNTV2Card::GetMixerSyncStatus
virtual bool GetMixerSyncStatus(const UWord inWhichMixer, bool &outIsSyncOK)
Returns the current sync state of the given mixer/keyer.
Definition: ntv2register.cpp:2962
CNTV2DemoCommon::GetTSIMuxesForFrameStore
static NTV2ChannelList GetTSIMuxesForFrameStore(CNTV2Card &inDevice, const NTV2Channel in1stFrameStore, const UWord inCount)
Definition: ntv2democommon.cpp:1182
NTV2CCGrabber::ExtractClosedCaptionData
virtual void ExtractClosedCaptionData(const uint32_t inFrameCount, const NTV2VideoFormat inVideoFormat)
Extracts closed-caption data, if present, and emits it on a character-by-character basis to the stand...
Definition: ntv2ccgrabber.cpp:976
AJAAncillaryList::SetFromDeviceAncBuffers
static AJAStatus SetFromDeviceAncBuffers(const NTV2Buffer &inF1AncBuffer, const NTV2Buffer &inF2AncBuffer, AJAAncillaryList &outPackets, const uint32_t inFrameNum=0)
Returns all ancillary data packets found in the given F1 and F2 ancillary data buffers.
Definition: ancillarylist.cpp:1076
NTV2Channel
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They're also commonly use...
Definition: ntv2enums.h:1305
NTV2Buffer
A generic user-space buffer object that has an address and a length. Used most often to share an arbi...
Definition: ntv2publicinterface.h:5993
IsField2Line21CaptionChannel
#define IsField2Line21CaptionChannel(_chan_)
Definition: ntv2caption608types.h:107
AUTOCIRCULATE_STATUS::acStartFrame
LWord acStartFrame
First frame to circulate. FIXFIXFIX Why is this signed? CHANGE TO ULWord??
Definition: ntv2publicinterface.h:7164
AJA_STATUS_SUCCESS
@ AJA_STATUS_SUCCESS
Definition: types.h:381
AJARefPtr
I am a reference-counted pointer template class. I am intended to be a proxy for an underlying object...
Definition: ajarefptr.h:89
aja::split
void split(const std::string &str, const char delim, std::vector< std::string > &elems)
Definition: common.cpp:350
MAX_ACCUM_FRAME_COUNT
static const uint32_t MAX_ACCUM_FRAME_COUNT(30)
NTV2_ASSERT
#define NTV2_ASSERT(_expr_)
Definition: ajatypes.h:506
GetNTV2FrameRateFromVideoFormat
NTV2FrameRate GetNTV2FrameRateFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:3530
CNTV2VPID::MakeInvalid
virtual CNTV2VPID & MakeInvalid(void)
Definition: ntv2vpid.h:102
AJAAncillaryData_Cea608_Line21
This class handles "analog" (Line 21) based CEA-608 caption data packets.
Definition: ancillarydata_cea608_line21.h:27
NTV2_Wgt3GSDIOut3
@ NTV2_Wgt3GSDIOut3
Definition: ntv2enums.h:2871
NTV2_Wgt3GSDIOut7
@ NTV2_Wgt3GSDIOut7
Definition: ntv2enums.h:2920
CNTV2Card::SetMixerBGInputControl
virtual bool SetMixerBGInputControl(const UWord inWhichMixer, const NTV2MixerKeyerInputControl inInputControl)
Sets the background input control value for the given mixer/keyer.
Definition: ntv2register.cpp:2897
CNTV2Card::ReadSDIInVPID
virtual bool ReadSDIInVPID(const NTV2Channel inSDIInput, ULWord &outValueA, ULWord &outValueB)
Definition: ntv2regvpid.cpp:68
AJAThread::Attach
virtual AJAStatus Attach(AJAThreadFunction *pThreadFunction, void *pUserContext)
Definition: thread.cpp:169
CNTV2Card::WaitForInputVerticalInterrupt
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 ...
Definition: ntv2subscriptions.cpp:149
CNTV2Card::EnableInputInterrupt
virtual bool EnableInputInterrupt(const NTV2Channel channel=NTV2_CHANNEL1)
Allows the CNTV2Card instance to wait for and respond to input vertical blanking interrupts originati...
Definition: ntv2interrupts.cpp:23
NTV2_AUDIO_48K
@ NTV2_AUDIO_48K
Definition: ntv2enums.h:1875
NTV2FrameData::AncBuffer2
NTV2Buffer & AncBuffer2(void)
Definition: ntv2democommon.h:117
NTV2_CC608_Red
@ NTV2_CC608_Red
Definition: ntv2caption608types.h:159
NTV2CCGrabber::IsCaptureThreadRunning
virtual bool IsCaptureThreadRunning(void) const
Returns true if my capture thread is currently running.
Definition: ntv2ccgrabber.h:159
g3GSDIOutputs
static const NTV2WidgetID g3GSDIOutputs[]
Definition: ntv2ccgrabber.cpp:382
CNTV2CaptionDecoder708::SetDisplayChannel
virtual bool SetDisplayChannel(const NTV2Line21Channel inChan)
Setsthe caption channel I'm currently focused on (i.e. that I'm currently "burning" into video).
NTV2CCGrabber::SwitchPixelFormat
virtual void SwitchPixelFormat(void)
Switches/rotates –pixelFormat.
Definition: ntv2ccgrabber.cpp:962
ancillarylist.h
Declares the AJAAncillaryList class.
AJA_STATUS_BUSY
@ AJA_STATUS_BUSY
Definition: types.h:391
NTV2FormatDescriptor::GetTopVisibleRowAddress
UByte * GetTopVisibleRowAddress(UByte *pInStartAddress) const
Definition: ntv2formatdescriptor.h:230
CNTV2DeviceScanner::GetFirstDeviceFromArgument
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...
Definition: ntv2devicescanner.cpp:366
NTV2_WgtSDIOut4
@ NTV2_WgtSDIOut4
Definition: ntv2enums.h:2868
NTV2MakeChannelList
NTV2ChannelList NTV2MakeChannelList(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Definition: ntv2publicinterface.cpp:3374
CCGrabberConfig::Get
AJALabelValuePairs Get(const bool inCompact=(0)) const
Definition: ntv2ccgrabber.cpp:1571
NTV2FormatDescriptor::GetVisibleRasterBytes
ULWord GetVisibleRasterBytes(const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.h:134
NTV2_AUDIOSYSTEM_1
@ NTV2_AUDIOSYSTEM_1
This identifies the first Audio System.
Definition: ntv2enums.h:3816
AJACircularBuffer::StartConsumeNextBuffer
FrameDataPtr StartConsumeNextBuffer(void)
The thread that's responsible for processing incoming frames – the consumer – calls this function to ...
Definition: circularbuffer.h:153
CaptureConfig::fPixelFormat
NTV2PixelFormat fPixelFormat
Pixel format to use.
Definition: ntv2democommon.h:273
NTV2_IS_HFR_STANDARD
#define NTV2_IS_HFR_STANDARD(__s__)
Definition: ntv2enums.h:201
CNTV2CaptionRenderer::BurnString
static bool BurnString(const std::string &inString, const NTV2Line21Attrs &inAttribs, NTV2Buffer &inFB, const NTV2FormatDesc &inFBDescriptor, const UWord inRowNum=15, const UWord inColumnNum=1)
Blits the contents of the given UTF-8 encoded string into the given host buffer using the given displ...
NTV2InputSourceToEmbeddedAudioInput
NTV2EmbeddedAudioInput NTV2InputSourceToEmbeddedAudioInput(const NTV2InputSource inInputSource)
Converts a given NTV2InputSource to its equivalent NTV2EmbeddedAudioInput value.
Definition: ntv2utils.cpp:4935
NTV2ACFrameRange::count
UWord count(void) const
Definition: ntv2utils.h:974
AJAAncillaryList::CountAncillaryDataWithType
virtual uint32_t CountAncillaryDataWithType(const AJAAncDataType inMatchType) const
Answers with the number of AJAAncillaryData objects having the given type.
Definition: ancillarylist.cpp:222
GetFrameBufferInputXptFromChannel
NTV2InputXptID GetFrameBufferInputXptFromChannel(const NTV2Channel inFrameStore, const bool inIsBInput=false)
Definition: ntv2signalrouter.cpp:762
CNTV2Card::ClearRouting
virtual bool ClearRouting(void)
Removes all existing signal path connections between any and all widgets on the AJA device.
Definition: ntv2regroute.cpp:278
NTV2CCGrabber::PlayFrames
virtual void PlayFrames(void)
Repeatedly updates captions (until global quit flag set).
Definition: ntv2ccgrabber.cpp:1413
NTV2XptConnection
std::pair< NTV2InputXptID, NTV2OutputXptID > NTV2XptConnection
Definition: ntv2signalrouter.h:38
CNTV2Card::AutoCirculateInitForInput
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 ...
Definition: ntv2autocirculate.cpp:221
NTV2DeviceID
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
Definition: ntv2enums.h:20
AJAAncillaryList::ParseAllAncillaryData
virtual AJAStatus ParseAllAncillaryData(void)
Sends a "ParsePayloadData" command to all of my AJAAncillaryData objects.
Definition: ancillarylist.cpp:205
NTV2CCGrabber::CaptioningChanged
virtual void CaptioningChanged(const NTV2Caption608ChangeInfo &inChangeInfo)
This function gets called whenever caption changes occur.
Definition: ntv2ccgrabber.cpp:1542
CNTV2MacDriverInterface::ReleaseStreamForApplication
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
Definition: ntv2macdriverinterface.cpp:516
CNTV2Card::SetOutputFrame
virtual bool SetOutputFrame(const NTV2Channel inChannel, const ULWord inValue)
Sets the output frame index number for the given FrameStore. This identifies which frame in device SD...
Definition: ntv2register.cpp:2191
NTV2_Wgt3GSDIOut1
@ NTV2_Wgt3GSDIOut1
Definition: ntv2enums.h:2869
NTV2FrameData::fAncBuffer2
NTV2Buffer fAncBuffer2
Additional "F2" host anc buffer.
Definition: ntv2democommon.h:86
NTV2FrameBufferFormat
NTV2FrameBufferFormat
Identifies a particular video frame buffer format. See Device Frame Buffer Formats for details.
Definition: ntv2enums.h:207
AJA_STATUS_MEMORY
@ AJA_STATUS_MEMORY
Definition: types.h:397
AJACircularBuffer::EndProduceNextBuffer
void EndProduceNextBuffer(void)
The producer thread calls this function to signal that it has finished populating the frame it obtain...
Definition: circularbuffer.h:259
AJAAncillaryData_Cea608_Vanc::ParsePayloadData
virtual AJAStatus ParsePayloadData(void)
Parses out (interprets) the "local" ancillary data from my payload data.
Definition: ancillarydata_cea608_vanc.cpp:100
NTV2Buffer::Allocate
bool Allocate(const size_t inByteCount, const bool inPageAligned=false)
Allocates (or re-allocates) my user-space storage using the given byte count. I assume full responsib...
Definition: ntv2publicinterface.cpp:1630
kCaptionDataSrc_INVALID
@ kCaptionDataSrc_INVALID
Definition: ntv2ccgrabber.h:53
CNTV2Card::GetVANCMode
virtual bool GetVANCMode(NTV2VANCMode &outVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Retrieves the current VANC mode for the given FrameStore.
Definition: ntv2register.cpp:2728
CNTV2CaptionDecoder608::Reset
virtual void Reset(void)
Flushes me, clearing all in-progress data.
CNTV2Card::ApplySignalRoute
virtual bool ApplySignalRoute(const CNTV2SignalRouter &inRouter, const bool inReplace=(0))
Applies the given routing table to the AJA device.
Definition: ntv2regroute.cpp:242
NTV2_Wgt3GSDIOut8
@ NTV2_Wgt3GSDIOut8
Definition: ntv2enums.h:2921
CNTV2CaptionDecoder608::BurnCaptions
virtual bool BurnCaptions(NTV2Buffer &inFB, const NTV2FormatDesc &inFD)
Blits all of my current caption channel's "on-air" captions into the given host buffer with the corre...
NTV2PixelFormat
NTV2FrameBufferFormat NTV2PixelFormat
An alias for NTV2FrameBufferFormat.
Definition: ntv2enums.h:248
CaptureConfig::Get
AJALabelValuePairs Get(const bool inCompact=(0)) const
Definition: ntv2democommon.cpp:1664
NTV2FrameData::fAncBuffer
NTV2Buffer fAncBuffer
Host ancillary data buffer.
Definition: ntv2democommon.h:85
CNTV2CaptionDecoder708::GetCC608CaptionData
virtual CaptionData GetCC608CaptionData(void)
Pops the next CC608 data.
CNTV2Card::SetAudioLoopBack
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
NTV2_CHANNEL1
@ NTV2_CHANNEL1
Specifies channel or Frame Store 1 (or the first item).
Definition: ntv2enums.h:1307
ntv2debug.h
CNTV2Card::SetFrameBufferFormat
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.
Definition: ntv2register.cpp:1812
CNTV2Card::SetSDITransmitEnable
virtual bool SetSDITransmitEnable(const NTV2Channel inChannel, const bool inEnable)
Sets the specified bidirectional SDI connector to act as an input or an output.
Definition: ntv2register.cpp:3796
CaptionData::f1_char2
UByte f1_char2
Caption Byte 2 of Field 1.
Definition: ntv2caption608types.h:659
CNTV2Card::GetSDITransmitEnable
virtual bool GetSDITransmitEnable(const NTV2Channel inChannel, bool &outEnabled)
Answers whether or not the specified SDI connector is currently acting as a transmitter (i....
Definition: ntv2register.cpp:3817
CNTV2Card::SetVANCShiftMode
virtual bool SetVANCShiftMode(NTV2Channel inChannel, NTV2VANCDataShiftMode inMode)
Enables or disables the "VANC Shift Mode" feature for the given channel.
Definition: ntv2register.cpp:2800
NTV2FormatDescriptor::GetLineOffsetFromSMPTELine
bool GetLineOffsetFromSMPTELine(const ULWord inSMPTELine, ULWord &outLineOffset) const
Answers with the equivalent line offset into the raster I describe for the given SMPTE line number.
Definition: ntv2formatdescriptor.cpp:1200
AJAAncillaryList::GetAncillaryDataWithType
virtual AJAAncillaryData * GetAncillaryDataWithType(const AJAAncDataType inMatchType, const uint32_t inIndex=0) const
Answers with the AJAAncillaryData object having the given type and index.
Definition: ancillarylist.cpp:238
NTV2_Wgt3GSDIOut5
@ NTV2_Wgt3GSDIOut5
Definition: ntv2enums.h:2918
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::void
j template void())
Definition: json.hpp:4893
NTV2CCGrabber::Run
virtual AJAStatus Run(void)
Runs me.
Definition: ntv2ccgrabber.cpp:605
AJAAncillaryList
I am an ordered collection of AJAAncillaryData instances which represent one or more SMPTE 291 data p...
Definition: ancillarylist.h:64
CCGrabberConfig::fCaptionSrc
CaptionDataSrc fCaptionSrc
Caption data source (Line21? 608 VANC? 608 Anc? etc)
Definition: ntv2ccgrabber.h:66
NTV2CCGrabber::StartCaptureThread
virtual AJAStatus StartCaptureThread(void)
Starts my capture thread.
Definition: ntv2ccgrabber.cpp:622
CaptionDataSrc
enum _CaptionDataSrc CaptionDataSrc
NTV2CCGrabber::Quit
virtual void Quit(void)
Gracefully stops me from running.
Definition: ntv2ccgrabber.cpp:102
NTV2_CHANNEL_INVALID
@ NTV2_CHANNEL_INVALID
Definition: ntv2enums.h:1316
NTV2_CHANNEL6
@ NTV2_CHANNEL6
Specifies channel or Frame Store 6 (or the 6th item).
Definition: ntv2enums.h:1312
GetMixerOutputXptFromChannel
NTV2OutputXptID GetMixerOutputXptFromChannel(const NTV2Channel inChannel, const bool inIsKey=false)
Definition: ntv2signalrouter.cpp:955
CNTV2CaptionDecoder608::GetOnAirCharacters
virtual std::string GetOnAirCharacters(const UWord inRowNumber=0) const
Retrieves all "on-air" characters either for all rows, or a specific row.
CNTV2Card::SetAudioSystemInputSource
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
NTV2CCGrabber::DoCCOutput
virtual void DoCCOutput(const uint32_t inFrameNum, const CaptionData &inCCData, const NTV2VideoFormat inVideoFormat)
Outputs CC data.
Definition: ntv2ccgrabber.cpp:1182
NTV2FrameData::VideoBuffer
NTV2Buffer & VideoBuffer(void)
Definition: ntv2democommon.h:106
NTV2_IS_4K_VIDEO_FORMAT
#define NTV2_IS_4K_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:746
NTV2_REFERENCE_INVALID
@ NTV2_REFERENCE_INVALID
Definition: ntv2enums.h:1425
NTV2_CHANNEL4
@ NTV2_CHANNEL4
Specifies channel or Frame Store 4 (or the 4th item).
Definition: ntv2enums.h:1310
kOutputMode_INVALID
@ kOutputMode_INVALID
Definition: ntv2ccgrabber.h:39
NTV2_CHANNEL5
@ NTV2_CHANNEL5
Specifies channel or Frame Store 5 (or the 5th item).
Definition: ntv2enums.h:1311
CNTV2Card::GetModelName
virtual std::string GetModelName(void)
Answers with this device's model name.
Definition: ntv2card.cpp:80
CaptionDecode608Stats
enum _CaptionDecode608Stats CaptionDecode608Stats
The currently supported caption decoder stats.
CNTV2Card::features
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:141
NTV2CCGrabber::SwitchOutput
virtual void SwitchOutput(void)
Switches/rotates –output mode.
Definition: ntv2ccgrabber.cpp:940
AJAThread
Definition: thread.h:69
AUTOCIRCULATE_WITH_ANC
#define AUTOCIRCULATE_WITH_ANC
Use this to AutoCirculate with ancillary data.
Definition: ntv2publicinterface.h:5527
AJAThread::Active
virtual bool Active()
Definition: thread.cpp:116
NTV2Caption608ChangeInfo
This class is used to respond to dynamic events that occur during CEA-608 caption decoding.
Definition: ntv2caption608types.h:779
NTV2_WgtSDIOut1
@ NTV2_WgtSDIOut1
Definition: ntv2enums.h:2865
AJAStatus
AJAStatus
Definition: types.h:378
GetMixerBGInputXpt
NTV2InputXptID GetMixerBGInputXpt(const NTV2Channel inChannel, const bool inIsKey=false)
Definition: ntv2signalrouter.cpp:981
aja::lower
std::string & lower(std::string &str)
Definition: common.cpp:436
NTV2InputSourceToString
std::string NTV2InputSourceToString(const NTV2InputSource inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7215
kAppSignature
static const ULWord kAppSignature((((uint32_t)( 'C'))<< 24)|(((uint32_t)( 'C'))<< 16)|(((uint32_t)( 'G'))<< 8)|(((uint32_t)( 'R'))<< 0))
NTV2_Wgt3GSDIOut2
@ NTV2_Wgt3GSDIOut2
Definition: ntv2enums.h:2870
NTV2TCIndexToString
std::string NTV2TCIndexToString(const NTV2TCIndex inValue, const bool inCompactDisplay=false)
Definition: ntv2utils.cpp:6413
NTV2CCGrabber::SetupOutputVideo
virtual AJAStatus SetupOutputVideo(const NTV2VideoFormat inVideoFormat)
Sets up everything I need for capturing video.
Definition: ntv2ccgrabber.cpp:1285
AJATime::Sleep
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
AJACircularBuffer::Add
AJAStatus Add(FrameDataPtr pInFrameData)
Appends a new frame buffer to me, increasing my frame storage capacity by one frame.
Definition: circularbuffer.h:92
CNTV2CaptionDecodeChannel608::GetStatTitle
static std::string GetStatTitle(const CaptionDecode608Stats inStat)
NTV2_VANCMODE_TALL
@ NTV2_VANCMODE_TALL
This identifies the "tall" mode in which there are some VANC lines in the frame buffer.
Definition: ntv2enums.h:3719
NTV2Standard
NTV2Standard
Identifies a particular video standard.
Definition: ntv2enums.h:153
NTV2_MAX_NUM_CHANNELS
@ NTV2_MAX_NUM_CHANNELS
Definition: ntv2enums.h:1315
CAPFAIL
#define CAPFAIL(_expr_)
Definition: ntv2democommon.h:28
NTV2_VANCMODE_OFF
@ NTV2_VANCMODE_OFF
This identifies the mode in which there are no VANC lines in the frame buffer.
Definition: ntv2enums.h:3718
CNTV2Card::SetSDIOutputAudioSystem
virtual bool SetSDIOutputAudioSystem(const NTV2Channel inSDIOutputConnector, const NTV2AudioSystem inAudioSystem)
Sets the device's NTV2AudioSystem that will provide audio for the given SDI output's audio embedder....
Definition: ntv2register.cpp:3949
AJATimeBase
Definition: timebase.h:18
CNTV2CaptionDecoder608::Get608ChannelDecoder
virtual CNTV2CaptionDecodeChannel608Ptr Get608ChannelDecoder(const NTV2Line21Channel inChannel) const
AJA_STATUS_FAIL
@ AJA_STATUS_FAIL
Definition: types.h:382
ULWord
uint32_t ULWord
Definition: ajatypes.h:253
CNTV2Card::EnableChannels
virtual bool EnableChannels(const NTV2ChannelSet &inChannels, const bool inDisableOthers=(0))
Enables the given FrameStore(s).
Definition: ntv2register.cpp:2107
NTV2_VANCDATA_8BITSHIFT_ENABLE
@ NTV2_VANCDATA_8BITSHIFT_ENABLE
Definition: ntv2enums.h:3736
AJASystemInfo::append
static AJALabelValuePairs & append(AJALabelValuePairs &inOutTable, const std::string &inLabel, const std::string &inValue=std::string())
A convenience function that appends the given label and value strings to the provided AJALabelValuePa...
Definition: info.h:168
AsConstUBytePtr
#define AsConstUBytePtr(__p__)
Definition: ntv2ccgrabber.cpp:28
NTV2FrameData::fVideoBuffer
NTV2Buffer fVideoBuffer
Host video buffer.
Definition: ntv2democommon.h:82
NTV2_VANCDATA_8BITSHIFT_DISABLE
@ NTV2_VANCDATA_8BITSHIFT_DISABLE
Definition: ntv2enums.h:3735
AUTOCIRCULATE_STATUS
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
Definition: ntv2publicinterface.h:7160
NTV2_CHANNEL7
@ NTV2_CHANNEL7
Specifies channel or Frame Store 7 (or the 7th item).
Definition: ntv2enums.h:1313
AJAAncillaryData
I am the principal class that stores a single SMPTE-291 SDI ancillary data packet OR the digitized co...
Definition: ancillarydata.h:552
NTV2FrameData::VideoBufferSize
ULWord VideoBufferSize(void) const
Definition: ntv2democommon.h:107
NTV2_CC608_CapModeUnknown
@ NTV2_CC608_CapModeUnknown
Unknown or invalid caption mode.
Definition: ntv2caption608types.h:126
NTV2CCGrabber::GetLine21ChannelNames
static std::string GetLine21ChannelNames(std::string inDelimiter=", ")
Returns a string containing a concatenation of human-readable names of every available NTV2Line21Chan...
Definition: ntv2ccgrabber.cpp:1556
NTV2ReferenceSource
NTV2ReferenceSource
These enum values identify a specific source for the device's (output) reference clock.
Definition: ntv2enums.h:1399
kCaptionDataSrc_608Anc
@ kCaptionDataSrc_608Anc
Definition: ntv2ccgrabber.h:51
AJAAncillaryData::GetPayloadData
virtual const uint8_t * GetPayloadData(void) const
Definition: ancillarydata.h:801
CNTV2Card::SetMode
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.
Definition: ntv2register.cpp:1607
kOutputMode_CaptionScreen
@ kOutputMode_CaptionScreen
Definition: ntv2ccgrabber.h:35
CNTV2DemoCommon::SetDefaultPageSize
static size_t SetDefaultPageSize(void)
Definition: ntv2democommon.cpp:1484
NTV2_CC608_Transparent
@ NTV2_CC608_Transparent
Definition: ntv2caption608types.h:217
NTV2DeviceIDToString
std::string NTV2DeviceIDToString(const NTV2DeviceID inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:4673
AJAAncillaryData_Cea608_Line21::ParsePayloadData
virtual AJAStatus ParsePayloadData(void)
Parses out (interprets) the "local" ancillary data from my payload data.
Definition: ancillarydata_cea608_line21.cpp:83
CNTV2Card::UnsubscribeInputVerticalEvent
virtual bool UnsubscribeInputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Unregisters me so I'm no longer notified when an input VBI is signaled on the given input channel.
Definition: ntv2subscriptions.cpp:75
GetCSCOutputXptFromChannel
NTV2OutputXptID GetCSCOutputXptFromChannel(const NTV2Channel inCSC, const bool inIsKey=false, const bool inIsRGB=false)
Definition: ntv2signalrouter.cpp:819
CNTV2CaptionDecoder708::GetNextServiceBlockInfoFromQueue
virtual bool GetNextServiceBlockInfoFromQueue(const size_t svcIndex, size_t &outBlockSize, size_t &outDataSize, int &outServiceNum, bool &outIsExtended) const
AJASystemInfo::ToString
virtual void ToString(std::string &outAllLabelsAndValues) const
Answers with a multi-line string that contains the complete host system info table.
AJAProcess::GetPid
static uint64_t GetPid()
Definition: process.cpp:35
NTV2FrameData::AncBufferSize
ULWord AncBufferSize(void) const
Definition: ntv2democommon.h:114
OutputMode
enum _OutputMode OutputMode
CNTV2CaptionDecoder608::SubscribeChangeNotification
virtual bool SubscribeChangeNotification(NTV2Caption608Changed *pInCallback, void *pInUserData=0)
Subscribes to change notifications.
CNTV2CaptionDecoder708::ParseSMPTE334AncPacket
virtual bool ParseSMPTE334AncPacket(bool &outHasParityErrors)
Parses the current frame's SMPTE 334 Ancillary packet and extracts the 608 and 708 caption data from ...
NTV2CCGrabber::SetupHostBuffers
virtual AJAStatus SetupHostBuffers(const NTV2VideoFormat inVideoFormat)
Sets up my circular buffers.
Definition: ntv2ccgrabber.cpp:200
CCGrabberConfig
This class is used to configure an NTV2CCGrabber instance.
Definition: ntv2ccgrabber.h:62
NTV2CCGrabber::Init
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
Definition: ntv2ccgrabber.cpp:119
CaptionData::HasData
bool HasData(void) const
Definition: ntv2caption608types.h:698
AUTOCIRCULATE_TRANSFER::GetCapturedAncByteCount
ULWord GetCapturedAncByteCount(const bool inField2=false) const
Definition: ntv2publicinterface.h:8346
NTV2_CHANNEL3
@ NTV2_CHANNEL3
Specifies channel or Frame Store 3 (or the 3rd item).
Definition: ntv2enums.h:1309
UWord
uint16_t UWord
Definition: ajatypes.h:251
AJACircularBuffer::StartProduceNextBuffer
FrameDataPtr StartProduceNextBuffer(void)
The thread that's responsible for providing frames – the producer – calls this function to populate t...
Definition: circularbuffer.h:109
CNTV2Card::AutoCirculateGetStatus
virtual bool AutoCirculateGetStatus(const NTV2Channel inChannel, AUTOCIRCULATE_STATUS &outStatus)
Returns the current AutoCirculate status for the given channel.
Definition: ntv2autocirculate.cpp:646
NTV2FrameData::AudioBufferSize
ULWord AudioBufferSize(void) const
Definition: ntv2democommon.h:110
NTV2FrameData::AncBuffer2Size
ULWord AncBuffer2Size(void) const
Definition: ntv2democommon.h:118
NTV2_IS_VANCMODE_ON
#define NTV2_IS_VANCMODE_ON(__v__)
Definition: ntv2enums.h:3727
NTV2_IS_VALID_INPUT_SOURCE
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1243
NTV2_FBF_8BIT_YCBCR
@ NTV2_FBF_8BIT_YCBCR
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:211
CaptureConfig::fDeviceSpec
std::string fDeviceSpec
The AJA device to use.
Definition: ntv2democommon.h:268
NTV2CCGrabber::StartPlayThread
virtual AJAStatus StartPlayThread(void)
Starts my playout thread.
Definition: ntv2ccgrabber.cpp:1387
CCGrabberConfig::CaptionDataSrcToString
static std::string CaptionDataSrcToString(const CaptionDataSrc inDataSrc)
Definition: ntv2ccgrabber.cpp:1649
NTV2VideoFormatToString
std::string NTV2VideoFormatToString(const NTV2VideoFormat inValue, const bool inUseFrameRate=false)
Definition: ntv2utils.cpp:6750
NTV2FrameData::AudioBuffer
NTV2Buffer & AudioBuffer(void)
Definition: ntv2democommon.h:109
AJA_SUCCESS
#define AJA_SUCCESS(_status_)
Definition: types.h:370
GetCSCInputXptFromChannel
NTV2InputXptID GetCSCInputXptFromChannel(const NTV2Channel inCSC, const bool inIsKeyInput=false)
Definition: ntv2signalrouter.cpp:775
NTV2MIXERMODE_FOREGROUND_ON
@ NTV2MIXERMODE_FOREGROUND_ON
Passes only foreground video + key to the Mixer output.
Definition: ntv2enums.h:1738
kRedOnTransparentBG
static const NTV2Line21Attributes kRedOnTransparentBG(NTV2_CC608_Red, NTV2_CC608_Blue, NTV2_CC608_Transparent)
NTV2_IS_HD_VIDEO_FORMAT
#define NTV2_IS_HD_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:700
CCGrabberConfig::GetLegalCaptionDataSources
static std::string GetLegalCaptionDataSources(void)
Definition: ntv2ccgrabber.cpp:1636
AUTOCIRCULATE_STATUS::IsStopped
bool IsStopped(void) const
Definition: ntv2publicinterface.h:7276
CNTV2CaptionDecoder608::Create
static bool Create(CNTV2CaptionDecoder608Ptr &outEncoder)
Creates a new CNTV2CaptionEncoder608 instance.
operator<<
std::ostream & operator<<(std::ostream &ioStrm, const CCGrabberConfig &inObj)
Definition: ntv2ccgrabber.cpp:1688
NTV2WidgetID
NTV2WidgetID
Definition: ntv2enums.h:2847
NTV2_CC608_Green
@ NTV2_CC608_Green
Definition: ntv2caption608types.h:156
CNTV2DriverInterface::IsDeviceReady
virtual bool IsDeviceReady(const bool inCheckValid=(0))
Definition: ntv2driverinterface.cpp:1284
CaptionData::bGotField2Data
bool bGotField2Data
True if Field 2 bytes have been set; otherwise false.
Definition: ntv2caption608types.h:661
NTV2_XptHDMIOutQ1Input
@ NTV2_XptHDMIOutQ1Input
Definition: ntv2enums.h:2794
NTV2_RP188::fDBB
ULWord fDBB
Definition: ntv2publicinterface.h:6761
GetVideoWriteSize
ULWord GetVideoWriteSize(const NTV2VideoFormat inVideoFormat, const NTV2FrameBufferFormat inFBFormat, const NTV2VANCMode inVancMode=NTV2_VANCMODE_OFF)
Identical to the GetVideoActiveSize function, except rounds the result up to the nearest 4K page size...
Definition: ntv2utils.cpp:2775
CCGrabberConfig::GetLegalOutputModes
static std::string GetLegalOutputModes(void)
Definition: ntv2ccgrabber.cpp:1585
DeviceCapabilities::CanDoInputSource
bool CanDoInputSource(const NTV2InputSource inSrc)
Definition: ntv2devicecapabilities.h:233
NTV2ChannelSet
std::set< NTV2Channel > NTV2ChannelSet
A set of distinct NTV2Channel values.
Definition: ntv2publicinterface.h:3854
AJACircularBuffer::EndConsumeNextBuffer
void EndConsumeNextBuffer(void)
The consumer thread calls this function to signal that it has finished processing the frame it obtain...
Definition: circularbuffer.h:266
AUTOCIRCULATE_TRANSFER::acANCField2Buffer
NTV2Buffer acANCField2Buffer
The host "Field 2" ancillary data buffer. This field is owned by the client application,...
Definition: ntv2publicinterface.h:8006
CNTV2Card::SetTsiFrameEnable
virtual bool SetTsiFrameEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 two-sample interleave (Tsi) frame mode on the device.
Definition: ntv2register.cpp:1311
NTV2_FBF_FIRST
@ NTV2_FBF_FIRST
Definition: ntv2enums.h:209
IS_VALID_OutputMode
#define IS_VALID_OutputMode(_x_)
Definition: ntv2ccgrabber.h:42
CNTV2Card::GetReference
virtual bool GetReference(NTV2ReferenceSource &outRefSource)
Answers with the device's current clock reference source.
Definition: ntv2register.cpp:1523
kOutputMode_CaptionFileSCC
@ kOutputMode_CaptionFileSCC
Definition: ntv2ccgrabber.h:36
CNTV2Card::GetInputVideoFormat
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.
Definition: ntv2register.cpp:3365
CRP188
Definition: ntv2rp188.h:55
AUTOCIRCULATE_STATUS::GetEndFrame
uint16_t GetEndFrame(void) const
Definition: ntv2publicinterface.h:7251
GetDLInOutputXptFromChannel
NTV2OutputXptID GetDLInOutputXptFromChannel(const NTV2Channel inDLInput)
Definition: ntv2signalrouter.cpp:917
NTV2_AUDIOSIZE_MAX
#define NTV2_AUDIOSIZE_MAX
Definition: ntv2democommon.h:46
CNTV2Card::SetEveryFrameServices
virtual bool SetEveryFrameServices(const NTV2EveryFrameTaskMode inMode)
Sets the device's task mode.
Definition: ntv2register.cpp:179
CNTV2CaptionDecoder608::IdleFrame
virtual void IdleFrame(void)
Call this once per video frame when I'm doing display "burn-in", whether there is new caption data to...
NTV2StringList
std::vector< std::string > NTV2StringList
Definition: ntv2utils.h:1134
AsConstULWordPtr
#define AsConstULWordPtr(__p__)
Definition: ntv2ccgrabber.cpp:29
NTV2VANCMode
NTV2VANCMode
These enum values identify the available VANC modes.
Definition: ntv2enums.h:3716
AJALock
Definition: lock.h:30
CNTV2CaptionDecoder708::Reset
virtual void Reset(void)
IS_VALID_CaptionDataSrc
#define IS_VALID_CaptionDataSrc(_x_)
Definition: ntv2ccgrabber.h:56
NTV2FormatDescriptor::GetTotalRasterBytes
ULWord GetTotalRasterBytes(const UWord inPlaneIndex0=0) const
Definition: ntv2formatdescriptor.h:114
NTV2_CC608_ChannelMax
@ NTV2_CC608_ChannelMax
Definition: ntv2caption608types.h:97
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:197
NTV2_IS_VALID_CHANNEL
#define NTV2_IS_VALID_CHANNEL(__x__)
Definition: ntv2enums.h:1319
CaptureConfig::fFrames
NTV2ACFrameRange fFrames
AutoCirculate frame count or range.
Definition: ntv2democommon.h:272
NTV2_DISABLE_TASKS
@ NTV2_DISABLE_TASKS
0: Disabled: Device is completely configured by controlling application(s) – no driver involvement.
Definition: ntv2publicinterface.h:4290
NTV2CCGrabber::PlayThreadStatic
static void PlayThreadStatic(AJAThread *pThread, void *pContext)
This is the playout thread's static callback function that gets called when the playout thread runs....
Definition: ntv2ccgrabber.cpp:1402
NTV2_VANCMODE_INVALID
@ NTV2_VANCMODE_INVALID
This identifies the invalid (unspecified, uninitialized) VANC mode.
Definition: ntv2enums.h:3721
CNTV2DemoCommon::GetAJAFrameRate
static AJA_FrameRate GetAJAFrameRate(const NTV2FrameRate inFrameRate)
Definition: ntv2democommon.cpp:1011
CNTV2Card::SetMixerFGInputControl
virtual bool SetMixerFGInputControl(const UWord inWhichMixer, const NTV2MixerKeyerInputControl inInputControl)
Sets the foreground input control value for the given mixer/keyer.
Definition: ntv2register.cpp:2874
AJAAncillaryList::CompareWithInfo
virtual std::string CompareWithInfo(const AJAAncillaryList &inCompareList, const bool inIgnoreLocation=true, const bool inIgnoreChecksum=true) const
Compares me with another list and returns a std::string that contains a human-readable explanation of...
Definition: ancillarylist.cpp:482
NTV2CCGrabber::SetupInputVideo
virtual AJAStatus SetupInputVideo(void)
Sets up everything I need for capturing video.
Definition: ntv2ccgrabber.cpp:257
CaptureConfig::fInputChannel
NTV2Channel fInputChannel
The device channel to use.
Definition: ntv2democommon.h:270
NTV2Buffer::GetHostAddress
void * GetHostAddress(const ULWord inByteOffset, const bool inFromEnd=false) const
Definition: ntv2publicinterface.cpp:1686
NTV2OutputCrosspointID
NTV2OutputCrosspointID
Identifies a widget output, a signal source, that potentially can drive another widget's input (ident...
Definition: ntv2enums.h:2471
NTV2ChannelList
std::vector< NTV2Channel > NTV2ChannelList
An ordered sequence of NTV2Channel values.
Definition: ntv2publicinterface.h:3835
NTV2Buffer::GetHostPointer
void * GetHostPointer(void) const
Definition: ntv2publicinterface.h:6049
AJAAutoLock
Definition: lock.h:91
CNTV2VPID::IsStandardTwoSampleInterleave
virtual bool IsStandardTwoSampleInterleave(void) const
Definition: ntv2vpid.cpp:281
NTV2CCGrabber::ReleaseHostBuffers
virtual void ReleaseHostBuffers(void)
Releases my circular buffers.
Definition: ntv2ccgrabber.cpp:240
gSDIOutputs
static const NTV2WidgetID gSDIOutputs[]
Definition: ntv2ccgrabber.cpp:379
NTV2_FORMAT_UNKNOWN
@ NTV2_FORMAT_UNKNOWN
Definition: ntv2enums.h:498
NTV2CCGrabber::CaptureFrames
virtual void CaptureFrames(void)
Repeatedly captures frames using AutoCirculate (until global quit flag set).
Definition: ntv2ccgrabber.cpp:648
NTV2FrameData::fAudioBuffer
NTV2Buffer fAudioBuffer
Host audio buffer.
Definition: ntv2democommon.h:84
CNTV2CaptionDecoder708::GetNextServiceBlockFromQueue
virtual size_t GetNextServiceBlockFromQueue(const size_t svcIndex, std::vector< UByte > &outData)
NTV2_WgtHDMIOut1
@ NTV2_WgtHDMIOut1
Definition: ntv2enums.h:2884
ntv2captionrenderer.h
Declares the CNTV2CaptionRenderer class.
CNTV2Card::Connect
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).
Definition: ntv2regroute.cpp:87
NTV2_FBF_10BIT_YCBCR
@ NTV2_FBF_10BIT_YCBCR
See 10-Bit YCbCr Format.
Definition: ntv2enums.h:210
NTV2_Wgt3GSDIOut4
@ NTV2_Wgt3GSDIOut4
Definition: ntv2enums.h:2872
NTV2CCGrabber::Caption608ChangedStatic
static void Caption608ChangedStatic(void *pInstance, const NTV2Caption608ChangeInfo &inChangeInfo)
This static function gets called whenever 608 captioning changes.
Definition: ntv2ccgrabber.cpp:1548
AJA_STATUS_INITIALIZE
@ AJA_STATUS_INITIALIZE
Definition: types.h:386
NTV2CCGrabber::WaitForStableInputSignal
virtual NTV2VideoFormat WaitForStableInputSignal(void)
Wait for a stable input signal, and return it.
Definition: ntv2ccgrabber.cpp:824
CNTV2CaptionDecoder608::SetDisplayChannel
virtual bool SetDisplayChannel(const NTV2Line21Channel inChannel)
Changes the caption channel that I'm focused on (or that I'm currently "burning" into video).
DEC
#define DEC(__x__)
Definition: ntv2publicinterface.h:5605
NTV2Line21ChannelToStr
const std::string & NTV2Line21ChannelToStr(const NTV2Line21Channel inLine21Channel, const bool inCompact=true)
Converts the given NTV2Line21Channel value into a human-readable string.
CNTV2Card::SetSDIOutputStandard
virtual bool SetSDIOutputStandard(const UWord inOutputSpigot, const NTV2Standard inValue)
Sets the SDI output spigot's video standard.
Definition: ntv2register.cpp:3200
kCaptionDataSrc_708Anc
@ kCaptionDataSrc_708Anc
Definition: ntv2ccgrabber.h:52
kOutputMode_CaptionStream
@ kOutputMode_CaptionStream
Definition: ntv2ccgrabber.h:34
CNTV2Card::DisableChannels
virtual bool DisableChannels(const NTV2ChannelSet &inChannels)
Disables the given FrameStore(s).
Definition: ntv2register.cpp:2087
false
#define false
Definition: ntv2devicefeatures.h:25
UByte
uint8_t UByte
Definition: ajatypes.h:248
AUTOCIRCULATE_WITH_RP188
#define AUTOCIRCULATE_WITH_RP188
Use this to AutoCirculate with RP188.
Definition: ntv2publicinterface.h:5521
NTV2CCGrabber::~NTV2CCGrabber
virtual ~NTV2CCGrabber()
Definition: ntv2ccgrabber.cpp:80
CNTV2Card::SetMixerVancOutputFromForeground
virtual bool SetMixerVancOutputFromForeground(const UWord inWhichMixer, const bool inFromForegroundSource=(!(0)))
Sets the VANC source for the given mixer/keyer to the foreground video (or not). See the SDI Ancillar...
Definition: ntv2register.cpp:2853
CAPWARN
#define CAPWARN(_expr_)
Definition: ntv2democommon.h:29
NTV2ACFrameRange::lastFrame
UWord lastFrame(void) const
Definition: ntv2utils.h:976
ConvertLine_v210_to_2vuy
bool ConvertLine_v210_to_2vuy(const ULWord *pInSrcLine_v210, UByte *pOutDstLine_2vuy, const ULWord inNumPixels)
Converts a single 10-bit YCbCr 'v210' raster line to 8-bit YCbCr '2vuy'.
Definition: ntv2transcode.cpp:49
AUTOCIRCULATE_STATUS::IsRunning
bool IsRunning(void) const
Definition: ntv2publicinterface.h:7266
GetFrameBufferOutputXptFromChannel
NTV2OutputXptID GetFrameBufferOutputXptFromChannel(const NTV2Channel inFrameStore, const bool inIsRGB=false, const bool inIs425=false)
Definition: ntv2signalrouter.cpp:845
CRP188::GetRP188CString
const char * GetRP188CString() const
Definition: ntv2rp188.cpp:924
NTV2CCGrabber::SetCaptionDisplayChannel
virtual void SetCaptionDisplayChannel(const NTV2Line21Channel inNewChannel)
Changes the caption channel I'm displaying.
Definition: ntv2ccgrabber.cpp:1526
NTV2_AUDIO_LOOPBACK_ON
@ NTV2_AUDIO_LOOPBACK_ON
Embeds SDI input source audio into the data stream.
Definition: ntv2enums.h:1976
NTV2_RP188::IsValid
bool IsValid(void) const
Answers true if I'm valid, or false if I'm not valid.
Definition: ntv2publicinterface.h:6802
ancillarydata_cea608_vanc.h
Declares the AJAAncillaryData_Cea608_Vanc class.
NTV2FrameBufferFormatToString
std::string NTV2FrameBufferFormatToString(const NTV2FrameBufferFormat inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:6940
AJAAncillaryData::ParsePayloadData
virtual AJAStatus ParsePayloadData(void)
Parses (interprets) the "local" ancillary data from my payload data.
Definition: ancillarydata.cpp:501
NTV2MIXERINPUTCONTROL_FULLRASTER
@ NTV2MIXERINPUTCONTROL_FULLRASTER
Definition: ntv2enums.h:1723
NTV2CCGrabber
I can decode captions from frames captured from an AJA device in real time. I can optionally play the...
Definition: ntv2ccgrabber.h:111
AJACircularBuffer::Clear
void Clear(void)
Clears my frame collection, their locks, everything.
Definition: circularbuffer.h:314
NTV2XptConnections
std::map< NTV2InputXptID, NTV2OutputXptID > NTV2XptConnections
Definition: ntv2signalrouter.h:39
GetTSIMuxOutputXptFromChannel
NTV2OutputXptID GetTSIMuxOutputXptFromChannel(const NTV2Channel inTSIMuxer, const bool inLinkB=false, const bool inIsRGB=false)
Definition: ntv2signalrouter.cpp:1005
AJA_STATUS_BAD_PARAM
@ AJA_STATUS_BAD_PARAM
Definition: types.h:392
CNTV2VPID::GetVideoFormat
virtual NTV2VideoFormat GetVideoFormat(void) const
Definition: ntv2vpid.cpp:674
NTV2Line21Channel
NTV2Line21Channel
The CEA-608 caption channels: CC1 thru CC4, TX1 thru TX4, plus XDS.
Definition: ntv2caption608types.h:82
CNTV2Card::WaitForOutputVerticalInterrupt
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 ...
Definition: ntv2subscriptions.cpp:134
NTV2CCGrabber::Switch608Source
virtual void Switch608Source(void)
Switches/rotates –608src.
Definition: ntv2ccgrabber.cpp:951
NTV2MakeChannelSet
NTV2ChannelSet NTV2MakeChannelSet(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Definition: ntv2publicinterface.cpp:3357
std
Definition: json.hpp:5362
NTV2_RP188
This struct replaces the old RP188_STRUCT.
Definition: ntv2publicinterface.h:6760
AUTOCIRCULATE_TRANSFER::acVideoBuffer
NTV2Buffer acVideoBuffer
The host video buffer. This field is owned by the client application, and thus is responsible for all...
Definition: ntv2publicinterface.h:7977
CNTV2Card::SetMixerMode
virtual bool SetMixerMode(const UWord inWhichMixer, const NTV2MixerKeyerMode inMode)
Sets the mode for the given mixer/keyer.
Definition: ntv2register.cpp:2920
IsRGBFormat
bool IsRGBFormat(const NTV2FrameBufferFormat format)
Definition: ntv2utils.cpp:5442
NTV2_Wgt3GSDIOut6
@ NTV2_Wgt3GSDIOut6
Definition: ntv2enums.h:2919
NTV2_AUDIO_EMBEDDED
@ NTV2_AUDIO_EMBEDDED
Obtain audio samples from the audio that's embedded in the video HANC.
Definition: ntv2enums.h:1952
CNTV2Card::AutoCirculateTransfer
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 ...
Definition: ntv2autocirculate.cpp:695
AJAAncDataType_Cea708
@ AJAAncDataType_Cea708
CEA708 (SMPTE 334) HD Closed Captioning.
Definition: ancillarydata.h:50
NTV2_WgtHDMIOut1v2
@ NTV2_WgtHDMIOut1v2
Definition: ntv2enums.h:2908
CNTV2Card::AutoCirculateInitForOutput
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...
Definition: ntv2autocirculate.cpp:353
NTV2VideoFormat
enum _NTV2VideoFormat NTV2VideoFormat
Identifies a particular video format.
Hex0N
#define Hex0N(__x__, __n__)
Definition: ntv2publicinterface.h:5597
CNTV2CaptionDecoder608::ProcessNew608FrameData
virtual bool ProcessNew608FrameData(const CaptionData &inCC608Data)
Notifies me that new frame data has arrived. Clients should call this method once per video frame wit...
kCaptionDataSrc_Default
@ kCaptionDataSrc_Default
Definition: ntv2ccgrabber.h:47
CNTV2VPID::IsRGBSampling
virtual bool IsRGBSampling(void) const
Definition: ntv2vpid.cpp:414
NTV2_WgtSDIOut3
@ NTV2_WgtSDIOut3
Definition: ntv2enums.h:2867
NTV2_WgtAnalogOut1
@ NTV2_WgtAnalogOut1
Definition: ntv2enums.h:2881
CIRCULAR_BUFFER_SIZE
static const size_t CIRCULAR_BUFFER_SIZE(10)
Number of NTV2FrameData's in our ring.
CNTV2MacDriverInterface::AcquireStreamForApplication
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 ...
Definition: ntv2macdriverinterface.cpp:481
kCaptionDataSrc_Line21
@ kCaptionDataSrc_Line21
Definition: ntv2ccgrabber.h:48
DeviceCapabilities::CanDoWidget
bool CanDoWidget(const NTV2WidgetID inWgtID)
Definition: ntv2devicecapabilities.h:260
NTV2CCGrabber::RouteInputSignal
virtual bool RouteInputSignal(const NTV2VideoFormat inVideoFormat)
Definition: ntv2ccgrabber.cpp:386
true
#define true
Definition: ntv2devicefeatures.h:26
CNTV2DriverInterface::GetDeviceID
virtual NTV2DeviceID GetDeviceID(void)
Definition: ntv2driverinterface.cpp:381
AUTOCIRCULATE_STATUS::HasAvailableInputFrame
bool HasAvailableInputFrame(void) const
Definition: ntv2publicinterface.h:7236
CCGrabberConfig::OutputModeToString
static std::string OutputModeToString(const OutputMode inMode)
Definition: ntv2ccgrabber.cpp:1598
CNTV2Card::GetEveryFrameServices
virtual bool GetEveryFrameServices(NTV2EveryFrameTaskMode &outMode)
Retrieves the device's current "retail service" task mode.
Definition: ntv2register.cpp:184
kGreenOnTransparentBG
static const NTV2Line21Attributes kGreenOnTransparentBG(NTV2_CC608_Green, NTV2_CC608_Blue, NTV2_CC608_Transparent)
CNTV2Card::DMAWriteFrame
virtual bool DMAWriteFrame(const ULWord inFrameNumber, const ULWord *pInFrameBuffer, const ULWord inByteCount)
Transfers a single frame from the host to the AJA device.
Definition: ntv2dma.cpp:65
NTV2FrameData::UnlockAll
bool UnlockAll(CNTV2Card &inDevice)
Definition: ntv2democommon.cpp:408
CNTV2Card::SetEnableVANCData
virtual bool SetEnableVANCData(const bool inVANCenabled, const bool inTallerVANC, const NTV2Standard inStandard, const NTV2FrameGeometry inGeometry, const NTV2Channel inChannel=NTV2_CHANNEL1)
Definition: ntv2register.cpp:2720
CNTV2VPID::SetVPID
virtual CNTV2VPID & SetVPID(const ULWord inData)
Definition: ntv2vpid.h:71
NTV2_CC708PrimaryCaptionServiceNum
const int NTV2_CC708PrimaryCaptionServiceNum
Definition: ntv2caption708serviceinfo.h:18
AJACircularBuffer::SetAbortFlag
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...
Definition: circularbuffer.h:51
AJAAncillaryData_Cea608_Vanc
This class handles VANC-based CEA-608 caption data packets (not "analog" Line 21).
Definition: ancillarydata_cea608_vanc.h:26
NTV2ChannelToString
std::string NTV2ChannelToString(const NTV2Channel inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:5759
NTV2_INPUT_SOURCE_IS_SDI
#define NTV2_INPUT_SOURCE_IS_SDI(_inpSrc_)
Definition: ntv2enums.h:1242
NTV2_IS_VANCMODE_TALL
#define NTV2_IS_VANCMODE_TALL(__v__)
Definition: ntv2enums.h:3725
kCaptionDataSrc_708FBVanc
@ kCaptionDataSrc_708FBVanc
Definition: ntv2ccgrabber.h:50
GetNTV2StandardFromVideoFormat
NTV2Standard GetNTV2StandardFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:2277
ancillarydata_cea708.h
Declares the AJAAncillaryData_Cea708 class.
CNTV2Line21Captioner::DecodeLine
static bool DecodeLine(const UByte *pLineData, UByte &outChar1, UByte &outChar2)
Decodes the supplied line of 8-bit uncompressed ('2vuy') data and, if successful, returns the two 8-b...
NTV2Buffer::Fill
bool Fill(const T &inValue)
Fills me with the given scalar value.
Definition: ntv2publicinterface.h:6218
AJAThread::SetPriority
virtual AJAStatus SetPriority(AJAThreadPriority priority)
Definition: thread.cpp:133
CNTV2Card::AutoCirculateStart
virtual bool AutoCirculateStart(const NTV2Channel inChannel, const ULWord64 inStartTime=0)
Starts AutoCirculating the specified channel that was previously initialized by CNTV2Card::AutoCircul...
Definition: ntv2autocirculate.cpp:503
CaptionData::bGotField1Data
bool bGotField1Data
True if Field 1 bytes have been set; otherwise false.
Definition: ntv2caption608types.h:657
CNTV2Card::SetReference
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=(0))
Sets the device's clock reference source. See Video Output Clocking & Synchronization for more inform...
Definition: ntv2register.cpp:1484
GetDLOutInputXptFromChannel
NTV2InputXptID GetDLOutInputXptFromChannel(const NTV2Channel inDLOutWidget)
Definition: ntv2signalrouter.cpp:808
NTV2Line21Attributes
CEA-608 Character Attributes.
Definition: ntv2caption608types.h:357
AJA_STATUS_OPEN
@ AJA_STATUS_OPEN
Definition: types.h:388
CCGrabberConfig::fUseVanc
bool fUseVanc
If true, use Vanc, even if the device supports Anc insertion.
Definition: ntv2ccgrabber.h:70
CaptionData
This structure encapsulates all possible CEA-608 caption data bytes that may be associated with a giv...
Definition: ntv2caption608types.h:655
NTV2FrameData::LockAll
bool LockAll(CNTV2Card &inDevice)
Definition: ntv2democommon.cpp:387
gMixerNums
static const UWord gMixerNums[]
Definition: ntv2ccgrabber.cpp:1282
AUTOCIRCULATE_TRANSFER::GetInputTimeCodes
bool GetInputTimeCodes(NTV2TimeCodeList &outValues) const
Intended for capture, answers with the timecodes captured in my acTransferStatus member's acFrameStam...
Definition: ntv2publicinterface.cpp:2834
CNTV2Card::SetNumberAudioChannels
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
CNTV2Card::SetAudioBufferSize
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
AJAThread::Start
virtual AJAStatus Start()
Definition: thread.cpp:91
CNTV2DemoCommon::StripFormatString
static std::string StripFormatString(const std::string &inStr)
Definition: ntv2democommon.cpp:933
NTV2ReferenceSourceToString
std::string NTV2ReferenceSourceToString(const NTV2ReferenceSource inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7258
CaptionData::f2_char2
UByte f2_char2
Caption Byte 2 of Field 2.
Definition: ntv2caption608types.h:663
CCGrabberConfig::StringToCaptionDataSrc
static CaptionDataSrc StringToCaptionDataSrc(const std::string &inDataSrcStr)
Definition: ntv2ccgrabber.cpp:1664
AJALabelValuePairs
std::vector< AJALabelValuePair > AJALabelValuePairs
An ordered sequence of label/value pairs.
Definition: info.h:69
BIT
#define BIT(_x_)
Definition: ajatypes.h:561
CNTV2Card::SubscribeInputVerticalEvent
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: ntv2subscriptions.cpp:39
xHEX0N
#define xHEX0N(__x__, __n__)
Definition: ntv2publicinterface.h:5604
AJA_FAILURE
#define AJA_FAILURE(_status_)
Definition: types.h:371
NTV2_IS_VALID_AUDIO_SYSTEM
#define NTV2_IS_VALID_AUDIO_SYSTEM(__x__)
Definition: ntv2enums.h:3833
NTV2CCGrabber::CaptureThreadStatic
static void CaptureThreadStatic(AJAThread *pThread, void *pContext)
This is the capture thread's static callback function that gets called when the capture thread runs....
Definition: ntv2ccgrabber.cpp:636
AJAAncDataType_Cea608_Line21
@ AJAAncDataType_Cea608_Line21
CEA608 SD Closed Captioning ("Line 21" waveform)
Definition: ancillarydata.h:52
CNTV2CaptionDecoder708::SetSMPTE334AncData
virtual bool SetSMPTE334AncData(const AJAAncillaryData_Cea708 &inPacket)
Copies the given SMPTE 334 CDP data from the given ancillary data packet into my private CDP buffer.
Definition: ntv2captiondecoder708.h:106
CNTV2Card::EnableChannel
virtual bool EnableChannel(const NTV2Channel inChannel)
Enables the given FrameStore.
Definition: ntv2register.cpp:2097
NTV2_MODE_DISPLAY
@ NTV2_MODE_DISPLAY
Playout (output) mode, which reads from device SDRAM.
Definition: ntv2enums.h:1200
DeviceCapabilities::CanDoFrameBufferFormat
bool CanDoFrameBufferFormat(const NTV2PixelFormat inPF)
Definition: ntv2devicecapabilities.h:223
NTV2FrameData::AncBuffer
NTV2Buffer & AncBuffer(void)
Definition: ntv2democommon.h:113
NTV2FormatDescriptor::GetFullRasterHeight
ULWord GetFullRasterHeight(void) const
Definition: ntv2formatdescriptor.h:175
NTV2ChannelToAudioSystem
NTV2AudioSystem NTV2ChannelToAudioSystem(const NTV2Channel inChannel)
Converts the given NTV2Channel value into its equivalent NTV2AudioSystem.
Definition: ntv2utils.cpp:4927
AUTOCIRCULATE_TRANSFER::acANCBuffer
NTV2Buffer acANCBuffer
The host ancillary data buffer. This field is owned by the client application, and thus is responsibl...
Definition: ntv2publicinterface.h:7995
NTV2_XptAnalogOutInput
@ NTV2_XptAnalogOutInput
Definition: ntv2enums.h:2810
NTV2CCGrabber::NTV2CCGrabber
NTV2CCGrabber(const CCGrabberConfig &inConfigData)
Constructs me using the given configuration settings.
Definition: ntv2ccgrabber.cpp:40
NTV2CCGrabber::RouteOutputSignal
virtual bool RouteOutputSignal(const NTV2VideoFormat inVideoFormat)
Definition: ntv2ccgrabber.cpp:1311
CCGrabberConfig::fBurnCaptions
bool fBurnCaptions
If true, burn-in captions on 2nd channel.
Definition: ntv2ccgrabber.h:69
CNTV2Card::AutoCirculateStop
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...
Definition: ntv2autocirculate.cpp:519
GetTSIMuxInputXptFromChannel
NTV2InputXptID GetTSIMuxInputXptFromChannel(const NTV2Channel inTSIMuxer, const bool inLinkB=false)
Definition: ntv2signalrouter.cpp:993
memory.h
Declares the AJAMemory class.
DEVICE_ID_NOTFOUND
@ DEVICE_ID_NOTFOUND
Invalid or "not found".
Definition: ntv2enums.h:90
NTV2_ANCSIZE_MAX
#define NTV2_ANCSIZE_MAX
Definition: ntv2democommon.h:47
CaptureConfig::fInputSource
NTV2InputSource fInputSource
The device input connector to use.
Definition: ntv2democommon.h:271
CAPNOTE
#define CAPNOTE(_expr_)
Definition: ntv2democommon.h:31
CaptionData::f1_char1
UByte f1_char1
Caption Byte 1 of Field 1.
Definition: ntv2caption608types.h:658
AUTOCIRCULATE_TRANSFER::SetBuffers
bool SetBuffers(ULWord *pInVideoBuffer, const ULWord inVideoByteCount, ULWord *pInAudioBuffer, const ULWord inAudioByteCount, ULWord *pInANCBuffer, const ULWord inANCByteCount, ULWord *pInANCF2Buffer=NULL, const ULWord inANCF2ByteCount=0)
Sets my buffers for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2696
CNTV2CaptionDecoder608::GetDisplayChannel
virtual NTV2Line21Channel GetDisplayChannel(void) const
Answers with the caption channel that I'm currently focused on (or that I'm currently "burning" into ...
Definition: ntv2captiondecoder608.h:108
CNTV2CaptionDecoder708::GetDisplayChannel
virtual NTV2Line21Channel GetDisplayChannel(void) const
Answers with the caption channel that I'm currently focused on (or that I'm currently "burning" into ...
Definition: ntv2captiondecoder708.h:98
NTV2_OEM_TASKS
@ NTV2_OEM_TASKS
2: OEM: Device is configured by controlling application(s), with minimal driver involvement.
Definition: ntv2publicinterface.h:4292
GetDLOutOutputXptFromChannel
NTV2OutputXptID GetDLOutOutputXptFromChannel(const NTV2Channel inDLOutput, const bool inIsLinkB=false)
Definition: ntv2signalrouter.cpp:905
NTV2CCGrabber::ToggleVANC
virtual void ToggleVANC(void)
Toggles the use of VANC. (Debug, experimental)
Definition: ntv2ccgrabber.cpp:933
kOutputMode_Stats
@ kOutputMode_Stats
Definition: ntv2ccgrabber.h:38
AJATimeCode
Utility class for timecodes.
Definition: timecode.h:17
AJAAncillaryList::SetFromVANCData
static AJAStatus SetFromVANCData(const NTV2Buffer &inFrameBuffer, const NTV2FormatDescriptor &inFormatDesc, AJAAncillaryList &outPackets, const uint32_t inFrameNum=0)
Returns all packets found in the VANC lines of the given NTV2 frame buffer.
Definition: ancillarylist.cpp:880
NTV2FrameData::fTimecodes
NTV2TimeCodes fTimecodes
Map of TC indexes to NTV2_RP188 values.
Definition: ntv2democommon.h:87
CNTV2Card::SetAudioRate
virtual bool SetAudioRate(const NTV2AudioRate inRate, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the NTV2AudioRate for the given Audio System.
Definition: ntv2audio.cpp:205
NTV2_FBF_LAST
@ NTV2_FBF_LAST
Definition: ntv2enums.h:243
NTV2_AUDIOSYSTEM_INVALID
@ NTV2_AUDIOSYSTEM_INVALID
Definition: ntv2enums.h:3826
CNTV2CaptionDecoder608::UnsubscribeChangeNotification
virtual bool UnsubscribeChangeNotification(NTV2Caption608Changed *pInCallback, void *pInUserData=0)
Unsubscribes a prior change notification subscription.