AJA NTV2 SDK  18.1.0.2262
NTV2 SDK 18.1.0.2262
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 VDFAIL(__x__) AJA_sERROR (AJA_DebugUnit_VDev, AJAFUNC << ": " << __x__)
25 #define VDWARN(__x__) AJA_sWARNING(AJA_DebugUnit_VDev, AJAFUNC << ": " << __x__)
26 #define VDNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_VDev, AJAFUNC << ": " << __x__)
27 #define VDINFO(__x__) AJA_sINFO (AJA_DebugUnit_VDev, AJAFUNC << ": " << __x__)
28 #define VDDBUG(__x__) AJA_sDEBUG (AJA_DebugUnit_VDev, AJAFUNC << ": " << __x__)
29 
30 #define C2FAIL(__x__) AJA_sERROR (AJA_DebugUnit_CP2, AJAFUNC << ": " << __x__)
31 #define C2WARN(__x__) AJA_sWARNING(AJA_DebugUnit_CP2, AJAFUNC << ": " << __x__)
32 #define C2NOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_CP2, AJAFUNC << ": " << __x__)
33 #define C2INFO(__x__) AJA_sINFO (AJA_DebugUnit_CP2, AJAFUNC << ": " << __x__)
34 #define C2DBUG(__x__) AJA_sDEBUG (AJA_DebugUnit_CP2, AJAFUNC << ": " << __x__)
35 
36 
37 #if !defined(NTV2_DEPRECATE_17_1)
38  bool CNTV2DeviceScanner::IsHexDigit (const char inChr)
39  { static const string sHexDigits("0123456789ABCDEFabcdef");
40  return sHexDigits.find(inChr) != string::npos;
41  }
42 
43  bool CNTV2DeviceScanner::IsDecimalDigit (const char inChr)
44  { static const string sDecDigits("0123456789");
45  return sDecDigits.find(inChr) != string::npos;
46  }
47 
48  bool CNTV2DeviceScanner::IsAlphaNumeric (const char inChr)
49  { static const string sLegalChars("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
50  return sLegalChars.find(inChr) != string::npos;
51  }
52 
53  bool CNTV2DeviceScanner::IsLegalDecimalNumber (const string & inStr, const size_t inMaxLength)
54  {
55  return aja::is_legal_decimal_number(inStr, inMaxLength);
56  }
57 
58  uint64_t CNTV2DeviceScanner::IsLegalHexSerialNumber (const string & inStr) // 0x3236333331375458
59  {
60  return aja::is_legal_hex_serial_number(inStr);
61  }
62 
63  bool CNTV2DeviceScanner::IsAlphaNumeric (const string & inStr)
64  {
65  for (size_t ndx(0); ndx < inStr.size(); ndx++)
66  if (!aja::is_alpha_numeric(inStr.at(ndx)))
67  return false;
68  return true;
69  }
70 #endif // !defined(NTV2_DEPRECATE_17_1)
71 
72 bool CNTV2DeviceScanner::IsLegalSerialNumber (const string & inStr)
73 {
74  if (inStr.length() != 8 && inStr.length() != 9)
75  return false;
76  return aja::is_alpha_numeric(inStr);
77 }
78 
81 
83 {
84  AJAAutoLock tmpLock(&sDevInfoListLock);
85  return sDevInfoList.size();
86 }
87 
89 {
90  if (inScanNow)
91  ScanHardware();
92 }
93 
94  #if !defined(NTV2_DEPRECATE_16_3)
95  CNTV2DeviceScanner::CNTV2DeviceScanner (bool inScanNow, UWord inDeviceMask)
96  {
97  (void)inDeviceMask;
98  if (inScanNow)
99  ScanHardware();
100  }
101  #endif // !defined(NTV2_DEPRECATE_16_3)
102 
104 {
105  AJAAutoLock tmpLock(&sDevInfoListLock);
106  return sDevInfoList;
107 }
108 
109 
111 {
112  AJAAutoLock tmpLock(&sDevInfoListLock);
113  sDevInfoList.clear();
114 
115  for (UWord boardNum(0); ; boardNum++)
116  {
117  CNTV2Card tmpDev(boardNum);
118  if (!tmpDev.IsOpen())
119  break;
120  const NTV2DeviceID deviceID (tmpDev.GetDeviceID());
121 
122  if (deviceID != DEVICE_ID_NOTFOUND)
123  {
124  ostringstream oss;
125  NTV2DeviceInfo info;
126  info.deviceIndex = boardNum;
127  info.deviceID = deviceID;
128  tmpDev.GetSerialNumberString(info.serialNumber);
129 
130  oss << ::NTV2DeviceIDToString (deviceID, tmpDev.IsSupported(kDeviceHasMicrophoneInput)) << " - " << boardNum;
131 
132  info.deviceIdentifier = oss.str();
133  SetDeviceAttributes(info, tmpDev);
134  SetAudioAttributes(info, tmpDev);
135  sDevInfoList.push_back(info);
136  }
137  tmpDev.Close();
138  } // boardNum loop
139 
140  GetVDevList(sDevInfoList); // For VKONA support
141  GetCP2DevList(sDevInfoList); // For CP2 support
142 } // ScanHardware
143 
144 bool CNTV2DeviceScanner::DeviceIDPresent (const NTV2DeviceID inDeviceID, const bool inRescan)
145 {
146  AJAAutoLock tmpLock(&sDevInfoListLock);
147  if (inRescan)
148  ScanHardware();
149 
150  for (NTV2DeviceInfoListConstIter iter(sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
151  if (iter->deviceID == inDeviceID)
152  return true; // Found!
153  return false; // Not found
154 
155 } // DeviceIDPresent
156 
157 
158 bool CNTV2DeviceScanner::GetDeviceInfo (const ULWord inDeviceIndexNumber, NTV2DeviceInfo & outDeviceInfo, const bool inRescan)
159 {
160  AJAAutoLock tmpLock(&sDevInfoListLock);
161  if (inRescan)
162  ScanHardware();
163 
164  for (NTV2DeviceInfoListConstIter iter(sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
165  if (iter->deviceIndex == inDeviceIndexNumber)
166  {
167  outDeviceInfo = *iter;
168  return true; // Found!
169  }
170  return false; // No devices with this index number
171 
172 } // GetDeviceInfo
173 
174 bool CNTV2DeviceScanner::GetDeviceAtIndex (const ULWord inDeviceIndexNumber, CNTV2Card & outDevice)
175 {
176  outDevice.Close();
177  AJAAutoLock tmpLock(&sDevInfoListLock);
178  ScanHardware();
179  for (NTV2DeviceInfoListConstIter iter(sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
180  if (iter->deviceIndex == inDeviceIndexNumber)
181  {
182  if (iter->isVirtualDevice)
183  return outDevice.Open(iter->vdevUrl);
184  else
185  return outDevice.Open(UWord(inDeviceIndexNumber));
186  }
187  return false; // No devices with this index number
188 
189 } // GetDeviceAtIndex
190 
191 
193 {
194  outDevice.Close();
195  AJAAutoLock tmpLock(&sDevInfoListLock);
196  ScanHardware();
197  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
198  if (sDevInfoList.at(ndx).deviceID == inDeviceID)
199  {
200  if (sDevInfoList.at(ndx).isVirtualDevice)
201  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
202  else
203  return outDevice.Open(UWord(ndx));
204  }
205  return false; // Not found
206 
207 } // GetFirstDeviceWithID
208 
209 
210 bool CNTV2DeviceScanner::GetFirstDeviceWithName (const string & inNameSubString, CNTV2Card & outDevice)
211 {
212  outDevice.Close();
213  AJAAutoLock tmpLock(&sDevInfoListLock);
214  ScanHardware();
215  string nameSubString(inNameSubString); aja::lower(nameSubString);
216  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
217  {
218  string deviceName(sDevInfoList.at(ndx).deviceIdentifier); aja::lower(deviceName);
219  if (deviceName.find(nameSubString) != string::npos)
220  {
221  if (sDevInfoList.at(ndx).isVirtualDevice)
222  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
223  else
224  return outDevice.Open(UWord(ndx));
225  }
226  }
227  if (nameSubString == "io4kplus")
228  { // Io4K+ == DNXIV...
229  nameSubString = "avid dnxiv";
230  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
231  {
232  string deviceName(sDevInfoList.at(ndx).deviceIdentifier); aja::lower(deviceName);
233  if (deviceName.find(nameSubString) != string::npos)
234  {
235  if (sDevInfoList.at(ndx).isVirtualDevice)
236  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
237  else
238  return outDevice.Open(UWord(ndx));
239  }
240  }
241  }
242  return false; // Not found
243 
244 } // GetFirstDeviceWithName
245 
246 bool CNTV2DeviceScanner::GetVirtualDeviceWithName (const string & inNameString, CNTV2Card & outDevice, const bool inRescan)
247 {
248  outDevice.Close();
249  AJAAutoLock tmpLock(&sDevInfoListLock);
250  if (inRescan)
251  ScanHardware();
252  string nameString(inNameString); aja::lower(nameString);
253  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
254  {
255  if (!sDevInfoList.at(ndx).isVirtualDevice)
256  continue;
257  string deviceName(sDevInfoList.at(ndx).vdevName); aja::lower(deviceName);
258  if (deviceName == nameString)
259  {
260  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
261  }
262  }
263  return false; // Not found
264 }
265 
266 bool CNTV2DeviceScanner::GetFirstDeviceWithSerial (const string & inSerialStr, CNTV2Card & outDevice)
267 {
268  outDevice.Close();
269  AJAAutoLock tmpLock(&sDevInfoListLock);
270  ScanHardware();
271  string searchSerialStr(inSerialStr); aja::lower(searchSerialStr);
272  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
273  {
274  string ser(sDevInfoList.at(ndx).serialNumber); aja::lower(ser);
275  if (ser.find(searchSerialStr) != string::npos)
276  {
277  if (sDevInfoList.at(ndx).isVirtualDevice)
278  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
279  else
280  return outDevice.Open(UWord(ndx));
281  }
282  }
283  return false;
284 }
285 
286 
287 #if !defined(NTV2_DEPRECATE_17_5)
288 bool CNTV2DeviceScanner::GetDeviceWithSerial (const uint64_t inSerialNumber, CNTV2Card & outDevice)
289 {
290  const string serNumStr(::SerialNum64ToString(inSerialNumber));
291  return GetDeviceWithSerial(serNumStr, outDevice);
292 }
293 #endif // !defined(NTV2_DEPRECATE_17_5)
294 
295 bool CNTV2DeviceScanner::GetDeviceWithSerial (const string & inSerialNumber, CNTV2Card & outDevice)
296 {
297  outDevice.Close();
298  AJAAutoLock tmpLock(&sDevInfoListLock);
299  ScanHardware();
300  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
301  if (sDevInfoList.at(ndx).serialNumber == inSerialNumber)
302  {
303  if (sDevInfoList.at(ndx).isVirtualDevice)
304  return outDevice.Open(sDevInfoList.at(ndx).vdevUrl);
305  else
306  return outDevice.Open(UWord(ndx));
307  }
308  return false;
309 }
310 
311 
312 bool CNTV2DeviceScanner::GetFirstDeviceFromArgument (const string & inArgument, CNTV2Card & outDevice)
313 {
314  outDevice.Close();
315  if (inArgument.empty())
316  return false;
317 
318  // Special case: 'LIST' or '?' --- print an enumeration of available devices to stdout, then bail
319  AJAAutoLock tmpLock(&sDevInfoListLock);
320  ScanHardware();
321  string upperArg(inArgument); aja::upper(upperArg);
322  if (upperArg == "LIST" || upperArg == "?")
323  {
324  if (sDevInfoList.empty())
325  cout << "No devices detected" << endl;
326  else
327  cout << DEC(sDevInfoList.size()) << " available " << (sDevInfoList.size() == 1 ? "device:" : "devices:") << endl;
328  for (size_t ndx(0); ndx < sDevInfoList.size(); ndx++)
329  {
330  if (sDevInfoList.at(ndx).isVirtualDevice)
331  {
332  cout << DECN(ndx, 2) << " | " << setw(8) << "virtual";
333  if (!sDevInfoList.at(ndx).vdevName.empty())
334  cout << " | " << setw(10) << sDevInfoList.at(ndx).vdevName;
335  cout << " | " << sDevInfoList.at(ndx).vdevUrl << endl;
336  }
337  else
338  {
339  cout << DECN(ndx, 2) << " | " << setw(8) << "local";
340  const string serNum(sDevInfoList.at(ndx).serialNumber);
341  if (!serNum.empty())
342  cout << " | " << setw(10) << serNum;
343  cout << " | " << setw(16) << ::NTV2DeviceIDToString(sDevInfoList.at(ndx).deviceID);
344  cout << endl;
345  }
346  }
347  return false;
348  }
349 
350  for (NTV2DeviceInfoListConstIter iter (sDevInfoList.begin()); iter != sDevInfoList.end(); ++iter)
351  {
352  if (iter->isVirtualDevice)
353  { bool ok (false);
354  if (to_string(iter->deviceIndex) == inArgument
355  || iter->deviceIdentifier == inArgument
356  || iter->vdevName == inArgument
357  || (aja::is_legal_decimal_number(inArgument, inArgument.length())
358  && aja::is_legal_hex_serial_number(inArgument)
359  && iter->deviceID == NTV2DeviceID(stoi(inArgument))))
360  {
361  ok = outDevice.Open(iter->vdevUrl);
362  if (ok)
363  outDevice.setDeviceIndexNumber(UWord(iter->deviceIndex)); // Patch _boardNumber
364  return ok;
365  }
366  else if (IsLegalSerialNumber(inArgument))
367  return outDevice.Open(inArgument);
368  else if (inArgument.find("://") != string::npos)
369  return outDevice.Open(inArgument);
370  }
371  else
372  {
373  if (to_string(iter->deviceIndex) == inArgument)
374  return outDevice.Open(inArgument);
375  else if (iter->deviceIdentifier == inArgument)
376  return outDevice.Open(inArgument);
377  else if (aja::is_legal_decimal_number(inArgument, inArgument.length()) && aja::is_legal_hex_serial_number(inArgument) && iter->deviceID == NTV2DeviceID(stoi(inArgument)))
378  return outDevice.Open(inArgument);
379  else if (IsLegalSerialNumber(inArgument))
380  return outDevice.Open(inArgument);
381  else if (inArgument.find("://") != string::npos)
382  return outDevice.Open(inArgument);
383  }
384  }
385  return outDevice.Open(inArgument);
386 } // GetFirstDeviceFromArgument
387 
388 
390 { // Name that will find given device via CNTV2DeviceScanner::GetFirstDeviceFromArgument
391  if (!inDevice.IsOpen())
392  return string();
393  // Nub address 1st...
394  if (!inDevice.GetHostName().empty() && inDevice.IsRemote())
395  return inDevice.GetHostName(); // Nub host/device
396 
397  // Serial number 2nd...
398  string str;
399  if (inDevice.GetSerialNumberString(str))
400  return str;
401 
402  // Model name 3rd...
403  str = ::NTV2DeviceIDToString(inDevice.GetDeviceID(), false);
404  if (!str.empty() && str != "???")
405  return str;
406 
407  // Index number last...
408  ostringstream oss; oss << DEC(inDevice.GetIndexNumber());
409  return oss.str();
410 }
411 
412 
413 ostream & operator << (ostream & inOutStr, const NTV2DeviceInfoList & inList)
414 {
415  for (NTV2DeviceInfoListConstIter iter(inList.begin()); iter != inList.end(); ++iter)
416  inOutStr << " " << *iter;
417  return inOutStr;
418 
419 } // NTV2DeviceInfoList ostream operator <<
420 
421 
423 {
424  const NTV2DeviceInfo & first (*this);
425  size_t diffs (0);
426 
427  // 'memcmp' would be simpler, but because NTV2DeviceInfo has no constructor, the unfilled bytes in
428  // its "boardIdentifier" field are indeterminate, making it worthless for accurate comparisons.
429  // "boardSerialNumber" and boardNumber are the only required comparisons, but I also check boardType,
430  // boardID, and pciSlot for good measure...
431  if (first.deviceID != second.deviceID) diffs++;
432  if (first.deviceIndex != second.deviceIndex) diffs++;
433  if (first.serialNumber != second.serialNumber) diffs++;
434  if (first.pciSlot != second.pciSlot) diffs++;
435 
436  // Needs to be fixed now that deviceIdentifier is a std::string
437  //#if defined (AJA_DEBUG)
438  // if (::strncmp (first.deviceIdentifier.c_str (), second.deviceIdentifier.c_str (), first.deviceIdentifier.length ()))) diffs++;
439  // if (diffs)
440  // {cout << "## DEBUG: " << diffs << " diff(s):" << endl << "#### first ####" << endl << first << "#### second ####" << endl << second << endl;}
441  //#endif // AJA_DEBUG
442 
443  return diffs ? false : true;
444 
445 } // equality operator
446 
448 {
449  deviceID = DEVICE_ID_INVALID;
450  deviceIndex = 0;
451  pciSlot = 0;
452  deviceSerialNumber = 0;
453  serialNumber = "";
454  numVidInputs = 0;
455  numVidOutputs = 0;
456  numAnlgVidInputs = 0;
457  numAnlgVidOutputs = 0;
458  numHDMIVidInputs = 0;
459  numHDMIVidOutputs = 0;
460  numInputConverters = 0;
461  numOutputConverters = 0;
462  numUpConverters = 0;
463  numDownConverters = 0;
464  downConverterDelay = 0;
465  isoConvertSupport = false;
466  rateConvertSupport = false;
467  dvcproHDSupport = false;
468  qrezSupport = false;
469  hdvSupport = false;
470  quarterExpandSupport = false;
471  vidProcSupport = false;
472  dualLinkSupport = false;
473  colorCorrectionSupport = false;
474  programmableCSCSupport = false;
475  rgbAlphaOutputSupport = false;
476  breakoutBoxSupport = false;
477  procAmpSupport = false;
478  has2KSupport = false;
479  has4KSupport = false;
480  has8KSupport = false;
481  has3GLevelConversion = false;
482  proResSupport = false;
483  sdi3GSupport = false;
484  sdi12GSupport = false;
485  ipSupport = false;
486  biDirectionalSDI = false;
487  ltcInSupport = false;
488  ltcOutSupport = false;
489  ltcInOnRefPort = false;
490  stereoOutSupport = false;
491  stereoInSupport = false;
492  multiFormat = false;
493  numAudioStreams = 0;
494  numAnalogAudioInputChannels = 0;
495  numAESAudioInputChannels = 0;
496  numEmbeddedAudioInputChannels = 0;
497  numHDMIAudioInputChannels = 0;
498  numAnalogAudioOutputChannels = 0;
499  numAESAudioOutputChannels = 0;
500  numEmbeddedAudioOutputChannels = 0;
501  numHDMIAudioOutputChannels = 0;
502  numDMAEngines = 0;
503  numSerialPorts = 0;
504  pingLED = 0;
505  deviceIdentifier.clear();
506  audioSampleRateList.clear();
507  audioNumChannelsList.clear();
508  audioBitsPerSampleList.clear();
509  audioInSourceList.clear();
510  audioOutSourceList.clear();
511 }
512 
514 {
515  if (&info != this)
516  *this = info;
517 }
518 
519 
521  const NTV2DeviceInfoList & inNewList,
522  NTV2DeviceInfoList & outBoardsAdded,
523  NTV2DeviceInfoList & outBoardsRemoved)
524 {
525  NTV2DeviceInfoListConstIter oldIter (inOldList.begin ());
526  NTV2DeviceInfoListConstIter newIter (inNewList.begin ());
527 
528  outBoardsAdded.clear ();
529  outBoardsRemoved.clear ();
530 
531  while (true)
532  {
533  if (oldIter == inOldList.end () && newIter == inNewList.end ())
534  break; // Done -- exit
535 
536  if (oldIter != inOldList.end () && newIter != inNewList.end ())
537  {
538  const NTV2DeviceInfo & oldInfo (*oldIter), newInfo (*newIter);
539 
540  if (oldInfo != newInfo)
541  {
542  // Out with the old...
543  outBoardsRemoved.push_back (oldInfo);
544 
545  // In with the new...
546  if (newInfo.deviceID && newInfo.deviceID != NTV2DeviceID(0xFFFFFFFF))
547  outBoardsAdded.push_back (newInfo);
548  } // if mismatch
549 
550  ++oldIter;
551  ++newIter;
552  continue; // Move along
553 
554  } // if both valid
555 
556  if (oldIter != inOldList.end () && newIter == inNewList.end ())
557  {
558  outBoardsRemoved.push_back (*oldIter);
559  ++oldIter;
560  continue; // Move along
561  } // old is valid, new is not valid
562 
563  if (oldIter == inOldList.end () && newIter != inNewList.end ())
564  {
565  if (newIter->deviceID && newIter->deviceID != NTV2DeviceID(0xFFFFFFFF))
566  outBoardsAdded.push_back (*newIter);
567  ++newIter;
568  continue; // Move along
569  } // old is not valid, new is valid
570 
571  NTV2_ASSERT(false && "should never get here");
572 
573  } // loop til break
574 
575  // Return 'true' if there were any changes...
576  return !outBoardsAdded.empty () || !outBoardsRemoved.empty ();
577 
578 } // CompareDeviceInfoLists
579 
580 
581 ostream & operator << (ostream & inOutStr, const NTV2AudioSampleRateList & inList)
582 {
583  for (NTV2AudioSampleRateListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
584  inOutStr << " " << *iter;
585 
586  return inOutStr;
587 }
588 
589 
590 ostream & operator << (ostream & inOutStr, const NTV2AudioChannelsPerFrameList & inList)
591 {
592  for (NTV2AudioChannelsPerFrameListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
593  inOutStr << " " << *iter;
594 
595  return inOutStr;
596 }
597 
598 
599 ostream & operator << (ostream & inOutStr, const NTV2AudioSourceList & inList)
600 {
601  for (NTV2AudioSourceListConstIter iter(inList.begin()); iter != inList.end(); ++iter)
602  switch (*iter) // AudioSourceEnum
603  {
604  case kSourceSDI: return inOutStr << " SDI";
605  case kSourceAES: return inOutStr << " AES";
606  case kSourceADAT: return inOutStr << " ADAT";
607  case kSourceAnalog: return inOutStr << " Analog";
608  case kSourceNone: return inOutStr << " None";
609  case kSourceAll: return inOutStr << " All";
610  }
611  return inOutStr << " ???";
612 }
613 
614 
615 ostream & operator << (ostream & inOutStr, const NTV2AudioBitsPerSampleList & inList)
616 {
617  for (NTV2AudioBitsPerSampleListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
618  inOutStr << " " << *iter;
619 
620  return inOutStr;
621 }
622 
623 
624 ostream & operator << (ostream & inOutStr, const NTV2DeviceInfo & inInfo)
625 {
626  inOutStr << "Device Info for '" << inInfo.deviceIdentifier << "'" << endl
627  << " Device Index Number: " << inInfo.deviceIndex << endl
628  << " Device ID: 0x" << hex << inInfo.deviceID << dec << endl
629  << " Serial Number: " << inInfo.serialNumber << endl
630  << " PCI Slot: 0x" << hex << inInfo.pciSlot << dec << endl
631  << " Video Inputs: " << inInfo.numVidInputs << endl
632  << " Video Outputs: " << inInfo.numVidOutputs << endl
633  #if defined (_DEBUG)
634  << " Analog Video Inputs: " << inInfo.numAnlgVidInputs << endl
635  << " Analog Video Outputs: " << inInfo.numAnlgVidOutputs << endl
636  << " HDMI Video Inputs: " << inInfo.numHDMIVidInputs << endl
637  << " HDMI Video Outputs: " << inInfo.numHDMIVidOutputs << endl
638  << " Input Converters: " << inInfo.numInputConverters << endl
639  << " Output Converters: " << inInfo.numOutputConverters << endl
640  << " Up Converters: " << inInfo.numUpConverters << endl
641  << " Down Converters: " << inInfo.numDownConverters << endl
642  << " Down Converter Delay: " << inInfo.downConverterDelay << endl
643  << " DVCProHD: " << (inInfo.dvcproHDSupport ? "Y" : "N") << endl
644  << " Qrez: " << (inInfo.qrezSupport ? "Y" : "N") << endl
645  << " HDV: " << (inInfo.hdvSupport ? "Y" : "N") << endl
646  << " Quarter Expand: " << (inInfo.quarterExpandSupport ? "Y" : "N") << endl
647  << " ISO Convert: " << (inInfo.isoConvertSupport ? "Y" : "N") << endl
648  << " Rate Convert: " << (inInfo.rateConvertSupport ? "Y" : "N") << endl
649  << " VidProc: " << (inInfo.vidProcSupport ? "Y" : "N") << endl
650  << " Dual-Link: " << (inInfo.dualLinkSupport ? "Y" : "N") << endl
651  << " Color-Correction: " << (inInfo.colorCorrectionSupport ? "Y" : "N") << endl
652  << " Programmable CSC: " << (inInfo.programmableCSCSupport ? "Y" : "N") << endl
653  << " RGB Alpha Output: " << (inInfo.rgbAlphaOutputSupport ? "Y" : "N") << endl
654  << " Breakout Box: " << (inInfo.breakoutBoxSupport ? "Y" : "N") << endl
655  << " ProcAmp: " << (inInfo.procAmpSupport ? "Y" : "N") << endl
656  << " 2K: " << (inInfo.has2KSupport ? "Y" : "N") << endl
657  << " 4K: " << (inInfo.has4KSupport ? "Y" : "N") << endl
658  << " 8K: " << (inInfo.has8KSupport ? "Y" : "N") << endl
659  << " 3G Level Conversion: " << (inInfo.has3GLevelConversion ? "Y" : "N") << endl
660  << " ProRes: " << (inInfo.proResSupport ? "Y" : "N") << endl
661  << " SDI 3G: " << (inInfo.sdi3GSupport ? "Y" : "N") << endl
662  << " SDI 12G: " << (inInfo.sdi12GSupport ? "Y" : "N") << endl
663  << " IP: " << (inInfo.ipSupport ? "Y" : "N") << endl
664  << " SDI Bi-Directional: " << (inInfo.biDirectionalSDI ? "Y" : "N") << endl
665  << " LTC In: " << (inInfo.ltcInSupport ? "Y" : "N") << endl
666  << " LTC Out: " << (inInfo.ltcOutSupport ? "Y" : "N") << endl
667  << " LTC In on Ref Port: " << (inInfo.ltcInOnRefPort ? "Y" : "N") << endl
668  << " Stereo Out: " << (inInfo.stereoOutSupport ? "Y" : "N") << endl
669  << " Stereo In: " << (inInfo.stereoInSupport ? "Y" : "N") << endl
670  << " Audio Sample Rates: " << inInfo.audioSampleRateList << endl
671  << " AudioNumChannelsList: " << inInfo.audioNumChannelsList << endl
672  << " AudioBitsPerSampleList: " << inInfo.audioBitsPerSampleList << endl
673  << " AudioInSourceList: " << inInfo.audioInSourceList << endl
674  << " AudioOutSourceList: " << inInfo.audioOutSourceList << endl
675  << " Audio Streams: " << inInfo.numAudioStreams << endl
676  << " Analog Audio Input Channels: " << inInfo.numAnalogAudioInputChannels << endl
677  << " Analog Audio Output Channels: " << inInfo.numAnalogAudioOutputChannels << endl
678  << " AES Audio Input Channels: " << inInfo.numAESAudioInputChannels << endl
679  << " AES Audio Output Channels: " << inInfo.numAESAudioOutputChannels << endl
680  << " Embedded Audio Input Channels: " << inInfo.numEmbeddedAudioInputChannels << endl
681  << " Embedded Audio Output Channels: " << inInfo.numEmbeddedAudioOutputChannels << endl
682  << " HDMI Audio Input Channels: " << inInfo.numHDMIAudioInputChannels << endl
683  << " HDMI Audio Output Channels: " << inInfo.numHDMIAudioOutputChannels << endl
684  << " DMA Engines: " << inInfo.numDMAEngines << endl
685  << " Serial Ports: " << inInfo.numSerialPorts << endl
686  #endif // AJA_DEBUG
687  << "";
688 
689  return inOutStr;
690 
691 } // NTV2DeviceInfo ostream operator <<
692 
693 
694 ostream & operator << (ostream & inOutStr, const NTV2AudioPhysicalFormat & inFormat)
695 {
696  inOutStr << "AudioPhysicalFormat:" << endl
697  << " boardNumber: " << inFormat.boardNumber << endl
698  << " sampleRate: " << inFormat.sampleRate << endl
699  << " numChannels: " << inFormat.numChannels << endl
700  << " bitsPerSample: " << inFormat.bitsPerSample << endl
701  #if defined (DEBUG) || defined (AJA_DEBUG)
702  << " sourceIn: 0x" << hex << inFormat.sourceIn << dec << endl
703  << " sourceOut: 0x" << hex << inFormat.sourceOut << dec << endl
704  #endif // DEBUG or AJA_DEBUG
705  ;
706 
707  return inOutStr;
708 
709 } // AudioPhysicalFormat ostream operator <<
710 
711 
712 std::ostream & operator << (std::ostream & inOutStr, const NTV2AudioPhysicalFormatList & inList)
713 {
714  for (NTV2AudioPhysicalFormatListConstIter iter (inList.begin ()); iter != inList.end (); ++iter)
715  inOutStr << *iter;
716 
717  return inOutStr;
718 
719 } // AudioPhysicalFormatList ostream operator <<
720 
721 
722 // Private methods
723 
724 void CNTV2DeviceScanner::SetDeviceAttributes (NTV2DeviceInfo & devInfo, CNTV2DriverInterface & dev)
725 {
740  devInfo.hdvSupport = dev.IsSupported(kDeviceCanDoHDV);
757  devInfo.sdi3GSupport = wgtIDs.find(NTV2_Wgt3GSDIOut1) != wgtIDs.end();
759  devInfo.ipSupport = dev.IsSupported(kDeviceCanDoIP);
768  devInfo.procAmpSupport = false;
769 }
770 
771 void CNTV2DeviceScanner::SetAudioAttributes (NTV2DeviceInfo & info, CNTV2DriverInterface & dev)
772 {
773  // Start with empty lists...
774  info.audioSampleRateList.clear();
775  info.audioNumChannelsList.clear();
776  info.audioBitsPerSampleList.clear();
777  info.audioInSourceList.clear();
778  info.audioOutSourceList.clear();
779 
780 
782  {
783  ULWord audioControl;
784  dev.ReadRegister(kRegAud1Control, audioControl);
785 
786  //audioSampleRateList
787  info.audioSampleRateList.push_back(k48KHzSampleRate);
789  info.audioSampleRateList.push_back(k96KHzSampleRate);
790 
791  //audioBitsPerSampleList
793 
794  //audioInSourceList
795  info.audioInSourceList.push_back(kSourceSDI);
796  if (audioControl & BIT(21))
797  info.audioInSourceList.push_back(kSourceAES);
799  info.audioInSourceList.push_back(kSourceAnalog);
800 
801  //audioOutSourceList
802  info.audioOutSourceList.push_back(kSourceAll);
803 
804  //audioNumChannelsList
811 
813  }
814 
823 
824 } // SetAudioAttributes
825 
826 // Back door access to sDevInfoList
827 bool CNTV2DeviceScanner::PatchDeviceInfo (const UWord inDevIndex, CNTV2DriverInterface & dev) // STATIC
828 {
829  AJAAutoLock tmpLock(&sDevInfoListLock);
830  if (inDevIndex >= UWord(sDevInfoList.size()))
831  return false; // Bad index
832  if (!dev.IsOpen())
833  return false; // No device instance
834 
835  NTV2DeviceInfo & devInfo (sDevInfoList.at(inDevIndex));
836  NTV2DeviceID devID (dev.GetDeviceID());
837  if (!devID)
838  return false; // Bad device ID
839  if (devID == DEVICE_ID_INVALID)
840  return false; // Bad device ID
841 
842  if (devInfo.deviceID == devID)
843  return true; // Matching device IDs
844 
845  // Mismatched device IDs -- patch sDevInfoList entry...
846  VDNOTE(dev.GetDescription() << ": patched sDevInfoList[" << DEC(inDevIndex) << "]: device ID changed from '"
847  << ::NTV2DeviceIDToString(devInfo.deviceID) << "' to '"
848  << ::NTV2DeviceIDToString(devID) << "'");
849  devInfo.deviceID = devID;
850  SetDeviceAttributes (devInfo, dev);
851  SetAudioAttributes (devInfo, dev);
852  return true;
853 }
854 
855 bool CNTV2DeviceScanner::GetVDevList (NTV2DeviceInfoList & outVDevList)
856 {
857 #if defined(NTV2_PREVENT_PLUGIN_LOAD)
858  return false; // Plugin loading disabled, therefore no virtual devices
859 #else // else NTV2_PREVENT_PLUGIN_LOAD
860  string vdevPath (::NTV2GetVDevFolderPath());
861  if (vdevPath.empty())
862  return false;
863  ULWord vdIndex (ULWord(outVDevList.size()));
864  NTV2StringList vdevFiles;
865  AJAFileIO::ReadDirectory(vdevPath, "*.vdev", vdevFiles);
866  for (const auto & vdevFile : vdevFiles)
867  {
868  VDDBUG(vdevFile);
869  json vdevJson;
870  {
871  std::ifstream vf(vdevFile);
872  if (!vf.is_open())
873  {VDFAIL("Unable to open '" << vdevFile << "'"); return false;}
874  try
875  {
876  vdevJson = json::parse(vf);
877  }
878  catch (const json::parse_error& e)
879  {
880  VDFAIL("Invalid JSON at byte " << e.byte << " in '" << vdevFile << "': " << e.what() << ", exceptionID " << e.id);
881  return false;
882  }
883  }
884 
885  NTV2DeviceInfo newVDev;
886  newVDev.isVirtualDevice = true;
887  newVDev.deviceIndex = vdIndex;
888  newVDev.deviceID = DEVICE_ID_SOFTWARE;
889  newVDev.deviceIdentifier = "";
890  newVDev.vdevName = "";
891  bool explicitlyDisabled(false);
892 
893  // EXPECTED JSON KEYS:
894  // "urlspec" [required] Specifies urlspec used to load the plugin.
895  // "name" [optional] Specifies a human-readable name for the device.
896  // If not specified, the .vdev file's base name is used instead.
897  // "disabled" [optional] Specify boolean 'true' to explicitly disable the device; 'false' retains device.
898  // If not specified, the device will always be considered enabled.
899  if (vdevJson.size() > 32)
900  {VDFAIL("File '" << vdevFile << "': more than 32 keys"); continue;}
901  NTV2StringSet keys;
902  for (auto it(vdevJson.cbegin()); it != vdevJson.cend(); ++it)
903  if (keys.find(it.key()) == keys.end())
904  keys.insert(it.key());
906  NTV2StringList goodKeys, badKeys;
907  for (NTV2StringSetConstIter itKey(keys.begin()); itKey != keys.end(); ++itKey)
908  {
909  if (legalKeys.find(*itKey) == legalKeys.end())
910  badKeys.push_back(*itKey);
911  else
912  goodKeys.push_back(*itKey);
913  }
914  if (!badKeys.empty())
915  VDWARN("File '" << vdevFile << "': ignored " << DEC(badKeys.size()) << " unknown key(s): '" << aja::join(badKeys, "', '") << "'");
916  auto nameVal (vdevJson[kVDevJSON_Name]), urlspecVal (vdevJson[kVDevJSON_URLSpec]), disabledVal (vdevJson[kVDevJSON_Disabled]);
917  if (urlspecVal.is_null())
918  {VDFAIL("File '" << vdevFile << "': missing required 'urlspec' parameter"); continue;}
919  if (disabledVal.is_boolean())
920  {
921  NTV2_ASSERT(!disabledVal.is_null());
922  explicitlyDisabled = disabledVal.get<bool>();
923  }
924  else if (!disabledVal.is_null())
925  {VDFAIL("File '" << vdevFile << "': invalid 'disabled' value -- expected boolean 'true' or 'false' value"); continue;}
926  if (explicitlyDisabled)
927  {VDINFO("File '" << vdevFile << "': explicitly 'disabled'"); continue;}
928  newVDev.vdevUrl = urlspecVal.get<std::string>(); // done, we have the vdevUrl
929  NTV2DeviceSpecParser parser (newVDev.vdevUrl); // Check it
930  if (!nameVal.is_null())
931  newVDev.vdevName = nameVal.get<std::string>(); // Name specified in JSON file
932  { // URLencode & append these URL params: &vdevfname= &vdevfpath= &vdevname= &vdevbasename=
933  newVDev.vdevUrl += parser.HasQueryParams() ? "&" : "?";
934  newVDev.vdevUrl += kQParamVDevFolderPath "=" + ::PercentEncode(vdevPath);
935  string fName (vdevFile);
936  fName.erase(fName.find(vdevPath), vdevPath.length()+1); // Remove everything up to file name
937  newVDev.vdevUrl += "&" kQParamVDevFileName "=" + ::PercentEncode(fName); // Remember file name
938  fName.erase(fName.length()-5, 5); // Lop off file name extension
939  if (newVDev.vdevName.empty())
940  newVDev.vdevName = fName; // Use file base name if no name specified in JSON file
941  newVDev.vdevUrl += "&" kQParamVDevName "=" + ::PercentEncode(newVDev.vdevName); // Remember name
942  ostringstream oss; oss << DEC(newVDev.deviceIndex);
943  newVDev.vdevUrl += "&" kQParamVDevIndex "=" + oss.str(); // Remember index number
944  }
945  if (!newVDev.vdevName.empty())
946  { ostringstream oss; oss << newVDev.vdevName << " - " << newVDev.deviceIndex;
947  newVDev.deviceIdentifier = oss.str();
948  }
949 
950  outVDevList.push_back(newVDev);
951  vdIndex++; // Now increment the device index number
952  } // for each vdev file found
953  return true;
954 #endif // else NTV2_PREVENT_PLUGIN_LOAD
955 } // GetVDevList
956 
957 bool CNTV2DeviceScanner::GetCP2DevList (NTV2DeviceInfoList & outVDevList)
958 {
959 #if defined(NTV2_PREVENT_PLUGIN_LOAD)
960  return false; // Plugin loading disabled, therefore no virtual devices
961 #else // else NTV2_PREVENT_PLUGIN_LOAD
962  string vdevPath;
964  if (pathInfo.GetValue(AJA_SystemInfoTag_Path_PersistenceStoreUser, vdevPath) != AJA_STATUS_SUCCESS)
965  return false;
966  }
967  vdevPath += "virtualdevices";
968  ULWord vdIndex = ULWord(outVDevList.size());
969  NTV2StringList vdevFiles;
970  AJAFileIO::ReadDirectory(vdevPath, "*.vdev", vdevFiles);
971  for (const auto & vdevFile : vdevFiles)
972  {
973  json vdevJson;
974  {
975  std::ifstream vf(vdevFile);
976  if (!vf.is_open())
977  {C2FAIL("Unable to open '" << vdevFile << "'"); return false;}
978  try
979  {
980  vdevJson = json::parse(vf);
981  }
982  catch (const json::parse_error& e)
983  {
984  C2FAIL("Invalid JSON at byte " << e.byte << " in '" << vdevFile << "': " << e.what() << ", exceptionID " << e.id);
985  return false;
986  }
987  }
988 
989  NTV2DeviceInfo newVDev;
990  newVDev.isVirtualDevice = true;
991  newVDev.deviceIndex = vdIndex++;
992  newVDev.deviceID = DEVICE_ID_SOFTWARE;
993  newVDev.deviceIdentifier = "";
994  newVDev.vdevName = "";
995 
996  // EXPECTED JSON KEYS:
997  // "plugin" [required] Specifies name of plugin to be loaded.
998  // "name" [optional] Specifies a human-readable name for the device.
999  // "host" [optional] Specifies host to use in the plugin URL. Defaults to "localhost".
1000  string hostName;
1001  auto pluginVal (vdevJson["plugin"]), nameVal (vdevJson["name"]), hostVal (vdevJson["host"]), urlspecVal (vdevJson["urlspec"]);
1002  if (pluginVal.is_null())
1003  {C2FAIL("File: '" << vdevFile << "' missing required 'plugin' parameter"); continue;}
1004  if (!urlspecVal.is_null())
1005  C2WARN("File: '" << vdevFile << "' 'urlspec' parameter ignored");
1006 
1007  newVDev.vdevUrl = pluginVal.get<std::string>();
1008  if (!nameVal.is_null())
1009  {
1010  ostringstream oss;
1011  oss << nameVal.get<std::string>() << " - " << newVDev.deviceIndex;
1012  newVDev.deviceIdentifier = oss.str();
1013  newVDev.vdevName = nameVal.get<std::string>();
1014  }
1015 
1016  if (!hostVal.is_null())
1017  hostName = hostVal.get<std::string>();
1018  if (hostName.empty())
1019  hostName = "localhost";
1020  newVDev.vdevUrl += "://" + hostName + "/?";
1021 
1022  NTV2StringList params;
1023  for (auto it (vdevJson.begin()); it != vdevJson.end(); ++it)
1024  if (it.key() != "plugin" && it.key() != "name" && it.key() != "host")
1025  {
1026  auto paramValStr = to_string(it.value());
1027  aja::strip(paramValStr, "\"");
1028  params.push_back(it.key() + "=" + ::PercentEncode(paramValStr));
1029  }
1030 
1031  if (!newVDev.deviceIdentifier.empty())
1032  params.push_back("displayname=" + ::PercentEncode(newVDev.deviceIdentifier));
1033  const string queryStr(aja::join(params, "&"));
1034  if (!queryStr.empty())
1035  newVDev.vdevUrl += "?" + queryStr;
1036  outVDevList.push_back(newVDev);
1037  } // for each .vdev file found
1038  return true;
1039 #endif // else NTV2_PREVENT_PLUGIN_LOAD
1040 } // GetCP2DeviceList
bool programmableCSCSupport
Programmable color space converter?
#define VDINFO(__x__)
NTV2DeviceInfoList GetDeviceInfoList(void)
nlohmann::json json
The number of input converter widgets on the device.
virtual bool IsSupported(const NTV2BoolParamID inParamID)
#define C2WARN(__x__)
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:46
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.
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...
#define VDWARN(__x__)
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:596
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:49
The number of analog LTC outputs on the device.
The number of AES/EBU audio output channels on the device.
NTV2StringSet::const_iterator NTV2StringSetConstIter
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:44
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:7382
static bool PatchDeviceInfo(const UWord inDevIndex, CNTV2DriverInterface &dev)
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:236
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:43
#define NTV2_ASSERT(_expr_)
Definition: ajatypes.h:489
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?
I&#39;m the base class that undergirds the platform-specific derived classes (from which CNTV2Card is ult...
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:100
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
std::set< std::string > NTV2StringSet
#define VDDBUG(__x__)
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)
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...
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)
#define VDFAIL(__x__)
bool has8KSupport
Supports 8K formats?
static bool IsHexDigit(const char inChr)
bool sdi12GSupport
Supports 12G?
UWord numUpConverters
Total number of up-converters.
std::set< ULWord > ULWordSet
A collection of unique ULWord (uint32_t) values.
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:50
True if device has 12G SDI connectors.
#define kQParamVDevFileName
.vdev file name (with extension)
Definition: ntv2nubaccess.h:45
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...
uint64_t is_legal_hex_serial_number(const std::string &inStr)
Definition: common.cpp:540
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 std::string GetDescription(void) const
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:51
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.
#define C2FAIL(__x__)
True if the device can handle 4K/UHD video.
The number of RS-422 serial ports on the device.
std::string vdevName
bool is_legal_decimal_number(const std::string &inStr, size_t inMaxLength)
Definition: common.cpp:526
uint16_t UWord
Definition: ajatypes.h:234
bool stereoOutSupport
Supports stereo output?
UWord numAudioStreams
Maximum number of independent audio streams.
#define VDNOTE(__x__)
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:7891
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.
std::vector< std::string > NTV2StringList
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
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.
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...