aja-props.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. #include "aja-props.hpp"
  2. #include "aja-common.hpp"
  3. #include <ajantv2/includes/ntv2devicefeatures.h>
  4. #include <ajantv2/includes/ntv2utils.h>
  5. // AJASource Properties
  6. SourceProps::SourceProps()
  7. : deviceID{DEVICE_ID_NOTFOUND},
  8. ioSelect{IOSelection::Invalid},
  9. // inputSource{NTV2_INPUTSOURCE_INVALID},
  10. videoFormat{NTV2_FORMAT_UNKNOWN},
  11. pixelFormat{NTV2_FBF_INVALID},
  12. sdiTransport{SDITransport::SingleLink},
  13. sdi4kTransport{SDITransport4K::TwoSampleInterleave},
  14. audioNumChannels{kDefaultAudioChannels},
  15. audioSampleSize{kDefaultAudioSampleSize},
  16. audioSampleRate{kDefaultAudioSampleRate},
  17. vpids{},
  18. autoDetect{false},
  19. deactivateWhileNotShowing{false},
  20. swapFrontCenterLFE{false}
  21. {
  22. }
  23. SourceProps::SourceProps(NTV2DeviceID devID)
  24. : deviceID{devID},
  25. ioSelect{IOSelection::Invalid},
  26. // inputSource{NTV2_INPUTSOURCE_INVALID},
  27. videoFormat{NTV2_FORMAT_UNKNOWN},
  28. pixelFormat{NTV2_FBF_INVALID},
  29. sdiTransport{SDITransport::SingleLink},
  30. sdi4kTransport{SDITransport4K::TwoSampleInterleave},
  31. audioNumChannels{kDefaultAudioChannels},
  32. audioSampleSize{kDefaultAudioSampleSize},
  33. audioSampleRate{kDefaultAudioSampleRate},
  34. vpids{},
  35. autoDetect{false},
  36. deactivateWhileNotShowing{false},
  37. swapFrontCenterLFE{false}
  38. {
  39. }
  40. SourceProps::SourceProps(const SourceProps &props)
  41. {
  42. deviceID = props.deviceID;
  43. ioSelect = props.ioSelect;
  44. // inputSource = props.inputSource;
  45. videoFormat = props.videoFormat;
  46. pixelFormat = props.pixelFormat;
  47. sdiTransport = props.sdiTransport;
  48. sdi4kTransport = props.sdi4kTransport;
  49. audioNumChannels = props.audioNumChannels;
  50. audioSampleSize = props.audioSampleSize;
  51. audioSampleRate = props.audioSampleRate;
  52. vpids = props.vpids;
  53. autoDetect = props.autoDetect;
  54. deactivateWhileNotShowing = props.deactivateWhileNotShowing;
  55. swapFrontCenterLFE = props.swapFrontCenterLFE;
  56. }
  57. SourceProps::SourceProps(SourceProps &&props)
  58. {
  59. deviceID = props.deviceID;
  60. ioSelect = props.ioSelect;
  61. // inputSource = props.inputSource;
  62. videoFormat = props.videoFormat;
  63. pixelFormat = props.pixelFormat;
  64. sdiTransport = props.sdiTransport;
  65. sdi4kTransport = props.sdi4kTransport;
  66. audioNumChannels = props.audioNumChannels;
  67. audioSampleSize = props.audioSampleSize;
  68. audioSampleRate = props.audioSampleRate;
  69. vpids = props.vpids;
  70. autoDetect = props.autoDetect;
  71. deactivateWhileNotShowing = props.deactivateWhileNotShowing;
  72. swapFrontCenterLFE = props.swapFrontCenterLFE;
  73. }
  74. void SourceProps::operator=(const SourceProps &props)
  75. {
  76. deviceID = props.deviceID;
  77. ioSelect = props.ioSelect;
  78. // inputSource = props.inputSource;
  79. videoFormat = props.videoFormat;
  80. pixelFormat = props.pixelFormat;
  81. sdiTransport = props.sdiTransport;
  82. sdi4kTransport = props.sdi4kTransport;
  83. audioNumChannels = props.audioNumChannels;
  84. audioSampleSize = props.audioSampleSize;
  85. audioSampleRate = props.audioSampleRate;
  86. vpids = props.vpids;
  87. autoDetect = props.autoDetect;
  88. deactivateWhileNotShowing = props.deactivateWhileNotShowing;
  89. swapFrontCenterLFE = props.swapFrontCenterLFE;
  90. }
  91. void SourceProps::operator=(SourceProps &&props)
  92. {
  93. deviceID = props.deviceID;
  94. ioSelect = props.ioSelect;
  95. // inputSource = props.inputSource;
  96. videoFormat = props.videoFormat;
  97. pixelFormat = props.pixelFormat;
  98. sdiTransport = props.sdiTransport;
  99. sdi4kTransport = props.sdi4kTransport;
  100. audioNumChannels = props.audioNumChannels;
  101. audioSampleSize = props.audioSampleSize;
  102. audioSampleRate = props.audioSampleRate;
  103. vpids = props.vpids;
  104. autoDetect = props.autoDetect;
  105. deactivateWhileNotShowing = props.deactivateWhileNotShowing;
  106. swapFrontCenterLFE = props.swapFrontCenterLFE;
  107. }
  108. bool SourceProps::operator==(const SourceProps &props)
  109. {
  110. return (deviceID == props.deviceID && ioSelect == props.ioSelect &&
  111. // inputSource == props.inputSource &&
  112. videoFormat == props.videoFormat &&
  113. pixelFormat == props.pixelFormat &&
  114. // vpid == props.vpid &&
  115. autoDetect == props.autoDetect &&
  116. sdiTransport == props.sdiTransport &&
  117. sdi4kTransport == props.sdi4kTransport &&
  118. audioNumChannels == props.audioNumChannels &&
  119. audioSampleSize == props.audioSampleSize &&
  120. audioSampleRate == props.audioSampleRate &&
  121. deactivateWhileNotShowing == props.deactivateWhileNotShowing &&
  122. swapFrontCenterLFE == props.swapFrontCenterLFE);
  123. }
  124. bool SourceProps::operator!=(const SourceProps &props)
  125. {
  126. return !operator==(props);
  127. }
  128. NTV2InputSource SourceProps::InitialInputSource() const
  129. {
  130. auto inputSources = InputSources();
  131. if (!inputSources.empty()) {
  132. return *inputSources.begin();
  133. }
  134. return NTV2_INPUTSOURCE_INVALID;
  135. }
  136. NTV2InputSourceSet SourceProps::InputSources() const
  137. {
  138. NTV2InputSourceSet inputSources;
  139. aja::IOSelectionToInputSources(ioSelect, inputSources);
  140. return inputSources;
  141. }
  142. NTV2Channel SourceProps::Channel() const
  143. {
  144. return NTV2InputSourceToChannel(InitialInputSource());
  145. }
  146. NTV2Channel SourceProps::Framestore() const
  147. {
  148. if (deviceID == DEVICE_ID_KONAHDMI && ioSelect == IOSelection::HDMI2 &&
  149. NTV2_IS_4K_VIDEO_FORMAT(videoFormat)) {
  150. return NTV2_CHANNEL3;
  151. }
  152. return Channel();
  153. }
  154. NTV2AudioSystem SourceProps::AudioSystem() const
  155. {
  156. return NTV2ChannelToAudioSystem(Channel());
  157. }
  158. NTV2AudioRate SourceProps::AudioRate() const
  159. {
  160. NTV2AudioRate rate = NTV2_AUDIO_48K;
  161. switch (audioSampleRate) {
  162. default:
  163. case 48000:
  164. rate = NTV2_AUDIO_48K;
  165. break;
  166. case 96000:
  167. rate = NTV2_AUDIO_96K;
  168. break;
  169. case 192000:
  170. rate = NTV2_AUDIO_192K;
  171. break;
  172. }
  173. return rate;
  174. }
  175. // Size in bytes of N channels of audio
  176. size_t SourceProps::AudioSize() const
  177. {
  178. return audioNumChannels * audioSampleSize;
  179. }
  180. audio_format SourceProps::AudioFormat() const
  181. {
  182. // NTV2 is always 32-bit PCM
  183. return AUDIO_FORMAT_32BIT;
  184. }
  185. speaker_layout SourceProps::SpeakerLayout() const
  186. {
  187. if (audioNumChannels == 1)
  188. return SPEAKERS_MONO;
  189. else if (audioNumChannels == 2)
  190. return SPEAKERS_STEREO;
  191. else if (audioNumChannels == 3)
  192. return SPEAKERS_2POINT1;
  193. else if (audioNumChannels == 4)
  194. return SPEAKERS_4POINT0;
  195. else if (audioNumChannels == 5)
  196. return SPEAKERS_4POINT1;
  197. else if (audioNumChannels == 6)
  198. return SPEAKERS_5POINT1;
  199. // NTV2 card is always set to at least 8ch
  200. return SPEAKERS_7POINT1;
  201. }
  202. //
  203. // AJAOutput Properties
  204. //
  205. OutputProps::OutputProps(NTV2DeviceID devID)
  206. : deviceID{devID},
  207. ioSelect{IOSelection::Invalid},
  208. outputDest{NTV2_OUTPUTDESTINATION_ANALOG},
  209. videoFormat{NTV2_FORMAT_UNKNOWN},
  210. pixelFormat{NTV2_FBF_INVALID},
  211. sdi4kTransport{SDITransport4K::TwoSampleInterleave},
  212. audioNumChannels{8},
  213. audioSampleSize{kDefaultAudioSampleSize},
  214. audioSampleRate{kDefaultAudioSampleRate}
  215. {
  216. }
  217. OutputProps::OutputProps(OutputProps &&props)
  218. {
  219. deviceID = props.deviceID;
  220. ioSelect = props.ioSelect;
  221. outputDest = props.outputDest;
  222. videoFormat = props.videoFormat;
  223. pixelFormat = props.pixelFormat;
  224. sdiTransport = props.sdiTransport;
  225. sdi4kTransport = props.sdi4kTransport;
  226. audioNumChannels = props.audioNumChannels;
  227. audioSampleSize = props.audioSampleSize;
  228. audioSampleRate = props.audioSampleRate;
  229. }
  230. OutputProps::OutputProps(const OutputProps &props)
  231. {
  232. deviceID = props.deviceID;
  233. ioSelect = props.ioSelect;
  234. outputDest = props.outputDest;
  235. videoFormat = props.videoFormat;
  236. pixelFormat = props.pixelFormat;
  237. sdiTransport = props.sdiTransport;
  238. sdi4kTransport = props.sdi4kTransport;
  239. audioNumChannels = props.audioNumChannels;
  240. audioSampleSize = props.audioSampleSize;
  241. audioSampleRate = props.audioSampleRate;
  242. }
  243. void OutputProps::operator=(const OutputProps &props)
  244. {
  245. deviceID = props.deviceID;
  246. ioSelect = props.ioSelect;
  247. outputDest = props.outputDest;
  248. videoFormat = props.videoFormat;
  249. pixelFormat = props.pixelFormat;
  250. sdiTransport = props.sdiTransport;
  251. sdi4kTransport = props.sdi4kTransport;
  252. audioNumChannels = props.audioNumChannels;
  253. audioSampleSize = props.audioSampleSize;
  254. audioSampleRate = props.audioSampleRate;
  255. }
  256. void OutputProps::operator=(OutputProps &&props)
  257. {
  258. deviceID = props.deviceID;
  259. ioSelect = props.ioSelect;
  260. outputDest = props.outputDest;
  261. videoFormat = props.videoFormat;
  262. pixelFormat = props.pixelFormat;
  263. sdiTransport = props.sdiTransport;
  264. sdi4kTransport = props.sdi4kTransport;
  265. audioNumChannels = props.audioNumChannels;
  266. audioSampleSize = props.audioSampleSize;
  267. audioSampleRate = props.audioSampleRate;
  268. }
  269. bool OutputProps::operator==(const OutputProps &props)
  270. {
  271. return (deviceID == props.deviceID && ioSelect == props.ioSelect &&
  272. // outputDest == props.outputDest &&
  273. videoFormat == props.videoFormat &&
  274. pixelFormat == props.pixelFormat &&
  275. sdiTransport == props.sdiTransport &&
  276. sdi4kTransport == props.sdi4kTransport &&
  277. audioNumChannels == props.audioNumChannels &&
  278. audioSampleSize == props.audioSampleSize &&
  279. audioSampleRate == props.audioSampleRate);
  280. }
  281. bool OutputProps::operator!=(const OutputProps &props)
  282. {
  283. return !operator==(props);
  284. }
  285. NTV2FormatDesc OutputProps::FormatDesc()
  286. {
  287. return NTV2FormatDesc(videoFormat, pixelFormat, NTV2_VANCMODE_OFF);
  288. }
  289. NTV2Channel OutputProps::Channel() const
  290. {
  291. // Output Channel Special Cases
  292. // KONA1 -- Has 2 framestores but only 1 bi-directional SDI widget
  293. if (deviceID == DEVICE_ID_KONA1) {
  294. return NTV2_CHANNEL2;
  295. } else if ((deviceID == DEVICE_ID_IO4K ||
  296. deviceID == DEVICE_ID_IO4KPLUS) &&
  297. outputDest == NTV2_OUTPUTDESTINATION_SDI5) {
  298. // IO4K/IO4K+ SDI Monitor - Use framestore 4 but SDI5
  299. return NTV2_CHANNEL4;
  300. }
  301. if (NTV2_OUTPUT_DEST_IS_HDMI(outputDest)) {
  302. if (aja::CardCanDoHDMIMonitorOutput(deviceID) &&
  303. NTV2_IS_4K_VIDEO_FORMAT(videoFormat))
  304. return NTV2_CHANNEL3;
  305. return static_cast<NTV2Channel>(
  306. NTV2DeviceGetNumFrameStores(deviceID) - 1);
  307. }
  308. return NTV2OutputDestinationToChannel(outputDest);
  309. }
  310. NTV2Channel OutputProps::Framestore() const
  311. {
  312. if (deviceID == DEVICE_ID_TTAP_PRO) {
  313. return NTV2_CHANNEL1;
  314. } else if (deviceID == DEVICE_ID_KONA1) {
  315. return NTV2_CHANNEL2;
  316. } else if (deviceID == DEVICE_ID_IO4K ||
  317. deviceID == DEVICE_ID_IO4KPLUS) {
  318. // SDI Monitor output uses framestore 4
  319. if (ioSelect == IOSelection::SDI5)
  320. return NTV2_CHANNEL4;
  321. }
  322. // HDMI Monitor output uses framestore 4
  323. if (ioSelect == IOSelection::HDMIMonitorOut) {
  324. if (deviceID == DEVICE_ID_KONA5_8K)
  325. return NTV2_CHANNEL4;
  326. if (NTV2_IS_4K_VIDEO_FORMAT(videoFormat))
  327. return NTV2_CHANNEL3;
  328. else
  329. return NTV2_CHANNEL4;
  330. }
  331. return NTV2OutputDestinationToChannel(outputDest);
  332. }
  333. NTV2AudioSystem OutputProps::AudioSystem() const
  334. {
  335. return NTV2ChannelToAudioSystem(Channel());
  336. }
  337. NTV2AudioRate OutputProps::AudioRate() const
  338. {
  339. NTV2AudioRate rate = NTV2_AUDIO_48K;
  340. switch (audioSampleRate) {
  341. default:
  342. case 48000:
  343. rate = NTV2_AUDIO_48K;
  344. break;
  345. case 96000:
  346. rate = NTV2_AUDIO_96K;
  347. break;
  348. case 192000:
  349. rate = NTV2_AUDIO_192K;
  350. break;
  351. }
  352. return rate;
  353. }
  354. // Size in bytes of N channels of audio
  355. size_t OutputProps::AudioSize() const
  356. {
  357. return audioNumChannels * audioSampleSize;
  358. }
  359. audio_format OutputProps::AudioFormat() const
  360. {
  361. // NTV2 is always 32-bit PCM
  362. return AUDIO_FORMAT_32BIT;
  363. }
  364. speaker_layout OutputProps::SpeakerLayout() const
  365. {
  366. if (audioNumChannels == 2)
  367. return SPEAKERS_STEREO;
  368. // NTV2 is always at least 8ch on modern boards
  369. return SPEAKERS_7POINT1;
  370. }