AJA NTV2 SDK  18.1.0.2439
NTV2 SDK 18.1.0.2439
ntv2windriverinterface.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
10 #include "ntv2publicinterface.h"
11 #include "ntv2nubtypes.h"
12 #include "ntv2debug.h"
13 #include "winioctl.h"
14 #include "ajabase/system/debug.h"
15 #include <sstream>
16 
17 using namespace std;
18 
19 #ifdef _AJA_COMPILE_WIN2K_SOFT_LINK
20 typedef WINSETUPAPI
21 HDEVINFO
22 (WINAPI *
23 pfcnSetupDiGetClassDevsA)(
24  IN CONST GUID *ClassGuid, OPTIONAL
25  IN PCSTR Enumerator, OPTIONAL
26  IN HWND hwndParent, OPTIONAL
27  IN DWORD Flags
28  );
29 
30 typedef WINSETUPAPI
31 HDEVINFO
32 (WINAPI *
33 pfcnSetupDiGetClassDevsW)(
34  IN CONST GUID *ClassGuid, OPTIONAL
35  IN PCWSTR Enumerator, OPTIONAL
36  IN HWND hwndParent, OPTIONAL
37  IN DWORD Flags
38  );
39 #ifdef UNICODE
40 #define pfcnSetupDiGetClassDevs pfcnSetupDiGetClassDevsW
41 #else
42 #define pfcnSetupDiGetClassDevs pfcnSetupDiGetClassDevsA
43 #endif
44 
45 typedef WINSETUPAPI
46 BOOL
47 (WINAPI *
48 pfcnSetupDiEnumDeviceInterfaces)(
49  IN HDEVINFO DeviceInfoSet,
50  IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL
51  IN CONST GUID *InterfaceClassGuid,
52  IN DWORD MemberIndex,
53  OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
54  );
55 
56 
57 typedef WINSETUPAPI
58 BOOL
59 (WINAPI *
60 pfcnSetupDiGetDeviceInterfaceDetailA)(
61  IN HDEVINFO DeviceInfoSet,
62  IN PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
63  OUT PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData, OPTIONAL
64  IN DWORD DeviceInterfaceDetailDataSize,
65  OUT PDWORD RequiredSize, OPTIONAL
66  OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
67  );
68 
69 typedef WINSETUPAPI
70 BOOL
71 (WINAPI *
72 pfcnSetupDiGetDeviceInterfaceDetailW)(
73  IN HDEVINFO DeviceInfoSet,
74  IN PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
75  OUT PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, OPTIONAL
76  IN DWORD DeviceInterfaceDetailDataSize,
77  OUT PDWORD RequiredSize, OPTIONAL
78  OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
79  );
80 #ifdef UNICODE
81 #define pfcnSetupDiGetDeviceInterfaceDetail pfcnSetupDiGetDeviceInterfaceDetailW
82 #else
83 #define pfcnSetupDiGetDeviceInterfaceDetail pfcnSetupDiGetDeviceInterfaceDetailA
84 #endif
85 
86 typedef WINSETUPAPI
87 BOOL
88 (WINAPI *
89  pfcnSetupDiDestroyDeviceInfoList)(
90  IN HDEVINFO DeviceInfoSet
91  );
92 
93 typedef WINSETUPAPI
94 BOOL
95 (WINAPI *
96  pfcnSetupDiDestroyDriverInfoList)(
97  IN HDEVINFO DeviceInfoSet,
98  IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL
99  IN DWORD DriverType
100  );
101 
102 static pfcnSetupDiGetClassDevs pSetupDiGetClassDevs = NULL;
103 static pfcnSetupDiEnumDeviceInterfaces pSetupDiEnumDeviceInterfaces = NULL;
104 static pfcnSetupDiGetDeviceInterfaceDetail pSetupDiGetDeviceInterfaceDetail = NULL;
105 static pfcnSetupDiDestroyDeviceInfoList pSetupDiDestroyDeviceInfoList = NULL;
106 static pfcnSetupDiDestroyDriverInfoList pSetupDiDestroyDriverInfoList = NULL;
107 
108 HINSTANCE hSetupAPI = NULL;
109 
110 #endif
111 
112 static std::string GetKernErrStr (const DWORD inError)
113 {
114  LPVOID lpMsgBuf(NULL);
115  FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
116  NULL,
117  inError,
118  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
119  (LPTSTR) &lpMsgBuf,
120  0,
121  NULL);
122  string result (lpMsgBuf ? reinterpret_cast<const char*>(lpMsgBuf) : "");
123  LocalFree (lpMsgBuf);
124 // Truncate at <CR><LF>...
125  const size_t crPos(result.find(".\r"));
126  if (crPos != string::npos)
127  result.resize(crPos);
128  return result;
129 }
130 
131 
132 // WinDriverInterface Logging Macros
133 #define HEX2(__x__) "0x" << hex << setw(2) << setfill('0') << (0xFF & uint8_t (__x__)) << dec
134 #define HEX4(__x__) "0x" << hex << setw(4) << setfill('0') << (0xFFFF & uint16_t(__x__)) << dec
135 #define HEX8(__x__) "0x" << hex << setw(8) << setfill('0') << (0xFFFFFFFF & uint32_t(__x__)) << dec
136 #define HEX16(__x__) "0x" << hex << setw(16) << setfill('0') << uint64_t(__x__) << dec
137 #define KR(_kr_) "kernResult=" << HEX8(_kr_) << "(" << GetKernErrStr(_kr_) << ")"
138 #define INSTP(_p_) HEX16(uint64_t(_p_))
139 
140 #define WDIFAIL(__x__) AJA_sERROR (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
141 #define WDIWARN(__x__) AJA_sWARNING(AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
142 #define WDINOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
143 #define WDIINFO(__x__) AJA_sINFO (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
144 #define WDIDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_DriverInterface, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
145 
146 
148  : _pspDevIFaceDetailData (AJA_NULL)
149  ,_hDevInfoSet (INVALID_HANDLE_VALUE)
150  ,_hDevice (INVALID_HANDLE_VALUE)
151  ,_previousAudioState (0)
152  ,_previousAudioSelection (0)
153  ,mInterruptEventHandles ()
154 #if !defined(NTV2_DEPRECATE_16_0)
155  ,_vecDmaLocked ()
156 #endif // !defined(NTV2_DEPRECATE_16_0)
157 {
160  mInterruptEventHandles.push_back(AJA_NULL);
161  ::memset(&_spDevInfoData, 0, sizeof(_spDevInfoData));
162  ::memset(&_GUID_PROPSET, 0, sizeof(_GUID_PROPSET));
163 }
164 
166 {
167  if (IsOpen())
168  Close();
169 }
170 
171 
172 #if !defined(NTV2_NULL_DEVICE)
173 // Board Open / Close methods
176 
178 {
179  NTV2_ASSERT(!IsRemote());
180  NTV2_ASSERT(!IsOpen());
182  string boardStr;
183 
184  {
185  DEFINE_GUIDSTRUCT("844B39E5-C98E-45a1-84DE-3BAF3F4F9F14", AJAVIDEO_NTV2_PROPSET);
186 #define AJAVIDEO_NTV2_PROPSET DEFINE_GUIDNAMED(AJAVIDEO_NTV2_PROPSET)
188  }
189 
190  REFGUID refguid = _GUID_PROPSET;
191  setDeviceIndexNumber(inDeviceIndex);
192 
193  DWORD dwShareMode (GetShareMode() ? FILE_SHARE_READ | FILE_SHARE_WRITE : 0);
194  DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED;
195  DWORD dwReqSize=0;
196  SP_DEVICE_INTERFACE_DATA spDevIFaceData;
197  memset(&spDevIFaceData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
198  GUID myguid = refguid; // an un-const guid for compiling with new Platform SDK!
199  _hDevInfoSet = SetupDiGetClassDevs(&myguid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
201  return false;
202  spDevIFaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
203  myguid = refguid;
204  if (!SetupDiEnumDeviceInterfaces(_hDevInfoSet, NULL, &myguid, GetIndexNumber(), &spDevIFaceData))
205  {
206  SetupDiDestroyDeviceInfoList(_hDevInfoSet);
207  return false;
208  }
209 
210  if (SetupDiGetDeviceInterfaceDetail(_hDevInfoSet, &spDevIFaceData, NULL, 0, &dwReqSize, NULL))
211  {
212  SetupDiDestroyDeviceInfoList(_hDevInfoSet);
213  return false; //should have failed!
214  }
215  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
216  {
217  SetupDiDestroyDeviceInfoList(_hDevInfoSet);
218  return false;
219  }
220  _pspDevIFaceDetailData = PSP_DEVICE_INTERFACE_DETAIL_DATA(new BYTE[dwReqSize]);
222  {
223  SetupDiDestroyDeviceInfoList(_hDevInfoSet);
224  return false; // out of memory
225  }
226 
227  memset(&_spDevInfoData, 0, sizeof(SP_DEVINFO_DATA));
228  _spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
229  _pspDevIFaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
230  //now we are setup to get the info we want!
231  if (!SetupDiGetDeviceInterfaceDetail(_hDevInfoSet, &spDevIFaceData, _pspDevIFaceDetailData, dwReqSize, NULL, &_spDevInfoData))
232  {
233  delete [] _pspDevIFaceDetailData;
235  SetupDiDestroyDeviceInfoList(_hDevInfoSet);
236  return false; // out of memory
237  }
238 
239  ULONG deviceInstanceSize = 0;
240  CM_Get_Device_ID_Size(&deviceInstanceSize, _spDevInfoData.DevInst, 0);
241  char* deviceInstance = (char*)new BYTE[deviceInstanceSize*2];
242  CM_Get_Device_IDA(_spDevInfoData.DevInst, deviceInstance, deviceInstanceSize*2, 0);
243  boardStr = deviceInstance;
244  delete [] deviceInstance;
245 
246  _hDevice = CreateFile(_pspDevIFaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, dwShareMode, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
248  {
249  WDIFAIL("CreateFile failed for '" << boardStr << "'");
250  delete [] _pspDevIFaceDetailData;
252  SetupDiDestroyDeviceInfoList(_hDevInfoSet);
253  _hDevInfoSet = NULL;
254  return false;
255  }
256 
257  _boardOpened = true;
259 
260  WDIINFO ("Opened '" << boardStr << "' deviceID=" << HEX8(_boardID) << " deviceIndex=" << DEC(GetIndexNumber()));
261  return true;
262 } // OpenLocalPhysical
263 
264 
265 
267 {
268  NTV2_ASSERT(!IsRemote());
269  NTV2_ASSERT(IsOpen());
271 
272  // Unsubscribe all interrupts...
273  for (INTERRUPT_ENUMS eInt(eVerticalInterrupt); eInt < eNumInterruptTypes; eInt = INTERRUPT_ENUMS(eInt+1))
274  WinConfigureSubscription (/*bSubscribe*/false, eInt);
276  {
277  delete [] _pspDevIFaceDetailData;
279  }
280  if (_hDevInfoSet)
281  {
282 #ifndef _AJA_COMPILE_WIN2K_SOFT_LINK
283  SetupDiDestroyDeviceInfoList(_hDevInfoSet);
284 #else
285  if (pSetupDiDestroyDeviceInfoList)
286  pSetupDiDestroyDeviceInfoList(_hDevInfoSet);
287 #endif
289  }
290 
292  CloseHandle(_hDevice);
293  WDIINFO ("Closed deviceID=" << HEX8(_boardID) << " deviceIndex=" << DEC(GetIndexNumber()));
294 
296  _boardOpened = false;
297  return true;
298 }
299 #endif // !defined(NTV2_NULL_DEVICE)
300 
301 
302 
304 // Read and Write Register methods
306 
307 bool CNTV2WinDriverInterface::ReadRegister (const ULWord inRegNum, ULWord & outValue, const ULWord inMask, const ULWord inShift)
308 {
309  if (inShift >= 32)
310  {
311  WDIFAIL("Shift " << DEC(inShift) << " > 31, reg=" << DEC(inRegNum) << " msk=" << xHEX0N(inMask,8));
312  return false;
313  }
314 #if defined(NTV2_NUB_CLIENT_SUPPORT)
315  if (IsRemote())
316  return CNTV2DriverInterface::ReadRegister (inRegNum, outValue, inMask, inShift);
317 #endif // defined(NTV2_NUB_CLIENT_SUPPORT)
318  if (!IsOpen())
319  return false;
320 
322 
324  DWORD dwBytesReturned = 0;
325  ZeroMemory(&propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETREGISTER_S));
326  propStruct.Property.Set = _GUID_PROPSET;
328  propStruct.Property.Flags = KSPROPERTY_TYPE_GET;
329  propStruct.RegisterID = inRegNum;
330  propStruct.ulRegisterMask = inMask;
331  propStruct.ulRegisterShift = inShift;
333  const bool ok = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_GETSETREGISTER, &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETREGISTER_S),
334  &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETREGISTER_S), &dwBytesReturned, NULL);
336  if (ok)
337  {
338  outValue = propStruct.ulRegisterValue;
339 #if defined(NTV2_PRETEND_DEVICE)
340  if (inRegNum == kRegBoardID && outValue == NTV2_PRETEND_DEVICE_FROM)
341  outValue = NTV2_PRETEND_DEVICE_TO;
342 // else if (inRegNum == kRegReserved83 || inRegNum == kRegLPRJ45IP)
343 // outValue = 0x0A03FAD9; // Local IPv4 10.3.250.217
344 #endif // NTV2_PRETEND_DEVICE
345  return true;
346  }
347  WDIFAIL("reg=" << DEC(inRegNum) << " val=" << xHEX0N(outValue,8) << " msk=" << xHEX0N(inMask,8) << " shf=" << DEC(inShift) << " failed: " << ::GetKernErrStr(GetLastError()));
348  return false;
349 }
350 
351 
352 bool CNTV2WinDriverInterface::WriteRegister (const ULWord inRegNum, const ULWord inValue, const ULWord inMask, const ULWord inShift)
353 {
354  if (inShift >= 32)
355  {
356  WDIFAIL("Shift " << DEC(inShift) << " > 31, reg=" << DEC(inRegNum) << " msk=" << xHEX0N(inMask,8));
357  return false;
358  }
359 #if defined(NTV2_WRITEREG_PROFILING) // Register Write Profiling
360  if (mRecordRegWrites)
361  {
362  AJAAutoLock autoLock(&mRegWritesLock);
363  mRegWrites.push_back(NTV2RegInfo(inRegNum, inValue, inMask, inShift));
364  if (mSkipRegWrites)
365  return true;
366  }
367 #endif // defined(NTV2_WRITEREG_PROFILING) // Register Write Profiling
368 #if defined(NTV2_NUB_CLIENT_SUPPORT)
369  if (IsRemote())
370  return CNTV2DriverInterface::WriteRegister(inRegNum, inValue, inMask, inShift);
371 #endif // defined(NTV2_NUB_CLIENT_SUPPORT)
372  if (!IsOpen())
373  return false;
375  DWORD dwBytesReturned = 0;
376  NTV2_ASSERT(inShift < 32);
377 
378  ZeroMemory(&propStruct,sizeof(KSPROPERTY_AJAPROPS_GETSETREGISTER_S));
379  propStruct.Property.Set = _GUID_PROPSET;
381  propStruct.Property.Flags = KSPROPERTY_TYPE_SET;
382  propStruct.RegisterID = inRegNum;
383  propStruct.ulRegisterValue = inValue;
384  propStruct.ulRegisterMask = inMask;
385  propStruct.ulRegisterShift = inShift;
387  const bool ok = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_GETSETREGISTER, &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETREGISTER_S),
388  &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETREGISTER_S), &dwBytesReturned, NULL);
390  if (!ok)
391  {
392  WDIFAIL("reg=" << DEC(inRegNum) << " val=" << xHEX0N(inValue,8) << " msk=" << xHEX0N(inMask,8) << " shf=" << DEC(inShift) << " failed: " << ::GetKernErrStr(GetLastError()));
393  return false;
394  }
395  return true;
396 }
397 
399 // Interrupt enabling / disabling method
401 
402 // Method: ConfigureInterrupt
403 // Input: bool bEnable (turn on/off interrupt), INTERRUPT_ENUMS eInterruptType
404 // Output: bool status
405 // Purpose: Provides a 1 point connection to driver for interrupt calls
406 bool CNTV2WinDriverInterface::ConfigureInterrupt (const bool bEnable, const INTERRUPT_ENUMS eInterruptType)
407 {
408  if (IsRemote())
409  return false;
410  if (!IsOpen())
411  return false;
412  KSPROPERTY_AJAPROPS_INTERRUPTS_S propStruct; // boilerplate AVStream Property structure
413  DWORD dwBytesReturned = 0;
414  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_INTERRUPTS_S));
415  propStruct.Property.Set = _GUID_PROPSET;
417  propStruct.Property.Flags = bEnable ? KSPROPERTY_TYPE_GET : KSPROPERTY_TYPE_SET;
418  propStruct.eInterrupt = eInterruptType;
419 
420  if (!DeviceIoControl (_hDevice, IOCTL_AJAPROPS_INTERRUPTS, &propStruct, sizeof(KSPROPERTY_AJAPROPS_INTERRUPTS_S),
421  &propStruct, sizeof(KSPROPERTY_AJAPROPS_INTERRUPTS_S), &dwBytesReturned, NULL))
422  {
423  WDIFAIL("interruptType=" << DEC(eInterruptType) << " enable=" << (bEnable?"Y":"N") << " failed: " << ::GetKernErrStr(GetLastError()));
424  return false;
425  }
426  return true;
427 }
428 
429 // Method: ConfigureSubscriptions
430 // Input: bool bSubscribe (true if subscribing), INTERRUPT_ENUMS eInterruptType,
431 // HANDLE & hSubcription
432 // Output: HANDLE & hSubcription (if subscribing)
433 // Notes: collects all driver calls for subscriptions in one place
434 bool CNTV2WinDriverInterface::WinConfigureSubscription (const bool bSubscribe, const INTERRUPT_ENUMS eInterruptType)
435 {
436  NTV2_ASSERT(IsOpen() && "Device not open");
437  NTV2_ASSERT(!IsRemote() && "Not local/physical device");
438  NTV2_ASSERT(NTV2_IS_VALID_INTERRUPT_ENUM(eInterruptType) && "Invalid interruptType");
439 
440  HANDLE hSubscription = HANDLE(mInterruptEventHandles.at(eInterruptType));
441 
442  // Check for previouse call to subscribe
443  if (bSubscribe && hSubscription)
444  return true; // Already subscribed
445 
446  // Check for valid handle to unsubscribe
447  if (!bSubscribe && !hSubscription)
448  return true; // Already unsubscribed
449 
450  // Assure that the avCard has been properly opened
451  if (bSubscribe)
452  hSubscription = CreateEvent (NULL, FALSE, FALSE, NULL);
454  DWORD dwBytesReturned = 0;
455  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_NEWSUBSCRIPTIONS_S));
456  propStruct.Property.Set = _GUID_PROPSET;
458  propStruct.Property.Flags = bSubscribe ? KSPROPERTY_TYPE_GET : KSPROPERTY_TYPE_SET;
459  propStruct.Handle = hSubscription;
460  propStruct.eInterrupt = eInterruptType;
461 
462  BOOL bRet = DeviceIoControl (_hDevice, IOCTL_AJAPROPS_NEWSUBSCRIPTIONS, &propStruct, sizeof(KSPROPERTY_AJAPROPS_NEWSUBSCRIPTIONS_S),
463  &propStruct, sizeof(KSPROPERTY_AJAPROPS_NEWSUBSCRIPTIONS_S), &dwBytesReturned, NULL);
464  if ((!bSubscribe && bRet) || (bSubscribe && !bRet))
465  {
466  CloseHandle(hSubscription);
467  WDINOTE("Closed event handle " << xHEX0N(hSubscription,16) << " for '" << NTV2CfgInterrupt::IntName(eInterruptType) << "'");
468  mInterruptEventHandles.at(eInterruptType) = PULWord(0);
469  }
470 
471  if (!bRet)
472  {
473  WDIFAIL("'IOCTL_AJAPROPS_NEWSUBSCRIPTIONS|" << (bSubscribe ? "KSPROPERTY_TYPE_GET" : "KSPROPERTY_TYPE_SET") << "' failed for '" << NTV2CfgInterrupt::IntName(eInterruptType) << "' subscribe=" << (bSubscribe?"Y":"N") << " failed");
474  return false;
475  }
476  if (bSubscribe)
477  {
478  mEventCounts.at(eInterruptType) = 0; // clear this interrupt's event counter
479  mInterruptEventHandles.at(eInterruptType) = PULWord(hSubscription); // Store handle in this interrupt's "slot"
480  }
481  return true;
482 }
483 
485 {
486  if (!NTV2_IS_VALID_INTERRUPT_ENUM(eInterruptType))
487  return HANDLE(0);
488  return HANDLE(mInterruptEventHandles.at(eInterruptType));
489 }
490 
491 // Method: getInterruptCount
492 // Input: NONE
493 // Output: ULONG or equivalent(i.e. ULWord).
495 {
496  if (!IsOpen())
497  {WDIFAIL("Failed for '" << NTV2CfgInterrupt::IntName(eInterruptType) << "': device not open"); return false;}
498  if (!NTV2_IS_VALID_INTERRUPT_ENUM(eInterruptType))
499  {WDIFAIL("Failed for '" << NTV2CfgInterrupt::IntName(eInterruptType) << "': bad interrupt ID"); return false;}
500 #if defined(NTV2_NUB_CLIENT_SUPPORT)
501  if (IsRemote())
502  return CNTV2DriverInterface::GetInterruptCount(eInterruptType, outCount);
503 #endif // defined(NTV2_NUB_CLIENT_SUPPORT)
504 
506  DWORD dwBytesReturned = 0;
507  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_NEWSUBSCRIPTIONS_S));
508  propStruct.Property.Set = _GUID_PROPSET;
510  propStruct.Property.Flags = KSPROPERTY_TYPE_GET;
511  propStruct.eInterrupt = eGetIntCount;
512  propStruct.ulIntCount = ULONG(eInterruptType);
514  const bool ok = DeviceIoControl (_hDevice, IOCTL_AJAPROPS_NEWSUBSCRIPTIONS, &propStruct, sizeof(KSPROPERTY_AJAPROPS_NEWSUBSCRIPTIONS_S),
515  &propStruct, sizeof(KSPROPERTY_AJAPROPS_NEWSUBSCRIPTIONS_S), &dwBytesReturned, NULL);
517  if (!ok)
518  {
519  WDIFAIL("interruptType=" << DEC(eInterruptType) << " failed: " << ::GetKernErrStr(GetLastError()));
520  return false;
521  }
522  outCount = propStruct.ulIntCount;
523  return true;
524 }
525 
526 static const uint32_t sIntEnumToStatKeys[] = { AJA_DebugStat_WaitForInterruptOut1, // eOutput1 // 0
528  AJA_DebugStat_WaitForInterruptIn1, // eInput1 // 2
529  AJA_DebugStat_WaitForInterruptIn2, // eInput2 // 3
531  AJA_DebugStat_WaitForInterruptUartTx1, // eUart1Tx // 14
532  AJA_DebugStat_WaitForInterruptUartRx1, // eUart1Rx // 15
534  AJA_DebugStat_WaitForInterruptIn3, // eInput3 // 24
535  AJA_DebugStat_WaitForInterruptIn4, // eInput4 // 25
536  AJA_DebugStat_WaitForInterruptUartTx2, // eUartTx2 // 26
537  AJA_DebugStat_WaitForInterruptUartRx2, // eUartRx2 // 27
539  AJA_DebugStat_WaitForInterruptIn5, // eInput5 // 29
540  AJA_DebugStat_WaitForInterruptIn6, // eInput6 // 30
541  AJA_DebugStat_WaitForInterruptIn7, // eInput7 // 31
542  AJA_DebugStat_WaitForInterruptIn8, // eInput8 // 32
544 
546 {
547  if (!IsOpen())
548  {WDIWARN("Cannot wait for '" << NTV2CfgInterrupt::IntName(type) << "' -- device not open"); return false;}
549  if (!NTV2_IS_VALID_INTERRUPT_ENUM(type))
550  {WDIWARN("Cannot wait for '" << NTV2CfgInterrupt::IntName(type) << "' -- bad interrupt id"); return false;}
551 #if defined(NTV2_NUB_CLIENT_SUPPORT)
552  if (IsRemote())
553  return CNTV2DriverInterface::WaitForInterrupt(type, timeOutMs);
554 #endif // defined(NTV2_NUB_CLIENT_SUPPORT)
555 
556  HANDLE hEvent (GetInterruptEvent(type));
557  if (NULL == hEvent)
558  {
559  // No interrupt subscribed, so just Sleep for the timeout value
560  Sleep (timeOutMs);
561  WDIWARN("No event handle for '" << NTV2CfgInterrupt::IntName(type) << "' -- instead slept for " << timeOutMs << " msec");
562  return false;
563  }
564 
565  // Interrupt subscribed -- wait on it
567  DWORD status = WaitForSingleObject(hEvent, timeOutMs);
569  if (status == WAIT_OBJECT_0)
570  {
571  BumpEventCount (type);
572  WDIDBG("Subscribed interrupt '" << NTV2CfgInterrupt::IntName(type) << "' triggered, count=" << mEventCounts.at(type));
573  return true; // All good!!
574  }
575  if (status == WAIT_ABANDONED)
576  WDIFAIL("Subscribed interrupt '" << NTV2CfgInterrupt::IntName(type) << "' failed: WAIT_ABANDONED, count=" << mEventCounts.at(type));
577  else if (status == WAIT_TIMEOUT)
578  WDIFAIL("Subscribed interrupt '" << NTV2CfgInterrupt::IntName(type) << "' timed out after " << timeOutMs << " msec, count=" << mEventCounts.at(type));
579  else
580  WDIFAIL("Subscribed interrupt '" << NTV2CfgInterrupt::IntName(type) << "' failed: " << ::GetKernErrStr(GetLastError()));
581  return false;
582 }
583 
585 // OEM Mapping to Userspace Methods
587 
588 #if !defined(NTV2_DEPRECATE_16_0)
589  // Method: MapFrameBuffers
591  {
592  if (IsRemote())
593  return false;
594  if (!IsOpen())
595  return false;
597  DWORD dwBytesReturned = 0;
598  _pFrameBaseAddress = 0;
600  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S));
601  propStruct.Property.Set = _GUID_PROPSET;
602  propStruct.Property.Id = KSPROPERTY_AJAPROPS_MAPMEMORY;
603  propStruct.Property.Flags = KSPROPERTY_TYPE_GET;
605 
606  if (!DeviceIoControl(_hDevice, IOCTL_AJAPROPS_MAPMEMORY, &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S),
607  &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S), &dwBytesReturned, NULL))
608  {
609  WDIFAIL("failed: " << ::GetKernErrStr(GetLastError()));
610  return false;
611  }
612  ULWord boardIDRegister;
613  ReadRegister(kRegBoardID, boardIDRegister); //unfortunately GetBoardID is in ntv2card...ooops.
614  _pFrameBaseAddress = (ULWord *) propStruct.mapMemory.Address;
617  return true;
618  }
619 
620  // Method: UnmapFrameBuffers
622  {
623  if (IsRemote())
624  return false;
625  if (!IsOpen())
626  return false;
627  ULWord boardIDRegister;
628  ReadRegister(kRegBoardID, boardIDRegister); //unfortunately GetBoardID is in ntv2card...ooops.
629  ULWord * pFrameBaseAddress;
630  pFrameBaseAddress = _pFrameBaseAddress;
631  if (!pFrameBaseAddress)
632  return true;
633 
635  DWORD dwBytesReturned = 0;
636  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S));
637  propStruct.Property.Set = _GUID_PROPSET;
638  propStruct.Property.Id = KSPROPERTY_AJAPROPS_MAPMEMORY;
639  propStruct.Property.Flags = KSPROPERTY_TYPE_SET;
641  propStruct.mapMemory.Address = pFrameBaseAddress;
642  BOOL fRet = DeviceIoControl (_hDevice, IOCTL_AJAPROPS_MAPMEMORY, &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S),
643  &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S), &dwBytesReturned, NULL);
644  _pFrameBaseAddress = 0;
647  if (fRet)
648  return true;
649 
650  WDIFAIL("failed: " << ::GetKernErrStr(GetLastError()));
651  return false;
652  }
653 
654  // Method: MapRegisters
656  {
657  if (IsRemote())
658  return false;
659  if (!IsOpen())
660  return false;
662  DWORD dwBytesReturned = 0;
665  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S));
666  propStruct.Property.Set=_GUID_PROPSET;
668  propStruct.Property.Flags = KSPROPERTY_TYPE_GET;
669  propStruct.bMapType = NTV2_MAPMEMORY_REGISTER;
670  if (!DeviceIoControl (_hDevice, IOCTL_AJAPROPS_MAPMEMORY, &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S),
671  &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S), &dwBytesReturned, NULL))
672  {
673  WDIFAIL("failed: " << ::GetKernErrStr(GetLastError()));
674  return false;
675  }
676 
679  return true;
680  }
681 
682  // Method: UnmapRegisters
684  {
685  if (IsRemote())
686  return false;
687  if (!IsOpen())
688  return false;
689  if (_pRegisterBaseAddress == 0)
690  return true;
691 
693  DWORD dwBytesReturned = 0;
694  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S));
695  propStruct.Property.Set = _GUID_PROPSET;
696  propStruct.Property.Id = KSPROPERTY_AJAPROPS_MAPMEMORY;
697  propStruct.Property.Flags = KSPROPERTY_TYPE_SET;
698  propStruct.bMapType = NTV2_MAPMEMORY_REGISTER;
700  BOOL fRet = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_MAPMEMORY, &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S),
701  &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S), &dwBytesReturned, NULL);
704  if (fRet)
705  return true;
706  WDIFAIL("failed: " << ::GetKernErrStr(GetLastError()));
707  return false;
708  }
709 
710  // Method: MapXena2Flash
712  {
713  if (IsRemote())
714  return false;
715  if (!IsOpen())
716  return false;
718  DWORD dwBytesReturned = 0;
721  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S));
722  propStruct.Property.Set = _GUID_PROPSET;
723  propStruct.Property.Id = KSPROPERTY_AJAPROPS_MAPMEMORY;
724  propStruct.Property.Flags = KSPROPERTY_TYPE_GET;
726  if (!DeviceIoControl (_hDevice, IOCTL_AJAPROPS_MAPMEMORY, &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S),
727  &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S), &dwBytesReturned, NULL))
728  {
729  WDIFAIL("failed: " << ::GetKernErrStr(GetLastError()));
730  return false;
731  }
734  return true;
735  }
736 
737  // Method: UnmapXena2Flash
739  {
740  if (IsRemote())
741  return false;
742  if (!IsOpen())
743  return false;
744  if (_pRegisterBaseAddress == 0)
745  return true;
746 
748  DWORD dwBytesReturned = 0;
749  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S));
750  propStruct.Property.Set = _GUID_PROPSET;
751  propStruct.Property.Id = KSPROPERTY_AJAPROPS_MAPMEMORY;
752  propStruct.Property.Flags = KSPROPERTY_TYPE_SET;
755  BOOL fRet = DeviceIoControl (_hDevice, IOCTL_AJAPROPS_MAPMEMORY, &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S),
756  &propStruct, sizeof(KSPROPERTY_AJAPROPS_MAPMEMORY_S), &dwBytesReturned, NULL);
759  if (fRet)
760  return true;
761  WDIFAIL("failed: " << ::GetKernErrStr(GetLastError()));
762  return false;
763  }
764 
765  bool CNTV2WinDriverInterface::MapMemory (PVOID pvUserVa, ULWord ulNumBytes, bool bMap, ULWord* ulUser)
766  {
767  if (IsRemote())
768  return false;
769  if (!IsOpen())
770  return false;
771 
772  KSPROPERTY_AJAPROPS_DMA_S propStruct;
773  DWORD dwBytesReturned = 0;
774  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_DMA_S));
775  propStruct.Property.Set = _GUID_PROPSET;
776  propStruct.Property.Id = KSPROPERTY_AJAPROPS_DMA;
777  propStruct.Property.Flags = bMap ? KSPROPERTY_TYPE_GET : KSPROPERTY_TYPE_SET;
778  propStruct.dmaEngine = NTV2_PIO;
779  propStruct.pvVidUserVa = pvUserVa;
780  propStruct.ulVidNumBytes = ulNumBytes;
781  if (!DeviceIoControl (_hDevice, IOCTL_AJAPROPS_DMA, &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_S),
782  &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_S), &dwBytesReturned, NULL))
783  {
784  WDIFAIL (KR(GetLastError()) << " -- numBytes=" << ulNumBytes << " map=" << (bMap?"Y":"N"));
785  return false;
786  }
787  if (ulUser)
788  *ulUser = propStruct.ulFrameOffset;
789  return true;
790  }
791 
792  // DmaUnlock
793  // Called from avclasses destructor to insure the process isn't terminating
794  // with memory still locked - a guaranteed cause of a blue screen
796  {
797  if (!IsOpen())
798  return false;
799  if (IsRemote())
800  return false;
801  // For every locked entry, try to free it
802  for (size_t ndx(0); ndx < _vecDmaLocked.size(); ndx++)
804 
805  NTV2_ASSERT(_vecDmaLocked.empty() && "_vecDmaLocked should be empty");
806  return true;
807  }
808 
810  // PrepareMemoryForDMA
811  // Passes the address of a user space allocated frame buffer and the buffer's size to the
812  // kernel, where the kernel
813  // creates a MDL and probes & locks the memory. The framebuffer's userspace address is saved
814  // in the kernel, and all subsequent DMA calls to this address will avoid the time penalties
815  // of the MDL creation and the probe & lock.
816  // NOTE: When this method is used to lock new()ed memory, this memory *should*
817  // be unlocked with the CompleteMemoryForDMA() method before calling delete(). The avclasses
818  // destructor does call DmaUnlock() which attempts to unlock all locked pages with calls
819  // to CompleteMemoryForDMA().
820  // NOTE: Any memory that is new()ed *should* be delete()ed before the process goes out of
821  // scope.
823  {
824  if (!IsOpen())
825  return false;
826  if (IsRemote())
827  return false;
828  // Use NTV2_PIO as an overloaded flag to indicate this is not a DMA transfer
829  if (!DmaTransfer (NTV2_PIO, true, 0, pFrameBuffer, 0, ulNumBytes, false))
830  return false;
831  // Succeeded -- add pFrameBuffer to the avclasses' vector of locked memory
832  _vecDmaLocked.push_back(pFrameBuffer);
833  return true;
834  }
835 
837  // CompleteMemoryForDMA: unlock and free resources
838  // The inverse of PrepareMemoryForDMA. It passes the framebuffer address to the kernel, where
839  // the kernel looks up this address and unlocks the memory, unmaps the memory, and deletes the
840  // MDL.
841  // NOTE: this method does not cleanup the call to new() which created the memory. It is the new()
842  // caller's responsibility to call delete() after calling this method to finish the cleanup.
844  {
845  if (!IsOpen())
846  return false;
847  if (IsRemote())
848  return false;
849  // Use NTV2_PIO as an overloaded flag to indicate this is not a DMA transfer
850  if (!DmaTransfer (NTV2_PIO, false, 0, pFrameBuffer, 0, 0))
851  return false;
852  // Succeeded -- remove pFrameBuffer from the avclasses' vector of locked memory
853  // Find the entry in the avclasses vector that holds this framebuffer's address
854  for (DMA_LOCKED_VEC::iterator vecIter(_vecDmaLocked.begin()); vecIter != _vecDmaLocked.end(); ++vecIter)
855  // If we've found one, erase (delete) it
856  if (*vecIter == pFrameBuffer)
857  {
858  _vecDmaLocked.erase(vecIter);
859  break;
860  }
861  return true;
862  }
863 #endif // !defined(NTV2_DEPRECATE_16_0)
864 
865 
867 // DMA
868 
870  const bool inIsRead,
871  const ULWord inFrameNumber,
872  ULWord * pFrameBuffer,
873  const ULWord inOffsetBytes,
874  const ULWord inByteCount,
875  const bool inSynchronous)
876 {
877  if (IsRemote())
878  return CNTV2DriverInterface::DmaTransfer(inDMAEngine, inIsRead, inFrameNumber, pFrameBuffer,
879  inOffsetBytes, inByteCount, inSynchronous);
880  if (!IsOpen())
881  return false;
882 
883  KSPROPERTY_AJAPROPS_DMA_S propStruct;
884  DWORD dwBytesReturned = 0;
885  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_DMA_S));
886  propStruct.Property.Set = _GUID_PROPSET;
887  propStruct.Property.Id = KSPROPERTY_AJAPROPS_DMA;
888  propStruct.Property.Flags = inIsRead ? KSPROPERTY_TYPE_GET : KSPROPERTY_TYPE_SET;
889  propStruct.dmaEngine = inDMAEngine;
890  propStruct.pvVidUserVa = PVOID(pFrameBuffer);
891  propStruct.ulFrameNumber = inFrameNumber;
892  propStruct.ulFrameOffset = inOffsetBytes;
893  propStruct.ulVidNumBytes = inByteCount;
894  propStruct.ulAudNumBytes = 0;
895  propStruct.bSync = inSynchronous;
897  const bool ok = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_DMA, &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_S),
898  &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_S), &dwBytesReturned, NULL);
900  if (!ok)
901  {
902  WDIFAIL ("failed: " << ::GetKernErrStr(GetLastError()) << ": eng=" << inDMAEngine << " frm=" << inFrameNumber
903  << " off=" << HEX8(inOffsetBytes) << " len=" << HEX8(inByteCount) << " " << (inIsRead ? "Rd" : "Wr"));
904  return false;
905  }
906  return true;
907 }
908 
909 
911  const bool inIsRead,
912  const ULWord inFrameNumber,
913  ULWord * pFrameBuffer,
914  const ULWord inOffsetBytes,
915  const ULWord inByteCount,
916  const ULWord inNumSegments,
917  const ULWord inHostPitch,
918  const ULWord inCardPitch,
919  const bool inSynchronous)
920 {
921  if (IsRemote())
922  return CNTV2DriverInterface::DmaTransfer(inDMAEngine, inIsRead, inFrameNumber, pFrameBuffer,
923  inOffsetBytes, inByteCount, inNumSegments, inHostPitch, inCardPitch, inSynchronous);
924  if (!IsOpen())
925  return false;
926 
927  KSPROPERTY_AJAPROPS_DMA_EX_S propStruct;
928  DWORD dwBytesReturned = 0;
929  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_DMA_EX_S));
930  propStruct.Property.Set = _GUID_PROPSET;
931  propStruct.Property.Id = KSPROPERTY_AJAPROPS_DMA_EX;
932  propStruct.Property.Flags = inIsRead ? KSPROPERTY_TYPE_GET : KSPROPERTY_TYPE_SET;
933  propStruct.dmaEngine = inDMAEngine;
934  propStruct.pvVidUserVa = PVOID(pFrameBuffer);
935  propStruct.ulFrameNumber = inFrameNumber;
936  propStruct.ulFrameOffset = inOffsetBytes;
937  propStruct.ulVidNumBytes = inByteCount;
938  propStruct.ulAudNumBytes = 0;
939  propStruct.ulVidNumSegments = inNumSegments;
940  propStruct.ulVidSegmentHostPitch = inHostPitch;
941  propStruct.ulVidSegmentCardPitch = inCardPitch;
942  propStruct.bSync = inSynchronous;
944  const bool ok = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_DMA_EX, &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_EX_S),
945  &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_EX_S), &dwBytesReturned, NULL);
947  if (!ok)
948  {
949  WDIFAIL ("failed: " << ::GetKernErrStr(GetLastError()) << ": eng=" << inDMAEngine << " frm=" << inFrameNumber
950  << " off=" << HEX8(inOffsetBytes) << " len=" << HEX8(inByteCount) << " " << (inIsRead ? "Rd" : "Wr"));
951  return false;
952  }
953  return true;
954 }
955 
957  const NTV2Channel inDMAChannel,
958  const bool inIsTarget,
959  const ULWord inFrameNumber,
960  const ULWord inCardOffsetBytes,
961  const ULWord inByteCount,
962  const ULWord inNumSegments,
963  const ULWord inHostPitch,
964  const ULWord inCardPitch,
965  const PCHANNEL_P2P_STRUCT & inP2PData)
966 {
967  if (IsRemote())
968  return CNTV2DriverInterface::DmaTransfer(inDMAEngine, inDMAChannel, inIsTarget, inFrameNumber, inCardOffsetBytes,
969  inByteCount, inNumSegments, inHostPitch, inCardPitch, inP2PData);
970  if (!IsOpen())
971  return false;
972  if (!inP2PData)
973  {
974  WDIFAIL ("pP2PData == NULL");
975  return false;
976  }
977 
978  DWORD dwBytesReturned(0);
980  ZeroMemory (&propStruct,sizeof(KSPROPERTY_AJAPROPS_DMA_P2P_S));
981 
982  propStruct.Property.Set = _GUID_PROPSET;
983  propStruct.Property.Id = KSPROPERTY_AJAPROPS_DMA_P2P;
984  if (inIsTarget)
985  { // reset p2p struct
986  memset(inP2PData, 0, sizeof(CHANNEL_P2P_STRUCT));
987  inP2PData->p2pSize = sizeof(CHANNEL_P2P_STRUCT);
988  propStruct.Property.Flags = KSPROPERTY_TYPE_GET; // get does target
989  }
990  else
991  { // check for valid p2p struct
992  if (inP2PData->p2pSize != sizeof(CHANNEL_P2P_STRUCT))
993  {
994  WDIFAIL ("p2pSize=" << inP2PData->p2pSize << " != sizeof(CHANNEL_P2P_STRUCT) " << sizeof(CHANNEL_P2P_STRUCT));
995  return false;
996  }
997  propStruct.Property.Flags = KSPROPERTY_TYPE_SET; // set does transfer
998  }
999 
1000  propStruct.dmaEngine = inDMAEngine;
1001  propStruct.dmaChannel = inDMAChannel;
1002  propStruct.ulFrameNumber = inFrameNumber;
1003  propStruct.ulFrameOffset = inCardOffsetBytes;
1004  propStruct.ulVidNumBytes = inByteCount;
1005  propStruct.ulVidNumSegments = inNumSegments;
1006  propStruct.ulVidSegmentHostPitch = inHostPitch;
1007  propStruct.ulVidSegmentCardPitch = inCardPitch;
1008  propStruct.ullVideoBusAddress = inP2PData->videoBusAddress;
1009  propStruct.ullMessageBusAddress = inP2PData->messageBusAddress;
1010  propStruct.ulVideoBusSize = inP2PData->videoBusSize;
1011  propStruct.ulMessageData = inP2PData->messageData;
1013  const bool ok = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_DMA_P2P, &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_P2P_S),
1014  &propStruct, sizeof(KSPROPERTY_AJAPROPS_DMA_P2P_S), &dwBytesReturned, NULL);
1016  if (!ok)
1017  {
1018  WDIFAIL ("Failed: " << ::GetKernErrStr(GetLastError()) << ": eng=" << inDMAEngine << " ch=" << inDMAChannel
1019  << " frm=" << inFrameNumber << " off=" << HEX8(inCardOffsetBytes) << " siz=" << HEX8(inByteCount)
1020  << " #segs=" << inNumSegments << " hostPitch=" << inHostPitch << " cardPitch=" << inCardPitch
1021  << " target=" << (inIsTarget?"Y":"N"));
1022  return false;
1023  }
1024  if (inIsTarget)
1025  {
1026  // check for data returned
1027  if (dwBytesReturned != sizeof(KSPROPERTY_AJAPROPS_DMA_P2P_S))
1028  {
1029  WDIFAIL ("Target failed: " << ::GetKernErrStr(GetLastError()) << " eng=" << inDMAEngine << " ch=" << inDMAChannel
1030  << " frm=" << inFrameNumber << " off=" << HEX8(inCardOffsetBytes) << " vSiz=" << HEX8(inByteCount)
1031  << " segs=" << inNumSegments << " hostPitch=" << inHostPitch << " cardPitch=" << inCardPitch
1032  << " target=" << (inIsTarget?"Y":"N") << " p2pBytesRet=" << HEX8(dwBytesReturned)
1033  << " p2pSize=" << HEX8(sizeof(KSPROPERTY_AJAPROPS_DMA_P2P_S)));
1034  return false;
1035  }
1036 
1037  // fill in p2p data
1038  inP2PData->videoBusAddress = propStruct.ullVideoBusAddress;
1039  inP2PData->messageBusAddress = propStruct.ullMessageBusAddress;
1040  inP2PData->videoBusSize = propStruct.ulVideoBusSize;
1041  inP2PData->messageData = propStruct.ulMessageData;
1042  }
1043  return true;
1044 }
1045 
1046 
1048 // AutoCirculate
1050 {
1051  if (IsRemote())
1052  return CNTV2DriverInterface::AutoCirculate(autoCircData);
1053  bool bRes(true);
1054  DWORD dwBytesReturned(0);
1055 
1056  switch (autoCircData.eCommand)
1057  {
1058  case eInitAutoCirc:
1059  {
1060  if (autoCircData.lVal4 <= 1 && autoCircData.lVal5 == 0 && autoCircData.lVal6 == 0)
1061  {
1063  memset(&autoCircControl, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_S));
1064  autoCircControl.Property.Set = _GUID_PROPSET;
1065  autoCircControl.Property.Id = KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL;
1066  autoCircControl.Property.Flags = KSPROPERTY_TYPE_SET;
1067  autoCircControl.channelSpec = autoCircData.channelSpec;
1068  autoCircControl.eCommand = autoCircData.eCommand;
1069 
1070  autoCircControl.lVal1 = autoCircData.lVal1;
1071  autoCircControl.lVal2 = autoCircData.lVal2;
1072  autoCircControl.lVal3 = autoCircData.lVal3;
1073  autoCircControl.bVal1 = autoCircData.bVal1;
1074  autoCircControl.bVal2 = autoCircData.bVal2;
1075  autoCircControl.bVal3 = autoCircData.bVal3;
1076  autoCircControl.bVal4 = autoCircData.bVal4;
1077  autoCircControl.bVal5 = autoCircData.bVal5;
1078  autoCircControl.bVal6 = autoCircData.bVal6;
1079  autoCircControl.bVal7 = autoCircData.bVal7;
1080  autoCircControl.bVal8 = autoCircData.bVal8;
1082  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_CONTROL, &autoCircControl, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_S),
1083  &autoCircControl, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_S), &dwBytesReturned, NULL);
1085  if (!bRes)
1086  WDIFAIL("ACInit failed: " << ::GetKernErrStr(GetLastError()));
1087  }
1088  else
1089  {
1091  memset(&autoCircControl, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_EX_S));
1092  autoCircControl.Property.Set = _GUID_PROPSET;
1094  autoCircControl.Property.Flags = KSPROPERTY_TYPE_SET;
1095  autoCircControl.channelSpec = autoCircData.channelSpec;
1096  autoCircControl.eCommand = autoCircData.eCommand;
1097 
1098  autoCircControl.lVal1 = autoCircData.lVal1;
1099  autoCircControl.lVal2 = autoCircData.lVal2;
1100  autoCircControl.lVal3 = autoCircData.lVal3;
1101  autoCircControl.lVal4 = autoCircData.lVal4;
1102  autoCircControl.lVal5 = autoCircData.lVal5;
1103  autoCircControl.lVal6 = autoCircData.lVal6;
1104  autoCircControl.bVal1 = autoCircData.bVal1;
1105  autoCircControl.bVal2 = autoCircData.bVal2;
1106  autoCircControl.bVal3 = autoCircData.bVal3;
1107  autoCircControl.bVal4 = autoCircData.bVal4;
1108  autoCircControl.bVal5 = autoCircData.bVal5;
1109  autoCircControl.bVal6 = autoCircData.bVal6;
1110  autoCircControl.bVal7 = autoCircData.bVal7;
1111  autoCircControl.bVal8 = autoCircData.bVal8;
1113  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_CONTROL_EX, &autoCircControl, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_EX_S),
1114  &autoCircControl, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_EX_S), &dwBytesReturned, NULL);
1116  if (!bRes)
1117  WDIFAIL("ACInitEx failed: " << ::GetKernErrStr(GetLastError()));
1118  }
1119  break;
1120  } // eInitAutoCirc
1121 
1122  case eStartAutoCirc:
1123  case eStopAutoCirc:
1124  case eAbortAutoCirc:
1125  case ePauseAutoCirc:
1126  case eFlushAutoCirculate:
1127  case ePrerollAutoCirculate:
1128  case eStartAutoCircAtTime:
1129  {
1131  memset(&autoCircControl, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_S));
1132  autoCircControl.Property.Set = _GUID_PROPSET;
1133  autoCircControl.Property.Id = KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL;
1134  autoCircControl.Property.Flags = KSPROPERTY_TYPE_SET;
1135  autoCircControl.channelSpec = autoCircData.channelSpec;
1136  autoCircControl.eCommand = autoCircData.eCommand;
1137 
1138  switch (autoCircData.eCommand)
1139  {
1140  case ePauseAutoCirc:
1141  autoCircControl.bVal1 = autoCircData.bVal1;
1142  break;
1143 
1144  case ePrerollAutoCirculate:
1145  autoCircControl.lVal1 = autoCircData.lVal1;
1146  break;
1147 
1148  case eStartAutoCircAtTime:
1149  autoCircControl.lVal1 = autoCircData.lVal1;
1150  autoCircControl.lVal2 = autoCircData.lVal2;
1151  break;
1152 
1153  default: break; //NTV2_ASSERT(false && "Bad eCommand");
1154  }
1156  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_CONTROL, &autoCircControl, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_S),
1157  &autoCircControl, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_CONTROL_S), &dwBytesReturned, NULL);
1159  if (!bRes)
1160  WDIFAIL("ACInitEx failed: " << ::GetKernErrStr(GetLastError()));
1161  break;
1162  } // eStartAutoCirc, eStopAutoCirc, etc.
1163 
1164  case eGetAutoCirc:
1165  {
1167  memset(&autoCircStatus, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_STATUS_S));
1168  autoCircStatus.Property.Set = _GUID_PROPSET;
1169  autoCircStatus.Property.Id = KSPROPERTY_AJAPROPS_AUTOCIRC_STATUS;
1170  autoCircStatus.Property.Flags = KSPROPERTY_TYPE_GET;
1171  autoCircStatus.channelSpec = autoCircData.channelSpec;
1172  autoCircStatus.eCommand = autoCircData.eCommand;
1173  if (autoCircData.pvVal1)
1174  {
1176  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_STATUS, &autoCircStatus, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_STATUS_S),
1177  &autoCircStatus, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_STATUS_S), &dwBytesReturned, NULL);
1179  if (bRes)
1180  *(AUTOCIRCULATE_STATUS_STRUCT *)autoCircData.pvVal1 = autoCircStatus.autoCircStatus;
1181  else
1182  WDIFAIL("GetAC failed: " << ::GetKernErrStr(GetLastError()));
1183  }
1184  else
1185  {bRes = false; WDIFAIL("GetAC failed: NULL pvVal1");}
1186  break;
1187  } // eGetAutoCirc
1188 
1189  case eGetFrameStamp:
1190  {
1192  memset(&autoCircFrame, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_S));
1193  autoCircFrame.Property.Set = _GUID_PROPSET;
1194  autoCircFrame.Property.Id = KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME;
1195  autoCircFrame.Property.Flags = KSPROPERTY_TYPE_GET;
1196  autoCircFrame.channelSpec = autoCircData.channelSpec;
1197  autoCircFrame.eCommand = autoCircData.eCommand;
1198  autoCircFrame.lFrameNum = autoCircData.lVal1;
1199 
1200  if (autoCircData.pvVal1)
1201  {
1202  autoCircFrame.frameStamp = *(FRAME_STAMP_STRUCT *) autoCircData.pvVal1;
1204  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_FRAME, &autoCircFrame, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_S),
1205  &autoCircFrame, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_S), &dwBytesReturned, NULL);
1207  if (bRes)
1208  *(FRAME_STAMP_STRUCT *)autoCircData.pvVal1 = autoCircFrame.frameStamp;
1209  else
1210  WDIFAIL("GetFrameStamp failed: " << ::GetKernErrStr(GetLastError()));
1211  }
1212  else
1213  {bRes = false; WDIFAIL("GetFrameStamp failed: NULL pvVal1");}
1214  break;
1215  } // eGetFrameStamp
1216 
1217  case eGetFrameStampEx2:
1218  {
1220  memset(&autoCircFrame, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_EX2_S));
1221  autoCircFrame.Property.Set = _GUID_PROPSET;
1223  autoCircFrame.Property.Flags = KSPROPERTY_TYPE_GET;
1224  autoCircFrame.channelSpec = autoCircData.channelSpec;
1225  autoCircFrame.eCommand = autoCircData.eCommand;
1226  autoCircFrame.lFrameNum = autoCircData.lVal1;
1227 
1228  if (autoCircData.pvVal1)
1229  {
1230  autoCircFrame.frameStamp = *(FRAME_STAMP_STRUCT *) autoCircData.pvVal1;
1231  if (autoCircData.pvVal2)
1232  autoCircFrame.acTask = *(AUTOCIRCULATE_TASK_STRUCT *) autoCircData.pvVal2;
1233 
1235  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_FRAME_EX2, &autoCircFrame, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_EX2_S),
1236  &autoCircFrame, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_EX2_S), &dwBytesReturned, NULL);
1238  if (bRes)
1239  {
1240  *(FRAME_STAMP_STRUCT *)autoCircData.pvVal1 = autoCircFrame.frameStamp;
1241  if (autoCircData.pvVal2)
1242  *(AUTOCIRCULATE_TASK_STRUCT *) autoCircData.pvVal2 = autoCircFrame.acTask;
1243  }
1244  else
1245  WDIFAIL("GetFrameStampEx2 failed: " << ::GetKernErrStr(GetLastError()));
1246  }
1247  else
1248  {bRes = false; WDIFAIL("GetFrameStampEx2 failed: NULL pvVal1");}
1249  break;
1250  }
1251 
1253  {
1255  memset(&acXfer, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_TRANSFER_S));
1256  acXfer.Property.Set = _GUID_PROPSET;
1258  acXfer.Property.Flags = KSPROPERTY_TYPE_GET;
1259  acXfer.eCommand = autoCircData.eCommand;
1260 
1261  if (!autoCircData.pvVal1 || !autoCircData.pvVal2)
1262  {bRes = false; WDIFAIL("ACXfer failed: pvVal1 or pvVal2 NULL"); break;}
1263  acXfer.acTransfer = *(PAUTOCIRCULATE_TRANSFER_STRUCT) autoCircData.pvVal1; // Reqd XferStruct
1264  AUTOCIRCULATE_TRANSFER_STATUS_STRUCT acStatus = *(PAUTOCIRCULATE_TRANSFER_STATUS_STRUCT) autoCircData.pvVal2; // Reqd XferStatusStruct
1265 
1266  // Ensure audio buffer alignment OK
1267  if (acXfer.acTransfer.audioBufferSize && (acXfer.acTransfer.audioBufferSize % 4))
1268  {bRes = false; WDIFAIL("ACXfer failed: audio buffer size " << DEC(acXfer.acTransfer.audioBufferSize) << " not mod 4"); break;}
1269  if (acXfer.acTransfer.audioBuffer && (ULWord64(acXfer.acTransfer.audioBuffer) % 4))
1270  {bRes = false; WDIFAIL("ACXfer failed: audio buffer addr " << xHEX0N(acXfer.acTransfer.audioBuffer,16) << " not DWORD-aligned"); break;}
1271 
1273  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_TRANSFER, &acXfer, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_TRANSFER_S),
1274  &acStatus, sizeof (AUTOCIRCULATE_TRANSFER_STATUS_STRUCT), &dwBytesReturned, NULL);
1276  if (bRes)
1277  *(PAUTOCIRCULATE_TRANSFER_STATUS_STRUCT)autoCircData.pvVal2 = acStatus;
1278  else
1279  WDIFAIL("ACXfer failed: " << ::GetKernErrStr(GetLastError()));
1280  break;
1281  } // eTransferAutoCirculate
1282 
1284  {
1286  memset(&acXfer, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_TRANSFER_EX_S));
1287  acXfer.Property.Set = _GUID_PROPSET;
1289  acXfer.Property.Flags = KSPROPERTY_TYPE_GET;
1290  acXfer.eCommand = autoCircData.eCommand;
1291 
1292  if (!autoCircData.pvVal1 || !autoCircData.pvVal2)
1293  {bRes = false; WDIFAIL("ACXferEx failed: NULL XferStruct or XferStatusStruct"); break;}
1294  acXfer.acTransfer = *(PAUTOCIRCULATE_TRANSFER_STRUCT) autoCircData.pvVal1; // Reqd XferStruct
1295  AUTOCIRCULATE_TRANSFER_STATUS_STRUCT acStatus = *(PAUTOCIRCULATE_TRANSFER_STATUS_STRUCT) autoCircData.pvVal2; // Reqd XferStatusStruct
1296  if (autoCircData.pvVal3)
1297  acXfer.acTransferRoute = *(NTV2RoutingTable*) autoCircData.pvVal3; // Optional RoutingTable
1298 
1299  // Ensure audio buffer alignment OK
1300  if (acXfer.acTransfer.audioBufferSize && (acXfer.acTransfer.audioBufferSize % 4))
1301  {bRes = false; WDIFAIL("ACXferEx failed: audio buffer size " << DEC(acXfer.acTransfer.audioBufferSize) << " not mod 4"); break;}
1302  if (acXfer.acTransfer.audioBuffer && (ULWord64(acXfer.acTransfer.audioBuffer) % 4))
1303  {bRes = false; WDIFAIL("ACXferEx failed: audio buffer addr " << xHEX0N(acXfer.acTransfer.audioBuffer,16) << " not DWORD-aligned"); break;}
1304 
1307  &acStatus, sizeof (AUTOCIRCULATE_TRANSFER_STATUS_STRUCT), &dwBytesReturned, NULL);
1309  if (bRes)
1310  *(PAUTOCIRCULATE_TRANSFER_STATUS_STRUCT)autoCircData.pvVal2 = acStatus;
1311  else
1312  WDIFAIL("ACXferEx failed: " << ::GetKernErrStr(GetLastError()));
1313  break;
1314  } // eTransferAutoCirculateEx
1315 
1317  {
1319  memset(&acXfer, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_TRANSFER_EX2_S));
1320  acXfer.Property.Set = _GUID_PROPSET;
1322  acXfer.Property.Flags = KSPROPERTY_TYPE_GET;
1323  acXfer.eCommand = autoCircData.eCommand;
1324 
1325  if (!autoCircData.pvVal1 || !autoCircData.pvVal2)
1326  {bRes = false; WDIFAIL("ACXferEx2 failed: NULL XferStruct or RoutingTable"); break;}
1327 
1328  acXfer.acTransfer = *(PAUTOCIRCULATE_TRANSFER_STRUCT) autoCircData.pvVal1; // Reqd XferStruct
1329  AUTOCIRCULATE_TRANSFER_STATUS_STRUCT acStatus = *(PAUTOCIRCULATE_TRANSFER_STATUS_STRUCT) autoCircData.pvVal2; // Reqd XferStatusStruct
1330  if (autoCircData.pvVal3)
1331  acXfer.acTransferRoute = *(NTV2RoutingTable*) autoCircData.pvVal3; // Optional RoutingTable
1332  if (autoCircData.pvVal4)
1333  acXfer.acTask = *(PAUTOCIRCULATE_TASK_STRUCT) autoCircData.pvVal4; // Optional TaskStruct
1334 
1335  // Ensure audio buffer alignment OK
1336  if (acXfer.acTransfer.audioBufferSize && (acXfer.acTransfer.audioBufferSize % 4))
1337  {bRes = false; WDIFAIL("ACXferEx2 failed: audio buffer size " << DEC(acXfer.acTransfer.audioBufferSize) << " not mod 4"); break;}
1338  if (acXfer.acTransfer.audioBuffer && (ULWord64(acXfer.acTransfer.audioBuffer) % 4))
1339  {bRes = false; WDIFAIL("ACXferEx2 failed: audio buffer addr " << xHEX0N(acXfer.acTransfer.audioBuffer,16) << " not DWORD-aligned"); break;}
1340 
1343  &acStatus, sizeof (AUTOCIRCULATE_TRANSFER_STATUS_STRUCT), &dwBytesReturned, NULL);
1345  if (bRes)
1346  *(PAUTOCIRCULATE_TRANSFER_STATUS_STRUCT)autoCircData.pvVal2 = acStatus;
1347  else
1348  WDIFAIL("ACXferEx2 failed: " << ::GetKernErrStr(GetLastError()));
1349  break;
1350  } // eTransferAutoCirculateEx2
1351 
1352  case eSetCaptureTask:
1353  {
1355  memset(&autoCircFrame, 0, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_EX2_S));
1356  autoCircFrame.Property.Set = _GUID_PROPSET;
1358  autoCircFrame.Property.Flags = KSPROPERTY_TYPE_SET;
1359  autoCircFrame.channelSpec = autoCircData.channelSpec;
1360  autoCircFrame.eCommand = autoCircData.eCommand;
1361  autoCircFrame.lFrameNum = 0;
1362 
1363  if (!autoCircData.pvVal1)
1364  {bRes = false; WDIFAIL("ACSetCaptureTask failed: NULL TaskStruct"); break;}
1365  autoCircFrame.acTask = *(AUTOCIRCULATE_TASK_STRUCT *) autoCircData.pvVal1; // Reqd TaskStruct
1366 
1368  bRes = DeviceIoControl(_hDevice, IOCTL_AJAPROPS_AUTOCIRC_CAPTURE_TASK, &autoCircFrame, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_EX2_S),
1369  &autoCircFrame, sizeof(KSPROPERTY_AJAPROPS_AUTOCIRC_FRAME_EX2_S), &dwBytesReturned, NULL);
1371  if (!bRes)
1372  WDIFAIL("ACSetCaptureTask failed: " << ::GetKernErrStr(GetLastError()));
1373  break;
1374  } // eSetCaptureTask
1375 
1376  case eSetActiveFrame:
1378  { bRes = false;
1379  WDIFAIL("Bad AC command %d" << autoCircData.eCommand);
1380  break;
1381  }
1382  } // switch on autoCircData.eCommand
1383  return bRes;
1384 } // AutoCirculate
1385 
1386 
1388 {
1389  if (!pInMessage)
1390  {WDIFAIL("Failed: NULL pointer"); return false;}
1391  if (IsRemote())
1392  return CNTV2DriverInterface::NTV2Message(pInMessage); // Implement NTV2Message on nub
1393  DWORD dwBytesReturned(0);
1395  const bool ok = DeviceIoControl(_hDevice, IOCTL_AJANTV2_MESSAGE, pInMessage, pInMessage->GetSizeInBytes (), pInMessage, pInMessage->GetSizeInBytes(), &dwBytesReturned, NULL);
1397  if (!ok)
1398  {WDIFAIL("Failed: " << ::GetKernErrStr(GetLastError()) << ": " << *pInMessage); return false;}
1399  return true;
1400 }
1401 
1402 
1404 {
1406 }
1407 
1409 {
1411 }
1412 
1413 
1414 //
1415 // Management of downloaded Xilinx bitfile
1416 //
1417 //
1419 {
1420  if (IsRemote())
1421  return CNTV2DriverInterface::DriverGetBitFileInformation (outBitfileInfo, bitFileType);
1422  if (::NTV2DeviceHasSPIFlash(_boardID)) // No need to query the driver for boards with SPIFlash
1423  return CNTV2DriverInterface::DriverGetBitFileInformation (outBitfileInfo, bitFileType);
1424 
1425  // Ask the driver...
1426  DWORD dwBytesReturned(0);
1428  ZeroMemory(&propStruct,sizeof(KSPROPERTY_AJAPROPS_GETSETBITFILEINFO_S));
1429  propStruct.Property.Set = _GUID_PROPSET;
1431  propStruct.Property.Flags = KSPROPERTY_TYPE_GET;
1432  if (!DeviceIoControl(_hDevice, IOCTL_AJAPROPS_GETSETBITFILEINFO, &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETBITFILEINFO_S),
1433  &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETBITFILEINFO_S), &dwBytesReturned, NULL))
1434  {
1435  WDIFAIL("Failed");
1436  return false;
1437  }
1438  outBitfileInfo = propStruct.bitFileInfoStruct;
1439  return true;
1440 }
1441 
1443 {
1444  DWORD dwBytesReturned(0);
1446  ZeroMemory(&propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETBITFILEINFO_S));
1447  propStruct.Property.Set = _GUID_PROPSET;
1449  propStruct.Property.Flags = KSPROPERTY_TYPE_SET;
1450  propStruct.bitFileInfoStruct = inBitfileInfo;
1451  if (DeviceIoControl(_hDevice, IOCTL_AJAPROPS_GETSETBITFILEINFO, &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETBITFILEINFO_S),
1452  &propStruct, sizeof(KSPROPERTY_AJAPROPS_GETSETBITFILEINFO_S), &dwBytesReturned, NULL))
1453  return true;
1454 
1455  WDIFAIL("Failed");
1456  return false;
1457 }
1458 
1459 
1460 #include <ntv2devicefeatures.h>
1461 
1463 {
1464  if (IsRemote())
1465  return false;
1467 }
Everything needed to call CNTV2Card::ReadRegister or CNTV2Card::WriteRegister functions.
Defines & structs shared between user-space and Windows kernel driver.
virtual bool RestoreHardwareProcampRegisters(void)
#define IOCTL_AJAPROPS_AUTOCIRC_FRAME
#define IOCTL_AJAPROPS_AUTOCIRC_CONTROL_EX
#define IOCTL_AJAPROPS_DMA_P2P
virtual bool UnmapFrameBuffers(void)
uint32_t * PULWord
Definition: ajatypes.h:237
#define IOCTL_AJAPROPS_AUTOCIRC_FRAME_EX2
Declares the AJADebug class.
#define WDIWARN(__x__)
virtual UWord GetIndexNumber(void) const
void setDeviceIndexNumber(const UWord num)
#define NTV2_IS_VALID_INTERRUPT_ENUM(__e__)
#define IOCTL_AJAPROPS_MAPMEMORY
bool NTV2DeviceHasSPIFlash(const NTV2DeviceID inDeviceID)
virtual HANDLE GetEventHandleForInterrupt(const INTERRUPT_ENUMS eInterruptType)
defined(NTV2_DEPRECATE_17_6)
virtual bool Close(void)
Closes me, releasing host resources that may have been allocated in a previous Open call...
virtual bool AutoCirculate(AUTOCIRCULATE_DATA &autoCircData)
Sends an AutoCirculate command to the NTV2 driver.
#define IOCTL_AJAPROPS_NEWSUBSCRIPTIONS
if(!(riid==IID_IUnknown) &&!(riid==IID_IClassFactory))
Definition: dllentry.cpp:196
ULONG(__stdcall *_RegisterTraceGuids)(__in IN WMIDPREQUEST RequestAddress
static bool GetShareMode(void)
#define IOCTL_AJAPROPS_AUTOCIRC_TRANSFER_EX2
virtual ~CNTV2WinDriverInterface()
My default destructor.
struct AUTOCIRCULATE_TASK_STRUCT * PAUTOCIRCULATE_TASK_STRUCT
virtual bool WaitForInterrupt(const INTERRUPT_ENUMS eInterruptType, const ULWord timeOutMs=50)
Efficiently waits for the next given interrupt to be signaled on the device.
Definition: json.hpp:5362
#define AJAVIDEO_NTV2_PROPSET
virtual bool PrepareMemoryForDMA(ULWord *pFrameBuffer, const ULWord ulNumBytes)
uint32_t ULWord
Definition: ajatypes.h:236
virtual bool DmaTransfer(const NTV2DMAEngine inDMAEngine, const bool inIsRead, const ULWord inFrameNumber, ULWord *pFrameBuffer, const ULWord inCardOffsetBytes, const ULWord inTotalByteCount, const bool inSynchronous=(!(0)))
Transfers data between the AJA device and the host. This function will block and not return to the ca...
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1361
short HANDLE
Definition: ajatypes.h:298
PSP_DEVICE_INTERFACE_DETAIL_DATA _pspDevIFaceDetailData
#define NTV2_ASSERT(_expr_)
Definition: ajatypes.h:489
virtual bool ReadRegister(const ULWord inRegNum, ULWord &outValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0)
Physical device implementation of CNTV2DriverInterface::ReadRegister.
void * PVOID
Definition: ajatypes.h:299
static AJAStatus StatTimerStop(const uint32_t inKey)
Definition: debug.cpp:1161
virtual bool DmaTransfer(const NTV2DMAEngine inDMAEngine, const bool inIsRead, const ULWord inFrameNumber, ULWord *pFrameBuffer, const ULWord inCardOffsetBytes, const ULWord inByteCount, const bool inSynchronous=(!(0)))
Transfers data between the AJA device and the host. This function will block and not return to the ca...
#define WDIDBG(__x__)
#define IOCTL_AJAPROPS_GETSETBITFILEINFO
virtual bool IsRemote(void) const
struct AUTOCIRCULATE_TRANSFER_STATUS_STRUCT * PAUTOCIRCULATE_TRANSFER_STATUS_STRUCT
#define IOCTL_AJAPROPS_AUTOCIRC_TRANSFER_EX
ULWord GetSizeInBytes(void) const
My total size, in bytes, including header, body and trailer (but excluding embedded NTV2Buffer data) ...
NTV2DeviceID _boardID
My cached device ID.
virtual bool MapMemory(PVOID pvUserVa, ULWord ulNumBytes, bool bMap, ULWord *ulUser=NULL)
virtual bool DriverSetBitFileInformation(const BITFILE_INFO_STRUCT &inBitfileInfo)
virtual bool IsOpen(void) const
bool _boardOpened
True if I&#39;m open and connected to the device.
AUTOCIRCULATE_STATUS_STRUCT autoCircStatus
virtual void BumpEventCount(const INTERRUPT_ENUMS eInterruptType)
Atomically increments the event count tally for the given interrupt type.
NTV2DMAEngine
Definition: ntv2enums.h:1861
#define AJA_NULL
Definition: ajatypes.h:180
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...
virtual bool WriteRegister(const ULWord inRegNum, const ULWord inValue, const ULWord inMask=0xFFFFFFFF, const ULWord inShift=0)
Physical device implementation of CNTV2DriverInterface::WriteRegister.
virtual bool DriverGetBitFileInformation(BITFILE_INFO_STRUCT &outBitfileInfo, const NTV2BitFileType inBitfileType=NTV2_VideoProcBitFile)
defined(NTV2_DEPRECATE_17_2)
enum _INTERRUPT_ENUMS_ INTERRUPT_ENUMS
bool mRecordRegWrites
True if recording; otherwise false when not recording.
All new NTV2 structs start with this common header.
virtual bool NTV2Message(NTV2_HEADER *pInMessage)
Sends a message to the NTV2 driver (the new, improved, preferred way).
AJALock mRegWritesLock
Guard mutex for mRegWrites.
#define KR(_kr_)
NTV2_GlobalAudioPlaybackMode
Definition: ntv2enums.h:2111
Declares data types and structures used in NTV2 "nub" packets.
uint64_t ULWord64
Definition: ajatypes.h:239
#define WDINOTE(__x__)
NTV2Crosspoint channelSpec
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...
NTV2BitFileType
Definition: ntv2enums.h:3354
static const uint32_t sIntEnumToStatKeys[]
virtual bool NTV2Message(NTV2_HEADER *pInMessage)
Sends a message to the NTV2 driver (the new, improved, preferred way).
#define IOCTL_AJAPROPS_AUTOCIRC_STATUS
#define IOCTL_AJAPROPS_INTERRUPTS
virtual bool DriverGetBitFileInformation(BITFILE_INFO_STRUCT &outBitFileInfo, const NTV2BitFileType inBitFileType=NTV2_VideoProcBitFile)
defined(NTV2_DEPRECATE_17_2)
static AJAStatus StatTimerStart(const uint32_t inKey)
Definition: debug.cpp:1141
Declares the MSWindows-specific flavor of CNTV2DriverInterface.
struct AUTOCIRCULATE_P2P_STRUCT CHANNEL_P2P_STRUCT
#define IOCTL_AJAPROPS_DMA
Added to support 64 bit driver.
#define DEC(__x__)
#define IOCTL_AJAPROPS_GETSETREGISTER
#define IOCTL_AJANTV2_MESSAGE
virtual bool ConfigureInterrupt(const bool bEnable, const INTERRUPT_ENUMS eInterruptType)
#define IOCTL_AJAPROPS_DMA_EX
#define WDIINFO(__x__)
virtual bool GetInterruptCount(const INTERRUPT_ENUMS eInterrupt, ULWord &outCount)
Answers with the current total number of interrupts of the given type processed by the driver&#39;s inter...
AUTO_CIRC_COMMAND eCommand
uint16_t UWord
Definition: ajatypes.h:234
_EventCounts mEventCounts
My event tallies, one for each interrupt type. Note that these.
virtual bool SetAudioOutputMode(NTV2_GlobalAudioPlaybackMode mode)
#define IOCTL_AJAPROPS_AUTOCIRC_TRANSFER
#define xHEX0N(__x__, __n__)
virtual bool WaitForInterrupt(const INTERRUPT_ENUMS eInterrupt, const ULWord timeOutMs=68)
Efficiently waits for the next given interrupt to be signaled on the device.
#define INVALID_HANDLE_VALUE
Definition: ajatypes.h:312
virtual bool GetAudioOutputMode(NTV2_GlobalAudioPlaybackMode *mode)
#define IOCTL_AJAPROPS_AUTOCIRC_CAPTURE_TASK
CNTV2WinDriverInterface()
My default constructor.
struct AUTOCIRCULATE_TRANSFER_STRUCT * PAUTOCIRCULATE_TRANSFER_STRUCT
#define HEX8(__x__)
static std::string IntName(const INTERRUPT_ENUMS id)
NTV2RegisterWrites mRegWrites
Stores WriteRegister data.
static std::string GetKernErrStr(const DWORD inError)
virtual bool CompleteMemoryForDMA(ULWord *pFrameBuffer)
virtual bool OpenLocalPhysical(const UWord inDeviceIndex)
Opens the local/physical device connection.
bool mSkipRegWrites
True if actual register writes are skipped while recording.
Declares enums and structs used by all platform drivers and the SDK.
virtual bool AutoCirculate(AUTOCIRCULATE_DATA &pAutoCircData)
Sends an AutoCirculate command to the NTV2 driver.
#define IOCTL_AJAPROPS_AUTOCIRC_CONTROL
Declares device capability functions.
virtual bool GetInterruptCount(const INTERRUPT_ENUMS eInterrupt, ULWord &outCount)
Answers with the current total number of interrupts of the given type processed by the driver&#39;s inter...
virtual bool WinConfigureSubscription(const bool bSubscribe, const INTERRUPT_ENUMS eInterruptType)
#define WDIFAIL(__x__)
#define NULL
Definition: ntv2vpid.cpp:18
virtual bool CloseLocalPhysical(void)
Releases host resources associated with the local/physical device connection.
#define GetInterruptEvent(__x__)