AJA NTV2 SDK  18.0.0.2717
NTV2 SDK 18.0.0.2717
ntv2vcam.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
7 #include "ntv2vcam.h"
8 
9 static const ULWord gDemoAppSignature NTV2_FOURCC('V', 'C', 'A', 'M');
10 static const uint32_t gAudMaxSizeBytes(256 * 1024); // Max audio bytes for single frame (14.98fps 16ch 48kHz)
11 
12 #if !defined(AJA_WINDOWS)
13  static bool gGlobalQuit(false);
14  static void SignalHandler(int inSignal)
15  {
16  (void)inSignal;
17  gGlobalQuit = true;
18  }
19 #else // begin AJA_WINDOWS section
20  OutputVideoPin::OutputVideoPin(HRESULT* phr, CSource* pFilter, LPCWSTR pPinName)
21  : CSourceStream(VCAM_VIDEO_PIN_NAME, phr, pFilter, pPinName)
22  {
23  }
24 
25  OutputVideoPin::~OutputVideoPin()
26  {
27  }
28 
29  STDMETHODIMP OutputVideoPin::QueryInterface(REFIID riid, void** ppv)
30  {
31  if (!ppv)
32  return E_POINTER;
33 
34  *ppv = nullptr;
35 
36  if (riid == IID_IKsPropertySet)
37  *ppv = static_cast<IKsPropertySet*>(this);
38  else if (riid == IID_IAMStreamConfig)
39  *ppv = static_cast<IAMStreamConfig*>(this);
40  else
41  return CSourceStream::QueryInterface(riid, ppv);
42 
43  AddRef();
44  return S_OK;
45  }
46 
47  STDMETHODIMP_(ULONG) OutputVideoPin::AddRef()
48  {
49  return CSourceStream::AddRef();
50  }
51 
52  STDMETHODIMP_(ULONG) OutputVideoPin::Release()
53  {
54  return CSourceStream::Release();
55  }
56 
57  STDMETHODIMP OutputVideoPin::CheckMediaType(const CMediaType* pmt)
58  {
59  if (!pmt)
60  return E_POINTER;
61 
62  if (*pmt->Type() != MEDIATYPE_Video)
63  return E_INVALIDARG;
64 
65  if (*pmt->FormatType() != FORMAT_VideoInfo)
66  return E_INVALIDARG;
67 
68  if (*pmt->Subtype() != MEDIASUBTYPE_UYVY)
69  return E_INVALIDARG;
70 
71  return S_OK;
72  }
73 
74  HRESULT OutputVideoPin::GetMediaType(CMediaType* pMediaType)
75  {
76  if (VCAM()->Initialize())
77  return CopyMediaType(pMediaType, &m_mt);
78 
79  return E_FAIL;
80  }
81 
82  HRESULT OutputVideoPin::FillBuffer(IMediaSample* pSample)
83  {
84  return VCAM()->GetNextFrame(this, pSample);
85  }
86 
87  HRESULT OutputVideoPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pRequest)
88  {
89  CAutoLock cAutoLock(m_pFilter->pStateLock());
90 
91  if (!pAlloc)
92  return E_POINTER;
93 
94  VIDEOINFO* pvi = reinterpret_cast<VIDEOINFO*>(m_mt.Format());
95  if (!pvi)
96  return E_UNEXPECTED;
97 
98  pRequest->cBuffers = 1;
99  pRequest->cbBuffer = pvi->bmiHeader.biSizeImage;
100 
101  ALLOCATOR_PROPERTIES Actual;
102  HRESULT hr = pAlloc->SetProperties(pRequest, &Actual);
103  if (FAILED(hr))
104  return hr;
105 
106  if (Actual.cbBuffer < pRequest->cbBuffer)
107  return E_FAIL;
108 
109  if (Actual.cBuffers != 1)
110  return E_FAIL;
111 
112  return NOERROR;
113  }
114 
115  STDMETHODIMP OutputVideoPin::EnumMediaTypes(IEnumMediaTypes** ppEnum)
116  {
117  return CSourceStream::EnumMediaTypes(ppEnum);
118  }
119 
120  STDMETHODIMP OutputVideoPin::Notify(IBaseFilter* pSender, Quality q)
121  {
122  return CSourceStream::Notify(pSender, q);
123  }
124 
125  STDMETHODIMP OutputVideoPin::Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData)
126  {
127  return E_NOTIMPL;
128  }
129 
130  STDMETHODIMP OutputVideoPin::Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD* pcbReturned)
131  {
132  if (guidPropSet != AMPROPSETID_Pin)
133  return E_PROP_SET_UNSUPPORTED;
134 
135  if (dwPropID != AMPROPERTY_PIN_CATEGORY)
136  return E_PROP_ID_UNSUPPORTED;
137 
138  if (pPropData == NULL && pcbReturned == NULL)
139  return E_POINTER;
140 
141  if (pcbReturned)
142  *pcbReturned = sizeof(GUID);
143 
144  if (pPropData == NULL)
145  return S_OK;
146 
147  if (cbPropData < sizeof(GUID))
148  return E_UNEXPECTED;
149 
150  *(GUID*)pPropData = PIN_CATEGORY_CAPTURE;
151 
152  return S_OK;
153  }
154 
155  STDMETHODIMP OutputVideoPin::QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD* pTypeSupport)
156  {
157  if (guidPropSet != AMPROPSETID_Pin)
158  return E_PROP_SET_UNSUPPORTED;
159 
160  if (dwPropID != AMPROPERTY_PIN_CATEGORY)
161  return E_PROP_ID_UNSUPPORTED;
162 
163  if (pTypeSupport)
164  *pTypeSupport = KSPROPERTY_SUPPORT_GET;
165 
166  return S_OK;
167  }
168 
169  STDMETHODIMP OutputVideoPin::SetFormat(AM_MEDIA_TYPE* pmt)
170  {
171  if (!pmt)
172  return E_POINTER;
173 
174  if (pmt->majortype == m_mt.majortype &&
175  pmt->subtype == m_mt.subtype &&
176  pmt->formattype == m_mt.formattype)
177  {
178  m_mt = *pmt;
179  return S_OK;
180  }
181 
182  return VFW_E_INVALIDMEDIATYPE;
183  }
184 
185  STDMETHODIMP OutputVideoPin::GetFormat(AM_MEDIA_TYPE** ppmt)
186  {
187  if (!ppmt)
188  return E_POINTER;
189 
190  *ppmt = CreateMediaType(&m_mt);
191  if (!*ppmt)
192  return E_OUTOFMEMORY;
193 
194  return S_OK;
195  }
196 
197  STDMETHODIMP OutputVideoPin::GetNumberOfCapabilities(int* piCount, int* piSize)
198  {
199  if (!piCount || !piSize)
200  return E_POINTER;
201 
202  *piCount = 1;
203  *piSize = sizeof(VIDEO_STREAM_CONFIG_CAPS);
204 
205  return S_OK;
206  }
207 
208  STDMETHODIMP OutputVideoPin::GetStreamCaps(int iIndex, AM_MEDIA_TYPE** ppmt, BYTE* pSCC)
209  {
210  if (!ppmt || !pSCC)
211  return E_POINTER;
212 
213  if (iIndex < 0 || iIndex >= 1)
214  return S_FALSE;
215 
216  CMediaType mediaType;
217  if (FAILED(GetMediaType(&mediaType)))
218  return E_FAIL;
219  *ppmt = CreateMediaType(&mediaType);
220  if (!*ppmt)
221  return E_OUTOFMEMORY;
222 
223  VIDEOINFO* vih = reinterpret_cast<decltype(vih)>((*ppmt)->pbFormat);
224  VIDEO_STREAM_CONFIG_CAPS* caps = reinterpret_cast<VIDEO_STREAM_CONFIG_CAPS*>(pSCC);
225  ZeroMemory(caps, sizeof(VIDEO_STREAM_CONFIG_CAPS));
226  caps->guid = FORMAT_VideoInfo;
227  caps->MinFrameInterval = vih->AvgTimePerFrame;
228  caps->MaxFrameInterval = vih->AvgTimePerFrame;
229  caps->MinOutputSize.cx = vih->bmiHeader.biWidth;
230  caps->MinOutputSize.cy = vih->bmiHeader.biHeight;
231  caps->MaxOutputSize = caps->MinOutputSize;
232  caps->InputSize = caps->MinOutputSize;
233  caps->MinCroppingSize = caps->MinOutputSize;
234  caps->MaxCroppingSize = caps->MinOutputSize;
235  caps->CropGranularityX = vih->bmiHeader.biWidth;
236  caps->CropGranularityY = vih->bmiHeader.biHeight;
237  caps->MinBitsPerSecond = vih->dwBitRate;
238  caps->MaxBitsPerSecond = caps->MinBitsPerSecond;
239 
240  return S_OK;
241  }
242 
243  OutputAudioPin::OutputAudioPin(HRESULT* phr, CSource* pFilter, LPCWSTR pPinName)
244  : CSourceStream(VCAM_AUDIO_PIN_NAME, phr, pFilter, pPinName)
245  {
246  }
247 
248  OutputAudioPin::~OutputAudioPin()
249  {
250  }
251 
252  STDMETHODIMP OutputAudioPin::QueryInterface(REFIID riid, void** ppv)
253  {
254  if (!ppv)
255  return E_POINTER;
256 
257  *ppv = nullptr;
258 
259  if (riid == IID_IKsPropertySet)
260  *ppv = static_cast<IKsPropertySet*>(this);
261  else if (riid == IID_IAMStreamConfig)
262  *ppv = static_cast<IAMStreamConfig*>(this);
263  else
264  return CSourceStream::QueryInterface(riid, ppv);
265 
266  AddRef();
267  return S_OK;
268  }
269 
270  STDMETHODIMP_(ULONG) OutputAudioPin::AddRef()
271  {
272  return CSourceStream::AddRef();
273  }
274 
275  STDMETHODIMP_(ULONG) OutputAudioPin::Release()
276  {
277  return CSourceStream::Release();
278  }
279 
280  STDMETHODIMP OutputAudioPin::CheckMediaType(const CMediaType* pmt)
281  {
282  if (!pmt)
283  return E_POINTER;
284 
285  if (*pmt->Type() != MEDIATYPE_Audio)
286  return E_INVALIDARG;
287 
288  if (*pmt->Subtype() != MEDIASUBTYPE_PCM)
289  return E_INVALIDARG;
290 
291  if (*pmt->FormatType() != FORMAT_WaveFormatEx)
292  return E_INVALIDARG;
293 
294  WAVEFORMATEX* pwfex = reinterpret_cast<WAVEFORMATEX*>(pmt->Format());
295  if (!pwfex)
296  return E_INVALIDARG;
297 
298  if (pwfex->wFormatTag != WAVE_FORMAT_PCM && pwfex->wFormatTag != WAVE_FORMAT_EXTENSIBLE)
299  return E_INVALIDARG;
300 
301  if (pwfex->nChannels != VCAM()->GetNumAudioChannels())
302  return E_INVALIDARG;
303 
304  if (pwfex->nSamplesPerSec != VCAM()->GetAudioSampleRate())
305  return E_INVALIDARG;
306 
307  if (pwfex->wBitsPerSample != VCAM()->GetAudioBitsPerSample())
308  return E_INVALIDARG;
309 
310  if (pwfex->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
311  {
312  WAVEFORMATEXTENSIBLE* pwfxext = reinterpret_cast<WAVEFORMATEXTENSIBLE*>(pwfex);
313  if (pwfxext->SubFormat != KSDATAFORMAT_SUBTYPE_PCM)
314  return E_INVALIDARG;
315  }
316 
317  return S_OK;
318  }
319 
320  HRESULT OutputAudioPin::GetMediaType(CMediaType* pMediaType)
321  {
322  if (VCAM()->Initialize())
323  return CopyMediaType(pMediaType, &m_mt);
324 
325  return E_FAIL;
326  }
327 
328  HRESULT OutputAudioPin::FillBuffer(IMediaSample* pSample)
329  {
330  return VCAM()->GetNextFrame(this, pSample);
331  }
332 
333  HRESULT OutputAudioPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pRequest)
334  {
335  CAutoLock cAutoLock(m_pFilter->pStateLock());
336 
337  if (!pAlloc)
338  return E_POINTER;
339 
340  WAVEFORMATEX* pwfx = reinterpret_cast<WAVEFORMATEX*>(m_mt.Format());
341  if (!pwfx)
342  return E_UNEXPECTED;
343 
344  pRequest->cBuffers = 1;
345  pRequest->cbBuffer = gAudMaxSizeBytes * VCAM()->GetNumAudioLinks();
346 
347  ALLOCATOR_PROPERTIES Actual;
348  HRESULT hr = pAlloc->SetProperties(pRequest, &Actual);
349  if (FAILED(hr))
350  return hr;
351 
352  if (Actual.cbBuffer < pRequest->cbBuffer)
353  return E_FAIL;
354 
355  if (Actual.cBuffers != 1)
356  return E_FAIL;
357 
358  return S_OK;
359  }
360 
361  STDMETHODIMP OutputAudioPin::EnumMediaTypes(IEnumMediaTypes** ppEnum)
362  {
363  return CSourceStream::EnumMediaTypes(ppEnum);
364  }
365 
366  STDMETHODIMP OutputAudioPin::Notify(IBaseFilter* pSender, Quality q)
367  {
368  return S_OK;
369  }
370 
371  STDMETHODIMP OutputAudioPin::Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData)
372  {
373  return E_NOTIMPL;
374  }
375 
376  STDMETHODIMP OutputAudioPin::Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD* pcbReturned)
377  {
378  if (guidPropSet != AMPROPSETID_Pin)
379  return E_PROP_SET_UNSUPPORTED;
380 
381  if (dwPropID != AMPROPERTY_PIN_CATEGORY)
382  return E_PROP_ID_UNSUPPORTED;
383 
384  if (pPropData == NULL && pcbReturned == NULL)
385  return E_POINTER;
386 
387  if (pcbReturned)
388  *pcbReturned = sizeof(GUID);
389 
390  if (pPropData == NULL)
391  return S_OK;
392 
393  if (cbPropData < sizeof(GUID))
394  return E_UNEXPECTED;
395 
396  *(GUID*)pPropData = PIN_CATEGORY_CAPTURE;
397 
398  return S_OK;
399  }
400 
401  STDMETHODIMP OutputAudioPin::QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD* pTypeSupport)
402  {
403  if (guidPropSet != AMPROPSETID_Pin)
404  return E_PROP_SET_UNSUPPORTED;
405 
406  if (dwPropID != AMPROPERTY_PIN_CATEGORY)
407  return E_PROP_ID_UNSUPPORTED;
408 
409  if (pTypeSupport)
410  *pTypeSupport = KSPROPERTY_SUPPORT_GET;
411 
412  return S_OK;
413  }
414 
415  STDMETHODIMP OutputAudioPin::SetFormat(AM_MEDIA_TYPE* pmt)
416  {
417  if (!pmt)
418  return E_POINTER;
419 
420  if (pmt->majortype == m_mt.majortype &&
421  pmt->subtype == m_mt.subtype &&
422  pmt->formattype == m_mt.formattype)
423  {
424  m_mt = *pmt;
425  return S_OK;
426  }
427 
428  return VFW_E_INVALIDMEDIATYPE;
429  }
430 
431  STDMETHODIMP OutputAudioPin::GetFormat(AM_MEDIA_TYPE** ppmt)
432  {
433  if (!ppmt)
434  return E_POINTER;
435 
436  *ppmt = CreateMediaType(&m_mt);
437  if (!*ppmt)
438  return E_OUTOFMEMORY;
439 
440  return S_OK;
441  }
442 
443  STDMETHODIMP OutputAudioPin::GetNumberOfCapabilities(int* piCount, int* piSize)
444  {
445  if (!piCount || !piSize)
446  return E_POINTER;
447 
448  *piCount = 1;
449  *piSize = sizeof(AUDIO_STREAM_CONFIG_CAPS);
450 
451  return S_OK;
452  }
453 
454  STDMETHODIMP OutputAudioPin::GetStreamCaps(int iIndex, AM_MEDIA_TYPE** ppmt, BYTE* pSCC)
455  {
456  if (!ppmt || !pSCC)
457  return E_POINTER;
458 
459  if (iIndex < 0 || iIndex >= 1)
460  return E_INVALIDARG;
461 
462  CMediaType mediaType;
463  if (FAILED(GetMediaType(&mediaType)))
464  return E_FAIL;
465  *ppmt = CreateMediaType(&mediaType);
466  if (!*ppmt)
467  return E_OUTOFMEMORY;
468 
469  WAVEFORMATEX* wfex = reinterpret_cast<decltype(wfex)>((*ppmt)->pbFormat);
470  AUDIO_STREAM_CONFIG_CAPS* caps = reinterpret_cast<AUDIO_STREAM_CONFIG_CAPS*>(pSCC);
471  ZeroMemory(caps, sizeof(AUDIO_STREAM_CONFIG_CAPS));
472  caps->guid = FORMAT_WaveFormatEx;
473  caps->MinimumChannels = wfex->nChannels;
474  caps->MaximumChannels = wfex->nChannels;
475  caps->MinimumBitsPerSample = wfex->wBitsPerSample;
476  caps->MaximumBitsPerSample = wfex->wBitsPerSample;
477  caps->MinimumSampleFrequency = wfex->nSamplesPerSec;
478  caps->MaximumSampleFrequency = wfex->nSamplesPerSec;
479 
480  return S_OK;
481  }
482 
483  CUnknown* WINAPI NTV2VCAM::CreateInstance(LPUNKNOWN pUnk, HRESULT* phr)
484  {
485  NTV2VCAM* pFilter = new NTV2VCAM(pUnk, phr);
486  if (pFilter == NULL)
487  *phr = E_OUTOFMEMORY;
488  return pFilter;
489  }
490 
491  STDMETHODIMP NTV2VCAM::QueryInterface(REFIID riid, void** ppv)
492  {
493  return CSource::QueryInterface(riid, ppv);
494  }
495 
496  STDMETHODIMP_(ULONG) NTV2VCAM::AddRef()
497  {
498  return CSource::AddRef();
499  }
500 
501  STDMETHODIMP_(ULONG) NTV2VCAM::Release()
502  {
503  return CSource::Release();
504  }
505 
506  STDMETHODIMP NTV2VCAM::EnumPins(IEnumPins** ppEnum)
507  {
508  return CSource::EnumPins(ppEnum);
509  }
510 
511  STDMETHODIMP NTV2VCAM::FindPin(LPCWSTR Id, IPin** ppPin)
512  {
513  if (Id == nullptr || ppPin == nullptr)
514  return E_POINTER;
515 
516  if (lstrcmpW(Id, VCAM_VIDEO_PIN_NAME_W) == 0)
517  {
518  *ppPin = GetPin(0);
519  (*ppPin)->AddRef();
520  return S_OK;
521  }
522 
523  *ppPin = nullptr;
524  return VFW_E_NOT_FOUND;
525  }
526 
527  STDMETHODIMP NTV2VCAM::QueryFilterInfo(FILTER_INFO* pInfo)
528  {
529  if (!pInfo)
530  return E_POINTER;
531 
532  memcpy(pInfo->achName, VCAM_FILTER_NAME_W, sizeof(VCAM_FILTER_NAME_W));
533 
534  pInfo->pGraph = m_pGraph;
535  if (m_pGraph)
536  m_pGraph->AddRef();
537  return NOERROR;
538  }
539 
540  STDMETHODIMP NTV2VCAM::JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName)
541  {
542  m_pGraph = pGraph;
543  if (m_pGraph)
544  m_pGraph->AddRef();
545  return NOERROR;
546  }
547 
548  STDMETHODIMP NTV2VCAM::QueryVendorInfo(LPWSTR* pVendorInfo)
549  {
550  return S_OK;
551  }
552 
553  NTV2VCAM::NTV2VCAM (LPUNKNOWN pUnk, HRESULT* phr)
554  : CSource(NAME(VCAM_FILTER_NAME), pUnk, CLSID_VirtualWebcam)
555  , mVideos(MAX_VIDEOS)
556  , mAudios(MAX_AUDIOS)
557  {
558  CAutoLock cAutoLock(&m_cStateLock);
559  m_paStreams = (CSourceStream**) new OutputPin * [2];
560  if (m_paStreams == NULL)
561  {
562  if (phr)
563  *phr = E_OUTOFMEMORY;
564  return;
565  }
566 
567  m_paStreams[0] = new OutputVideoPin(phr, this, VCAM_VIDEO_PIN_NAME_W);
568  if (m_paStreams[0] == NULL)
569  {
570  if (phr)
571  *phr = E_OUTOFMEMORY;
572  return;
573  }
574 
575  m_paStreams[1] = new OutputAudioPin(phr, this, VCAM_AUDIO_PIN_NAME_W);
576  if (m_paStreams[1] == NULL)
577  {
578  if (phr)
579  *phr = E_OUTOFMEMORY;
580 
581  return;
582  }
583 
584  mAjaDevice = "2";
585  mInputType = "hdmi";
587  mPixelFormatStr = "uyvy";
588  }
589 #endif // end AJA_WINDOWS section
590 
591 NTV2VCAM::~NTV2VCAM()
592 {
593  cout << "## NOTE: NTV2VCAM terminated" << endl;
594 
595  #if defined(AJALinux)
596  if (mLbDisplay > 0)
597  {
598  close(mLbDisplay);
599  #if !defined(AJA_MISSING_DEV_V4L2LOOPBACK)
600  if (ioctl(mLbDevice, V4L2LOOPBACK_CTL_REMOVE, mLbDeviceNR) == -1)
601  {
602  cerr << "## ERROR (" << errno << "): failed to remove V4L2 device for output" << endl;
603  mErrorCode = AJA_VW_V4L2DEVICEREMOVEFAILED;
604  return;
605  }
606  #endif
607  }
608  #if !defined(AJA_MISSING_DEV_V4L2LOOPBACK)
609  if (mLbDevice > 0)
610  close(mLbDevice);
611  #endif
612 
613  if (mPcmHandle)
614  {
615  snd_pcm_drain(mPcmHandle);
616  snd_pcm_close(mPcmHandle);
617  }
618  #endif // AJALinux
619 
621 
622  if (!mDoMultiFormat)
623  {
625  mDevice.SetEveryFrameServices(mSavedTaskMode);
626  }
627 }
628 
629 #if defined(AJALinux)
630 bool NTV2VCAM::Initialize (int argc, const char** argv)
631 {
632  { // Parse command-line params...
633  int showVersion(0), useHDMI(0), inputChannel(0);
634  char * pAjaDevSpec = AJA_NULL;
635  char * pPixFormat = AJA_NULL;
636  char * pVideoDevice = AJA_NULL;
637  char * pAudioDevice = AJA_NULL;
638  const CNTV2DemoCommon::PoptOpts optionsTable[] =
639  {
640  {"version", 'v', POPT_ARG_NONE, &showVersion, 0, "NTV2 version", AJA_NULL},
641  {"device", 'd', POPT_ARG_STRING, &pAjaDevSpec, 0, "AJA device", "index#, serial#, or model"},
642  {"hdmi", 'h', POPT_ARG_NONE, &useHDMI, 0, "use HDMI input?", AJA_NULL},
643  {"channel", 'c', POPT_ARG_INT, &inputChannel, 0, "input channel", "1-8"},
644  {"pixelformat", 'p', POPT_ARG_STRING, &pPixFormat, 0, "pixel format", "FourCC string or 'list'"},
645  {"vdev", 'i', POPT_ARG_STRING, &pVideoDevice, 0, "video device", "/dev/video1"},
646  {"adev", 'u', POPT_ARG_STRING, &pAudioDevice, 0, "audio device", "hw:Loopback,1,1"},
647  {"audiolinks", 'a', POPT_ARG_INT, &mNumAudioLinks,0, "multilink audio systems", "0 for silence or 1-4"},
650  };
651  CNTV2DemoCommon::Popt popt(argc, argv, optionsTable);
652  if (!popt)
653  {
654  cerr << "## ERROR (" << errno << "): " << popt.errorStr() << endl;
655  mErrorCode = AJA_VW_INVALIDARGS;
656  return false;
657  }
658  mAjaDevice = pAjaDevSpec ? pAjaDevSpec : "0";
659  mInputType = useHDMI ? "hdmi" : "sdi";
660  mPixelFormatStr = pPixFormat ? pPixFormat : "2vuy";
661  mVideoDevice = pVideoDevice ? pVideoDevice : "";
662  mAudioDevice = pAudioDevice ? pAudioDevice : "";
663  if (showVersion)
664  {
665  cout << argv[0] << ", NTV2 SDK " << NTV2Version() << endl;
666  return false;
667  }
668  mInputChannel = NTV2Channel(inputChannel ? inputChannel-1 : 0);
669  }
670 
671 #elif defined(AJA_WINDOWS)
672 
673 bool NTV2VCAM::Initialize()
674 {
675  if (mInitialized)
676  return true;
677 #endif // AJA_WINDOWS or AJALinux
678 
679  if (mAjaDevice.empty())
680  {
681  cerr << "## ERROR (" << errno << "): Parameter 'AJA device' is required." << endl;
682  mErrorCode = AJA_VW_MISSINGARGS;
683  return false;
684  }
685  if (mInputType.empty())
686  {
687  cerr << "## ERROR (" << errno << "): Parameter 'input type' is required." << endl;
688  mErrorCode = AJA_VW_MISSINGARGS;
689  return false;
690  }
691  if (mPixelFormatStr.empty())
692  {
693  cerr << "## ERROR (" << errno << "): Parameter 'pixel format' is required." << endl;
694  mErrorCode = AJA_VW_MISSINGARGS;
695  return false;
696  }
697  #if defined(AJALinux)
698  if (mVideoDevice.empty())
699  {
700  cerr << "## ERROR (" << errno << "): Parameter 'video device' is required." << endl;
701  mErrorCode = AJA_VW_MISSINGARGS;
702  return false;
703  }
704  #endif // AJALinux
705  if (mPixelFormatStr == "list")
706  {
707  cout << CNTV2DemoCommon::GetPixelFormatStrings(PIXEL_FORMATS_ALL, mAjaDevice) << endl;
708  return false;
709  }
710  mPixelFormat = mPixelFormatStr.empty() ? NTV2_FBF_8BIT_YCBCR : CNTV2DemoCommon::GetPixelFormatFromString(mPixelFormatStr);
712  {
713  cerr << "## ERROR (" << errno << "): invalid pixel format" << endl;
714  mErrorCode = AJA_VW_INVALIDPIXELFORMAT;
715  return false;
716  }
717 
719  {
720  cerr << "## ERROR (" << errno << "): invalid channel '" << DEC(mInputChannel+1) << "'" << endl;
721  mErrorCode = AJA_VW_INVALIDINPUTCHANNEL;
722  return false;
723  }
724 
726  {
727  cerr << "## ERROR (" << errno << "): cannot find AJA device '" << mAjaDevice << "'" << endl;
728  mErrorCode = AJA_VW_INVALIDAJADEVICE;
729  return false;
730  }
731 
732  if (!mDevice.IsDeviceReady())
733  {
734  cerr << "## ERROR (" << errno << "): AJA device not ready" << endl;
735  mErrorCode = AJA_VW_AJADEVICENOTREADY;
736  return false;
737  }
738 
739  if (!mDevice.features().CanDoCapture())
740  {
741  cerr << "## ERROR (" << errno << "): AJA device does not support capture" << endl;
742  mErrorCode = AJA_VW_AJADEVICENOCAPTURE;
743  return false;
744  }
745 
746  if (mInputType == "hdmi")
747  {
748  if (mDevice.features().GetNumHDMIVideoInputs() <= 0)
749  {
750  cerr << "## ERROR (" << errno << "): AJA device does not support HDMI" << endl;
751  mErrorCode = AJA_VW_NOHDMISUPPORT;
752  return false;
753  }
754  mIsKonaHDMI = true;
755  mIOKinds = NTV2_IOKINDS_HDMI;
756  }
757 
759  {
760  cerr << "## ERROR (" << errno << "): AJA device does not support pixel format" << endl;
761  mErrorCode = AJA_VW_AJADEVICENOPIXELFORMAT;
762  return false;
763  }
764 
765  ULWord appSignature(0);
766  int32_t appPID(0);
768  {
769  cerr << "## ERROR: (" << errno << ") Unable to get device's current owner" << endl;
770  mErrorCode = AJA_VW_GETDEVICEOWNERFAILED;
771  return false;
772  }
773  if (!mDoMultiFormat)
774  {
776  {
777  cerr << "## ERROR: (" << errno << ") Unable to acquire AJA device because another app (pid " << appPID << ") owns it" << endl;
778  mErrorCode = AJA_STATUS_BUSY;
779  return false;
780  }
781  }
782  if (!mDevice.GetEveryFrameServices(mSavedTaskMode))
783  {
784  cerr << "## ERROR: (" << errno << ") Unable to get device's retail service task mode" << endl;
785  mErrorCode = AJA_VW_GETFRAMESERVICESFAILED;
786  return false;
787  }
788  else
789  {
790  if (!mDevice.SetEveryFrameServices(NTV2_OEM_TASKS))
791  {
792  cerr << "## ERROR: (" << errno << ") Unable to set device's retail service task mode to oem tasks" << endl;
793  mErrorCode = AJA_VW_SETFRAMESERVICESFAILED;
794  return false;
795  }
796  }
797 
798  if (mDevice.features().CanDoMultiFormat())
799  mDevice.SetMultiFormatMode(mDoMultiFormat);
800 
803  Get4KInputFormat(mVideoFormat);
805  {
806  cerr << "## ERROR (" << errno << "): invalid video format '" << mVideoFormat << "'" << endl;
807  mErrorCode = AJA_VW_INVALIDVIDEOFORMAT;
808  return false;
809  }
811  {
813  {
814  cerr << "## ERROR (" << errno << "): invalid channel '" << DEC(mInputChannel) << "'" << endl;
815  mErrorCode = AJA_VW_INVALIDINPUTCHANNEL;
816  return false;
817  }
818  mInputSource = NTV2ChannelToInputSource(mInputChannel, mIOKinds);
819  if (mIsKonaHDMI && NTV2_INPUT_SOURCE_IS_SDI(mInputSource))
820  mInputSource = NTV2ChannelToInputSource(NTV2InputSourceToChannel(mInputSource), mIOKinds);
821  if (!mDevice.features().CanDoInputSource(mInputSource))
822  {
823  cerr << "## ERROR (" << errno << "): invalid input source" << endl;
824  mErrorCode = AJA_VW_INVALIDINPUTSOURCE;
825  return false;
826  }
827 
828  mNumSpigots = 1;
829  mActiveFrameStores = NTV2MakeChannelSet(mInputChannel, mNumSpigots);
830  mActiveSDIs = NTV2MakeChannelSet(mInputChannel, mNumSpigots);
831  }
833  {
834  const NTV2Channel origCh(mInputChannel);
835  if (mIsKonaHDMI)
836  {
837  if (!mDoTSIRouting)
838  {
839  cerr << "## ERROR (" << errno << "): AJA device requires TSI support" << endl;
840  mErrorCode = AJA_VW_NOTSISUPPORT;
841  return false;
842  }
846  }
847  else if (mDevice.features().CanDo12gRouting())
848  {
849  mDoTSIRouting = false;
850  if (UWord(origCh) >= mDevice.features().GetNumFrameStores())
851  {
852  cerr << "## ERROR (" << errno << "): invalid channel '" << DEC(mInputChannel) << "'" << endl;
853  mErrorCode = AJA_VW_INVALIDINPUTCHANNEL;
854  return false;
855  }
856  mInputSource = NTV2ChannelToInputSource(mInputChannel);
857  }
858  else if (mDoTSIRouting)
859  {
862  else if (mInputChannel < NTV2_CHANNEL5)
864  else if (mInputChannel < NTV2_CHANNEL7)
866  else
868  }
869  else
870  {
872  }
873 
874  if (!NTV2_IS_VALID_INPUT_SOURCE(mInputSource))
875  mInputSource = NTV2ChannelToInputSource(mInputChannel);
876 
878  {
879  cerr << "## ERROR (" << errno << "): invalid channel '" << DEC(mInputChannel) << "'" << endl;
880  mErrorCode = AJA_VW_INVALIDINPUTCHANNEL;
881  return false;
882  }
883  if (!NTV2_IS_VALID_INPUT_SOURCE(mInputSource))
884  {
885  cerr << "## ERROR (" << errno << "): invalid input source '" << DEC(mInputSource) << "'" << endl;
886  mErrorCode = AJA_VW_INVALIDINPUTSOURCE;
887  return false;
888  }
889 
890  if (mInputChannel != origCh)
891  cerr << "## WARNING: Specified channel Ch" << DEC(origCh + 1) << " corrected to use Ch" << DEC(mInputChannel + 1) << " to work for UHD/4K on '" << mDevice.GetDisplayName() << "'" << endl;
892 
893  mNumSpigots = mDevice.features().CanDo12gRouting() ? 1 : (mDoTSIRouting ? 2 : 4);
894  mActiveFrameStores = NTV2MakeChannelSet(mInputChannel, mNumSpigots);
895  mActiveSDIs = NTV2MakeChannelSet(mInputChannel, mNumSpigots);
896  }
897 
898  if (!mDevice.EnableChannels(mActiveFrameStores, !mDoMultiFormat))
899  {
900  cerr << "## ERROR (" << errno << "): enable channels failed" << endl;
901  mErrorCode = AJA_VW_ENABLECHANNELSFAILED;
902  return false;
903  }
904 
906  {
907  cerr << "## ERROR (" << errno << "): enable input interrupt failed" << endl;
909  return false;
910  }
911 
913  {
914  cerr << "## ERROR (" << errno << "): subscribe input vertical event failed" << endl;
916  return false;
917  }
918 
920  {
921  cerr << "## ERROR (" << errno << "): subscribe output vertical event failed" << endl;
923  return false;
924  }
925 
926  if (mDevice.features().HasBiDirectionalSDI() && NTV2_INPUT_SOURCE_IS_SDI(mInputSource))
927  {
928  if (!mDevice.SetSDITransmitEnable(mActiveSDIs, false))
929  {
930  cerr << "## ERROR (" << errno << "): set SDI transmit enabled failed" << endl;
932  return false;
933  }
935  {
936  cerr << "## ERROR (" << errno << "): wait for output vertical interrupt failed" << endl;
938  return false;
939  }
940  }
941 
943 
945  {
946  cerr << "## ERROR (" << errno << "): failed to set capture mode" << endl;
947  mErrorCode = AJA_VW_SETCAPTUREMODEFAILED;
948  return false;
949  }
950 
951  if (!mDoMultiFormat)
952  if (!mDevice.SetReference(NTV2_REFERENCE_FREERUN))
953  {
954  cerr << "## ERROR (" << errno << "): set freerun reference failed" << endl;
956  return false;
957  }
958 
959  if (!mDevice.SetVideoFormat(mVideoFormat, false, false, mInputChannel))
960  {
961  cerr << "## ERROR (" << errno << "): failed to set video format on AJA device" << endl;
962  mErrorCode = AJA_VW_SETVIDEOFORMATFAILED;
963  return false;
964  }
965 
966  if (!mDevice.SetVANCMode(mActiveFrameStores, NTV2_VANCMODE_OFF))
967  {
968  cerr << "## ERROR (" << errno << "): set VANC mode off failed" << endl;
969  mErrorCode = AJA_VW_SETVANCMODEOFFFAILED;
970  return false;
971  }
972 
974  {
975  if (mDevice.features().CanDo12gRouting() || mDoTSIRouting)
976  {
978  if (!mDevice.SetTsiFrameEnable(true, mInputChannel))
979  {
980  cerr << "## ERROR (" << errno << "): set TSI frame enable failed" << endl;
981  mErrorCode = AJA_VW_SETTSIFRAMEENABLEFAILED;
982  return false;
983  }
984  }
985  else
986  {
987  if (!mDevice.Set4kSquaresEnable(true, mInputChannel))
988  {
989  cerr << "## ERROR (" << errno << "): set 4k squares enable failed" << endl;
990  mErrorCode = AJA_VW_SET4KSQUARESENABLEFAILED;
991  return false;
992  }
993  }
994  }
995 
996  if (!mDevice.SetFrameBufferFormat(mActiveFrameStores, mPixelFormat))
997  {
998  cerr << "## ERROR (" << errno << "): set frame buffer format failed" << endl;
1000  return false;
1001  }
1002 
1003  mVideoBuffer.Allocate(mFormatDesc.GetTotalRasterBytes());
1004  mDevice.DMABufferLock(mVideoBuffer, true);
1005 
1006  SetupAudio();
1007 
1009  if (NTV2_INPUT_SOURCE_IS_HDMI(mInputSource))
1013  {
1014  if (!GetInputRouting4K(connections, inputColorSpace == NTV2_LHIHDMIColorSpaceRGB))
1015  {
1016  cerr << "## ERROR (" << errno << "): get input routing failed" << endl;
1017  mErrorCode = AJA_VW_GETINPUTROUTEFAILED;
1018  return false;
1019  }
1020  }
1021  else
1022  {
1023  if (!GetInputRouting(connections, inputColorSpace == NTV2_LHIHDMIColorSpaceRGB))
1024  {
1025  cerr << "## ERROR (" << errno << "): get input routing failed" << endl;
1026  mErrorCode = AJA_VW_GETINPUTROUTEFAILED;
1027  return false;
1028  }
1029  }
1030  if (!mDevice.ApplySignalRoute(connections, !mDoMultiFormat))
1031  {
1032  cerr << "## ERROR (" << errno << "): apply signal route failed" << endl;
1033  mErrorCode = AJA_VW_APPLYSIGNALROUTEFAILED;
1034  return false;
1035  }
1036 
1037  #if defined(AJALinux)
1038  #if !defined(AJA_MISSING_DEV_V4L2LOOPBACK)
1039  mLbDevice = open(V4L2_DRIVER_NAME, O_RDONLY);
1040  if (mLbDevice == -1)
1041  {
1042  cerr << "## ERROR (" << errno << "): failed to open V4L2 driver" << endl;
1043  mErrorCode = AJA_VW_V4L2DRIVEROPENFAILED;
1044  return false;
1045  }
1047  memset(&cfg, 0, sizeof(v4l2_loopback_config));
1048  cfg.output_nr = mLbDeviceNR = ExtractNumber(mVideoDevice.c_str());
1049  string labelName = "AJA virtual webcam device " + to_string(mLbDeviceNR);
1050  strcpy(cfg.card_label, labelName.c_str());
1051  mLbDeviceNR = ioctl(mLbDevice, V4L2LOOPBACK_CTL_ADD, &cfg);
1052  if (mLbDeviceNR == -1)
1053  {
1054  cerr << "## ERROR (" << errno << "): failed to create V4L2 device for output" << endl;
1055  mErrorCode = AJA_VW_V4L2DEVICECREATEFAILED;
1056  return false;
1057  }
1058  #endif // !defined(AJA_MISSING_DEV_V4L2LOOPBACK)
1059  mLbDisplay = open(mVideoDevice.c_str(), O_RDWR);
1060  if (mLbDisplay == -1)
1061  {
1062  cerr << "## ERROR (" << errno << "): failed to open V4L2 output device" << endl;
1063  mErrorCode = AJA_VW_V4L2DEVICEOPENFAILED;
1064  return false;
1065  }
1066 
1067  struct v4l2_format lbFormat;
1068  memset(&lbFormat, 0, sizeof(lbFormat));
1069  lbFormat.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1070  lbFormat.fmt.pix.width = mFormatDesc.GetRasterWidth();
1071  lbFormat.fmt.pix.height = mFormatDesc.GetRasterHeight();
1072  lbFormat.fmt.pix.field = V4L2_FIELD_NONE;
1073  lbFormat.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
1074  lbFormat.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1075  if (ioctl(mLbDisplay, VIDIOC_S_FMT, &lbFormat) == -1)
1076  cerr << "## ERROR (" << errno << "): cannot set video format on video loopback device" << endl;
1077 
1078  struct v4l2_streamparm streamParm;
1079  memset(&streamParm, 0, sizeof(streamParm));
1080  streamParm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1081  streamParm.parm.output.timeperframe.numerator = 1;
1082  streamParm.parm.output.timeperframe.denominator = GetFps();
1083  if (ioctl(mLbDisplay, VIDIOC_S_PARM, &streamParm) == -1)
1084  cerr << "## ERROR (" << errno << "): cannot set frame rate on video loopback device" << endl;
1085  #endif // AJALinux
1086 
1087  bool retVal = false;
1089  retVal = mFrames.setExactRange(0, 6);
1091  {
1092  const UWord startFrame12g[] = { 0, 7, 64, 71 };
1093  const UWord startFrame[] = { 0, 7, 14, 21 };
1094  if (mDevice.features().CanDo12gRouting())
1095  retVal = mFrames.setRangeWithCount(7, startFrame12g[mInputChannel]);
1096  else
1097  retVal = mFrames.setRangeWithCount(7, startFrame[mInputChannel / 2]);
1098  }
1099  else
1100  retVal = mFrames.setCountOnly(7);
1101  if (!retVal)
1102  {
1103  cerr << "## ERROR (" << errno << "): failed to set AC frame range" << endl;
1104  mErrorCode = AJA_VW_SETACFRAMERANGEFAILED;
1105  return false;
1106  }
1107 
1108  #if defined(AJA_WINDOWS)
1109  if (OutputVideoPin* pVideoPin = dynamic_cast<OutputVideoPin*>(m_paStreams[0]))
1110  {
1111  VIDEOINFO vi;
1112  ZeroMemory(&vi, sizeof(VIDEOINFO));
1113  vi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1114  vi.bmiHeader.biWidth = mFormatDesc.GetRasterWidth();
1115  vi.bmiHeader.biHeight = mFormatDesc.GetRasterHeight();
1116  vi.bmiHeader.biPlanes = mFormatDesc.GetNumPlanes();
1117  vi.bmiHeader.biBitCount = mFormatDesc.GetNumBitsLuma() + mFormatDesc.GetNumBitsChroma() + mFormatDesc.GetNumBitsAlpha();
1118  vi.bmiHeader.biCompression = 0x59565955; //UYVY
1119  vi.bmiHeader.biSizeImage = mFormatDesc.GetTotalRasterBytes();
1120  vi.AvgTimePerFrame = GetFps();
1121 
1122  pVideoPin->m_mt.SetType(&MEDIATYPE_Video);
1123  pVideoPin->m_mt.SetSubtype(&MEDIASUBTYPE_UYVY);
1124  pVideoPin->m_mt.SetFormatType(&FORMAT_VideoInfo);
1125  pVideoPin->m_mt.SetSampleSize(vi.bmiHeader.biSizeImage);
1126  pVideoPin->m_mt.SetTemporalCompression(FALSE);
1127  pVideoPin->m_mt.SetFormat(reinterpret_cast<BYTE*>(&vi), sizeof(VIDEOINFO));
1128  }
1129 
1130  if (OutputAudioPin* pAudioPin = dynamic_cast<OutputAudioPin*>(m_paStreams[1]))
1131  {
1133  ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE));
1134  wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
1135  wfx.Format.nChannels = mNumAudioChannels;
1136  wfx.Format.nSamplesPerSec = mSampleRate;
1137  wfx.Format.wBitsPerSample = mBitsPerSample;
1138  wfx.Format.nBlockAlign = (wfx.Format.nChannels * wfx.Format.wBitsPerSample) / 8;
1139  wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
1140  wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
1141 
1142  wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;
1143  if (mNumAudioChannels == 2)
1144  {
1145  wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
1146  }
1147  else if (mNumAudioChannels == 16)
1148  {
1149  wfx.dwChannelMask =
1150  SPEAKER_FRONT_LEFT |
1151  SPEAKER_FRONT_RIGHT |
1152  SPEAKER_FRONT_CENTER |
1153  SPEAKER_LOW_FREQUENCY |
1154  SPEAKER_BACK_LEFT |
1155  SPEAKER_BACK_RIGHT |
1156  SPEAKER_FRONT_LEFT_OF_CENTER |
1157  SPEAKER_FRONT_RIGHT_OF_CENTER |
1158  SPEAKER_BACK_CENTER |
1159  SPEAKER_SIDE_LEFT |
1160  SPEAKER_SIDE_RIGHT |
1161  SPEAKER_TOP_CENTER |
1162  SPEAKER_TOP_FRONT_LEFT |
1163  SPEAKER_TOP_FRONT_CENTER |
1164  SPEAKER_TOP_FRONT_RIGHT |
1165  SPEAKER_TOP_BACK_CENTER;
1166  }
1167  wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
1168 
1169  pAudioPin->m_mt.ResetFormatBuffer();
1170  pAudioPin->m_mt.SetType(&MEDIATYPE_Audio);
1171  pAudioPin->m_mt.SetSubtype(&MEDIASUBTYPE_PCM);
1172  pAudioPin->m_mt.SetFormatType(&FORMAT_WaveFormatEx);
1173  pAudioPin->m_mt.SetTemporalCompression(FALSE);
1174  pAudioPin->m_mt.SetSampleSize(wfx.Format.nBlockAlign);
1175 
1176  BYTE* pFormat = (BYTE*)pAudioPin->m_mt.AllocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
1177  memcpy(pFormat, &wfx, sizeof(WAVEFORMATEXTENSIBLE));
1178  }
1179 
1180  mInitialized = true;
1181  #endif // AJA_WINDOWS
1182  return true;
1183 } // NTV2VCAM::Initialize
1184 
1185 #if defined(AJALinux)
1186  bool NTV2VCAM::Run(void)
1187  {
1188  mDevice.AutoCirculateStop(mActiveFrameStores);
1189  if (!mDevice.AutoCirculateInitForInput(mInputChannel, mFrames.count(), mAudioSystem, mACOptions, 1, mFrames.firstFrame(), mFrames.lastFrame()))
1190  {cerr << "## ERROR: AC init for input failed" << endl; mErrorCode = AJA_VW_ACINITFORINPUTFAILED; return false;}
1191  if (!mDevice.AutoCirculateStart(mInputChannel))
1192  {cerr << "## ERROR: AC start failed" << endl; mErrorCode = AJA_VW_ACSTARTFAILED; return false;}
1193  if (!mAcTransfer.SetVideoBuffer(mVideoBuffer, mVideoBuffer.GetByteCount()))
1194  {cerr << "## ERROR: AC set video buffer failed" << endl; mErrorCode = AJA_VW_ACSETVIDEOBUFFERFAILED; return false;}
1195  if (mAudioBuffer && !mAcTransfer.SetAudioBuffer(mAudioBuffer, mAudioBuffer.GetByteCount()))
1196  {cerr << "## ERROR: AC set audio buffer failed" << endl; mErrorCode = AJA_VW_ACSETAUDIOBUFFERFAILED; return false;}
1197 
1198  signal(SIGINT, SignalHandler);
1199 
1200  while (!gGlobalQuit)
1201  {
1202  AUTOCIRCULATE_STATUS acStatus;
1203  if (!mDevice.AutoCirculateGetStatus(mInputChannel, acStatus))
1204  return false;
1205  if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
1206  {
1207  if (!mDevice.AutoCirculateTransfer(mInputChannel, mAcTransfer))
1208  {cerr << "## ERROR: AC transfer failed" << endl; mErrorCode = AJA_VW_ACTRANSFERFAILED; return false;}
1209 
1210  if (write(mLbDisplay, mVideoBuffer, mVideoBuffer.GetByteCount()) == -1)
1211  cerr << "## ERROR (" << errno << "): write to video loopback device failed" << endl;
1212 
1213  if (mAudioBuffer)
1214  {
1215  mAudioFrames = mAcTransfer.GetCapturedAudioByteCount() / (AUDIO_BYTESPERSAMPLE * mNumAudioChannels);
1216  unsigned long pcmReturn = snd_pcm_writei(mPcmHandle, mAudioBuffer, mAudioFrames);
1217  if (pcmReturn < 0)
1218  pcmReturn = snd_pcm_recover(mPcmHandle, pcmReturn, 0);
1219  if (pcmReturn < 0)
1220  cerr << "## ERROR (" << errno << "): snd_pcm_writei failed" << endl;
1221  if (pcmReturn > 0 && pcmReturn < mAudioFrames)
1222  cerr << "## ERROR (" << errno << "): short write - expected '" << mAudioFrames << "' frames, wrote '" << pcmReturn << "' frames" << endl;
1223  }
1224  }
1225  else
1227  } // while !mGlobalQuit
1228  return true;
1229  } // NTV2VCAM::Run
1230 #endif // AJALinux
1231 
1232 #if defined(AJA_WINDOWS)
1233  HRESULT NTV2VCAM::GetNextFrame (OutputPin* pPin, IMediaSample* pSample)
1234  {
1235  ASSERT(mInitialized);
1236  if (!mRunning)
1237  {
1238  mDevice.AutoCirculateStop(mActiveFrameStores);
1239  if (!mDevice.AutoCirculateInitForInput(mInputChannel, mFrames.count(), mAudioSystem, mACOptions, 1, mFrames.firstFrame(), mFrames.lastFrame()))
1240  {cerr << "## ERROR: AC init for input failed" << endl; mErrorCode = AJA_VW_ACINITFORINPUTFAILED; return S_FALSE;}
1241  if (!mDevice.AutoCirculateStart(mInputChannel))
1242  {cerr << "## ERROR: AC start failed" << endl; mErrorCode = AJA_VW_ACSTARTFAILED; return S_FALSE;}
1243  if (!mAcTransfer.SetVideoBuffer(mVideoBuffer, mVideoBuffer.GetByteCount()))
1244  {cerr << "## ERROR: AC set video buffer failed" << endl; mErrorCode = AJA_VW_ACSETVIDEOBUFFERFAILED; return S_FALSE;}
1245  if (mAudioBuffer && !mAcTransfer.SetAudioBuffer(mAudioBuffer, mAudioBuffer.GetByteCount()))
1246  {cerr << "## ERROR: AC set audio buffer failed" << endl; mErrorCode = AJA_VW_ACSETAUDIOBUFFERFAILED; return S_FALSE;}
1247  }
1248 
1249  AUTOCIRCULATE_STATUS acStatus;
1250  if (!mDevice.AutoCirculateGetStatus(mInputChannel, acStatus))
1251  return S_FALSE;
1252 
1253  if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
1254  {
1255  if (!mDevice.AutoCirculateTransfer(mInputChannel, mAcTransfer))
1256  {cerr << "## ERROR: AC transfer failed" << endl; mErrorCode = AJA_VW_ACTRANSFERFAILED; return S_FALSE;}
1257 
1258  mVideos.push(mVideoBuffer);
1259  mAudioBuffer ? mAudios.push(mAudioBuffer) : 0;
1260  }
1261  else
1263 
1264  BYTE* pData;
1265  HRESULT hr = pSample->GetPointer(&pData);
1266  if (FAILED(hr))
1267  {
1268  cerr << "## ERROR (" << errno << "): failed to get pointer to sample buffer" << endl;
1269  mErrorCode = AJA_VW_GETPOINTERFAILED;
1270  return S_FALSE;
1271  }
1272  ULWord cbData = pSample->GetSize();
1273  if (OutputVideoPin* pVideoPin = dynamic_cast<OutputVideoPin*>(pPin))
1274  {
1275  NTV2Buffer tmpVideoBuffer;
1276  if (mVideos.pop(tmpVideoBuffer))
1277  {
1278  if (tmpVideoBuffer.GetByteCount() != cbData)
1279  {
1280  cerr << "## ERROR: sample buffer size mismatch: AJA is " << tmpVideoBuffer.GetByteCount() << ", output is " << cbData << endl;
1281  mErrorCode = AJA_VW_SAMPLEBUFFERSIZEMISMATCH;
1282  return S_FALSE;
1283  }
1284  memcpy(pData, tmpVideoBuffer, cbData);
1285  pSample->SetActualDataLength(tmpVideoBuffer.GetByteCount());
1286  }
1287  }
1288  if (OutputAudioPin* pAudioPin = dynamic_cast<OutputAudioPin*>(pPin))
1289  {
1290  NTV2Buffer tmpAudioBuffer;
1291  if (mAudios.pop(tmpAudioBuffer))
1292  {
1293  if (mAcTransfer.GetCapturedAudioByteCount() > cbData)
1294  {
1295  cerr << "## ERROR: sample buffer size mismatch: AJA is " << tmpAudioBuffer.GetByteCount() << ", output is " << cbData << endl;
1296  mErrorCode = AJA_VW_SAMPLEBUFFERSIZEMISMATCH;
1297  return S_FALSE;
1298  }
1299  memcpy(pData, tmpAudioBuffer, mAcTransfer.GetCapturedAudioByteCount());
1300  pSample->SetActualDataLength(mAcTransfer.GetCapturedAudioByteCount());
1301  }
1302  }
1303  pSample->SetSyncPoint(TRUE);
1304  mRunning = true;
1305  return S_OK;
1306  } // GetNextFrame
1307 #endif // defined(AJA_WINDOWS)
1308 
1309 string NTV2VCAM::ULWordToString(const ULWord inNum)
1310 {
1311  ostringstream oss;
1312  oss << inNum;
1313  return oss.str();
1314 }
1315 
1316 bool NTV2VCAM::Get4KInputFormat(NTV2VideoFormat& inOutVideoFormat)
1317 {
1318  static struct VideoFormatPair
1319  {
1320  NTV2VideoFormat vIn;
1321  NTV2VideoFormat vOut;
1322  } VideoFormatPairs[] = { // vIn vOut
1341 
1345 
1349  };
1350  for (size_t formatNdx(0); formatNdx < sizeof(VideoFormatPairs) / sizeof(VideoFormatPair); formatNdx++)
1351  if (VideoFormatPairs[formatNdx].vIn == inOutVideoFormat)
1352  {
1353  inOutVideoFormat = VideoFormatPairs[formatNdx].vOut;
1354  return true;
1355  }
1356  return false;
1357 }
1358 
1359 void NTV2VCAM::SetupAudio()
1360 {
1361  #if defined(AJALinux)
1362  if (mAudioDevice.empty())
1363  return;
1364  #endif // AJALinux
1365 
1366  mAudioSystem = NTV2InputSourceToAudioSystem(mInputSource);
1367  if (mIsKonaHDMI)
1368  mAudioSystem = NTV2_AUDIOSYSTEM_2;
1369 
1370  if (!mDevice.features().CanDoMultiLinkAudio())
1371  mNumAudioLinks = 1;
1372 
1373  int fNumAudioSystems = mDevice.features().GetNumAudioSystems();
1374  if (mDoMultiFormat && fNumAudioSystems > 1 && UWord(mInputChannel) < fNumAudioSystems)
1375  mAudioSystem = NTV2ChannelToAudioSystem(mInputChannel);
1376  NTV2AudioSystemSet multiLinkAudioSystems(NTV2MakeAudioSystemSet(mAudioSystem, 1));
1377  if (mNumAudioLinks > 1)
1378  {
1381  {
1382  cerr << "## ERROR (" << errno << "): multi-Link audio only intended for input Ch1, not Ch" << DEC(mInputChannel) << endl;
1384  return;
1385  }
1388  {
1391  }
1392  }
1393 
1394  UWord failures = 0;
1395  mNumAudioChannels = mDevice.features().GetMaxAudioChannels();
1396  for (NTV2AudioSystemSetConstIter it = multiLinkAudioSystems.begin(); it != multiLinkAudioSystems.end(); ++it)
1397  {
1398  const NTV2AudioSystem audSys(*it);
1399  if (!mDevice.SetAudioSystemInputSource(audSys, NTV2InputSourceToAudioSource(mInputSource), NTV2InputSourceToEmbeddedAudioInput(mInputSource)))
1400  failures++;
1401  if (!mDevice.SetNumberAudioChannels(mNumAudioChannels, audSys))
1402  failures++;
1403  if (!mDevice.SetAudioRate(NTV2_AUDIO_48K, audSys))
1404  failures++;
1405  if (!mDevice.SetAudioBufferSize(NTV2_AUDIO_BUFFER_SIZE_4MB, audSys))
1406  failures++;
1407  if (!mDevice.SetAudioLoopBack(NTV2_AUDIO_LOOPBACK_OFF, audSys))
1408  failures++;
1409  }
1410  if (failures > 0)
1411  {
1412  cerr << "## ERROR (" << errno << "): configure audio system failed" << endl;
1413  mErrorCode = AJA_VW_CONFIGAUDIOSYSTEMFAILED;
1414  return;
1415  }
1416  #if defined(AJALinux)
1417  int pcmReturn = snd_pcm_open(&mPcmHandle, mAudioDevice.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
1418  if (pcmReturn < 0)
1419  {
1420  cerr << "## ERROR (" << errno << "): snd_pcm_open failed" << endl;
1421  return;
1422  }
1423  pcmReturn = snd_pcm_set_params(mPcmHandle, SND_PCM_FORMAT_S32_LE, SND_PCM_ACCESS_RW_INTERLEAVED, mNumAudioChannels, mSampleRate, 1, 500000);
1424  if (pcmReturn < 0)
1425  {
1426  cerr << "## ERROR (" << errno << "): snd_pcm_set_params failed" << endl;
1427  return;
1428  }
1429  #endif // AJALinux
1430  if (NTV2_IS_VALID_AUDIO_SYSTEM(mAudioSystem))
1431  {
1432  mAudioBuffer.Allocate(gAudMaxSizeBytes * mNumAudioLinks);
1433  mDevice.DMABufferLock(mAudioBuffer, true);
1434  }
1435 } // SetupAudio
1436 
1437 bool NTV2VCAM::GetInputRouting(NTV2XptConnections& conns, const bool isInputRGB)
1438 {
1439  const bool isFrameRGB(::IsRGBFormat(mPixelFormat));
1441  const NTV2OutputXptID inputOXpt(::GetInputSourceOutputXpt(mInputSource, false, isInputRGB));
1443  NTV2OutputXptID cscOXpt(::GetCSCOutputXptFromChannel(mInputChannel, /*key?*/false, /*RGB?*/isFrameRGB));
1444 
1445  conns.clear();
1446  if (isInputRGB && !isFrameRGB)
1447  {
1448  conns.insert(NTV2Connection(fbIXpt, cscOXpt)); // FB <== CSC
1449  conns.insert(NTV2Connection(cscVidIXpt, inputOXpt)); // CSC <== SDIIn/HDMIin
1450  }
1451  else if (!isInputRGB && isFrameRGB)
1452  {
1453  conns.insert(NTV2Connection(fbIXpt, cscOXpt)); // FB <== CSC
1454  conns.insert(NTV2Connection(cscVidIXpt, inputOXpt)); // CSC <== SDIIn/HDMIIn
1455  }
1456  else
1457  conns.insert(NTV2Connection(fbIXpt, inputOXpt)); // FB <== SDIIn/HDMIin
1458 
1459  return !conns.empty();
1460 }
1461 
1462 bool NTV2VCAM::GetInputRouting4K(NTV2XptConnections& conns, const bool isInputRGB)
1463 {
1464  UWord sdi(0), mux(0), csc(0), fb(0), path(0);
1467  const bool isFrameRGB(::IsRGBFormat(mPixelFormat));
1468  conns.clear();
1469  if (NTV2_INPUT_SOURCE_IS_HDMI(mInputSource))
1470  { // HDMI
1471  if (mDevice.features().CanDo12gRouting())
1472  { // FB <== SDIIn
1474  out = ::GetInputSourceOutputXpt(mInputSource);
1475  conns.insert(NTV2Connection(in, out));
1476  }
1477  else
1478  {
1480  { // HDMI CH1234
1481  if (isInputRGB == isFrameRGB)
1482  { // HDMI CH1234 RGB SIGNAL AND RGB FBF OR YUV SIGNAL AND YUV FBF
1483  for (path = 0; path < 4; path++)
1484  { // MUX <== HDMIIn
1485  in = ::GetTSIMuxInputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1);
1486  out = ::GetInputSourceOutputXpt(mInputSource, /*DS2*/false, isInputRGB, /*quadrant*/path);
1487  conns.insert(NTV2Connection(in, out));
1488  // FB <== MUX
1489  in = ::GetFrameBufferInputXptFromChannel(NTV2Channel(fb + path / 2), /*Binput*/path & 1);
1490  out = ::GetTSIMuxOutputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1, /*RGB*/isInputRGB);
1491  conns.insert(NTV2Connection(in, out));
1492  }
1493  } // HDMI CH1234 RGB SIGNAL AND RGB FBF
1494  else if (isInputRGB && !isFrameRGB)
1495  { // HDMI CH1234 RGB SIGNAL AND YUV FBF
1496  for (path = 0; path < 4; path++)
1497  {
1498  // CSC <== HDMIIn
1499  in = ::GetCSCInputXptFromChannel(NTV2Channel(csc + path));
1500  out = ::GetInputSourceOutputXpt(mInputSource, /*DS2*/false, isInputRGB, /*quadrant*/path);
1501  conns.insert(NTV2Connection(in, out));
1502  // MUX <== CSC
1503  in = ::GetTSIMuxInputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1);
1504  out = ::GetCSCOutputXptFromChannel(NTV2Channel(csc + path), /*key*/false, /*rgb*/isFrameRGB);
1505  conns.insert(NTV2Connection(in, out));
1506  // FB <== MUX
1507  in = ::GetFrameBufferInputXptFromChannel(NTV2Channel(fb + path / 2), /*DS2*/path & 1);
1508  out = ::GetTSIMuxOutputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1, /*rgb*/isFrameRGB);
1509  conns.insert(NTV2Connection(in, out));
1510  }
1511  } // HDMI CH1234 RGB SIGNAL AND YUV FBF
1512  else // !isInputRGB && isFrameRGB
1513  { // HDMI CH1234 YUV SIGNAL AND RGB FBF
1514  for (path = 0; path < 4; path++)
1515  {
1516  // CSC <== HDMIIn
1517  in = ::GetCSCInputXptFromChannel(NTV2Channel(csc + path));
1518  out = ::GetInputSourceOutputXpt(mInputSource, /*DS2*/false, isInputRGB, /*quadrant*/path);
1519  conns.insert(NTV2Connection(in, out));
1520  // MUX <== CSC
1521  in = ::GetTSIMuxInputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1);
1522  out = ::GetCSCOutputXptFromChannel(NTV2Channel(csc + path), /*key*/false, /*rgb*/isFrameRGB);
1523  conns.insert(NTV2Connection(in, out));
1524  // FB <== MUX
1525  in = ::GetFrameBufferInputXptFromChannel(NTV2Channel(fb + path / 2), /*DS2*/path & 1);
1526  out = ::GetTSIMuxOutputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1, /*rgb*/isFrameRGB);
1527  conns.insert(NTV2Connection(in, out));
1528  }
1529  } // HDMI CH1234 YUV SIGNAL AND RGB FBF
1530  } // HDMI CH1234
1531  else
1532  { // HDMI CH5678
1533  cerr << "## ERROR (" << errno << "): Ch5678 must be for Corvid88, but no HDMI on that device" << endl;
1534  } // HDMI CH5678
1535  }
1536  } // HDMI
1537  else
1538  { // SDI
1539  if (mDevice.features().CanDo12gRouting())
1540  { // FB <== SDIIn
1542  out = ::GetInputSourceOutputXpt(mInputSource);
1543  conns.insert(NTV2Connection(in, out));
1544  }
1545  else
1546  { // SDI CH1234 or CH5678
1548  {
1549  fb = 4; sdi = fb; mux = fb / 2; csc = fb;
1550  }
1551  if (isFrameRGB)
1552  { // RGB FB
1553  if (mDoTSIRouting)
1554  { // SDI CH1234 RGB TSI
1555  for (path = 0; path < 4; path++)
1556  {
1557  // CSC <== SDIIn
1558  in = ::GetCSCInputXptFromChannel(NTV2Channel(csc + path));
1560  conns.insert(NTV2Connection(in, out));
1561  // MUX <== CSC
1562  in = ::GetTSIMuxInputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1);
1563  out = ::GetCSCOutputXptFromChannel(NTV2Channel(csc + path), /*key*/false, /*rgb*/isFrameRGB);
1564  conns.insert(NTV2Connection(in, out));
1565  // FB <== MUX
1566  in = ::GetFrameBufferInputXptFromChannel(NTV2Channel(fb + path / 2), /*DS2*/path & 1);
1567  out = ::GetTSIMuxOutputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1, /*rgb*/isFrameRGB);
1568  conns.insert(NTV2Connection(in, out));
1569  } // for each spigot
1570  } // SDI CH1234 RGB TSI
1571  else
1572  { // SDI CH1234 RGB SQUARES
1573  for (path = 0; path < 4; path++)
1574  {
1575  // CSC <== SDIIn
1576  in = ::GetCSCInputXptFromChannel(NTV2Channel(csc + path));
1578  conns.insert(NTV2Connection(in, out));
1579  // FB <== CSC
1581  out = ::GetCSCOutputXptFromChannel(NTV2Channel(csc + path), /*key*/false, /*rgb*/isFrameRGB);
1582  conns.insert(NTV2Connection(in, out));
1583  } // for each spigot
1584  } // SDI CH1234 RGB SQUARES
1585  } // SDI CH1234 RGB FBF
1586  else // YUV FBF
1587  {
1588  if (mDoTSIRouting)
1589  { // SDI CH1234 YUV TSI
1590  for (path = 0; path < 4; path++)
1591  {
1592  // MUX <== SDIIn
1593  in = ::GetTSIMuxInputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1);
1595  conns.insert(NTV2Connection(in, out));
1596  // FB <== MUX
1597  in = ::GetFrameBufferInputXptFromChannel(NTV2Channel(fb + path / 2), /*DS2*/path & 1);
1598  out = ::GetTSIMuxOutputXptFromChannel(NTV2Channel(mux + path / 2), /*LinkB*/path & 1, /*rgb*/isFrameRGB);
1599  conns.insert(NTV2Connection(in, out));
1600  } // for each spigot
1601  } // SDI CH1234 YUV TSI
1602  else
1603  {
1604  for (path = 0; path < 4; path++)
1605  { // FB <== SDIIn
1608  conns.insert(NTV2Connection(in, out));
1609  } // for each path
1610  } // SDI CH1234 YUV SQUARES
1611  } // YUV FBF
1612  } // 3G SDI CH1234 or CH5678
1613  } // SDI
1614  return !conns.empty();
1615 }
1616 
1617 #if defined(AJALinux)
1618  int NTV2VCAM::ExtractNumber(const char* str)
1619  {
1620  string s(str);
1621  int i = s.length() - 1;
1622  while (i >= 0 && isdigit(s[i]))
1623  i--;
1624  return stoi(s.substr(i + 1));
1625  }
1626 #endif // AJALinux
1627 
1628 int NTV2VCAM::GetFps()
1629 {
1631  mDevice.GetFrameRate(frameRate, mInputChannel);
1632  switch (frameRate)
1633  {
1634  case NTV2_FRAMERATE_1500:
1635  case NTV2_FRAMERATE_1498: return 15;
1636 
1637  case NTV2_FRAMERATE_2500: return 25;
1638 
1639  case NTV2_FRAMERATE_3000:
1640  case NTV2_FRAMERATE_2997: return 30;
1641 
1642  case NTV2_FRAMERATE_4800:
1643  case NTV2_FRAMERATE_4795: return 48;
1644 
1645  case NTV2_FRAMERATE_5000: return 50;
1646 
1647  case NTV2_FRAMERATE_5994:
1648  case NTV2_FRAMERATE_6000: return 60;
1649 
1650  case NTV2_FRAMERATE_12000:
1651  case NTV2_FRAMERATE_11988: return 120;
1652 
1653  default: break;
1654  }
1655  return 24;
1656 }
1657 
1658 #if defined(AJA_WINDOWS)
1659  EnumPins::EnumPins(NTV2VCAM* filter_, EnumPins* pEnum)
1660  : mpFilter(filter_)
1661  , mCurPin(pEnum ? pEnum->mCurPin : 0)
1662  {
1663  }
1664 
1665  STDMETHODIMP EnumPins::QueryInterface(REFIID riid, void** ppv)
1666  {
1667  if (!ppv)
1668  return E_POINTER;
1669 
1670  if (riid == IID_IUnknown || riid == IID_IEnumPins)
1671  {
1672  *ppv = static_cast<IEnumPins*>(this);
1673  AddRef();
1674  return S_OK;
1675  }
1676 
1677  *ppv = nullptr;
1678  return E_NOINTERFACE;
1679  }
1680 
1681  STDMETHODIMP_(ULONG) EnumPins::AddRef()
1682  {
1683  return (ULONG)InterlockedIncrement(&mRefCount);
1684  }
1685 
1686  STDMETHODIMP_(ULONG) EnumPins::Release()
1687  {
1688  long ref = InterlockedDecrement(&mRefCount);
1689  if (ref == 0)
1690  {
1691  delete this;
1692  return 0;
1693  }
1694 
1695  return ref;
1696  }
1697 
1698  STDMETHODIMP EnumPins::Next(ULONG cPins, IPin * *ppPins, ULONG * pcFetched)
1699  {
1700  if (!ppPins || (cPins > 1 && !pcFetched))
1701  return E_POINTER;
1702 
1703  ULONG fetched = 0;
1704  for (int i = 0; i < cPins && mCurPin < mpFilter->GetPinCount(); ++i)
1705  {
1706  IPin* pPin = mpFilter->GetPin(mCurPin);
1707  if (!pPin)
1708  return S_FALSE;
1709 
1710  ppPins[fetched++] = pPin;
1711  pPin->AddRef();
1712  mCurPin++;
1713  }
1714 
1715  if (pcFetched)
1716  *pcFetched = fetched;
1717 
1718  return fetched == cPins ? S_OK : S_FALSE;
1719  }
1720 
1721  STDMETHODIMP EnumPins::Skip(ULONG cPins)
1722  {
1723  mCurPin += cPins;
1724  if (mCurPin >= mpFilter->GetPinCount())
1725  {
1726  mCurPin = mpFilter->GetPinCount();
1727  return S_FALSE;
1728  }
1729  return S_OK;
1730  }
1731 
1732  STDMETHODIMP EnumPins::Reset()
1733  {
1734  mCurPin = 0;
1735  return S_OK;
1736  }
1737 
1738  STDMETHODIMP EnumPins::Clone(IEnumPins * *ppEnum)
1739  {
1740  if (!ppEnum)
1741  return E_POINTER;
1742 
1743  EnumPins* pNew = new EnumPins(mpFilter, this);
1744  if (!pNew)
1745  return E_OUTOFMEMORY;
1746 
1747  pNew->AddRef();
1748  *ppEnum = pNew;
1749  return S_OK;
1750  }
1751 
1752  EnumMediaTypes::EnumMediaTypes(OutputVideoPin * pin_) : pin(pin_)
1753  {
1754  }
1755 
1756  STDMETHODIMP EnumMediaTypes::QueryInterface(REFIID riid, void** ppv)
1757  {
1758  if (riid == IID_IUnknown || riid == IID_IEnumMediaTypes)
1759  {
1760  AddRef();
1761  *ppv = static_cast<IEnumMediaTypes*>(this);
1762  return NOERROR;
1763  }
1764 
1765  *ppv = nullptr;
1766  return E_NOINTERFACE;
1767  }
1768 
1769  STDMETHODIMP_(ULONG) EnumMediaTypes::AddRef()
1770  {
1771  return (ULONG)InterlockedIncrement(&mRefCount);
1772  }
1773 
1774  STDMETHODIMP_(ULONG) EnumMediaTypes::Release()
1775  {
1776  long ref = InterlockedDecrement(&mRefCount);
1777  if (ref == 0)
1778  {
1779  delete this;
1780  return 0;
1781  }
1782  return ref;
1783  }
1784 
1785  STDMETHODIMP EnumMediaTypes::Next(ULONG cMediaTypes, AM_MEDIA_TYPE** ppMediaTypes, ULONG * pcFetched)
1786  {
1787  UINT nFetched = 0;
1788  if (curMT == 0 && cMediaTypes > 0)
1789  {
1790  AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
1791  if (!pmt)
1792  return E_OUTOFMEMORY;
1793 
1794  ZeroMemory(pmt, sizeof(AM_MEDIA_TYPE));
1795  CMediaType mt;
1796  HRESULT hr = pin->GetMediaType(&mt);
1797  if (FAILED(hr))
1798  {
1799  CoTaskMemFree(pmt);
1800  pmt = nullptr;
1801  return hr == VFW_S_NO_MORE_ITEMS ? S_FALSE : hr;
1802  }
1803  CopyMediaType(pmt, &mt);
1804 
1805  ppMediaTypes[0] = pmt;
1806  nFetched = 1;
1807  curMT++;
1808  }
1809 
1810  if (pcFetched)
1811  *pcFetched = nFetched;
1812 
1813  return (nFetched == cMediaTypes) ? S_OK : S_FALSE;
1814  }
1815 
1816  STDMETHODIMP EnumMediaTypes::Skip(ULONG cMediaTypes)
1817  {
1818  if ((curMT + cMediaTypes) > 1)
1819  {
1820  curMT = 1;
1821  return S_FALSE;
1822  }
1823  curMT += cMediaTypes;
1824  return S_OK;
1825  }
1826 
1827  STDMETHODIMP EnumMediaTypes::Reset()
1828  {
1829  curMT = 0;
1830  return S_OK;
1831  }
1832 
1833  STDMETHODIMP EnumMediaTypes::Clone(IEnumMediaTypes** ppEnum)
1834  {
1835  if (!ppEnum)
1836  return E_POINTER;
1837 
1838  EnumMediaTypes* pNew = new EnumMediaTypes(pin);
1839  if (!pNew)
1840  return E_OUTOFMEMORY;
1841 
1842  pNew->curMT = curMT;
1843  pNew->AddRef();
1844  *ppEnum = pNew;
1845  return S_OK;
1846  }
1847 #endif // defined(AJA_WINDOWS)
CNTV2Card::SubscribeOutputVerticalEvent
virtual bool SubscribeOutputVerticalEvent(const NTV2Channel inChannel)
Causes me to be notified when an output vertical blanking interrupt is generated for the given output...
Definition: ntv2subscriptions.cpp:25
CNTV2Card::SetVANCMode
virtual bool SetVANCMode(const NTV2VANCMode inVancMode, const NTV2Channel inChannel=NTV2_CHANNEL1)
Sets the VANC mode for the given FrameStore.
Definition: ntv2register.cpp:2703
AJA_VW_SETFRAMEBUFFERFORMATFAILED
#define AJA_VW_SETFRAMEBUFFERFORMATFAILED
Definition: ntv2vcam.h:74
NTV2_FORMAT_4x1920x1080p_6000
@ NTV2_FORMAT_4x1920x1080p_6000
Definition: ntv2enums.h:612
CNTV2Card::SetMultiFormatMode
virtual bool SetMultiFormatMode(const bool inEnable)
Enables or disables multi-format (per channel) device operation. If enabled, each device channel can ...
Definition: ntv2register.cpp:4428
NTV2ChannelToInputSource
NTV2InputSource NTV2ChannelToInputSource(const NTV2Channel inChannel, const NTV2IOKinds inKinds=NTV2_IOKINDS_SDI)
Definition: ntv2utils.cpp:5129
NTV2_FORMAT_1080psf_2398
@ NTV2_FORMAT_1080psf_2398
Definition: ntv2enums.h:548
NTV2InputSourceToChannel
NTV2Channel NTV2InputSourceToChannel(const NTV2InputSource inInputSource)
Converts a given NTV2InputSource to its equivalent NTV2Channel value.
Definition: ntv2utils.cpp:5044
CMediaType::Format
BYTE * Format() const
Definition: mtype.h:55
NTV2_AUDIO_LOOPBACK_OFF
@ NTV2_AUDIO_LOOPBACK_OFF
Embeds silence (zeroes) into the data stream.
Definition: ntv2enums.h:2026
AJA_VW_MISSINGARGS
#define AJA_VW_MISSINGARGS
Definition: ntv2vcam.h:97
AJA_VW_ACSTARTFAILED
#define AJA_VW_ACSTARTFAILED
Definition: ntv2vcam.h:78
AUTOCIRCULATE_TRANSFER::GetCapturedAudioByteCount
ULWord GetCapturedAudioByteCount(void) const
Definition: ntv2publicinterface.h:8669
NTV2_FOURCC
#define NTV2_FOURCC(_a_, _b_, _c_, _d_)
Definition: ntv2publicinterface.h:5623
AJA_VW_APPLYSIGNALROUTEFAILED
#define AJA_VW_APPLYSIGNALROUTEFAILED
Definition: ntv2vcam.h:76
poptOption
Definition: options_popt.h:148
gDemoAppSignature
static const ULWord gDemoAppSignature((((uint32_t)( 'V'))<< 24)|(((uint32_t)( 'C'))<< 16)|(((uint32_t)( 'A'))<< 8)|(((uint32_t)( 'M'))<< 0))
AJA_VW_GETINPUTROUTEFAILED
#define AJA_VW_GETINPUTROUTEFAILED
Definition: ntv2vcam.h:95
AJA_VW_V4L2DEVICECREATEFAILED
#define AJA_VW_V4L2DEVICECREATEFAILED
Definition: ntv2vcam.h:83
AJA_VW_SETTSIFRAMEENABLEFAILED
#define AJA_VW_SETTSIFRAMEENABLEFAILED
Definition: ntv2vcam.h:72
CNTV2Card::SetVideoFormat
virtual bool SetVideoFormat(const NTV2VideoFormat inVideoFormat, const bool inIsAJARetail=(!(0)), const bool inKeepVancSettings=(0), const NTV2Channel inChannel=NTV2_CHANNEL1)
Configures the AJA device to handle a specific video format.
Definition: ntv2register.cpp:204
v4l2_loopback_config::output_nr
int output_nr
Definition: v4l2loopback.h:35
CNTV2Card::Set4kSquaresEnable
virtual bool Set4kSquaresEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 "2K quadrants" mode for the given FrameStore bank on the device....
Definition: ntv2register.cpp:1238
CNTV2DemoCommon::GetPixelFormatFromString
static NTV2PixelFormat GetPixelFormatFromString(const std::string &inStr, const NTV2PixelFormatKinds inKinds=PIXEL_FORMATS_ALL, const std::string inDevSpec=std::string())
Returns the NTV2PixelFormat that matches the given string.
Definition: ntv2democommon.cpp:599
NTV2LHIHDMIColorSpace
NTV2LHIHDMIColorSpace
Definition: ntv2enums.h:3663
NTV2FormatDescriptor
Describes a video frame for a given video standard or format and pixel format, including the total nu...
Definition: ntv2formatdescriptor.h:41
NTV2_FRAMERATE_1500
@ NTV2_FRAMERATE_1500
15 frames per second
Definition: ntv2enums.h:424
CMediaType::Type
const GUID * Type() const
Definition: mtype.h:39
AUTOCIRCULATE_TRANSFER::SetAudioBuffer
bool SetAudioBuffer(ULWord *pInAudioBuffer, const ULWord inAudioByteCount)
Sets my audio buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2900
NTV2_FRAMERATE_6000
@ NTV2_FRAMERATE_6000
60 frames per second
Definition: ntv2enums.h:411
NULL
#define NULL
Definition: ntv2caption608types.h:19
NTV2Channel
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They're also commonly use...
Definition: ntv2enums.h:1353
NTV2Buffer
Describes a user-space buffer on the host computer. I have an address and a length,...
Definition: ntv2publicinterface.h:6216
NTV2Buffer::GetByteCount
ULWord GetByteCount(void) const
Definition: ntv2publicinterface.h:6290
NTV2_FRAMERATE_2997
@ NTV2_FRAMERATE_2997
Fractional rate of 30,000 frames per 1,001 seconds.
Definition: ntv2enums.h:415
AJA_VW_WAITFOROUTPUTVERTICALINTERRUPTFAILED
#define AJA_VW_WAITFOROUTPUTVERTICALINTERRUPTFAILED
Definition: ntv2vcam.h:66
AJA_VW_AJADEVICENOCAPTURE
#define AJA_VW_AJADEVICENOCAPTURE
Definition: ntv2vcam.h:55
WAVE_FORMAT_EXTENSIBLE
#define WAVE_FORMAT_EXTENSIBLE
Definition: streams.h:79
NAME
#define NAME(_x_)
Definition: wxdebug.h:179
CNTV2Card::GetHDMIInputColor
virtual bool GetHDMIInputColor(NTV2LHIHDMIColorSpace &outValue, const NTV2Channel inHDMIInput=NTV2_CHANNEL1)
Answers with the current colorspace for the given HDMI input.
Definition: ntv2hdmi.cpp:70
CSourceStream
Definition: source.h:88
CNTV2Card::WaitForInputVerticalInterrupt
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 ...
Definition: ntv2subscriptions.cpp:149
CNTV2Card::EnableInputInterrupt
virtual bool EnableInputInterrupt(const NTV2Channel channel=NTV2_CHANNEL1)
Allows the CNTV2Card instance to wait for and respond to input vertical blanking interrupts originati...
Definition: ntv2interrupts.cpp:23
NTV2_AUDIO_48K
@ NTV2_AUDIO_48K
Definition: ntv2enums.h:1926
NTV2_FRAMERATE_12000
@ NTV2_FRAMERATE_12000
120 frames per second
Definition: ntv2enums.h:422
CreateMediaType
AM_MEDIA_TYPE *WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc)
Definition: mtype.cpp:371
AJA_STATUS_BUSY
@ AJA_STATUS_BUSY
Definition: types.h:391
CNTV2DeviceScanner::GetFirstDeviceFromArgument
static bool GetFirstDeviceFromArgument(const std::string &inArgument, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the AJA device that matches a command li...
Definition: ntv2devicescanner.cpp:338
v4l2_loopback_config
Definition: v4l2loopback.h:19
v4l2_loopback_config::card_label
char card_label[32]
Definition: v4l2loopback.h:42
NTV2_FRAMERATE_INVALID
@ NTV2_FRAMERATE_INVALID
Definition: ntv2enums.h:437
CAutoLock
Definition: wxutil.h:83
appPID
int32_t appPID(0)
NTV2_AUDIOSYSTEM_1
@ NTV2_AUDIOSYSTEM_1
This identifies the first Audio System.
Definition: ntv2enums.h:3882
WAVEFORMATEXTENSIBLE::SubFormat
GUID SubFormat
Definition: streams.h:74
NTV2InputSourceToEmbeddedAudioInput
NTV2EmbeddedAudioInput NTV2InputSourceToEmbeddedAudioInput(const NTV2InputSource inInputSource)
Converts a given NTV2InputSource to its equivalent NTV2EmbeddedAudioInput value.
Definition: ntv2utils.cpp:4874
AJA_VW_V4L2DRIVEROPENFAILED
#define AJA_VW_V4L2DRIVEROPENFAILED
Definition: ntv2vcam.h:82
NTV2_FORMAT_1080p_2K_3000
@ NTV2_FORMAT_1080p_2K_3000
Definition: ntv2enums.h:625
NTV2_FORMAT_4x2048x1080p_2997
@ NTV2_FORMAT_4x2048x1080p_2997
Definition: ntv2enums.h:606
CNTV2Card::AutoCirculateInitForInput
virtual bool AutoCirculateInitForInput(const NTV2Channel inChannel, const UWord inFrameCount=7, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_INVALID, const ULWord inOptionFlags=0, const UByte inNumChannels=1, const UWord inStartFrameNumber=0, const UWord inEndFrameNumber=0)
Prepares for subsequent AutoCirculate ingest, designating a contiguous block of frame buffers on the ...
Definition: ntv2autocirculate.cpp:221
CNTV2MacDriverInterface::ReleaseStreamForApplication
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
Definition: ntv2macdriverinterface.cpp:540
NTV2_FORMAT_4x1920x1080p_2997
@ NTV2_FORMAT_4x1920x1080p_2997
Definition: ntv2enums.h:602
NTV2_FORMAT_4x1920x1080p_2500
@ NTV2_FORMAT_4x1920x1080p_2500
Definition: ntv2enums.h:595
STDMETHODIMP_
STDMETHODIMP_(ULONG) CUnknown
Definition: combase.cpp:163
AUTOCIRCULATE_WITH_MULTILINK_AUDIO3
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO3
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 3.
Definition: ntv2publicinterface.h:5715
AJA_VW_V4L2DEVICEOPENFAILED
#define AJA_VW_V4L2DEVICEOPENFAILED
Definition: ntv2vcam.h:84
mVideoFormat
mVideoFormat
Definition: ntv2vcam.cpp:801
aja::stoi
int stoi(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:122
ntv2vcam.h
Header file for NTV2VCAM demonstration class.
NTV2Buffer::Allocate
bool Allocate(const size_t inByteCount, const bool inPageAligned=false)
Allocates (or re-allocates) my user-space storage using the given byte count. I assume full responsib...
Definition: ntv2publicinterface.cpp:1810
NTV2_LHIHDMIColorSpaceRGB
@ NTV2_LHIHDMIColorSpaceRGB
Definition: ntv2enums.h:3666
CNTV2Card::ApplySignalRoute
virtual bool ApplySignalRoute(const CNTV2SignalRouter &inRouter, const bool inReplace=(0))
Applies the given routing table to the AJA device.
Definition: ntv2regroute.cpp:277
NTV2_IS_8K_VIDEO_FORMAT
#define NTV2_IS_8K_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:889
NTV2InputXptID
enum NTV2InputCrosspointID NTV2InputXptID
NTV2_OUTPUT_CROSSPOINT_INVALID
@ NTV2_OUTPUT_CROSSPOINT_INVALID
Definition: ntv2enums.h:2708
mPixelFormat
mPixelFormat
Definition: ntv2vcam.cpp:710
CNTV2Card::SetAudioLoopBack
virtual bool SetAudioLoopBack(const NTV2AudioLoopBack inMode, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Enables or disables NTV2AudioLoopBack mode for the given NTV2AudioSystem.
Definition: ntv2audio.cpp:300
NTV2_CHANNEL1
@ NTV2_CHANNEL1
Specifies channel or FrameStore 1 (or the first item).
Definition: ntv2enums.h:1355
CMediaType
Definition: mtype.h:18
CNTV2Card::SetFrameBufferFormat
virtual bool SetFrameBufferFormat(NTV2Channel inChannel, NTV2FrameBufferFormat inNewFormat, bool inIsAJARetail=(!(0)), NTV2HDRXferChars inXferChars=NTV2_VPID_TC_SDR_TV, NTV2HDRColorimetry inColorimetry=NTV2_VPID_Color_Rec709, NTV2HDRLuminance inLuminance=NTV2_VPID_Luminance_YCbCr)
Sets the frame buffer format for the given FrameStore on the AJA device.
Definition: ntv2register.cpp:1856
CNTV2Card::SetSDITransmitEnable
virtual bool SetSDITransmitEnable(const NTV2Channel inChannel, const bool inEnable)
Sets the specified bidirectional SDI connector to act as an input or an output.
Definition: ntv2register.cpp:3859
CopyMediaType
HRESULT WINAPI CopyMediaType(__out AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource)
Definition: mtype.cpp:397
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::void
j template void())
Definition: json.hpp:4893
POPT_ARG_INT
#define POPT_ARG_INT
Definition: options_popt.h:58
NTV2_FRAMERATE_2500
@ NTV2_FRAMERATE_2500
25 frames per second
Definition: ntv2enums.h:416
WAVEFORMATEXTENSIBLE
Definition: streams.h:65
NTV2FrameRate
NTV2FrameRate
Identifies a particular video frame rate.
Definition: ntv2enums.h:408
AJA_VW_CONFIGAUDIOSYSTEMFAILED
#define AJA_VW_CONFIGAUDIOSYSTEMFAILED
Definition: ntv2vcam.h:90
NTV2InputSourceToAudioSystem
NTV2AudioSystem NTV2InputSourceToAudioSystem(const NTV2InputSource inInputSource)
Converts a given NTV2InputSource to its equivalent NTV2AudioSystem value.
Definition: ntv2utils.cpp:5068
CNTV2Card::SetAudioSystemInputSource
virtual bool SetAudioSystemInputSource(const NTV2AudioSystem inAudioSystem, const NTV2AudioSource inAudioSource, const NTV2EmbeddedAudioInput inEmbeddedInput)
Sets the audio source for the given NTV2AudioSystem on the device.
Definition: ntv2audio.cpp:485
AJA_VW_SETSDITRANSITENABLEFAILED
#define AJA_VW_SETSDITRANSITENABLEFAILED
Definition: ntv2vcam.h:65
NTV2_FRAMERATE_4800
@ NTV2_FRAMERATE_4800
48 frames per second
Definition: ntv2enums.h:420
WAVEFORMATEXTENSIBLE::wValidBitsPerSample
WORD wValidBitsPerSample
Definition: streams.h:68
NTV2_IS_4K_VIDEO_FORMAT
#define NTV2_IS_4K_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:779
CNTV2Card::DMABufferLock
virtual bool DMABufferLock(const NTV2Buffer &inBuffer, bool inMap=(0), bool inRDMA=(0))
Page-locks the given host buffer to reduce transfer time and CPU usage of DMA transfers.
Definition: ntv2dma.cpp:429
AJA_VW_SETCAPTUREMODEFAILED
#define AJA_VW_SETCAPTUREMODEFAILED
Definition: ntv2vcam.h:68
AUTOCIRCULATE_WITH_MULTILINK_AUDIO1
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO1
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 1.
Definition: ntv2publicinterface.h:5713
AJA_VW_GETPOINTERFAILED
#define AJA_VW_GETPOINTERFAILED
Definition: ntv2vcam.h:98
NTV2_CHANNEL5
@ NTV2_CHANNEL5
Specifies channel or FrameStore 5 (or the 5th item).
Definition: ntv2enums.h:1359
NTV2MakeAudioSystemSet
NTV2AudioSystemSet NTV2MakeAudioSystemSet(const NTV2AudioSystem inFirstAudioSystem, const UWord inCount=1)
Definition: ntv2publicinterface.cpp:3634
CNTV2Card::features
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:148
NTV2_FORMAT_4x2048x1080p_2398
@ NTV2_FORMAT_4x2048x1080p_2398
Definition: ntv2enums.h:599
POPT_AUTOHELP
#define POPT_AUTOHELP
Definition: options_popt.h:220
AJA_VW_V4L2DEVICEREMOVEFAILED
#define AJA_VW_V4L2DEVICEREMOVEFAILED
Definition: ntv2vcam.h:88
CNTV2Card::GetDisplayName
virtual std::string GetDisplayName(void)
Answers with this device's display name.
Definition: ntv2card.cpp:86
AJA_VW_ACSETVIDEOBUFFERFAILED
#define AJA_VW_ACSETVIDEOBUFFERFAILED
Definition: ntv2vcam.h:79
connections
NTV2XptConnections connections
Definition: ntv2vcam.cpp:1011
AJA_VW_ACINITFORINPUTFAILED
#define AJA_VW_ACINITFORINPUTFAILED
Definition: ntv2vcam.h:77
NTV2_FORMAT_1080p_5994_B
@ NTV2_FORMAT_1080p_5994_B
Definition: ntv2enums.h:561
NTV2_FORMAT_1080p_2K_2400
@ NTV2_FORMAT_1080p_2K_2400
Definition: ntv2enums.h:556
NTV2_FORMAT_4x2048x1080p_3000
@ NTV2_FORMAT_4x2048x1080p_3000
Definition: ntv2enums.h:607
NTV2_AUDIOSYSTEM_2
@ NTV2_AUDIOSYSTEM_2
This identifies the 2nd Audio System.
Definition: ntv2enums.h:3883
NTV2_VANCMODE_OFF
@ NTV2_VANCMODE_OFF
This identifies the mode in which there are no VANC lines in the frame buffer.
Definition: ntv2enums.h:3784
ULWord
uint32_t ULWord
Definition: ajatypes.h:276
pName
CHAR * pName
Definition: amvideo.cpp:26
CMediaType::FormatType
const GUID * FormatType() const
Definition: mtype.h:59
CNTV2Card::EnableChannels
virtual bool EnableChannels(const NTV2ChannelSet &inChannels, const bool inDisableOthers=(0))
Enables the given FrameStore(s).
Definition: ntv2register.cpp:2170
WAVEFORMATEXTENSIBLE::Samples
union WAVEFORMATEXTENSIBLE::@35 Samples
AUTOCIRCULATE_STATUS
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
Definition: ntv2publicinterface.h:7405
WAVEFORMATEXTENSIBLE::dwChannelMask
DWORD dwChannelMask
Definition: streams.h:72
NTV2_CHANNEL7
@ NTV2_CHANNEL7
Specifies channel or FrameStore 7 (or the 7th item).
Definition: ntv2enums.h:1361
NTV2_FORMAT_1080p_2997
@ NTV2_FORMAT_1080p_2997
Definition: ntv2enums.h:550
inputColorSpace
NTV2LHIHDMIColorSpace inputColorSpace(NTV2_LHIHDMIColorSpaceYCbCr)
NTV2_FRAMERATE_1498
@ NTV2_FRAMERATE_1498
Fractional rate of 15,000 frames per 1,001 seconds.
Definition: ntv2enums.h:425
CNTV2MacDriverInterface::GetStreamingApplication
virtual bool GetStreamingApplication(ULWord &outAppType, int32_t &outProcessID)
Answers with the four-CC type and process ID of the application that currently "owns" the AJA device ...
Definition: ntv2macdriverinterface.cpp:675
CNTV2Card::SetMode
virtual bool SetMode(const NTV2Channel inChannel, const NTV2Mode inNewValue, const bool inIsRetail=(!(0)))
Determines if a given FrameStore on the AJA device will be used to capture or playout video.
Definition: ntv2register.cpp:1625
NTV2_FORMAT_1080p_3000
@ NTV2_FORMAT_1080p_3000
Definition: ntv2enums.h:551
gAudMaxSizeBytes
static const uint32_t gAudMaxSizeBytes(256 *1024)
NTV2_FORMAT_1080p_2500
@ NTV2_FORMAT_1080p_2500
Definition: ntv2enums.h:552
NTV2AudioSystemSet
std::set< NTV2AudioSystem > NTV2AudioSystemSet
A set of distinct NTV2AudioSystem values. New in SDK 16.2.
Definition: ntv2publicinterface.h:3984
AJA_VW_SAMPLEBUFFERSIZEMISMATCH
#define AJA_VW_SAMPLEBUFFERSIZEMISMATCH
Definition: ntv2vcam.h:99
SignalHandler
static void SignalHandler(int inSignal)
Definition: ntv2vcam.cpp:14
mInputChannel
mInputChannel
Definition: ntv2vcam.cpp:1010
AJA_VW_SUBSCRIBEINPUTVERTICALEVENTFAILED
#define AJA_VW_SUBSCRIBEINPUTVERTICALEVENTFAILED
Definition: ntv2vcam.h:63
V4L2LOOPBACK_CTL_ADD
#define V4L2LOOPBACK_CTL_ADD
Definition: v4l2loopback.h:87
GetCSCOutputXptFromChannel
NTV2OutputXptID GetCSCOutputXptFromChannel(const NTV2Channel inCSC, const bool inIsKey=false, const bool inIsRGB=false)
Definition: ntv2signalrouter.cpp:849
GetFrameBufferInputXptFromChannel
#define GetFrameBufferInputXptFromChannel
Definition: ntv2signalrouter.h:732
AJAProcess::GetPid
static uint64_t GetPid()
Definition: process.cpp:35
riid
__in REFIID riid
Definition: dllentry.cpp:192
NTV2_FORMAT_4x2048x1080p_5000
@ NTV2_FORMAT_4x2048x1080p_5000
Definition: ntv2enums.h:613
AJA_VW_AJADEVICENOPIXELFORMAT
#define AJA_VW_AJADEVICENOPIXELFORMAT
Definition: ntv2vcam.h:57
CNTV2DemoCommon::GetPixelFormatStrings
static std::string GetPixelFormatStrings(const NTV2PixelFormatKinds inKinds=PIXEL_FORMATS_ALL, const std::string inDevSpec=std::string())
Definition: ntv2democommon.cpp:567
AJA_VW_ACSETAUDIOBUFFERFAILED
#define AJA_VW_ACSETAUDIOBUFFERFAILED
Definition: ntv2vcam.h:80
NTV2_CHANNEL3
@ NTV2_CHANNEL3
Specifies channel or FrameStore 3 (or the 3rd item).
Definition: ntv2enums.h:1357
UWord
uint16_t UWord
Definition: ajatypes.h:274
CNTV2Card::AutoCirculateGetStatus
virtual bool AutoCirculateGetStatus(const NTV2Channel inChannel, AUTOCIRCULATE_STATUS &outStatus)
Returns the current AutoCirculate status for the given channel.
Definition: ntv2autocirculate.cpp:668
NTV2_IS_4K_HFR_VIDEO_FORMAT
#define NTV2_IS_4K_HFR_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:790
AJA_VW_ENABLECHANNELSFAILED
#define AJA_VW_ENABLECHANNELSFAILED
Definition: ntv2vcam.h:61
NTV2_FORMAT_4x1920x1080p_3000
@ NTV2_FORMAT_4x1920x1080p_3000
Definition: ntv2enums.h:603
gGlobalQuit
static bool gGlobalQuit((0))
NTV2_IS_VALID_INPUT_SOURCE
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1280
AJA_VW_SET4KSQUARESENABLEFAILED
#define AJA_VW_SET4KSQUARESENABLEFAILED
Definition: ntv2vcam.h:73
NTV2_FBF_8BIT_YCBCR
@ NTV2_FBF_8BIT_YCBCR
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:219
NTV2_REFERENCE_FREERUN
@ NTV2_REFERENCE_FREERUN
Specifies the device's internal clock.
Definition: ntv2enums.h:1455
CNTV2DemoCommon::Popt
Definition: ntv2democommon.h:849
NTV2_FORMAT_1080p_5000_B
@ NTV2_FORMAT_1080p_5000_B
Definition: ntv2enums.h:560
NTV2Version
std::string NTV2Version(const bool inDetailed=false)
Definition: ntv2version.cpp:41
NTV2_FORMAT_1080p_2K_5994_A
@ NTV2_FORMAT_1080p_2K_5994_A
Definition: ntv2enums.h:623
NTV2_INPUT_SOURCE_IS_HDMI
#define NTV2_INPUT_SOURCE_IS_HDMI(_inpSrc_)
Definition: ntv2enums.h:1277
AUTOCIRCULATE_TRANSFER::SetVideoBuffer
bool SetVideoBuffer(ULWord *pInVideoBuffer, const ULWord inVideoByteCount)
Sets my video buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2892
GetCSCInputXptFromChannel
NTV2InputXptID GetCSCInputXptFromChannel(const NTV2Channel inCSC, const bool inIsKeyInput=false)
Definition: ntv2signalrouter.cpp:805
NTV2_IS_HD_VIDEO_FORMAT
#define NTV2_IS_HD_VIDEO_FORMAT(__f__)
Definition: ntv2enums.h:733
AJA_VW_AJADEVICENOTREADY
#define AJA_VW_AJADEVICENOTREADY
Definition: ntv2vcam.h:54
NTV2Connection
std::pair< NTV2InputXptID, NTV2OutputXptID > NTV2Connection
This links an NTV2InputXptID and an NTV2OutputXptID.
Definition: ntv2signalrouter.h:38
CNTV2DriverInterface::IsDeviceReady
virtual bool IsDeviceReady(const bool inCheckValid=(0))
Definition: ntv2driverinterface.cpp:1348
AJA_VW_INVALIDPIXELFORMAT
#define AJA_VW_INVALIDPIXELFORMAT
Definition: ntv2vcam.h:56
NTV2_AUDIO_BUFFER_SIZE_4MB
@ NTV2_AUDIO_BUFFER_SIZE_4MB
Definition: ntv2enums.h:1913
retVal
else retVal
Definition: ntv2vcam.cpp:1100
AJA_VW_SETVANCMODEOFFFAILED
#define AJA_VW_SETVANCMODEOFFFAILED
Definition: ntv2vcam.h:71
CSource
Definition: source.h:43
NTV2_FORMAT_1080p_2K_2500
@ NTV2_FORMAT_1080p_2K_2500
Definition: ntv2enums.h:568
DeviceCapabilities::CanDoInputSource
bool CanDoInputSource(const NTV2InputSource inSrc)
Definition: ntv2devicecapabilities.h:237
CNTV2Card::SetTsiFrameEnable
virtual bool SetTsiFrameEnable(const bool inIsEnabled, const NTV2Channel inChannel)
Enables or disables SMPTE 425 two-sample interleave (Tsi) frame mode on the device.
Definition: ntv2register.cpp:1311
NTV2_FORMAT_1080p_6000_A
@ NTV2_FORMAT_1080p_6000_A
Definition: ntv2enums.h:567
NTV2_INPUTSOURCE_HDMI1
@ NTV2_INPUTSOURCE_HDMI1
Identifies the 1st HDMI video input.
Definition: ntv2enums.h:1261
AJA_VW_INCORRECTMULTILINKAUDIOCHANNEL
#define AJA_VW_INCORRECTMULTILINKAUDIOCHANNEL
Definition: ntv2vcam.h:75
CNTV2Card::GetInputVideoFormat
virtual NTV2VideoFormat GetInputVideoFormat(const NTV2InputSource inVideoSource=NTV2_INPUTSOURCE_SDI1, const bool inIsProgressive=(0))
Returns the video format of the signal that is present on the given input source.
Definition: ntv2register.cpp:3428
NTV2_FRAMERATE_11988
@ NTV2_FRAMERATE_11988
Fractional rate of 120,000 frames per 1,001 seconds.
Definition: ntv2enums.h:423
NTV2_FORMAT_1080p_2K_2398
@ NTV2_FORMAT_1080p_2K_2398
Definition: ntv2enums.h:555
CUnknown
Definition: combase.h:200
NTV2_FORMAT_1080p_2398
@ NTV2_FORMAT_1080p_2398
Definition: ntv2enums.h:553
AJA_VW_SETACFRAMERANGEFAILED
#define AJA_VW_SETACFRAMERANGEFAILED
Definition: ntv2vcam.h:96
NTV2_INPUT_CROSSPOINT_INVALID
@ NTV2_INPUT_CROSSPOINT_INVALID
Definition: ntv2enums.h:2885
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:220
NTV2_IS_VALID_CHANNEL
#define NTV2_IS_VALID_CHANNEL(__x__)
Definition: ntv2enums.h:1367
AJA_VW_INVALIDARGS
#define AJA_VW_INVALIDARGS
Definition: ntv2vcam.h:52
NTV2_INPUTSOURCE_HDMI2
@ NTV2_INPUTSOURCE_HDMI2
Identifies the 2nd HDMI video input.
Definition: ntv2enums.h:1262
NTV2_FORMAT_UNKNOWN
@ NTV2_FORMAT_UNKNOWN
Definition: ntv2enums.h:530
NTV2_IOKINDS_HDMI
@ NTV2_IOKINDS_HDMI
Specifies HDMI input/output kinds.
Definition: ntv2enums.h:1289
NTV2_IS_QUAD_QUAD_FORMAT
#define NTV2_IS_QUAD_QUAD_FORMAT(__f__)
Definition: ntv2enums.h:815
NTV2_FORMAT_4x1920x1080psf_2398
@ NTV2_FORMAT_4x1920x1080psf_2398
Definition: ntv2enums.h:590
NTV2_FORMAT_1080p_2K_6000_A
@ NTV2_FORMAT_1080p_2K_6000_A
Definition: ntv2enums.h:622
AJA_VW_INVALIDVIDEOFORMAT
#define AJA_VW_INVALIDVIDEOFORMAT
Definition: ntv2vcam.h:67
mFormatDesc
mFormatDesc
Definition: ntv2vcam.cpp:942
NTV2_LHIHDMIColorSpaceYCbCr
@ NTV2_LHIHDMIColorSpaceYCbCr
Definition: ntv2enums.h:3665
DEC
#define DEC(__x__)
Definition: ntv2publicinterface.h:5769
V4L2LOOPBACK_CTL_REMOVE
#define V4L2LOOPBACK_CTL_REMOVE
Definition: v4l2loopback.h:96
NTV2_FRAMERATE_5994
@ NTV2_FRAMERATE_5994
Fractional rate of 60,000 frames per 1,001 seconds.
Definition: ntv2enums.h:413
AJA_VW_NOTSISUPPORT
#define AJA_VW_NOTSISUPPORT
Definition: ntv2vcam.h:58
AUTOCIRCULATE_WITH_MULTILINK_AUDIO2
#define AUTOCIRCULATE_WITH_MULTILINK_AUDIO2
Use this to AutoCirculate with base audiosystem controlling base AudioSystem + 2.
Definition: ntv2publicinterface.h:5714
NTV2AudioSystemSetConstIter
NTV2AudioSystemSet::const_iterator NTV2AudioSystemSetConstIter
A handy const iterator into an NTV2AudioSystemSet. New in SDK 16.2.
Definition: ntv2publicinterface.h:3985
SetupAudio
SetupAudio()
AUTOCIRCULATE_STATUS::IsRunning
bool IsRunning(void) const
Definition: ntv2publicinterface.h:7545
NTV2_FORMAT_4x2048x1080p_2500
@ NTV2_FORMAT_4x2048x1080p_2500
Definition: ntv2enums.h:601
NTV2_FORMAT_4x1920x1080p_5994
@ NTV2_FORMAT_4x1920x1080p_5994
Definition: ntv2enums.h:611
CBasePin::Notify
STDMETHODIMP Notify(IBaseFilter *pSender, Quality q)
Definition: amfilter.cpp:2423
ULONG
ULONG(__stdcall *_RegisterTraceGuids)(__in IN WMIDPREQUEST RequestAddress
NTV2_MODE_CAPTURE
@ NTV2_MODE_CAPTURE
Capture (input) mode, which writes into device SDRAM.
Definition: ntv2enums.h:1239
AJA_VW_INVALIDINPUTSOURCE
#define AJA_VW_INVALIDINPUTSOURCE
Definition: ntv2vcam.h:60
NTV2XptConnections
std::map< NTV2InputXptID, NTV2OutputXptID > NTV2XptConnections
Definition: ntv2signalrouter.h:39
GetTSIMuxOutputXptFromChannel
NTV2OutputXptID GetTSIMuxOutputXptFromChannel(const NTV2Channel inTSIMuxer, const bool inLinkB=false, const bool inIsRGB=false)
Definition: ntv2signalrouter.cpp:1035
CNTV2Card::WaitForOutputVerticalInterrupt
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 ...
Definition: ntv2subscriptions.cpp:134
AJA_VW_ENABLEINPUTINTERRUPTFAILED
#define AJA_VW_ENABLEINPUTINTERRUPTFAILED
Definition: ntv2vcam.h:62
CBasePin::EnumMediaTypes
STDMETHODIMP EnumMediaTypes(__deref_out IEnumMediaTypes **ppEnum)
Definition: amfilter.cpp:2315
NTV2MakeChannelSet
NTV2ChannelSet NTV2MakeChannelSet(const NTV2Channel inFirstChannel, const UWord inNumChannels=1)
Definition: ntv2publicinterface.cpp:3579
IsRGBFormat
bool IsRGBFormat(const NTV2FrameBufferFormat format)
Definition: ntv2utils.cpp:5407
CNTV2Card::AutoCirculateTransfer
virtual bool AutoCirculateTransfer(const NTV2Channel inChannel, AUTOCIRCULATE_TRANSFER &transferInfo)
Transfers all or part of a frame as specified in the given AUTOCIRCULATE_TRANSFER object to/from the ...
Definition: ntv2autocirculate.cpp:717
NTV2_FORMAT_1080p_5000_A
@ NTV2_FORMAT_1080p_5000_A
Definition: ntv2enums.h:565
NTV2_FORMAT_4x2048x1080p_6000
@ NTV2_FORMAT_4x2048x1080p_6000
Definition: ntv2enums.h:615
appSignature
ULWord appSignature(0)
POPT_TABLEEND
#define POPT_TABLEEND
Definition: options_popt.h:215
NTV2VideoFormat
enum _NTV2VideoFormat NTV2VideoFormat
Identifies a particular video format.
NTV2_FORMAT_4x1920x1080p_5000
@ NTV2_FORMAT_4x1920x1080p_5000
Definition: ntv2enums.h:610
NTV2_FORMAT_4x1920x1080p_2398
@ NTV2_FORMAT_4x1920x1080p_2398
Definition: ntv2enums.h:593
CMediaType::Subtype
const GUID * Subtype() const
Definition: mtype.h:41
NTV2ACFrameRange::setExactRange
bool setExactRange(const UWord inFirstFrame, const UWord inLastFrame)
Definition: ntv2utils.h:1000
CNTV2MacDriverInterface::AcquireStreamForApplication
virtual bool AcquireStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Reserves exclusive use of the AJA device for a given process, preventing other processes on the host ...
Definition: ntv2macdriverinterface.cpp:505
AJA_VW_NOHDMISUPPORT
#define AJA_VW_NOHDMISUPPORT
Definition: ntv2vcam.h:91
AJA_VW_INVALIDAJADEVICE
#define AJA_VW_INVALIDAJADEVICE
Definition: ntv2vcam.h:53
NTV2_FORMAT_1080p_6000_B
@ NTV2_FORMAT_1080p_6000_B
Definition: ntv2enums.h:562
AJA_VW_GETFRAMESERVICESFAILED
#define AJA_VW_GETFRAMESERVICESFAILED
Definition: ntv2vcam.h:92
CBaseFilter::EnumPins
STDMETHODIMP EnumPins(__deref_out IEnumPins **ppEnum)
Definition: amfilter.cpp:674
AUTOCIRCULATE_STATUS::HasAvailableInputFrame
bool HasAvailableInputFrame(void) const
Definition: ntv2publicinterface.h:7515
NTV2_IS_QUAD_FRAME_FORMAT
#define NTV2_IS_QUAD_FRAME_FORMAT(__f__)
Definition: ntv2enums.h:808
NTV2_FORMAT_1080p_5994_A
@ NTV2_FORMAT_1080p_5994_A
Definition: ntv2enums.h:566
GetInputSourceOutputXpt
NTV2OutputXptID GetInputSourceOutputXpt(const NTV2InputSource inInputSource, const bool inIsSDI_DS2=false, const bool inIsHDMI_RGB=false, const UWord inHDMI_Quadrant=0)
Definition: ntv2signalrouter.cpp:895
NTV2_FORMAT_4x2048x1080p_5994
@ NTV2_FORMAT_4x2048x1080p_5994
Definition: ntv2enums.h:614
CNTV2Card::GetFrameRate
virtual bool GetFrameRate(NTV2FrameRate &outValue, NTV2Channel inChannel=NTV2_CHANNEL1)
Returns the AJA device's currently configured frame rate via its "value" parameter.
Definition: ntv2register.cpp:1022
AJA_VW_SETFRAMESERVICESFAILED
#define AJA_VW_SETFRAMESERVICESFAILED
Definition: ntv2vcam.h:93
NTV2ACFrameRange::setRangeWithCount
bool setRangeWithCount(const UWord inCount, const UWord inFirstFrame)
Definition: ntv2utils.h:1008
NTV2_INPUT_SOURCE_IS_SDI
#define NTV2_INPUT_SOURCE_IS_SDI(_inpSrc_)
Definition: ntv2enums.h:1279
NTV2OutputXptID
enum NTV2OutputCrosspointID NTV2OutputXptID
CNTV2Card::AutoCirculateStart
virtual bool AutoCirculateStart(const NTV2Channel inChannel, const ULWord64 inStartTime=0)
Starts AutoCirculating the specified channel that was previously initialized by CNTV2Card::AutoCircul...
Definition: ntv2autocirculate.cpp:525
CNTV2Card::SetReference
virtual bool SetReference(const NTV2ReferenceSource inRefSource, const bool inKeepFramePulseSelect=(0))
Sets the device's clock reference source. See Video Output Clocking & Synchronization for more inform...
Definition: ntv2register.cpp:1484
NTV2_FORMAT_1080p_2K_5000_A
@ NTV2_FORMAT_1080p_2K_5000_A
Definition: ntv2enums.h:626
NTV2_FRAMERATE_5000
@ NTV2_FRAMERATE_5000
50 frames per second
Definition: ntv2enums.h:419
CNTV2Card::SetNumberAudioChannels
virtual bool SetNumberAudioChannels(const ULWord inNumChannels, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the number of audio channels to be concurrently captured or played for a given Audio System on t...
Definition: ntv2audio.cpp:146
CNTV2Card::SetAudioBufferSize
virtual bool SetAudioBufferSize(const NTV2AudioBufferSize inValue, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Changes the size of the audio buffer that is used for a given Audio System in the AJA device.
Definition: ntv2audio.cpp:249
NTV2InputSourceToAudioSource
NTV2AudioSource NTV2InputSourceToAudioSource(const NTV2InputSource inInputSource)
Definition: ntv2utils.cpp:4898
NTV2_FRAMERATE_4795
@ NTV2_FRAMERATE_4795
Fractional rate of 48,000 frames per 1,001 seconds.
Definition: ntv2enums.h:421
aja::to_string
std::string to_string(bool val)
Definition: common.cpp:180
NTV2_FRAMERATE_3000
@ NTV2_FRAMERATE_3000
30 frames per second
Definition: ntv2enums.h:414
NTV2_IS_VALID_FRAME_BUFFER_FORMAT
#define NTV2_IS_VALID_FRAME_BUFFER_FORMAT(__s__)
Definition: ntv2enums.h:259
AJA_VW_SUBSCRIBEOUTPUTVERTICALEVENTFAILED
#define AJA_VW_SUBSCRIBEOUTPUTVERTICALEVENTFAILED
Definition: ntv2vcam.h:64
CNTV2Card::SubscribeInputVerticalEvent
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: ntv2subscriptions.cpp:39
NTV2AudioSystem
NTV2AudioSystem
Used to identify an Audio System on an NTV2 device. See Audio System Operation for more information.
Definition: ntv2enums.h:3880
NTV2_IS_VALID_AUDIO_SYSTEM
#define NTV2_IS_VALID_AUDIO_SYSTEM(__x__)
Definition: ntv2enums.h:3899
AJA_VW_GETDEVICEOWNERFAILED
#define AJA_VW_GETDEVICEOWNERFAILED
Definition: ntv2vcam.h:94
AUDIO_BYTESPERSAMPLE
#define AUDIO_BYTESPERSAMPLE
Definition: ntv2vcam.h:41
NTV2_FORMAT_4x2048x1080p_2400
@ NTV2_FORMAT_4x2048x1080p_2400
Definition: ntv2enums.h:600
DeviceCapabilities::CanDoFrameBufferFormat
bool CanDoFrameBufferFormat(const NTV2PixelFormat inPF)
Definition: ntv2devicecapabilities.h:227
NTV2_FORMAT_4x1920x1080p_2400
@ NTV2_FORMAT_4x1920x1080p_2400
Definition: ntv2enums.h:594
NTV2_FORMAT_4x1920x1080psf_2400
@ NTV2_FORMAT_4x1920x1080psf_2400
Definition: ntv2enums.h:591
NTV2ChannelToAudioSystem
NTV2AudioSystem NTV2ChannelToAudioSystem(const NTV2Channel inChannel)
Converts the given NTV2Channel value into its equivalent NTV2AudioSystem.
Definition: ntv2utils.cpp:4866
POPT_ARG_STRING
#define POPT_ARG_STRING
Definition: options_popt.h:57
CNTV2Card::AutoCirculateStop
virtual bool AutoCirculateStop(const NTV2Channel inChannel, const bool inAbort=(0))
Stops AutoCirculate for the given channel, and releases the on-device frame buffers that were allocat...
Definition: ntv2autocirculate.cpp:541
NTV2ACFrameRange::setCountOnly
bool setCountOnly(const UWord inCount)
Definition: ntv2utils.h:1016
GetTSIMuxInputXptFromChannel
NTV2InputXptID GetTSIMuxInputXptFromChannel(const NTV2Channel inTSIMuxer, const bool inLinkB=false)
Definition: ntv2signalrouter.cpp:1023
ASSERT
#define ASSERT(_x_)
Definition: wxdebug.h:205
NTV2_FORMAT_1080p_2400
@ NTV2_FORMAT_1080p_2400
Definition: ntv2enums.h:554
POPT_ARG_NONE
#define POPT_ARG_NONE
Definition: options_popt.h:56
hr
__out HRESULT & hr
Definition: pstream.cpp:145
WAVEFORMATEXTENSIBLE::Format
WAVEFORMATEX Format
Definition: streams.h:66
AJA_VW_INVALIDINPUTCHANNEL
#define AJA_VW_INVALIDINPUTCHANNEL
Definition: ntv2vcam.h:59
NTV2_FORMAT_1080psf_2400
@ NTV2_FORMAT_1080psf_2400
Definition: ntv2enums.h:549
AJA_VW_SETFREERUNREFERENCEFAILED
#define AJA_VW_SETFREERUNREFERENCEFAILED
Definition: ntv2vcam.h:69
PIXEL_FORMATS_ALL
@ PIXEL_FORMATS_ALL
Definition: ntv2democommon.h:252
AJA_VW_SETVIDEOFORMATFAILED
#define AJA_VW_SETVIDEOFORMATFAILED
Definition: ntv2vcam.h:70
AJA_VW_ACTRANSFERFAILED
#define AJA_VW_ACTRANSFERFAILED
Definition: ntv2vcam.h:85
CNTV2Card::SetAudioRate
virtual bool SetAudioRate(const NTV2AudioRate inRate, const NTV2AudioSystem inAudioSystem=NTV2_AUDIOSYSTEM_1)
Sets the NTV2AudioRate for the given Audio System.
Definition: ntv2audio.cpp:205
NTV2_OEM_TASKS
@ NTV2_OEM_TASKS
2: OEM (recommended): device configured by client application(s) with some driver involvement.
Definition: ntv2publicinterface.h:4466
NTV2_FORMAT_1080p_2K_2997
@ NTV2_FORMAT_1080p_2K_2997
Definition: ntv2enums.h:624