aja-props.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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 && pixelFormat == props.pixelFormat &&
  113. // vpid == props.vpid &&
  114. autoDetect == props.autoDetect && sdiTransport == props.sdiTransport &&
  115. sdi4kTransport == props.sdi4kTransport && audioNumChannels == props.audioNumChannels &&
  116. audioSampleSize == props.audioSampleSize && audioSampleRate == props.audioSampleRate &&
  117. deactivateWhileNotShowing == props.deactivateWhileNotShowing &&
  118. swapFrontCenterLFE == props.swapFrontCenterLFE);
  119. }
  120. bool SourceProps::operator!=(const SourceProps &props)
  121. {
  122. return !operator==(props);
  123. }
  124. NTV2InputSource SourceProps::InitialInputSource() const
  125. {
  126. auto inputSources = InputSources();
  127. if (!inputSources.empty()) {
  128. return *inputSources.begin();
  129. }
  130. return NTV2_INPUTSOURCE_INVALID;
  131. }
  132. NTV2InputSourceSet SourceProps::InputSources() const
  133. {
  134. NTV2InputSourceSet inputSources;
  135. aja::IOSelectionToInputSources(ioSelect, inputSources);
  136. return inputSources;
  137. }
  138. NTV2Channel SourceProps::Channel() const
  139. {
  140. return NTV2InputSourceToChannel(InitialInputSource());
  141. }
  142. NTV2Channel SourceProps::Framestore() const
  143. {
  144. if (deviceID == DEVICE_ID_KONAHDMI && ioSelect == IOSelection::HDMI2 && NTV2_IS_4K_VIDEO_FORMAT(videoFormat)) {
  145. return NTV2_CHANNEL3;
  146. }
  147. return Channel();
  148. }
  149. NTV2AudioSystem SourceProps::AudioSystem() const
  150. {
  151. return NTV2ChannelToAudioSystem(Channel());
  152. }
  153. NTV2AudioRate SourceProps::AudioRate() const
  154. {
  155. NTV2AudioRate rate = NTV2_AUDIO_48K;
  156. switch (audioSampleRate) {
  157. default:
  158. case 48000:
  159. rate = NTV2_AUDIO_48K;
  160. break;
  161. case 96000:
  162. rate = NTV2_AUDIO_96K;
  163. break;
  164. case 192000:
  165. rate = NTV2_AUDIO_192K;
  166. break;
  167. }
  168. return rate;
  169. }
  170. // Size in bytes of N channels of audio
  171. size_t SourceProps::AudioSize() const
  172. {
  173. return audioNumChannels * audioSampleSize;
  174. }
  175. audio_format SourceProps::AudioFormat() const
  176. {
  177. // NTV2 is always 32-bit PCM
  178. return AUDIO_FORMAT_32BIT;
  179. }
  180. speaker_layout SourceProps::SpeakerLayout() const
  181. {
  182. if (audioNumChannels == 1)
  183. return SPEAKERS_MONO;
  184. else if (audioNumChannels == 2)
  185. return SPEAKERS_STEREO;
  186. else if (audioNumChannels == 3)
  187. return SPEAKERS_2POINT1;
  188. else if (audioNumChannels == 4)
  189. return SPEAKERS_4POINT0;
  190. else if (audioNumChannels == 5)
  191. return SPEAKERS_4POINT1;
  192. else if (audioNumChannels == 6)
  193. return SPEAKERS_5POINT1;
  194. // NTV2 card is always set to at least 8ch
  195. return SPEAKERS_7POINT1;
  196. }
  197. //
  198. // AJAOutput Properties
  199. //
  200. OutputProps::OutputProps(NTV2DeviceID devID)
  201. : deviceID{devID},
  202. ioSelect{IOSelection::Invalid},
  203. outputDest{NTV2_OUTPUTDESTINATION_ANALOG},
  204. videoFormat{NTV2_FORMAT_UNKNOWN},
  205. pixelFormat{NTV2_FBF_INVALID},
  206. sdi4kTransport{SDITransport4K::TwoSampleInterleave},
  207. audioNumChannels{8},
  208. audioSampleSize{kDefaultAudioSampleSize},
  209. audioSampleRate{kDefaultAudioSampleRate}
  210. {
  211. }
  212. OutputProps::OutputProps(OutputProps &&props)
  213. {
  214. deviceID = props.deviceID;
  215. ioSelect = props.ioSelect;
  216. outputDest = props.outputDest;
  217. videoFormat = props.videoFormat;
  218. pixelFormat = props.pixelFormat;
  219. sdiTransport = props.sdiTransport;
  220. sdi4kTransport = props.sdi4kTransport;
  221. audioNumChannels = props.audioNumChannels;
  222. audioSampleSize = props.audioSampleSize;
  223. audioSampleRate = props.audioSampleRate;
  224. }
  225. OutputProps::OutputProps(const OutputProps &props)
  226. {
  227. deviceID = props.deviceID;
  228. ioSelect = props.ioSelect;
  229. outputDest = props.outputDest;
  230. videoFormat = props.videoFormat;
  231. pixelFormat = props.pixelFormat;
  232. sdiTransport = props.sdiTransport;
  233. sdi4kTransport = props.sdi4kTransport;
  234. audioNumChannels = props.audioNumChannels;
  235. audioSampleSize = props.audioSampleSize;
  236. audioSampleRate = props.audioSampleRate;
  237. }
  238. void OutputProps::operator=(const OutputProps &props)
  239. {
  240. deviceID = props.deviceID;
  241. ioSelect = props.ioSelect;
  242. outputDest = props.outputDest;
  243. videoFormat = props.videoFormat;
  244. pixelFormat = props.pixelFormat;
  245. sdiTransport = props.sdiTransport;
  246. sdi4kTransport = props.sdi4kTransport;
  247. audioNumChannels = props.audioNumChannels;
  248. audioSampleSize = props.audioSampleSize;
  249. audioSampleRate = props.audioSampleRate;
  250. }
  251. void OutputProps::operator=(OutputProps &&props)
  252. {
  253. deviceID = props.deviceID;
  254. ioSelect = props.ioSelect;
  255. outputDest = props.outputDest;
  256. videoFormat = props.videoFormat;
  257. pixelFormat = props.pixelFormat;
  258. sdiTransport = props.sdiTransport;
  259. sdi4kTransport = props.sdi4kTransport;
  260. audioNumChannels = props.audioNumChannels;
  261. audioSampleSize = props.audioSampleSize;
  262. audioSampleRate = props.audioSampleRate;
  263. }
  264. bool OutputProps::operator==(const OutputProps &props)
  265. {
  266. return (deviceID == props.deviceID && ioSelect == props.ioSelect &&
  267. // outputDest == props.outputDest &&
  268. videoFormat == props.videoFormat && pixelFormat == props.pixelFormat &&
  269. sdiTransport == props.sdiTransport && sdi4kTransport == props.sdi4kTransport &&
  270. audioNumChannels == props.audioNumChannels && audioSampleSize == props.audioSampleSize &&
  271. audioSampleRate == props.audioSampleRate);
  272. }
  273. bool OutputProps::operator!=(const OutputProps &props)
  274. {
  275. return !operator==(props);
  276. }
  277. NTV2FormatDesc OutputProps::FormatDesc()
  278. {
  279. return NTV2FormatDesc(videoFormat, pixelFormat, NTV2_VANCMODE_OFF);
  280. }
  281. NTV2Channel OutputProps::Channel() const
  282. {
  283. // Output Channel Special Cases
  284. // KONA1 -- Has 2 framestores but only 1 bi-directional SDI widget
  285. if (deviceID == DEVICE_ID_KONA1) {
  286. return NTV2_CHANNEL2;
  287. } else if ((deviceID == DEVICE_ID_IO4K || deviceID == DEVICE_ID_IO4KPLUS) &&
  288. outputDest == NTV2_OUTPUTDESTINATION_SDI5) {
  289. // IO4K/IO4K+ SDI Monitor - Use framestore 4 but SDI5
  290. return NTV2_CHANNEL4;
  291. }
  292. if (NTV2_OUTPUT_DEST_IS_HDMI(outputDest)) {
  293. if (aja::CardCanDoHDMIMonitorOutput(deviceID) && NTV2_IS_4K_VIDEO_FORMAT(videoFormat))
  294. return NTV2_CHANNEL3;
  295. return static_cast<NTV2Channel>(NTV2DeviceGetNumFrameStores(deviceID) - 1);
  296. }
  297. return NTV2OutputDestinationToChannel(outputDest);
  298. }
  299. NTV2Channel OutputProps::Framestore() const
  300. {
  301. if (deviceID == DEVICE_ID_TTAP_PRO) {
  302. return NTV2_CHANNEL1;
  303. } else if (deviceID == DEVICE_ID_KONA1) {
  304. return NTV2_CHANNEL2;
  305. } else if (deviceID == DEVICE_ID_IO4K || deviceID == DEVICE_ID_IO4KPLUS) {
  306. // SDI Monitor output uses framestore 4
  307. if (ioSelect == IOSelection::SDI5)
  308. return NTV2_CHANNEL4;
  309. }
  310. // HDMI Monitor output uses framestore 4
  311. if (ioSelect == IOSelection::HDMIMonitorOut) {
  312. if (deviceID == DEVICE_ID_KONA5_8K)
  313. return NTV2_CHANNEL4;
  314. if (NTV2_IS_4K_VIDEO_FORMAT(videoFormat))
  315. return NTV2_CHANNEL3;
  316. else
  317. return NTV2_CHANNEL4;
  318. }
  319. return NTV2OutputDestinationToChannel(outputDest);
  320. }
  321. NTV2AudioSystem OutputProps::AudioSystem() const
  322. {
  323. return NTV2ChannelToAudioSystem(Channel());
  324. }
  325. NTV2AudioRate OutputProps::AudioRate() const
  326. {
  327. NTV2AudioRate rate = NTV2_AUDIO_48K;
  328. switch (audioSampleRate) {
  329. default:
  330. case 48000:
  331. rate = NTV2_AUDIO_48K;
  332. break;
  333. case 96000:
  334. rate = NTV2_AUDIO_96K;
  335. break;
  336. case 192000:
  337. rate = NTV2_AUDIO_192K;
  338. break;
  339. }
  340. return rate;
  341. }
  342. // Size in bytes of N channels of audio
  343. size_t OutputProps::AudioSize() const
  344. {
  345. return audioNumChannels * audioSampleSize;
  346. }
  347. audio_format OutputProps::AudioFormat() const
  348. {
  349. // NTV2 is always 32-bit PCM
  350. return AUDIO_FORMAT_32BIT;
  351. }
  352. speaker_layout OutputProps::SpeakerLayout() const
  353. {
  354. if (audioNumChannels == 2)
  355. return SPEAKERS_STEREO;
  356. // NTV2 is always at least 8ch on modern boards
  357. return SPEAKERS_7POINT1;
  358. }