aja-props.cpp 10 KB

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