AJA NTV2 SDK  17.0.1.1246
NTV2 SDK 17.0.1.1246
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 (::NTV2DeviceGetNumFrameStores(mDeviceID) < 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 (!::NTV2DeviceCanDoPlayback(mDeviceID))
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 (::NTV2DeviceGetNumVideoInputs(mDeviceID) < 1 || ::NTV2DeviceGetNumVideoOutputs(mDeviceID) < 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 (!::NTV2DeviceGetNumMixers(mDeviceID)) // 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 (!::NTV2DeviceCanDoFrameBufferFormat(mDeviceID, 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 (::NTV2DeviceCanDoMultiFormat(mDeviceID))
172  mDevice.SetMultiFormatMode(mConfig.fDoMultiFormat);
173 
174  if (!mConfig.fUseVanc && !DeviceAncExtractorIsAvailable()) // --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...
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 (::NTV2DeviceGetNumFrameStores(mDeviceID));
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 (!::NTV2DeviceCanDoInputSource(mDeviceID, 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 (::NTV2DeviceHasBiDirectionalSDI(mDeviceID)) // 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 (!::NTV2DeviceCanDoFrameBufferFormat(mDeviceID, 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 (::NTV2DeviceGetNumAudioSystems(mDeviceID));
343  if (numAudioSystems > 1 && UWord(mConfig.fInputChannel) < numAudioSystems)
344  mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fInputChannel);
345 
346  // Configure the audio system...
348  mDevice.SetNumberAudioChannels (::NTV2DeviceGetMaxAudioChannels(mDeviceID), 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 >= ::NTV2DeviceGetNumVideoOutputs(mDeviceID)) // Kona1 has 2 FrameStores/Channels, but only 1 SDI output
359  sdiOutput = ::NTV2DeviceGetNumVideoOutputs(mDeviceID) - 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 < ::NTV2DeviceGetNumVideoOutputs(mDeviceID); sdiOutput++)
364  if (!::NTV2DeviceHasBiDirectionalSDI(mDeviceID)
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(mDeviceID, 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(mDeviceID, 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(mDeviceID, 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 (::NTV2DeviceHasBiDirectionalSDI(mDeviceID))
543  {
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
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 (::NTV2DeviceHasBiDirectionalSDI(mDeviceID) && 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) >= ::NTV2DeviceGetNumVideoChannels(mDeviceID))
596  break;
597  if (chan != sdiInputAsChan)
598  if (::NTV2DeviceCanDoWidget(mDeviceID, g3GSDIOutputs[chan]) || ::NTV2DeviceCanDoWidget(mDeviceID, 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 (::NTV2DeviceCanDo12gRouting(mDeviceID))
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
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 (!::NTV2DeviceCanDoVideoFormat(mDeviceID, result)) // Can this device handle this video format?
889  osserr << mDevice.GetModelName() << " can't handle " << ::NTV2VideoFormatToString(result);
890  else if (mVPIDInfoDS1.IsValid() && mVPIDInfoDS1.IsStandardTwoSampleInterleave() && !::NTV2DeviceCanDo425Mux(mDeviceID))
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 {
936 }
937 
938 
940 {
941  mConfig.fUseVanc = !mConfig.fUseVanc;
942  cerr << endl << "## NOTE: VANC frame geometry " << (mConfig.fUseVanc ? "enabled" : "disabled") << endl;
943 }
944 
945 
947 {
948  OutputMode mode (mConfig.fOutputMode);
949  mode = OutputMode(mode+1);
950  if (!IS_VALID_OutputMode(mode))
952  if (mConfig.fOutputMode != mode)
953  cerr << endl << "## NOTE: Output changed to '" << CCGrabberConfig::OutputModeToString(mode) << "'" << endl;
954  mConfig.fOutputMode = mode;
955 }
956 
958 {
959  CaptionDataSrc src (mConfig.fCaptionSrc);
960  src = CaptionDataSrc(src+1);
961  if (!IS_VALID_CaptionDataSrc(src))
963  if (mConfig.fCaptionSrc != src)
964  cerr << endl << "## NOTE: CC source changed to '" << CCGrabberConfig::CaptionDataSrcToString(src) << "'" << endl;
965  mConfig.fCaptionSrc = src;
966 }
967 
969 {
970  NTV2PixelFormat pf (mConfig.fPixelFormat);
971  do
972  {
973  pf = NTV2PixelFormat(pf+1);
974  if (pf == NTV2_FBF_LAST)
975  pf = NTV2_FBF_FIRST;
976  } while (NTV2_IS_FBF_PLANAR(pf) || !::NTV2DeviceCanDoFrameBufferFormat(mDeviceID, pf));
977  if (mConfig.fPixelFormat != pf)
978  cerr << endl << "## NOTE: Pixel format changed to " << ::NTV2FrameBufferFormatToString(pf) << endl;
979  mConfig.fPixelFormat = pf;
980 }
981 
982 void NTV2CCGrabber::ExtractClosedCaptionData (const uint32_t inFrameNum, const NTV2VideoFormat inVideoFormat)
983 {
984  AJAAncillaryList ancPackets, vancPackets;
985  CaptionData captionData708Anc, captionData708Vanc, captionData608Anc, captionData608Vanc, captionDataL21Anc, captionDataL21; // The 608 caption byte pairs (one pair per field)
986  const NTV2FormatDescriptor formatDesc (inVideoFormat, mConfig.fPixelFormat, mVancMode);
987 
988  if (NTV2_IS_VANCMODE_ON(mVancMode) || DeviceAncExtractorIsAvailable()) // Gotta have at least VANC or AncExt
989  {
990  // Get all VANC packets...
991  if (NTV2_IS_VANCMODE_ON(mVancMode))
992  {
993  AJAAncillaryList::SetFromVANCData (mInputXferInfo.acVideoBuffer, formatDesc, vancPackets, inFrameNum);
994  vancPackets.ParseAllAncillaryData();
995  }
996 
997  // Get all anc extractor packets...
999  {
1000  const NTV2Buffer validAncF1 (mInputXferInfo.acANCBuffer.GetHostAddress(0), mInputXferInfo.GetCapturedAncByteCount(false));
1001  const NTV2Buffer validAncF2 (mInputXferInfo.acANCField2Buffer.GetHostAddress(0), mInputXferInfo.GetCapturedAncByteCount(true));
1002  AJAAncillaryList::SetFromDeviceAncBuffers (validAncF1, validAncF2, ancPackets, inFrameNum);
1003  ancPackets.ParseAllAncillaryData();
1004  }
1005 
1006  if (NTV2_IS_VANCMODE_ON(mVancMode))
1007  { // Compare with what we got from VANC lines:
1008  NTV2StringList diffs;
1009  if (!ancPackets.CompareWithInfo (diffs, vancPackets, true/*ignoreLoc*/, false /*ignoreChksum*/))
1010  {
1011  NTV2StringList lines(aja::split(diffs.at(0), "\n")); // Only log first diff
1012  CAPDBG(DEC(diffs.size()) << " VANC/AncExt diff(s): " << lines.at(0));
1013  for (size_t n(1); n < lines.size(); n++)
1014  CAPDBG(lines.at(n));
1015  }
1016  }
1017  }
1018 
1019  // Get Line21 CC data...
1020  if (NTV2_IS_SD_VIDEO_FORMAT(inVideoFormat) && (mConfig.fPixelFormat == NTV2_FBF_8BIT_YCBCR || mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR))
1021  { // Anything encoded in Line 21?
1022  ULWord line21RowOffset(0);
1023  const UByte * pLine21(AJA_NULL);
1024  formatDesc.GetLineOffsetFromSMPTELine (21, line21RowOffset);
1025  pLine21 = AsConstUBytePtr(formatDesc.GetRowAddress(mInputXferInfo.acVideoBuffer.GetHostPointer(),
1026  line21RowOffset));
1027  if (pLine21)
1028  {
1029  if (mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR) // CNTV2Line21Captioner::DecodeLine requires 8-bit YUV
1030  ::ConvertLine_v210_to_2vuy(AsConstULWordPtr(pLine21), (UByte*)(pLine21), 720); // Convert YUV10 to YUV8 in-place
1031  captionDataL21.bGotField1Data = CNTV2Line21Captioner::DecodeLine(pLine21, captionDataL21.f1_char1, captionDataL21.f1_char2);
1032  }
1033  pLine21 = AsConstUBytePtr(formatDesc.GetRowAddress(mInputXferInfo.acVideoBuffer.GetHostPointer(),
1034  line21RowOffset+1)); // F2 should be on next row
1035  if (pLine21)
1036  {
1037  if (mConfig.fPixelFormat == NTV2_FBF_10BIT_YCBCR) // CNTV2Line21Captioner::DecodeLine requires 8-bit YUV
1038  ::ConvertLine_v210_to_2vuy(AsConstULWordPtr(pLine21), (UByte*)(pLine21), 720); // Convert YUV10 to YUV8 in-place
1039  captionDataL21.bGotField2Data = CNTV2Line21Captioner::DecodeLine(pLine21, captionDataL21.f2_char1, captionDataL21.f2_char2);
1040  }
1041  }
1042 
1043  // Any 608 packets (anc extractor)?
1044  if (ancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea608_Vanc, 0)) // F1
1045  {
1047  if (pkt608F1.GetPayloadData() && pkt608F1.GetPayloadByteCount() && AJA_SUCCESS(pkt608F1.ParsePayloadData()))
1048  pkt608F1.GetCEA608Bytes (captionData608Anc.f1_char1, captionData608Anc.f1_char2, captionData608Anc.bGotField1Data);
1049  }
1050  if (ancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea608_Vanc, 1)) // F2
1051  {
1053  if (pkt608F2.GetPayloadData() && pkt608F2.GetPayloadByteCount() && AJA_SUCCESS(pkt608F2.ParsePayloadData()))
1054  pkt608F2.GetCEA608Bytes(captionData608Anc.f2_char1, captionData608Anc.f2_char2, captionData608Anc.bGotField2Data);
1055  }
1056 
1057  // Any 608 packets (Vanc)?
1059  {
1061  if (pkt608F1.GetPayloadData() && pkt608F1.GetPayloadByteCount() && AJA_SUCCESS(pkt608F1.ParsePayloadData()))
1062  pkt608F1.GetCEA608Bytes (captionData608Vanc.f1_char1, captionData608Vanc.f1_char2, captionData608Vanc.bGotField1Data);
1063  }
1065  {
1067  if (pkt608F2.GetPayloadData() && pkt608F2.GetPayloadByteCount() && AJA_SUCCESS(pkt608F2.ParsePayloadData()))
1068  pkt608F2.GetCEA608Bytes(captionData608Vanc.f2_char1, captionData608Vanc.f2_char2, captionData608Vanc.bGotField2Data);
1069  }
1070 
1071  // Any 708 packets (vanc)?
1073  {
1074  AJAAncillaryData vancCEA708DataIn (vancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea708));
1075  bool hasParityErrors (false);
1076  if (vancCEA708DataIn.GetPayloadData() && vancCEA708DataIn.GetPayloadByteCount() && AJA_SUCCESS(vancCEA708DataIn.ParsePayloadData()))
1077  if (m708DecoderVanc->SetSMPTE334AncData (vancCEA708DataIn.GetPayloadData(), vancCEA708DataIn.GetPayloadByteCount()))
1078  if (m708DecoderVanc->ParseSMPTE334AncPacket(hasParityErrors))
1079  {
1080  vector<UByte> svcBlk;
1081  size_t blkSize(0), byteCount(0);
1082  int svcNum(0);
1083  bool isExtendedSvc(false);
1084  if (!hasParityErrors)
1085  captionData708Vanc = m708DecoderVanc->GetCC608CaptionData();
1086  if (m708DecoderVanc->GetNextServiceBlockInfoFromQueue (NTV2_CC708PrimaryCaptionServiceNum, blkSize, byteCount, svcNum, isExtendedSvc))
1087  m708DecoderVanc->GetNextServiceBlockFromQueue(NTV2_CC708PrimaryCaptionServiceNum, svcBlk); // Pop queued service block
1088  }
1089  }
1090  // Any 708 packets (anc extractor)?
1092  {
1093  AJAAncillaryData ancCEA708DataIn (ancPackets.GetAncillaryDataWithType(AJAAncDataType_Cea708));
1094  bool hasParityErrors (false);
1095  if (ancCEA708DataIn.GetPayloadData() && ancCEA708DataIn.GetPayloadByteCount() && AJA_SUCCESS(ancCEA708DataIn.ParsePayloadData()))
1096  if (m708DecoderAnc->SetSMPTE334AncData (ancCEA708DataIn.GetPayloadData(), ancCEA708DataIn.GetPayloadByteCount()))
1097  if (m708DecoderAnc->ParseSMPTE334AncPacket(hasParityErrors))
1098  {
1099  vector<UByte> svcBlk;
1100  size_t blkSize(0), byteCount(0);
1101  int svcNum(0);
1102  bool isExtendedSvc(false);
1103  if (!hasParityErrors)
1104  captionData708Anc = m708DecoderAnc->GetCC608CaptionData();
1105  if (m708DecoderAnc->GetNextServiceBlockInfoFromQueue (NTV2_CC708PrimaryCaptionServiceNum, blkSize, byteCount, svcNum, isExtendedSvc))
1106  m708DecoderAnc->GetNextServiceBlockFromQueue(NTV2_CC708PrimaryCaptionServiceNum, svcBlk); // Pop queued service block
1107  }
1108  }
1109  // Any "analog" packets?
1111  {
1113  if (AJA_SUCCESS(ancEIA608DataIn.ParsePayloadData()))
1114  ancEIA608DataIn.GetCEA608Bytes(captionDataL21Anc.f1_char1, captionDataL21Anc.f1_char2, captionDataL21Anc.bGotField1Data);
1116  {
1118  if (AJA_SUCCESS(ancEIA608F2.ParsePayloadData()))
1119  ancEIA608F2.GetCEA608Bytes(captionDataL21Anc.f2_char1, captionDataL21Anc.f2_char2, captionDataL21Anc.bGotField2Data);
1120  }
1121  }
1122 
1123  // Compare CaptionData results...
1124  ostringstream ossCompare;
1125  const CaptionData * p608CaptionData(AJA_NULL);
1126  if (NTV2_IS_SD_VIDEO_FORMAT(inVideoFormat))
1127  {
1128  const CaptionData * pL21CaptionData (AJA_NULL);
1129  if (captionDataL21.HasData() && captionDataL21Anc.HasData())
1130  if (captionDataL21 != captionDataL21Anc)
1131  ossCompare << "L21Vanc != L21Anlg: " << captionDataL21 << " " << captionDataL21Anc << endl;
1132  if (captionDataL21.HasData())
1133  pL21CaptionData = &captionDataL21;
1134  else if (captionDataL21Anc.HasData())
1135  pL21CaptionData = &captionDataL21Anc;
1136  if (captionData608Anc.HasData() && pL21CaptionData)
1137  if (captionData608Anc != *pL21CaptionData)
1138  ossCompare << "608 != L21: " << captionData608Anc << " " << *pL21CaptionData << endl;
1139  if (captionData608Anc.HasData())
1140  p608CaptionData = &captionData608Anc; // 608 anc has precedence
1141  else if (pL21CaptionData)
1142  p608CaptionData = pL21CaptionData; // followed by line 21
1143  }
1144  else
1145  {
1146  if (captionData608Anc.HasData() && captionData708Anc.HasData())
1147  if (captionData608Anc != captionData708Anc)
1148  ossCompare << "608anc != 708anc: " << captionData608Anc << " " << captionData708Anc << endl;
1149  if (captionData608Vanc.HasData() && captionData708Vanc.HasData())
1150  if (captionData608Vanc != captionData708Vanc)
1151  ossCompare << "608vanc != 708vanc: " << captionData608Vanc << " " << captionData708Vanc << endl;
1152  if (captionData708Anc.HasData())
1153  p608CaptionData = &captionData708Anc; // 608-in-708anc has highest precedence
1154  else if (captionData708Vanc.HasData())
1155  p608CaptionData = &captionData708Vanc; // followed by 608-in-708vanc
1156  else if (captionData608Anc.HasData())
1157  p608CaptionData = &captionData608Anc; // followed by 608anc
1158  else if (captionData608Vanc.HasData())
1159  p608CaptionData = &captionData608Vanc; // followed by 608vanc
1160  }
1161  if (!ossCompare.str().empty())
1162  CAPDBG("CaptionData mis-compare(s): " << ossCompare.str());
1163 
1164  // Set p608CaptionData based on mConfig.fCaptionSrc...
1165  switch (mConfig.fCaptionSrc)
1166  { // captionData708Anc, captionData708Vanc, captionData608Anc, captionData608Vanc, captionDataL21Anc, captionDataL21
1167  case kCaptionDataSrc_Line21: p608CaptionData = &captionDataL21Anc; break;
1168  case kCaptionDataSrc_608FBVanc: p608CaptionData = &captionDataL21; break;
1169  case kCaptionDataSrc_708FBVanc: p608CaptionData = &captionData708Vanc; break;
1170  case kCaptionDataSrc_608Anc: p608CaptionData = &captionData608Anc; break;
1171  case kCaptionDataSrc_708Anc: p608CaptionData = &captionData708Anc; break;
1172  default: break;
1173  }
1174 
1175  if (!p608CaptionData)
1176  return; // Got nothing
1177 
1178  // This demo only handles CEA-608 captions (no Teletext, IBU, etc.)
1179  // The 608 decoder expects to be called once per frame (to implement flashing characters, smooth-scroll roll-up, etc.).
1180  // Pass the caption byte pairs to it for processing (even if captionData.HasData returns false)...
1181  m608Decoder->ProcessNew608FrameData(*p608CaptionData);
1182 
1183  DoCCOutput(inFrameNum, *p608CaptionData, inVideoFormat);
1184 
1185 } // ExtractClosedCaptionData
1186 
1187 
1188 void NTV2CCGrabber::DoCCOutput (const uint32_t inFrameNum, const CaptionData & inCCData, const NTV2VideoFormat inVideoFormat)
1189 {
1190  // Print out the caption characters...
1191  const bool isFirstTime (mLastOutFrame == 0 && inFrameNum > mLastOutFrame);
1192  char char1(0), char2(0);
1193  const bool showField2 (IsField2Line21CaptionChannel(m608Channel));
1194  const bool gotData (showField2 ? inCCData.bGotField2Data : inCCData.bGotField1Data);
1195  switch (mConfig.fOutputMode)
1196  {
1198  if (gotData)
1199  { // Can't distinguish between CC1/CC2/Tx1/Tx2 for F1 (nor CC3/CC4/Tx3/Tx4 for F2).
1200  // They'll just have to be interspersed for now...
1201  char1 = (char(showField2 ? inCCData.f2_char1 : inCCData.f1_char1) & 0x7F);
1202  char2 = (char(showField2 ? inCCData.f2_char2 : inCCData.f1_char2) & 0x7F);
1203  if (char1 >= ' ' && char1 <= '~')
1204  {
1205  if (mLastOutStr != " " || char1 != ' ')
1206  {cout << char1 << flush; mLastOutStr = string(1,char1);}
1207  if (char2 >= ' ' && char2 <= '~')
1208  {
1209  if (mLastOutStr != " " || char2 != ' ')
1210  {cout << char2 << flush; mLastOutStr = string(1,char2);}
1211  }
1212  }
1213  else if (mLastOutStr != " ")
1214  {cout << " " << flush; mLastOutStr = " ";}
1215  }
1216  break;
1218  {
1219  if (inFrameNum == (mLastOutFrame+1))
1220  {
1221  mLastOutFrame = inFrameNum;
1222  if ((mLastOutFrame - mFirstOutFrame) < MAX_ACCUM_FRAME_COUNT)
1223  break; // Don't spew yet -- keep going
1224  }
1225  const string currentScreen(m608Decoder->GetOnAirCharacters());
1226  if (currentScreen != mLastOutStr)
1227  cout << currentScreen << endl;
1228  mLastOutStr = currentScreen;
1229  mFirstOutFrame = mLastOutFrame = inFrameNum;
1230  break;
1231  }
1233  {
1234  uint16_t u16(uint16_t(uint16_t(showField2 ? inCCData.f2_char1 : inCCData.f1_char1) << 8) | uint16_t(showField2 ? inCCData.f2_char2 : inCCData.f1_char2));
1235  ostringstream oss;
1236  oss << Hex0N(u16,4);
1237  mLastOutStr.append(mLastOutStr.empty() ? "\t" : " ");
1238  mLastOutStr.append(oss.str());
1239  if (inFrameNum == (mLastOutFrame+1))
1240  { // Save for later
1241  mLastOutFrame = inFrameNum;
1242  if ((mLastOutFrame - mFirstOutFrame) < MAX_ACCUM_FRAME_COUNT)
1243  break; // Don't spew yet -- keep going
1244  }
1245  if (isFirstTime)
1246  cout << "Scenarist_SCC V1.0" << endl;
1247 
1248  string tcStr;
1249  AJATimeCode tcFirst(mFirstOutFrame);
1251  tcFirst.QueryString(tcStr, tcBase, false);
1252  cout << endl << tcStr << ":" << mLastOutStr << endl;
1253  mFirstOutFrame = mLastOutFrame = inFrameNum;
1254  mLastOutStr.clear();
1255  break;
1256  }
1257  case kOutputMode_Stats:
1258  if (inFrameNum % 60 == 0) // Every 60 frames
1259  {
1260  CNTV2CaptionDecodeChannel608Ptr chDecoder (m608Decoder->Get608ChannelDecoder(m608Decoder->GetDisplayChannel()));
1261  if (chDecoder)
1262  {
1263  const vector<uint32_t> stats (chDecoder->GetStats());
1264  AJALabelValuePairs info;
1266  for (size_t num(0); num < stats.size(); num++)
1267  {
1269  if (title.empty())
1270  break;
1271  if (!stats[num])
1272  continue;
1273  ostringstream oss; oss << DEC(stats[num]);
1274  AJASystemInfo::append(info, title, oss.str());
1275  }
1276  cout << AJASystemInfo::ToString(info) << endl;
1277  }
1278  }
1279  break;
1280  default: break;
1281  }
1282 } // DoCCOutput
1283 
1284 
1286 
1287 
1288 static const UWord gMixerNums [] = {0, 0, 1, 1, 2, 2, 3, 3};
1289 
1290 
1292 {
1293  NTV2_ASSERT (mConfig.fBurnCaptions); // Must be burning captions
1294 
1295  // Configure the output FrameStore...
1296  mDevice.EnableChannel (mOutputChannel);
1297  mDevice.SetMode (mOutputChannel, NTV2_MODE_DISPLAY);
1298  mDevice.SetFrameBufferFormat (mOutputChannel, mPlayoutFBF);
1299  mDevice.SetVideoFormat (inVideoFormat, /*retailMode?*/false, /*keepVANC?*/false, /*channel*/mOutputChannel);
1300  mDevice.SetEnableVANCData(NTV2_IS_VANCMODE_TALL(mVancMode), NTV2_IS_VANCMODE_TALLER(mVancMode), mOutputChannel);
1301 
1302  // RGB: Set up mixer to "mix" mode, FG raster "unshaped", BG raster "full raster" and VANC pass-thru from BG...
1303  const UWord mixerNumber (gMixerNums[mOutputChannel]);
1304  mDevice.SetMixerMode (mixerNumber, NTV2MIXERMODE_FOREGROUND_ON);
1307  mDevice.SetMixerVancOutputFromForeground (mixerNumber, false); // false means "use BG VANC, not FG"
1308  cerr << "## NOTE: Caption burn-in using mixer/keyer " << (mixerNumber+1) << " on " << ::NTV2ChannelToString(mOutputChannel)
1309  << ", " << ::NTV2FrameBufferFormatToString(mPlayoutFBF)
1310  << ", " << ::NTV2VideoFormatToString(inVideoFormat) << endl;
1311 
1312  return AJA_STATUS_SUCCESS;
1313 
1314 } // SetupOutputVideo
1315 
1316 
1318 {
1319  NTV2_ASSERT (mConfig.fBurnCaptions); // Must be burning captions
1320  const NTV2OutputCrosspointID frameStoreOutputRGB (::GetFrameBufferOutputXptFromChannel (mOutputChannel, true)); // true=RGB
1321  const NTV2OutputCrosspointID cscOutputYUV (::GetCSCOutputXptFromChannel (mOutputChannel));
1322  const NTV2OutputCrosspointID cscOutputKey (::GetCSCOutputXptFromChannel (mOutputChannel, true)); // true=key
1323  const NTV2OutputCrosspointID mixerOutputYUV (::GetMixerOutputXptFromChannel (mOutputChannel));
1325  const NTV2Standard outputStandard (::GetNTV2StandardFromVideoFormat (inVideoFormat));
1326  const bool canVerify (mDevice.HasCanConnectROM());
1327  UWord connectFailures (0);
1328 
1329  if (mConfig.fDoMultiFormat)
1330  {
1331  // Multiformat --- route the one SDI output to the mixer's YUV output, and set its output standard...
1332  if (::NTV2DeviceHasBiDirectionalSDI(mDeviceID))
1333  mDevice.SetSDITransmitEnable (mOutputChannel, true);
1334  if (::NTV2DeviceCanDoWidget(mDeviceID, g3GSDIOutputs[mOutputChannel]) || ::NTV2DeviceCanDoWidget(mDeviceID, gSDIOutputs[mOutputChannel]))
1335  {
1336  if (!mDevice.Connect (::GetSDIOutputInputXpt(mOutputChannel), mixerOutputYUV, canVerify)) connectFailures++;
1337  mDevice.SetSDIOutputStandard (mOutputChannel, outputStandard);
1338  }
1339  }
1340  else
1341  {
1342  // If not multiformat: Route all SDI outputs to the mixer's YUV output...
1343  const ULWord numVideoOutputs (::NTV2DeviceGetNumVideoOutputs(mDeviceID));
1344  const NTV2Channel startNum (NTV2_CHANNEL1);
1345  const NTV2Channel endNum (NTV2_CHANNEL_INVALID);
1346  const NTV2Channel sdiInputAsChan (::NTV2InputSourceToChannel(mConfig.fInputSource));
1347 
1348  for (NTV2Channel chan(startNum); chan < endNum; chan = NTV2Channel(chan + 1))
1349  {
1350  if (ULWord(chan) >= numVideoOutputs)
1351  break;
1352  if (::NTV2DeviceHasBiDirectionalSDI(mDeviceID))
1353  {
1354  if (chan == sdiInputAsChan)
1355  continue; // Skip the input
1356  mDevice.SetSDITransmitEnable (chan, true);
1357  }
1358  if (::NTV2DeviceCanDoWidget(mDeviceID, g3GSDIOutputs[chan]) || ::NTV2DeviceCanDoWidget(mDeviceID, gSDIOutputs[chan]))
1359  {
1360  if (!mDevice.Connect (::GetSDIOutputInputXpt(chan), mixerOutputYUV, canVerify)) connectFailures++;
1361  mDevice.SetSDIOutputStandard (chan, outputStandard);
1362  }
1363  } // for each output spigot
1364  }
1365 
1366  // Connect CSC video input to frame buffer's RGB output:
1367  if (!mDevice.Connect (::GetCSCInputXptFromChannel(mOutputChannel), frameStoreOutputRGB, canVerify)) connectFailures++;
1368  // Connect mixer's foreground video input to the CSC's YUV video output:
1369  if (!mDevice.Connect (::GetMixerFGInputXpt(mOutputChannel), cscOutputYUV, canVerify)) connectFailures++;
1370  // Connect mixer's foreground key input to the CSC's YUV key output:
1371  if (!mDevice.Connect (::GetMixerFGInputXpt(mOutputChannel, true), cscOutputKey, canVerify)) connectFailures++;
1372  // Connect mixer's background video input to the SDI input:
1373  if (!mDevice.Connect (::GetMixerBGInputXpt(mOutputChannel), signalInput, canVerify)) connectFailures++;
1374 
1375  if (!mConfig.fDoMultiFormat)
1376  {
1377  // Connect more outputs -- HDMI, analog, SDI monitor, etc... (Don't bother to verify these connections)
1378  if (::NTV2DeviceCanDoWidget (mDeviceID, NTV2_WgtHDMIOut1))
1379  mDevice.Connect (NTV2_XptHDMIOutInput, mixerOutputYUV);
1380  if (::NTV2DeviceCanDoWidget (mDeviceID, NTV2_WgtHDMIOut1v2))
1381  mDevice.Connect (NTV2_XptHDMIOutQ1Input, mixerOutputYUV);
1382  if (::NTV2DeviceCanDoWidget (mDeviceID, NTV2_WgtAnalogOut1))
1383  mDevice.Connect (NTV2_XptAnalogOutInput, mixerOutputYUV);
1384  if (::NTV2DeviceCanDoWidget (mDeviceID, NTV2_WgtSDIMonOut1))
1385  mDevice.Connect (::GetSDIOutputInputXpt (NTV2_CHANNEL5), mixerOutputYUV);
1386  }
1387  return connectFailures == 0;
1388 
1389 } // RouteOutputSignal
1390 
1391 
1392 // Starts the play thread
1394 {
1395  // Create and start the playout thread...
1396  NTV2_ASSERT(mConfig.fBurnCaptions);
1397  AJAStatus result (mPlayoutThread.Attach(PlayThreadStatic, this));
1398  if (AJA_SUCCESS(result))
1399  result = mPlayoutThread.SetPriority(AJA_ThreadPriority_High);
1400  if (AJA_SUCCESS(result))
1401  result = mPlayoutThread.Start();
1402  return result;
1403 
1404 } // StartPlayThread
1405 
1406 
1407 // The playout thread function
1408 void NTV2CCGrabber::PlayThreadStatic (AJAThread * pThread, void * pContext) // static
1409 {
1410  (void) pThread;
1411  // Grab the NTV2Burn instance pointer from the pContext parameter,
1412  // then call its PlayFrames method...
1413  NTV2CCGrabber * pApp (reinterpret_cast <NTV2CCGrabber *> (pContext));
1414  pApp->PlayFrames ();
1415 
1416 } // PlayThreadStatic
1417 
1418 
1420 {
1421  const NTV2VideoFormat videoFormat (mDevice.GetInputVideoFormat(mConfig.fInputSource));
1423  ULWord fbNum (10); // Bounce between frames 10 & 11
1424  const string indicators [] = {"/", "-", "\\", "|", ""};
1425  AUTOCIRCULATE_STATUS acStatus;
1426 
1427  CAPNOTE("Thread started");
1428  SetupOutputVideo (videoFormat); // Set up device output
1429  RouteOutputSignal (videoFormat); // Set up output signal routing
1430  mDevice.GetVANCMode (vancMode, mConfig.fInputChannel);
1431  if (mDevice.AutoCirculateInitForOutput (mOutputChannel, 2) && mDevice.AutoCirculateGetStatus (mOutputChannel, acStatus)) // Find out which buffers we got
1432  fbNum = ULWord(acStatus.acStartFrame); // Use them
1433  else if (mDevice.AutoCirculateGetStatus(mConfig.fInputChannel, acStatus)) // Use the frame just past the last input A/C frame
1434  fbNum = ULWord(acStatus.GetEndFrame()) + 1;
1435 
1436  const NTV2FormatDesc formatDesc (videoFormat, mPlayoutFBF, vancMode);
1437  const uint32_t bufferSizeBytes (formatDesc.GetTotalRasterBytes ());
1438  const uint32_t activeSizeBytes (formatDesc.GetVisibleRasterBytes ());
1439  ULWord pingPong (0); // Bounce between 0 and 1
1440  UWord consecSyncErrs (0);
1441  // Caption status head-up-display...
1442  static uint64_t frameTally (0);
1443  const string strVideoFormat (CNTV2DemoCommon::StripFormatString (::NTV2VideoFormatToString (videoFormat)));
1444  ULWord lastErrorTally (0);
1445 
1446  // Allocate host frame buffer for blitting captions into...
1447  NTV2Buffer hostBuffer;
1448  if (!hostBuffer.Allocate(bufferSizeBytes, /*pageAligned*/true))
1449  {cerr << "## NOTE: Caption burn-in failed -- unable to allocate " << bufferSizeBytes << "-byte caption video buffer" << endl; return;}
1450  NTV2Buffer visibleRgn (formatDesc.GetTopVisibleRowAddress(AsUBytePtr(hostBuffer.GetHostPointer())),activeSizeBytes);
1451 
1452  // Clear both device ping/pong buffers to fully transparent, all black...
1453  hostBuffer.Fill(ULWord(0));
1454  mDevice.DMAWriteFrame (fbNum + 0, AsULWordPtr(hostBuffer.GetHostPointer()), bufferSizeBytes);
1455  mDevice.DMAWriteFrame (fbNum + 1, AsULWordPtr(hostBuffer.GetHostPointer()), bufferSizeBytes);
1456  mDevice.SetOutputFrame (mOutputChannel, fbNum + pingPong);
1457  pingPong = pingPong ? 0 : 1;
1458 
1459  // Do forever (until Quit)...
1460  while (!mGlobalQuit)
1461  {
1462  // Wait for the next frame to become ready to "consume"...
1463  NTV2FrameData * pFrameData(mCircularBuffer.StartConsumeNextBuffer());
1464  if (pFrameData)
1465  {
1466  // "Burn" captions into the host buffer before it gets sent to the AJA device...
1467  m608Decoder->BurnCaptions (hostBuffer, formatDesc);
1468  m608Decoder->IdleFrame(); // This is needed for captions that flash/blink
1469 
1470  if (mHeadUpDisplayOn)
1471  {
1472  ostringstream oss;
1473  const string strCaptionChan (::NTV2Line21ChannelToStr(NTV2_IS_HD_VIDEO_FORMAT(videoFormat)
1474  ? m708DecoderAnc->GetDisplayChannel()
1475  : m608Decoder->GetDisplayChannel()));
1476  oss << indicators [mCaptionDataTally % 4] << " " << strCaptionChan << " " << frameTally++ << " "
1477  << formatDesc.GetRasterWidth() << "x" << formatDesc.GetFullRasterHeight() << (mConfig.fUseVanc ? "v" : " ") << strVideoFormat;
1478 
1479  const ULWord newErrorTally (mErrorTally);
1480  const NTV2Line21Attributes & color (lastErrorTally != newErrorTally ? kRedOnTransparentBG : kGreenOnTransparentBG);
1481  CNTV2CaptionRenderer::BurnString (oss.str(), color, hostBuffer, formatDesc, 7, 1);
1482  lastErrorTally = newErrorTally;
1483 
1484  if (!pFrameData->fTimecodes.empty())
1485  {
1486  const NTV2_RP188 & tc (pFrameData->fTimecodes.begin()->second);
1487  if (tc.IsValid() && tc.fDBB & BIT(16)) // Bit 16 will be set if this frame had timecode
1488  {
1489  CRP188 rp188(tc);
1490  CNTV2CaptionRenderer::BurnString (rp188.GetRP188CString(), kGreenOnTransparentBG, hostBuffer, formatDesc, 8, 1);
1491  }
1492  }
1493  }
1494 
1495  // Transfer the caption raster to the device, then ping-pong it into the mixer foreground...
1496  mDevice.DMAWriteFrame (fbNum + pingPong, AsULWordPtr(visibleRgn.GetHostPointer()), activeSizeBytes);
1497  mDevice.SetOutputFrame (mOutputChannel, fbNum + pingPong); // Toggle device frame buffer
1498  pingPong = pingPong ? 0 : 1; // Switch device frame numbers for next time
1499  visibleRgn.Fill(ULWord(0)); // Clear visible region of host buffer to fully-transparent, all-black again
1500 
1501  // Signal that the frame has been "consumed"...
1502  mCircularBuffer.EndConsumeNextBuffer ();
1503 
1504  // Check for format change...
1505  if (videoFormat != mDevice.GetInputVideoFormat(mConfig.fInputSource))
1506  {
1507  cerr << "## NOTE: Caption burn-in stopped due to video format change -- was " << strVideoFormat
1508  << ", now " << ::NTV2VideoFormatToString (mDevice.GetInputVideoFormat(mConfig.fInputSource)) << endl;
1509  m608Decoder->Reset(); // Don't leave captions from old video stream on-screen
1510  m708DecoderAnc->Reset();
1511  m708DecoderVanc->Reset();
1512  break;
1513  }
1514 
1515  // Check mixer sync...
1516  bool mixerSyncOK (false);
1517  mDevice.GetMixerSyncStatus (gMixerNums[mOutputChannel], mixerSyncOK);
1518  if (mixerSyncOK)
1519  consecSyncErrs = 0;
1520  else if (++consecSyncErrs > 60) // Bail if lack of mixer sync for longer than ~1 sec
1521  {cerr << "#MXSYNC#"; consecSyncErrs = 0;} // break;}
1522  } // if pPlayData
1523  } // loop til quit signaled
1524 
1525  if (mDevice.AutoCirculateGetStatus (mOutputChannel, acStatus) && !acStatus.IsStopped())
1526  mDevice.AutoCirculateStop(mOutputChannel);
1527  CAPNOTE("Thread completed, will exit");
1528 
1529 } // PlayFrames
1530 
1531 
1533 {
1534  if (m608Channel != inNewChannel)
1535  {
1536  m608Channel = inNewChannel;
1537  if (m608Decoder)
1538  m608Decoder->SetDisplayChannel(m608Channel);
1539  if (m708DecoderAnc)
1540  m708DecoderAnc->SetDisplayChannel(m608Channel);
1541  if (m708DecoderVanc)
1542  m708DecoderVanc->SetDisplayChannel(m608Channel);
1543  cerr << endl << "## NOTE: Caption display channel changed to '" << ::NTV2Line21ChannelToStr(m608Channel) << "'" << endl;
1544  }
1545 }
1546 
1547 
1549 { (void) inChangeInfo;
1550  mCaptionDataTally++;
1551 }
1552 
1553 
1554 void NTV2CCGrabber::Caption608ChangedStatic (void * pInstance, const NTV2Caption608ChangeInfo & inChangeInfo) // STATIC
1555 {
1556  NTV2CCGrabber * pGrabber(reinterpret_cast<NTV2CCGrabber*>(pInstance));
1557  if (pGrabber)
1558  pGrabber->CaptioningChanged(inChangeInfo);
1559 }
1560 
1561 
1562 string NTV2CCGrabber::GetLine21ChannelNames (string inDelimiterStr) // static
1563 {
1564  string result;
1565  for (unsigned enumVal(0); enumVal < NTV2_CC608_ChannelMax; )
1566  {
1567  result += ::NTV2Line21ChannelToStr (NTV2Line21Channel(enumVal++));
1568  if (enumVal < NTV2_CC608_ChannelMax)
1569  result += inDelimiterStr;
1570  else
1571  break;
1572  }
1573  return result;
1574 
1575 } // GetLine21ChannelNames
1576 
1577 AJALabelValuePairs CCGrabberConfig::Get (const bool inCompact) const
1578 {
1579  AJALabelValuePairs result (CaptureConfig::Get(inCompact));
1580  AJASystemInfo::append(result, "Output Mode", IS_VALID_OutputMode(fOutputMode) ? OutputModeToString(fOutputMode) : "(invalid)");
1582  AJASystemInfo::append(result, "Timecode Source", ::NTV2TCIndexToString(fTimecodeSrc, inCompact));
1583  AJASystemInfo::append(result, "Caption Channel", ::NTV2Line21ChannelToStr(fCaptionChannel, inCompact));
1584  AJASystemInfo::append(result, "Burn-In Captions", fBurnCaptions ? "Y" : "N");
1585  AJASystemInfo::append(result, "MultiFormat Mode", fDoMultiFormat ? "Y" : "N");
1586  AJASystemInfo::append(result, "Use Vanc", fUseVanc ? "Y" : "N");
1587  return result;
1588 }
1589 
1590 
1592 {
1593  string result;
1595  {
1596  result += OutputModeToString(mode);
1597  mode = OutputMode(mode+1);
1598  if (mode < kOutputMode_INVALID)
1599  result += ",";
1600  }
1601  return result;
1602 }
1603 
1605 {
1606  static const string gModeStrs[] = {"stream","screen","scc","mcc","stats",""};
1607  if (IS_VALID_OutputMode(inMode))
1608  return gModeStrs[inMode];
1609  string result;
1610  for (unsigned ndx(0); ndx < 5; )
1611  {
1612  result += gModeStrs[ndx];
1613  if (!(gModeStrs[++ndx].empty()))
1614  result += "|";
1615  }
1616  return result;
1617 }
1618 
1620 {
1621  typedef pair<string,OutputMode> StringToOutputModePair;
1622  typedef map<string,OutputMode> StringToOutputModeMap;
1623  typedef StringToOutputModeMap::const_iterator StringToOutputModeConstIter;
1624  static StringToOutputModeMap sStringToOutputModeMap;
1625  static AJALock sStringToOutputModeMapLock;
1626  if (sStringToOutputModeMap.empty())
1627  {
1628  AJAAutoLock autoLock(&sStringToOutputModeMapLock);
1630  {
1631  string outputModeStr (OutputModeToString(om));
1632  aja::lower(outputModeStr);
1633  sStringToOutputModeMap.insert(StringToOutputModePair(outputModeStr,om));
1634  }
1635  }
1636  string modeStr(inModeStr);
1637  aja::lower(aja::strip(modeStr));
1638  StringToOutputModeConstIter iter(sStringToOutputModeMap.find(modeStr));
1639  return iter != sStringToOutputModeMap.end() ? iter->second : kOutputMode_INVALID;
1640 }
1641 
1643 {
1644  string result;
1646  {
1647  result += CaptionDataSrcToString(src);
1648  src = CaptionDataSrc(src+1);
1649  if (src < kCaptionDataSrc_INVALID)
1650  result += ",";
1651  }
1652  return result;
1653 }
1654 
1656 {
1657  static const string gSrcStrs[] = {"default","line21","608vanc","708vanc","608anc","708anc",""};
1658  if (IS_VALID_CaptionDataSrc(inDataSrc))
1659  return gSrcStrs[inDataSrc];
1660  string result;
1661  for (unsigned ndx(0); ndx < 6; )
1662  {
1663  result += gSrcStrs[ndx];
1664  if (!gSrcStrs[++ndx].empty())
1665  result += "|";
1666  }
1667  return result;
1668 }
1669 
1671 {
1672  typedef pair<string,CaptionDataSrc> StringToCaptionDataSrcPair;
1673  typedef map<string,CaptionDataSrc> StringToCaptionDataSrcMap;
1674  typedef StringToCaptionDataSrcMap::const_iterator StringToCaptionDataSrcConstIter;
1675  static StringToCaptionDataSrcMap sStringToCaptionDataSrcMap;
1676  static AJALock sStringToCaptionDataSrcMapLock;
1677  if (sStringToCaptionDataSrcMap.empty())
1678  {
1679  AJAAutoLock autoLock(&sStringToCaptionDataSrcMapLock);
1681  {
1682  string captionDataSrcStr (CaptionDataSrcToString(cds));
1683  aja::lower(captionDataSrcStr);
1684  sStringToCaptionDataSrcMap.insert(StringToCaptionDataSrcPair(captionDataSrcStr,cds));
1685  }
1686  }
1687  string cdsStr(inDataSrcStr);
1688  aja::lower(aja::strip(cdsStr));
1689  StringToCaptionDataSrcConstIter iter(sStringToCaptionDataSrcMap.find(cdsStr));
1690  return iter != sStringToCaptionDataSrcMap.end() ? iter->second : kCaptionDataSrc_INVALID;
1691 }
1692 
1693 
1694 std::ostream & operator << (std::ostream & ioStrm, const CCGrabberConfig & inObj)
1695 {
1696  ioStrm << AJASystemInfo::ToString(inObj.Get());
1697  return ioStrm;
1698 }
AUTOCIRCULATE_TRANSFER::acFrameBufferFormat
NTV2FrameBufferFormat acFrameBufferFormat
Specifies the frame buffer format to change to. Ignored if AUTOCIRCULATE_WITH_FBFCHANGE option is not...
Definition: ntv2publicinterface.h:7975
CNTV2Card::SetVANCMode
virtual bool SetVANCMode(const NTV2VANCMode inVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Sets the VANC mode for the given FrameStore.
Definition: ntv2register.cpp:2656
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:3288
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:4281
CCGrabberConfig::fTimecodeSrc
NTV2TCIndex fTimecodeSrc
Timecode source to use (if any)
Definition: ntv2ccgrabber.h:67
NTV2_XptHDMIOutInput
@ NTV2_XptHDMIOutInput
Definition: ntv2enums.h:2788
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:1619
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
NTV2_IS_VANCMODE_TALLER
#define NTV2_IS_VANCMODE_TALLER(__v__)
Definition: ntv2enums.h:3721
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:8258
AJATimeCode::QueryString
void QueryString(std::string &str, const AJATimeBase &timeBase, bool bDropFrame)
Definition: timecode.cpp:225
CNTV2CaptionDecoder708::SetSMPTE334AncData
virtual bool SetSMPTE334AncData(const UByte *pInAncData, const size_t inByteCount)
Copies a given SMPTE334 ancillary data packet into my private buffer for parsing.
NTV2_AUDIO_LOOPBACK_OFF
@ NTV2_AUDIO_LOOPBACK_OFF
Embeds silence (zeroes) into the data stream.
Definition: ntv2enums.h:1971
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:3267
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:2861
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:5413
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:2904
CNTV2CaptionDecoder708::Create
static bool Create(CNTV2CaptionDecoder708Ptr &outDecoder)
Creates a new CNTV2CaptionEncoder708 instance.
AUTOCIRCULATE_TRANSFER_STATUS::GetProcessedFrameCount
ULWord GetProcessedFrameCount(void) const
Definition: ntv2publicinterface.h:7868
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:1240
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:2978
CNTV2Card::ApplySignalRoute
virtual bool ApplySignalRoute(const CNTV2SignalRouter &inRouter, const bool inReplace=false)
Applies the given routing table to the AJA device.
Definition: ntv2regroute.cpp:242
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:982
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:994
NTV2Channel
NTV2Channel
These enum values are mostly used to identify a specific Frame Store. They're also commonly used to i...
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:5967
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:7109
AJA_STATUS_SUCCESS
@ AJA_STATUS_SUCCESS
Definition: types.h:368
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:601
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:2866
NTV2_Wgt3GSDIOut7
@ NTV2_Wgt3GSDIOut7
Definition: ntv2enums.h:2915
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:2913
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:968
ancillarylist.h
Declares the AJAAncillaryList class.
AJA_STATUS_BUSY
@ AJA_STATUS_BUSY
Definition: types.h:378
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:327
CaptureConfig::Get
AJALabelValuePairs Get(const bool inCompact=false) const
Definition: ntv2democommon.cpp:1685
NTV2_WgtSDIOut4
@ NTV2_WgtSDIOut4
Definition: ntv2enums.h:2863
NTV2MakeChannelList
NTV2ChannelList NTV2MakeChannelList(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Definition: ntv2publicinterface.cpp:3311
CCGrabberConfig::Get
AJALabelValuePairs Get(const bool inCompact=(0)) const
Definition: ntv2ccgrabber.cpp:1577
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:3811
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
NTV2DeviceCanDoMultiFormat
bool NTV2DeviceCanDoMultiFormat(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:4065
AJAAncillaryList::CountAncillaryDataWithType
virtual uint32_t CountAncillaryDataWithType(const AJAAncDataType inMatchType) const
Answers with the number of AJAAncillaryData objects having the given type.
Definition: ancillarylist.cpp:218
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:1419
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:201
NTV2CCGrabber::CaptioningChanged
virtual void CaptioningChanged(const NTV2Caption608ChangeInfo &inChangeInfo)
This function gets called whenever caption changes occur.
Definition: ntv2ccgrabber.cpp:1548
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:832
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:2207
NTV2_Wgt3GSDIOut1
@ NTV2_Wgt3GSDIOut1
Definition: ntv2enums.h:2864
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:384
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:1554
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:2744
CNTV2CaptionDecoder608::Reset
virtual void Reset(void)
Flushes me, clearing all in-progress data.
NTV2_Wgt3GSDIOut8
@ NTV2_Wgt3GSDIOut8
Definition: ntv2enums.h:2916
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
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:303
NTV2DeviceCanDoFrameBufferFormat
bool NTV2DeviceCanDoFrameBufferFormat(const NTV2DeviceID inDeviceID, const NTV2FrameBufferFormat inFBFormat)
Definition: ntv2devicefeatures.hpp:15330
NTV2_CHANNEL1
@ NTV2_CHANNEL1
Specifies channel or Frame Store 1 (or the first item).
Definition: ntv2enums.h:1307
ntv2debug.h
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:3805
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:3826
CNTV2Card::SetVANCShiftMode
virtual bool SetVANCShiftMode(NTV2Channel inChannel, NTV2VANCDataShiftMode inMode)
Enables or disables the "VANC Shift Mode" feature for the given channel.
Definition: ntv2register.cpp:2816
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:234
NTV2_Wgt3GSDIOut5
@ NTV2_Wgt3GSDIOut5
Definition: ntv2enums.h:2913
CNTV2Card::SetVideoFormat
virtual bool SetVideoFormat(const NTV2VideoFormat inVideoFormat, const bool inIsAJARetail=true, const bool inKeepVancSettings=false, const NTV2Channel inChannel=NTV2_CHANNEL1)
Configures the AJA device to handle a specific video format.
Definition: ntv2register.cpp:204
NTV2CCGrabber::Run
virtual AJAStatus Run(void)
Runs me.
Definition: ntv2ccgrabber.cpp:605
NTV2DeviceCanDo425Mux
bool NTV2DeviceCanDo425Mux(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:737
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:488
NTV2DeviceCanDoVideoFormat
bool NTV2DeviceCanDoVideoFormat(const NTV2DeviceID inDeviceID, const NTV2VideoFormat inVideoFormat)
Definition: ntv2devicefeatures.hpp:18535
NTV2CCGrabber::DoCCOutput
virtual void DoCCOutput(const uint32_t inFrameNum, const CaptionData &inCCData, const NTV2VideoFormat inVideoFormat)
Outputs CC data.
Definition: ntv2ccgrabber.cpp:1188
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:78
CaptionDecode608Stats
enum _CaptionDecode608Stats CaptionDecode608Stats
The currently supported caption decoder stats.
NTV2CCGrabber::SwitchOutput
virtual void SwitchOutput(void)
Switches/rotates –output mode.
Definition: ntv2ccgrabber.cpp:946
AJAThread
Definition: thread.h:69
AUTOCIRCULATE_WITH_ANC
#define AUTOCIRCULATE_WITH_ANC
Use this to AutoCirculate with ancillary data.
Definition: ntv2publicinterface.h:5496
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:2860
AJAStatus
AJAStatus
Definition: types.h:365
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:2865
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:1291
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:3714
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:3713
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: ntv2audio.cpp:573
AJATimeBase
Definition: timebase.h:18
CNTV2CaptionDecoder608::Get608ChannelDecoder
virtual CNTV2CaptionDecodeChannel608Ptr Get608ChannelDecoder(const NTV2Line21Channel inChannel) const
AJA_STATUS_FAIL
@ AJA_STATUS_FAIL
Definition: types.h:369
ULWord
uint32_t ULWord
Definition: ajatypes.h:246
NTV2_VANCDATA_8BITSHIFT_ENABLE
@ NTV2_VANCDATA_8BITSHIFT_ENABLE
Definition: ntv2enums.h:3731
NTV2DeviceCanDoWidget
bool NTV2DeviceCanDoWidget(const NTV2DeviceID inDeviceID, const NTV2WidgetID inWidgetID)
Definition: ntv2devicefeatures.hpp:30519
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:3730
AUTOCIRCULATE_STATUS
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
Definition: ntv2publicinterface.h:7105
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:550
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:1562
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:788
NTV2DeviceHasBiDirectionalSDI
bool NTV2DeviceHasBiDirectionalSDI(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:6454
kOutputMode_CaptionScreen
@ kOutputMode_CaptionScreen
Definition: ntv2ccgrabber.h:35
CNTV2DemoCommon::SetDefaultPageSize
static size_t SetDefaultPageSize(void)
Definition: ntv2democommon.cpp:1505
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
CNTV2Card::SetReference
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=false)
Sets the device's clock reference source. See Device Clocking and Synchronization for more informatio...
Definition: ntv2register.cpp:1486
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 ...
NTV2DeviceGetNumVideoInputs
UWord NTV2DeviceGetNumVideoInputs(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:11923
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
CNTV2Card::Connect
virtual bool Connect(const NTV2InputCrosspointID inInputXpt, const NTV2OutputCrosspointID inOutputXpt, const bool inValidate=false)
Connects the given widget signal input (sink) to the given widget signal output (source).
Definition: ntv2regroute.cpp:87
CaptionData::HasData
bool HasData(void) const
Definition: ntv2caption608types.h:698
AUTOCIRCULATE_TRANSFER::GetCapturedAncByteCount
ULWord GetCapturedAncByteCount(const bool inField2=false) const
Definition: ntv2publicinterface.h:8280
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:244
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
CNTV2DemoCommon::GetTSIMuxesForFrameStore
static NTV2ChannelList GetTSIMuxesForFrameStore(const NTV2DeviceID inDeviceID, const NTV2Channel in1stFrameStore, const UWord inCount)
Definition: ntv2democommon.cpp:1203
NTV2FrameData::AncBuffer2Size
ULWord AncBuffer2Size(void) const
Definition: ntv2democommon.h:118
NTV2_IS_VANCMODE_ON
#define NTV2_IS_VANCMODE_ON(__v__)
Definition: ntv2enums.h:3722
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:1393
CCGrabberConfig::CaptionDataSrcToString
static std::string CaptionDataSrcToString(const CaptionDataSrc inDataSrc)
Definition: ntv2ccgrabber.cpp:1655
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:357
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:1642
NTV2DeviceGetNumFrameStores
UWord NTV2DeviceGetNumFrameStores(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:10487
AUTOCIRCULATE_STATUS::IsStopped
bool IsStopped(void) const
Definition: ntv2publicinterface.h:7221
CNTV2CaptionDecoder608::Create
static bool Create(CNTV2CaptionDecoder608Ptr &outEncoder)
Creates a new CNTV2CaptionEncoder608 instance.
CNTV2Card::AutoCirculateStop
virtual bool AutoCirculateStop(const NTV2Channel inChannel, const bool inAbort=false)
Stops AutoCirculate for the given channel, and releases the on-device frame buffers that were allocat...
Definition: ntv2autocirculate.cpp:519
operator<<
std::ostream & operator<<(std::ostream &ioStrm, const CCGrabberConfig &inObj)
Definition: ntv2ccgrabber.cpp:1694
NTV2WidgetID
NTV2WidgetID
Definition: ntv2enums.h:2842
NTV2_CC608_Green
@ NTV2_CC608_Green
Definition: ntv2caption608types.h:156
CNTV2DriverInterface::IsDeviceReady
virtual bool IsDeviceReady(const bool inCheckValid=(0))
Definition: ntv2driverinterface.cpp:1228
CaptionData::bGotField2Data
bool bGotField2Data
True if Field 2 bytes have been set; otherwise false.
Definition: ntv2caption608types.h:661
NTV2DeviceCanDoPlayback
bool NTV2DeviceCanDoPlayback(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:4438
NTV2_XptHDMIOutQ1Input
@ NTV2_XptHDMIOutQ1Input
Definition: ntv2enums.h:2789
NTV2_RP188::fDBB
ULWord fDBB
Definition: ntv2publicinterface.h:6706
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:1591
NTV2ChannelSet
std::set< NTV2Channel > NTV2ChannelSet
A set of distinct NTV2Channel values.
Definition: ntv2publicinterface.h:3823
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:7941
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:1313
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:1527
kOutputMode_CaptionFileSCC
@ kOutputMode_CaptionFileSCC
Definition: ntv2ccgrabber.h:36
CRP188
Definition: ntv2rp188.h:55
AUTOCIRCULATE_STATUS::GetEndFrame
uint16_t GetEndFrame(void) const
Definition: ntv2publicinterface.h:7196
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:3711
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:190
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:4259
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:1408
NTV2_VANCMODE_INVALID
@ NTV2_VANCMODE_INVALID
This identifies the invalid (unspecified, uninitialized) VANC mode.
Definition: ntv2enums.h:3716
CNTV2DemoCommon::GetAJAFrameRate
static AJA_FrameRate GetAJAFrameRate(const NTV2FrameRate inFrameRate)
Definition: ntv2democommon.cpp:1022
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:2890
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:478
NTV2DeviceGetNumAudioSystems
UWord NTV2DeviceGetNumAudioSystems(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:9864
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:1610
NTV2DeviceGetNumMixers
UWord NTV2DeviceGetNumMixers(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:11389
NTV2OutputCrosspointID
NTV2OutputCrosspointID
Identifies a widget output, a signal source, that potentially can drive another widget's input (ident...
Definition: ntv2enums.h:2467
NTV2ChannelList
std::vector< NTV2Channel > NTV2ChannelList
An ordered sequence of NTV2Channel values.
Definition: ntv2publicinterface.h:3804
NTV2Buffer::GetHostPointer
void * GetHostPointer(void) const
Definition: ntv2publicinterface.h:6023
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:2879
ntv2captionrenderer.h
Declares the CNTV2CaptionRenderer class.
NTV2DeviceCanDo12gRouting
bool NTV2DeviceCanDo12gRouting(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:287
NTV2_FBF_10BIT_YCBCR
@ NTV2_FBF_10BIT_YCBCR
See 10-Bit YCbCr Format.
Definition: ntv2enums.h:210
NTV2_Wgt3GSDIOut4
@ NTV2_Wgt3GSDIOut4
Definition: ntv2enums.h:2867
NTV2CCGrabber::Caption608ChangedStatic
static void Caption608ChangedStatic(void *pInstance, const NTV2Caption608ChangeInfo &inChangeInfo)
This static function gets called whenever 608 captioning changes.
Definition: ntv2ccgrabber.cpp:1554
AJA_STATUS_INITIALIZE
@ AJA_STATUS_INITIALIZE
Definition: types.h:373
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:5579
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:3216
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:2103
false
#define false
Definition: ntv2devicefeatures.h:25
UByte
uint8_t UByte
Definition: ajatypes.h:241
AUTOCIRCULATE_WITH_RP188
#define AUTOCIRCULATE_WITH_RP188
Use this to AutoCirculate with RP188.
Definition: ntv2publicinterface.h:5490
NTV2CCGrabber::~NTV2CCGrabber
virtual ~NTV2CCGrabber()
Definition: ntv2ccgrabber.cpp:80
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:7211
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:1532
NTV2_AUDIO_LOOPBACK_ON
@ NTV2_AUDIO_LOOPBACK_ON
Embeds SDI input source audio into the data stream.
Definition: ntv2enums.h:1972
NTV2_RP188::IsValid
bool IsValid(void) const
Answers true if I'm valid, or false if I'm not valid.
Definition: ntv2publicinterface.h:6747
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:489
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
NTV2DeviceCanDoInputSource
bool NTV2DeviceCanDoInputSource(const NTV2DeviceID inDeviceID, const NTV2InputSource inInputSource)
Definition: ntv2devicefeatures.hpp:17462
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:379
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:957
NTV2MakeChannelSet
NTV2ChannelSet NTV2MakeChannelSet(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Definition: ntv2publicinterface.cpp:3294
NTV2_RP188
This struct replaces the old RP188_STRUCT.
Definition: ntv2publicinterface.h:6705
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:7912
CNTV2Card::SetMixerMode
virtual bool SetMixerMode(const UWord inWhichMixer, const NTV2MixerKeyerMode inMode)
Sets the mode for the given mixer/keyer.
Definition: ntv2register.cpp:2936
IsRGBFormat
bool IsRGBFormat(const NTV2FrameBufferFormat format)
Definition: ntv2utils.cpp:5442
NTV2_Wgt3GSDIOut6
@ NTV2_Wgt3GSDIOut6
Definition: ntv2enums.h:2914
NTV2_AUDIO_EMBEDDED
@ NTV2_AUDIO_EMBEDDED
Obtain audio samples from the audio that's embedded in the video HANC.
Definition: ntv2enums.h:1948
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:2903
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.
CNTV2Card::EnableChannels
virtual bool EnableChannels(const NTV2ChannelSet &inChannels, const bool inDisableOthers=false)
Enables the given FrameStore(s).
Definition: ntv2register.cpp:2123
Hex0N
#define Hex0N(__x__, __n__)
Definition: ntv2publicinterface.h:5571
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...
NTV2DeviceGetNumVideoChannels
ULWord NTV2DeviceGetNumVideoChannels(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:11834
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:2862
NTV2_WgtAnalogOut1
@ NTV2_WgtAnalogOut1
Definition: ntv2enums.h:2876
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:808
kCaptionDataSrc_Line21
@ kCaptionDataSrc_Line21
Definition: ntv2ccgrabber.h:48
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:371
AUTOCIRCULATE_STATUS::HasAvailableInputFrame
bool HasAvailableInputFrame(void) const
Definition: ntv2publicinterface.h:7181
CCGrabberConfig::OutputModeToString
static std::string OutputModeToString(const OutputMode inMode)
Definition: ntv2ccgrabber.cpp:1604
CNTV2Card::SetMixerVancOutputFromForeground
virtual bool SetMixerVancOutputFromForeground(const UWord inWhichMixer, const bool inFromForegroundSource=true)
Sets the VANC source for the given mixer/keyer to the foreground video (or not). See the Ancillary Da...
Definition: ntv2register.cpp:2869
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:411
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:2736
CNTV2VPID::SetVPID
virtual CNTV2VPID & SetVPID(const ULWord inData)
Definition: ntv2vpid.h:71
CNTV2Card::GetInputVideoFormat
virtual NTV2VideoFormat GetInputVideoFormat(const NTV2InputSource inVideoSource=NTV2_INPUTSOURCE_SDI1, const bool inIsProgressive=false)
Returns the video format of the signal that is present on the given input source.
Definition: ntv2register.cpp:3381
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:3720
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:6192
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
NTV2DeviceGetNumVideoOutputs
UWord NTV2DeviceGetNumVideoOutputs(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:12012
CaptionData::bGotField1Data
bool bGotField1Data
True if Field 1 bytes have been set; otherwise false.
Definition: ntv2caption608types.h:657
NTV2DeviceCanDoCustomAnc
bool NTV2DeviceCanDoCustomAnc(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:2087
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:375
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:390
CNTV2Card::SetFrameBufferFormat
virtual bool SetFrameBufferFormat(NTV2Channel inChannel, NTV2FrameBufferFormat inNewFormat, bool inIsAJARetail=true, 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:1828
gMixerNums
static const UWord gMixerNums[]
Definition: ntv2ccgrabber.cpp:1288
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:2732
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:149
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:252
AJAThread::Start
virtual AJAStatus Start()
Definition: thread.cpp:91
CNTV2DemoCommon::StripFormatString
static std::string StripFormatString(const std::string &inStr)
Definition: ntv2democommon.cpp:944
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
CNTV2Card::SetMode
virtual bool SetMode(const NTV2Channel inChannel, const NTV2Mode inNewValue, const bool inIsRetail=true)
Determines if a given FrameStore on the AJA device will be used to capture or playout video.
Definition: ntv2register.cpp:1613
CCGrabberConfig::StringToCaptionDataSrc
static CaptionDataSrc StringToCaptionDataSrc(const std::string &inDataSrcStr)
Definition: ntv2ccgrabber.cpp:1670
AJALabelValuePairs
std::vector< AJALabelValuePair > AJALabelValuePairs
An ordered sequence of label/value pairs.
Definition: info.h:69
BIT
#define BIT(_x_)
Definition: ajatypes.h:654
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:5578
AJA_FAILURE
#define AJA_FAILURE(_status_)
Definition: types.h:358
NTV2_IS_VALID_AUDIO_SYSTEM
#define NTV2_IS_VALID_AUDIO_SYSTEM(__x__)
Definition: ntv2enums.h:3828
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
CNTV2Card::EnableChannel
virtual bool EnableChannel(const NTV2Channel inChannel)
Enables the given FrameStore.
Definition: ntv2register.cpp:2113
NTV2_MODE_DISPLAY
@ NTV2_MODE_DISPLAY
Playout (output) mode, which reads from device SDRAM.
Definition: ntv2enums.h:1200
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:7930
NTV2CCGrabber::DeviceAncExtractorIsAvailable
virtual bool DeviceAncExtractorIsAvailable(void) const
Definition: ntv2ccgrabber.cpp:933
NTV2_XptAnalogOutInput
@ NTV2_XptAnalogOutInput
Definition: ntv2enums.h:2805
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:1317
CCGrabberConfig::fBurnCaptions
bool fBurnCaptions
If true, burn-in captions on 2nd channel.
Definition: ntv2ccgrabber.h:69
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:2594
NTV2DeviceGetMaxAudioChannels
UWord NTV2DeviceGetMaxAudioChannels(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:8796
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:97
NTV2_OEM_TASKS
@ NTV2_OEM_TASKS
2: OEM: Device is configured by controlling application(s), with minimal driver involvement.
Definition: ntv2publicinterface.h:4261
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:939
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:822
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:208
NTV2_FBF_LAST
@ NTV2_FBF_LAST
Definition: ntv2enums.h:243
NTV2_AUDIOSYSTEM_INVALID
@ NTV2_AUDIOSYSTEM_INVALID
Definition: ntv2enums.h:3821
CNTV2CaptionDecoder608::UnsubscribeChangeNotification
virtual bool UnsubscribeChangeNotification(NTV2Caption608Changed *pInCallback, void *pInUserData=0)
Unsubscribes a prior change notification subscription.