AJA NTV2 SDK  18.1.0.2439
NTV2 SDK 18.1.0.2439
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  mSavedTaskMode (NTV2_TASK_MODE_INVALID),
60  mCurrentFrame (0),
61  mCurrentSample (0),
62  mToneFrequency (440.0),
63  mAudioSystem (NTV2_AUDIOSYSTEM_INVALID),
64  mFormatDesc (),
65  mGlobalQuit (false),
66  mTCBurner (),
67  mHostBuffers (),
68  mFrameDataRing (),
69  mTestPatRasters ()
70 {
71 }
72 
73 
75 {
76  // Stop my playout and producer threads, then destroy them...
77  Quit();
78 
79  mDevice.UnsubscribeOutputVerticalEvent(mConfig.fOutputChannel); // Unsubscribe from output VBI event
80 } // destructor
81 
82 
83 void NTV2Player4K::Quit (void)
84 {
85  // Set the global 'quit' flag, and wait for the threads to go inactive...
86  mGlobalQuit = true;
87 
88  while (mProducerThread.Active())
89  AJATime::Sleep(10);
90 
91  while (mConsumerThread.Active())
92  AJATime::Sleep(10);
93 
94 #if defined(NTV2_BUFFER_LOCKING)
95  mDevice.DMABufferUnlockAll();
96 #endif // NTV2_BUFFER_LOCKING
97  if (!mConfig.fDoMultiFormat && mDevice.IsOpen())
98  {
100  if (NTV2_IS_VALID_TASK_MODE(mSavedTaskMode))
101  mDevice.SetTaskMode(mSavedTaskMode); // Restore prior task mode
102  }
103 } // Quit
104 
105 
107 {
108  AJAStatus status (AJA_STATUS_SUCCESS);
109 
110  // Open the device...
112  { if (aja::lower(mConfig.fDeviceSpec) != "list" && mConfig.fDeviceSpec != "?")
113  cerr << "## ERROR: Device '" << mConfig.fDeviceSpec << "' not found" << endl;
114  return AJA_STATUS_OPEN;
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.GetDescription() << "' 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  << "Device Description: " << mDevice.GetDescription() << endl
195  << endl;
196  #endif // defined(_DEBUG)
197  return AJA_STATUS_SUCCESS;
198 
199 } // Init
200 
201 
203 {
204  // Configure the device to output the requested video format...
205  if (mConfig.fVideoFormat == NTV2_FORMAT_UNKNOWN)
206  return AJA_STATUS_BAD_PARAM;
207  if (!mDevice.features().CanDoVideoFormat(mConfig.fVideoFormat))
208  { cerr << "## ERROR: '" << mDevice.GetDescription() << "' doesn't support "
209  << ::NTV2VideoFormatToString(mConfig.fVideoFormat) << endl;
210  return AJA_STATUS_UNSUPPORTED;
211  }
212  if (!mDevice.features().CanDoFrameBufferFormat(mConfig.fPixelFormat))
213  { cerr << "## ERROR: '" << mDevice.GetDescription() << "' doesn't support "
214  << ::NTV2FrameBufferFormatString(mConfig.fPixelFormat) << endl;
215  return AJA_STATUS_UNSUPPORTED;
216  }
217 
218  NTV2ChannelSet channels1357, channels15, frameStores;
219  channels1357.insert(NTV2_CHANNEL1); channels1357.insert(NTV2_CHANNEL3); channels1357.insert(NTV2_CHANNEL5); channels1357.insert(NTV2_CHANNEL7);
220  channels15.insert(NTV2_CHANNEL1); channels15.insert(NTV2_CHANNEL5);
221  if (mDevice.features().CanDo12gRouting())
222  frameStores = ::NTV2MakeChannelSet (mConfig.fOutputChannel, 1); // 1 x 12G FrameStore (fOutputChannel)
223  else if (mConfig.fDoTsiRouting)
224  { // "Tsi" routing requires 2 FrameStores
225  if (channels1357.find(mConfig.fOutputChannel) == channels1357.end())
226  return AJA_STATUS_BAD_PARAM; // fOutputChannel not Ch1, Ch3, Ch5 or Ch7
227  frameStores = ::NTV2MakeChannelSet (mConfig.fOutputChannel, 2); // 2 x FrameStores starting at Ch1, Ch3, Ch5 or Ch7
228  }
229  else
230  { // "Squares" routing requires 4 FrameStores
231  if (channels15.find(mConfig.fOutputChannel) == channels15.end())
232  return AJA_STATUS_BAD_PARAM; // fOutputChannel not Ch1 or Ch5
233  frameStores = ::NTV2MakeChannelSet (mConfig.fOutputChannel, 4); // 4 x FrameStores starting at Ch1 or Ch5
234  }
235  // Disable SDI output conversions
236  mDevice.SetSDIOutLevelAtoLevelBConversion (frameStores, false);
237  mDevice.SetSDIOutRGBLevelAConversion (frameStores, false);
238 
239  // Keep the raster description handy...
240  mFormatDesc = NTV2FormatDescriptor(mConfig.fVideoFormat, mConfig.fPixelFormat);
241  if (!mFormatDesc.IsValid())
242  return AJA_STATUS_FAIL;
243 
244  // Turn on the FrameStores (to read frame buffer memory and transmit video)...
245  mDevice.EnableChannels (frameStores, /*disableOthers=*/!mConfig.fDoMultiFormat);
246 
247  // This demo requires VANC be disabled...
248  mDevice.SetVANCMode (frameStores, NTV2_VANCMODE_OFF); // VANC is incompatible with 4K/UHD formats
249  mDevice.SetVANCShiftMode(frameStores, NTV2_VANCDATA_NORMAL);
250 
251  // Set the FrameStore video format...
252  mDevice.SetVideoFormat (frameStores, mConfig.fVideoFormat, false);
253 
254  // Set the frame buffer pixel format for the device FrameStore(s)...
255  mDevice.SetFrameBufferFormat (frameStores, mConfig.fPixelFormat);
256 
257  // The output interrupt is Enabled by default, but on some platforms, you must subscribe to it
258  // in order to be able to wait on its event/semaphore...
260 
261  // Get current per-field maximum Anc buffer size...
264 
265  // Set output clock reference...
267 
268  // At this point, video setup is complete (except for widget signal routing).
269  return AJA_STATUS_SUCCESS;
270 
271 } // SetUpVideo
272 
273 
275 {
276  uint16_t numAudioChannels (mDevice.features().GetMaxAudioChannels());
277  if (numAudioChannels > 8) // If audio system handles more than 8 channels...
278  if (!mDevice.features().CanDo2110()) // ...and SDI (i.e. not ST 2110 IP streaming)...
279  if (NTV2_IS_4K_4096_VIDEO_FORMAT(mConfig.fVideoFormat)) // ...and 4K (narrower HANC only fits 8 audio channels)
280  numAudioChannels = 8; // ...then reduce to 8 audio channels
281 
282  // Use the NTV2AudioSystem that has the same ordinal value as the output FrameStore/Channel...
283  mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fOutputChannel);
284 
285  if (mConfig.fNumAudioLinks > 1) // For users that want to send 32 or 64 audio channels on 2 or 4 SDI links
286  switch (mAudioSystem)
287  {
288  default:
289  case NTV2_AUDIOSYSTEM_1:
290  { const UWord numChan(NTV2_IS_4K_HFR_VIDEO_FORMAT(mConfig.fVideoFormat) ? 4 : 2);
291  const NTV2AudioSystemSet audSystems (::NTV2MakeAudioSystemSet (mAudioSystem, numChan));
292  for (UWord chan(0); chan < numChan; chan++)
293  mDevice.SetSDIOutputAudioSystem (NTV2Channel(chan), NTV2AudioSystem(chan));
294  mDevice.SetNumberAudioChannels (numAudioChannels, audSystems);
295  mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, audSystems);
296  mDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, audSystems);
297  break;
298  }
299  case NTV2_AUDIOSYSTEM_3:
302  break;
303  }
304  else
305  {
306  NTV2ChannelSet sdiSpigots (::NTV2MakeChannelSet (mConfig.fOutputChannel, 1));
307  if (!mDevice.features().CanDo12gRouting())
308  sdiSpigots = ::NTV2MakeChannelSet (mAudioSystem == NTV2_AUDIOSYSTEM_1 || mAudioSystem == NTV2_AUDIOSYSTEM_3
309  ? NTV2_CHANNEL1
310  : NTV2_CHANNEL5, 4);
311  mDevice.SetSDIOutputAudioSystem (sdiSpigots, mAudioSystem);
312  mDevice.SetNumberAudioChannels (numAudioChannels, mAudioSystem);
313  mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mAudioSystem);
314  mDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, mAudioSystem);
315  }
316 
317  if (mConfig.fDoHDMIOutput)
318  {
322  }
323 
324  return AJA_STATUS_SUCCESS;
325 
326 } // SetUpAudio
327 
328 
330 {
331  CNTV2DemoCommon::SetDefaultPageSize(); // Set host-specific page size
332 
333  // Let my circular buffer know when it's time to quit...
334  mFrameDataRing.SetAbortFlag (&mGlobalQuit);
335 
336  // Multi-link audio uses stacked buffers for transferring to the board,
337  // the first byte after the end of the first audio link buffer is the start of the second audio link buffer.
338  const size_t audioBufferSize (gAudMaxSizeBytes * uint32_t(mConfig.fNumAudioLinks));
339 
340  // Allocate and add each in-host NTV2FrameData to my circular buffer member variable...
341  mHostBuffers.reserve(CIRCULAR_BUFFER_SIZE);
342  while (mHostBuffers.size() < CIRCULAR_BUFFER_SIZE)
343  {
344  mHostBuffers.push_back(NTV2FrameData()); // Make a new NTV2FrameData...
345  NTV2FrameData & frameData(mHostBuffers.back()); // ...and get a reference to it
346 
347  // Don't allocate a page-aligned video buffer here.
348  // Instead, the test pattern buffers are used (and re-used) in the consumer thread.
349  // This saves a LOT of memory and time spent copying data with these large 4K/UHD rasters.
350  // NOTE: This differs substantially from the NTV2Player demo, which pre-allocates the ring of video buffers
351  // here, then in its producer thread, copies a fresh, unmodified test pattern raster into the video
352  // buffer, blits timecode into it, then transfers it to the hardware in its consumer thread.
353 
354  // Allocate a page-aligned audio buffer (if transmitting audio)
355  if (mConfig.WithAudio())
356  if (!frameData.fAudioBuffer.Allocate (audioBufferSize, BUFFER_PAGE_ALIGNED))
357  {
358  PLFAIL("Failed to allocate " << xHEX0N(audioBufferSize,8) << "-byte audio buffer");
359  return AJA_STATUS_MEMORY;
360  }
361  if (frameData.fAudioBuffer)
362  {
363  frameData.fAudioBuffer.Fill(ULWord(0));
364  #ifdef NTV2_BUFFER_LOCKING
365  mDevice.DMABufferLock(frameData.fAudioBuffer, /*alsoPreLockSGL*/true);
366  #endif
367  }
368  mFrameDataRing.Add (&frameData);
369  } // for each NTV2FrameData
370 
371  return AJA_STATUS_SUCCESS;
372 
373 } // SetUpHostBuffers
374 
375 
377 {
378  vector<NTV2TestPatternSelect> testPatIDs;
379  testPatIDs.push_back(NTV2_TestPatt_ColorBars100);
380  testPatIDs.push_back(NTV2_TestPatt_ColorBars75);
381  testPatIDs.push_back(NTV2_TestPatt_Ramp);
382  testPatIDs.push_back(NTV2_TestPatt_MultiBurst);
383  testPatIDs.push_back(NTV2_TestPatt_LineSweep);
384  testPatIDs.push_back(NTV2_TestPatt_CheckField);
385  testPatIDs.push_back(NTV2_TestPatt_FlatField);
386  testPatIDs.push_back(NTV2_TestPatt_MultiPattern);
387  testPatIDs.push_back(NTV2_TestPatt_Black);
388  testPatIDs.push_back(NTV2_TestPatt_White);
389  testPatIDs.push_back(NTV2_TestPatt_Border);
390  testPatIDs.push_back(NTV2_TestPatt_LinearRamp);
391  testPatIDs.push_back(NTV2_TestPatt_SlantRamp);
392  testPatIDs.push_back(NTV2_TestPatt_ZonePlate);
393  testPatIDs.push_back(NTV2_TestPatt_ColorQuadrant);
394  testPatIDs.push_back(NTV2_TestPatt_ColorQuadrantBorder);
395 
396  mTestPatRasters.clear();
397  for (size_t tpNdx(0); tpNdx < testPatIDs.size(); tpNdx++)
398  mTestPatRasters.push_back(NTV2Buffer());
399 
400  if (!mFormatDesc.IsValid())
401  {PLFAIL("Bad format descriptor"); return AJA_STATUS_FAIL;}
402  if (mFormatDesc.IsVANC())
403  {PLFAIL("VANC incompatible with UHD/4K: " << mFormatDesc); return AJA_STATUS_FAIL;}
404 
405  // Set up one video buffer for each test pattern...
406  for (size_t tpNdx(0); tpNdx < testPatIDs.size(); tpNdx++)
407  {
408  // Allocate the buffer memory...
409  if (!mTestPatRasters.at(tpNdx).Allocate (mFormatDesc.GetVideoWriteSize(), BUFFER_PAGE_ALIGNED))
410  { PLFAIL("Test pattern buffer " << DEC(tpNdx+1) << " of " << DEC(testPatIDs.size()) << ": "
411  << xHEX0N(mFormatDesc.GetVideoWriteSize(),8) << "-byte page-aligned alloc failed");
412  return AJA_STATUS_MEMORY;
413  }
414 
415  // Fill the buffer with test pattern...
416  NTV2TestPatternGen testPatternGen;
417  if (!testPatternGen.DrawTestPattern (testPatIDs.at(tpNdx), mFormatDesc, mTestPatRasters.at(tpNdx)))
418  {
419  cerr << "## ERROR: DrawTestPattern " << DEC(tpNdx) << " failed: " << mFormatDesc << endl;
420  return AJA_STATUS_FAIL;
421  }
422 
423  #ifdef NTV2_BUFFER_LOCKING
424  // Try to prelock the memory, including its scatter-gather list...
425  if (!mDevice.DMABufferLock(mTestPatRasters.at(tpNdx), /*alsoLockSegmentMap=*/true))
426  PLWARN("Test pattern buffer " << DEC(tpNdx+1) << " of " << DEC(testPatIDs.size()) << ": failed to pre-lock");
427  #endif
428  } // loop for each predefined pattern
429 
430  return AJA_STATUS_SUCCESS;
431 
432 } // SetUpTestPatternBuffers
433 
434 
436 {
437  const bool isRGB (::IsRGBFormat(mConfig.fPixelFormat));
438  bool useLinkGrouping = false;
439  UWord failures(0); // tally of routing failures
440 
441  if (!mConfig.fDoMultiFormat)
442  mDevice.ClearRouting(); // Replace current signal routing
443 
444  // Construct switch value to avoid multiple if-then-else
445  int switchValue = 0;
447  switchValue += 8;
448  if (mConfig.fDoTsiRouting)
449  switchValue += 4;
450  if (isRGB)
451  switchValue += 2;
452  if (mConfig.fDoRGBOnWire)
453  switchValue += 1;
454  if (mDevice.features().CanDo12GSDI() && !mDevice.features().CanDo12gRouting())
455  {
456  mDevice.SetSDIOut6GEnable(NTV2_CHANNEL3, false);
457  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, false);
458  if (mConfig.fDoLinkGrouping)
459  useLinkGrouping = true;
460  }
461 
462  switch (switchValue)
463  {
464  case 0: // Low Frame Rate, Square, Pixel YCbCr, Wire YCbCr
465  if (!RouteFsToSDIOut()) failures++;
467  break;
468  case 1: // Low Frame Rate, Square, Pixel YCbCr, Wire RGB
469  if (!RouteFsToCsc()) failures++;
470  if (!RouteCscToDLOut()) failures++;
471  if (!RouteDLOutToSDIOut()) failures++;
473  break;
474  case 2: // Low Frame Rate, Square, Pixel RGB, Wire YCbCr
475  if (!RouteFsToCsc()) failures++;
476  if (!RouteCscTo4xSDIOut()) failures++;
478  break;
479  case 3: // Low Frame Rate, Square, Pixel RGB, Wire RGB
480  if (!RouteFsToDLOut()) failures++;
481  if (!RouteDLOutToSDIOut()) failures++;
483  break;
484  case 4: // Low Frame Rate, Tsi, Pixel YCbCr, Wire YCbCr
485  if (!RouteFsToTsiMux()) failures++;
486  if (!RouteTsiMuxTo2xSDIOut()) failures++;
487  if (useLinkGrouping)
488  {
489  mDevice.SetSDIOut6GEnable(NTV2_CHANNEL3, true);
491  }
492  else
494  break;
495  case 5: // Low Frame Rate, Tsi, Pixel YCbCr, Wire RGB
496  if (!RouteFsToTsiMux()) failures++;
497  if (!RouteTsiMuxToCsc()) failures++;
498  if (!RouteCscToDLOut()) failures++;
499  if (!RouteDLOutToSDIOut()) failures++;
500  if (useLinkGrouping)
501  {
502  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
504  }
505  else
507  break;
508  case 6: // Low Frame Rate, Tsi, Pixel RGB, Wire YCbCr
509  if (!RouteFsToTsiMux()) failures++;
510  if (!RouteTsiMuxToCsc()) failures++;
511  if (!RouteCscTo2xSDIOut()) failures++;
512  if (useLinkGrouping)
513  {
514  mDevice.SetSDIOut6GEnable(NTV2_CHANNEL3, true);
516  }
517  else
519  break;
520  case 7: // Low Frame Rate, Tsi, Pixel RGB, Wire RGB
521  if (!RouteFsToTsiMux()) failures++;
522  if (!RouteTsiMuxToDLOut()) failures++;
523  if (!RouteDLOutToSDIOut()) failures++;
524  if (useLinkGrouping)
525  {
526  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
528  }
529  else
531  break;
532  case 8: // High Frame Rate, Square, Pixel YCbCr, Wire YCbCr
533  if (!RouteFsToSDIOut()) failures++;
535  break;
536  case 9: // High Frame Rate, Square, Pixel YCbCr, Wire RGB
537  // No valid routing for this case
538  break;
539  case 10: // High Frame Rate, Square, Pixel RGB, Wire YCbCr
540  if (!RouteFsToCsc()) failures++;
541  if (!RouteCscTo4xSDIOut()) failures++;
543  break;
544  case 11: // High Frame Rate, Square, Pixel RGB, Wire RGB
545  // No valid routing for this case
546  break;
547  case 12: // High Frame Rate, Tsi, Pixel YCbCr, Wire YCbCr
548  if (!RouteFsToTsiMux()) failures++;
549  if (!RouteTsiMuxTo4xSDIOut()) failures++;
550  if (useLinkGrouping)
551  {
552  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
554  }
555  else
557  break;
558  case 13: // High Frame Rate, Tsi, Pixel YCbCr, Wire RGB
559  // No valid routing for this case
560  break;
561  case 14: // High Frame Rate, Tsi, Pixel RGB, Wire YCbCr
562  if (!RouteFsToTsiMux()) failures++;
563  if (!RouteTsiMuxToCsc()) failures++;
564  if (!RouteCscTo4xSDIOut()) failures++;
565  if(useLinkGrouping)
566  {
567  mDevice.SetSDIOut12GEnable(NTV2_CHANNEL3, true);
569  }
570  else
572  break;
573  case 15: // High Frame Rate, Tsi, Pixel RGB, Wire RGB
574  // No valid routing for this case
575  break;
576  default:
577  return false; // Fail
578  }
579 
580  if (mDevice.features().CanDo12gRouting())
581  mDevice.SetTsiFrameEnable (true, mConfig.fOutputChannel);
582  else if (mConfig.fDoTsiRouting)
583  mDevice.SetTsiFrameEnable (true, mConfig.fOutputChannel);
584  else
585  mDevice.Set4kSquaresEnable (true, mConfig.fOutputChannel);
586 
587  // Send signal to secondary outputs, if supported
588  if (!Route4KDownConverter()) failures++;
589  if (!RouteHDMIOutput()) failures++;
590  return failures == 0;
591 
592 } // RouteOutputSignal
593 
594 
595 void NTV2Player4K::SetupSDITransmitters (const NTV2Channel inFirstSDI, const UWord inNumSDIs)
596 {
597  if (mDevice.features().HasBiDirectionalSDI())
598  mDevice.SetSDITransmitEnable(::NTV2MakeChannelSet (inFirstSDI, mDevice.features().CanDo12gRouting() ? 1 : inNumSDIs),
599  /*transmit=*/true);
600 }
601 
602 
604 {
606  return true;
607 
608  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
609  UWord connectFailures (0);
610  if (::IsRGBFormat(mConfig.fPixelFormat))
611  {
612  mDevice.Enable4KDCRGBMode(true);
613 
614  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
615  {
616  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
617  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
618  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
619  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
620 
621  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
622  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
623  }
624  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
625  {
626  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
627  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
628  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
629  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
630 
631  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
632  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
633  }
634  }
635  else // YUV FBF
636  {
637  mDevice.Enable4KDCRGBMode (false);
638 
639  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
640  {
641  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
642  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
643  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
644  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
645 
646  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
647  }
648  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
649  {
650  if (!mDevice.Connect (NTV2_Xpt4KDCQ1Input, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
651  if (!mDevice.Connect (NTV2_Xpt4KDCQ2Input, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
652  if (!mDevice.Connect (NTV2_Xpt4KDCQ3Input, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
653  if (!mDevice.Connect (NTV2_Xpt4KDCQ4Input, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
654 
655  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt4KDownConverterOut, canVerify)) connectFailures++;
656  }
657  }
658  return connectFailures == 0;
659 
660 } // Route4KDownConverter
661 
662 
664 {
665  const bool isRGB (::IsRGBFormat(mConfig.fPixelFormat));
666  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
667  UWord connectFailures (0);
668 
669  if (mConfig.fDoHDMIOutput &&
673  || mDevice.features().CanDoWidget(NTV2_WgtHDMIOut1v5)) )
674  {
675  if (mDevice.features().CanDo12gRouting())
676  {
677  if (!mDevice.Connect (NTV2_XptHDMIOutInput, ::GetFrameStoreOutputXptFromChannel (mConfig.fOutputChannel, isRGB, false/*is425*/), canVerify))
678  connectFailures++;
679  }
680  else if(mConfig.fDoTsiRouting)
681  {
682  if (isRGB)
683  {
684  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
685  {
686  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
687  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
688  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
689  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
690  }
691  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
692  {
693  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
694  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
695  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
696  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
697  }
698  }
699  else
700  {
701  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
702  {
703  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
704  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
705  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
706  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
707  }
708  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
709  {
710  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
711  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
712  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
713  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
714  }
715  }
716  }
717  else
718  {
719  if (isRGB)
720  {
721  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
722  {
723  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
724  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
725 
726  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
727  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
728 
729  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
730  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
731 
732  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
733  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
734  }
735  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
736  {
737  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
738  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
739 
740  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
741  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
742 
743  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
744  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
745 
746  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
747  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
748  }
749  }
750  else
751  {
752  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
753  {
754  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
755  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
756  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
757  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
758  }
759  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
760  {
761  if (!mDevice.Connect (NTV2_XptHDMIOutInput, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
762  if (!mDevice.Connect (NTV2_XptHDMIOutQ2Input, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
763  if (!mDevice.Connect (NTV2_XptHDMIOutQ3Input, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
764  if (!mDevice.Connect (NTV2_XptHDMIOutQ4Input, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
765  }
766  }
767  }
768 
769  mDevice.SetHDMIV2TxBypass (false);
777  }
778  else
780  return connectFailures == 0;
781 
782 } // RouteHDMIOutput
783 
784 
786 {
787  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
788  UWord connectFailures (0);
789  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
790  {
791  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
792  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
793  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
794  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
795  }
796  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
797  {
798  if (!mDevice.Connect (NTV2_XptDualLinkOut5Input, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
799  if (!mDevice.Connect (NTV2_XptDualLinkOut6Input, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
800  if (!mDevice.Connect (NTV2_XptDualLinkOut7Input, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
801  if (!mDevice.Connect (NTV2_XptDualLinkOut8Input, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
802  }
803  return connectFailures == 0;
804 } // RouteFsToDLOut
805 
806 
808 {
809  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
810  UWord connectFailures (0);
811  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
812  {
813  if (::IsRGBFormat(mConfig.fPixelFormat))
814  {
815  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
816  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
817  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
818  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
819  }
820  else
821  {
822  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
823  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
824  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
825  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
826  }
827  }
828  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
829  {
830  if (::IsRGBFormat(mConfig.fPixelFormat))
831  {
832  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
833  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
834  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_XptFrameBuffer7RGB, canVerify)) connectFailures++;
835  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_XptFrameBuffer8RGB, canVerify)) connectFailures++;
836  }
837  else
838  {
839  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
840  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
841  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
842  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
843  }
844  }
845  return connectFailures == 0;
846 } // RouteFsToCsc
847 
848 
850 {
851  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
852  UWord connectFailures (0);
853  if (mDevice.features().CanDo12gRouting())
854  {
855  if (!mDevice.Connect ( ::GetSDIOutputInputXpt (mConfig.fOutputChannel, false/*isDS2*/),
856  ::GetFrameStoreOutputXptFromChannel (mConfig.fOutputChannel, false/*isRGB*/, false/*is425*/),
857  canVerify))
858  connectFailures++;
859  }
860  else
861  {
862  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
863  {
864  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
865  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
866  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
867  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
868  }
869  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
870  {
871  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
872  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
873  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_XptFrameBuffer7YUV, canVerify)) connectFailures++;
874  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_XptFrameBuffer8YUV, canVerify)) connectFailures++;
875  }
876  }
877  return connectFailures == 0;
878 } // RouteFsToSDIOut
879 
880 
882 {
883  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
884  UWord connectFailures (0);
885  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
886  {
887  if (::IsRGBFormat(mConfig.fPixelFormat))
888  {
889  if (!mDevice.Connect (NTV2_Xpt425Mux1AInput, NTV2_XptFrameBuffer1RGB, canVerify)) connectFailures++;
890  if (!mDevice.Connect (NTV2_Xpt425Mux1BInput, NTV2_XptFrameBuffer1_DS2RGB, canVerify)) connectFailures++;
891  if (!mDevice.Connect (NTV2_Xpt425Mux2AInput, NTV2_XptFrameBuffer2RGB, canVerify)) connectFailures++;
892  if (!mDevice.Connect (NTV2_Xpt425Mux2BInput, NTV2_XptFrameBuffer2_DS2RGB, canVerify)) connectFailures++;
893  }
894  else
895  {
896  if (!mDevice.Connect (NTV2_Xpt425Mux1AInput, NTV2_XptFrameBuffer1YUV, canVerify)) connectFailures++;
897  if (!mDevice.Connect (NTV2_Xpt425Mux1BInput, NTV2_XptFrameBuffer1_DS2YUV, canVerify)) connectFailures++;
898  if (!mDevice.Connect (NTV2_Xpt425Mux2AInput, NTV2_XptFrameBuffer2YUV, canVerify)) connectFailures++;
899  if (!mDevice.Connect (NTV2_Xpt425Mux2BInput, NTV2_XptFrameBuffer2_DS2YUV, canVerify)) connectFailures++;
900  }
901  }
902  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
903  {
904  if (::IsRGBFormat(mConfig.fPixelFormat))
905  {
906  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer3RGB, canVerify)) connectFailures++;
907  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer3_DS2RGB, canVerify)) connectFailures++;
908  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer4RGB, canVerify)) connectFailures++;
909  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer4_DS2RGB, canVerify)) connectFailures++;
910  }
911  else
912  {
913  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer3YUV, canVerify)) connectFailures++;
914  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer3_DS2YUV, canVerify)) connectFailures++;
915  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer4YUV, canVerify)) connectFailures++;
916  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer4_DS2YUV, canVerify)) connectFailures++;
917  }
918  }
919  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
920  {
921  if (::IsRGBFormat(mConfig.fPixelFormat))
922  {
923  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer5RGB, canVerify)) connectFailures++;
924  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer5_DS2RGB, canVerify)) connectFailures++;
925  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer6RGB, canVerify)) connectFailures++;
926  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer6_DS2RGB, canVerify)) connectFailures++;
927  }
928  else
929  {
930  if (!mDevice.Connect (NTV2_Xpt425Mux3AInput, NTV2_XptFrameBuffer5YUV, canVerify)) connectFailures++;
931  if (!mDevice.Connect (NTV2_Xpt425Mux3BInput, NTV2_XptFrameBuffer5_DS2YUV, canVerify)) connectFailures++;
932  if (!mDevice.Connect (NTV2_Xpt425Mux4AInput, NTV2_XptFrameBuffer6YUV, canVerify)) connectFailures++;
933  if (!mDevice.Connect (NTV2_Xpt425Mux4BInput, NTV2_XptFrameBuffer6_DS2YUV, canVerify)) connectFailures++;
934  }
935  }
936  return connectFailures == 0;
937 } // RouteFsToTsiMux
938 
939 
941 {
942  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
943  UWord connectFailures (0);
944  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
945  {
946  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptDuallinkOut1, canVerify)) connectFailures++;
947  if (!mDevice.Connect (NTV2_XptSDIOut1InputDS2, NTV2_XptDuallinkOut1DS2, canVerify)) connectFailures++;
948  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptDuallinkOut2, canVerify)) connectFailures++;
949  if (!mDevice.Connect (NTV2_XptSDIOut2InputDS2, NTV2_XptDuallinkOut2DS2, canVerify)) connectFailures++;
950  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_XptDuallinkOut3, canVerify)) connectFailures++;
951  if (!mDevice.Connect (NTV2_XptSDIOut3InputDS2, NTV2_XptDuallinkOut3DS2, canVerify)) connectFailures++;
952  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_XptDuallinkOut4, canVerify)) connectFailures++;
953  if (!mDevice.Connect (NTV2_XptSDIOut4InputDS2, NTV2_XptDuallinkOut4DS2, canVerify)) connectFailures++;
954  }
955  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
956  {
957  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptDuallinkOut5, canVerify)) connectFailures++;
958  if (!mDevice.Connect (NTV2_XptSDIOut5InputDS2, NTV2_XptDuallinkOut5DS2, canVerify)) connectFailures++;
959  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptDuallinkOut6, canVerify)) connectFailures++;
960  if (!mDevice.Connect (NTV2_XptSDIOut6InputDS2, NTV2_XptDuallinkOut6DS2, canVerify)) connectFailures++;
961  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_XptDuallinkOut7, canVerify)) connectFailures++;
962  if (!mDevice.Connect (NTV2_XptSDIOut7InputDS2, NTV2_XptDuallinkOut7DS2, canVerify)) connectFailures++;
963  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_XptDuallinkOut8, canVerify)) connectFailures++;
964  if (!mDevice.Connect (NTV2_XptSDIOut8InputDS2, NTV2_XptDuallinkOut8DS2, canVerify)) connectFailures++;
965  }
966  return connectFailures == 0;
967 } // RouteDLOutToSDIOut
968 
969 
971 {
972  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
973  UWord connectFailures (0);
974  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
975  {
976  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
977  if (!mDevice.Connect (NTV2_XptSDIOut1InputDS2, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
978  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
979  if (!mDevice.Connect (NTV2_XptSDIOut2InputDS2, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
980  }
981  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
982  {
983  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
984  if (!mDevice.Connect (NTV2_XptSDIOut5InputDS2, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
985  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
986  if (!mDevice.Connect (NTV2_XptSDIOut6InputDS2, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
987  }
988  return connectFailures == 0;
989 } // RouteCscTo2xSDIOut
990 
991 
993 {
994  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
995  UWord connectFailures (0);
996  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
997  {
998  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_XptCSC1VidYUV, canVerify)) connectFailures++;
999  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_XptCSC2VidYUV, canVerify)) connectFailures++;
1000  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_XptCSC3VidYUV, canVerify)) connectFailures++;
1001  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_XptCSC4VidYUV, canVerify)) connectFailures++;
1002  }
1003  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1004  {
1005  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_XptCSC5VidYUV, canVerify)) connectFailures++;
1006  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_XptCSC6VidYUV, canVerify)) connectFailures++;
1007  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_XptCSC7VidYUV, canVerify)) connectFailures++;
1008  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_XptCSC8VidYUV, canVerify)) connectFailures++;
1009  }
1010  return connectFailures == 0;
1011 } // RouteCscTo4xSDIOut
1012 
1013 
1015 {
1016  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1017  UWord connectFailures (0);
1018  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1019  {
1020  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_XptCSC1VidRGB, canVerify)) connectFailures++;
1021  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_XptCSC2VidRGB, canVerify)) connectFailures++;
1022  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_XptCSC3VidRGB, canVerify)) connectFailures++;
1023  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_XptCSC4VidRGB, canVerify)) connectFailures++;
1024  }
1025  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1026  {
1027  if (!mDevice.Connect (NTV2_XptDualLinkOut5Input, NTV2_XptCSC5VidRGB, canVerify)) connectFailures++;
1028  if (!mDevice.Connect (NTV2_XptDualLinkOut6Input, NTV2_XptCSC6VidRGB, canVerify)) connectFailures++;
1029  if (!mDevice.Connect (NTV2_XptDualLinkOut7Input, NTV2_XptCSC7VidRGB, canVerify)) connectFailures++;
1030  if (!mDevice.Connect (NTV2_XptDualLinkOut8Input, NTV2_XptCSC8VidRGB, canVerify)) connectFailures++;
1031  }
1032  return connectFailures == 0;
1033 } // RouteCscToDLOut
1034 
1035 
1037 {
1038  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1039  UWord connectFailures (0);
1040  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1041  {
1042  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_Xpt425Mux1ARGB, canVerify)) connectFailures++;
1043  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_Xpt425Mux1BRGB, canVerify)) connectFailures++;
1044  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_Xpt425Mux2ARGB, canVerify)) connectFailures++;
1045  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_Xpt425Mux2BRGB, canVerify)) connectFailures++;
1046  }
1047  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1048  {
1049  if (!mDevice.Connect (NTV2_XptDualLinkOut1Input, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1050  if (!mDevice.Connect (NTV2_XptDualLinkOut2Input, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1051  if (!mDevice.Connect (NTV2_XptDualLinkOut3Input, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1052  if (!mDevice.Connect (NTV2_XptDualLinkOut4Input, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1053  }
1054  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1055  {
1056  if (!mDevice.Connect (NTV2_XptDualLinkOut5Input, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1057  if (!mDevice.Connect (NTV2_XptDualLinkOut6Input, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1058  if (!mDevice.Connect (NTV2_XptDualLinkOut7Input, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1059  if (!mDevice.Connect (NTV2_XptDualLinkOut8Input, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1060  }
1061  return connectFailures == 0;
1062 } // RouteTsiMuxToDLOut
1063 
1064 
1066 {
1067  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1068  UWord connectFailures (0);
1069  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1070  {
1071  if (::IsRGBFormat(mConfig.fPixelFormat))
1072  {
1073  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux1ARGB, canVerify)) connectFailures++;
1074  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux1BRGB, canVerify)) connectFailures++;
1075  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux2ARGB, canVerify)) connectFailures++;
1076  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux2BRGB, canVerify)) connectFailures++;
1077  }
1078  else
1079  {
1080  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
1081  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
1082  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
1083  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
1084  }
1085  }
1086  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1087  {
1088  if (::IsRGBFormat(mConfig.fPixelFormat))
1089  {
1090  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1091  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1092  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1093  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1094  }
1095  else
1096  {
1097  if (!mDevice.Connect (NTV2_XptCSC1VidInput, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1098  if (!mDevice.Connect (NTV2_XptCSC2VidInput, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1099  if (!mDevice.Connect (NTV2_XptCSC3VidInput, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1100  if (!mDevice.Connect (NTV2_XptCSC4VidInput, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1101  }
1102  }
1103  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1104  {
1105  if (::IsRGBFormat(mConfig.fPixelFormat))
1106  {
1107  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt425Mux3ARGB, canVerify)) connectFailures++;
1108  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_Xpt425Mux3BRGB, canVerify)) connectFailures++;
1109  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_Xpt425Mux4ARGB, canVerify)) connectFailures++;
1110  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_Xpt425Mux4BRGB, canVerify)) connectFailures++;
1111  }
1112  else
1113  {
1114  if (!mDevice.Connect (NTV2_XptCSC5VidInput, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1115  if (!mDevice.Connect (NTV2_XptCSC6VidInput, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1116  if (!mDevice.Connect (NTV2_XptCSC7VidInput, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1117  if (!mDevice.Connect (NTV2_XptCSC8VidInput, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1118  }
1119  }
1120  return connectFailures == 0;
1121 } // RouteTsiMuxToCsc
1122 
1123 
1125 {
1126  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1127  UWord connectFailures (0);
1128  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1129  {
1130  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
1131  if (!mDevice.Connect (NTV2_XptSDIOut1InputDS2, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
1132  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
1133  if (!mDevice.Connect (NTV2_XptSDIOut2InputDS2, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
1134  }
1135  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1136  {
1137  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1138  if (!mDevice.Connect (NTV2_XptSDIOut3InputDS2, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1139  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1140  if (!mDevice.Connect (NTV2_XptSDIOut4InputDS2, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1141  }
1142  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1143  {
1144  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1145  if (!mDevice.Connect (NTV2_XptSDIOut5InputDS2, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1146  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1147  if (!mDevice.Connect (NTV2_XptSDIOut6InputDS2, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1148  }
1149  return connectFailures == 0;
1150 } // RouteTsiMuxTo2xSDIOut
1151 
1152 
1154 {
1155  const bool canVerify (mDevice.features().HasCrosspointConnectROM());
1156  UWord connectFailures (0);
1157  if (mConfig.fOutputChannel == NTV2_CHANNEL1)
1158  {
1159  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_Xpt425Mux1AYUV, canVerify)) connectFailures++;
1160  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_Xpt425Mux1BYUV, canVerify)) connectFailures++;
1161  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_Xpt425Mux2AYUV, canVerify)) connectFailures++;
1162  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_Xpt425Mux2BYUV, canVerify)) connectFailures++;
1163  }
1164  else if (mConfig.fOutputChannel == NTV2_CHANNEL3)
1165  { // Io4k+ 12G output
1166  if (!mDevice.Connect (NTV2_XptSDIOut1Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1167  if (!mDevice.Connect (NTV2_XptSDIOut2Input, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1168  if (!mDevice.Connect (NTV2_XptSDIOut3Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1169  if (!mDevice.Connect (NTV2_XptSDIOut4Input, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1170  }
1171  else if (mConfig.fOutputChannel == NTV2_CHANNEL5)
1172  {
1173  if (!mDevice.Connect (NTV2_XptSDIOut5Input, NTV2_Xpt425Mux3AYUV, canVerify)) connectFailures++;
1174  if (!mDevice.Connect (NTV2_XptSDIOut6Input, NTV2_Xpt425Mux3BYUV, canVerify)) connectFailures++;
1175  if (!mDevice.Connect (NTV2_XptSDIOut7Input, NTV2_Xpt425Mux4AYUV, canVerify)) connectFailures++;
1176  if (!mDevice.Connect (NTV2_XptSDIOut8Input, NTV2_Xpt425Mux4BYUV, canVerify)) connectFailures++;
1177  }
1178  return connectFailures == 0;
1179 } // RouteTsiMuxTo4xSDIOut
1180 
1181 
1183 {
1184  // Start my consumer and producer threads...
1187  return AJA_STATUS_SUCCESS;
1188 
1189 } // Run
1190 
1191 
1192 
1194 // This is where the play thread starts
1195 
1197 {
1198  // Create and start the playout thread...
1199  mConsumerThread.Attach (ConsumerThreadStatic, this);
1200  mConsumerThread.SetPriority(AJA_ThreadPriority_High);
1201  mConsumerThread.Start();
1202 
1203 } // StartConsumerThread
1204 
1205 
1206 // The playout thread function
1207 void NTV2Player4K::ConsumerThreadStatic (AJAThread * pThread, void * pContext) // static
1208 { (void) pThread;
1209  // Grab the NTV2Player4K instance pointer from the pContext parameter,
1210  // then call its PlayFrames method...
1211  NTV2Player4K * pApp (reinterpret_cast<NTV2Player4K*>(pContext));
1212  if (pApp)
1213  pApp->ConsumeFrames();
1214 
1215 } // ConsumerThreadStatic
1216 
1217 
1219 {
1220  ULWord acOptions (AUTOCIRCULATE_WITH_RP188);
1221  AUTOCIRCULATE_TRANSFER outputXfer;
1222  AUTOCIRCULATE_STATUS outputStatus;
1223  AJAAncillaryData * pPkt (AJA_NULL);
1224  ULWord goodXfers(0), badXfers(0), prodWaits(0), noRoomWaits(0), startFrm(3);
1225  const UWord numACFramesPerChannel(7);
1226 
1227  // Stop AutoCirculate, just in case someone else left it running...
1228  mDevice.AutoCirculateStop(mConfig.fOutputChannel);
1229  mDevice.WaitForOutputVerticalInterrupt(mConfig.fOutputChannel, 4); // Let it stop
1230  PLNOTE("Thread started");
1231 
1232  if (pPkt)
1233  { // Allocate page-aligned host Anc buffer...
1234  uint32_t hdrPktSize (0);
1235  if (!outputXfer.acANCBuffer.Allocate(gAncMaxSizeBytes, BUFFER_PAGE_ALIGNED) || !outputXfer.acANCBuffer.Fill(0LL))
1236  PLWARN("Anc buffer " << xHEX0N(gAncMaxSizeBytes,8) << "(" << DEC(gAncMaxSizeBytes) << ")-byte allocate failed -- HDR anc insertion disabled");
1237  else if (AJA_FAILURE(pPkt->GenerateTransmitData (outputXfer.acANCBuffer, outputXfer.acANCBuffer, hdrPktSize)))
1238  {
1239  PLWARN("HDR anc insertion disabled -- GenerateTransmitData failed");
1240  outputXfer.acANCBuffer.Deallocate();
1241  }
1242  else
1243  acOptions |= AUTOCIRCULATE_WITH_ANC;
1244  }
1245 #ifdef NTV2_BUFFER_LOCKING
1246  if (outputXfer.acANCBuffer)
1247  mDevice.DMABufferLock(outputXfer.acANCBuffer, /*alsoLockSGL*/true);
1248 #endif
1249 
1250  // Calculate start & end frame numbers (if mConfig.fFrames not used)...
1251  UWord startNum(0), endNum(0);
1252  if (mDevice.features().CanDo12gRouting())
1253  startNum = numACFramesPerChannel * mConfig.fOutputChannel;
1254  else switch (mConfig.fOutputChannel)
1255  { default:
1256  case NTV2_CHANNEL1: if (mConfig.fNumAudioLinks > 1)
1257  {
1260  {
1263  }
1264  }
1265  AJA_FALL_THRU;
1266  case NTV2_CHANNEL2: startNum = numACFramesPerChannel * 0; break;
1267 
1268  case NTV2_CHANNEL3: if (mConfig.fNumAudioLinks > 1)
1270  AJA_FALL_THRU;
1271  case NTV2_CHANNEL4: startNum = numACFramesPerChannel * 1; break;
1272 
1274  case NTV2_CHANNEL6: startNum = numACFramesPerChannel * 2; break;
1275 
1277  case NTV2_CHANNEL8: startNum = numACFramesPerChannel * 3; break;
1278  }
1279  endNum = startNum + numACFramesPerChannel - 1;
1280 
1281  // Initialize & start AutoCirculate...
1282  bool initOK(false);
1283  if (mConfig.fFrames.valid()) // --frames option controls everything:
1284  initOK = mDevice.AutoCirculateInitForOutput (mConfig.fOutputChannel, mConfig.fFrames.count(), mAudioSystem, acOptions,
1285  1 /*numChannels*/, mConfig.fFrames.firstFrame(), mConfig.fFrames.lastFrame());
1286  else // --frames option not used -- explicitly specify start & end frame numbers (as calculated above)
1287  initOK = mDevice.AutoCirculateInitForOutput (mConfig.fOutputChannel, 0, mAudioSystem, acOptions,
1288  1 /*numChannels*/, startNum, endNum);
1289  if (!initOK)
1290  {PLFAIL("AutoCirculateInitForOutput failed"); mGlobalQuit = true;}
1291  else
1292  { mDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outputStatus);
1293  startFrm = outputStatus.GetFrameCount() - 1;
1294  if (startFrm > 3)
1295  startFrm = 3;
1296  }
1297 
1298  while (!mGlobalQuit)
1299  {
1300  mDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outputStatus);
1301 
1302  // Check if there's room for another frame on the card...
1303  if (outputStatus.CanAcceptMoreOutputFrames())
1304  {
1305  // Device has at least one free frame buffer that can be filled.
1306  // Wait for the next frame in our ring to become ready to "consume"...
1307  NTV2FrameData * pFrameData (mFrameDataRing.StartConsumeNextBuffer());
1308  if (!pFrameData)
1309  {prodWaits++; continue;}
1310 
1311  // Unlike in the NTV2Player demo, I now burn the current timecode into the test pattern buffer that was noted
1312  // earlier into this FrameData in my Producer thread. This is done to avoid copying large 4K/UHD rasters.
1313  const NTV2FrameRate ntv2FrameRate (::GetNTV2FrameRateFromVideoFormat(mConfig.fVideoFormat));
1314  const TimecodeFormat tcFormat (CNTV2DemoCommon::NTV2FrameRate2TimecodeFormat(ntv2FrameRate));
1315  const CRP188 rp188Info (mCurrentFrame++, 0, 0, 10, tcFormat);
1316  NTV2_RP188 tcData;
1317  string timeCodeString;
1318 
1319  rp188Info.GetRP188Reg (tcData);
1320  rp188Info.GetRP188Str (timeCodeString);
1321  mTCBurner.BurnTimeCode (pFrameData->fVideoBuffer, timeCodeString.c_str(), 80);
1322 
1323  // Transfer the timecode-burned frame (plus audio) to the device for playout...
1324  outputXfer.acVideoBuffer.Set (pFrameData->fVideoBuffer, pFrameData->fVideoBuffer);
1325  outputXfer.acAudioBuffer.Set (pFrameData->fAudioBuffer, pFrameData->fNumAudioBytes);
1326  outputXfer.SetOutputTimeCode (tcData, ::NTV2ChannelToTimecodeIndex(mConfig.fOutputChannel, /*LTC=*/false, /*F2=*/false));
1327  outputXfer.SetOutputTimeCode (tcData, ::NTV2ChannelToTimecodeIndex(mConfig.fOutputChannel, /*LTC=*/true, /*F2=*/false));
1328 
1329  // Perform the DMA transfer to the device...
1330  if (mDevice.AutoCirculateTransfer (mConfig.fOutputChannel, outputXfer))
1331  { if (++goodXfers == startFrm)
1332  mDevice.AutoCirculateStart(mConfig.fOutputChannel);
1333  }
1334  else
1335  badXfers++;
1336 
1337  // Signal that the frame has been "consumed"...
1338  mFrameDataRing.EndConsumeNextBuffer();
1339  continue; // Back to top of while loop
1340  }
1341 
1342  // Wait for one or more buffers to become available on the device, which should occur at next VBI...
1343  noRoomWaits++;
1345  } // loop til quit signaled
1346 
1347  // Stop AutoCirculate...
1348  mDevice.AutoCirculateStop(mConfig.fOutputChannel);
1349  PLNOTE("Thread completed: " << DEC(goodXfers) << " xfers, " << DEC(badXfers) << " failed, "
1350  << DEC(prodWaits) << " starves, " << DEC(noRoomWaits) << " VBI waits");
1351 
1352 } // ConsumeFrames
1353 
1354 
1355 
1357 // This is where the producer thread starts
1358 
1360 {
1361  // Create and start the producer thread...
1362  mProducerThread.Attach(ProducerThreadStatic, this);
1363  mProducerThread.SetPriority(AJA_ThreadPriority_High);
1364  mProducerThread.Start();
1365 
1366 } // StartProducerThread
1367 
1368 
1369 void NTV2Player4K::ProducerThreadStatic (AJAThread * pThread, void * pContext) // static
1370 {
1371  (void) pThread;
1372  NTV2Player4K * pApp (reinterpret_cast<NTV2Player4K*>(pContext));
1373  if (pApp)
1374  pApp->ProduceFrames();
1375 
1376 } // ProducerThreadStatic
1377 
1378 
1380 {
1381  ULWord freqNdx(0), testPatNdx(0), badTally(0);
1382  double timeOfLastSwitch (0.0);
1383 
1386 
1387  PLNOTE("Thread started");
1388  while (!mGlobalQuit)
1389  {
1390  NTV2FrameData * pFrameData (mFrameDataRing.StartProduceNextBuffer());
1391  if (!pFrameData)
1392  { badTally++; // No frame available!
1393  AJATime::Sleep(10); // Wait a bit for the consumer thread to free one up for me...
1394  continue; // ...then try again
1395  }
1396 
1397  // Unlike NTV2Player::ProduceFrames, NTV2Player4K::ProduceFrames doesn't touch this frame's video buffer.
1398  // Instead, to avoid wasting time copying large 4K/UHD rasters, in this thread we simply note which test
1399  // pattern buffer is to be modified and subsequently transferred to the hardware. This happens later, in
1400  // NTV2Player4K::ConsumeFrames...
1401  NTV2Buffer & testPatVidBuffer(mTestPatRasters.at(testPatNdx));
1402  pFrameData->fVideoBuffer.Set(testPatVidBuffer.GetHostPointer(), testPatVidBuffer.GetByteCount());
1403 
1404  // If also playing audio...
1405  if (pFrameData->AudioBuffer()) // ...then generate audio tone data for this frame...
1406  pFrameData->fNumAudioBytes = AddTone(pFrameData->AudioBuffer()); // ...and remember number of audio bytes to xfer
1407 
1408  // Every few seconds, change the test pattern and tone frequency...
1409  const double currentTime (timeBase.FramesToSeconds(mCurrentFrame++));
1410  if (currentTime > timeOfLastSwitch + 4.0)
1411  {
1412  freqNdx = (freqNdx + 1) % gNumFrequencies;
1413  testPatNdx = (testPatNdx + 1) % ULWord(mTestPatRasters.size());
1414  mToneFrequency = gFrequencies[freqNdx];
1415  timeOfLastSwitch = currentTime;
1416  PLINFO("F" << DEC0N(mCurrentFrame,6) << ": tone=" << mToneFrequency << "Hz, pattern='" << tpNames.at(testPatNdx) << "'");
1417  } // if time to switch test pattern & tone frequency
1418 
1419  // Signal that I'm done producing this FrameData, making it immediately available for transfer/playout...
1420  mFrameDataRing.EndProduceNextBuffer();
1421 
1422  } // loop til mGlobalQuit goes true
1423  PLNOTE("Thread completed: " << DEC(mCurrentFrame) << " frame(s) produced, " << DEC(badTally) << " failed");
1424 
1425 } // ProduceFrames
1426 
1427 
1428 uint32_t NTV2Player4K::AddTone (ULWord * audioBuffer)
1429 {
1432  ULWord numChannels (0);
1433 
1434  mDevice.GetFrameRate (frameRate, mConfig.fOutputChannel);
1435  mDevice.GetAudioRate (audioRate, mAudioSystem);
1436  mDevice.GetNumberAudioChannels (numChannels, mAudioSystem);
1437 
1438  // Since audio on AJA devices use fixed sample rates (typically 48KHz), certain video frame rates will
1439  // necessarily result in some frames having more audio samples than others. GetAudioSamplesPerFrame is
1440  // called to calculate the correct sample count for the current frame...
1441  const ULWord numSamples (::GetAudioSamplesPerFrame (frameRate, audioRate, mCurrentFrame));
1442  const double sampleRateHertz (::GetAudioSamplesPerSecond(audioRate));
1443 
1444  // Unlike NTV2Player::AddTone, NTV2Player4K::AddTone handles multi-link audio:
1445  ULWord bytesWritten(0), startSample(mCurrentSample);
1446  for (UWord linkNdx(0); linkNdx < mConfig.fNumAudioLinks; linkNdx++)
1447  {
1448  mCurrentSample = startSample;
1449  bytesWritten += ::AddAudioTone (audioBuffer + (bytesWritten/4), // audio buffer to fill
1450  mCurrentSample, // which sample for continuing the waveform
1451  numSamples, // number of samples to generate
1452  sampleRateHertz, // sample rate [Hz]
1453  0.50, // uniform amplitude
1454  mToneFrequency, // uniform tone frequency [Hz]
1455  31, // bits per sample
1456  false, // don't byte swap
1457  numChannels); // number of audio channels to generate
1458  } // for each SDI audio link
1459  return bytesWritten;
1460 
1461 } // AddTone
1462 
1463 
1465 {
1466  mDevice.AutoCirculateGetStatus (mConfig.fOutputChannel, outStatus);
1467 }
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:205
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:3901
virtual bool SetHDMIV2Mode(const NTV2HDMIV2Mode inMode)
Sets HDMI V2 mode for the device.
Definition: ntv2hdmi.cpp:709
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:301
#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:1464
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=(0))
Sets the device&#39;s clock reference source. See Video Output Clocking & Synchronization for more inform...
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
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:997
Declares the NTV2TestPatternGen class.
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
Definition: ntv2card.h:2763
virtual bool GetAudioRate(NTV2AudioRate &outRate, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Returns the current NTV2AudioRate for the given Audio System.
Definition: ntv2audio.cpp:227
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:998
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:3905
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:236
virtual bool AutoCirculateGetStatus(const NTV2Channel inChannel, AUTOCIRCULATE_STATUS &outStatus)
Returns the current AutoCirculate status for the given channel.
virtual bool SetFrameBufferFormat(NTV2Channel inChannel, NTV2FrameBufferFormat inNewFormat, bool inIsAJARetail=(!(0)), NTV2HDRXferChars inXferChars=NTV2_VPID_TC_SDR_TV, NTV2HDRColorimetry inColorimetry=NTV2_VPID_Color_Rec709, NTV2HDRLuminance inLuminance=NTV2_VPID_Luminance_YCbCr)
Sets the frame buffer format for the given FrameStore on the AJA device.
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1361
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:4966
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:1010
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:3327
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:416
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.
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:180
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...
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:6750
Embeds silence (zeroes) into the data stream.
Definition: ntv2enums.h:2035
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:1370
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:1473
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:1364
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:798
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 UnsubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Unregisters me so I&#39;m no longer notified when an output VBI is signaled on the given output channel...
Definition: ntv2card.h:2819
virtual bool Connect(const NTV2InputCrosspointID inInputXpt, const NTV2OutputCrosspointID inOutputXpt, const bool inValidate=(0))
Connects the given widget signal input (sink) to the given widget signal output (source).
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:5414
This object specifies the information that will be transferred to or from the AJA device in the CNTV2...
virtual bool SetAudioBufferSize(const NTV2AudioBufferSize inValue, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Changes the size of the audio buffer that is used for a given Audio System in the AJA device...
Definition: ntv2audio.cpp:250
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:181
#define AJA_FALL_THRU
Definition: ajatypes.h:200
#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:3903
virtual bool WaitForOutputVerticalInterrupt(const NTV2Channel inChannel=NTV2_CHANNEL1, UWord inRepeatCount=1)
Efficiently sleeps the calling thread/process until the next one or more field (interlaced video) or ...
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:4236
This identifies the 4th Audio System.
Definition: ntv2enums.h:3906
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:936
ULWord GetFrameCount(void) const
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:1032
uint16_t UWord
Definition: ajatypes.h:234
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:1363
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 AutoCirculate streaming for the specified channel that was previously initialized by CNTV2Card...
bool CanDoFrameBufferFormat(const NTV2PixelFormat inPF)
virtual bool AutoCirculateInitForOutput(const NTV2Channel inChannel, const UWord inFrameCount=7, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_INVALID, const ULWord inOptionFlags=0, const UByte inNumChannels=1, const UWord inStartFrameNumber=0, const UWord inEndFrameNumber=0)
Prepares for subsequent AutoCirculate playback streaming, designating a contiguous block of frame buf...
#define xHEX0N(__x__, __n__)
virtual 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:4873
Specifies channel or FrameStore 4 (or the 4th item).
Definition: ntv2enums.h:1366
NTV2ChannelSet NTV2MakeChannelSet(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Specifies channel or FrameStore 5 (or the 5th item).
Definition: ntv2enums.h:1367
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:1933
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:1368
bool CanDoVideoFormat(const NTV2VideoFormat inVF)
UWord lastFrame(void) const
Definition: ntv2utils.h:999
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:1005
#define AUTOCIRCULATE_WITH_RP188
Use this to AutoCirculate with RP188.
const char * NTV2FrameBufferFormatString(NTV2FrameBufferFormat fmt)
Definition: ntv2debug.cpp:220
Specifies channel or FrameStore 7 (or the 7th item).
Definition: ntv2enums.h:1369
bool GetRP188Str(std::string &sRP188) const
Definition: ntv2rp188.cpp:918
std::string & lower(std::string &str)
Definition: common.cpp:436
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:147
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:3805
Specifies channel or FrameStore 3 (or the 3rd item).
Definition: ntv2enums.h:1365
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:837