AJA NTV2 SDK  18.1.0.2439
NTV2 SDK 18.1.0.2439
ntv2subscriptions.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #include "ntv2card.h"
9 #include "ajabase/system/debug.h"
10 
11 using namespace std;
12 
13 #define INSTP(_p_) HEX0N(uint64_t(_p_),16)
14 #define DIFAIL(__x__) AJA_sERROR (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
15 #define DIWARN(__x__) AJA_sWARNING(AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
16 #define DINOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
17 #define DIINFO(__x__) AJA_sINFO (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
18 #define DIDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
19 
20 
23 
24 
25 // Subscribe/Unsubscribe to/from events
26 
28 {
29  if (!IsOpen())
30  {DIFAIL("Cannot subscribe to '" << NTV2CfgInterrupt::IntName(id) << "' -- device not open"); return false;}
32  {DIFAIL("Cannot subscribe to '" << NTV2CfgInterrupt::IntName(id) << "' -- bad interrupt ID"); return false;}
33 #if defined(NTV2_NUB_CLIENT_SUPPORT)
34  if (IsRemote())
35  { NTV2ConfigureInterrupt msg(this);
36  return _pRPCAPI->NTV2MessageRemote(msg.doSubscribe(id)) && msg.isSuccess();
37  }
38 #endif// defined(NTV2_NUB_CLIENT_SUPPORT)
39 #if defined(MSWindows)
40  return WinConfigureSubscription (true, id);
41 #else
42  DIDBG("Subscribe to '" << NTV2CfgInterrupt::IntName(id) << "' is a no-op on this platform");
43  return true; // Non-Windows platforms reply "good to go"
44 #endif
45 }
46 
48 { UWord failures(0);
49  for (NTV2ChannelSetConstIter it(inChannels.begin()); it != inChannels.end(); ++it)
50  if (!SubscribeOutputVerticalEvent(*it))
51  failures++;
52  return !failures;
53 }
54 
56 { UWord failures(0);
57  for (NTV2ChannelSetConstIter it(inChannels.begin()); it != inChannels.end(); ++it)
58  if (!SubscribeInputVerticalEvent(*it))
59  failures++;
60  return !failures;
61 }
62 
64 {
65  if (!IsOpen())
66  {DIFAIL("Cannot unsubscribe from '" << NTV2CfgInterrupt::IntName(id) << "' -- device not open"); return false;}
68  {DIFAIL("Cannot unsubscribe from '" << NTV2CfgInterrupt::IntName(id) << "' -- bad interrupt ID"); return false;}
69 #if defined(NTV2_NUB_CLIENT_SUPPORT)
70  if (IsRemote())
71  { NTV2ConfigureInterrupt msg(this);
72  return _pRPCAPI->NTV2MessageRemote(msg.doUnsubscribe(id)) && msg.isSuccess();
73  }
74 #endif// defined(NTV2_NUB_CLIENT_SUPPORT)
75 #if defined(MSWindows)
76  return WinConfigureSubscription (false, id);
77 #else
78  DIDBG("Unsubscribe from '" << NTV2CfgInterrupt::IntName(id) << "' is a no-op on this platform");
79  return true; // Non-Windows platforms reply "good to go"
80 #endif
81 }
82 
84 { UWord failures(0);
85  for (NTV2ChannelSetConstIter it(inChannels.begin()); it != inChannels.end(); ++it)
86  if (!UnsubscribeOutputVerticalEvent(*it))
87  failures++;
88  return !failures;
89 }
90 
92 { UWord failures(0);
93  for (NTV2ChannelSetConstIter it(inChannels.begin()); it != inChannels.end(); ++it)
94  if (!UnsubscribeInputVerticalEvent(*it))
95  failures++;
96  return !failures;
97 }
98 
99 // NOTE: There's currently no API call to inquire which interrupts are subscribed or not
100 
101 
102 // Get interrupt count from driver
103 
105 {
106  outCount = 0;
107  return GetInterruptCount(::NTV2ChannelToOutputInterrupt(inChannel), outCount);
108 }
109 
110 
112 {
113  outCount = 0;
114  return GetInterruptCount (::NTV2ChannelToInputInterrupt(inChannel), outCount);
115 }
116 
117 // NOTE: There's currently no driver API call to reset the driver's interrupt counters
118 
119 
120 bool CNTV2Card::WaitForOutputVerticalInterrupt (const NTV2Channel inChannel, UWord inRepeatCount)
121 {
122  bool result (true);
123  if (!NTV2_IS_VALID_CHANNEL(inChannel))
124  return false;
125  if (!inRepeatCount)
126  return false;
127  do
128  {
129  result = WaitForInterrupt (::NTV2ChannelToOutputInterrupt(inChannel));
130  } while (--inRepeatCount && result);
131  return result;
132 }
133 
134 
135 bool CNTV2Card::WaitForInputVerticalInterrupt (const NTV2Channel inChannel, UWord inRepeatCount)
136 {
137  bool result (true);
138  if (!NTV2_IS_VALID_CHANNEL (inChannel))
139  return false;
140  if (!inRepeatCount)
141  return false;
142  do
143  {
144  result = WaitForInterrupt (::NTV2ChannelToInputInterrupt(inChannel));
145  } while (--inRepeatCount && result);
146  return result;
147 }
148 
149 
150 bool CNTV2Card::GetOutputFieldID (const NTV2Channel channel, NTV2FieldID & outFieldID)
151 {
152  // CHANNEL1 CHANNEL2 CHANNEL3 CHANNEL4 CHANNEL5 CHANNEL6 CHANNEL7 CHANNEL8
154  static ULWord bitShift [] = { 23, 5, 3, 1, 9, 7, 5, 3, 0};
155 
156  // Check status register to see if it is the one we want.
157  ULWord statusValue (0);
158  outFieldID = ReadRegister (regNum[channel], statusValue)
159  ? NTV2FieldID((statusValue >> bitShift[channel]) & 0x1)
161  return NTV2_IS_VALID_FIELD(outFieldID);
162 
163 } // GetOutputFieldID
164 
165 
166 bool CNTV2Card::WaitForOutputFieldID (const NTV2FieldID inFieldID, const NTV2Channel channel)
167 {
168  // Wait for next field interrupt...
169  bool bInterruptHappened (WaitForOutputVerticalInterrupt(channel));
170 
171  // Check status register to see if it is the one we want.
172  NTV2FieldID currentFieldID (NTV2_FIELD0);
173  GetOutputFieldID(channel, currentFieldID);
174 
175  // If not, wait for another field interrupt...
176  if (currentFieldID != inFieldID)
177  bInterruptHappened = WaitForOutputVerticalInterrupt(channel);
178 
179  return bInterruptHappened;
180 
181 } // WaitForOutputFieldID
182 
183 
184 bool CNTV2Card::GetInputFieldID (const NTV2Channel channel, NTV2FieldID & outFieldID)
185 {
186  // CHANNEL1 CHANNEL2 CHANNEL3 CHANNEL4 CHANNEL5 CHANNEL6 CHANNEL7 CHANNEL8
188  static ULWord bitShift [] = { 21, 19, 21, 19, 17, 15, 13, 3, 0};
189 
190  // See if the field ID of the last input vertical interrupt is the one of interest...
191  ULWord statusValue (0);
192  outFieldID = ReadRegister (regNum[channel], statusValue)
193  ? NTV2FieldID((statusValue >> bitShift[channel]) & 0x1)
195  return NTV2_IS_VALID_FIELD(outFieldID);
196 
197 } // GetInputFieldID
198 
199 
200 bool CNTV2Card::WaitForInputFieldID (const NTV2FieldID inFieldID, const NTV2Channel channel)
201 {
202  // Wait for next field interrupt...
203  bool bInterruptHappened (WaitForInputVerticalInterrupt(channel));
204 
205  // See if the field ID of the last input vertical interrupt is the one of interest...
206  NTV2FieldID currentFieldID (NTV2_FIELD0);
207  GetInputFieldID(channel, currentFieldID);
208 
209  // If not, wait for another field interrupt...
210  if (currentFieldID != inFieldID)
211  bInterruptHappened = WaitForInputVerticalInterrupt(channel);
212 
213  return bInterruptHappened;
214 
215 } // WaitForInputFieldID
virtual bool WaitForInputFieldID(const NTV2FieldID inFieldID, const NTV2Channel inChannel=NTV2_CHANNEL1)
Efficiently sleeps the calling thread/process until the next input VBI for the given field and input ...
NTV2FieldID
These values are used to identify fields for interlaced video. See Field/Frame Interrupts and CNTV2Ca...
Definition: ntv2enums.h:1845
NTV2ChannelSet::const_iterator NTV2ChannelSetConstIter
A handy const iterator into an NTV2ChannelSet.
Declares the AJADebug class.
bool isSuccess(void) const
#define NTV2_IS_VALID_INTERRUPT_ENUM(__e__)
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
Definition: ntv2card.h:2763
Configure interrupt (subscribe/unsubscribe, enable/disable, query subscribed interrupts, query enabled interrupts, etc.).
#define DIDBG(__x__)
INTERRUPT_ENUMS NTV2ChannelToInputInterrupt(const NTV2Channel inChannel)
Converts the given NTV2Channel value into the equivalent input INTERRUPT_ENUMS value.
Definition: ntv2utils.cpp:4941
Definition: json.hpp:5362
uint32_t ULWord
Definition: ajatypes.h:236
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1361
virtual bool SubscribeEvent(const INTERRUPT_ENUMS inEventCode)
Causes me to be notified when the given event/interrupt is triggered for the AJA device.
#define DIFAIL(__x__)
virtual bool WaitForOutputFieldID(const NTV2FieldID inFieldID, const NTV2Channel inChannel=NTV2_CHANNEL1)
Efficiently sleeps the calling thread/process until the next output VBI for the given field and outpu...
virtual bool SubscribeInputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Causes me to be notified when an input vertical blanking interrupt occurs on the given input channel...
Definition: ntv2card.h:2787
enum _INTERRUPT_ENUMS_ INTERRUPT_ENUMS
static INTERRUPT_ENUMS gChannelToInputVerticalInterrupt[]
virtual bool GetInputFieldID(const NTV2Channel inChannel, NTV2FieldID &outFieldID)
Returns the current field ID of the specified input channel.
virtual bool UnsubscribeEvent(const INTERRUPT_ENUMS inEventCode)
Unregisters me so I&#39;m no longer notified when the given event/interrupt is triggered on the AJA devic...
NTV2ConfigInterrupt & doUnsubscribe(const INTERRUPT_ENUMS id)
Unsubscribe local HANDLE from given interruptID.
#define NTV2_IS_VALID_CHANNEL(__x__)
Definition: ntv2enums.h:1375
virtual bool UnsubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Unregisters me so I&#39;m no longer notified when an output VBI is signaled on the given output channel...
Definition: ntv2card.h:2819
std::set< NTV2Channel > NTV2ChannelSet
A set of distinct NTV2Channel values.
virtual bool WaitForOutputVerticalInterrupt(const NTV2Channel inChannel=NTV2_CHANNEL1, UWord inRepeatCount=1)
Efficiently sleeps the calling thread/process until the next one or more field (interlaced video) or ...
virtual bool GetOutputFieldID(const NTV2Channel inChannel, NTV2FieldID &outFieldID)
Returns the current field ID of the specified output channel.
NTV2ConfigInterrupt & doSubscribe(const INTERRUPT_ENUMS id)
Create event handle and subscribe it to given interruptID.
uint16_t UWord
Definition: ajatypes.h:234
virtual bool UnsubscribeInputVerticalEvent(const NTV2Channel inChannel=NTV2_CHANNEL1)
Unregisters me so I&#39;m no longer notified when an input VBI is signaled on the given input channel...
Definition: ntv2card.h:2837
Declares the CNTV2Card class.
#define NTV2_IS_VALID_FIELD(__x__)
Definition: ntv2enums.h:1852
virtual bool GetInputVerticalInterruptCount(ULWord &outCount, const NTV2Channel inChannel=NTV2_CHANNEL1)
Answers with the number of input vertical interrupts handled by the driver for the given input channe...
Identifies the first field in time for an interlaced video frame, or the first and only field in a pr...
Definition: ntv2enums.h:1847
INTERRUPT_ENUMS NTV2ChannelToOutputInterrupt(const NTV2Channel inChannel)
Converts the given NTV2Channel value into the equivalent output INTERRUPT_ENUMS value.
Definition: ntv2utils.cpp:4951
static std::string IntName(const INTERRUPT_ENUMS id)
virtual bool GetOutputVerticalInterruptCount(ULWord &outCount, const NTV2Channel inChannel=NTV2_CHANNEL1)
Answers with the number of output vertical interrupts handled by the driver for the given output chan...
virtual bool WaitForInputVerticalInterrupt(const NTV2Channel inChannel=NTV2_CHANNEL1, UWord inRepeatCount=1)
Efficiently sleeps the calling thread/process until the next one or more field (interlaced video) or ...
static INTERRUPT_ENUMS gChannelToOutputVerticalInterrupt[]