AJA NTV2 SDK  18.0.0.2122
NTV2 SDK 18.0.0.2122
ntv2devicescanner.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2devicescanner.h"
9 #include "ntv2devicefeatures.h"
10 #include "ntv2utils.h"
11 #include "ajabase/common/common.h"
12 #include "ajabase/system/debug.h"
13 #include "ajabase/system/lock.h"
14 #include <sstream>
15 #include "ajabase/system/info.h"
16 #include "ajabase/common/json.hpp"
17 #include <fstream>
18 #include "ajabase/system/file_io.h"
19 
20 using namespace std;
21 using json = nlohmann::json;
22 
23 
24 #define PLFAIL(__x__) AJA_sERROR (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__)
25 #define PLWARN(__x__) AJA_sWARNING(AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__)
26 #define PLNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__)
27 #define PLINFO(__x__) AJA_sINFO (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__)
28 #define PLDBUG(__x__) AJA_sDEBUG (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__)
29 
30 
31 #if !defined(NTV2_DEPRECATE_17_1)
32  bool CNTV2DeviceScanner::IsHexDigit (const char inChr)
33  { static const string sHexDigits("0123456789ABCDEFabcdef");
34  return sHexDigits.find(inChr) != string::npos;
35  }
36 
37  bool CNTV2DeviceScanner::IsDecimalDigit (const char inChr)
38  { static const string sDecDigits("0123456789");
39  return sDecDigits.find(inChr) != string::npos;
40  }
41 
42  bool CNTV2DeviceScanner::IsAlphaNumeric (const char inChr)
43  { static const string sLegalChars("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
44  return sLegalChars.find(inChr) != string::npos;
45  }
46 
47  bool CNTV2DeviceScanner::IsLegalDecimalNumber (const string & inStr, const size_t inMaxLength)
48  {
49  return aja::is_legal_decimal_number(inStr, inMaxLength);
50  }
51 
52  uint64_t CNTV2DeviceScanner::IsLegalHexSerialNumber (const string & inStr) // 0x3236333331375458
53  {
54  return aja::is_legal_hex_serial_number(inStr);
55  }
56 
57  bool CNTV2DeviceScanner::IsAlphaNumeric (const string & inStr)
58  {
59  for (size_t ndx(0); ndx < inStr.size(); ndx++)
60  if (!aja::is_alpha_numeric(inStr.at(ndx)))
61  return false;
62  return true;
63  }
64 #endif // !defined(NTV2_DEPRECATE_17_1)
65 
66 bool CNTV2DeviceScanner::IsLegalSerialNumber (const string & inStr)
67 {
68  if (inStr.length() != 8 && inStr.length() != 9)
69  return false;
70  return aja::is_alpha_numeric(inStr);
71 }
72 
75 
77 {
78  AJAAutoLock tmpLock(&sDevInfoListLock);
79  return sDevInfoList.size();
80 }
81 
83 {
84  if (inScanNow)
85  ScanHardware();
86 }
87 
88  #if !defined(NTV2_DEPRECATE_16_3)
89  CNTV2DeviceScanner::CNTV2DeviceScanner (bool inScanNow, UWord inDeviceMask)
90  {
91  (void)inDeviceMask;
92  if (inScanNow)
93  ScanHardware();
94  }
95  #endif // !defined(NTV2_DEPRECATE_16_3)
96 
98 {
99  AJAAutoLock tmpLock(&sDevInfoListLock);
100  return sDevInfoList;
101 }
102 
103 
105 {
106  AJAAutoLock tmpLock(&sDevInfoListLock);
107  sDevInfoList.clear();
108 
109  for (UWord boardNum(0); ; boardNum++)
110  {
111  CNTV2Card tmpDev(boardNum);
112  if (!tmpDev.IsOpen())
113  break;
114  const NTV2DeviceID deviceID (tmpDev.GetDeviceID());
115 
116  if (deviceID != DEVICE_ID_NOTFOUND)
117  {
118  ostringstream oss;
119  NTV2DeviceInfo info;
120  info.deviceIndex = boardNum;
121  info.deviceID = deviceID;
122  tmpDev.GetSerialNumberString(info.serialNumber);
123 
124  oss << ::NTV2DeviceIDToString (deviceID, tmpDev.IsSupported(kDeviceHasMicrophoneInput)) << " - " << boardNum;
125 
126  info.deviceIdentifier = oss.str();
127  SetDeviceAttributes(info, tmpDev);
128  SetAudioAttributes(info, tmpDev);
129  sDevInfoList.push_back(info);
130  }
131  tmpDev.Close();
132  } // boardNum loop
133 
134  GetVDevList(sDevInfoList); // For VKONA support
135  GetCP2DevList(sDevInfoList); // For CP2 support
136 } // ScanHardware
137 
138 bool CNTV2DeviceScanner::DeviceIDPresent (const NTV2DeviceID inDeviceID, const bool inRescan)
139 {
140  AJAAutoLock tmpLock(&sDevInfoListLock);
141  if (inRescan)
142  ScanHardware();
143 
144  for (NTV2DeviceInfoListConstIter iter(sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
145  if (iter->deviceID == inDeviceID)
146  return true; // Found!
147  return false; // Not found
148 
149 } // DeviceIDPresent
150 
151 
152 bool CNTV2DeviceScanner::GetDeviceInfo (const ULWord inDeviceIndexNumber, NTV2DeviceInfo & outDeviceInfo, const bool inRescan)
153 {
154  AJAAutoLock tmpLock(&sDevInfoListLock);
155  if (inRescan)
156  ScanHardware();
157 
158  for (NTV2DeviceInfoListConstIter iter(sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
159  if (iter->deviceIndex == inDeviceIndexNumber)
160  {
161  outDeviceInfo = *iter;
162  return true; // Found!
163  }
164  return false; // No devices with this index number
165 
166 } // GetDeviceInfo
167 
168 bool CNTV2DeviceScanner::GetDeviceAtIndex (const ULWord inDeviceIndexNumber, CNTV2Card & outDevice)
169 {
170  outDevice.Close();
171  AJAAutoLock tmpLock(&sDevInfoListLock);
172  ScanHardware();
173  for (NTV2DeviceInfoListConstIter iter(sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
174  if (iter->deviceIndex == inDeviceIndexNumber)
175  {
176  if (iter->isVirtualDevice)
177  return outDevice.Open(iter->vdevUrl);
178  else
179  return outDevice.Open(UWord(inDeviceIndexNumber));
180  }
181  return false; // No devices with this index number
182 
183 } // GetDeviceAtIndex
184 
185 
187 {
188  outDevice.Close();
189  AJAAutoLock tmpLock(&sDevInfoListLock);
190  ScanHardware();
191  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
192  if (sDevInfoList.at(ndx).deviceID == inDeviceID)
193  {
194  if (sDevInfoList.at(ndx).isVirtualDevice)
195  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
196  else
197  return outDevice.Open(UWord(ndx));
198  }
199  return false; // Not found
200 
201 } // GetFirstDeviceWithID
202 
203 
204 bool CNTV2DeviceScanner::GetFirstDeviceWithName (const string & inNameSubString, CNTV2Card & outDevice)
205 {
206  outDevice.Close();
207  AJAAutoLock tmpLock(&sDevInfoListLock);
208  ScanHardware();
209  string nameSubString(inNameSubString); aja::lower(nameSubString);
210  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
211  {
212  string deviceName(sDevInfoList.at(ndx).deviceIdentifier); aja::lower(deviceName);
213  if (deviceName.find(nameSubString) != string::npos)
214  {
215  if (sDevInfoList.at(ndx).isVirtualDevice)
216  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
217  else
218  return outDevice.Open(UWord(ndx));
219  }
220  }
221  if (nameSubString == "io4kplus")
222  { // Io4K+ == DNXIV...
223  nameSubString = "avid dnxiv";
224  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
225  {
226  string deviceName(sDevInfoList.at(ndx).deviceIdentifier); aja::lower(deviceName);
227  if (deviceName.find(nameSubString) != string::npos)
228  {
229  if (sDevInfoList.at(ndx).isVirtualDevice)
230  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
231  else
232  return outDevice.Open(UWord(ndx));
233  }
234  }
235  }
236  return false; // Not found
237 
238 } // GetFirstDeviceWithName
239 
240 bool CNTV2DeviceScanner::GetVirtualDeviceWithName (const string & inNameString, CNTV2Card & outDevice, const bool inRescan)
241 {
242  outDevice.Close();
243  AJAAutoLock tmpLock(&sDevInfoListLock);
244  if (inRescan)
245  ScanHardware();
246  string nameString(inNameString); aja::lower(nameString);
247  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
248  {
249  if (!sDevInfoList.at(ndx).isVirtualDevice)
250  continue;
251  string deviceName(sDevInfoList.at(ndx).vdevName); aja::lower(deviceName);
252  if (deviceName == nameString)
253  {
254  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
255  }
256  }
257  return false; // Not found
258 }
259 
260 bool CNTV2DeviceScanner::GetFirstDeviceWithSerial (const string & inSerialStr, CNTV2Card & outDevice)
261 {
262  outDevice.Close();
263  AJAAutoLock tmpLock(&sDevInfoListLock);
264  ScanHardware();
265  string searchSerialStr(inSerialStr); aja::lower(searchSerialStr);
266  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
267  {
268  string ser(sDevInfoList.at(ndx).serialNumber); aja::lower(ser);
269  if (ser.find(searchSerialStr) != string::npos)
270  {
271  if (sDevInfoList.at(ndx).isVirtualDevice)
272  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
273  else
274  return outDevice.Open(UWord(ndx));
275  }
276  }
277  return false;
278 }
279 
280 
281 #if !defined(NTV2_DEPRECATE_17_5)
282 bool CNTV2DeviceScanner::GetDeviceWithSerial (const uint64_t inSerialNumber, CNTV2Card & outDevice)
283 {
284  const string serNumStr(::SerialNum64ToString(inSerialNumber));
285  return GetDeviceWithSerial(serNumStr, outDevice);
286 }
287 #endif // !defined(NTV2_DEPRECATE_17_5)
288 
289 bool CNTV2DeviceScanner::GetDeviceWithSerial (const string & inSerialNumber, CNTV2Card & outDevice)
290 {
291  outDevice.Close();
292  AJAAutoLock tmpLock(&sDevInfoListLock);
293  ScanHardware();
294  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
295  if (sDevInfoList.at(ndx).serialNumber == inSerialNumber)
296  {
297  if (sDevInfoList.at(ndx).isVirtualDevice)
298  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
299  else
300  return outDevice.Open(UWord(ndx));
301  }
302  return false;
303 }
304 
305 
306 bool CNTV2DeviceScanner::GetFirstDeviceFromArgument (const string & inArgument, CNTV2Card & outDevice)
307 {
308  outDevice.Close();
309  if (inArgument.empty())
310  return false;
311 
312  // Special case: 'LIST' or '?' --- print an enumeration of available devices to stdout, then bail
313  AJAAutoLock tmpLock(&sDevInfoListLock);
314  ScanHardware();
315  string upperArg(inArgument); aja::upper(upperArg);
316  if (upperArg == "LIST" || upperArg == "?")
317  {
318  if (sDevInfoList.empty())
319  cout << "No devices detected" << endl;
320  else
321  cout << DEC(sDevInfoList.size()) << " available " << (sDevInfoList.size() == 1 ? "device:" : "devices:") << endl;
322  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
323  {
324  if (sDevInfoList.at(ndx).isVirtualDevice)
325  {
326  cout << DECN(ndx, 2) << " | " << setw(8) << "virtual";
327  if (!sDevInfoList.at(ndx).vdevName.empty())
328  cout << " | " << setw(10) << sDevInfoList.at(ndx).vdevName;
329  cout << " | " << sDevInfoList.at(ndx).vdevUrl << endl;
330  }
331  else
332  {
333  cout << DECN(ndx, 2) << " | " << setw(8) << "local";
334  const string serNum(sDevInfoList.at(ndx).serialNumber);
335  if (!serNum.empty())
336  cout << " | " << setw(10) << serNum;
337  cout << " | " << setw(16) << ::NTV2DeviceIDToString(sDevInfoList.at(ndx).deviceID);
338  cout << endl;
339  }
340  }
341  return false;
342  }
343 
344  for (NTV2DeviceInfoListConstIter iter (sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
345  {
346  if (iter->isVirtualDevice)
347  { bool ok (false);
348  if (to_string(iter->deviceIndex) == inArgument
349  || iter->deviceIdentifier == inArgument
350  || iter->vdevName == inArgument
351  || (aja::is_legal_decimal_number(inArgument, inArgument.length())
352  && aja::is_legal_hex_serial_number(inArgument)
353  && iter->deviceID == NTV2DeviceID(stoi(inArgument))))
354  {
355  ok = outDevice.Open(iter->vdevUrl);
356  if (ok)
357  outDevice.setDeviceIndexNumber(UWord(iter->deviceIndex)); // Patch _boardNumber
358  return ok;
359  }
360  else if (IsLegalSerialNumber(inArgument))
361  return outDevice.Open(inArgument);
362  else if (inArgument.find("://") != string::npos)
363  return outDevice.Open(inArgument);
364  }
365  else
366  {
367  if (to_string(iter->deviceIndex) == inArgument)
368  return outDevice.Open(inArgument);
369  else if (iter->deviceIdentifier == inArgument)
370  return outDevice.Open(inArgument);
371  else if (aja::is_legal_decimal_number(inArgument, inArgument.length()) && aja::is_legal_hex_serial_number(inArgument) && iter->deviceID == NTV2DeviceID(stoi(inArgument)))
372  return outDevice.Open(inArgument);
373  else if (IsLegalSerialNumber(inArgument))
374  return outDevice.Open(inArgument);
375  else if (inArgument.find("://") != string::npos)
376  return outDevice.Open(inArgument);
377  }
378  }
379  return outDevice.Open(inArgument);
380 } // GetFirstDeviceFromArgument
381 
382 
384 { // Name that will find given device via CNTV2DeviceScanner::GetFirstDeviceFromArgument
385  if (!inDevice.IsOpen())
386  return string();
387  // Nub address 1st...
388  if (!inDevice.GetHostName().empty() && inDevice.IsRemote())
389  return inDevice.GetHostName(); // Nub host/device
390 
391  // Serial number 2nd...
392  string str;
393  if (inDevice.GetSerialNumberString(str))
394  return str;
395 
396  // Model name 3rd...
397  str = ::NTV2DeviceIDToString(inDevice.GetDeviceID(), false);
398  if (!str.empty() && str != "???")
399  return str;
400 
401  // Index number last...
402  ostringstream oss; oss << DEC(inDevice.GetIndexNumber());
403  return oss.str();
404 }
405 
406 
407 ostream & operator << (ostream & inOutStr, const NTV2DeviceInfoList & inList)
408 {
409  for (NTV2DeviceInfoListConstIter iter(inList.begin()); iter != inList.end(); ++iter)
410  inOutStr << " " << *iter;
411  return inOutStr;
412 
413 } // NTV2DeviceInfoList ostream operator <<
414 
415 
417 {
418  const NTV2DeviceInfo & first (*this);
419  size_t diffs (0);
420 
421  // 'memcmp' would be simpler, but because NTV2DeviceInfo has no constructor, the unfilled bytes in
422  // its "boardIdentifier" field are indeterminate, making it worthless for accurate comparisons.
423  // "boardSerialNumber" and boardNumber are the only required comparisons, but I also check boardType,
424  // boardID, and pciSlot for good measure...
425  if (first.deviceID != second.deviceID) diffs++;
426  if (first.deviceIndex != second.deviceIndex) diffs++;
427  if (first.serialNumber != second.serialNumber) diffs++;
428  if (first.pciSlot != second.pciSlot) diffs++;
429 
430  // Needs to be fixed now that deviceIdentifier is a std::string
431  //#if defined (AJA_DEBUG)
432  // if (::strncmp (first.deviceIdentifier.c_str (), second.deviceIdentifier.c_str (), first.deviceIdentifier.length ()))) diffs++;
433  // if (diffs)
434  // {cout << "## DEBUG: " << diffs << " diff(s):" << endl << "#### first ####" << endl << first << "#### second ####" << endl << second << endl;}
435  //#endif // AJA_DEBUG
436 
437  return diffs ? false : true;
438 
439 } // equality operator
440 
442 {
443  deviceID = DEVICE_ID_INVALID;
444  deviceIndex = 0;
445  pciSlot = 0;
446  deviceSerialNumber = 0;
447  serialNumber = "";
448  numVidInputs = 0;
449  numVidOutputs = 0;
450  numAnlgVidInputs = 0;
451  numAnlgVidOutputs = 0;
452  numHDMIVidInputs = 0;
453  numHDMIVidOutputs = 0;
454  numInputConverters = 0;
455  numOutputConverters = 0;
456  numUpConverters = 0;
457  numDownConverters = 0;
458  downConverterDelay = 0;
459  isoConvertSupport = false;
460  rateConvertSupport = false;
461  dvcproHDSupport = false;
462  qrezSupport = false;
463  hdvSupport = false;
464  quarterExpandSupport = false;
465  vidProcSupport = false;
466  dualLinkSupport = false;
467  colorCorrectionSupport = false;
468  programmableCSCSupport = false;
469  rgbAlphaOutputSupport = false;
470  breakoutBoxSupport = false;
471  procAmpSupport = false;
472  has2KSupport = false;
473  has4KSupport = false;
474  has8KSupport = false;
475  has3GLevelConversion = false;
476  proResSupport = false;
477  sdi3GSupport = false;
478  sdi12GSupport = false;
479  ipSupport = false;
480  biDirectionalSDI = false;
481  ltcInSupport = false;
482  ltcOutSupport = false;
483  ltcInOnRefPort = false;
484  stereoOutSupport = false;
485  stereoInSupport = false;
486  multiFormat = false;
487  numAudioStreams = 0;
488  numAnalogAudioInputChannels = 0;
489  numAESAudioInputChannels = 0;
490  numEmbeddedAudioInputChannels = 0;
491  numHDMIAudioInputChannels = 0;
492  numAnalogAudioOutputChannels = 0;
493  numAESAudioOutputChannels = 0;
494  numEmbeddedAudioOutputChannels = 0;
495  numHDMIAudioOutputChannels = 0;
496  numDMAEngines = 0;
497  numSerialPorts = 0;
498  pingLED = 0;
499  deviceIdentifier.clear();
500  audioSampleRateList.clear();
501  audioNumChannelsList.clear();
502  audioBitsPerSampleList.clear();
503  audioInSourceList.clear();
504  audioOutSourceList.clear();
505 }
506 
508 {
509  if (&info != this)
510  *this = info;
511 }
512 
513 
515  const NTV2DeviceInfoList & inNewList,
516  NTV2DeviceInfoList & outBoardsAdded,
517  NTV2DeviceInfoList & outBoardsRemoved)
518 {
519  NTV2DeviceInfoListConstIter oldIter (inOldList.begin ());
520  NTV2DeviceInfoListConstIter newIter (inNewList.begin ());
521 
522  outBoardsAdded.clear ();
523  outBoardsRemoved.clear ();
524 
525  while (true)
526  {
527  if (oldIter == inOldList.end () && newIter == inNewList.end ())
528  break; // Done -- exit
529 
530  if (oldIter != inOldList.end () && newIter != inNewList.end ())
531  {
532  const NTV2DeviceInfo & oldInfo (*oldIter), newInfo (*newIter);
533 
534  if (oldInfo != newInfo)
535  {
536  // Out with the old...
537  outBoardsRemoved.push_back (oldInfo);
538 
539  // In with the new...
540  if (newInfo.deviceID && newInfo.deviceID != NTV2DeviceID(0xFFFFFFFF))
541  outBoardsAdded.push_back (newInfo);
542  } // if mismatch
543 
544  ++oldIter;
545  ++newIter;
546  continue; // Move along
547 
548  } // if both valid
549 
550  if (oldIter != inOldList.end () && newIter == inNewList.end ())
551  {
552  outBoardsRemoved.push_back (*oldIter);
553  ++oldIter;
554  continue; // Move along
555  } // old is valid, new is not valid
556 
557  if (oldIter == inOldList.end () && newIter != inNewList.end ())
558  {
559  if (newIter->deviceID && newIter->deviceID != NTV2DeviceID(0xFFFFFFFF))
560  outBoardsAdded.push_back (*newIter);
561  ++newIter;
562  continue; // Move along
563  } // old is not valid, new is valid
564 
565  NTV2_ASSERT(false && "should never get here");
566 
567  } // loop til break
568 
569  // Return 'true' if there were any changes...
570  return !outBoardsAdded.empty () || !outBoardsRemoved.empty ();
571 
572 } // CompareDeviceInfoLists
573 
574 
575 ostream & operator << (ostream & inOutStr, const NTV2AudioSampleRateList & inList)
576 {
577  for (NTV2AudioSampleRateListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
578  inOutStr << " " << *iter;
579 
580  return inOutStr;
581 }
582 
583 
584 ostream & operator << (ostream & inOutStr, const NTV2AudioChannelsPerFrameList & inList)
585 {
586  for (NTV2AudioChannelsPerFrameListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
587  inOutStr << " " << *iter;
588 
589  return inOutStr;
590 }
591 
592 
593 ostream & operator << (ostream & inOutStr, const NTV2AudioSourceList & inList)
594 {
595  for (NTV2AudioSourceListConstIter iter(inList.begin()); iter != inList.end(); ++iter)
596  switch (*iter) // AudioSourceEnum
597  {
598  case kSourceSDI: return inOutStr << " SDI";
599  case kSourceAES: return inOutStr << " AES";
600  case kSourceADAT: return inOutStr << " ADAT";
601  case kSourceAnalog: return inOutStr << " Analog";
602  case kSourceNone: return inOutStr << " None";
603  case kSourceAll: return inOutStr << " All";
604  }
605  return inOutStr << " ???";
606 }
607 
608 
609 ostream & operator << (ostream & inOutStr, const NTV2AudioBitsPerSampleList & inList)
610 {
611  for (NTV2AudioBitsPerSampleListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
612  inOutStr << " " << *iter;
613 
614  return inOutStr;
615 }
616 
617 
618 ostream & operator << (ostream & inOutStr, const NTV2DeviceInfo & inInfo)
619 {
620  inOutStr << "Device Info for '" << inInfo.deviceIdentifier << "'" << endl
621  << " Device Index Number: " << inInfo.deviceIndex << endl
622  << " Device ID: 0x" << hex << inInfo.deviceID << dec << endl
623  << " Serial Number: " << inInfo.serialNumber << endl
624  << " PCI Slot: 0x" << hex << inInfo.pciSlot << dec << endl
625  << " Video Inputs: " << inInfo.numVidInputs << endl
626  << " Video Outputs: " << inInfo.numVidOutputs << endl
627  #if defined (_DEBUG)
628  << " Analog Video Inputs: " << inInfo.numAnlgVidInputs << endl
629  << " Analog Video Outputs: " << inInfo.numAnlgVidOutputs << endl
630  << " HDMI Video Inputs: " << inInfo.numHDMIVidInputs << endl
631  << " HDMI Video Outputs: " << inInfo.numHDMIVidOutputs << endl
632  << " Input Converters: " << inInfo.numInputConverters << endl
633  << " Output Converters: " << inInfo.numOutputConverters << endl
634  << " Up Converters: " << inInfo.numUpConverters << endl
635  << " Down Converters: " << inInfo.numDownConverters << endl
636  << " Down Converter Delay: " << inInfo.downConverterDelay << endl
637  << " DVCProHD: " << (inInfo.dvcproHDSupport ? "Y" : "N") << endl
638  << " Qrez: " << (inInfo.qrezSupport ? "Y" : "N") << endl
639  << " HDV: " << (inInfo.hdvSupport ? "Y" : "N") << endl
640  << " Quarter Expand: " << (inInfo.quarterExpandSupport ? "Y" : "N") << endl
641  << " ISO Convert: " << (inInfo.isoConvertSupport ? "Y" : "N") << endl
642  << " Rate Convert: " << (inInfo.rateConvertSupport ? "Y" : "N") << endl
643  << " VidProc: " << (inInfo.vidProcSupport ? "Y" : "N") << endl
644  << " Dual-Link: " << (inInfo.dualLinkSupport ? "Y" : "N") << endl
645  << " Color-Correction: " << (inInfo.colorCorrectionSupport ? "Y" : "N") << endl
646  << " Programmable CSC: " << (inInfo.programmableCSCSupport ? "Y" : "N") << endl
647  << " RGB Alpha Output: " << (inInfo.rgbAlphaOutputSupport ? "Y" : "N") << endl
648  << " Breakout Box: " << (inInfo.breakoutBoxSupport ? "Y" : "N") << endl
649  << " ProcAmp: " << (inInfo.procAmpSupport ? "Y" : "N") << endl
650  << " 2K: " << (inInfo.has2KSupport ? "Y" : "N") << endl
651  << " 4K: " << (inInfo.has4KSupport ? "Y" : "N") << endl
652  << " 8K: " << (inInfo.has8KSupport ? "Y" : "N") << endl
653  << " 3G Level Conversion: " << (inInfo.has3GLevelConversion ? "Y" : "N") << endl
654  << " ProRes: " << (inInfo.proResSupport ? "Y" : "N") << endl
655  << " SDI 3G: " << (inInfo.sdi3GSupport ? "Y" : "N") << endl
656  << " SDI 12G: " << (inInfo.sdi12GSupport ? "Y" : "N") << endl
657  << " IP: " << (inInfo.ipSupport ? "Y" : "N") << endl
658  << " SDI Bi-Directional: " << (inInfo.biDirectionalSDI ? "Y" : "N") << endl
659  << " LTC In: " << (inInfo.ltcInSupport ? "Y" : "N") << endl
660  << " LTC Out: " << (inInfo.ltcOutSupport ? "Y" : "N") << endl
661  << " LTC In on Ref Port: " << (inInfo.ltcInOnRefPort ? "Y" : "N") << endl
662  << " Stereo Out: " << (inInfo.stereoOutSupport ? "Y" : "N") << endl
663  << " Stereo In: " << (inInfo.stereoInSupport ? "Y" : "N") << endl
664  << " Audio Sample Rates: " << inInfo.audioSampleRateList << endl
665  << " AudioNumChannelsList: " << inInfo.audioNumChannelsList << endl
666  << " AudioBitsPerSampleList: " << inInfo.audioBitsPerSampleList << endl
667  << " AudioInSourceList: " << inInfo.audioInSourceList << endl
668  << " AudioOutSourceList: " << inInfo.audioOutSourceList << endl
669  << " Audio Streams: " << inInfo.numAudioStreams << endl
670  << " Analog Audio Input Channels: " << inInfo.numAnalogAudioInputChannels << endl
671  << " Analog Audio Output Channels: " << inInfo.numAnalogAudioOutputChannels << endl
672  << " AES Audio Input Channels: " << inInfo.numAESAudioInputChannels << endl
673  << " AES Audio Output Channels: " << inInfo.numAESAudioOutputChannels << endl
674  << " Embedded Audio Input Channels: " << inInfo.numEmbeddedAudioInputChannels << endl
675  << " Embedded Audio Output Channels: " << inInfo.numEmbeddedAudioOutputChannels << endl
676  << " HDMI Audio Input Channels: " << inInfo.numHDMIAudioInputChannels << endl
677  << " HDMI Audio Output Channels: " << inInfo.numHDMIAudioOutputChannels << endl
678  << " DMA Engines: " << inInfo.numDMAEngines << endl
679  << " Serial Ports: " << inInfo.numSerialPorts << endl
680  #endif // AJA_DEBUG
681  << "";
682 
683  return inOutStr;
684 
685 } // NTV2DeviceInfo ostream operator <<
686 
687 
688 ostream & operator << (ostream & inOutStr, const NTV2AudioPhysicalFormat & inFormat)
689 {
690  inOutStr << "AudioPhysicalFormat:" << endl
691  << " boardNumber: " << inFormat.boardNumber << endl
692  << " sampleRate: " << inFormat.sampleRate << endl
693  << " numChannels: " << inFormat.numChannels << endl
694  << " bitsPerSample: " << inFormat.bitsPerSample << endl
695  #if defined (DEBUG) || defined (AJA_DEBUG)
696  << " sourceIn: 0x" << hex << inFormat.sourceIn << dec << endl
697  << " sourceOut: 0x" << hex << inFormat.sourceOut << dec << endl
698  #endif // DEBUG or AJA_DEBUG
699  ;
700 
701  return inOutStr;
702 
703 } // AudioPhysicalFormat ostream operator <<
704 
705 
706 std::ostream & operator << (std::ostream & inOutStr, const NTV2AudioPhysicalFormatList & inList)
707 {
708  for (NTV2AudioPhysicalFormatListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
709  inOutStr << *iter;
710 
711  return inOutStr;
712 
713 } // AudioPhysicalFormatList ostream operator <<
714 
715 
716 // Private methods
717 
718 void CNTV2DeviceScanner::SetDeviceAttributes (NTV2DeviceInfo & inDeviceInfo, CNTV2Card & inDevice)
719 {
720  inDevice.GetSerialNumberString(inDeviceInfo.serialNumber);
721  const ULWordSet wgtIDs (inDevice.GetSupportedItems(kNTV2EnumsID_WidgetID));
722  inDeviceInfo.numVidInputs = inDevice.GetNumSupported(kDeviceGetNumVideoInputs);
733  inDeviceInfo.dvcproHDSupport = inDevice.IsSupported(kDeviceCanDoDVCProHD);
734  inDeviceInfo.qrezSupport = inDevice.IsSupported(kDeviceCanDoQREZ);
735  inDeviceInfo.hdvSupport = inDevice.IsSupported(kDeviceCanDoHDV);
740  inDeviceInfo.breakoutBoxSupport = inDevice.IsSupported(kDeviceCanDoBreakoutBox);
741  inDeviceInfo.vidProcSupport = inDevice.IsSupported(kDeviceCanDoVideoProcessing);
742  inDeviceInfo.dualLinkSupport = inDevice.IsSupported(kDeviceCanDoDualLink);
744  inDeviceInfo.pingLED = inDevice.GetNumSupported(kDeviceGetPingLED);
745  inDeviceInfo.has2KSupport = inDevice.IsSupported(kDeviceCanDo2KVideo);
746  inDeviceInfo.has4KSupport = inDevice.IsSupported(kDeviceCanDo4KVideo);
747  inDeviceInfo.has8KSupport = inDevice.IsSupported(kDeviceCanDo8KVideo);
749  inDeviceInfo.isoConvertSupport = inDevice.IsSupported(kDeviceCanDoIsoConvert);
750  inDeviceInfo.rateConvertSupport = inDevice.IsSupported(kDeviceCanDoRateConvert);
751  inDeviceInfo.proResSupport = inDevice.IsSupported(kDeviceCanDoProRes);
752  inDeviceInfo.sdi3GSupport = wgtIDs.find(NTV2_Wgt3GSDIOut1) != wgtIDs.end();
753  inDeviceInfo.sdi12GSupport = inDevice.IsSupported(kDeviceCanDo12GSDI);
754  inDeviceInfo.ipSupport = inDevice.IsSupported(kDeviceCanDoIP);
756  inDeviceInfo.ltcInSupport = inDevice.GetNumSupported(kDeviceGetNumLTCInputs) > 0;
757  inDeviceInfo.ltcOutSupport = inDevice.GetNumSupported(kDeviceGetNumLTCOutputs) > 0;
758  inDeviceInfo.ltcInOnRefPort = inDevice.IsSupported(kDeviceCanDoLTCInOnRefPort);
759  inDeviceInfo.stereoOutSupport = inDevice.IsSupported(kDeviceCanDoStereoOut);
760  inDeviceInfo.stereoInSupport = inDevice.IsSupported(kDeviceCanDoStereoIn);
761  inDeviceInfo.multiFormat = inDevice.IsSupported(kDeviceCanDoMultiFormat);
763  inDeviceInfo.procAmpSupport = false;
764 }
765 
766 void CNTV2DeviceScanner::SetAudioAttributes (NTV2DeviceInfo & info, CNTV2Card & inBoard)
767 {
768  // Start with empty lists...
769  info.audioSampleRateList.clear();
770  info.audioNumChannelsList.clear();
771  info.audioBitsPerSampleList.clear();
772  info.audioInSourceList.clear();
773  info.audioOutSourceList.clear();
774 
775 
777  {
778  ULWord audioControl;
779  inBoard.ReadRegister(kRegAud1Control, audioControl);
780 
781  //audioSampleRateList
782  info.audioSampleRateList.push_back(k48KHzSampleRate);
783  if (inBoard.IsSupported(kDeviceCanDoAudio96K))
784  info.audioSampleRateList.push_back(k96KHzSampleRate);
785 
786  //audioBitsPerSampleList
788 
789  //audioInSourceList
790  info.audioInSourceList.push_back(kSourceSDI);
791  if (audioControl & BIT(21))
792  info.audioInSourceList.push_back(kSourceAES);
794  info.audioInSourceList.push_back(kSourceAnalog);
795 
796  //audioOutSourceList
797  info.audioOutSourceList.push_back(kSourceAll);
798 
799  //audioNumChannelsList
806 
808  }
809 
818 
819 } // SetAudioAttributes
820 
821 bool CNTV2DeviceScanner::GetVDevList (NTV2DeviceInfoList & outVDevList)
822 {
823 #if defined(NTV2_PREVENT_PLUGIN_LOAD)
824  return false; // Plugin loading disabled, therefore no virtual devices
825 #else // else NTV2_PREVENT_PLUGIN_LOAD
826  string vdevPath (::NTV2GetVDevFolderPath());
827  if (vdevPath.empty())
828  return false;
829  ULWord vdIndex (ULWord(outVDevList.size()));
830  NTV2StringList vdevFiles;
831  AJAFileIO::ReadDirectory(vdevPath, "*.vdev", vdevFiles);
832  for (const auto & vdevFile : vdevFiles)
833  {
834  PLDBUG(vdevFile);
835  json vdevJson;
836  {
837  std::ifstream vf(vdevFile);
838  if (!vf.is_open())
839  {PLFAIL("Unable to open '" << vdevFile << "'"); return false;}
840  try
841  {
842  vdevJson = json::parse(vf);
843  }
844  catch (const json::parse_error& e)
845  {
846  PLFAIL("Invalid JSON at byte " << e.byte << " in '" << vdevFile << "': " << e.what() << ", exceptionID " << e.id);
847  return false;
848  }
849  }
850 
851  NTV2DeviceInfo newVDev;
852  newVDev.isVirtualDevice = true;
853  newVDev.deviceIndex = vdIndex;
854  newVDev.deviceID = DEVICE_ID_SOFTWARE;
855  newVDev.deviceIdentifier = "";
856  newVDev.vdevName = "";
857  bool explicitlyDisabled(false);
858 
859  // EXPECTED JSON KEYS:
860  // "urlspec" [required] Specifies urlspec used to load the plugin.
861  // "name" [optional] Specifies a human-readable name for the device.
862  // If not specified, the .vdev file's base name is used instead.
863  // "disabled" [optional] Specify boolean 'true' to explicitly disable the device; 'false' retains device.
864  // If not specified, the device will always be considered enabled.
865  if (vdevJson.size() > 32)
866  {PLFAIL("File '" << vdevFile << "': more than 32 keys"); continue;}
867  NTV2StringSet keys;
868  for (auto it(vdevJson.cbegin()); it != vdevJson.cend(); ++it)
869  if (keys.find(it.key()) == keys.end())
870  keys.insert(it.key());
872  NTV2StringList goodKeys, badKeys;
873  for (NTV2StringSetConstIter itKey(keys.begin()); itKey != keys.end(); ++itKey)
874  {
875  if (legalKeys.find(*itKey) == legalKeys.end())
876  badKeys.push_back(*itKey);
877  else
878  goodKeys.push_back(*itKey);
879  }
880  if (!badKeys.empty())
881  PLWARN("File '" << vdevFile << "': ignored " << DEC(badKeys.size()) << " unknown key(s): '" << aja::join(badKeys, "', '") << "'");
882  auto nameVal (vdevJson[kVDevJSON_Name]), urlspecVal (vdevJson[kVDevJSON_URLSpec]), disabledVal (vdevJson[kVDevJSON_Disabled]);
883  if (urlspecVal.is_null())
884  {PLFAIL("File '" << vdevFile << "': missing required 'urlspec' parameter"); continue;}
885  if (disabledVal.is_boolean())
886  {
887  NTV2_ASSERT(!disabledVal.is_null());
888  explicitlyDisabled = disabledVal.get<bool>();
889  }
890  else if (!disabledVal.is_null())
891  {PLFAIL("File '" << vdevFile << "': invalid 'disabled' value -- expected boolean 'true' or 'false' value"); continue;}
892  if (explicitlyDisabled)
893  {PLNOTE("File '" << vdevFile << "': explicitly 'disabled'"); continue;}
894  newVDev.vdevUrl = urlspecVal.get<std::string>(); // done, we have the vdevUrl
895  NTV2DeviceSpecParser parser (newVDev.vdevUrl); // Check it
896  if (!nameVal.is_null())
897  newVDev.vdevName = nameVal.get<std::string>(); // Name specified in JSON file
898  { // URLencode & append these URL params: &vdevfname= &vdevfpath= &vdevname= &vdevbasename=
899  newVDev.vdevUrl += parser.HasQueryParams() ? "&" : "?";
900  newVDev.vdevUrl += kQParamVDevFolderPath "=" + ::PercentEncode(vdevPath);
901  string fName (vdevFile);
902  fName.erase(fName.find(vdevPath), vdevPath.length()+1); // Remove everything up to file name
903  newVDev.vdevUrl += "&" kQParamVDevFileName "=" + ::PercentEncode(fName); // Remember file name
904  fName.erase(fName.length()-5, 5); // Lop off file name extension
905  if (newVDev.vdevName.empty())
906  newVDev.vdevName = fName; // Use file base name if no name specified in JSON file
907  newVDev.vdevUrl += "&" kQParamVDevName "=" + ::PercentEncode(newVDev.vdevName); // Remember name
908  ostringstream oss; oss << DEC(newVDev.deviceIndex);
909  newVDev.vdevUrl += "&" kQParamVDevIndex "=" + oss.str(); // Remember index number
910  }
911  if (!newVDev.vdevName.empty())
912  { ostringstream oss; oss << newVDev.vdevName << " - " << newVDev.deviceIndex;
913  newVDev.deviceIdentifier = oss.str();
914  }
915 
916  outVDevList.push_back(newVDev);
917  vdIndex++; // Now increment the device index number
918  } // for each vdev file found
919  return true;
920 #endif // else NTV2_PREVENT_PLUGIN_LOAD
921 } // GetVDevList
922 
923 bool CNTV2DeviceScanner::GetCP2DevList (NTV2DeviceInfoList & outVDevList)
924 {
925 #if defined(NTV2_PREVENT_PLUGIN_LOAD)
926  return false; // Plugin loading disabled, therefore no virtual devices
927 #else // else NTV2_PREVENT_PLUGIN_LOAD
928  string vdevPath;
930  if (pathInfo.GetValue(AJA_SystemInfoTag_Path_PersistenceStoreUser, vdevPath) != AJA_STATUS_SUCCESS)
931  return false;
932  }
933  vdevPath += "virtualdevices";
934  ULWord vdIndex = ULWord(outVDevList.size());
935  NTV2StringList vdevFiles;
936  AJAFileIO::ReadDirectory(vdevPath, "*.vdev", vdevFiles);
937  for (const auto & vdevFile : vdevFiles)
938  {
939  json vdevJson;
940  {
941  std::ifstream vf(vdevFile);
942  if (!vf.is_open())
943  {PLFAIL("Unable to open '" << vdevFile << "'"); return false;}
944  try
945  {
946  vdevJson = json::parse(vf);
947  }
948  catch (const json::parse_error& e)
949  {
950  PLFAIL("Invalid JSON at byte " << e.byte << " in '" << vdevFile << "': " << e.what() << ", exceptionID " << e.id);
951  return false;
952  }
953  }
954 
955  NTV2DeviceInfo newVDev;
956  newVDev.isVirtualDevice = true;
957  newVDev.deviceIndex = vdIndex++;
958  newVDev.deviceID = DEVICE_ID_SOFTWARE;
959  newVDev.deviceIdentifier = "";
960  newVDev.vdevName = "";
961 
962  // EXPECTED JSON KEYS:
963  // "plugin" [required] Specifies name of plugin to be loaded.
964  // "name" [optional] Specifies a human-readable name for the device.
965  // "host" [optional] Specifies host to use in the plugin URL. Defaults to "localhost".
966  string hostName;
967  auto pluginVal (vdevJson["plugin"]), nameVal (vdevJson["name"]), hostVal (vdevJson["host"]), urlspecVal (vdevJson["urlspec"]);
968  if (pluginVal.is_null())
969  {PLFAIL("File: '" << vdevFile << "' missing required 'plugin' parameter"); continue;}
970  if (!urlspecVal.is_null())
971  PLWARN("File: '" << vdevFile << "' 'urlspec' parameter ignored");
972 
973  newVDev.vdevUrl = pluginVal.get<std::string>();
974  if (!nameVal.is_null())
975  {
976  ostringstream oss;
977  oss << nameVal.get<std::string>() << " - " << newVDev.deviceIndex;
978  newVDev.deviceIdentifier = oss.str();
979  newVDev.vdevName = nameVal.get<std::string>();
980  }
981 
982  if (!hostVal.is_null())
983  hostName = hostVal.get<std::string>();
984  if (hostName.empty())
985  hostName = "localhost";
986  newVDev.vdevUrl += "://" + hostName + "/?";
987 
988  NTV2StringList params;
989  for (auto it (vdevJson.begin()); it != vdevJson.end(); ++it)
990  if (it.key() != "plugin" && it.key() != "name" && it.key() != "host")
991  {
992  auto paramValStr = to_string(it.value());
993  aja::strip(paramValStr, "\"");
994  params.push_back(it.key() + "=" + ::PercentEncode(paramValStr));
995  }
996 
997  if (!newVDev.deviceIdentifier.empty())
998  params.push_back("displayname=" + ::PercentEncode(newVDev.deviceIdentifier));
999  const string queryStr(aja::join(params, "&"));
1000  if (!queryStr.empty())
1001  newVDev.vdevUrl += "?" + queryStr;
1002  outVDevList.push_back(newVDev);
1003  } // for each .vdev file found
1004  return true;
1005 #endif // else NTV2_PREVENT_PLUGIN_LOAD
1006 } // GetCP2DeviceList
#define PLWARN(__x__)
bool programmableCSCSupport
Programmable color space converter?
NTV2DeviceInfoList GetDeviceInfoList(void)
nlohmann::json json
The number of input converter widgets on the device.
virtual bool IsSupported(const NTV2BoolParamID inParamID)
True if device can handle 2Kx1556 (film) video.
static bool GetFirstDeviceWithID(const NTV2DeviceID inDeviceID, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the first AJA device found on the host t...
#define kQParamVDevIndex
Device index number for .vdev virtual device.
Definition: ntv2nubaccess.h:45
True if device supports 3D video output over dual-stream SDI.
Declares the AJALock class.
bool ipSupport
Supports IP IO?
The number of SDI-embedded input audio channels supported by the device.
True if audio system(s) support 2 or more audio channels.
bool is_legal_decimal_number(const std::string &inStr, const size_t inMaxLength)
Definition: common.cpp:526
The number of analog video outputs on the device.
UWord numAnalogAudioInputChannels
Total number of analog audio input channels.
True if device can do ISO conversion.
UWord numAnalogAudioOutputChannels
Total number of analog audio output channels.
static bool GetFirstDeviceWithSerial(const std::string &inSerialStr, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the first AJA device whose serial number...
static bool GetVirtualDeviceWithName(const std::string &inNameString, CNTV2Card &outDevice, const bool inRescan=(!(0)))
Rescans the host, and returns an open CNTV2Card instance for the first virtual device with a matching...
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:28
UWord numOutputConverters
Total number of output converters.
True if device can squeeze/stretch between 1920x1080/1280x1080 and 1280x720/960x720.
#define BIT(_x_)
Definition: ajatypes.h:578
UWord numAnlgVidInputs
Total number of analog video inputs.
True if device can do 3G level B to 3G level A conversion.
True if device supports an AJA breakout box.
#define kVDevJSON_Name
Optional name for virtual device to override .vdev file name (expects string value) ...
Definition: ntv2nubaccess.h:48
The number of analog LTC outputs on the device.
The number of AES/EBU audio output channels on the device.
Declares the AJADebug class.
NTV2AudioPhysicalFormatList::const_iterator NTV2AudioPhysicalFormatListConstIter
virtual UWord GetIndexNumber(void) const
static bool IsLegalDecimalNumber(const std::string &inStr, const size_t maxLen=2)
The number of independent Audio Systems on the device.
void setDeviceIndexNumber(const UWord num)
bool ltcInOnRefPort
Supports LTC on reference input?
#define kQParamVDevName
Device name, if not specified in .vdev file, then base name of .vdev file.
Definition: ntv2nubaccess.h:43
static AJAStatus ReadDirectory(const std::string &directory, const std::string &filePattern, std::vector< std::string > &fileContainer)
Definition: file_io.cpp:805
UWord numVidOutputs
Total number of video outputs – analog, digital, whatever.
virtual bool Close(void)
Closes me, releasing host resources that may have been allocated in a previous Open call...
std::string NTV2GetVDevFolderPath(const bool inAddTrailingPathDelim=false)
Definition: ntv2utils.cpp:7717
One-stop shop for parsing device specifications. (New in SDK 16.3) I do very little in the way of val...
virtual bool Open(const UWord inDeviceIndex)
Opens a local/physical AJA device so it can be monitored/controlled.
static bool DeviceIDPresent(const NTV2DeviceID inDeviceID, const bool inRescan=(0))
True if device has SFP connectors.
UWord numEmbeddedAudioInputChannels
Total number of embedded (SDI) audio input channels.
Definition: lock.h:28
True if device can do video processing.
bool has2KSupport
Supports 2K formats?
Definition: json.hpp:5362
True if device can handle QRez.
#define false
uint32_t ULWord
Definition: ajatypes.h:223
The number of DMA engines on the device.
UWord numHDMIAudioInputChannels
Total number of HDMI audio input channels.
ULWord pciSlot
PCI slot (if applicable and/or known)
#define kQParamVDevFolderPath
Path to folder containing .vdev files.
Definition: ntv2nubaccess.h:42
#define NTV2_ASSERT(_expr_)
Definition: ajatypes.h:476
The number of SDI video outputs on the device.
virtual bool IsRemote(void) const
NTV2AudioSampleRateList audioSampleRateList
My supported audio sample rates.
NTV2AudioSourceList audioInSourceList
My supported audio input sources (AES, ADAT, etc.)
True if device can read LTC (Linear TimeCode) from its reference input.
UWord numAnlgVidOutputs
Total number of analog video outputs.
True if device SDI connectors are bi-directional.
std::string PercentEncode(const std::string &inStr)
static AJALock sDevInfoListLock
static bool GetFirstDeviceWithName(const std::string &inNameSubString, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the first AJA device whose device identi...
UWord numDMAEngines
Total number of DMA engines.
bool ltcOutSupport
Supports LTC output?
bool proResSupport
Supports ProRes?
True if device has CSCs capable of splitting the key (alpha) and YCbCr (fill) from RGB frame buffers ...
True if device has at least one programmable color space converter widget.
True if device supports 3D video input over dual-stream SDI.
bool breakoutBoxSupport
Can support a breakout box?
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
Definition: ntv2enums.h:20
The highest bit number of the LED bits in the Global Control Register on the device.
std::vector< AudioBitsPerSampleEnum > NTV2AudioBitsPerSampleList
UWord numHDMIVidOutputs
Total number of HDMI outputs.
True if device can handle quarter-sized frames (pixel-halving and line-halving during input...
bool ltcInSupport
Accepts LTC input?
virtual bool IsOpen(void) const
CNTV2DeviceScanner(const bool inScanNow=(!(0)))
std::string to_string(bool val)
Definition: common.cpp:180
Invalid or "not found".
Definition: ntv2enums.h:98
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...
NTV2AudioChannelsPerFrameList::const_iterator NTV2AudioChannelsPerFrameListConstIter
NTV2AudioBitsPerSampleList::const_iterator NTV2AudioBitsPerSampleListConstIter
static bool GetDeviceWithSerial(const std::string &inSerialNumber, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the first AJA device whose serial number...
True if device can squeeze/stretch between 1920x1080 and 1440x1080.
bool has4KSupport
Supports 4K formats?
Declares the AJAFileIO class.
virtual bool GetSerialNumberString(std::string &outSerialNumberString)
Answers with a string that contains my human-readable serial number.
Definition: ntv2card.cpp:229
std::string serialNumber
Unique device serial number (new in SDK 17.5)
NTV2StringSet::const_iterator NTV2StringSetConstIter
Definition: ntv2utils.h:1159
std::vector< NTV2DeviceInfo > NTV2DeviceInfoList
I am an ordered list of NTV2DeviceInfo structs.
The number of up-converters on the device.
bool is_alpha_numeric(const char inChr)
Definition: common.cpp:521
AudioChannelsPerFrameEnum numChannels
static size_t GetNumDevices(void)
bool has8KSupport
Supports 8K formats?
static bool IsHexDigit(const char inChr)
bool sdi12GSupport
Supports 12G?
UWord numUpConverters
Total number of up-converters.
#define PLNOTE(__x__)
std::set< ULWord > ULWordSet
A collection of unique ULWord (uint32_t) values.
std::vector< std::string > NTV2StringList
Definition: ntv2utils.h:1155
Software device that doesn&#39;t emulate one of the above devices.
Definition: ntv2enums.h:83
NTV2DeviceInfoList::const_iterator NTV2DeviceInfoListConstIter
bool colorCorrectionSupport
Supports color correction?
#define kVDevJSON_URLSpec
URLspec for virtual device (expects string value)
Definition: ntv2nubaccess.h:49
True if device has 12G SDI connectors.
#define kQParamVDevFileName
.vdev file name (with extension)
Definition: ntv2nubaccess.h:44
UWord numAESAudioInputChannels
Total number of AES audio input channels.
static bool CompareDeviceInfoLists(const NTV2DeviceInfoList &inOldList, const NTV2DeviceInfoList &inNewList, NTV2DeviceInfoList &outDevicesAdded, NTV2DeviceInfoList &outDevicesRemoved)
True if audio system(s) support 6 or more audio channels.
virtual NTV2DeviceID GetDeviceID(void)
bool biDirectionalSDI
Supports Bi-directional SDI.
static bool GetDeviceAtIndex(const ULWord inDeviceIndexNumber, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the AJA device having the given zero-bas...
#define PLFAIL(__x__)
uint64_t is_legal_hex_serial_number(const std::string &inStr)
Definition: common.cpp:536
int stoi(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:122
std::vector< AudioChannelsPerFrameEnum > NTV2AudioChannelsPerFrameList
Declares the CNTV2DeviceScanner class.
virtual bool ReadRegister(const ULWord inRegNum, ULWord &outValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0)
Reads all or part of the 32-bit contents of a specific register (real or virtual) on the AJA device...
ULWord deviceIndex
Device index number – this will be phased out someday.
The number of HDMI video outputs on the device.
UWord numHDMIVidInputs
Total number of HDMI inputs.
ostream & operator<<(ostream &inOutStr, const NTV2DeviceInfoList &inList)
The number of SDI-embedded output audio channels supported by the device.
std::vector< AudioSampleRateEnum > NTV2AudioSampleRateList
UWord numVidInputs
Total number of video inputs – analog, digital, whatever.
std::string NTV2DeviceIDToString(const NTV2DeviceID inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:4608
bool operator==(const NTV2DeviceInfo &rhs) const
True if device supports 10-bit RGB input/output over 2-wire SDI.
std::string & strip(std::string &str, const std::string &ws)
Definition: common.cpp:461
UWord numDownConverters
Total number of down-converters.
#define kVDevJSON_Disabled
Virtual device is disabled if value is true (expects boolean value)
Definition: ntv2nubaccess.h:50
The number of analog audio output channels on the device.
NTV2AudioChannelsPerFrameList audioNumChannelsList
My supported number of audio channels per frame.
#define DEC(__x__)
static bool GetDeviceInfo(const ULWord inDeviceIndexNumber, NTV2DeviceInfo &outDeviceInfo, const bool inRescan=(0))
The number of analog LTC inputs on the device.
The number of analog video inputs on the device.
Declares numerous NTV2 utility functions.
UWord numSerialPorts
Total number of serial ports.
virtual ULWord GetNumSupported(const NTV2NumericParamID inParamID)
Declares the AJASystemInfo class.
static void ScanHardware(void)
The number of output converter widgets on the device.
True if device has any analog inputs or outputs.
True if the device can handle 4K/UHD video.
The number of RS-422 serial ports on the device.
std::string vdevName
uint16_t UWord
Definition: ajatypes.h:221
bool stereoOutSupport
Supports stereo output?
UWord numAudioStreams
Maximum number of independent audio streams.
static NTV2DeviceInfoList sDevInfoList
The number of HDMI audio input channels on the device.
static bool IsAlphaNumeric(const char inStr)
static bool IsLegalSerialNumber(const std::string &inStr)
static std::string GetDeviceRefName(CNTV2Card &inDevice)
virtual ULWordSet GetSupportedItems(const NTV2EnumsID inEnumsID)
UWord numInputConverters
Total number of input converters.
True if device has any LUTs.
AudioBitsPerSampleEnum bitsPerSample
The down-converter delay on the device.
bool dualLinkSupport
Supports dual-link?
static uint64_t IsLegalHexSerialNumber(const std::string &inStr)
std::string vdevUrl
static bool IsDecimalDigit(const char inChr)
NTV2AudioSampleRateList::const_iterator NTV2AudioSampleRateListConstIter
Private include file for all ajabase sources.
UWord numEmbeddedAudioOutputChannels
Total number of embedded (SDI) audio output channels.
The number of analog audio input channels on the device.
True if audio system(s) support 8 or more audio channels.
True if device has a microphone input connector.
std::string SerialNum64ToString(const uint64_t &inSerNum)
Definition: ntv2utils.cpp:8243
std::string & upper(std::string &str)
Definition: common.cpp:442
std::string join(const std::vector< std::string > &parts, const std::string &delim)
Definition: common.cpp:468
bool stereoInSupport
Supports stereo input?
bool rgbAlphaOutputSupport
Supports RGB alpha channel?
UWord numHDMIAudioOutputChannels
Total number of HDMI audio output channels.
NTV2AudioBitsPerSampleList audioBitsPerSampleList
My supported audio bits-per-sample.
NTV2DeviceID deviceID
Device ID/species (e.g., DEVICE_ID_KONA3G, DEVICE_ID_IOXT, etc.)
std::vector< NTV2AudioPhysicalFormat > NTV2AudioPhysicalFormatList
I am an ordered list of NTV2AudioPhysicalFormat structs.
std::string & lower(std::string &str)
Definition: common.cpp:436
#define DECN(__x__, __n__)
Identifies the NTV2AudioWidgetID enumerated type.
std::vector< AudioSourceEnum > NTV2AudioSourceList
#define PLDBUG(__x__)
True if device supports 8K video formats.
bool has3GLevelConversion
Supports 3G Level Conversion?
The number of HDMI audio output channels on the device.
The number of SDI video inputs on the device.
bool multiFormat
Supports multiple video formats?
AudioSampleRateEnum sampleRate
True if device can can accommodate Apple ProRes-compressed video in its frame buffers.
virtual std::string GetHostName(void) const
NTV2AudioSourceList::const_iterator NTV2AudioSourceListConstIter
Declares device capability functions.
NTV2AudioSourceList audioOutSourceList
My supported audio output destinations (AES, etc.)
The number of AES/EBU audio input channels on the device.
std::set< std::string > NTV2StringSet
Definition: ntv2utils.h:1158
The number of down-converters on the device.
UWord numAESAudioOutputChannels
Total number of AES audio output channels.
True if Audio System(s) support a 96kHz sample rate.
bool sdi3GSupport
Supports 3G?
std::string deviceIdentifier
Device name as seen in Control Panel, Watcher, Cables, etc.
True if device can do frame rate conversion.
The number of HDMI video inputs on the device.
True if device can simultaneously handle different video formats on more than one SDI input or output...