AJA NTV2 SDK  18.0.0.2122
NTV2 SDK 18.0.0.2122
ntv2player4k.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2player4k.h"
9 #include "ntv2debug.h"
10 #include "ntv2devicescanner.h"
11 #include "ntv2testpatterngen.h"
13 #include "ajabase/system/process.h"
17 
18 using namespace std;
19 
20 //#define NTV2_BUFFER_LOCKING // Define this to pre-lock video/audio buffers in kernel
21 
22 // Convenience macros for EZ logging:
23 #define TCFAIL(_expr_) AJA_sERROR (AJA_DebugUnit_TimecodeGeneric, AJAFUNC << ": " << _expr_)
24 #define TCWARN(_expr_) AJA_sWARNING(AJA_DebugUnit_TimecodeGeneric, AJAFUNC << ": " << _expr_)
25 #define TCNOTE(_expr_) AJA_sNOTICE (AJA_DebugUnit_TimecodeGeneric, AJAFUNC << ": " << _expr_)
26 #define TCINFO(_expr_) AJA_sINFO (AJA_DebugUnit_TimecodeGeneric, AJAFUNC << ": " << _expr_)
27 #define TCDBG(_expr_) AJA_sDEBUG (AJA_DebugUnit_TimecodeGeneric, AJAFUNC << ": " << _expr_)
28 
34 static ULWord gAncMaxSizeBytes (NTV2_ANCSIZE_MAX); // Max per-frame anc buffer size, in bytes
35 
44 static const uint32_t gAudMaxSizeBytes (256 * 1024); // Max per-frame audio buffer size, in bytes
45 
46 static const bool BUFFER_PAGE_ALIGNED (true);
47 
48 // Audio tone generator data
49 static const double gFrequencies [] = {250.0, 500.0, 1000.0, 2000.0};
50 static const ULWord gNumFrequencies (sizeof(gFrequencies) / sizeof(double));
51 // Unlike NTV2Player, this demo uses the same waveform amplitude in each audio channel
52 
53 
55  : mConfig (inConfig),
56  mConsumerThread (),
57  mProducerThread (),
58  mDevice (),
59  mDeviceID (DEVICE_ID_INVALID),
60  mSavedTaskMode (NTV2_TASK_MODE_INVALID),
61  mCurrentFrame (0),
62  mCurrentSample (0),
63  mToneFrequency (440.0),
64  mAudioSystem (NTV2_AUDIOSYSTEM_INVALID),
65  mFormatDesc (),
66  mGlobalQuit (false),
67  mTCBurner (),
68  mHostBuffers (),
69  mFrameDataRing (),
70  mTestPatRasters ()
71 {
72 }
73 
74 
76 {
77  // Stop my playout and producer threads, then destroy them...
78  Quit();
79 
80  mDevice.UnsubscribeOutputVerticalEvent(mConfig.fOutputChannel); // Unsubscribe from output VBI event
81 } // destructor
82 
83 
84 void NTV2Player4K::Quit (void)
85 {
86  // Set the global 'quit' flag, and wait for the threads to go inactive...
87  mGlobalQuit = true;
88 
89  while (mProducerThread.Active())
90  AJATime::Sleep(10);
91 
92  while (mConsumerThread.Active())
93  AJATime::Sleep(10);
94 
95 #if defined(NTV2_BUFFER_LOCKING)
96  mDevice.DMABufferUnlockAll();
97 #endif // NTV2_BUFFER_LOCKING
98  if (!mConfig.fDoMultiFormat && mDevice.IsOpen())
99  {
101  if (NTV2_IS_VALID_TASK_MODE(mSavedTaskMode))
102  mDevice.SetTaskMode(mSavedTaskMode); // Restore prior task mode
103  }
104 } // Quit
105 
106 
108 {
109  AJAStatus status (AJA_STATUS_SUCCESS);
110 
111  // Open the device...
113  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not found" << endl; return AJA_STATUS_OPEN;}
114  mDeviceID = mDevice.GetDeviceID(); // Keep this ID handy -- it's used frequently
115 
116  if (!mDevice.IsDeviceReady(false))
117  {cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not ready" << endl; return AJA_STATUS_INITIALIZE;}
118  if (!mDevice.features().CanDoPlayback())
119  {cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' is capture-only" << endl; return AJA_STATUS_FEATURE;}
120 
121  const UWord maxNumChannels (mDevice.features().GetNumFrameStores());
122 
123  // Check for an invalid configuration
124  if (NTV2_IS_4K_HFR_VIDEO_FORMAT(mConfig.fVideoFormat) && mConfig.fDoRGBOnWire)
125  {cerr << "## ERROR: HFR RGB output not supported" << endl; return AJA_STATUS_BAD_PARAM;}
126 
127  // Check for valid channel...
128  if (UWord(mConfig.fOutputChannel) >= maxNumChannels)
129  {
130  cerr << "## ERROR: Cannot use channel '" << DEC(mConfig.fOutputChannel+1) << "' -- device only supports channel 1"
131  << (maxNumChannels > 1 ? string(" thru ") + string(1, char(maxNumChannels+'0')) : "") << endl;
132  return AJA_STATUS_UNSUPPORTED;
133  }
134  if (mDevice.features().CanDo12gRouting())
135  {
136  if (mConfig.fDoTsiRouting)
137  cerr << "## WARNING: '--tsi' option used with device that has 12G FrameStores with integral Tsi muxers" << endl;
138  mConfig.fDoTsiRouting = false; // Kona5 & Corvid44/12G FrameStores have built-in TSI muxers for easier routing
139  }
140  else if (mConfig.fDoTsiRouting)
141  {
142  if (mConfig.fOutputChannel & 1)
143  {
144  cerr << "## ERROR: Tsi requires Ch" << DEC(mConfig.fOutputChannel-1) << " -- not Ch" << DEC(mConfig.fOutputChannel) << endl;
145  return AJA_STATUS_BAD_PARAM;
146  }
147  }
148  else if (mConfig.fOutputChannel != NTV2_CHANNEL1 && mConfig.fOutputChannel != NTV2_CHANNEL5)
149  {
150  cerr << "## ERROR: Squares requires Ch1 or Ch5, not Ch" << DEC(mConfig.fOutputChannel) << endl;
151  return AJA_STATUS_BAD_PARAM;
152  }
153 
154  if (!mConfig.fDoMultiFormat)
155  {
156  mDevice.GetTaskMode(mSavedTaskMode); // Save the current task mode
158  return AJA_STATUS_BUSY; // Device is in use by another app -- fail
159  }
160  mDevice.SetTaskMode(NTV2_OEM_TASKS); // Set OEM service level
161 
162  if (mDevice.features().CanDoMultiFormat())
163  mDevice.SetMultiFormatMode(mConfig.fDoMultiFormat);
164  else
165  mConfig.fDoMultiFormat = false;
166 
167  // Set up the video and audio...
168  status = SetUpVideo();
169  if (AJA_FAILURE(status))
170  return status;
171  status = mConfig.WithAudio() ? SetUpAudio() : AJA_STATUS_SUCCESS;
172  if (AJA_FAILURE(status))
173  return status;
174 
175  // Set up the circular buffers, and the test pattern buffers...
176  status = SetUpHostBuffers();
177  if (AJA_FAILURE(status))
178  return status;
179  status = SetUpTestPatternBuffers();
180  if (AJA_FAILURE(status))
181  return status;
182 
183  // Set up the device signal routing...
184  if (!RouteOutputSignal())
185  return AJA_STATUS_FAIL;
186 
187  // Lastly, prepare my AJATimeCodeBurn instance...
188  if (!mTCBurner.RenderTimeCodeFont (CNTV2DemoCommon::GetAJAPixelFormat(mConfig.fPixelFormat), mFormatDesc.numPixels, mFormatDesc.numLines))
189  {cerr << "## ERROR: RenderTimeCodeFont failed for: " << mFormatDesc << endl; return AJA_STATUS_UNSUPPORTED;}
190 
191  // Ready to go...
192  #if defined(_DEBUG)
193  cerr << mConfig;
194  if (mDevice.IsRemote())
195  cerr << "Device Description: " << mDevice.GetDescription() << endl;
196  cerr << endl;
197  #endif // defined(_DEBUG)
198  return AJA_STATUS_SUCCESS;
199 
200 } // Init
201 
202 
204 {
205  // Configure the device to output the requested video format...
206  if (mConfig.fVideoFormat == NTV2_FORMAT_UNKNOWN)
207  return AJA_STATUS_BAD_PARAM;
208  if (!mDevice.features().CanDoVideoFormat(mConfig.fVideoFormat))
209  { cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' doesn't support "
210  << ::NTV2VideoFormatToString(mConfig.fVideoFormat) << endl;
211  return AJA_STATUS_UNSUPPORTED;
212  }
213  if (!mDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
214  { cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' doesn't support "
215  << ::NTV2FrameBufferFormatString(mConfig.fPixelFormat) << endl;
216  return AJA_STATUS_UNSUPPORTED;
217  }
218 
219  NTV2ChannelSet channels1357, channels15, frameStores;
220  channels1357.insert(NTV2_CHANNEL1); channels1357.insert(NTV2_CHANNEL3); channels1357.insert(NTV2_CHANNEL5); channels1357.insert(NTV2_CHANNEL7);
221  channels15.insert(NTV2_CHANNEL1); channels15.insert(NTV2_CHANNEL5);
222  if (mDevice.features().CanDo12gRouting())
223  frameStores = ::NTV2MakeChannelSet (mConfig.fOutputChannel, 1); // 1 x 12G FrameStore (fOutputChannel)
224  else if (mConfig.fDoTsiRouting)
225  { // "Tsi" routing requires 2 FrameStores
226  if (channels1357.find(mConfig.fOutputChannel) == channels1357.end())
227  return AJA_STATUS_BAD_PARAM; // fOutputChannel not Ch1, Ch3, Ch5 or Ch7
228  frameStores = ::NTV2MakeChannelSet (mConfig.fOutputChannel, 2); // 2 x FrameStores starting at Ch1, Ch3, Ch5 or Ch7
229  }
230  else
231  { // "Squares" routing requires 4 FrameStores
232  if (channels15.find(mConfig.fOutputChannel) == channels15.end())
233  return AJA_STATUS_BAD_PARAM; // fOutputChannel not Ch1 or Ch5
234  frameStores = ::NTV2MakeChannelSet (mConfig.fOutputChannel, 4); // 4 x FrameStores starting at Ch1 or Ch5
235  }
236  // Disable SDI output conversions
237  mDevice.SetSDIOutLevelAtoLevelBConversion (frameStores, false);
238  mDevice.SetSDIOutRGBLevelAConversion (frameStores, false);
239 
240  // Keep the raster description handy...
241  mFormatDesc = NTV2FormatDescriptor(mConfig.fVideoFormat, mConfig.fPixelFormat);
242  if (!mFormatDesc.IsValid())
243  return AJA_STATUS_FAIL;
244 
245  // Turn on the FrameStores (to read frame buffer memory and transmit video)...
246  mDevice.EnableChannels (frameStores, /*disableOthers=*/!mConfig.fDoMultiFormat);
247 
248  // This demo requires VANC be disabled...
249  mDevice.SetVANCMode (frameStores, NTV2_VANCMODE_OFF); // VANC is incompatible with 4K/UHD formats
250  mDevice.SetVANCShiftMode(frameStores, NTV2_VANCDATA_NORMAL);
251 
252  // Set the FrameStore video format...
253  mDevice.SetVideoFormat (frameStores, mConfig.fVideoFormat, false);
254 
255  // Set the frame buffer pixel format for the device FrameStore(s)...
256  mDevice.SetFrameBufferFormat (frameStores, mConfig.fPixelFormat);
257 
258  // The output interrupt is Enabled by default, but on some platforms, you must subscribe to it
259  // in order to be able to wait on its event/semaphore...
261 
262  // Get current per-field maximum Anc buffer size...
265 
266  // Set output clock reference...
268 
269  // At this point, video setup is complete (except for widget signal routing).
270  return AJA_STATUS_SUCCESS;
271 
272 } // SetUpVideo
273 
274 
276 {
277  uint16_t numAudioChannels (mDevice.features().GetMaxAudioChannels());
278  if (numAudioChannels > 8) // If audio system handles more than 8 channels...
279  if (!mDevice.features().CanDo2110()) // ...and SDI (i.e. not ST 2110 IP streaming)...
280  if (NTV2_IS_4K_4096_VIDEO_FORMAT(mConfig.fVideoFormat)) // ...and 4K (narrower HANC only fits 8 audio channels)
281  numAudioChannels = 8; // ...then reduce to 8 audio channels
282 
283  // Use the NTV2AudioSystem that has the same ordinal value as the output FrameStore/Channel...
284  mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fOutputChannel);
285 
286  if (mConfig.fNumAudioLinks > 1) // For users that want to send 32 or 64 audio channels on 2 or 4 SDI links
287  switch (mAudioSystem)
288  {
289  default:
290  case NTV2_AUDIOSYSTEM_1:
291  { const UWord numChan(NTV2_IS_4K_HFR_VIDEO_FORMAT(mConfig.fVideoFormat) ? 4 : 2);
292  const NTV2AudioSystemSet audSystems (::NTV2MakeAudioSystemSet (mAudioSystem, numChan));
293  for (UWord chan(0); chan < numChan; chan++)
294  mDevice.SetSDIOutputAudioSystem (NTV2Channel(chan), NTV2AudioSystem(chan));
295  mDevice.SetNumberAudioChannels (numAudioChannels, audSystems);
296  mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, audSystems);
297  mDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, audSystems);
298  break;
299  }
300  case NTV2_AUDIOSYSTEM_3:
303  break;
304  }
305  else
306  {
307  NTV2ChannelSet sdiSpigots (::NTV2MakeChannelSet (mConfig.fOutputChannel, 1));
308  if (!mDevice.features().CanDo12gRouting())
309  sdiSpigots = ::NTV2MakeChannelSet (mAudioSystem == NTV2_AUDIOSYSTEM_1 || mAudioSystem == NTV2_AUDIOSYSTEM_3
310  ? NTV2_CHANNEL1
311  : NTV2_CHANNEL5, 4);
312  mDevice.SetSDIOutputAudioSystem (sdiSpigots, mAudioSystem);
313  mDevice.SetNumberAudioChannels (numAudioChannels, mAudioSystem);
314  mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mAudioSystem);
315  mDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, mAudioSystem);
316  }
317 
318  if (mConfig.fDoHDMIOutput)
319  {
323  }
324 
325  return AJA_STATUS_SUCCESS;
326 
327 } // SetUpAudio
328 
329 
331 {
332  CNTV2DemoCommon::SetDefaultPageSize(); // Set host-specific page size
333 
334  // Let my circular buffer know when it's time to quit...
335  mFrameDataRing.SetAbortFlag (&mGlobalQuit);
336 
337  // Multi-link audio uses stacked buffers for transferring to the board,
338  // the first byte after the end of the first audio link buffer is the start of the second audio link buffer.
339  const size_t audioBufferSize (gAudMaxSizeBytes * uint32_t(mConfig.fNumAudioLinks));
340 
341  // Allocate and add each in-host NTV2FrameData to my circular buffer member variable...
342  mHostBuffers.reserve(CIRCULAR_BUFFER_SIZE);
343  while (mHostBuffers.size() < CIRCULAR_BUFFER_SIZE)
344  {
345  mHostBuffers.push_back(NTV2FrameData()); // Make a new NTV2FrameData...
346  NTV2FrameData & frameData(mHostBuffers.back()); // ...and get a reference to it
347 
348  // Don't allocate a page-aligned video buffer here.
349  // Instead, the test pattern buffers are used (and re-used) in the consumer thread.
350  // This saves a LOT of memory and time spent copying data with these large 4K/UHD rasters.
351  // NOTE: This differs substantially from the NTV2Player demo, which pre-allocates the ring of video buffers
352  // here, then in its producer thread, copies a fresh, unmodified test pattern raster into the video
353  // buffer, blits timecode into it, then transfers it to the hardware in its consumer thread.
354 
355  // Allocate a page-aligned audio buffer (if transmitting audio)
356  if (mConfig.WithAudio())
357  if (!frameData.fAudioBuffer.Allocate (audioBufferSize, BUFFER_PAGE_ALIGNED))
358  {
359  PLFAIL("Failed to allocate " << xHEX0N(audioBufferSize,8) << "-byte audio buffer");
360  return AJA_STATUS_MEMORY;
361  }
362  if (frameData.fAudioBuffer)
363  {
364  frameData.fAudioBuffer.Fill(ULWord(0));
365  #ifdef NTV2_BUFFER_LOCKING
366  mDevice.DMABufferLock(frameData.fAudioBuffer, /*alsoPreLockSGL*/true);
367  #endif
368  }
369  mFrameDataRing.Add (&frameData);
370  } // for each NTV2FrameData
371 
372  return AJA_STATUS_SUCCESS;
373 
374 } // SetUpHostBuffers
375 
376 
378 {
379  vector<NTV2TestPatternSelect> testPatIDs;
380  testPatIDs.push_back(NTV2_TestPatt_ColorBars100);
381  testPatIDs.push_back(NTV2_TestPatt_ColorBars75);
382  testPatIDs.push_back(NTV2_TestPatt_Ramp);
383  testPatIDs.push_back(NTV2_TestPatt_MultiBurst);
384  testPatIDs.push_back(NTV2_TestPatt_LineSweep);
385  testPatIDs.push_back(NTV2_TestPatt_CheckField);
386  testPatIDs.push_back(NTV2_TestPatt_FlatField);
387  testPatIDs.push_back(NTV2_TestPatt_MultiPattern);
388  testPatIDs.push_back(NTV2_TestPatt_Black);
389  testPatIDs.push_back(NTV2_TestPatt_White);
390  testPatIDs.push_back(NTV2_TestPatt_Border);
391  testPatIDs.push_back(NTV2_TestPatt_LinearRamp);
392  testPatIDs.push_back(NTV2_TestPatt_SlantRamp);
393  testPatIDs.push_back(NTV2_TestPatt_ZonePlate);
394  testPatIDs.push_back(NTV2_TestPatt_ColorQuadrant);
395  testPatIDs.push_back(NTV2_TestPatt_ColorQuadrantBorder);
396 
397  mTestPatRasters.clear();
398  for (size_t tpNdx(0); tpNdx < testPatIDs.size(); tpNdx++)
399  mTestPatRasters.push_back(NTV2Buffer());
400 
401  if (!mFormatDesc.IsValid())
402  {PLFAIL("Bad format descriptor"); return AJA_STATUS_FAIL;}
403  if (mFormatDesc.IsVANC())
404  {PLFAIL("VANC incompatible with UHD/4K: " << mFormatDesc); return AJA_STATUS_FAIL;}
405 
406  // Set up one video buffer for each test pattern...
407  for (size_t tpNdx(0); tpNdx < testPatIDs.size(); tpNdx++)
408  {
409  // Allocate the buffer memory...
410  if (!mTestPatRasters.at(tpNdx).Allocate (mFormatDesc.GetVideoWriteSize(), BUFFER_PAGE_ALIGNED))
411  { PLFAIL("Test pattern buffer " << DEC(tpNdx+1) << " of " << DEC(testPatIDs.size()) << ": "
412  << xHEX0N(mFormatDesc.GetVideoWriteSize(),8) << "-byte page-aligned alloc failed");
413  return AJA_STATUS_MEMORY;
414  }
415 
416  // Fill the buffer with test pattern...
417  NTV2TestPatternGen testPatternGen;
418  if (!testPatternGen.DrawTestPattern (testPatIDs.at(tpNdx), mFormatDesc, mTestPatRasters.at(tpNdx)))
419  {
420  cerr << "## ERROR: DrawTestPattern " << DEC(tpNdx) << " failed: " << mFormatDesc << endl;
421  return AJA_STATUS_FAIL;
422  }
423 
424  #ifdef NTV2_BUFFER_LOCKING
425  // Try to prelock the memory, including its scatter-gather list...
426  if (!mDevice.DMABufferLock(mTestPatRasters.at(tpNdx), /*alsoLockSegmentMap=*/true))
427  PLWARN("Test pattern buffer " << DEC(tpNdx+1) << " of " << DEC(testPatIDs.size()) << ": failed to pre-lock");
428  #endif
429  } // loop for each predefined pattern
430 
431  return AJA_STATUS_SUCCESS;
432 
433 } // SetUpTestPatternBuffers
434 
435 
437 {
438  const bool isRGB (::IsRGBFormat(mConfig.fPixelFormat));
439  bool useLinkGrouping = false;
440  UWord failures(0); // tally of routing failures
441 
442  if (!mConfig.fDoMultiFormat)
443  mDevice.ClearRouting(); // Replace current signal routing
444 
445  // Construct switch value to avoid multiple if-then-else
446  int switchValue = 0;
448  switchValue += 8;
449  if (mConfig.fDoTsiRouting)
450  switchValue += 4;
451  if (isRGB)
452  switchValue += 2;
453  if (mConfig.fDoRGBOnWire)
454  switchValue += 1;
455  if (mDevice.features().CanDo12GSDI() && !mDevice.features().CanDo12gRouting())
456  {
457  mDevice.SetSDIOut6GEnable(NTV2_CHANNEL3, false);
458  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, false);
459  if (mConfig.fDoLinkGrouping)
460  useLinkGrouping = true;
461  }
462 
463  switch (switchValue)
464  {
465  case 0: // Low Frame Rate, Square, Pixel YCbCr, Wire YCbCr
466  if (!RouteFsToSDIOut()) failures++;
468  break;
469  case 1: // Low Frame Rate, Square, Pixel YCbCr, Wire RGB
470  if (!RouteFsToCsc()) failures++;
471  if (!RouteCscToDLOut()) failures++;
472  if (!RouteDLOutToSDIOut()) failures++;
474  break;
475  case 2: // Low Frame Rate, Square, Pixel RGB, Wire YCbCr
476  if (!RouteFsToCsc()) failures++;
477  if (!RouteCscTo4xSDIOut()) failures++;
479  break;
480  case 3: // Low Frame Rate, Square, Pixel RGB, Wire RGB
481  if (!RouteFsToDLOut()) failures++;
482  if (!RouteDLOutToSDIOut()) failures++;
484  break;
485  case 4: // Low Frame Rate, Tsi, Pixel YCbCr, Wire YCbCr
486  if (!RouteFsToTsiMux()) failures++;
487  if (!RouteTsiMuxTo2xSDIOut()) failures++;
488  if (useLinkGrouping)
489  {
490  mDevice.SetSDIOut6GEnable(NTV2_CHANNEL3, true);
492  }
493  else
495  break;
496  case 5: // Low Frame Rate, Tsi, Pixel YCbCr, Wire RGB
497  if (!RouteFsToTsiMux()) failures++;
498  if (!RouteTsiMuxToCsc()) failures++;
499  if (!RouteCscToDLOut()) failures++;
500  if (!RouteDLOutToSDIOut()) failures++;
501  if (useLinkGrouping)
502  {
503  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
505  }
506  else
508  break;
509  case 6: // Low Frame Rate, Tsi, Pixel RGB, Wire YCbCr
510  if (!RouteFsToTsiMux()) failures++;
511  if (!RouteTsiMuxToCsc()) failures++;
512  if (!RouteCscTo2xSDIOut()) failures++;
513  if (useLinkGrouping)
514  {
515  mDevice.SetSDIOut6GEnable(NTV2_CHANNEL3, true);
517  }
518  else
520  break;
521  case 7: // Low Frame Rate, Tsi, Pixel RGB, Wire RGB
522  if (!RouteFsToTsiMux()) failures++;
523  if (!RouteTsiMuxToDLOut()) failures++;
524  if (!RouteDLOutToSDIOut()) failures++;
525  if (useLinkGrouping)
526  {
527  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
529  }
530  else
532  break;
533  case 8: // High Frame Rate, Square, Pixel YCbCr, Wire YCbCr
534  if (!RouteFsToSDIOut()) failures++;
536  break;
537  case 9: // High Frame Rate, Square, Pixel YCbCr, Wire RGB
538  // No valid routing for this case
539  break;
540  case 10: // High Frame Rate, Square, Pixel RGB, Wire YCbCr
541  if (!RouteFsToCsc()) failures++;
542  if (!RouteCscTo4xSDIOut()) failures++;
544  break;
545  case 11: // High Frame Rate, Square, Pixel RGB, Wire RGB
546  // No valid routing for this case
547  break;
548  case 12: // High Frame Rate, Tsi, Pixel YCbCr, Wire YCbCr
549  if (!RouteFsToTsiMux()) failures++;
550  if (!RouteTsiMuxTo4xSDIOut()) failures++;
551  if (useLinkGrouping)
552  {
553  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
555  }
556  else
558  break;
559  case 13: // High Frame Rate, Tsi, Pixel YCbCr, Wire RGB
560  // No valid routing for this case
561  break;
562  case 14: // High Frame Rate, Tsi, Pixel RGB, Wire YCbCr
563  if (!RouteFsToTsiMux()) failures++;
564  if (!RouteTsiMuxToCsc()) failures++;
565  if (!RouteCscTo4xSDIOut()) failures++;
566  if(useLinkGrouping)
567  {
568  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
570  }
571  else
573  break;
574  case 15: // High Frame Rate, Tsi, Pixel RGB, Wire RGB
575  // No valid routing for this case
576  break;
577  default:
578  return false; // Fail
579  }
580 
581  if (mDevice.features().CanDo12gRouting())
582  mDevice.SetTsiFrameEnable (true, mConfig.fOutputChannel);
583  else if (mConfig.fDoTsiRouting)
584  mDevice.SetTsiFrameEnable (true, mConfig.fOutputChannel);
585  else
586  mDevice.Set4kSquaresEnable (true, mConfig.fOutputChannel);
587 
588  // Send signal to secondary outputs, if supported
589  if (!Route4KDownConverter()) failures++;
590  if (!RouteHDMIOutput()) failures++;
591  return failures == 0;
592 
593 } // RouteOutputSignal
594 
595 
596 void NTV2Player4K::SetupSDITransmitters (const NTV2Channel inFirstSDI, const UWord inNumSDIs)
597 {
598  if (mDevice.features().HasBiDirectionalSDI())
599  mDevice.SetSDITransmitEnable(::NTV2MakeChannelSet (inFirstSDI, mDevice.features().CanDo12gRouting() ? 1 : inNumSDIs),
600  /*transmit=*/true);
601 }
602 
603 
605 {
607  return true;
608 
609  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
610  UWord connectFailures (0);
611  if (::IsRGBFormat(mConfig.fPixelFormat))
612  {
613  mDevice.Enable4KDCRGBMode(true);
614 
615  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
616  {
617  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
618  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
619  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
620  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
621 
622  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
623  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
624  }
625  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
626  {
627  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
628  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
629  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
630  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
631 
632  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
633  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
634  }
635  }
636  else // YUV FBF
637  {
638  mDevice.Enable4KDCRGBMode (false);
639 
640  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
641  {
642  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
643  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
644  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
645  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
646 
647  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
648  }
649  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
650  {
651  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
652  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
653  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
654  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
655 
656  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
657  }
658  }
659  return connectFailures == 0;
660 
661 } // Route4KDownConverter
662 
663 
665 {
666  const bool isRGB (::IsRGBFormat(mConfig.fPixelFormat));
667  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
668  UWord connectFailures (0);
669 
670  if (mConfig.fDoHDMIOutput &&
674  || mDevice.features().CanDoWidget(NTV2_WgtHDMIOut1v5)) )
675  {
676  if (mDevice.features().CanDo12gRouting())
677  {
678  if (!mDevice.Connect (NTV2_XptHDMIOutInput, ::GetFrameStoreOutputXptFromChannel (mConfig.fOutputChannel, isRGB, false/*is425*/), canVerify))
679  connectFailures++;
680  }
681  else if(mConfig.fDoTsiRouting)
682  {
683  if (isRGB)
684  {
685  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
686  {
687  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
688  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
689  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
690  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
691  }
692  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
693  {
694  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
695  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
696  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
697  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
698  }
699  }
700  else
701  {
702  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
703  {
704  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
705  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
706  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
707  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
708  }
709  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
710  {
711  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
712  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
713  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
714  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
715  }
716  }
717  }
718  else
719  {
720  if (isRGB)
721  {
722  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
723  {
724  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
725  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
726 
727  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
728  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
729 
730  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
731  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
732 
733  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
734  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
735  }
736  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
737  {
738  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
739  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
740 
741  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
742  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
743 
744  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
745  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
746 
747  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
748  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
749  }
750  }
751  else
752  {
753  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
754  {
755  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
756  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
757  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
758  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
759  }
760  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
761  {
762  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
763  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
764  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
765  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
766  }
767  }
768  }
769 
770  mDevice.SetHDMIV2TxBypass (false);
778  }
779  else
781  return connectFailures == 0;
782 
783 } // RouteHDMIOutput
784 
785 
787 {
788  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
789  UWord connectFailures (0);
790  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
791  {
792  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
793  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
794  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
795  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
796  }
797  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
798  {
799  if (!mDevice.Connect (NTV2_XptDualLinkOut5Input, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
800  if (!mDevice.Connect (NTV2_XptDualLinkOut6Input, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
801  if (!mDevice.Connect (NTV2_XptDualLinkOut7Input, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
802  if (!mDevice.Connect (NTV2_XptDualLinkOut8Input, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
803  }
804  return connectFailures == 0;
805 } // RouteFsToDLOut
806 
807 
809 {
810  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
811  UWord connectFailures (0);
812  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
813  {
814  if (::IsRGBFormat(mConfig.fPixelFormat))
815  {
816  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
817  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
818  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
819  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
820  }
821  else
822  {
823  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
824  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
825  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
826  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
827  }
828  }
829  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
830  {
831  if (::IsRGBFormat(mConfig.fPixelFormat))
832  {
833  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
834  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
835  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
836  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
837  }
838  else
839  {
840  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
841  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
842  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
843  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
844  }
845  }
846  return connectFailures == 0;
847 } // RouteFsToCsc
848 
849 
851 {
852  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
853  UWord connectFailures (0);
854  if (mDevice.features().CanDo12gRouting())
855  {
856  if (!mDevice.Connect ( ::GetSDIOutputInputXpt (mConfig.fOutputChannel, false/*isDS2*/),
857  ::GetFrameStoreOutputXptFromChannel (mConfig.fOutputChannel, false/*isRGB*/, false/*is425*/),
858  canVerify))
859  connectFailures++;
860  }
861  else
862  {
863  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
864  {
865  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
866  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
867  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
868  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
869  }
870  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
871  {
872  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
873  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
874  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
875  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
876  }
877  }
878  return connectFailures == 0;
879 } // RouteFsToSDIOut
880 
881 
883 {
884  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
885  UWord connectFailures (0);
886  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
887  {
888  if (::IsRGBFormat(mConfig.fPixelFormat))
889  {
890  if (!mDevice.Connect (NTV2_Xpt425Mux1AInput, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
891  if (!mDevice.Connect (NTV2_Xpt425Mux1BInput, NTV2_XptFrameBuffer1_DS2RGB, canVerify)) connectFailures++;
892  if (!mDevice.Connect (NTV2_Xpt425Mux2AInput, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
893  if (!mDevice.Connect (NTV2_Xpt425Mux2BInput, NTV2_XptFrameBuffer2_DS2RGB, canVerify)) connectFailures++;
894  }
895  else
896  {
897  if (!mDevice.Connect (NTV2_Xpt425Mux1AInput, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
898  if (!mDevice.Connect (NTV2_Xpt425Mux1BInput, NTV2_XptFrameBuffer1_DS2YUV, canVerify)) connectFailures++;
899  if (!mDevice.Connect (NTV2_Xpt425Mux2AInput, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
900  if (!mDevice.Connect (NTV2_Xpt425Mux2BInput, NTV2_XptFrameBuffer2_DS2YUV, canVerify)) connectFailures++;
901  }
902  }
903  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
904  {
905  if (::IsRGBFormat(mConfig.fPixelFormat))
906  {
907  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
908  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer3_DS2RGB, canVerify)) connectFailures++;
909  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
910  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer4_DS2RGB, canVerify)) connectFailures++;
911  }
912  else
913  {
914  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
915  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer3_DS2YUV, canVerify)) connectFailures++;
916  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
917  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer4_DS2YUV, canVerify)) connectFailures++;
918  }
919  }
920  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
921  {
922  if (::IsRGBFormat(mConfig.fPixelFormat))
923  {
924  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
925  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer5_DS2RGB, canVerify)) connectFailures++;
926  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
927  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer6_DS2RGB, canVerify)) connectFailures++;
928  }
929  else
930  {
931  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
932  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer5_DS2YUV, canVerify)) connectFailures++;
933  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
934  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer6_DS2YUV, canVerify)) connectFailures++;
935  }
936  }
937  return connectFailures == 0;
938 } // RouteFsToTsiMux
939 
940 
942 {
943  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
944  UWord connectFailures (0);
945  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
946  {
947  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptDuallinkOut1, canVerify)) connectFailures++;
948  if (!mDevice.Connect (NTV2_XptSDIOut1InputDS2, NTV2_XptDuallinkOut1DS2, canVerify)) connectFailures++;
949  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptDuallinkOut2, canVerify)) connectFailures++;
950  if (!mDevice.Connect (NTV2_XptSDIOut2InputDS2, NTV2_XptDuallinkOut2DS2, canVerify)) connectFailures++;
951  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_XptDuallinkOut3, canVerify)) connectFailures++;
952  if (!mDevice.Connect (NTV2_XptSDIOut3InputDS2, NTV2_XptDuallinkOut3DS2, canVerify)) connectFailures++;
953  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_XptDuallinkOut4, canVerify)) connectFailures++;
954  if (!mDevice.Connect (NTV2_XptSDIOut4InputDS2, NTV2_XptDuallinkOut4DS2, canVerify)) connectFailures++;
955  }
956  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
957  {
958  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptDuallinkOut5, canVerify)) connectFailures++;
959  if (!mDevice.Connect (NTV2_XptSDIOut5InputDS2, NTV2_XptDuallinkOut5DS2, canVerify)) connectFailures++;
960  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptDuallinkOut6, canVerify)) connectFailures++;
961  if (!mDevice.Connect (NTV2_XptSDIOut6InputDS2, NTV2_XptDuallinkOut6DS2, canVerify)) connectFailures++;
962  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_XptDuallinkOut7, canVerify)) connectFailures++;
963  if (!mDevice.Connect (NTV2_XptSDIOut7InputDS2, NTV2_XptDuallinkOut7DS2, canVerify)) connectFailures++;
964  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_XptDuallinkOut8, canVerify)) connectFailures++;
965  if (!mDevice.Connect (NTV2_XptSDIOut8InputDS2, NTV2_XptDuallinkOut8DS2, canVerify)) connectFailures++;
966  }
967  return connectFailures == 0;
968 } // RouteDLOutToSDIOut
969 
970 
972 {
973  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
974  UWord connectFailures (0);
975  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
976  {
977  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
978  if (!mDevice.Connect (NTV2_XptSDIOut1InputDS2, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
979  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
980  if (!mDevice.Connect (NTV2_XptSDIOut2InputDS2, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
981  }
982  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
983  {
984  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
985  if (!mDevice.Connect (NTV2_XptSDIOut5InputDS2, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
986  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
987  if (!mDevice.Connect (NTV2_XptSDIOut6InputDS2, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
988  }
989  return connectFailures == 0;
990 } // RouteCscTo2xSDIOut
991 
992 
994 {
995  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
996  UWord connectFailures (0);
997  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
998  {
999  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
1000  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
1001  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
1002  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
1003  }
1004  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1005  {
1006  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
1007  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
1008  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
1009  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
1010  }
1011  return connectFailures == 0;
1012 } // RouteCscTo4xSDIOut
1013 
1014 
1016 {
1017  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1018  UWord connectFailures (0);
1019  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1020  {
1021  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_XptCSC1VidRGB, canVerify)) connectFailures++;
1022  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_XptCSC2VidRGB, canVerify)) connectFailures++;
1023  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_XptCSC3VidRGB, canVerify)) connectFailures++;
1024  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_XptCSC4VidRGB, canVerify)) connectFailures++;
1025  }
1026  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1027  {
1028  if (!mDevice.Connect (NTV2_XptDualLinkOut5Input, NTV2_XptCSC5VidRGB, canVerify)) connectFailures++;
1029  if (!mDevice.Connect (NTV2_XptDualLinkOut6Input, NTV2_XptCSC6VidRGB, canVerify)) connectFailures++;
1030  if (!mDevice.Connect (NTV2_XptDualLinkOut7Input, NTV2_XptCSC7VidRGB, canVerify)) connectFailures++;
1031  if (!mDevice.Connect (NTV2_XptDualLinkOut8Input, NTV2_XptCSC8VidRGB, canVerify)) connectFailures++;
1032  }
1033  return connectFailures == 0;
1034 } // RouteCscToDLOut
1035 
1036 
1038 {
1039  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1040  UWord connectFailures (0);
1041  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1042  {
1043  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_Xpt425Mux1ARGB, canVerify)) connectFailures++;
1044  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_Xpt425Mux1BRGB, canVerify)) connectFailures++;
1045  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_Xpt425Mux2ARGB, canVerify)) connectFailures++;
1046  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_Xpt425Mux2BRGB, canVerify)) connectFailures++;
1047  }
1048  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1049  {
1050  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1051  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1052  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1053  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1054  }
1055  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1056  {
1057  if (!mDevice.Connect (NTV2_XptDualLinkOut5Input, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1058  if (!mDevice.Connect (NTV2_XptDualLinkOut6Input, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1059  if (!mDevice.Connect (NTV2_XptDualLinkOut7Input, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1060  if (!mDevice.Connect (NTV2_XptDualLinkOut8Input, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1061  }
1062  return connectFailures == 0;
1063 } // RouteTsiMuxToDLOut
1064 
1065 
1067 {
1068  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1069  UWord connectFailures (0);
1070  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1071  {
1072  if (::IsRGBFormat(mConfig.fPixelFormat))
1073  {
1074  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux1ARGB, canVerify)) connectFailures++;
1075  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux1BRGB, canVerify)) connectFailures++;
1076  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux2ARGB, canVerify)) connectFailures++;
1077  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux2BRGB, canVerify)) connectFailures++;
1078  }
1079  else
1080  {
1081  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
1082  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
1083  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
1084  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
1085  }
1086  }
1087  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1088  {
1089  if (::IsRGBFormat(mConfig.fPixelFormat))
1090  {
1091  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1092  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1093  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1094  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1095  }
1096  else
1097  {
1098  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1099  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1100  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1101  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1102  }
1103  }
1104  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1105  {
1106  if (::IsRGBFormat(mConfig.fPixelFormat))
1107  {
1108  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1109  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1110  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1111  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1112  }
1113  else
1114  {
1115  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1116  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1117  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1118  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1119  }
1120  }
1121  return connectFailures == 0;
1122 } // RouteTsiMuxToCsc
1123 
1124 
1126 {
1127  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1128  UWord connectFailures (0);
1129  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1130  {
1131  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
1132  if (!mDevice.Connect (NTV2_XptSDIOut1InputDS2, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
1133  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
1134  if (!mDevice.Connect (NTV2_XptSDIOut2InputDS2, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
1135  }
1136  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1137  {
1138  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1139  if (!mDevice.Connect (NTV2_XptSDIOut3InputDS2, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1140  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1141  if (!mDevice.Connect (NTV2_XptSDIOut4InputDS2, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1142  }
1143  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1144  {
1145  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1146  if (!mDevice.Connect (NTV2_XptSDIOut5InputDS2, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1147  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1148  if (!mDevice.Connect (NTV2_XptSDIOut6InputDS2, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1149  }
1150  return connectFailures == 0;
1151 } // RouteTsiMuxTo2xSDIOut
1152 
1153 
1155 {
1156  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1157  UWord connectFailures (0);
1158  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1159  {
1160  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
1161  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
1162  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
1163  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
1164  }
1165  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1166  { // Io4k+ 12G output
1167  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1168  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1169  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1170  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1171  }
1172  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1173  {
1174  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1175  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1176  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1177  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1178  }
1179  return connectFailures == 0;
1180 } // RouteTsiMuxTo4xSDIOut
1181 
1182 
1184 {
1185  // Start my consumer and producer threads...
1188  return AJA_STATUS_SUCCESS;
1189 
1190 } // Run
1191 
1192 
1193 
1195 // This is where the play thread starts
1196 
1198 {
1199  // Create and start the playout thread...
1200  mConsumerThread.Attach (ConsumerThreadStatic, this);
1201  mConsumerThread.SetPriority(AJA_ThreadPriority_High);
1202  mConsumerThread.Start();
1203 
1204 } // StartConsumerThread
1205 
1206 
1207 // The playout thread function
1208 void NTV2Player4K::ConsumerThreadStatic (AJAThread * pThread, void * pContext) // static
1209 { (void) pThread;
1210  // Grab the NTV2Player4K instance pointer from the pContext parameter,
1211  // then call its PlayFrames method...
1212  NTV2Player4K * pApp (reinterpret_cast<NTV2Player4K*>(pContext));
1213  if (pApp)
1214  pApp->ConsumeFrames();
1215 
1216 } // ConsumerThreadStatic
1217 
1218 
1220 {
1221  ULWord acOptions (AUTOCIRCULATE_WITH_RP188);
1222  AUTOCIRCULATE_TRANSFER outputXfer;
1223  AUTOCIRCULATE_STATUS outputStatus;
1224  AJAAncillaryData * pPkt (AJA_NULL);
1225  ULWord goodXfers(0), badXfers(0), prodWaits(0), noRoomWaits(0);
1226  const UWord numACFramesPerChannel(7);
1227 
1228  // Stop AutoCirculate, just in case someone else left it running...
1229  mDevice.AutoCirculateStop(mConfig.fOutputChannel);
1230  mDevice.WaitForOutputVerticalInterrupt(mConfig.fOutputChannel, 4); // Let it stop
1231  PLNOTE("Thread started");
1232 
1233  if (pPkt)
1234  { // Allocate page-aligned host Anc buffer...
1235  uint32_t hdrPktSize (0);
1236  if (!outputXfer.acANCBuffer.Allocate(gAncMaxSizeBytes, BUFFER_PAGE_ALIGNED) || !outputXfer.acANCBuffer.Fill(0LL))
1237  PLWARN("Anc buffer " << xHEX0N(gAncMaxSizeBytes,8) << "(" << DEC(gAncMaxSizeBytes) << ")-byte allocate failed -- HDR anc insertion disabled");
1238  else if (AJA_FAILURE(pPkt->GenerateTransmitData (outputXfer.acANCBuffer, outputXfer.acANCBuffer, hdrPktSize)))
1239  {
1240  PLWARN("HDR anc insertion disabled -- GenerateTransmitData failed");
1241  outputXfer.acANCBuffer.Deallocate();
1242  }
1243  else
1244  acOptions |= AUTOCIRCULATE_WITH_ANC;
1245  }
1246 #ifdef NTV2_BUFFER_LOCKING
1247  if (outputXfer.acANCBuffer)
1248  mDevice.DMABufferLock(outputXfer.acANCBuffer, /*alsoLockSGL*/true);
1249 #endif
1250 
1251  // Calculate start & end frame numbers (if mConfig.fFrames not used)...
1252  UWord startNum(0), endNum(0);
1253  if (mDevice.features().CanDo12gRouting())
1254  startNum = numACFramesPerChannel * mConfig.fOutputChannel;
1255  else switch (mConfig.fOutputChannel)
1256  { default:
1257  case NTV2_CHANNEL1: if (mConfig.fNumAudioLinks > 1)
1258  {
1261  {
1264  }
1265  }
1266  AJA_FALL_THRU;
1267  case NTV2_CHANNEL2: startNum = numACFramesPerChannel * 0; break;
1268 
1269  case NTV2_CHANNEL3: if (mConfig.fNumAudioLinks > 1)
1271  AJA_FALL_THRU;
1272  case NTV2_CHANNEL4: startNum = numACFramesPerChannel * 1; break;
1273 
1275  case NTV2_CHANNEL6: startNum = numACFramesPerChannel * 2; break;
1276 
1278  case NTV2_CHANNEL8: startNum = numACFramesPerChannel * 3; break;
1279  }
1280  endNum = startNum + numACFramesPerChannel - 1;
1281 
1282  // Initialize & start AutoCirculate...
1283  bool initOK(false);
1284  if (mConfig.fFrames.valid()) // --frames option controls everything:
1285  initOK = mDevice.AutoCirculateInitForOutput (mConfig.fOutputChannel, mConfig.fFrames.count(), mAudioSystem, acOptions,
1286  1 /*numChannels*/, mConfig.fFrames.firstFrame(), mConfig.fFrames.lastFrame());
1287  else // --frames option not used -- explicitly specify start & end frame numbers (as calculated above)
1288  initOK = mDevice.AutoCirculateInitForOutput (mConfig.fOutputChannel, 0, mAudioSystem, acOptions,
1289  1 /*numChannels*/, startNum, endNum);
1290  if (!initOK)
1291  {PLFAIL("AutoCirculateInitForOutput failed"); mGlobalQuit = true;}
1292 
1293  while (!mGlobalQuit)
1294  {
1295  mDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outputStatus);
1296 
1297  // Check if there's room for another frame on the card...
1298  if (outputStatus.CanAcceptMoreOutputFrames())
1299  {
1300  // Device has at least one free frame buffer that can be filled.
1301  // Wait for the next frame in our ring to become ready to "consume"...
1302  NTV2FrameData * pFrameData (mFrameDataRing.StartConsumeNextBuffer());
1303  if (!pFrameData)
1304  {prodWaits++; continue;}
1305 
1306  // Unlike in the NTV2Player demo, I now burn the current timecode into the test pattern buffer that was noted
1307  // earlier into this FrameData in my Producer thread. This is done to avoid copying large 4K/UHD rasters.
1308  const NTV2FrameRate ntv2FrameRate (::GetNTV2FrameRateFromVideoFormat(mConfig.fVideoFormat));
1309  const TimecodeFormat tcFormat (CNTV2DemoCommon::NTV2FrameRate2TimecodeFormat(ntv2FrameRate));
1310  const CRP188 rp188Info (mCurrentFrame++, 0, 0, 10, tcFormat);
1311  NTV2_RP188 tcData;
1312  string timeCodeString;
1313 
1314  rp188Info.GetRP188Reg (tcData);
1315  rp188Info.GetRP188Str (timeCodeString);
1316  mTCBurner.BurnTimeCode (pFrameData->fVideoBuffer, timeCodeString.c_str(), 80);
1317 
1318  // Transfer the timecode-burned frame (plus audio) to the device for playout...
1319  outputXfer.acVideoBuffer.Set (pFrameData->fVideoBuffer, pFrameData->fVideoBuffer);
1320  outputXfer.acAudioBuffer.Set (pFrameData->fAudioBuffer, pFrameData->fNumAudioBytes);
1321  outputXfer.SetOutputTimeCode (tcData, ::NTV2ChannelToTimecodeIndex(mConfig.fOutputChannel, /*LTC=*/false, /*F2=*/false));
1322  outputXfer.SetOutputTimeCode (tcData, ::NTV2ChannelToTimecodeIndex(mConfig.fOutputChannel, /*LTC=*/true, /*F2=*/false));
1323 
1324  // Perform the DMA transfer to the device...
1325  if (mDevice.AutoCirculateTransfer (mConfig.fOutputChannel, outputXfer))
1326  goodXfers++;
1327  else
1328  badXfers++;
1329 
1330  if (goodXfers == 3)
1331  mDevice.AutoCirculateStart(mConfig.fOutputChannel);
1332 
1333  // Signal that the frame has been "consumed"...
1334  mFrameDataRing.EndConsumeNextBuffer();
1335  continue; // Back to top of while loop
1336  }
1337 
1338  // Wait for one or more buffers to become available on the device, which should occur at next VBI...
1339  noRoomWaits++;
1341  } // loop til quit signaled
1342 
1343  // Stop AutoCirculate...
1344  mDevice.AutoCirculateStop(mConfig.fOutputChannel);
1345  PLNOTE("Thread completed: " << DEC(goodXfers) << " xfers, " << DEC(badXfers) << " failed, "
1346  << DEC(prodWaits) << " starves, " << DEC(noRoomWaits) << " VBI waits");
1347 
1348 } // ConsumeFrames
1349 
1350 
1351 
1353 // This is where the producer thread starts
1354 
1356 {
1357  // Create and start the producer thread...
1358  mProducerThread.Attach(ProducerThreadStatic, this);
1359  mProducerThread.SetPriority(AJA_ThreadPriority_High);
1360  mProducerThread.Start();
1361 
1362 } // StartProducerThread
1363 
1364 
1365 void NTV2Player4K::ProducerThreadStatic (AJAThread * pThread, void * pContext) // static
1366 {
1367  (void) pThread;
1368  NTV2Player4K * pApp (reinterpret_cast<NTV2Player4K*>(pContext));
1369  if (pApp)
1370  pApp->ProduceFrames();
1371 
1372 } // ProducerThreadStatic
1373 
1374 
1376 {
1377  ULWord freqNdx(0), testPatNdx(0), badTally(0);
1378  double timeOfLastSwitch (0.0);
1379 
1382 
1383  PLNOTE("Thread started");
1384  while (!mGlobalQuit)
1385  {
1386  NTV2FrameData * pFrameData (mFrameDataRing.StartProduceNextBuffer());
1387  if (!pFrameData)
1388  { badTally++; // No frame available!
1389  AJATime::Sleep(10); // Wait a bit for the consumer thread to free one up for me...
1390  continue; // ...then try again
1391  }
1392 
1393  // Unlike NTV2Player::ProduceFrames, NTV2Player4K::ProduceFrames doesn't touch this frame's video buffer.
1394  // Instead, to avoid wasting time copying large 4K/UHD rasters, in this thread we simply note which test
1395  // pattern buffer is to be modified and subsequently transferred to the hardware. This happens later, in
1396  // NTV2Player4K::ConsumeFrames...
1397  NTV2Buffer & testPatVidBuffer(mTestPatRasters.at(testPatNdx));
1398  pFrameData->fVideoBuffer.Set(testPatVidBuffer.GetHostPointer(), testPatVidBuffer.GetByteCount());
1399 
1400  // If also playing audio...
1401  if (pFrameData->AudioBuffer()) // ...then generate audio tone data for this frame...
1402  pFrameData->fNumAudioBytes = AddTone(pFrameData->AudioBuffer()); // ...and remember number of audio bytes to xfer
1403 
1404  // Every few seconds, change the test pattern and tone frequency...
1405  const double currentTime (timeBase.FramesToSeconds(mCurrentFrame++));
1406  if (currentTime > timeOfLastSwitch + 4.0)
1407  {
1408  freqNdx = (freqNdx + 1) % gNumFrequencies;
1409  testPatNdx = (testPatNdx + 1) % ULWord(mTestPatRasters.size());
1410  mToneFrequency = gFrequencies[freqNdx];
1411  timeOfLastSwitch = currentTime;
1412  PLINFO("F" << DEC0N(mCurrentFrame,6) << ": tone=" << mToneFrequency << "Hz, pattern='" << tpNames.at(testPatNdx) << "'");
1413  } // if time to switch test pattern & tone frequency
1414 
1415  // Signal that I'm done producing this FrameData, making it immediately available for transfer/playout...
1416  mFrameDataRing.EndProduceNextBuffer();
1417 
1418  } // loop til mGlobalQuit goes true
1419  PLNOTE("Thread completed: " << DEC(mCurrentFrame) << " frame(s) produced, " << DEC(badTally) << " failed");
1420 
1421 } // ProduceFrames
1422 
1423 
1424 uint32_t NTV2Player4K::AddTone (ULWord * audioBuffer)
1425 {
1428  ULWord numChannels (0);
1429 
1430  mDevice.GetFrameRate (frameRate, mConfig.fOutputChannel);
1431  mDevice.GetAudioRate (audioRate, mAudioSystem);
1432  mDevice.GetNumberAudioChannels (numChannels, mAudioSystem);
1433 
1434  // Since audio on AJA devices use fixed sample rates (typically 48KHz), certain video frame rates will
1435  // necessarily result in some frames having more audio samples than others. GetAudioSamplesPerFrame is
1436  // called to calculate the correct sample count for the current frame...
1437  const ULWord numSamples (::GetAudioSamplesPerFrame (frameRate, audioRate, mCurrentFrame));
1438  const double sampleRateHertz (::GetAudioSamplesPerSecond(audioRate));
1439 
1440  // Unlike NTV2Player::AddTone, NTV2Player4K::AddTone handles multi-link audio:
1441  ULWord bytesWritten(0), startSample(mCurrentSample);
1442  for (UWord linkNdx(0); linkNdx < mConfig.fNumAudioLinks; linkNdx++)
1443  {
1444  mCurrentSample = startSample;
1445  bytesWritten += ::AddAudioTone (audioBuffer + (bytesWritten/4), // audio buffer to fill
1446  mCurrentSample, // which sample for continuing the waveform
1447  numSamples, // number of samples to generate
1448  sampleRateHertz, // sample rate [Hz]
1449  0.50, // uniform amplitude
1450  mToneFrequency, // uniform tone frequency [Hz]
1451  31, // bits per sample
1452  false, // don't byte swap
1453  numChannels); // number of audio channels to generate
1454  } // for each SDI audio link
1455  return bytesWritten;
1456 
1457 } // AddTone
1458 
1459 
1461 {
1462  mDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outStatus);
1463 }
ULWord GetVideoWriteSize(ULWord inPageSize=4096UL) const
static const bool BUFFER_PAGE_ALIGNED((!(0)))
NTV2FrameRate GetNTV2FrameRateFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:3630
Declares the AJAAncillaryData_HDR_HDR10 class.
double FramesToSeconds(int64_t frames) const
Definition: timebase.cpp:197
virtual bool SetTaskMode(const NTV2TaskMode inMode)
Sets the device&#39;s task mode.
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
#define NTV2_IS_VALID_TASK_MODE(__m__)
NTV2AudioSystem
Used to identify an Audio System on an NTV2 device. See Audio System Operation for more information...
Definition: ntv2enums.h:3895
virtual bool SetHDMIV2Mode(const NTV2HDMIV2Mode inMode)
Sets HDMI V2 mode for the device.
Definition: ntv2hdmi.cpp:678
virtual AJAStatus GenerateTransmitData(uint8_t *pBuffer, const size_t inMaxBytes, uint32_t &outPacketSize)
Generates "raw" ancillary data from my internal ancillary data (playback) – see SDI Anc Buffer Data ...
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...
virtual bool SetAudioLoopBack(const NTV2AudioLoopBack inMode, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Enables or disables NTV2AudioLoopBack mode for the given NTV2AudioSystem.
Definition: ntv2audio.cpp:300
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO3
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 3. ...
Specifies the device&#39;s internal clock.
Definition: ntv2enums.h:1459
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=(0))
Sets the device&#39;s clock reference source. See Video Output Clocking & Synchronization for more inform...
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
AJAStatus Add(FrameDataPtr pInFrameData)
Appends a new frame buffer to me, increasing my frame storage capacity by one frame.
The NTV2 test pattern generator.
virtual bool RouteDLOutToSDIOut(void)
Sets up board routing from the Dual Link outputs to the SDI outputs.
virtual bool SetLHIHDMIOutColorSpace(const NTV2LHIHDMIColorSpace inNewValue, const NTV2Channel inWhichHDMIOut=NTV2_CHANNEL1)
Sets the color space to use for the given HDMI output.
Definition: ntv2hdmi.cpp:475
#define DEC0N(__x__, __n__)
virtual AJAStatus SetUpAudio(void)
Performs all audio setup.
virtual bool RouteFsToSDIOut(void)
Sets up board routing from the Frame Stores to the SDI outputs.
virtual void GetACStatus(AUTOCIRCULATE_STATUS &outStatus)
Provides status information about my output (playout) process.
virtual bool SetVideoFormat(const NTV2VideoFormat inVideoFormat, const bool inIsAJARetail=(!(0)), const bool inKeepVancSettings=(0), const NTV2Channel inChannel=NTV2_CHANNEL1)
Configures the AJA device to handle a specific video format.
virtual AJAStatus SetUpHostBuffers(void)
Sets up my host video & audio buffers.
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...
virtual bool SetSDIOut6GEnable(const NTV2Channel inChannel, const bool inEnable)
AJAStatus
Definition: types.h:380
virtual bool IsDeviceReady(const bool inCheckValid=(0))
static void ConsumerThreadStatic(AJAThread *pThread, void *pContext)
This is the consumer thread&#39;s static callback function that gets called when the consumer thread star...
static uint64_t GetPid()
Definition: process.cpp:35
virtual bool RouteCscToDLOut(void)
Sets up board routing from the Color Space Converters to the Dual Link outputs.
#define AJA_FAILURE(_status_)
Definition: types.h:373
#define PLINFO(_xpr_)
UWord count(void) const
Definition: ntv2utils.h:984
Declares the NTV2TestPatternGen class.
virtual bool GetAudioRate(NTV2AudioRate &outRate, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Returns the current NTV2AudioRate for the given Audio System.
Definition: ntv2audio.cpp:226
bool fDoLinkGrouping
If true, enables 6/12G output mode on IoX3/Kona5 (4K/8K)
NTV2AudioSystemSet NTV2MakeAudioSystemSet(const NTV2AudioSystem inFirstAudioSystem, const UWord inCount=1)
NTV2Buffer acVideoBuffer
The host video buffer. This field is owned by the client application, and thus is responsible for all...
static const ULWord gNumFrequencies(sizeof(gFrequencies)/sizeof(double))
virtual AJAStatus SetPriority(AJAThreadPriority priority)
Definition: thread.cpp:133
FrameDataPtr StartConsumeNextBuffer(void)
The thread that&#39;s responsible for processing incoming frames – the consumer – calls this function t...
bool CanAcceptMoreOutputFrames(void) const
bool SetOutputTimeCode(const NTV2_RP188 &inTimecode, const NTV2TCIndex inTCIndex=NTV2_TCINDEX_SDI1)
Intended for playout, sets one element of my acOutputTimeCodes member.
Declares the AJAAncillaryData_HDR_HLG class.
virtual void Quit(void)
Gracefully stops me from running.
UWord firstFrame(void) const
Definition: ntv2utils.h:985
Header file for NTV2Player4K demonstration class.
Definition: json.hpp:5362
virtual AJAStatus Start()
Definition: thread.cpp:91
This identifies the 3rd Audio System.
Definition: ntv2enums.h:3899
virtual void ProduceFrames(void)
My producer thread that repeatedly produces video frames.
void EndConsumeNextBuffer(void)
The consumer thread calls this function to signal that it has finished processing the frame it obtain...
std::string fDeviceSpec
The AJA device to use.
#define false
uint32_t ULWord
Definition: ajatypes.h:223
virtual bool AutoCirculateGetStatus(const NTV2Channel inChannel, AUTOCIRCULATE_STATUS &outStatus)
Returns the current AutoCirculate status for the given channel.
virtual bool SetFrameBufferFormat(NTV2Channel inChannel, NTV2FrameBufferFormat inNewFormat, bool inIsAJARetail=(!(0)), NTV2HDRXferChars inXferChars=NTV2_VPID_TC_SDR_TV, NTV2HDRColorimetry inColorimetry=NTV2_VPID_Color_Rec709, NTV2HDRLuminance inLuminance=NTV2_VPID_Luminance_YCbCr)
Sets the frame buffer format for the given FrameStore on the AJA device.
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1357
virtual bool SetHDMIV2TxBypass(const bool inBypass)
Definition: ntv2hdmi.cpp:362
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:148
virtual bool GetAncRegionOffsetFromBottom(ULWord &outByteOffsetFromBottom, const NTV2AncillaryDataRegion inAncRegion=NTV2_AncRgn_All)
Answers with the byte offset to the start of an ancillary data region within a device frame buffer...
Definition: ntv2dma.cpp:601
virtual bool SetMultiFormatMode(const bool inEnable)
Enables or disables multi-format (per channel) device operation. If enabled, each device channel can ...
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO1
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 1. ...
virtual void StartProducerThread(void)
Starts my producer thread.
virtual bool ClearRouting(void)
Removes all existing signal path connections between any and all widgets on the AJA device...
Declares the AJATimeBase class.
virtual bool RouteTsiMuxToDLOut(void)
Sets up board routing from the Two Sample Interleave muxes to the Dual Link outputs.
This struct replaces the old RP188_STRUCT.
NTV2TCIndex NTV2ChannelToTimecodeIndex(const NTV2Channel inChannel, const bool inEmbeddedLTC=false, const bool inIsF2=false)
Converts the given NTV2Channel value into the equivalent NTV2TCIndex value.
Definition: ntv2utils.cpp:4962
virtual bool IsRemote(void) const
ULWord numPixels
Width – total number of pixels per line.
virtual bool Active()
Definition: thread.cpp:116
bool Fill(const T &inValue)
Fills me with the given scalar value.
virtual bool GetTaskMode(NTV2TaskMode &outMode)
Retrieves the device&#39;s current task mode.
bool WithAudio(void) const
virtual bool SetHDMIOutAudioRate(const NTV2AudioRate inNewValue, const NTV2Channel inWhichHDMIOut=NTV2_CHANNEL1)
Sets the HDMI output&#39;s audio rate.
Definition: ntv2audio.cpp:1009
bool Deallocate(void)
Deallocates my user-space storage (if I own it – i.e. from a prior call to Allocate).
virtual bool RouteTsiMuxToCsc(void)
Sets up board routing from the Two Sample Interleave muxes to the color Space Converters.
static AJA_PixelFormat GetAJAPixelFormat(const NTV2PixelFormat inFormat)
This selects audio channels 1 thru 8.
Definition: ntv2enums.h:3322
static const uint32_t gAudMaxSizeBytes(256 *1024)
The maximum number of bytes of 48KHz audio that can be transferred for a single frame. Worst case, assuming 16 channels of audio (max), 4 bytes per sample, and 67 msec per frame (assuming the lowest possible frame rate of 14.98 fps)... 48,000 samples per second requires 3,204 samples x 4 bytes/sample x 16 = 205,056 bytes 201K min will suffice, with 768 bytes to spare But it could be more efficient for page-aligned (and page-locked) memory to round to 256K.
NTV2FrameRate
Identifies a particular video frame rate.
Definition: ntv2enums.h:412
virtual bool RouteOutputSignal(void)
Performs all widget/signal routing for playout.
static void ProducerThreadStatic(AJAThread *pThread, void *pContext)
This is the producer thread&#39;s static callback function that gets called when the producer thread star...
static const double gFrequencies[]
virtual bool DrawTestPattern(const std::string &inTPName, const NTV2FormatDescriptor &inFormatDesc, NTV2Buffer &inBuffer)
Renders the given test pattern or color into a host raster buffer.
virtual bool EnableChannels(const NTV2ChannelSet &inChannels, const bool inDisableOthers=(0))
Enables the given FrameStore(s).
virtual std::string GetDescription(void) const
Definition: ntv2card.cpp:139
UWord fNumAudioLinks
The number of audio systems to control for multi-link audio (4K/8K)
static TimecodeFormat NTV2FrameRate2TimecodeFormat(const NTV2FrameRate inFrameRate)
virtual bool RouteTsiMuxTo4xSDIOut(void)
Sets up board routing from the Two Sample Interleave muxes to the 4xSDI outputs.
virtual bool IsOpen(void) const
virtual void StartConsumerThread(void)
Starts my consumer thread.
virtual bool UnsubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Unregisters me so I&#39;m no longer notified when an output VBI is signaled on the given output channel...
static bool GetFirstDeviceFromArgument(const std::string &inArgument, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the AJA device that matches a command li...
virtual bool SetSDITransmitEnable(const NTV2Channel inChannel, const bool inEnable)
Sets the specified bidirectional SDI connector to act as an input or an output.
virtual bool AutoCirculateTransfer(const NTV2Channel inChannel, AUTOCIRCULATE_TRANSFER &transferInfo)
Transfers all or part of a frame as specified in the given AUTOCIRCULATE_TRANSFER object to/from the ...
virtual bool AcquireStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Reserves exclusive use of the AJA device for a given process, preventing other processes on the host ...
virtual bool DMABufferLock(const NTV2Buffer &inBuffer, bool inMap=(0), bool inRDMA=(0))
Page-locks the given host buffer to reduce transfer time and CPU usage of DMA transfers.
Definition: ntv2dma.cpp:429
#define AJA_NULL
Definition: ajatypes.h:167
void SetAbortFlag(const bool *pAbortFlag)
Tells me the boolean variable I should monitor such that when it gets set to "true" will cause any th...
virtual std::string GetDisplayName(void)
Answers with this device&#39;s display name.
Definition: ntv2card.cpp:88
Describes a video frame for a given video standard or format and pixel format, including the total nu...
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
virtual bool RouteTsiMuxTo2xSDIOut(void)
Sets up board routing from the Two Sample Interleave muxes to the 2xSDI outputs.
NTV2PixelFormat fPixelFormat
The pixel format to use.
2: OEM (recommended): device configured by client application(s) with some driver involvement...
virtual bool Enable4KDCRGBMode(bool inEnable)
Sets 4K Down Convert RGB mode.
virtual bool SetHDMIOutVideoStandard(const NTV2Standard inNewValue, const NTV2Channel inWhichHDMIOut=NTV2_CHANNEL1)
Sets the video standard to use for the given HDMI output.
Definition: ntv2hdmi.cpp:339
virtual bool SetSDIOutputAudioSystem(const NTV2Channel inSDIOutputConnector, const NTV2AudioSystem inAudioSystem)
Sets the device&#39;s NTV2AudioSystem that will provide audio for the given SDI output&#39;s audio embedder...
#define PLNOTE(_xpr_)
virtual AJAStatus SetUpTestPatternBuffers(void)
Creates my test pattern buffers.
std::set< NTV2AudioSystem > NTV2AudioSystemSet
A set of distinct NTV2AudioSystem values. New in SDK 16.2.
NTV2VideoFormat fVideoFormat
The video format to use.
std::string NTV2VideoFormatToString(const NTV2VideoFormat inValue, const bool inUseFrameRate=false)
Definition: ntv2utils.cpp:6746
Embeds silence (zeroes) into the data stream.
Definition: ntv2enums.h:2030
virtual bool SetVANCShiftMode(NTV2Channel inChannel, NTV2VANCDataShiftMode inMode)
Enables or disables the "VANC Shift Mode" feature for the given channel.
virtual bool SetTsiFrameEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 two-sample interleave (Tsi) frame mode on the device.
Specifies channel or FrameStore 8 (or the 8th item).
Definition: ntv2enums.h:1366
AJA_EXPORT bool RenderTimeCodeFont(AJA_PixelFormat pixelFormat, uint32_t numPixels, uint32_t numLines)
virtual bool DMABufferUnlockAll()
Unlocks all previously-locked buffers used for DMA transfers.
Definition: ntv2dma.cpp:457
Specifies the PTP source on SFP 1.
Definition: ntv2enums.h:1468
bool fDoRGBOnWire
If true, produce RGB on the wire; otherwise output YUV.
#define AUTOCIRCULATE_WITH_ANC
Use this to AutoCirculate with ancillary data.
Specifies channel or FrameStore 2 (or the 2nd item).
Definition: ntv2enums.h:1360
virtual NTV2DeviceID GetDeviceID(void)
virtual bool RouteHDMIOutput(void)
Sets up board routing output via the HDMI (if available).
#define NTV2_IS_4K_HFR_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:794
virtual ~NTV2Player4K(void)
Declares the CNTV2DeviceScanner class.
virtual bool AutoCirculateStop(const NTV2Channel inChannel, const bool inAbort=(0))
Stops AutoCirculate for the given channel, and releases the on-device frame buffers that were allocat...
bool AddAudioTone(ULWord &outNumBytesWritten, NTV2Buffer &inAudioBuffer, ULWord &inOutCurrentSample, const ULWord inNumSamples, const double inSampleRate, const double inAmplitude, const double inFrequency, const ULWord inNumBits, const bool inByteSwap, const ULWord inNumChannels)
Fills the given buffer with 32-bit (ULWord) audio tone samples.
Definition: ntv2utils.cpp:4413
Declares the AJAProcess class.
Describes a user-space buffer on the host computer. I have an address and a length, plus some optional attributes (allocated by SDK?, page-aligned? etc.).
#define PLFAIL(_xpr_)
virtual bool Connect(const NTV2InputCrosspointID inInputXpt, const NTV2OutputCrosspointID inOutputXpt, const bool inValidate=(0))
Connects the given widget signal input (sink) to the given widget signal output (source).
bool fDoMultiFormat
If true, enable device-sharing; otherwise take exclusive control of device.
static NTV2TestPatternNames getTestPatternNames(void)
bool IsRGBFormat(const NTV2FrameBufferFormat format)
Definition: ntv2utils.cpp:5410
This object specifies the information that will be transferred to or from the AJA device in the CNTV2...
virtual bool SetAudioBufferSize(const NTV2AudioBufferSize inValue, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Changes the size of the audio buffer that is used for a given Audio System in the AJA device...
Definition: ntv2audio.cpp:249
virtual bool RouteFsToDLOut(void)
Sets up board routing from the Frame Stores to the Dual Link out.
virtual bool GetNumberAudioChannels(ULWord &outNumChannels, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Returns the current number of audio channels being captured or played by a given Audio System on the ...
Definition: ntv2audio.cpp:180
#define AJA_FALL_THRU
Definition: ajatypes.h:187
#define DEC(__x__)
static ULWord gAncMaxSizeBytes(NTV2_ANCSIZE_MAX)
The maximum number of bytes of ancillary data that can be transferred for a single field...
bool fDoTsiRouting
If true, enable TSI routing; otherwise route for square division (4K/8K)
std::set< NTV2Channel > NTV2ChannelSet
A set of distinct NTV2Channel values.
void EndProduceNextBuffer(void)
The producer thread calls this function to signal that it has finished populating the frame it obtain...
This identifies the first Audio System.
Definition: ntv2enums.h:3897
virtual bool WaitForOutputVerticalInterrupt(const NTV2Channel inChannel=NTV2_CHANNEL1, UWord inRepeatCount=1)
Efficiently sleeps the calling thread/process until the next one or more field (interlaced video) or ...
virtual uint32_t AddTone(ULWord *audioBuffer)
Inserts audio tone (based on my current tone frequency) into the given audio buffer.
NTV2Channel fOutputChannel
The device channel to use.
static const size_t CIRCULAR_BUFFER_SIZE(10)
Number of NTV2FrameData&#39;s in our ring.
static const ULWord kDemoAppSignature((((uint32_t)( 'D'))<< 24)|(((uint32_t)( 'E'))<< 16)|(((uint32_t)( 'M'))<< 8)|(((uint32_t)( 'O'))<< 0))
ULWord numLines
Height – total number of lines.
I am an object that can play out a 4K or UHD test pattern (with timecode) to an output of an AJA devi...
Definition: ntv2player4k.h:24
virtual AJAStatus Attach(AJAThreadFunction *pThreadFunction, void *pUserContext)
Definition: thread.cpp:169
bool Set(const void *pInUserPointer, const size_t inByteCount)
Sets (or resets) me from a client-supplied address and size.
FrameDataPtr StartProduceNextBuffer(void)
The thread that&#39;s responsible for providing frames – the producer – calls this function to populate...
double GetAudioSamplesPerSecond(const NTV2AudioRate inAudioRate)
Returns the audio sample rate as a number of audio samples per second.
Definition: ntv2utils.cpp:3303
virtual bool SetSDIOutRGBLevelAConversion(const UWord inOutputSpigot, const bool inEnable)
Enables or disables an RGB-over-3G-level-A conversion at the SDI output widget (assuming the AJA devi...
Identifies the "normal" Field 2 ancillary data region.
Definition: ntv2enums.h:4230
This identifies the 4th Audio System.
Definition: ntv2enums.h:3900
mFormatDesc
Definition: ntv2vcam.cpp:942
virtual bool SetSDIOutLevelAtoLevelBConversion(const UWord inOutputSpigot, const bool inEnable)
Enables or disables 3G level A to 3G level B conversion at the SDI output widget (assuming the AJA de...
virtual bool SetHDMIOutAudioSource8Channel(const NTV2Audio8ChannelSelect inNewValue, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1, const NTV2Channel inWhichHDMIOut=NTV2_CHANNEL1)
Changes the HDMI output&#39;s 8-channel audio source.
Definition: ntv2audio.cpp:935
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
NTV2OutputXptID GetFrameStoreOutputXptFromChannel(const NTV2Channel inFrameStore, const bool inIsRGB=false, const bool inIs425=false)
virtual bool SetHDMIOutAudioFormat(const NTV2AudioFormat inNewValue, const NTV2Channel inWhichHDMIOut=NTV2_CHANNEL1)
Sets the HDMI output&#39;s audio format.
Definition: ntv2audio.cpp:1031
uint16_t UWord
Definition: ajatypes.h:221
ULWord GetAudioSamplesPerFrame(const NTV2FrameRate inFrameRate, const NTV2AudioRate inAudioRate, ULWord inCadenceFrame=0, bool inIsSMPTE372Enabled=false)
Returns the number of audio samples for a given video frame rate, audio sample rate, and frame number. This is useful since AJA devices use fixed audio sample rates (typically 48KHz), and some video frame rates will necessarily result in some frames having more audio samples than others.
Definition: ntv2utils.cpp:2889
Declares the AJAAncillaryData_HDR_SDR class.
virtual bool SetHDMIOutVideoFPS(const NTV2FrameRate inNewValue, const NTV2Channel inWhichHDMIOut=NTV2_CHANNEL1)
Sets the video frame rate to use for the given HDMI output.
Definition: ntv2hdmi.cpp:388
Specifies channel or FrameStore 1 (or the first item).
Definition: ntv2enums.h:1359
virtual bool RouteFsToTsiMux(void)
Sets up board routing from the Frame Stores to the Two Sample Interleave muxes.
virtual bool AutoCirculateStart(const NTV2Channel inChannel, const ULWord64 inStartTime=0)
Starts AutoCirculating the specified channel that was previously initialized by CNTV2Card::AutoCircul...
bool CanDoFrameBufferFormat(const NTV2PixelFormat inPF)
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
virtual bool AutoCirculateInitForOutput(const NTV2Channel inChannel, const UWord inFrameCount=7, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_INVALID, const ULWord inOptionFlags=0, const UByte inNumChannels=1, const UWord inStartFrameNumber=0, const UWord inEndFrameNumber=0)
Prepares for subsequent AutoCirculate playout, designating a contiguous block of frame buffers on the...
#define xHEX0N(__x__, __n__)
virtual AJAStatus Run(void)
Runs me.
bool CanDoWidget(const NTV2WidgetID inWgtID)
TimecodeFormat
Definition: ntv2rp188.h:22
virtual bool GetFrameRate(NTV2FrameRate &outValue, NTV2Channel inChannel=NTV2_CHANNEL1)
Returns the AJA device&#39;s currently configured frame rate via its "value" parameter.
static AJA_FrameRate GetAJAFrameRate(const NTV2FrameRate inFrameRate)
AJA_EXPORT bool BurnTimeCode(void *pBaseVideoAddress, const std::string &inTimeCodeStr, const uint32_t inYPercent)
I encapsulate the video, audio and anc host buffers used in the AutoCirculate demos. I&#39;m a more modern version of the AVDataBuffer.
NTV2AudioSystem NTV2ChannelToAudioSystem(const NTV2Channel inChannel)
Converts the given NTV2Channel value into its equivalent NTV2AudioSystem.
Definition: ntv2utils.cpp:4869
Specifies channel or FrameStore 4 (or the 4th item).
Definition: ntv2enums.h:1362
NTV2ChannelSet NTV2MakeChannelSet(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Specifies channel or FrameStore 5 (or the 5th item).
Definition: ntv2enums.h:1363
NTV2ACFrameRange fFrames
AutoCirculate frame count or range.
NTV2Standard GetNTV2StandardFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:2375
Configures an NTV2Player instance.
bool GetRP188Reg(RP188_STRUCT &outRP188) const
Definition: ntv2rp188.cpp:1241
NTV2AudioRate
Definition: ntv2enums.h:1928
NTV2StringList NTV2TestPatternNames
An ordered sequence of pattern names.
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO2
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 2. ...
virtual void ConsumeFrames(void)
My consumer thread that repeatedly plays frames using AutoCirculate (until quit). ...
static size_t SetDefaultPageSize(void)
#define PLWARN(_xpr_)
NTV2Buffer acAudioBuffer
The host audio buffer. This field is owned by the client application, and thus is responsible for all...
Specifies channel or FrameStore 6 (or the 6th item).
Definition: ntv2enums.h:1364
bool CanDoVideoFormat(const NTV2VideoFormat inVF)
UWord lastFrame(void) const
Definition: ntv2utils.h:986
I am the principal class that stores a single SMPTE-291 SDI ancillary data packet OR the digitized co...
virtual bool RouteCscTo2xSDIOut(void)
Sets up board routing from the Color Space Converters to the 2xSDI outputs.
bool valid(void) const
Definition: ntv2utils.h:988
#define AUTOCIRCULATE_WITH_RP188
Use this to AutoCirculate with RP188.
const char * NTV2FrameBufferFormatString(NTV2FrameBufferFormat fmt)
Definition: ntv2debug.cpp:214
Specifies channel or FrameStore 7 (or the 7th item).
Definition: ntv2enums.h:1365
bool GetRP188Str(std::string &sRP188) const
Definition: ntv2rp188.cpp:918
NTV2Buffer acANCBuffer
The host ancillary data buffer. This field is owned by the client application, and thus is responsibl...
virtual bool Route4KDownConverter(void)
Sets up board routing for the 4K DownConverter to SDI Monitor (if available).
NTV2InputXptID GetSDIOutputInputXpt(const NTV2Channel inSDIOutput, const bool inIsDS2=false)
virtual bool SetVANCMode(const NTV2VANCMode inVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Sets the VANC mode for the given FrameStore.
virtual bool SetSDIOut12GEnable(const NTV2Channel inChannel, const bool inEnable)
virtual bool RouteCscTo4xSDIOut(void)
Sets up board routing from the Color Space Converters to the 4xSDI outputs.
NTV2Player4K(const PlayerConfig &inConfig)
Constructs me using the given configuration settings.
virtual bool SetNumberAudioChannels(const ULWord inNumChannels, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the number of audio channels to be concurrently captured or played for a given Audio System on t...
Definition: ntv2audio.cpp:146
virtual bool RouteFsToCsc(void)
Sets up board routing from the Frame Stores to the Color Space Converters.
bool fDoHDMIOutput
If true, enable HDMI output; otherwise, disable HDMI output.
virtual AJAStatus SetUpVideo(void)
Performs all video setup.
#define NTV2_ANCSIZE_MAX
This identifies the mode in which there are no VANC lines in the frame buffer.
Definition: ntv2enums.h:3799
Specifies channel or FrameStore 3 (or the 3rd item).
Definition: ntv2enums.h:1361
virtual void SetupSDITransmitters(const NTV2Channel inFirstSDI, const UWord inNumSDIs)
Sets up bi-directional SDI transmitters.
#define NTV2_IS_4K_4096_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:833