AJA NTV2 SDK  18.0.0.2122
NTV2 SDK 18.0.0.2122
ntv2config2110.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2config2110.h"
9 #include "ntv2endian.h"
10 #include "ntv2card.h"
11 #include "ntv2utils.h"
12 #include <sstream>
13 #include <ajabase/network/network.h>
15 #include <algorithm>
16 #include <math.h>
17 
18 #if defined (AJALinux) || defined (AJAMac)
19 #include <stdlib.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #endif
24 
25 #define RESET_MILLISECONDS 5
26 
31 
36 
41 
46 
51 
52 using namespace std;
53 
55 {
56  for (int i=0; i < 2; i++)
57  {
58  localPort[i] = 0;
59  remotePort[i] = 0;
60  remoteIP[i].erase();
61  }
62  videoFormat = NTV2_FORMAT_UNKNOWN;
63  videoSamples = VPIDSampling_YUV_422;
64  ttl = 0x40;
65  tos = 0x64;
66  ssrc = 1000;
67  numAudioChannels = 0;
68  firstAudioChannel = 0;
69  audioPktInterval = PACKET_INTERVAL_1mS;
70  channel = (NTV2Channel)0;
71 }
72 
74 {
75  return !(*this == other);
76 }
77 
79 {
80  // NOTE(paulh): Consider using std::equal to compare arrays if these sizes ever change (seems unlikely)
81  if ((localPort[0] == other.localPort[0]) &&
82  (localPort[1] == other.localPort[1]) &&
83  (remotePort[0] == other.remotePort[0]) &&
84  (remotePort[1] == other.remotePort[1]) &&
85  (remoteIP[0] == other.remoteIP[0]) &&
86  (remoteIP[1] == other.remoteIP[1]) &&
87  (videoFormat == other.videoFormat) &&
88  (videoSamples == other.videoSamples) &&
89  (numAudioChannels == other.numAudioChannels) &&
90  (firstAudioChannel == other.firstAudioChannel) &&
91  (audioPktInterval == other.audioPktInterval))
92  {
93  return true;
94  }
95  else
96  {
97  return false;
98  }
99 }
100 
102 {
103  rxMatch = 0;
104  sourceIP.erase();
105  destIP.erase();
106  sourcePort = 0;
107  destPort = 0;
108  ssrc = 1000;
109  vlan = 1;
110  payloadType = 0;
111  videoFormat = NTV2_FORMAT_UNKNOWN;
112  videoSamples = VPIDSampling_YUV_422;
113  numAudioChannels = 2;
114  audioPktInterval = PACKET_INTERVAL_1mS;
115 }
116 
118 {
119  return (!(*this == other));
120 }
121 
123 {
124  if ( (rxMatch == other.rxMatch) &&
125  (sourceIP == other.sourceIP) &&
126  (destIP == other.destIP) &&
127  (sourcePort == other.sourcePort) &&
128  (destPort == other.destPort) &&
129  (ssrc == other.ssrc) &&
130  (vlan == other.vlan) &&
131  (videoFormat == other.videoFormat) &&
132  (videoSamples == other.videoSamples) &&
133  (numAudioChannels == other.numAudioChannels) &&
134  (audioPktInterval == other.audioPktInterval))
135  {
136  return true;
137  }
138  else
139  {
140  return false;
141  }
142 }
143 
145 //
146 // CNTV2Config2110
147 //
149 
151 {
152  uint32_t features = getFeatures();
153 
154  _numTx0Chans = (features & (SAREK_TX0_MASK)) >> 28;
155  _numRx0Chans = (features & (SAREK_RX0_MASK)) >> 24;
156  _numTx1Chans = (features & (SAREK_TX1_MASK)) >> 20;
157  _numRx1Chans = (features & (SAREK_RX1_MASK)) >> 16;
158 
159  _numRxChans = _numRx0Chans + _numRx1Chans;
160  _numTxChans = _numTx0Chans + _numTx1Chans;
161 
162  _biDirectionalChannels = false;
163 }
164 
166 {
167 }
168 
170 {
171  string ip, subnet, gateway;
172  struct in_addr addr;
173  addr.s_addr = (uint32_t)netConfig.ipc_ip;
174  ip = AJANetwork::aja_inet_ntoa(addr);
175  addr.s_addr = (uint32_t)netConfig.ipc_subnet;
176  subnet = AJANetwork::aja_inet_ntoa(addr);
177  addr.s_addr = (uint32_t)netConfig.ipc_gateway;
178  gateway = AJANetwork::aja_inet_ntoa(addr);
179 
180  bool rv = SetNetworkConfiguration(sfp, ip, subnet, gateway);
181  return rv;
182 }
183 
185 {
186  string ip, subnet, gateway;
187  GetNetworkConfiguration(sfp, ip, subnet, gateway);
188 
189  netConfig.ipc_ip = NTV2EndianSwap32((uint32_t)AJANetwork::aja_inet_addr(ip.c_str()));
190  netConfig.ipc_subnet = NTV2EndianSwap32((uint32_t)AJANetwork::aja_inet_addr(subnet.c_str()));
191  netConfig.ipc_gateway = NTV2EndianSwap32((uint32_t)AJANetwork::aja_inet_addr(gateway.c_str()));
192 
193  return true;
194 }
195 
196 bool CNTV2Config2110::SetNetworkConfiguration(const eSFP sfp, const std::string localIPAddress, const std::string subnetMask, const std::string gateway)
197 {
198  if (!mDevice.IsMBSystemReady())
199  {
201  return false;
202  }
203 
204  if (!mDevice.IsMBSystemValid())
205  {
207  return false;
208  }
209 
210  uint32_t addr = AJANetwork::aja_inet_addr(localIPAddress.c_str());
211  addr = NTV2EndianSwap32(addr);
212 
213  uint32_t macLo;
214  uint32_t macHi;
215 
216  // get sfp1 mac address
217  uint32_t macAddressRegister = SAREK_REGS + kRegSarekMAC;
218  mDevice.ReadRegister(macAddressRegister, macHi);
219  macAddressRegister++;
220  mDevice.ReadRegister(macAddressRegister, macLo);
221 
222  uint32_t boardHi = (macHi & 0xffff0000) >>16;
223  uint32_t boardLo = ((macHi & 0x0000ffff) << 16) + ((macLo & 0xffff0000) >> 16);
224 
225  // get sfp2 mac address
226  macAddressRegister++;
227  mDevice.ReadRegister(macAddressRegister, macHi);
228  macAddressRegister++;
229  mDevice.ReadRegister(macAddressRegister, macLo);
230 
231  uint32_t boardHi2 = (macHi & 0xffff0000) >>16;
232  uint32_t boardLo2 = ((macHi & 0x0000ffff) << 16) + ((macLo & 0xffff0000) >> 16);
233 
234 
235  uint32_t core;
242 
249 
250  bool rv = SetMBNetworkConfiguration (sfp, localIPAddress, subnetMask, gateway);
251  if (!rv) return false;
252 
253  if (sfp == SFP_1)
254  {
255  ConfigurePTP(sfp,localIPAddress);
256  }
257 
258  return true;
259 }
260 
261 bool CNTV2Config2110::GetNetworkConfiguration(const eSFP sfp, std::string & localIPAddress, std::string & subnetMask, std::string & gateway)
262 {
263  struct in_addr addr;
264 
265  if (sfp == SFP_1)
266  {
267  uint32_t val;
269  addr.s_addr = val;
270  localIPAddress = AJANetwork::aja_inet_ntoa(addr);
271 
273  addr.s_addr = val;
274  subnetMask = AJANetwork::aja_inet_ntoa(addr);
275 
277  addr.s_addr = val;
278  gateway = AJANetwork::aja_inet_ntoa(addr);
279  }
280  else
281  {
282  uint32_t val;
284  addr.s_addr = val;
285  localIPAddress = AJANetwork::aja_inet_ntoa(addr);
286 
288  addr.s_addr = val;
289  subnetMask = AJANetwork::aja_inet_ntoa(addr);
290 
292  addr.s_addr = val;
293  gateway = AJANetwork::aja_inet_ntoa(addr);
294  }
295  return true;
296 }
297 
299 {
301 }
302 
303 bool CNTV2Config2110::SetRxStreamConfiguration(const eSFP sfp, const NTV2Stream stream, const rx_2110Config & rxConfig)
304 {
307  {
309  return false;
310  }
311 
312  if ((StreamType(stream) == VIDEO_STREAM) ||
313  (StreamType(stream) == AUDIO_STREAM) ||
314  (StreamType(stream) == ANC_STREAM))
315  {
316  if (GetSFPActive(sfp) == false)
317  {
319  return false;
320  }
321 
322  SetRxStreamEnable(sfp, stream, false);
323 
324  ResetDepacketizerStream(stream);
325  SetupDepacketizerStream(stream,rxConfig);
326  SetupDecapsulatorStream(sfp, stream, rxConfig);
327  return true;
328  }
329  else
330  {
332  return false;
333  }
334 }
335 
336 void CNTV2Config2110::SetupDecapsulatorStream(const eSFP sfp, const NTV2Stream stream, const rx_2110Config & rxConfig)
337 {
338  uint32_t decapBaseAddr = GetDecapsulatorAddress(sfp, stream);
339 
340  // source ip address
341  uint32_t sourceIp = AJANetwork::aja_inet_addr(rxConfig.sourceIP.c_str());
342  sourceIp = NTV2EndianSwap32(sourceIp);
343  mDevice.WriteRegister(kRegDecap_match_src_ip + decapBaseAddr, sourceIp);
344 
345  // dest ip address
346  uint32_t destIp = AJANetwork::aja_inet_addr(rxConfig.destIP.c_str());
347  destIp = NTV2EndianSwap32(destIp);
348  mDevice.WriteRegister(kRegDecap_match_dst_ip + decapBaseAddr, destIp);
349 
350  // source port
352 
353  // dest port
354  mDevice.WriteRegister(kRegDecap_match_udp_dst_port + decapBaseAddr, rxConfig.destPort);
355 
356  // ssrc
357  mDevice.WriteRegister(kRegDecap_match_ssrc + decapBaseAddr, rxConfig.ssrc);
358 
359  // vlan
360  //WriteRegister(kRegDecap_match_vlan + decapBaseAddr, rxConfig.VLAN);
361 
362  // payloadType
363  mDevice. WriteRegister(kRegDecap_match_payload + decapBaseAddr, rxConfig.payloadType);
364 
365  // matching
366  mDevice.WriteRegister(kRegDecap_match_sel + decapBaseAddr, rxConfig.rxMatch);
367 }
368 
370 {
371  uint32_t depacketizerBaseAddr = GetDepacketizerAddress(stream);
372 
373  if (StreamType(stream) == VIDEO_STREAM)
374  {
375  mDevice.WriteRegister(kReg4175_depkt_control + depacketizerBaseAddr, 0x00);
376  }
377  else if (StreamType(stream) == AUDIO_STREAM)
378  {
379  mDevice.WriteRegister(kReg3190_depkt_enable + depacketizerBaseAddr, 0x00);
380  }
381 }
382 
384 {
385  uint32_t depacketizerBaseAddr = GetDepacketizerAddress(stream);
386 
387  if (StreamType(stream) == VIDEO_STREAM)
388  {
389  mDevice.WriteRegister(kReg4175_depkt_control + depacketizerBaseAddr, 0x01);
390  }
391  else if (StreamType(stream) == AUDIO_STREAM)
392  {
393  mDevice.WriteRegister(kReg3190_depkt_enable + depacketizerBaseAddr, 0x01);
394  }
395 }
396 
398 {
399  // disable decasulator
400  uint32_t decapBaseAddr = GetDecapsulatorAddress(sfp, stream);
401  mDevice.WriteRegister(kRegDecap_chan_enable + decapBaseAddr, 0x00);
402 }
403 
405 {
406  // enable decasulator
407  uint32_t decapBaseAddr = GetDecapsulatorAddress(sfp, stream);
408  mDevice.WriteRegister(kRegDecap_chan_enable + decapBaseAddr, 0x01);
409 }
410 
412 {
413  if (StreamType(stream) == VIDEO_STREAM)
414  {
415  uint32_t val;
416  uint32_t bit;
417 
418  switch(stream)
419  {
420  default:
421  case NTV2_VIDEO1_STREAM:
422  bit = BIT(16);
423  break;
424  case NTV2_VIDEO2_STREAM:
425  bit = BIT(17);
426  break;
427  case NTV2_VIDEO3_STREAM:
428  bit = BIT(18);
429  break;
430  case NTV2_VIDEO4_STREAM:
431  bit = BIT(19);
432  break;
433  }
434 
435  // read/modify/write reset bit for a given channel
437 
438  // Set reset bit
439  val |= bit;
441 
442  // Unset reset bit
443  val &= ~bit;
445 
446  // Wait just a bit
448  }
449 }
450 
452 {
453  if (StreamType(stream) == VIDEO_STREAM)
454  {
455  uint32_t val;
456  uint32_t bit;
457 
458  switch(stream)
459  {
460  default:
461  case NTV2_VIDEO1_STREAM:
462  bit = BIT(0);
463  break;
464  case NTV2_VIDEO2_STREAM:
465  bit = BIT(1);
466  break;
467  case NTV2_VIDEO3_STREAM:
468  bit = BIT(2);
469  break;
470  case NTV2_VIDEO4_STREAM:
471  bit = BIT(3);
472  break;
473  }
474 
475  // read/modify/write reset bit for a given channel
477 
478  // Set reset bit
479  val |= bit;
481 
482  // Unset reset bit
483  val &= ~bit;
485 
486  // Wait just a bit
488  }
489 }
490 
492 {
493  if (StreamType(stream) == VIDEO_STREAM)
494  {
495  SetVideoFormatForRxTx(stream, (NTV2VideoFormat) rxConfig.videoFormat, true);
496  }
497  else if (StreamType(stream) == AUDIO_STREAM)
498  {
499  // setup 3190 depacketizer
500  uint32_t depacketizerBaseAddr = GetDepacketizerAddress(stream);
501 
502  mDevice.WriteRegister(kReg3190_depkt_enable + depacketizerBaseAddr, 0x00);
503  uint32_t num_samples = (rxConfig.audioPktInterval == PACKET_INTERVAL_125uS) ? 6 : 48;
504  uint32_t num_channels = rxConfig.numAudioChannels;
505  uint32_t val = (num_samples << 8) + num_channels;
506  mDevice.WriteRegister(kReg3190_depkt_config + depacketizerBaseAddr,val);
507 
508  // audio channels
509  mDevice.WriteRegister(kReg3190_depkt_enable + depacketizerBaseAddr,0x01);
510  }
511 }
512 
513 void CNTV2Config2110::SetVideoFormatForRxTx(const NTV2Stream stream, const NTV2VideoFormat format, const bool rx)
514 {
515  if (StreamType(stream) == VIDEO_STREAM)
516  {
518 
522  bool is2K = fd.Is2KFormat();
523 
524  uint32_t val = ( (((uint32_t) fr) << 8) |
525  (((uint32_t) fg) << 4) |
526  ((uint32_t) std ) );
527 
528  if (is2K)
529  val += BIT(13);
530 
531  if (NTV2_IS_PSF_VIDEO_FORMAT (format))
532  val += BIT(15);
533 
534  uint32_t reg, reg2;
535  if (rx)
536  {
537  reg = stream - NTV2_CHANNEL1 + kRegRxVideoDecode1;
538  reg2 = stream - NTV2_CHANNEL1 + kRegRxNtv2VideoDecode1;
539  }
540  else
541  {
542  reg = stream - NTV2_CHANNEL1 + kRegTxVideoDecode1;
543  reg2 = stream - NTV2_CHANNEL1 + kRegTxNtv2VideoDecode1;
544  }
545 
546  // Write the format for the firmware and also tuck it away in NTV2 flavor so we can retrieve it easily
548  mDevice.WriteRegister(reg2 + SAREK_REGS2, format);
549  }
550 }
551 
552 void CNTV2Config2110::GetVideoFormatForRxTx(const NTV2Stream stream, NTV2VideoFormat & format, uint32_t & hwFormat, const bool rx)
553 {
554  if (StreamType(stream) == VIDEO_STREAM)
555  {
556  uint32_t reg, reg2, value;
557  if (rx)
558  {
559  reg = stream - NTV2_CHANNEL1 + kRegRxVideoDecode1;
560  reg2 = stream - NTV2_CHANNEL1 + kRegRxNtv2VideoDecode1;
561  }
562  else
563  {
564  reg = stream - NTV2_CHANNEL1 + kRegTxVideoDecode1;
565  reg2 = stream - NTV2_CHANNEL1 + kRegTxNtv2VideoDecode1;
566  }
567 
568  // Write the format for the firmware and also tuck it away in NTV2 flavor so we can retrieve it easily
570  hwFormat = value;
571  mDevice.ReadRegister(reg2 + SAREK_REGS2, value);
572  format = (NTV2VideoFormat)value;
573  }
574 }
575 
577 {
580  {
582  return false;
583  }
584 
585  if ((StreamType(stream) == VIDEO_STREAM) ||
586  (StreamType(stream) == AUDIO_STREAM) ||
587  (StreamType(stream) == ANC_STREAM))
588  {
589  uint32_t val;
590  uint32_t depacketizerBaseAddr;
591 
592  // get address,strean
593  uint32_t decapBaseAddr = GetDecapsulatorAddress(sfp, stream);
594 
595  // source ip address
596  mDevice.ReadRegister(kRegDecap_match_src_ip + decapBaseAddr, val);
597  struct in_addr in;
598  in.s_addr = NTV2EndianSwap32(val);
599  char * ip = AJANetwork::aja_inet_ntoa(in);
600  rxConfig.sourceIP = ip;
601 
602  // dest ip address
603  mDevice.ReadRegister(kRegDecap_match_dst_ip + decapBaseAddr, val);
604  in.s_addr = NTV2EndianSwap32(val);
605  ip = AJANetwork::aja_inet_ntoa(in);
606  rxConfig.destIP = ip;
607 
608  // source port
609  mDevice.ReadRegister(kRegDecap_match_udp_src_port + decapBaseAddr, rxConfig.sourcePort);
610 
611  // dest port
612  mDevice.ReadRegister(kRegDecap_match_udp_dst_port + decapBaseAddr, rxConfig.destPort);
613 
614  // ssrc
615  mDevice.ReadRegister(kRegDecap_match_ssrc + decapBaseAddr, rxConfig.ssrc);
616 
617  // vlan
618  //mDevice.ReadRegister(kRegDecap_match_vlan + decapBaseAddr, val);
619  //rxConfig.VLAN = val & 0xffff;
620 
621  // payloadType
622  mDevice.ReadRegister(kRegDecap_match_payload + decapBaseAddr, val);
623  rxConfig.payloadType = val & 0x7f;
624 
625  // matching
626  mDevice.ReadRegister(kRegDecap_match_sel + decapBaseAddr, rxConfig.rxMatch);
627 
628  if (StreamType(stream) == VIDEO_STREAM)
629  {
630  NTV2VideoFormat format;
631  uint32_t hwFormat;
632 
633  depacketizerBaseAddr = GetDepacketizerAddress(stream);
634  GetVideoFormatForRxTx(stream, format, hwFormat, true);
635  rxConfig.videoFormat = format;
636  }
637  else if (StreamType(stream) == AUDIO_STREAM)
638  {
639  uint32_t samples;
640 
641  depacketizerBaseAddr = GetDepacketizerAddress(stream);
642  mDevice.ReadRegister(kReg3190_depkt_config + depacketizerBaseAddr, samples);
643  rxConfig.audioPktInterval = (((samples >> 8) & 0xff) == 6) ? PACKET_INTERVAL_125uS : PACKET_INTERVAL_1mS;
644  rxConfig.numAudioChannels = samples & 0xff;
645  }
646  return true;
647  }
648  else
649  {
651  return false;
652  }
653 }
654 
655 bool CNTV2Config2110::SetRxStreamEnable(const eSFP sfp, const NTV2Stream stream, bool enable)
656 {
659  {
661  return false;
662  }
663 
664  if ((StreamType(stream) == VIDEO_STREAM) ||
665  (StreamType(stream) == AUDIO_STREAM) ||
666  (StreamType(stream) == ANC_STREAM))
667  {
668  if (GetSFPActive(sfp) == false)
669  {
671  return false;
672  }
673 
674  if (enable)
675  {
676  uint32_t decapBaseAddr = GetDecapsulatorAddress(sfp, stream);
677 
678  // get source and dest ip address
679  uint32_t srcIp, destIp;
680  mDevice.ReadRegister(kRegDecap_match_src_ip + decapBaseAddr, srcIp);
681  mDevice.ReadRegister(kRegDecap_match_dst_ip + decapBaseAddr, destIp);
682 
683  // setup IGMP subscription
684  uint8_t ip0 = (destIp & 0xff000000)>> 24;
685  if (ip0 >= 224 && ip0 <= 239)
686  {
687  // is multicast
688  SetIGMPGroup(sfp, stream, destIp, srcIp, true);
689  }
690  else
691  {
692  UnsetIGMPGroup(sfp, stream);
693  }
694 
695  EnableDepacketizerStream(stream);
696  EnableDecapsulatorStream(sfp, stream);
697  }
698  else
699  {
700  // disable IGMP subscription
701  bool disableIGMP;
702  GetIGMPDisable(sfp, disableIGMP);
703  if (!disableIGMP)
704  {
705  EnableIGMPGroup(sfp, stream, false);
706  }
707 
708  DisableDecapsulatorStream(sfp, stream);
710  }
711  return true;
712  }
713  else
714  {
716  return false;
717  }
718 }
719 
720 bool CNTV2Config2110::GetRxStreamEnable(const eSFP sfp, const NTV2Stream stream, bool & enabled)
721 {
724  {
726  return false;
727  }
728 
729  enabled = false;
730 
731  if ((StreamType(stream) == VIDEO_STREAM) ||
732  (StreamType(stream) == AUDIO_STREAM) ||
733  (StreamType(stream) == ANC_STREAM))
734  {
735  // get address
736  uint32_t decapBaseAddr = GetDecapsulatorAddress(sfp, stream);
737 
738  uint32_t val;
739  mDevice.ReadRegister(kRegDecap_chan_enable + decapBaseAddr, val);
740  enabled = (val & 0x01);
741  return true;
742  }
743  else
744  {
746  return false;
747  }
748 }
749 
750 bool CNTV2Config2110::GetRxPacketCount(const NTV2Stream stream, uint32_t & packets)
751 {
752  uint32_t depacketizerBaseAddr;
753 
754  if (StreamType(stream) == VIDEO_STREAM)
755  {
756  depacketizerBaseAddr = GetDepacketizerAddress(stream);
757  mDevice.ReadRegister(kReg4175_depkt_rx_pkt_cnt+ depacketizerBaseAddr, packets);
758  }
759  else if (StreamType(stream) == AUDIO_STREAM)
760  {
761  depacketizerBaseAddr = GetDepacketizerAddress(stream);
762  mDevice.ReadRegister(kReg3190_depkt_rx_pkt_count + depacketizerBaseAddr, packets);
763  }
764  else
765  {
766  packets = 0;
767  }
768 
769  return true;
770 }
771 
772 bool CNTV2Config2110::GetRxByteCount(const NTV2Stream stream, uint32_t & bytes)
773 {
774  uint32_t depacketizerBaseAddr;
775 
776  if (StreamType(stream) == VIDEO_STREAM)
777  {
778  depacketizerBaseAddr = GetDepacketizerAddress(stream);
779  mDevice.ReadRegister(kReg4175_depkt_rx_byte_cnt+ depacketizerBaseAddr, bytes);
780  }
781  // Currently only the video stream reports bytes
782  else
783  {
784  bytes = 0;
785  }
786 
787  return true;
788 }
789 
790 bool CNTV2Config2110::GetRxByteCount(const eSFP sfp, uint64_t & bytes)
791 {
792  uint32_t val_lo, val_hi;
793 
794  if (sfp == SFP_1)
795  {
798  }
799  else
800  {
803  }
804 
805  bytes = ((uint64_t)val_hi << 32) + val_lo;
806  return true;
807 }
808 
809 bool CNTV2Config2110::GetTxPacketCount(const NTV2Stream stream, uint32_t & packets)
810 {
811  if (StreamType(stream) == VIDEO_STREAM)
812  {
813  uint32_t count;
814 
815  uint32_t baseAddrPacketizer = GetPacketizerAddress(NTV2_VIDEO1_STREAM, GetSampling(SFP_1, stream));
816  mDevice.ReadRegister(kReg4175_pkt_tx_pkt_cnt + baseAddrPacketizer, count);
817  packets = count;
818  }
819  else
820  {
821  // TODO:
822  packets = 0;
823  }
824 
825  return true;
826 }
827 
828 bool CNTV2Config2110::GetTxByteCount(const eSFP sfp, uint64_t & bytes)
829 {
830  uint32_t val_lo, val_hi;
831 
832  if (sfp == SFP_1)
833  {
836  }
837  else
838  {
841  }
842 
843  bytes = ((uint64_t)val_hi << 32) + val_lo;
844  return true;
845 }
846 
847 int CNTV2Config2110::LeastCommonMultiple(int a,int b)
848 {
849  int m = a;
850  int n = b;
851  while (m != n)
852  {
853  if (m < n)
854  m += a;
855  else
856  n +=b;
857  }
858  return m;
859 }
860 
862 {
863  if (GetSFPActive(SFP_1) == false)
864  {
866  return false;
867  }
868 
869  ResetPacketizerStream(stream);
870 
871  SetFramerStream(SFP_1, stream, txConfig);
872  SetFramerStream(SFP_2, stream, txConfig);
873  SetSampling(SFP_1, stream, txConfig.videoSamples);
874  SetSampling(SFP_2, stream, txConfig.videoSamples);
875 
876  if (StreamType(stream) == VIDEO_STREAM)
877  {
878  // video setup 3190 packetizer
879  uint32_t baseAddrPacketizer = GetPacketizerAddress(stream, GetSampling(SFP_1, stream));
880 
881  NTV2VideoFormat vfmt = txConfig.videoFormat;
882 
883  // Write the video format into the arbitrator
884  SetVideoFormatForRxTx(stream, vfmt, false);
885 
886  // setup 4175 packetizer
887  bool interlaced = false;
889  {
890  interlaced = true;
891  }
892  else if (NTV2_IS_PSF_VIDEO_FORMAT(vfmt))
893  {
894  interlaced = true;
895  }
896 
898 
899  // width
900  uint32_t width = fd.GetRasterWidth();
901  mDevice.WriteRegister(kReg4175_pkt_width + baseAddrPacketizer,width);
902 
903  // height
904  uint32_t height = fd.GetRasterHeight();
905  if (interlaced)
906  {
907  height /= 2;
908  }
909  mDevice.WriteRegister(kReg4175_pkt_height + baseAddrPacketizer,height);
910 
911  // video format = sampling
912  int vf;
913  int componentsPerPixel;
914  int componentsPerUnit;
915 
916  VPIDSampling sampling = GetSampling(SFP_1, stream);
917  switch(sampling)
918  {
920  vf = 0;
921  componentsPerPixel = 3;
922  componentsPerUnit = 3;
923  break;
924  default:
926  componentsPerPixel = 2;
927  componentsPerUnit = 4;
928  vf = 2;
929  break;
930  }
931  mDevice.WriteRegister(kReg4175_pkt_vid_fmt + baseAddrPacketizer,vf);
932 
933  const int bitsPerComponent = 10;
934  const int pixelsPerClock = 1;
935  int activeLineLength = (width * componentsPerPixel * bitsPerComponent)/8;
936 
937  int pixelGroup_root = LeastCommonMultiple((bitsPerComponent * componentsPerUnit), 8);
938  int pixelGroupSize = pixelGroup_root/8;
939 
940  int bytesPerCycle = (pixelsPerClock * bitsPerComponent * componentsPerPixel)/8;
941 
942  int lcm = LeastCommonMultiple(pixelGroupSize,bytesPerCycle);
943  int payloadLength_root = min(activeLineLength,1376)/lcm;
944  int payloadLength = payloadLength_root * lcm;
945 
946  float pktsPerLine = ((float)activeLineLength)/((float)payloadLength);
947  int ipktsPerLine = (int)ceil(pktsPerLine);
948 
949  int payloadLengthLast = activeLineLength - (payloadLength * (ipktsPerLine -1));
950 
951  int ppp = (payloadLength/pixelGroupSize) * 2; // as per JeffL
952 
953  if ((sampling == VPIDSampling_GBR_444) &&
956  {
958  {
959  ipktsPerLine = 0x07;
960  payloadLength = 0x0558;
961  payloadLengthLast = 0x03f0;
962  ppp = 0x0130;
963  }
964  else if (NTV2_IS_720P_VIDEO_FORMAT(txConfig.videoFormat))
965  {
966  ipktsPerLine = 0x05;
967  payloadLength = 0x0558;
968  payloadLengthLast = 0x0120;
969  ppp = 0x0130;
970  }
971  // assume 1920x1080 format
972  else
973  {
974  ipktsPerLine = 0x07;
975  payloadLength = 0x0558;
976  payloadLengthLast = 0x01b0;
977  ppp = 0x0130;
978  }
979  }
980 
981  // pkts per line
982  mDevice.WriteRegister(kReg4175_pkt_pkts_per_line + baseAddrPacketizer,ipktsPerLine);
983 
984  // payload length
985  mDevice.WriteRegister(kReg4175_pkt_payload_len + baseAddrPacketizer,payloadLength);
986 
987  // payload length last
988  mDevice.WriteRegister(kReg4175_pkt_payload_len_last + baseAddrPacketizer,payloadLengthLast);
989 
990  // payloadType
991  mDevice.WriteRegister(kReg4175_pkt_payload_type + baseAddrPacketizer,txConfig.payloadType);
992 
993  // SSRC
994  mDevice.WriteRegister(kReg4175_pkt_ssrc + baseAddrPacketizer,txConfig.ssrc);
995 
996  // pix per pkt
997  mDevice.WriteRegister(kReg4175_pkt_pix_per_pkt + baseAddrPacketizer,ppp);
998 
999  // interlace
1000  int ilace = (interlaced) ? 0x01 : 0x00;
1001  mDevice.WriteRegister(kReg4175_pkt_interlace_ctrl + baseAddrPacketizer,ilace);
1002 
1003  // end setup 4175 packetizer
1004  SetTxFormat(VideoStreamToChannel(stream), txConfig.videoFormat);
1005  }
1006  else if (StreamType(stream) == AUDIO_STREAM)
1007  {
1008  // audio setup 3190 packetizer
1009  uint32_t baseAddrPacketizer = GetPacketizerAddress(stream, GetSampling(SFP_1, stream));
1010 
1011  uint32_t audioChans = txConfig.numAudioChannels;
1012  uint32_t samples = (txConfig.audioPktInterval == PACKET_INTERVAL_125uS) ? 6 : 48;
1013  uint32_t plength = audioChans * samples * 3;
1014 
1015  // audio select
1016  uint32_t aselect = ((uint32_t)txConfig.firstAudioChannel << 16 ) + (audioChans-1);
1017  aselect = (txConfig.channel << 24) + aselect;
1018  uint32_t offset = (stream - NTV2_AUDIO1_STREAM) * 4;
1020 
1021  // num samples
1022  mDevice.WriteRegister(kReg3190_pkt_num_samples + baseAddrPacketizer, samples);
1023 
1024  // audio channels - zero-based (i.e. 0 = 1 channel)
1025  mDevice.WriteRegister(kReg3190_pkt_num_audio_channels + baseAddrPacketizer, audioChans);
1026 
1027  // payload length
1028  mDevice.WriteRegister(kReg3190_pkt_payload_len + baseAddrPacketizer, plength);
1029 
1030  // payloadType
1031  mDevice.WriteRegister(kReg3190_pkt_payload_type + baseAddrPacketizer, txConfig.payloadType);
1032 
1033  // ssrc
1034  mDevice.WriteRegister(kReg3190_pkt_ssrc + baseAddrPacketizer, txConfig.ssrc);
1035  }
1036  else if (StreamType(stream) == ANC_STREAM)
1037  {
1038  uint32_t channel = (uint32_t)(stream-NTV2_ANC1_STREAM);
1039 
1040  // Setup the anc inserter params, these are static values that don't change from frame to frame
1041  mDevice.AncInsertSetIPParams(channel, channel+4, txConfig.payloadType, txConfig.ssrc);
1042 
1043  // for anc streams we tuck away these values
1044  // payloadType
1046 
1047  // ssrc
1049  }
1050 
1051  return true;
1052 }
1053 
1054 
1055 bool CNTV2Config2110::SetFramerStream(const eSFP sfp, const NTV2Stream stream, const tx_2110Config & txConfig)
1056 {
1057  // get frame address
1058  uint32_t baseAddrFramer = GetFramerAddress(sfp, stream);
1059 
1060  // select channel
1061  SelectTxFramerChannel(stream, baseAddrFramer);
1062 
1063  // setup framer
1064  // hold off access while we update channel regs
1065  AcquireFramerControlAccess(baseAddrFramer);
1066 
1067  uint32_t val = (txConfig.tos << 8) | txConfig.ttl;
1068  WriteChannelRegister(kRegFramer_ip_hdr_media + baseAddrFramer, val);
1069 
1070  int index = (int)sfp;
1071  // dest ip address
1072  uint32_t destIp = AJANetwork::aja_inet_addr(txConfig.remoteIP[index].c_str());
1073  destIp = NTV2EndianSwap32(destIp);
1074  WriteChannelRegister(kRegFramer_dst_ip + baseAddrFramer,destIp);
1075 
1076  // source port
1077  WriteChannelRegister(kRegFramer_udp_src_port + baseAddrFramer,txConfig.localPort[index]);
1078 
1079  // dest port
1080  WriteChannelRegister(kRegFramer_udp_dst_port + baseAddrFramer,txConfig.remotePort[index]);
1081 
1082  // MAC address
1083  uint32_t hi;
1084  uint32_t lo;
1085  bool rv = GetMACAddress(sfp, stream, txConfig.remoteIP[index], hi, lo);
1086  if (!rv) return false;
1087  WriteChannelRegister(kRegFramer_dest_mac_lo + baseAddrFramer,lo);
1088  WriteChannelRegister(kRegFramer_dest_mac_hi + baseAddrFramer,hi);
1089 
1090  // enable register updates
1091  ReleaseFramerControlAccess(baseAddrFramer);
1092 
1093  // end framer setup
1094  return true;
1095 }
1096 
1097 
1099 {
1100  uint32_t baseAddrPacketizer;
1101 
1102  GetFramerStream(SFP_1, stream, txConfig);
1103  GetFramerStream(SFP_2, stream, txConfig);
1104  txConfig.videoSamples = GetSampling(SFP_1, stream);
1105 
1106  uint32_t val;
1107  if (StreamType(stream) == VIDEO_STREAM)
1108  {
1109  // select video packetizer
1110  baseAddrPacketizer = GetPacketizerAddress(stream, GetSampling(SFP_1, stream));
1111 
1112  // payloadType
1113  mDevice.ReadRegister(kReg4175_pkt_payload_type + baseAddrPacketizer, val);
1114  txConfig.payloadType = (uint16_t)val;
1115 
1116  // SSRC
1117  mDevice.ReadRegister(kReg4175_pkt_ssrc + baseAddrPacketizer, txConfig.ssrc);
1118 
1119  // Video format
1120  GetTxFormat(VideoStreamToChannel(stream), txConfig.videoFormat);
1121  }
1122  else if (StreamType(stream) == AUDIO_STREAM)
1123  {
1124  // select audio packetizer
1125  baseAddrPacketizer = GetPacketizerAddress(stream, GetSampling(SFP_1, stream));
1126 
1127  // audio - payloadType
1128  mDevice.ReadRegister(kReg3190_pkt_payload_type + baseAddrPacketizer, val);
1129  txConfig.payloadType = (uint16_t)val;
1130 
1131  // ssrc
1132  mDevice.ReadRegister(kReg3190_pkt_ssrc + baseAddrPacketizer, txConfig.ssrc);
1133 
1134  // audio select
1135  uint32_t offset = Get2110TxStreamIndex(stream) * 4;
1136  uint32_t aselect;
1138 
1139  txConfig.firstAudioChannel = (aselect >> 16) & 0xff;
1140  txConfig.numAudioChannels = (aselect & 0xff) + 1;
1141 
1142  // packet interval
1143  uint32_t samples;
1144  mDevice.ReadRegister(kReg3190_pkt_num_samples + baseAddrPacketizer, samples);
1145  txConfig.audioPktInterval = (samples == 6) ? PACKET_INTERVAL_125uS : PACKET_INTERVAL_1mS;
1146  }
1147  else if (StreamType(stream) == ANC_STREAM)
1148  {
1149  uint32_t regOffset = (uint32_t)(stream-NTV2_ANC1_STREAM);
1150 
1151  // payloadType
1153  txConfig.payloadType = (uint16_t)val;
1154 
1155  // ssrc
1157  }
1158 
1159  return true;
1160 }
1161 
1162 void CNTV2Config2110::GetFramerStream(const eSFP sfp, const NTV2Stream stream, tx_2110Config & txConfig)
1163 {
1164  int index = (int)sfp;
1165 
1166  // get frame address
1167  uint32_t baseAddrFramer = GetFramerAddress(sfp, stream);
1168 
1169  // Select channel
1170  SelectTxFramerChannel(stream, baseAddrFramer);
1171 
1172  uint32_t val;
1173  ReadChannelRegister(kRegFramer_ip_hdr_media + baseAddrFramer,&val);
1174  txConfig.ttl = val & 0xff;
1175  txConfig.tos = (val & 0xff00) >> 8;
1176 
1177  // dest ip address
1178  ReadChannelRegister(kRegFramer_dst_ip + baseAddrFramer,&val);
1179  struct in_addr in;
1180  in.s_addr = NTV2EndianSwap32(val);
1181  char * ip = AJANetwork::aja_inet_ntoa(in);
1182  txConfig.remoteIP[index] = ip;
1183 
1184  // source port
1185  ReadChannelRegister(kRegFramer_udp_src_port + baseAddrFramer,&txConfig.localPort[index]);
1186 
1187  // dest port
1188  ReadChannelRegister(kRegFramer_udp_dst_port + baseAddrFramer,&txConfig.remotePort[index]);
1189 }
1190 
1191 bool CNTV2Config2110::SetTxStreamEnable(const NTV2Stream stream, bool enableSfp1, bool enableSfp2)
1192 {
1193  if (enableSfp1 && (GetSFPActive(SFP_1) == false))
1194  {
1196  return false;
1197  }
1198 
1199  if (enableSfp2 && (GetSFPActive(SFP_2) == false))
1200  {
1202  return false;
1203  }
1204 
1205  EnableFramerStream(SFP_1, stream, enableSfp1);
1206  EnableFramerStream(SFP_2, stream, enableSfp2);
1207  SetArbiter(SFP_1, stream, enableSfp1);
1208  SetArbiter(SFP_2, stream, enableSfp2);
1209 
1210  // Generate and push the SDP
1211  GenSDP(enableSfp1, enableSfp2, stream);
1212 
1213  if ((StreamType(stream) == VIDEO_STREAM) || (StreamType(stream) == AUDIO_STREAM))
1214  {
1215  // ** Packetizer
1216  uint32_t packetizerBaseAddr = GetPacketizerAddress(stream, GetSampling(SFP_1, stream));
1217 
1218  if (enableSfp1 || enableSfp2)
1219  {
1220  // enable
1221  mDevice.WriteRegister(kReg4175_pkt_ctrl + packetizerBaseAddr, 0x00);
1222  mDevice.WriteRegister(kReg4175_pkt_ctrl + packetizerBaseAddr, 0x80);
1223  mDevice.WriteRegister(kReg4175_pkt_ctrl + packetizerBaseAddr, 0x81);
1224  }
1225  else
1226  {
1227  // disable
1228  mDevice.WriteRegister(kReg4175_pkt_ctrl + packetizerBaseAddr, 0x00);
1229  }
1230  }
1231 
1232  return true;
1233 }
1234 
1235 void CNTV2Config2110::EnableFramerStream(const eSFP sfp, const NTV2Stream stream, bool enable)
1236 {
1237  // ** Framer
1238  // get frame address
1239  uint32_t baseAddrFramer = GetFramerAddress(sfp, stream);
1240 
1241  // select channel
1242  SelectTxFramerChannel(stream, baseAddrFramer);
1243 
1244  // hold off access while we update channel regs
1245  AcquireFramerControlAccess(baseAddrFramer);
1246 
1247  if (enable)
1248  {
1249  uint32_t localIp;
1250  if (sfp == SFP_1)
1251  {
1253  }
1254  else
1255  {
1257  }
1258 
1259  WriteChannelRegister(kRegFramer_src_ip + baseAddrFramer, NTV2EndianSwap32(localIp));
1260 
1261  // enable
1262  WriteChannelRegister(kRegFramer_chan_ctrl + baseAddrFramer, 0x01); // enables tx over mac1/mac2
1263  }
1264  else
1265  {
1266  // disable
1267  WriteChannelRegister(kRegFramer_chan_ctrl + baseAddrFramer, 0x0); // disables channel
1268  }
1269 
1270  // enable register updates
1271  ReleaseFramerControlAccess(baseAddrFramer);
1272 
1273  // ** Framer end
1274 }
1275 
1276 bool CNTV2Config2110::GetTxStreamEnable(const NTV2Stream stream, bool & sfp1Enabled, bool & sfp2Enabled)
1277 {
1278  GetArbiter(SFP_1, stream, sfp1Enabled);
1279  GetArbiter(SFP_2, stream, sfp2Enabled);
1280  return true;
1281 }
1282 
1284 {
1285  uint32_t val = ((uint32_t)id[0] << 24) | ((uint32_t)id[1] << 16) | ((uint32_t)id[2] << 8) | ((uint32_t)id[3] << 0);
1287  val = ((uint32_t)id[4] << 24) | ((uint32_t)id[5] << 16) | ((uint32_t)id[6] << 8) | ((uint32_t)id[7] << 0);
1289  return true;
1290 }
1291 
1293 {
1294  uint32_t val;
1296  id[0] = val >> 24;
1297  id[1] = val >> 16;
1298  id[2] = val >> 8;
1299  id[3] = val >> 0;
1301  id[4] = val >> 24;
1302  id[5] = val >> 16;
1303  id[6] = val >> 8;
1304  id[7] = val >> 0;
1305  return true;
1306 }
1307 
1308 bool CNTV2Config2110::SetPTPDomain(const uint8_t domain)
1309 {
1310  mDevice.WriteRegister(kRegPll_swptp_Domain + SAREK_PLL, (uint32_t)domain);
1311  return true;
1312 }
1313 
1314 bool CNTV2Config2110::GetPTPDomain(uint8_t &domain)
1315 {
1316  uint32_t val;
1318  domain = val;
1319  return true;
1320 }
1321 
1323 {
1324  uint32_t val = 0;
1325 
1327  ptpStatus.PTP_gmId[0] = val >> 24;
1328  ptpStatus.PTP_gmId[1] = val >> 16;
1329  ptpStatus.PTP_gmId[2] = val >> 8;
1330  ptpStatus.PTP_gmId[3] = val >> 0;
1331 
1333  ptpStatus.PTP_gmId[4] = val >> 24;
1334  ptpStatus.PTP_gmId[5] = val >> 16;
1335  ptpStatus.PTP_gmId[6] = val >> 8;
1336  ptpStatus.PTP_gmId[7] = val >> 0;
1337 
1339  ptpStatus.PTP_masterId[0] = val >> 24;
1340  ptpStatus.PTP_masterId[1] = val >> 16;
1341  ptpStatus.PTP_masterId[2] = val >> 8;
1342  ptpStatus.PTP_masterId[3] = val >> 0;
1343 
1345  ptpStatus.PTP_masterId[4] = val >> 24;
1346  ptpStatus.PTP_masterId[5] = val >> 16;
1347  ptpStatus.PTP_masterId[6] = val >> 8;
1348  ptpStatus.PTP_masterId[7] = val >> 0;
1349 
1351  ptpStatus.PTP_domain = val;
1352 
1354  ptpStatus.PTP_LockedState = (PTPLockStatus)val;
1355 
1356  return true;
1357 }
1358 
1359 bool CNTV2Config2110::Set4KModeEnable(const bool enable)
1360 {
1361  if (!mDevice.IsMBSystemReady())
1362  {
1364  return false;
1365  }
1366 
1367  uint32_t val;
1369  if (enable)
1370  val |= BIT(0);
1371  else
1372  val &= ~BIT(0);
1373 
1375 
1376  return true;
1377 }
1378 
1380 {
1381  uint32_t val;
1383 
1384  enable = val & 0x01;
1385  return true;
1386 }
1387 
1389 {
1390  if (!mDevice.IsMBSystemReady())
1391  {
1393  return false;
1394  }
1395 
1396  uint32_t val;
1398  if (enable)
1399  val |= BIT(4);
1400  else
1401  val &= ~BIT(4);
1402 
1404 
1405  return true;
1406 }
1407 
1409 {
1410  uint32_t val;
1412 
1413  enable = val & 0x10;
1414  return true;
1415 }
1416 
1417 bool CNTV2Config2110::SetIPServicesControl(const bool enable, const bool forceReconfig)
1418 {
1419  uint32_t val = 0;
1420  if (enable)
1421  val = 1;
1422 
1423  if (forceReconfig)
1424  val |= BIT(1);
1425 
1427 
1428  return true;
1429 }
1430 
1431 bool CNTV2Config2110::GetIPServicesControl(bool & enable, bool & forceReconfig)
1432 {
1433  uint32_t val;
1435 
1436  if (val & BIT(0))
1437  enable = true;
1438  else
1439  enable = false;
1440 
1441  if (val & BIT(1))
1442  forceReconfig = true;
1443  else
1444  forceReconfig = false;
1445 
1446  return true;
1447 }
1448 
1449 bool CNTV2Config2110::SetIGMPDisable(const eSFP sfp, const bool disable)
1450 {
1451  uint32_t val = (disable) ? 1 : 0;
1452  if (sfp == SFP_1 )
1453  {
1455  }
1456  else
1457  {
1459  }
1460  return true;
1461 }
1462 
1463 bool CNTV2Config2110::GetIGMPDisable(const eSFP sfp, bool & disabled)
1464 {
1465  uint32_t val;
1466  if (sfp == SFP_1 )
1467  {
1469  }
1470  else
1471  {
1473  }
1474 
1475  disabled = (val == 1) ? true : false;
1476 
1477  return true;
1478 }
1479 
1481 {
1482  uint32_t mbversion;
1483  switch (version)
1484  {
1485  case eIGMPVersion_2:
1486  mbversion = 2;
1487  break;
1488  case eIGMPVersion_3:
1489  mbversion = 3;
1490  break;
1491  default:
1493  return false;
1494  }
1495  return CNTV2MBController::SetIGMPVersion(mbversion);
1496 }
1497 
1499 {
1500  uint32_t version32;
1501  bool rv = mDevice.ReadRegister(SAREK_REGS + kRegSarekIGMPVersion, version32);
1502  version = (version32 == 2) ? eIGMPVersion_2 : eIGMPVersion_3;
1503  return rv;
1504 }
1505 
1507 //
1508 //
1509 //
1511 
1513 {
1514  uint32_t offset = 0;
1515 
1516  switch (stream)
1517  {
1518  case NTV2_VIDEO1_STREAM:
1519  offset = 0x00;
1520  break;
1521  case NTV2_VIDEO2_STREAM:
1522  offset = 0x20;
1523  break;
1524  case NTV2_VIDEO3_STREAM:
1525  offset = 0x40;
1526  break;
1527  case NTV2_VIDEO4_STREAM:
1528  offset = 0x60;
1529  break;
1530  case NTV2_AUDIO1_STREAM:
1531  offset = 0x10;
1532  break;
1533  case NTV2_AUDIO2_STREAM:
1534  offset = 0x30;
1535  break;
1536  case NTV2_AUDIO3_STREAM:
1537  offset = 0x50;
1538  break;
1539  case NTV2_AUDIO4_STREAM:
1540  offset = 0x70;
1541  break;
1542  case NTV2_ANC1_STREAM:
1543  offset = 0x80;
1544  break;
1545  case NTV2_ANC2_STREAM:
1546  offset = 0x90;
1547  break;
1548  case NTV2_ANC3_STREAM:
1549  offset = 0xA0;
1550  break;
1551  case NTV2_ANC4_STREAM:
1552  offset = 0xB0;
1553  break;
1554 
1555  default:
1556  break;
1557  }
1558 
1559  if (sfp == SFP_1)
1560  return SAREK_2110_DECAPSULATOR_0 + offset;
1561  else
1562  return SAREK_2110_DECAPSULATOR_1 + offset;
1563 }
1564 
1566 {
1567  uint32_t basePacketizer = 0;
1568 
1569  // Only video and audio streams have depacketizers
1570  if (StreamType(stream) == VIDEO_STREAM)
1571  {
1572  basePacketizer = videoDepacketizers[stream-NTV2_VIDEO1_STREAM];
1573  }
1574  else if (StreamType(stream) == AUDIO_STREAM)
1575  {
1576  basePacketizer = audioDepacketizers[stream-NTV2_AUDIO1_STREAM];
1577  }
1578 
1579  return basePacketizer;
1580 }
1581 
1582 uint32_t CNTV2Config2110::GetFramerAddress(const eSFP sfp, const NTV2Stream stream)
1583 {
1584  if (sfp == SFP_2)
1585  {
1586  if (StreamType(stream) == VIDEO_STREAM)
1588  else
1590  }
1591  else
1592  {
1593  if (StreamType(stream) == VIDEO_STREAM)
1595  else
1597  }
1598 }
1599 
1600 void CNTV2Config2110::SelectTxFramerChannel(const NTV2Stream stream, const uint32_t baseAddrFramer)
1601 {
1602  // select channel
1603  uint32_t index = Get2110TxStreamIndex(stream);
1604  SetChannel(kRegFramer_channel_access + baseAddrFramer, index);
1605 }
1606 
1607 uint32_t CNTV2Config2110::GetPacketizerAddress(const NTV2Stream stream, const VPIDSampling sampling)
1608 {
1609  uint32_t basePacketizer = 0;
1610 
1611  // Only video and audio streams have packetizers
1612  if (StreamType(stream) == VIDEO_STREAM)
1613  {
1614  if ((sampling == VPIDSampling_GBR_444) &&
1617  basePacketizer = videoRGB12Packetizers[stream-NTV2_VIDEO1_STREAM];
1618  else
1619  basePacketizer = videoPacketizers[stream-NTV2_VIDEO1_STREAM];
1620 
1621  uint32_t index = Get2110TxStreamIndex(stream);
1622  mDevice.WriteRegister(kReg4175_pkt_chan_num + basePacketizer, index);
1623  }
1624  else if (StreamType(stream) == AUDIO_STREAM)
1625  {
1626  basePacketizer = audioPacketizers[stream-NTV2_AUDIO1_STREAM];
1627  uint32_t index = Get2110TxStreamIndex(stream);
1628  mDevice.WriteRegister(kReg3190_pkt_chan_num + basePacketizer, index);
1629  }
1630 
1631  return basePacketizer;
1632 }
1633 
1634 bool CNTV2Config2110::ConfigurePTP (const eSFP sfp, const std::string localIPAddress)
1635 {
1636  uint32_t macLo;
1637  uint32_t macHi;
1638 
1639  // get primaray mac address
1640  uint32_t macAddressRegister = SAREK_REGS + kRegSarekMAC;
1641  if (sfp != SFP_1)
1642  {
1643  macAddressRegister += 2;
1644  }
1645  mDevice.ReadRegister(macAddressRegister, macHi);
1646  macAddressRegister++;
1647  mDevice.ReadRegister(macAddressRegister, macLo);
1648 
1649  uint32_t alignedMACHi = macHi >> 16;
1650  uint32_t alignedMACLo = (macLo >> 16) | ( (macHi & 0xffff) << 16);
1651 
1652  uint32_t addr = AJANetwork::aja_inet_addr(localIPAddress.c_str());
1653  addr = NTV2EndianSwap32(addr);
1654 
1655  // configure pll
1658 
1662  uint32_t val;
1664  if (val == 0)
1666  else
1669 
1670  //WriteChannelRegister(kRegPll_PTP_LclClkIdLo + SAREK_PLL, (0xfe << 24) | ((macHi & 0x000000ff) << 16) | (macLo >> 16));
1671  //WriteChannelRegister(kRegPll_PTP_LclClkIdHi + SAREK_PLL, (macHi & 0xffffff00) | 0xff);
1672 
1673  return true;
1674 }
1675 
1677 {
1678  return GetSFPInfo(sfp, data);
1679 }
1680 
1682 {
1683  uint32_t val;
1685  uint32_t val2;
1687 
1688  if (sfp == SFP_2)
1689  {
1690  sfpStatus.SFP_linkUp = (val & LINK_B_UP) ? true : false;
1691  sfpStatus.SFP_present = (val2 & SFP_2_NOT_PRESENT) ? false : true;
1692  sfpStatus.SFP_rxLoss = (val2 & SFP_2_RX_LOS) ? true : false;
1693  sfpStatus.SFP_txFault = (val2 & SFP_2_TX_FAULT) ? true : false;
1694  }
1695  else
1696  {
1697  sfpStatus.SFP_linkUp = (val & LINK_A_UP) ? true : false;
1698  sfpStatus.SFP_present = (val2 & SFP_1_NOT_PRESENT) ? false : true;
1699  sfpStatus.SFP_rxLoss = (val2 & SFP_1_RX_LOS) ? true : false;
1700  sfpStatus.SFP_txFault = (val2 & SFP_1_TX_FAULT) ? true : false;
1701  }
1702 
1703  return true;
1704 }
1705 
1707 {
1709 }
1710 
1712 {
1713  NTV2IpError error = mIpErrorCode;
1715  return error;
1716 }
1717 
1718 void CNTV2Config2110::AcquireFramerControlAccess(const uint32_t baseAddr)
1719 {
1720  WriteChannelRegister(kRegFramer_control + baseAddr, 0x00);
1721  uint32_t val;
1722  mDevice.ReadRegister(kRegFramer_status + baseAddr, val);
1723  while (val & BIT(1))
1724  {
1725  // Wait
1726  AJATime::Sleep(10);
1727 
1728  mDevice.ReadRegister(kRegFramer_status + baseAddr, val);
1729  }
1730 }
1731 
1732 void CNTV2Config2110::ReleaseFramerControlAccess(const uint32_t baseAddr)
1733 {
1734  WriteChannelRegister(kRegFramer_control + baseAddr, 0x02);
1735 }
1736 
1738 {
1739  // this stream number is a core 'channel' number
1740  uint32_t index = 0;
1741  switch (stream)
1742  {
1743  case NTV2_VIDEO1_STREAM:
1744  case NTV2_VIDEO2_STREAM:
1745  case NTV2_VIDEO3_STREAM:
1746  case NTV2_VIDEO4_STREAM:
1747  index = (uint32_t)(stream-NTV2_VIDEO1_STREAM);
1748  break;
1749 
1750  case NTV2_AUDIO1_STREAM:
1751  case NTV2_AUDIO2_STREAM:
1752  case NTV2_AUDIO3_STREAM:
1753  case NTV2_AUDIO4_STREAM:
1754  case NTV2_ANC1_STREAM:
1755  case NTV2_ANC2_STREAM:
1756  case NTV2_ANC3_STREAM:
1757  case NTV2_ANC4_STREAM:
1758  index = (uint32_t)(stream-NTV2_AUDIO1_STREAM);
1759  break;
1760 
1761  case NTV2_VIDEO4K_STREAM:
1762  default:
1763  break;
1764  }
1765  return index;
1766 }
1767 
1768 bool CNTV2Config2110::GetMACAddress(const eSFP port, const NTV2Stream stream, string remoteIP, uint32_t & hi, uint32_t & lo)
1769 {
1770  uint32_t destIp = AJANetwork::aja_inet_addr(remoteIP.c_str());
1771  destIp = NTV2EndianSwap32(destIp);
1772 
1773  uint32_t mac;
1774  MACAddr macaddr;
1775 
1776  // is remote address muticast?
1777  uint8_t ip0 = (destIp & 0xff000000)>> 24;
1778  if (ip0 >= 224 && ip0 <= 239)
1779  {
1780  // multicast - generate MAC
1781  mac = destIp & 0x7fffff; // lower 23 bits
1782 
1783  macaddr.mac[0] = 0x01;
1784  macaddr.mac[1] = 0x00;
1785  macaddr.mac[2] = 0x5e;
1786  macaddr.mac[3] = mac >> 16;
1787  macaddr.mac[4] = (mac & 0xffff) >> 8;
1788  macaddr.mac[5] = mac & 0xff;
1789  }
1790  else
1791  {
1792  // unicast - get MAC from ARP
1793  string macAddr;
1794  bool rv;
1795  // is destination on the same subnet?
1796  IPVNetConfig nc;
1797  GetNetworkConfiguration(port, nc);
1798  if ( (destIp & nc.ipc_subnet) != (nc.ipc_ip & nc.ipc_subnet))
1799  {
1800  struct in_addr addr;
1801  addr.s_addr = NTV2EndianSwap32(nc.ipc_gateway);
1802  string gateIp = AJANetwork::aja_inet_ntoa(addr);
1803  rv = GetRemoteMAC(gateIp, port, stream, macAddr);
1804  }
1805  else
1806  {
1807  rv = GetRemoteMAC(remoteIP, port, stream, macAddr);
1808  }
1809  if (!rv)
1810  {
1811  SetTxStreamEnable(stream, false);
1813  return false;
1814  }
1815 
1816  istringstream ss(macAddr);
1817  string token;
1818  int i=0;
1819  while (i < 6)
1820  {
1821  getline (ss, token, ':');
1822  macaddr.mac[i++] = (uint8_t)strtoul(token.c_str(), NULL, 16);
1823  }
1824  }
1825 
1826  hi = macaddr.mac[0] << 8;
1827  hi += macaddr.mac[1];
1828 
1829  lo = macaddr.mac[2] << 24;
1830  lo += macaddr.mac[3] << 16;
1831  lo += macaddr.mac[4] << 8;
1832  lo += macaddr.mac[5];
1833 
1834  return true;
1835 }
1836 
1837 string CNTV2Config2110::GetSDPUrl(const eSFP sfp, const NTV2Stream stream)
1838 {
1839  string localIPAddress, subnetMask, gateway;
1840  string preAmble = "http://";
1841  string namePre = "tx";
1842  string namePost;
1843 
1844  GetNetworkConfiguration(sfp, localIPAddress, subnetMask, gateway);
1845 
1846  switch (stream)
1847  {
1848  case NTV2_VIDEO1_STREAM: namePost = "video1.sdp"; break;
1849  case NTV2_VIDEO2_STREAM: namePost = "video2.sdp"; break;
1850  case NTV2_VIDEO3_STREAM: namePost = "video3.sdp"; break;
1851  case NTV2_VIDEO4_STREAM: namePost = "video4.sdp"; break;
1852  case NTV2_AUDIO1_STREAM: namePost = "audio1.sdp"; break;
1853  case NTV2_AUDIO2_STREAM: namePost = "audio2.sdp"; break;
1854  case NTV2_AUDIO3_STREAM: namePost = "audio3.sdp"; break;
1855  case NTV2_AUDIO4_STREAM: namePost = "audio4.sdp"; break;
1856  case NTV2_ANC1_STREAM: namePost = "anc1.sdp"; break;
1857  case NTV2_ANC2_STREAM: namePost = "anc2.sdp"; break;
1858  case NTV2_ANC3_STREAM: namePost = "anc3.sdp"; break;
1859  case NTV2_ANC4_STREAM: namePost = "anc4.sdp"; break;
1860  case NTV2_VIDEO4K_STREAM: namePost = "video4K.sdp"; break;
1861 
1862  default: namePost = ""; break;
1863  }
1864 
1865  return preAmble + localIPAddress + "/" + namePre + namePost;
1866 }
1867 
1868 string CNTV2Config2110::GetGeneratedSDP(bool enabledSfp1, bool enabledSfp2, const NTV2Stream stream)
1869 {
1870  GenSDP(enabledSfp1, enabledSfp2, stream, false);
1871  return txsdp.str();
1872 }
1873 
1874 string CNTV2Config2110::To_String(int val)
1875 {
1876  ostringstream oss;
1877  oss << val;
1878  return oss.str();
1879 }
1880 
1881 bool CNTV2Config2110::GenSDP(const bool enableSfp1, const bool enableSfp2,
1882  const NTV2Stream stream, bool pushit)
1883 {
1884  stringstream & sdp = txsdp;
1885 
1886  sdp.str("");
1887  sdp.clear();
1888 
1889  // protocol version
1890  sdp << "v=0" << endl;
1891 
1892  // username session-id version network-type address-type address
1893  sdp << "o=- ";
1894 
1895  uint64_t t = GetNTPTimestamp();
1896  sdp << To_String((int)t);
1897 
1898  sdp << " 0 IN IP4 ";
1899 
1900  uint32_t val;
1901  // o is required but for multi SDP's we will just assume the originator is SFP_1
1902  if (!enableSfp1 && (StreamType(stream) != VIDEO_4K_STREAM))
1904  else
1906 
1907  struct in_addr addr;
1908  addr.s_addr = val;
1909  string localIPAddress = AJANetwork::aja_inet_ntoa(addr);
1910  sdp << localIPAddress << endl;
1911 
1912  // session name
1913  sdp << "s=AJA KonaIP 2110" << endl;
1914 
1915  // time the session is active
1916  sdp << "t=0 0" <<endl;
1917 
1918  // PTP
1919  PTPStatus ptpStatus;
1920  GetPTPStatus(ptpStatus);
1921 
1922  char gmInfo[32];
1923  snprintf(gmInfo, sizeof(gmInfo), "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X:%d",
1924  ptpStatus.PTP_gmId[0], ptpStatus.PTP_gmId[1], ptpStatus.PTP_gmId[2], ptpStatus.PTP_gmId[3],
1925  ptpStatus.PTP_gmId[4], ptpStatus.PTP_gmId[5], ptpStatus.PTP_gmId[6], ptpStatus.PTP_gmId[7], ptpStatus.PTP_domain);
1926 
1927 
1928  if (StreamType(stream) == VIDEO_STREAM)
1929  {
1930  GenVideoStreamSDP(sdp, enableSfp1, enableSfp2, stream, &gmInfo[0]);
1931  }
1932  else if (StreamType(stream) == VIDEO_4K_STREAM)
1933  {
1934  GenVideoStreamMultiSDPInfo(sdp, &gmInfo[0]);
1935  }
1936  else if (StreamType(stream) == AUDIO_STREAM)
1937  {
1938  GenAudioStreamSDP(sdp, enableSfp1, enableSfp2, stream, &gmInfo[0]);
1939  }
1940  else if (StreamType(stream) == ANC_STREAM)
1941  {
1942  GenAncStreamSDP(sdp, enableSfp1, enableSfp2, stream, &gmInfo[0]);
1943  }
1944 
1945  //cout << "SDP --------------- " << stream << endl << sdp.str() << endl;
1946 
1947  bool rv = true;
1948 
1949  if (pushit)
1950  {
1951  string filename = "tx";
1952 
1953  switch (stream)
1954  {
1955  case NTV2_VIDEO1_STREAM: filename += "video1.sdp"; break;
1956  case NTV2_VIDEO2_STREAM: filename += "video2.sdp"; break;
1957  case NTV2_VIDEO3_STREAM: filename += "video3.sdp"; break;
1958  case NTV2_VIDEO4_STREAM: filename += "video4.sdp"; break;
1959  case NTV2_AUDIO1_STREAM: filename += "audio1.sdp"; break;
1960  case NTV2_AUDIO2_STREAM: filename += "audio2.sdp"; break;
1961  case NTV2_AUDIO3_STREAM: filename += "audio3.sdp"; break;
1962  case NTV2_AUDIO4_STREAM: filename += "audio4.sdp"; break;
1963  case NTV2_ANC1_STREAM: filename += "anc1.sdp"; break;
1964  case NTV2_ANC2_STREAM: filename += "anc2.sdp"; break;
1965  case NTV2_ANC3_STREAM: filename += "anc3.sdp"; break;
1966  case NTV2_ANC4_STREAM: filename += "anc4.sdp"; break;
1967  case NTV2_VIDEO4K_STREAM: filename += "video4K.sdp"; break;
1968  default: filename += ""; break;
1969  }
1970  rv = PushSDP(filename,sdp);
1971  }
1972 
1973  return rv;
1974 }
1975 
1976 bool CNTV2Config2110::GenVideoStreamSDP(stringstream &sdp, const bool enableSfp1,
1977  const bool enableSfp2, const NTV2Stream stream, char *gmInfo)
1978 {
1979  bool isDash7 = enableSfp1 && enableSfp2;
1980  if (isDash7)
1981  {
1982  sdp << "a=group:DUP 1 2" << endl;
1983  }
1984  if (enableSfp1)
1985  {
1986  GenVideoStreamSDPInfo(sdp, SFP_1, stream, gmInfo);
1987  sdp << "a=mid:" << (isDash7?"1":"VID") << endl;
1988  }
1989  if (enableSfp2)
1990  {
1991  GenVideoStreamSDPInfo(sdp, SFP_2, stream, gmInfo);
1992  sdp << "a=mid:" << (isDash7?"2":"VID") << endl;
1993  }
1994  return true;
1995 }
1996 
1997 bool CNTV2Config2110::GenVideoStreamSDPInfo(stringstream & sdp, const eSFP sfp, const NTV2Stream stream, char* gmInfo)
1998 {
1999  tx_2110Config config;
2000  GetTxStreamConfiguration(stream, config);
2001 
2002  uint32_t baseAddrPacketizer = GetPacketizerAddress(stream, GetSampling(sfp, stream));
2003 
2004  uint32_t width;
2005  mDevice.ReadRegister(kReg4175_pkt_width + baseAddrPacketizer, width);
2006 
2007  uint32_t height;
2008  mDevice.ReadRegister(kReg4175_pkt_height + baseAddrPacketizer, height);
2009 
2010  uint32_t ilace;
2011  mDevice.ReadRegister(kReg4175_pkt_interlace_ctrl + baseAddrPacketizer, ilace);
2012 
2013  if (ilace == 1)
2014  {
2015  height *= 2;
2016  }
2017 
2018  NTV2VideoFormat vfmt;
2019  GetTxFormat(VideoStreamToChannel(stream), vfmt);
2021  string rateString = rateToString(frate);
2022 
2023  // media name
2024  sdp << "m=video ";
2025  if (sfp == SFP_2)
2026  sdp << To_String(config.remotePort[1]);
2027  else
2028  sdp << To_String(config.remotePort[0]);
2029 
2030  sdp << " RTP/AVP ";
2031  sdp << To_String(config.payloadType) << endl;
2032 
2033  // connection information
2034  sdp << "c=IN IP4 ";
2035  if (sfp == SFP_2)
2036  sdp << config.remoteIP[1];
2037  else
2038  sdp << config.remoteIP[0];
2039  sdp << "/" << To_String(config.ttl) << endl;
2040 
2041  // source information
2042  sdp << "a=source-filter: incl IN IP4 ";
2043  uint32_t val;
2044 
2045  if (sfp == SFP_2)
2046  {
2047  sdp << config.remoteIP[1];
2049  }
2050  else
2051  {
2052  sdp << config.remoteIP[0];
2054  }
2055 
2056  struct in_addr addr;
2057  addr.s_addr = val;
2058  string localIPAddress = AJANetwork::aja_inet_ntoa(addr);
2059  sdp << ' ' << localIPAddress << endl;
2060 
2061  // rtpmap
2062  sdp << "a=rtpmap:";
2063  sdp << To_String(config.payloadType);
2064  sdp << " raw/90000" << endl;
2065 
2066  //fmtp
2067  sdp << "a=fmtp:";
2068  sdp << To_String(config.payloadType);
2069  if (config.videoSamples == VPIDSampling_GBR_444)
2070  sdp << " sampling=RGB; width=";
2071  else
2072  sdp << " sampling=YCbCr-4:2:2; width=";
2073 
2074  sdp << To_String(width);
2075  sdp << "; height=";
2076  sdp << To_String(height);
2077  sdp << "; exactframerate=";
2078  sdp << rateString;
2079  sdp << "; depth=10; TCS=SDR; colorimetry=";
2080  sdp << ((NTV2_IS_SD_VIDEO_FORMAT(vfmt)) ? "BT601" : "BT709");
2081  sdp << "; PM=2110GPM; SSN=ST2110-20:2017; TP=2110TPN; ";
2083  {
2084  sdp << "interlace; ";
2085  }
2086  else if (NTV2_IS_PSF_VIDEO_FORMAT(vfmt))
2087  {
2088  sdp << "interlace segmented";
2089  }
2090  sdp << endl;
2091 
2092  // PTP
2093  sdp << "a=ts-refclk:ptp=IEEE1588-2008:" << gmInfo << endl;
2094  sdp << "a=mediaclk:direct=0" << endl;
2095 
2096  return true;
2097 }
2098 
2099 
2100 bool CNTV2Config2110::GenVideoStreamMultiSDPInfo(stringstream & sdp, char* gmInfo)
2101 {
2102  uint32_t quadSwapOut;
2103  NTV2Stream stream;
2104 
2105  // Read virtual to see if we are to quad swap the outputs
2107 
2108  sdp << "a=group:MULTI-2SI 1 2 3 4 " << endl;
2109 
2110  // generate SDP's for all 4 video streams
2111  for (int i=0; i<4; i++)
2112  {
2113  if (quadSwapOut != 0)
2114  {
2115  switch (i)
2116  {
2117  case 0: stream = NTV2_VIDEO3_STREAM; break;
2118  case 1: stream = NTV2_VIDEO4_STREAM; break;
2119  case 2: stream = NTV2_VIDEO1_STREAM; break;
2120  case 3: stream = NTV2_VIDEO2_STREAM; break;
2121  }
2122  }
2123  else
2124  stream = (NTV2Stream)i;
2125 
2126  bool enabledA;
2127  bool enabledB;
2128  // See which steam is enabled, the code is written in such a way so that
2129  // if neither SFP1 or SFP2 is enabled it will use data from SFP1
2130  GetTxStreamEnable(stream, enabledA, enabledB);
2131 
2132  tx_2110Config config;
2133  GetTxStreamConfiguration(stream, config);
2134 
2135  uint32_t baseAddrPacketizer = GetPacketizerAddress(stream, GetSampling(SFP_1, stream));
2136 
2137  uint32_t width;
2138  mDevice.ReadRegister(kReg4175_pkt_width + baseAddrPacketizer, width);
2139 
2140  uint32_t height;
2141  mDevice.ReadRegister(kReg4175_pkt_height + baseAddrPacketizer, height);
2142 
2143  uint32_t ilace;
2144  mDevice.ReadRegister(kReg4175_pkt_interlace_ctrl + baseAddrPacketizer, ilace);
2145 
2146  if (ilace == 1)
2147  {
2148  height *= 2;
2149  }
2150 
2151  NTV2VideoFormat vfmt;
2152  GetTxFormat(VideoStreamToChannel(stream), vfmt);
2154  string rateString = rateToString(frate);
2155 
2156  // media name
2157  sdp << "m=video ";
2158  if (enabledB)
2159  sdp << To_String(config.remotePort[1]);
2160  else
2161  sdp << To_String(config.remotePort[0]);
2162 
2163  sdp << " RTP/AVP ";
2164  sdp << To_String(config.payloadType) << endl;
2165 
2166  // dest information
2167  sdp << "c=IN IP4 ";
2168  if (enabledB)
2169  sdp << config.remoteIP[1];
2170  else
2171  sdp << config.remoteIP[0];
2172  sdp << "/" << To_String(config.ttl) << endl;
2173 
2174  // source information
2175  sdp << "a=source-filter: incl IN IP4 ";
2176  uint32_t val;
2177 
2178  if (enabledB)
2179  {
2180  sdp << config.remoteIP[1];
2182  }
2183  else
2184  {
2185  sdp << config.remoteIP[0];
2187  }
2188 
2189  struct in_addr addr;
2190  addr.s_addr = val;
2191  string localIPAddress = AJANetwork::aja_inet_ntoa(addr);
2192  sdp << ' ' << localIPAddress << endl;
2193 
2194  // rtpmap
2195  sdp << "a=rtpmap:";
2196  sdp << To_String(config.payloadType);
2197  sdp << " raw/90000" << endl;
2198 
2199  //fmtp
2200  sdp << "a=fmtp:";
2201  sdp << To_String(config.payloadType);
2202  sdp << " sampling=YCbCr-4:2:2; width=";
2203  sdp << To_String(width);
2204  sdp << "; height=";
2205  sdp << To_String(height);
2206  sdp << "; exactframerate=";
2207  sdp << rateString;
2208  sdp << "; depth=10; TCS=SDR; colorimetry=";
2209  sdp << ((NTV2_IS_SD_VIDEO_FORMAT(vfmt)) ? "BT601" : "BT709");
2210  sdp << "; PM=2110GPM; SSN=ST2110-20:2017; TP=2110TPN; ";
2212  {
2213  sdp << "interlace; ";
2214  }
2215  else if (NTV2_IS_PSF_VIDEO_FORMAT(vfmt))
2216  {
2217  sdp << "interlace segmented";
2218  }
2219  sdp << endl;
2220 
2221  // PTP
2222  sdp << "a=ts-refclk:ptp=IEEE1588-2008:" << gmInfo << endl;
2223  sdp << "a=mediaclk:direct=0" << endl;
2224  sdp << "a=mid:" << i+1 << endl;
2225  }
2226 
2227  return true;
2228 }
2229 
2230 
2231 bool CNTV2Config2110::GenAudioStreamSDP(stringstream &sdp, const bool enableSfp1,
2232  const bool enableSfp2, const NTV2Stream stream, char *gmInfo)
2233 {
2234  bool isDash7 = enableSfp1 && enableSfp2;
2235  if (isDash7)
2236  {
2237  sdp << "a=group:DUP 1 2" << endl;
2238  }
2239  if (enableSfp1)
2240  {
2241  GenAudioStreamSDPInfo(sdp, SFP_1, stream, gmInfo);
2242  sdp << "a=mid:" << (isDash7?"1":"VID") << endl;
2243  }
2244  if (enableSfp2)
2245  {
2246  GenAudioStreamSDPInfo(sdp, SFP_2, stream, gmInfo);
2247  sdp << "a=mid:" << (isDash7?"2":"VID") << endl;
2248  }
2249  return true;
2250 }
2251 
2252 bool CNTV2Config2110::GenAudioStreamSDPInfo(stringstream & sdp, const eSFP sfp, const NTV2Stream stream, char* gmInfo)
2253 {
2254  tx_2110Config config;
2255  GetTxStreamConfiguration(stream, config);
2256 
2257  // media name
2258  sdp << "m=audio ";
2259  if (sfp == SFP_2)
2260  sdp << To_String(config.remotePort[1]);
2261  else
2262  sdp << To_String(config.remotePort[0]);
2263 
2264  sdp << " RTP/AVP ";
2265  sdp << To_String(config.payloadType) << endl;
2266 
2267  // connection information
2268  sdp << "c=IN IP4 ";
2269  if (sfp == SFP_2)
2270  sdp << config.remoteIP[1];
2271  else
2272  sdp << config.remoteIP[0];
2273 
2274  sdp << "/" << To_String(config.ttl) << endl;
2275 
2276  // source information
2277  sdp << "a=source-filter: incl IN IP4 ";
2278  uint32_t val;
2279 
2280  if (sfp == SFP_2)
2281  {
2282  sdp << config.remoteIP[1];
2284  }
2285  else
2286  {
2287  sdp << config.remoteIP[0];
2289  }
2290 
2291  struct in_addr addr;
2292  addr.s_addr = val;
2293  string localIPAddress = AJANetwork::aja_inet_ntoa(addr);
2294  sdp << ' ' << localIPAddress << endl;
2295 
2296  // rtpmap
2297  sdp << "a=rtpmap:";
2298  sdp << To_String(config.payloadType);
2299  sdp << " L24/48000/";
2300  sdp << To_String(config.numAudioChannels) << endl;
2301 
2302  //fmtp
2303  sdp << "a=fmtp:";
2304  sdp << To_String(config.payloadType);
2305  sdp << " channel-order=SMPTE2110.(";
2306  switch (config.numAudioChannels)
2307  {
2308  case 2:
2309  sdp << "ST)";
2310  break;
2311  case 4:
2312  sdp << "SGRP)";
2313  break;
2314  case 8:
2315  default:
2316  sdp << "SGRP,SGRP)";
2317  break;
2318  case 12:
2319  sdp << "SGRP,SGRP,SGRP)";
2320  break;
2321  case 16:
2322  sdp << "SGRP,SGRP,SGRP,SGRP)";
2323  break;
2324  }
2325  sdp << endl;
2326 
2327  if (config. audioPktInterval == PACKET_INTERVAL_125uS)
2328  {
2329  sdp << "a=ptime:0.125" << endl;
2330  }
2331  else
2332  {
2333  sdp << "a=ptime:1.000" << endl;
2334  }
2335 
2336  sdp << "a=ts-refclk:ptp=IEEE1588-2008:" << gmInfo << endl;
2337  sdp << "a=mediaclk:direct=0" << endl;
2338 
2339  return true;
2340 }
2341 
2342 bool CNTV2Config2110::GenAncStreamSDP(stringstream &sdp, const bool enableSfp1,
2343  const bool enableSfp2, const NTV2Stream stream, char *gmInfo)
2344 {
2345  bool isDash7 = enableSfp1 && enableSfp2;
2346  if (isDash7)
2347  {
2348  sdp << "a=group:DUP 1 2" << endl;
2349  }
2350  if (enableSfp1)
2351  {
2352  GenAncStreamSDPInfo(sdp, SFP_1, stream, gmInfo);
2353  sdp << "a=mid:" << (isDash7?"1":"VID") << endl;
2354  }
2355  if (enableSfp2)
2356  {
2357  GenAncStreamSDPInfo(sdp, SFP_2, stream, gmInfo);
2358  sdp << "a=mid:" << (isDash7?"2":"VID") << endl;
2359  }
2360  return true;
2361 }
2362 
2363 bool CNTV2Config2110::GenAncStreamSDPInfo(stringstream & sdp, const eSFP sfp, const NTV2Stream stream, char* gmInfo)
2364 {
2365  tx_2110Config config;
2366  GetTxStreamConfiguration(stream, config);
2367 
2368  // media name
2369  sdp << "m=video ";
2370  if (sfp == SFP_2)
2371  sdp << To_String(config.remotePort[1]);
2372  else
2373  sdp << To_String(config.remotePort[0]);
2374 
2375  sdp << " RTP/AVP ";
2376  sdp << To_String(config.payloadType) << endl;
2377 
2378  // connection information
2379  sdp << "c=IN IP4 ";
2380  if (sfp == SFP_2)
2381  sdp << config.remoteIP[1];
2382  else
2383  sdp << config.remoteIP[0];
2384  sdp << "/" << To_String(config.ttl) << endl;
2385 
2386  // source information
2387  sdp << "a=source-filter: incl IN IP4 ";
2388  uint32_t val;
2389 
2390  if (sfp == SFP_2)
2391  {
2392  sdp << config.remoteIP[1];
2394  }
2395  else
2396  {
2397  sdp << config.remoteIP[0];
2399  }
2400 
2401  struct in_addr addr;
2402  addr.s_addr = val;
2403  string localIPAddress = AJANetwork::aja_inet_ntoa(addr);
2404  sdp << ' ' << localIPAddress << endl;
2405 
2406  // rtpmap
2407  sdp << "a=rtpmap:";
2408  sdp << To_String(config.payloadType);
2409  sdp << " smpte291/90000" << endl;
2410 
2411  // PTP
2412  sdp << "a=ts-refclk:ptp=IEEE1588-2008:" << gmInfo << endl;
2413  sdp << "a=mediaclk:direct=0" << endl;
2414 
2415  return true;
2416 }
2417 
2418 
2420 {
2422 
2423  switch (stream)
2424  {
2425  case NTV2_VIDEO1_STREAM:
2426  case NTV2_VIDEO2_STREAM:
2427  case NTV2_VIDEO3_STREAM:
2428  case NTV2_VIDEO4_STREAM:
2429  type = VIDEO_STREAM;
2430  break;
2431  case NTV2_AUDIO1_STREAM:
2432  case NTV2_AUDIO2_STREAM:
2433  case NTV2_AUDIO3_STREAM:
2434  case NTV2_AUDIO4_STREAM:
2435  type = AUDIO_STREAM;
2436  break;
2437  case NTV2_ANC1_STREAM:
2438  case NTV2_ANC2_STREAM:
2439  case NTV2_ANC3_STREAM:
2440  case NTV2_ANC4_STREAM:
2441  type = ANC_STREAM;
2442  break;
2443 
2444  case NTV2_VIDEO4K_STREAM:
2445  type = VIDEO_4K_STREAM;
2446  break;
2447 
2448  default:
2449  type = INVALID_STREAM;
2450  break;
2451  }
2452  return type;
2453 }
2454 
2456 {
2457  NTV2Channel channel;
2458  switch (stream)
2459  {
2460  case NTV2_VIDEO1_STREAM: channel = NTV2_CHANNEL1; break;
2461  case NTV2_VIDEO2_STREAM: channel = NTV2_CHANNEL2; break;
2462  case NTV2_VIDEO3_STREAM: channel = NTV2_CHANNEL3; break;
2463  case NTV2_VIDEO4_STREAM: channel = NTV2_CHANNEL4; break;
2464  default: channel = NTV2_CHANNEL_INVALID; break;
2465  }
2466  return channel;
2467 }
2468 
2469 
2470 bool CNTV2Config2110::GetActualSDP(std::string url, std::string & sdp)
2471 {
2472  return GetSDP(url, sdp);
2473 }
2474 
2475 
2476 int CNTV2Config2110::getDescriptionValue(int startLine, string type, string & value)
2477 {
2478  for (unsigned i(startLine); i < sdpLines.size(); i++)
2479  {
2480  string line = sdpLines[i];
2481  size_t pos = line.find(type);
2482  if (pos != string::npos)
2483  {
2484  value = line.substr(pos + type.size() + 1);
2485  return i;
2486  }
2487  }
2488  return -1; // not found
2489 }
2490 
2491 string CNTV2Config2110::getVideoDescriptionValue(string type)
2492 {
2493  vector<string>::iterator it;
2494  for (it = tokens.begin(); it != tokens.end(); it++)
2495  {
2496  string line = *it;
2497  size_t pos = line.find(type);
2498  if (pos != string::npos)
2499  {
2500  line = line.substr(pos + type.size());
2501  line.erase(remove(line.begin(), line.end(), ';'), line.end());
2502  return line;
2503  }
2504  }
2505  string result;
2506  return result; // not found
2507 }
2508 
2509 vector<string> CNTV2Config2110::split(const char *str, char delim)
2510 {
2511  vector<string> result;
2512  do
2513  {
2514  const char * begin = str;
2515  while(*str != delim && *str)
2516  {
2517  str++;
2518  }
2519  result.push_back(string(begin, str));
2520  } while (0 != *str++);
2521  return result;
2522 }
2523 
2525 {
2526  if (sdp.empty())
2527  {
2529  return false;
2530  }
2531 
2532  // remove any carriage returns
2533  sdp.erase(remove(sdp.begin(), sdp.end(), '\r'), sdp.end());
2534 
2535  // break into a vector of lines and then into tokenw
2536  sdpLines.clear();
2537  stringstream ss(sdp);
2538  string to;
2539 
2540  while(getline(ss,to,'\n'))
2541  {
2542  sdpLines.push_back(to);
2543  }
2544 
2545  // rudimentary check it is an sdp file
2546  int index;
2547  string value;
2548 
2549  // is this really an SDP
2550  index = getDescriptionValue(0,"v=",value);
2551  if (index == -1)
2552  {
2554  return false;
2555  }
2556 
2557  // make sure this is a multi-2si sdp
2558  index = getDescriptionValue(index,"a=group",value);
2559  if (index == -1)
2560  {
2562  return false;
2563  }
2564 
2565  tokens = split(value.c_str(), ' ');
2566  if (!((tokens.size() != 5) && (tokens[0] == "MULTI-2SI")))
2567  {
2569  return false;
2570  }
2571 
2572  // fill in RX struct for each stream
2573  for (int i=0; i<4; i++)
2574  {
2575  uint32_t rxMatch = 0;
2576  int rv;
2577 
2578  rxConfig.rx2110Config[i].sourceIP = "0.0.0.0";
2579 
2580  index = getDescriptionValue(index,"m=video",value);
2581  if (index == -1)
2582  {
2583  // does not contain video
2585  return false;
2586  }
2587  tokens = split(value.c_str(), ' ');
2588  if ((tokens.size() >= 1) && !tokens[0].empty())
2589  {
2590  rxConfig.rx2110Config[i].destPort = atoi(tokens[0].c_str());
2591  rxMatch |= RX_MATCH_2110_DEST_PORT;
2592  }
2593  if ((tokens.size() >= 3) && !tokens[2].empty())
2594  {
2595  rxConfig.rx2110Config[i].payloadType = atoi(tokens[2].c_str());
2596  rxMatch |= RX_MATCH_2110_PAYLOAD;
2597  }
2598 
2599  rv = getDescriptionValue(index,"c=IN",value);
2600  if (rv >= index)
2601  {
2602  tokens = split(value.c_str(), ' ');
2603  if (tokens.size() >= 2)
2604  {
2605  tokens = split(tokens[1].c_str(), '/');
2606  if ((tokens.size() >= 1) && !tokens[0].empty())
2607  {
2608  rxConfig.rx2110Config[i].destIP = tokens[0];
2609  rxMatch |= RX_MATCH_2110_DEST_IP;
2610  }
2611  }
2612  }
2613 
2614  //if there is a source-filter attribute, it overrides the o= source attribute
2615  rv = getDescriptionValue(index,"a=source-filter:",value);
2616  if (rv > index)
2617  {
2618  tokens = split(value.c_str(), ' ');
2619  if (tokens.size() >= 5 && !tokens[4].empty())
2620  {
2621  rxConfig.rx2110Config[i].sourceIP = tokens[4];
2622  rxMatch |= RX_MATCH_2110_SOURCE_IP;
2623  }
2624  }
2625 
2626  rv = getDescriptionValue(index,"a=rtpmap",value);
2627  if (rv > index)
2628  {
2629  tokens = split(value.c_str(), ' ');
2630  if ((tokens.size() >= 1) && !tokens[0].empty())
2631  {
2632  rxConfig.rx2110Config[i].payloadType = atoi(tokens[0].c_str());
2633  rxMatch |= RX_MATCH_2110_PAYLOAD;
2634  }
2635  }
2636 
2637  rv = getDescriptionValue(index,"a=fmtp",value);
2638  if (rv > index)
2639  {
2640  tokens = split(value.c_str(), ' ');
2641  string sampling = getVideoDescriptionValue("sampling=");
2642  if (sampling == "YCbCr-4:2:2")
2643  {
2645  }
2646  string width = getVideoDescriptionValue("width=");
2647  string height = getVideoDescriptionValue("height=");
2648  string rate = getVideoDescriptionValue("exactframerate=");
2649  bool interlace = false;
2650  bool segmented = false;
2651  vector<string>::iterator it;
2652 
2653  for (it = tokens.begin(); it != tokens.end(); it++)
2654  {
2655  // For interlace, we can get one of the following tokens:
2656  // interlace
2657  // interlace;
2658  // interlace=1
2659  // interlace segmented
2660 
2661  if (*it == "interlace")
2662  {
2663  interlace=true;
2664  continue;
2665  }
2666 
2667  if (it->substr(0,10) == "interlace;")
2668  {
2669  interlace=true;
2670  continue;
2671  }
2672  if (it->substr(0,11) == "interlace=1")
2673  {
2674  interlace=true;
2675  continue;
2676  }
2677  if ((it->substr( 0, 9 ) == "segmented") && interlace)
2678  {
2679  interlace=false;
2680  segmented=true;
2681  break;
2682  }
2683  }
2684  int w = atoi(width.c_str());
2685  int h = atoi(height.c_str());
2686  NTV2FrameRate r = stringToRate(rate);
2687  NTV2VideoFormat vf = ::GetFirstMatchingVideoFormat(r, h, w, interlace, segmented, false /* no level B */);
2688  rxConfig.rx2110Config[i].videoFormat = vf;
2689  }
2690  rxConfig.rx2110Config[i].rxMatch = rxMatch;
2691  index++;
2692  }
2693 
2694  return true;
2695 }
2696 
2697 
2699 {
2700  if (sdp.empty())
2701  {
2703  return false;
2704  }
2705 
2706  // remove any carriage returns
2707  sdp.erase(remove(sdp.begin(), sdp.end(), '\r'), sdp.end());
2708 
2709  // break into a vector of lines and then into tokenw
2710  sdpLines.clear();
2711  stringstream ss(sdp);
2712  string to;
2713 
2714  while(getline(ss,to,'\n'))
2715  {
2716  sdpLines.push_back(to);
2717  }
2718 
2719  // rudimentary check it is an sdp file
2720  int index;
2721  string value;
2722 
2723  // is this really an SDP
2724  index = getDescriptionValue(0,"v=",value);
2725  if (index == -1)
2726  {
2728  return false;
2729  }
2730 
2731  // originator
2732  index = getDescriptionValue(index,"o=",value);
2733  if (index == -1)
2734  {
2736  return false;
2737  }
2738 
2739  uint32_t rxMatch = 0;
2740 
2741  tokens = split(value.c_str(), ' ');
2742  if ((tokens.size() >= 6) && (tokens[3] == "IN") && (tokens[4] == "IP4"))
2743  {
2744  if (!tokens[5].empty())
2745  {
2746  rxConfig.sourceIP = tokens[5];
2747  rxMatch |= RX_MATCH_2110_SOURCE_IP;
2748  }
2749  }
2750 
2751  int rv = getDescriptionValue(0,"c=IN",value);
2752  if (rv >= index)
2753  {
2754  tokens = split(value.c_str(), ' ');
2755  if (tokens.size() >= 2)
2756  {
2757  tokens = split(tokens[1].c_str(), '/');
2758  if ((tokens.size() >= 1) && !tokens[0].empty())
2759  {
2760  rxConfig.destIP = tokens[0];
2761  rxMatch |= RX_MATCH_2110_DEST_IP;
2762  }
2763  }
2764  }
2765 
2766  index = getDescriptionValue(index,"m=video",value);
2767  if (index == -1)
2768  {
2769  // does not contain video
2771  return false;
2772  }
2773  tokens = split(value.c_str(), ' ');
2774  if ((tokens.size() >= 1) && !tokens[0].empty())
2775  {
2776  rxConfig.destPort = atoi(tokens[0].c_str());
2777  rxMatch |= RX_MATCH_2110_DEST_PORT;
2778  }
2779  if ((tokens.size() >= 3) && !tokens[2].empty())
2780  {
2781  rxConfig.payloadType = atoi(tokens[2].c_str());
2782  rxMatch |= RX_MATCH_2110_PAYLOAD;
2783  }
2784 
2785  rv = getDescriptionValue(index,"c=IN",value);
2786  if (rv >= index)
2787  {
2788  // this overwrites if found before
2789  tokens = split(value.c_str(), ' ');
2790  if (tokens.size() >= 2)
2791  {
2792  tokens = split(tokens[1].c_str(), '/');
2793  if ((tokens.size() >= 1) && !tokens[0].empty())
2794  {
2795  rxConfig.destIP = tokens[0];
2796  rxMatch |= RX_MATCH_2110_DEST_IP;
2797  }
2798  }
2799  }
2800 
2801  // if there is a source-filter attribute, it overrides the o= source attribute
2802  rv = getDescriptionValue(index,"a=source-filter:",value);
2803  if (rv > index)
2804  {
2805  tokens = split(value.c_str(), ' ');
2806  if (tokens.size() >= 5 && !tokens[4].empty())
2807  {
2808  rxConfig.sourceIP = tokens[4];
2809  rxMatch |= RX_MATCH_2110_SOURCE_IP;
2810  }
2811  }
2812 
2813  rv = getDescriptionValue(index,"a=rtpmap",value);
2814  if (rv > index)
2815  {
2816  tokens = split(value.c_str(), ' ');
2817  if ((tokens.size() >= 1) && !tokens[0].empty())
2818  {
2819  rxConfig.payloadType = atoi(tokens[0].c_str());
2820  rxMatch |= RX_MATCH_2110_PAYLOAD;
2821  }
2822  }
2823 
2824  rv = getDescriptionValue(index,"a=fmtp",value);
2825  if (rv > index)
2826  {
2827  tokens = split(value.c_str(), ' ');
2828  string sampling = getVideoDescriptionValue("sampling=");
2829  if (sampling == "YCbCr-4:2:2")
2830  {
2832  }
2833  string width = getVideoDescriptionValue("width=");
2834  string height = getVideoDescriptionValue("height=");
2835  string rate = getVideoDescriptionValue("exactframerate=");
2836  bool interlace = false;
2837  bool segmented = false;
2838  vector<string>::iterator it;
2839  for (it = tokens.begin(); it != tokens.end(); it++)
2840  {
2841  // For interlace, we can get one of the following tokens:
2842  // interlace
2843  // interlace;
2844  // interlace=1
2845  // interlace segmented
2846 
2847  if (*it == "interlace")
2848  {
2849  interlace=true;
2850  continue;
2851  }
2852 
2853  if (it->substr(0,10) == "interlace;")
2854  {
2855  interlace=true;
2856  continue;
2857  }
2858  if (it->substr(0,11) == "interlace=1")
2859  {
2860  interlace=true;
2861  continue;
2862  }
2863  if ((it->substr( 0, 9 ) == "segmented") && interlace)
2864  {
2865  interlace=false;
2866  segmented=true;
2867  break;
2868  }
2869  }
2870  int w = atoi(width.c_str());
2871  int h = atoi(height.c_str());
2872  NTV2FrameRate r = stringToRate(rate);
2873  NTV2VideoFormat vf = ::GetFirstMatchingVideoFormat(r, h, w, interlace, segmented, false /* no level B */);
2874  rxConfig.videoFormat = vf;
2875  }
2876  rxConfig.rxMatch = rxMatch;
2877  return true;
2878 }
2879 
2880 
2882 {
2883  if (sdp.empty())
2884  {
2886  return false;
2887  }
2888 
2889  uint32_t rxMatch = 0;
2890 
2891  // remove any carriage returns
2892  sdp.erase(remove(sdp.begin(), sdp.end(), '\r'), sdp.end());
2893 
2894  // break into a vector of lines and then into tokenw
2895 
2896  sdpLines.clear();
2897  stringstream ss(sdp);
2898  string to;
2899 
2900  while(getline(ss,to,'\n'))
2901  {
2902  sdpLines.push_back(to);
2903  }
2904 
2905  // rudimentary check it is an sdp file
2906  int index;
2907  string value;
2908 
2909  // is this really an SDP
2910  index = getDescriptionValue(0,"v=",value);
2911  if (index == -1)
2912  {
2914  return false;
2915  }
2916 
2917  // originator
2918  index = getDescriptionValue(index,"o=",value);
2919  if (index == -1)
2920  {
2922  return false;
2923  }
2924 
2925  tokens = split(value.c_str(), ' ');
2926  if ((tokens.size() >= 6) && (tokens[3] == "IN") && (tokens[4] == "IP4"))
2927  {
2928  if (!tokens[5].empty())
2929  {
2930  rxConfig.sourceIP = tokens[5];
2931  rxMatch |= RX_MATCH_2110_SOURCE_IP;
2932  }
2933  }
2934 
2935  int rv = getDescriptionValue(0,"c=IN",value);
2936  if (rv >= index)
2937  {
2938  tokens = split(value.c_str(), ' ');
2939  if (tokens.size() >= 2)
2940  {
2941  tokens = split(tokens[1].c_str(), '/');
2942  if ((tokens.size() >= 1) && !tokens[0].empty())
2943  {
2944  rxConfig.destIP = tokens[0];
2945  rxMatch |= RX_MATCH_2110_DEST_IP;
2946  }
2947  }
2948  }
2949 
2950  // audio stream
2951  index = getDescriptionValue(index,"m=audio",value);
2952  if (index == -1)
2953  {
2954  // does not contain audio
2956  return false;
2957  }
2958 
2959  tokens = split(value.c_str(), ' ');
2960  if ((tokens.size() >= 1) && !tokens[0].empty())
2961  {
2962  rxConfig.destPort = atoi(tokens[0].c_str());
2963  rxMatch |= RX_MATCH_2110_DEST_PORT;
2964  }
2965 
2966  if ((tokens.size() >= 3) && !tokens[2].empty())
2967  {
2968  rxConfig.payloadType = atoi(tokens[2].c_str());
2969  rxMatch |= RX_MATCH_2110_PAYLOAD;
2970  }
2971 
2972  rv = getDescriptionValue(index,"c=IN",value);
2973  if (rv >= index)
2974  {
2975  // this overwrites if found before
2976  tokens = split(value.c_str(), ' ');
2977  if ((tokens.size() >= 2))
2978  {
2979  tokens = split(tokens[1].c_str(), '/');
2980  if ((tokens.size() >= 1)&& !tokens[0].empty())
2981  {
2982  rxConfig.destIP = tokens[0];
2983  rxMatch |= RX_MATCH_2110_DEST_IP;
2984  }
2985  }
2986  }
2987 
2988  // if there is a source-filter attribute, it overrides the o= source attribute
2989  rv = getDescriptionValue(index,"a=source-filter:",value);
2990  if (rv > index)
2991  {
2992  tokens = split(value.c_str(), ' ');
2993  if (tokens.size() >= 5 && !tokens[4].empty())
2994  {
2995  rxConfig.sourceIP = tokens[4];
2996  rxMatch |= RX_MATCH_2110_SOURCE_IP;
2997  }
2998  }
2999 
3000  rv = getDescriptionValue(index,"a=rtpmap",value);
3001  if (rv > index)
3002  {
3003  tokens = split(value.c_str(), ' ');
3004  if ((tokens.size() >= 1)&& !tokens[0].empty())
3005  {
3006  rxConfig.payloadType = atoi(tokens[0].c_str());
3007  rxMatch |= RX_MATCH_2110_PAYLOAD;
3008  }
3009  if ((tokens.size() >= 2))
3010  {
3011  tokens = split(tokens[1].c_str(), '/');
3012  if ((tokens.size() >= 3) && !tokens[2].empty())
3013  {
3014  rxConfig.numAudioChannels = atoi(tokens[2].c_str());
3015  }
3016  }
3017  }
3018 
3019  rv = getDescriptionValue(index,"a=ptime",value);
3020  if (rv > index)
3021  {
3022  tokens = split(value.c_str(), ' ');
3023  if ((tokens.size() >= 1)&& !tokens[0].empty())
3024  {
3025  tokens = split(tokens[0].c_str(), '.');
3026  if (tokens.size() >= 2)
3027  {
3028  if ((atoi(tokens[0].c_str()) == 1) && (atoi(tokens[1].c_str()) == 0))
3030  else if ((atoi(tokens[0].c_str()) == 0) && (atoi(tokens[1].c_str()) == 125))
3032  }
3033  }
3034  }
3035 
3036  rxConfig.rxMatch = rxMatch;
3037  return true;
3038 }
3039 
3040 
3042 {
3043  if (sdp.empty())
3044  {
3046  return false;
3047  }
3048 
3049  // remove any carriage returns
3050  sdp.erase(remove(sdp.begin(), sdp.end(), '\r'), sdp.end());
3051 
3052  // break into a vector of lines and then into tokenw
3053  sdpLines.clear();
3054  stringstream ss(sdp);
3055  string to;
3056 
3057  while(getline(ss,to,'\n'))
3058  {
3059  sdpLines.push_back(to);
3060  }
3061 
3062  // rudimentary check it is an sdp file
3063  int index;
3064  string value;
3065 
3066  // is this really an SDP
3067  index = getDescriptionValue(0,"v=",value);
3068  if (index == -1)
3069  {
3071  return false;
3072  }
3073 
3074  // originator
3075  index = getDescriptionValue(index,"o=",value);
3076  if (index == -1)
3077  {
3079  return false;
3080  }
3081 
3082  uint32_t rxMatch = 0;
3083 
3084  tokens = split(value.c_str(), ' ');
3085  if ((tokens.size() >= 6) && (tokens[3] == "IN") && (tokens[4] == "IP4"))
3086  {
3087  if (!tokens[5].empty())
3088  {
3089  rxConfig.sourceIP = tokens[5];
3090  rxMatch |= RX_MATCH_2110_SOURCE_IP;
3091  }
3092  }
3093 
3094  int rv = getDescriptionValue(0,"c=IN",value);
3095  if (rv >= index)
3096  {
3097  tokens = split(value.c_str(), ' ');
3098  if (tokens.size() >= 2)
3099  {
3100  tokens = split(tokens[1].c_str(), '/');
3101  if ((tokens.size() >= 1) && !tokens[0].empty())
3102  {
3103  rxConfig.destIP = tokens[0];
3104  rxMatch |= RX_MATCH_2110_DEST_IP;
3105  }
3106  }
3107  }
3108 
3109  index = getDescriptionValue(index,"m=video",value);
3110  if (index == -1)
3111  {
3112  // does not contain video
3114  return false;
3115  }
3116  tokens = split(value.c_str(), ' ');
3117  if ((tokens.size() >= 1) && !tokens[0].empty())
3118  {
3119  rxConfig.destPort = atoi(tokens[0].c_str());
3120  rxMatch |= RX_MATCH_2110_DEST_PORT;
3121  }
3122  if ((tokens.size() >= 3) && !tokens[2].empty())
3123  {
3124  rxConfig.payloadType = atoi(tokens[2].c_str());
3125  rxMatch |= RX_MATCH_2110_PAYLOAD;
3126  }
3127 
3128  rv = getDescriptionValue(index,"c=IN",value);
3129  if (rv >= index)
3130  {
3131  // this overwrites if found before
3132  tokens = split(value.c_str(), ' ');
3133  if (tokens.size() >= 2)
3134  {
3135  tokens = split(tokens[1].c_str(), '/');
3136  if ((tokens.size() >= 1) && !tokens[0].empty())
3137  {
3138  rxConfig.destIP = tokens[0];
3139  rxMatch |= RX_MATCH_2110_DEST_IP;
3140  }
3141  }
3142  }
3143 
3144  // if there is a source-filter attribute, it overrides the o= source attribute
3145  rv = getDescriptionValue(index,"a=source-filter:",value);
3146  if (rv > index)
3147  {
3148  tokens = split(value.c_str(), ' ');
3149  if (tokens.size() >= 5 && !tokens[4].empty())
3150  {
3151  rxConfig.sourceIP = tokens[4];
3152  rxMatch |= RX_MATCH_2110_SOURCE_IP;
3153  }
3154  }
3155 
3156  rv = getDescriptionValue(index,"a=rtpmap",value);
3157  if (rv > index)
3158  {
3159  tokens = split(value.c_str(), ' ');
3160  if ((tokens.size() >= 1) && !tokens[0].empty())
3161  {
3162  rxConfig.payloadType = atoi(tokens[0].c_str());
3163  rxMatch |= RX_MATCH_2110_PAYLOAD;
3164  }
3165  }
3166 
3167  rxConfig.rxMatch = rxMatch;
3168  return true;
3169 }
3170 
3171 
3172 std::string CNTV2Config2110::rateToString(NTV2FrameRate rate)
3173 {
3174  string rateString;
3175  switch (rate)
3176  {
3177  default:
3178  case NTV2_FRAMERATE_UNKNOWN :
3179  rateString = "00";
3180  break;
3181  case NTV2_FRAMERATE_6000 :
3182  rateString = "60";
3183  break;
3184  case NTV2_FRAMERATE_5994 :
3185  rateString = "60000/1001";
3186  break;
3187  case NTV2_FRAMERATE_3000 :
3188  rateString = "30";
3189  break;
3190  case NTV2_FRAMERATE_2997 :
3191  rateString = "30000/1001";
3192  break;
3193  case NTV2_FRAMERATE_2500 :
3194  rateString = "25";
3195  break;
3196  case NTV2_FRAMERATE_2400 :
3197  rateString = "24";
3198  break;
3199  case NTV2_FRAMERATE_2398 :
3200  rateString = "24000/1001";
3201  break;
3202  case NTV2_FRAMERATE_5000 :
3203  rateString = "50";
3204  break;
3205  case NTV2_FRAMERATE_4800 :
3206  rateString = "48";
3207  break;
3208  case NTV2_FRAMERATE_4795 :
3209  rateString = "48000/1001";
3210  break;
3211  case NTV2_FRAMERATE_12000 :
3212  rateString = "120";
3213  break;
3214  case NTV2_FRAMERATE_11988 :
3215  rateString = "120000/1001";
3216  break;
3217  case NTV2_FRAMERATE_1500 :
3218  rateString = "15";
3219  break;
3220  case NTV2_FRAMERATE_1498 :
3221  rateString = "1500/1001";
3222  break;
3223  }
3224  return rateString;
3225 }
3226 
3227 NTV2FrameRate CNTV2Config2110::stringToRate(std::string rateString)
3228 {
3229  NTV2FrameRate rate;
3230  if (rateString == "60")
3231  rate = NTV2_FRAMERATE_6000;
3232  else if (rateString == "60000/1001")
3233  rate = NTV2_FRAMERATE_5994;
3234  else if (rateString == "30")
3235  rate = NTV2_FRAMERATE_3000;
3236  else if (rateString == "30000/1001")
3237  rate = NTV2_FRAMERATE_2997;
3238  else if (rateString == "25")
3239  rate = NTV2_FRAMERATE_2500;
3240  else if (rateString == "24")
3241  rate = NTV2_FRAMERATE_2400;
3242  else if (rateString == "24000/1001")
3243  rate = NTV2_FRAMERATE_2398;
3244  else if (rateString == "50")
3245  rate = NTV2_FRAMERATE_5000;
3246  else if (rateString == "48")
3247  rate = NTV2_FRAMERATE_4800;
3248  else if (rateString == "48000/1001")
3249  rate = NTV2_FRAMERATE_4795;
3250  else if (rateString == "120")
3251  rate = NTV2_FRAMERATE_12000;
3252  else if (rateString == "120000/1001")
3253  rate = NTV2_FRAMERATE_11988;
3254  else if (rateString == "15")
3255  rate = NTV2_FRAMERATE_1500;
3256  else if (rateString == "1500/1001")
3257  rate = NTV2_FRAMERATE_1498;
3258  else
3259  rate = NTV2_FRAMERATE_UNKNOWN;
3260  return rate;
3261 }
3262 
3263 void CNTV2Config2110::SetArbiter(const eSFP sfp, const NTV2Stream stream, bool enable)
3264 {
3265  uint32_t reg;
3266  if (StreamType(stream) == VIDEO_STREAM)
3267  {
3269  }
3270  else
3271  {
3273  }
3274  uint32_t val;
3275  mDevice.ReadRegister(reg, val);
3276 
3277  uint32_t bit = (1 << Get2110TxStreamIndex(stream)) << (int(sfp) * 16);
3278  if ((GetSampling(sfp, stream) == VPIDSampling_GBR_444) &&
3281  bit = bit << 4;
3282 
3283  if (enable)
3284  val |= bit;
3285  else
3286  val &= ~bit;
3287 
3288  mDevice.WriteRegister(reg, val);
3289 }
3290 
3291 void CNTV2Config2110::GetArbiter(const eSFP sfp, NTV2Stream stream, bool & enable)
3292 {
3293  uint32_t reg;
3294  if (StreamType(stream) == VIDEO_STREAM)
3295  {
3297  }
3298  else
3299  {
3301  }
3302  uint32_t val;
3303  mDevice.ReadRegister(reg, val);
3304 
3305  uint32_t bit = (1 << Get2110TxStreamIndex(stream)) << (int(sfp) * 16);
3306  if ((GetSampling(sfp, stream) == VPIDSampling_GBR_444) &&
3309  bit = bit << 4;
3310 
3311  enable = (val & bit);
3312 }
3313 
3314 void CNTV2Config2110::SetSampling(const eSFP sfp, const NTV2Stream stream, const VPIDSampling sampling)
3315 {
3316  if (StreamType(stream) == VIDEO_STREAM)
3317  {
3318  uint32_t samp = sampling;
3319  uint32_t mask = 0;
3320 
3321  switch (stream)
3322  {
3323  case NTV2_VIDEO4_STREAM:
3324  mask = 0xffff0fff;
3325  samp = samp << 12;
3326  break;
3327 
3328  case NTV2_VIDEO3_STREAM:
3329  mask = 0xfffff0ff;
3330  samp = samp << 8;
3331  break;
3332 
3333  case NTV2_VIDEO2_STREAM:
3334  mask = 0xffffff0f;
3335  samp = samp << 4;
3336  break;
3337 
3338  default:
3339  case NTV2_VIDEO1_STREAM:
3340  mask = 0xfffffff0;
3341  break;
3342  }
3343 
3344  if (sfp == SFP_2)
3345  {
3346  mask = mask << 16;
3347  mask |= 0xffff;
3348  samp = samp << 16;
3349  }
3350 
3351  uint32_t val;
3353  val &= mask;
3354  val |= samp;
3356  }
3357 }
3358 
3360 {
3362 
3363  if (StreamType(stream) == VIDEO_STREAM)
3364  {
3365  uint32_t val;
3367 
3368  if (sfp == SFP_2)
3369  val = val >> 16;
3370 
3371  switch (stream)
3372  {
3373  case NTV2_VIDEO4_STREAM:
3374  val = val >> 12;
3375  break;
3376 
3377  case NTV2_VIDEO3_STREAM:
3378  val = val >> 8;
3379  break;
3380 
3381  case NTV2_VIDEO2_STREAM:
3382  val = val >> 4;
3383  break;
3384 
3385  default:
3386  case NTV2_VIDEO1_STREAM:
3387  break;
3388 
3389  }
3390  sampling = (VPIDSampling)(val &= 0x0000000f);
3391  }
3392 
3393  return sampling;
3394 }
3395 
3396 bool CNTV2Config2110::SetLLDPInfo(std::string sysname)
3397 {
3398  return CNTV2MBController::SetLLDPInfo(sysname);
3399 }
3400 
3401 bool CNTV2Config2110::GetLLDPInfo(std::string &chassisId0, std::string &portId0,
3402  std::string &chassisId1, std::string &portId1)
3403 {
3404  return CNTV2MBController::GetLLDPInfo(chassisId0, portId0, chassisId1, portId1);
3405 }
3406 
3408 {
3410 }
3411 
Fractional rate of 15,000 frames per 1,001 seconds.
Definition: ntv2enums.h:429
#define NTV2_IS_SD_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:744
#define kReg4175_pkt_ctrl
uint8_t PTP_masterId[8]
#define kReg3190_pkt_num_samples
#define SFP_1_RX_LOS
#define NTV2_IS_720P_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:749
NTV2FrameRate GetNTV2FrameRateFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:3630
NTV2Channel channel
#define kRegPll_swptp_GrandMasterIdHi
#define SAREK_2110_DECAPSULATOR_1
void SetupDecapsulatorStream(const eSFP sfp, const NTV2Stream stream, const rx_2110Config &rxConfig)
bool GenAncStreamSDP(std::stringstream &sdp, const bool enableSfp1, const bool enableSfp2, const NTV2Stream stream, char *gmInfo)
#define kRegSarekRxReset
#define SAREK_3190_TX_PACKETIZER_0
#define kRegDecap_match_sel
#define SAREK_2110_AUDIO_ANC_FRAMER_1
#define kReg4175_pkt_payload_len_last
#define SAREK_4175_RX_DEPACKETIZER_4
#define kRegDecap_chan_enable
std::string NTV2IpErrorEnumToString(const NTV2IpError inIpErrorEnumValue)
Definition: ntv2utils.cpp:7512
#define kRegTxNtv2VideoDecode1
#define kRegDecap_match_ssrc
eNTV2PacketInterval audioPktInterval
static uint32_t videoDepacketizers[4]
#define SAREK_3190_RX_DEPACKETIZER_3
#define SAREK_4175_TX_PACKETIZER_RGB12_4
VPIDSampling videoSamples
#define kRegPll_PTP_LclMacHi
#define NULL
#define kSarekRegIGMPDisable2
#define kReg4175_depkt_rx_pkt_cnt
#define SFP_2_TX_FAULT
CNTV2Card & mDevice
Definition: ntv2mailbox.h:79
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:28
uint8_t firstAudioChannel
uint32_t numAudioChannels
#define BIT(_x_)
Definition: ajatypes.h:578
NTV2IpError getLastErrorCode(void)
See 10-Bit YCbCr Format.
Definition: ntv2enums.h:222
bool PushSDP(std::string filename, std::stringstream &sdpstream)
#define kRegDecap_match_udp_src_port
#define SAREK_RX0_MASK
enum _NTV2VideoFormat NTV2VideoFormat
Identifies a particular video format.
bool GetSDP(std::string url, std::string &sdp)
#define LINK_B_UP
Fractional rate of 120,000 frames per 1,001 seconds.
Definition: ntv2enums.h:427
#define SAREK_3190_TX_PACKETIZER_2
bool operator!=(const rx_2110Config &other)
#define kRegFramer_udp_src_port
bool GetPTPStatus(PTPStatus &ptpStatus)
uint64_t GetNTPTimestamp(void)
#define NTV2_VIDEO_FORMAT_HAS_PROGRESSIVE_PICTURE(__f__)
Definition: ntv2enums.h:1049
#define RX_MATCH_2110_DEST_IP
#define SAREK_REGS
#define kReg10gemac_rx_bytes_hi
Declares the AJATime class.
bool GetSFPInfo(eSFP port, SFPMSAData &sfpdata)
void GetArbiter(const eSFP sfp, const NTV2Stream stream, bool &enable)
bool GetMACAddress(const eSFP port, const NTV2Stream stream, std::string remoteIP, uint32_t &hi, uint32_t &lo)
bool ExtractRxAudioConfigFromSDP(std::string sdp, rx_2110Config &rxConfig)
#define kSarekRegIGMPDisable
#define SFP_1_NOT_PRESENT
#define kReg10gemac_tx_bytes_lo
#define kRegSarekGATE0
#define NTV2_IS_2K_1080_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:763
4K Video stream using 4 streams
Definition: ntv2enums.h:1438
Defines a number of handy byte-swapping macros.
bool GetRxStreamEnable(const eSFP sfp, const NTV2Stream stream, bool &enabled)
bool GenAudioStreamSDPInfo(std::stringstream &sdp, const eSFP sfp, const NTV2Stream stream, char *gmInfo)
bool WriteChannelRegister(ULWord reg, ULWord value, ULWord mask=0xFFFFFFFF, ULWord shift=0x0)
Definition: json.hpp:5362
Fractional rate of 60,000 frames per 1,001 seconds.
Definition: ntv2enums.h:417
bool GetPTPDomain(uint8_t &domain)
#define kReg4175_pkt_height
NTV2Channel VideoStreamToChannel(const NTV2Stream stream)
PTPLockStatus PTP_LockedState
#define SAREK_4175_RX_DEPACKETIZER_2
#define kReg4175_pkt_payload_len
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1357
#define kReg4175_pkt_ssrc
uint32_t sourcePort
Specifies the source (sender) port number (if RX_MATCH_2110_SOURCE_PORT set)
#define RX_MATCH_2110_DEST_PORT
#define SAREK_10G_EMAC_0
#define SAREK_3190_RX_DEPACKETIZER_4
bool SetTxStreamConfiguration(const NTV2Stream stream, const tx_2110Config &txConfig)
uint16_t vlan
Specifies the VLAN TCI (if RX_MATCH_2110_VLAN set)
bool GetSFPActive(eSFP sfp)
uint32_t localPort[2]
Specifies the local (source) port number.
bool GenSDP(bool enableSfp1, bool enableSfp2, const NTV2Stream stream, bool pushit=(!(0)))
bool GetPTPPreferredGrandMasterId(uint8_t(&id)[8])
#define kReg3190_pkt_payload_type
#define SAREK_4175_TX_PACKETIZER_3
uint32_t rxMatch
Bitmap of rxMatch criteria used.
Represents an unknown or invalid frame rate.
Definition: ntv2enums.h:414
void GetFramerStream(const eSFP sfp, const NTV2Stream stream, tx_2110Config &txConfig)
uint16_t payloadType
#define kRegSarekLinkStatus
50 frames per second
Definition: ntv2enums.h:423
void EnableIGMPGroup(eSFP port, NTV2Stream stream, bool enable)
bool GetIGMPVersion(eIGMPVersion_t &version)
void SelectTxFramerChannel(const NTV2Stream stream, const uint32_t baseAddr)
Fractional rate of 48,000 frames per 1,001 seconds.
Definition: ntv2enums.h:425
void DisableDecapsulatorStream(const eSFP sfp, const NTV2Stream stream)
30 frames per second
Definition: ntv2enums.h:418
std::string GetSDPUrl(const eSFP sfp, const NTV2Stream stream)
uint8_t PTP_domain
#define kRegPll_PTP_LclIP
NTV2FrameRate
Identifies a particular video frame rate.
Definition: ntv2enums.h:412
#define kRegFramer_dest_mac_lo
unsigned int n
Definition: pstream.cpp:148
NTV2Standard
Identifies a particular video standard.
Definition: ntv2enums.h:165
#define kRegPll_swptp_Domain
#define kRegPll_PTP_MstrMcast
#define kRegPll_swptp_PreferredGmIdHi
Declares the CNTV2Config2110 class.
void DisableDepacketizerStream(const NTV2Stream stream)
ULWord GetRasterHeight(const bool inVisibleOnly=false) const
std::string GetGeneratedSDP(bool enabledSfp1, bool enabledSfp2, const NTV2Stream stream)
#define SAREK_REGS2
bool GetLLDPInfo(std::string &chassisId0, std::string &portId0, std::string &chassisId1, std::string &portId1)
bool SetIGMPVersion(const eIGMPVersion_t version)
eIGMPVersion_t
#define kRegPll_PTP_MstrIP
uint32_t GetDepacketizerAddress(const NTV2Stream stream)
NTV2VideoFormat videoFormat
#define RX_MATCH_2110_PAYLOAD
bool SetFramerStream(const eSFP sfp, const NTV2Stream stream, const tx_2110Config &txConfig)
#define kReg10gemac_tx_bytes_hi
void EnableDepacketizerStream(const NTV2Stream stream)
#define kRegFramer_channel_access
#define kReg3190_depkt_enable
bool SetAudioCombineEnable(const bool enable)
Enables or disables the audio combiner.
#define kRegSarekGATE1
#define kRegArb_4KMode
Describes a video frame for a given video standard or format and pixel format, including the total nu...
Audio data.
Definition: ntv2enums.h:1436
void SetIGMPGroup(eSFP port, NTV2Stream stream, uint32_t mcast_addr, uint32_t src_addr, bool enable)
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
bool SetLLDPInfo(std::string sysname)
void split(const std::string &str, const char delim, std::vector< std::string > &elems)
Definition: common.cpp:350
bool GetTxPacketCount(NTV2Stream stream, uint32_t &packets)
bool GetRxByteCount(const NTV2Stream stream, uint32_t &bytes)
#define kRegRxVideoDecode1
#define SAREK_4175_TX_PACKETIZER_RGB12_2
bool SetRxStreamEnable(const eSFP sfp, const NTV2Stream stream, bool enable)
#define RX_MATCH_2110_SOURCE_IP
#define kRegPll_swptp_GrandMasterIdLo
#define kRegArb_video
#define NTV2_IS_PSF_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:1016
bool GenAudioStreamSDP(std::stringstream &sdp, const bool enableSfp1, const bool enableSfp2, const NTV2Stream stream, char *gmInfo)
#define kRegSarekNET1
bool GetLinkStatus(eSFP port, SFPStatus &sfpStatus)
void SetArbiter(const eSFP sfp, const NTV2Stream stream, bool enable)
VPIDSampling GetSampling(const eSFP sfp, const NTV2Stream stream)
#define SAREK_2110_DECAPSULATOR_0
Configures a SMPTE 2110 Receive Channel.
Configures a SMPTE 2110 Transmit Channel.
bool GetRxPacketCount(const NTV2Stream stream, uint32_t &packets)
Specifies channel or FrameStore 2 (or the 2nd item).
Definition: ntv2enums.h:1360
virtual NTV2DeviceID GetDeviceID(void)
NTV2StreamType StreamType(const NTV2Stream stream)
#define SAREK_4175_RX_DEPACKETIZER_1
bool operator==(const rx_2110Config &other)
void SetupDepacketizerStream(const NTV2Stream stream, const rx_2110Config &rxConfig)
VPIDSampling
Definition: ntv2enums.h:4088
bool operator!=(const tx_2110Config &other)
#define kRegFramer_dst_ip
rx_2110Config rx2110Config[4]
#define kRegSarekSFPStatus
#define SAREK_3190_TX_PACKETIZER_1
bool ConfigurePTP(const eSFP sfp, const std::string localIPAddress)
#define SAREK_2110_AUDIO_STREAMSELECT
#define kReg4175_pkt_pkts_per_line
#define kReg4175_depkt_control
bool SetIGMPVersion(uint32_t version)
void SetVideoFormatForRxTx(const NTV2Stream stream, const NTV2VideoFormat format, const bool rx)
#define SAREK_2110_VIDEO_FRAMER_0
#define SAREK_4175_TX_PACKETIZER_4
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...
uint8_t numAudioChannels
#define kReg4175_depkt_rx_byte_cnt
static uint32_t GetDecapsulatorAddress(eSFP sfp, NTV2Stream stream)
#define LINK_A_UP
uint32_t ipc_subnet
#define kRegArb_audio
#define kRegDecap_match_udp_dst_port
#define PLL_CONFIG_PTP
#define SAREK_4175_RX_DEPACKETIZER_3
Fractional rate of 30,000 frames per 1,001 seconds.
Definition: ntv2enums.h:419
#define kReg3190_pkt_chan_num
bool GetRxStreamConfiguration(const eSFP sfp, const NTV2Stream stream, rx_2110Config &rxConfig)
Anc data.
Definition: ntv2enums.h:1437
#define kRegFramer_udp_dst_port
uint32_t GetPacketizerAddress(const NTV2Stream stream, const VPIDSampling sampling)
#define kRegPll_swptp_MasterIdLo
bool DisableNetworkInterface(const eSFP sfp)
#define kRegTxAncSSRC1
#define kRegDecap_match_src_ip
bool SetRxStreamConfiguration(const eSFP sfp, const NTV2Stream stream, const rx_2110Config &rxConfig)
#define kReg4175_pkt_width
void UnsetIGMPGroup(eSFP port, NTV2Stream stream)
bool SetIGMPDisable(const eSFP sfp, const bool disable)
Disables the automatic (default) joining of multicast groups using IGMP, based on remote IP address f...
bool GetTxStreamConfiguration(const NTV2Stream stream, tx_2110Config &txConfig)
bool SetNetworkConfiguration(const eSFP sfp, const IPVNetConfig &netConfig)
bool GetTxStreamEnable(const NTV2Stream stream, bool &sfp1Enabled, bool &sfp2Enabled)
static uint32_t audioPacketizers[4]
virtual bool AncInsertSetIPParams(const UWord inSDIOutput, const UWord ancChannel, const ULWord payloadID, const ULWord ssrc)
Configures the Anc inserter IP specific params.
Definition: ntv2anc.cpp:498
bool operator==(const tx_2110Config &other)
NTV2FrameGeometry
Identifies a particular video frame geometry.
Definition: ntv2enums.h:348
bool GetSFPMSAData(eSFP port, SFPMSAData &data)
60 frames per second
Definition: ntv2enums.h:415
15 frames per second
Definition: ntv2enums.h:428
Declares numerous NTV2 utility functions.
#define PLL_CONFIG_DCO_MODE
std::string remoteIP[2]
Specifies remote (destination) IP address.
#define RESET_MILLISECONDS
bool SetMBNetworkConfiguration(eSFP port, std::string ipaddr, std::string netmask, std::string gateway)
#define kRegDecap_match_payload
#define SAREK_4175_TX_PACKETIZER_2
bool ExtractRxVideoConfigFromSDP(std::string sdp, rx_2110Config &rxConfig)
bool Set4KModeEnable(const bool enable)
#define kRegSarekSampling
#define kReg4175_pkt_pix_per_pkt
#define kRegFramer_chan_ctrl
#define SAREK_2110_AUDIO_ANC_FRAMER_0
bool GenVideoStreamMultiSDPInfo(std::stringstream &sdp, char *gmInfo)
bool GetLLDPInfo(std::string &chassisId0, std::string &portId0, std::string &chassisId1, std::string &portId1)
PTPLockStatus
bool GetIPServicesControl(bool &enable, bool &forceReconfig)
void ResetDepacketizerStream(const NTV2Stream stream)
bool ExtractRxAncConfigFromSDP(std::string sdp, rx_2110Config &rxConfig)
bool GetRemoteMAC(std::string remote_IPAddress, eSFP port, NTV2Stream stream, std::string &MACaddress)
#define SAREK_TX0_MASK
bool GetTxByteCount(const eSFP sfp, uint64_t &bytes)
virtual bool WriteRegister(const ULWord inRegNum, const ULWord inValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0)
Updates or replaces all or part of the 32-bit contents of a specific register (real or virtual) on th...
ULWord GetRasterWidth(void) const
#define kRegTxVideoDecode1
uint32_t GetFramerAddress(const eSFP sfp, const NTV2Stream stream)
#define kRegDecap_match_dst_ip
uint8_t mac[6]
Specifies channel or FrameStore 1 (or the first item).
Definition: ntv2enums.h:1359
120 frames per second
Definition: ntv2enums.h:426
static uint32_t videoRGB12Packetizers[4]
NTV2Standard GetVideoStandard(void) const
bool GetAudioCombineEnable(bool &outEnabled)
Answers with the enable/disable state of the audio combiner.
#define kReg3190_pkt_num_audio_channels
static uint32_t audioDepacketizers[4]
#define kRegPll_swptp_LockedState
25 frames per second
Definition: ntv2enums.h:420
#define kReg3190_depkt_config
#define kRegPll_PTP_EventUdp
#define SFP_2_NOT_PRESENT
#define kReg3190_pkt_payload_len
#define SAREK_2110_TX_ARBITRATOR
static uint32_t videoPacketizers[4]
#define kRegSarekMAC
#define SAREK_4175_TX_PACKETIZER_RGB12_1
NTV2Stream
Identifies a specific IP-based data stream.
Definition: ntv2enums.h:1407
#define SAREK_TX1_MASK
bool GetNetworkConfiguration(const eSFP sfp, IPVNetConfig &netConfig)
NTV2VideoFormat GetFirstMatchingVideoFormat(const NTV2FrameRate inFrameRate, const UWord inHeightLines, const UWord inWidthPixels, const bool inIsInterlaced, const bool inIsLevelB, const bool inIsPSF)
Definition: ntv2utils.cpp:1921
void ResetPacketizerStream(const NTV2Stream stream)
Declares the CNTV2Card class.
NTV2VideoFormat videoFormat
uint32_t getFeatures()
Specifies channel or FrameStore 4 (or the 4th item).
Definition: ntv2enums.h:1362
void SetSampling(const eSFP sfp, const NTV2Stream stream, const VPIDSampling sampling)
#define kRegPll_swptp_MasterIdHi
bool GenVideoStreamSDP(std::stringstream &sdp, const bool enableSfp1, const bool enableSfp2, const NTV2Stream stream, char *gmInfo)
std::string sourceIP
Specifies the source (sender) IP address (if RX_MATCH_2110_SOURCE_IP set). If it&#39;s in the multiclass ...
uint8_t PTP_gmId[8]
bool GetActualSDP(std::string url, std::string &sdp)
#define kReg4175_pkt_chan_num
uint32_t remotePort[2]
Specifies the remote (destination) port number.
#define kReg4175_pkt_interlace_ctrl
bool Get4KModeEnable(bool &enable)
static uint32_t Get2110TxStreamIndex(NTV2Stream stream)
void GetVideoFormatForRxTx(const NTV2Stream stream, NTV2VideoFormat &format, uint32_t &hwFormat, const bool rx)
NTV2StreamType
Identifies the kind of data that can be carried by an IP-based data stream.
Definition: ntv2enums.h:1433
virtual bool IsMBSystemValid(void)
void ReleaseFramerControlAccess(const uint32_t baseAddr)
#define SAREK_3190_RX_DEPACKETIZER_2
std::string getLastError(void)
#define SAREK_4175_TX_PACKETIZER_1
#define SAREK_2110_VIDEO_FRAMER_1
bool GetIGMPDisable(const eSFP sfp, bool &disabled)
#define SAREK_PLL
#define kRegFramer_src_mac_lo
#define kRegRxNtv2VideoDecode1
#define kRegPll_PTP_LclMacLo
uint32_t destPort
Specifies the destination (target) port number (if RX_MATCH_2110_DEST_PORT set)
std::string destIP
Specifies the destination (target) IP address (if RX_MATCH_2110_DEST_IP set)
bool SetPTPDomain(const uint8_t domain)
#define kRegSarekIGMPVersion
#define kRegFramer_dest_mac_hi
#define kRegFramer_src_ip
void AcquireFramerControlAccess(const uint32_t baseAddr)
#define SAREK_10G_EMAC_1
#define kReg4175_pkt_payload_type
virtual bool IsMBSystemReady(void)
#define kReg3190_pkt_ssrc
48 frames per second
Definition: ntv2enums.h:424
eNTV2PacketInterval audioPktInterval
bool DisableNetworkInterface(eSFP port)
#define SAREK_3190_TX_PACKETIZER_3
#define kRegPll_swptp_PreferredGmIdLo
#define kRegSarekIP1
void EnableFramerStream(const eSFP sfp, const NTV2Stream stream, bool enable)
#define kRegSarekIP0
#define kRegSarekNET0
NTV2IpError
Definition: ntv2enums.h:4313
#define kRegFramer_control
bool SetIPServicesControl(const bool enable, const bool forceReconfig)
#define kReg10gemac_rx_bytes_lo
#define SAREK_3190_RX_DEPACKETIZER_1
24 frames per second
Definition: ntv2enums.h:421
void EnableDecapsulatorStream(const eSFP sfp, const NTV2Stream stream)
#define SFP_2_RX_LOS
uint16_t payloadType
Video data.
Definition: ntv2enums.h:1435
#define SFP_1_TX_FAULT
VPIDSampling videoSamples
bool SetTxFormat(NTV2Channel chan, NTV2VideoFormat fmt)
CNTV2Config2110(CNTV2Card &device)
uint32_t ssrc
Specifies the SSRC identifier (if RX_MATCH_2110_SSRC set)
bool ReadChannelRegister(const ULWord inReg, ULWord &outValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0x0)
#define kRegFramer_src_mac_hi
#define NTV2EndianSwap32(__val__)
Definition: ntv2endian.h:19
bool SetPTPPreferredGrandMasterId(const uint8_t id[8])
#define kReg4175_pkt_tx_pkt_cnt
#define kRegFramer_status
#define SAREK_RX1_MASK
#define SAREK_4175_TX_PACKETIZER_RGB12_3
uint32_t ipc_gateway
bool SetLLDPInfo(std::string sysname)
#define kReg3190_depkt_rx_pkt_count
Fractional rate of 24,000 frames per 1,001 seconds.
Definition: ntv2enums.h:422
bool SetTxStreamEnable(const NTV2Stream stream, bool enableSfp1, bool enableSfp2=(0))
Specifies channel or FrameStore 3 (or the 3rd item).
Definition: ntv2enums.h:1361
bool GetTxFormat(NTV2Channel chan, NTV2VideoFormat &fmt)
#define kRegTxAncPayload1
bool GenVideoStreamSDPInfo(std::stringstream &sdp, const eSFP sfp, const NTV2Stream stream, char *gmInfo)
#define kRegSarekServices
#define kReg4175_pkt_vid_fmt
bool GenAncStreamSDPInfo(std::stringstream &sdp, const eSFP sfp, const NTV2Stream stream, char *gmInfo)
#define kRegPll_PTP_Match
NTV2IpError mIpErrorCode
Definition: ntv2mailbox.h:81
NTV2FrameGeometry GetNTV2FrameGeometryFromVideoFormat(const NTV2VideoFormat inVideoFormat)
Definition: ntv2utils.cpp:2644
#define kRegFramer_ip_hdr_media
#define kRegPll_Config
void SetChannel(ULWord channelOffset, ULWord channelNumber)