AJA NTV2 SDK  17.5.0.1492
NTV2 SDK 17.5.0.1492
ntv2qtpreview.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
9 #include <QtCore>
10 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
11  #include <QtWidgets>
12 #else
13  #include <QtGui>
14 #endif
15 #include "ntv2qtpreview.h"
16 #include "ajabase/system/debug.h"
17 #include "ntv2utils.h"
18 
19 using namespace std;
20 
21 // Convenience macros for EZ logging:
22 #define FGFAIL(_expr_) AJA_sERROR (AJA_DebugUnit_DemoCapture, AJAFUNC << ": " << _expr_)
23 #define FGWARN(_expr_) AJA_sWARNING(AJA_DebugUnit_DemoCapture, AJAFUNC << ": " << _expr_)
24 #define FGDBG(_expr_) AJA_sDEBUG (AJA_DebugUnit_DemoCapture, AJAFUNC << ": " << _expr_)
25 #define FGNOTE(_expr_) AJA_sNOTICE (AJA_DebugUnit_DemoCapture, AJAFUNC << ": " << _expr_)
26 #define FGINFO(_expr_) AJA_sINFO (AJA_DebugUnit_DemoCapture, AJAFUNC << ": " << _expr_)
27 
28 
29 typedef QListIterator <QAbstractButton *> QButtonIterator;
30 
31 
32 NTV2QtPreview::NTV2QtPreview (QWidget * parent, Qt::WindowFlags flags)
33  : QDialog (parent, flags)
34 {
35  if (objectName ().isEmpty ())
36  setObjectName (QString::fromUtf8 ("Dialog"));
37 
38  mBoardChoiceCombo = new QComboBox;
39 
40  // Input selection radio button group...
41  mInputButtonGroup = new QButtonGroup ();
42  mInputButtonGroup->addButton (new QRadioButton (tr ("Off")), NTV2_INPUTSOURCE_INVALID);
43  for (unsigned ndx (0); ndx < 8; ndx++)
44  mInputButtonGroup->addButton (new QRadioButton ((QString ("SDI %1").arg (string (1, char (ndx + '1')).c_str ()))), ::GetNTV2InputSourceForIndex(ndx, NTV2_IOKINDS_SDI));
45  for (unsigned ndx (0); ndx < 4; ndx++)
46  mInputButtonGroup->addButton (new QRadioButton ((QString ("HDMI %1").arg (string (1, char (ndx + '1')).c_str ()))), ::GetNTV2InputSourceForIndex(ndx, NTV2_IOKINDS_HDMI));
47  mInputButtonGroup->addButton (new QRadioButton (tr ("Analog")), ::GetNTV2InputSourceForIndex(0, NTV2_IOKINDS_ANALOG));
48  mInputButtonGroup->button (NTV2_INPUTSOURCE_INVALID)->setChecked (true);
49 
50  // Checkboxes...
51  mWithAudioCheckBox = new QCheckBox ("With Audio", this);
52  mCheckFor4kCheckBox = new QCheckBox ("Check for 4K Input", this);
53  mCheckFixedReference = new QCheckBox ("Fixed Reference", this);
54 
55  mVideoPreviewWidget = new AJAPreviewWidget (this);
56  mVideoPreviewWidget->setFixedWidth (QTPREVIEW_WIDGET_X);
57  mVideoPreviewWidget->setFixedHeight (QTPREVIEW_WIDGET_Y);
58 
59  mFrameGrabber = new NTV2FrameGrabber (this);
60  mFrameGrabber->SetDeviceIndex (mBoardChoiceCombo->currentIndex ());
61  mFrameGrabber->SetInputSource (NTV2_INPUTSOURCE_SDI1);
62 
63  QVBoxLayout * layout (new QVBoxLayout);
64  layout->addWidget (mBoardChoiceCombo);
65  layout->addWidget (mVideoPreviewWidget);
66 
67  #if defined (INCLUDE_AJACC)
68  QVBoxLayout * bottomLeftLayout (new QVBoxLayout);
69  bottomLeftLayout->setContentsMargins (0, 0, 0, 0);
70 
71  for (QButtonIterator iter (mInputButtonGroup->buttons()); iter.hasNext (); )
72  bottomLeftLayout->addWidget (iter.next());
73 
74  bottomLeftLayout->addWidget (mWithAudioCheckBox);
75  bottomLeftLayout->addWidget (mCheckFor4kCheckBox);
76  bottomLeftLayout->addStretch (1);
77 
78  QVBoxLayout * bottomRightLayout (new QVBoxLayout);
79  bottomRightLayout->setContentsMargins (0, 0, 0, 0);
80 
81  mCaptionButtonGroup = new QButtonGroup ();
82  mCaptionButtonGroup->addButton (new QRadioButton (tr ("CC Off")), NTV2_CC608_ChannelInvalid);
83  for (unsigned ndx (1); ndx <= 8; ndx++)
84  mCaptionButtonGroup->addButton (new QRadioButton (QString ("%1%2").arg (string (ndx < 5 ? "CC" : "TXT").c_str(), string (1, char ((ndx < 5 ? ndx : ndx - 4) + '0')).c_str())),
85  NTV2Line21Channel (ndx-1));
86  mCaptionButtonGroup->button (NTV2_CC608_ChannelInvalid)->setChecked (true);
87 
88  for (QButtonIterator iter (mCaptionButtonGroup->buttons()); iter.hasNext (); )
89  bottomRightLayout->addWidget (iter.next());
90 
91  QHBoxLayout * bottomLayout (new QHBoxLayout);
92  bottomLayout->setContentsMargins (0, 0, 0, 0);
93 
94  bottomLayout->addLayout (bottomLeftLayout);
95  bottomLayout->addLayout (bottomRightLayout);
96  layout->addLayout (bottomLayout);
97  #else // !defined (INCLUDE_AJACC)
98  for (QButtonIterator iter(mInputButtonGroup->buttons()); iter.hasNext(); )
99  layout->addWidget (iter.next());
100  layout->addWidget (mWithAudioCheckBox);
101  layout->addWidget (mCheckFor4kCheckBox);
102  layout->addWidget (mCheckFixedReference);
103  #endif // !defined (INCLUDE_AJACC)
104 
105  layout->addStretch (1);
106  setLayout (layout);
107 
108  connect (mBoardChoiceCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(RequestDeviceChange(const int)));
109  connect (mInputButtonGroup, SIGNAL(idReleased(int)), this, SLOT(inputChanged(int)));
110  connect (mWithAudioCheckBox, SIGNAL(stateChanged(int)), this, SLOT(withAudioChanged(int)));
111  connect (mCheckFixedReference, SIGNAL(toggled(bool)), this, SLOT(fixedRefChanged(bool)));
112  connect (mCheckFor4kCheckBox, SIGNAL(stateChanged(int)), this, SLOT(checkFor4kChanged(int)));
113  connect (mFrameGrabber, SIGNAL(newFrame(const QImage&, bool)), mVideoPreviewWidget, SLOT(updateFrame(const QImage &, bool)));
114  connect (mFrameGrabber, SIGNAL(newStatusString(const QString)), mVideoPreviewWidget, SLOT(updateStatusString(const QString)));
115  #if defined (INCLUDE_AJACC)
116  connect (mFrameGrabber, SIGNAL (captionScreenChanged (const ushort *)), mVideoPreviewWidget, SLOT (updateCaptionScreen (const ushort *)));
117  connect (mCaptionButtonGroup, SIGNAL (buttonReleased (int)), mFrameGrabber, SLOT (changeCaptionChannel (int)));
118  #endif // defined (INCLUDE_AJACC)
119 
120  mFrameGrabber->SetInputSource (NTV2_INPUTSOURCE_INVALID);
121  mFrameGrabber->start ();
122  mTimerID = startTimer (100);
123 
124  mPnp.Install (PnpCallback, this, AJA_Pnp_PciVideoDevices);
125  devicesChanged();
126 
127 } // constructor
128 
129 
131 {
132  mPnp.Uninstall();
133  delete mFrameGrabber;
134 
135 } // destructor
136 
137 
138 void NTV2QtPreview::RequestDeviceChange (const int inDeviceIndexNum)
139 {
140  // Notify my frame grabber to change devices...
141  if (mFrameGrabber)
142  mFrameGrabber->SetDeviceIndex(inDeviceIndexNum);
143  FGNOTE("Device changed to " << inDeviceIndexNum);
144 
145 } // RequestDeviceChange
146 
147 
148 void NTV2QtPreview::inputChanged (int inputRadioButtonId)
149 {
150  const NTV2InputSource chosenInputSource(NTV2InputSource(inputRadioButtonId+0));
151 
152  CNTV2Card device;
153  if (!CNTV2DeviceScanner::GetDeviceAtIndex (ULWord(mBoardChoiceCombo->currentIndex()), device))
154  {FGNOTE("No device at " << mBoardChoiceCombo->currentIndex()); return;}
155 
156  if (!NTV2_IS_VALID_INPUT_SOURCE(chosenInputSource))
157  {
159  FGNOTE("off");
160  }
161  else if (device.features().CanDoInputSource(chosenInputSource))
162  {
163  mFrameGrabber->SetInputSource(chosenInputSource);
164  FGNOTE(::NTV2InputSourceToString(chosenInputSource));
165  }
166  else FGWARN("input source " << inputRadioButtonId << " unsupported by device");
167 
168 } // inputChanged
169 
170 
171 void NTV2QtPreview::withAudioChanged (int state)
172 {
173  mFrameGrabber->SetWithAudio (state == Qt::Checked ? true : false);
174 
175 } // withAudioChanged
176 
177 
178 void NTV2QtPreview::fixedRefChanged (bool checked)
179 {
180  mFrameGrabber->SetFixedReference(checked);
181 
182 }
183 
184 
185 void NTV2QtPreview::checkFor4kChanged (int state)
186 {
187  mFrameGrabber->CheckFor4kInput (state == Qt::Checked ? true : false);
188 
189 } // checkFor4kChanged
190 
191 
192 void NTV2QtPreview::updateInputs (void)
193 {
194  CNTV2Card ntv2Card (mBoardChoiceCombo->currentIndex());
195  if (ntv2Card.IsOpen())
196  {
197  for (QButtonIterator iter(mInputButtonGroup->buttons()); iter.hasNext(); )
198  {
199  QRadioButton * pButton (reinterpret_cast<QRadioButton*>(iter.next()));
200  const NTV2InputSource inputSource (NTV2InputSource(mInputButtonGroup->id(pButton)));
201  if (NTV2_IS_VALID_INPUT_SOURCE(inputSource))
202  {
203  const bool hasInputSource (ntv2Card.features().CanDoInputSource(inputSource));
204  const string videoFormatStr (hasInputSource ? ::NTV2VideoFormatToString(ntv2Card.GetInputVideoFormat(inputSource)) : "");
205  const QString buttonLabel (QString("%1 %2").arg(::NTV2InputSourceToString(inputSource, true).c_str(), videoFormatStr.empty() ? "No Detected Input" : videoFormatStr.c_str()));
206  pButton->setText(buttonLabel);
207  pButton->setEnabled(hasInputSource);
208  }
209  } // for each radio button
210  #if defined (INCLUDE_AJACC)
211  const bool hasCustomAnc (mDevice.features().CanDoCustomAnc());
212  for (QButtonIterator iter (mCaptionButtonGroup->buttons()); iter.hasNext(); )
213  iter.next()->setEnabled(hasCustomAnc);
214  #endif // defined (INCLUDE_AJACC)
215  } // if board opened ok
216 } // updateInputs
217 
218 
219 void NTV2QtPreview::timerEvent (QTimerEvent * event)
220 {
221  if (event->timerId() == mTimerID)
222  updateInputs();
223  else
224  QWidget::timerEvent(event);
225 } // timerEvent
226 
227 
228 void NTV2QtPreview::devicesChanged (void)
229 {
230  FGNOTE("");
231  mInputButtonGroup->button (NTV2_INPUTSOURCE_INVALID)->setChecked(true);
232  inputChanged (NTV2_INPUTSOURCE_INVALID); // necessary?
233 
234  mBoardChoiceCombo->clear();
235  for (ULWord ndx(0); ndx < 100; ndx++)
236  {
237  CNTV2Card device(ndx);
238  if (device.IsOpen())
239  mBoardChoiceCombo->addItem(tr(device.GetDisplayName().c_str()), QVariant());
240  else if (!ndx)
241  {mBoardChoiceCombo->addItem(tr("No Devices Found")); break;}
242  else
243  break;
244  }
245  mBoardChoiceCombo->setCurrentIndex(0);
246 } // devicesChanged
247 
248 
249 void NTV2QtPreview::PnpCallback (AJAPnpMessage inMessage, void * pUserData) // static
250 {
251  if (pUserData)
252  if (inMessage == AJA_Pnp_DeviceAdded || inMessage == AJA_Pnp_DeviceRemoved)
253  {
254  NTV2QtPreview * pMainWindow (reinterpret_cast<NTV2QtPreview*>(pUserData));
255  pMainWindow->devicesChanged();
256  }
257 } // PnpCallback
NTV2_IOKINDS_HDMI
@ NTV2_IOKINDS_HDMI
Specifies HDMI input/output kinds.
Definition: ntv2enums.h:1284
NTV2QtPreview
I am a QDialog that displays whatever video is present on the SDI inputs of an AJA device....
Definition: ntv2qtpreview.h:30
NTV2QtPreview::NTV2QtPreview
NTV2QtPreview(QWidget *parent=NULL, Qt::WindowFlags flags=Qt::WindowFlags())
Definition: ntv2qtpreview.cpp:32
AJAPnpMessage
AJAPnpMessage
Definition: pnp.h:22
NTV2QtPreview::~NTV2QtPreview
~NTV2QtPreview()
Definition: ntv2qtpreview.cpp:130
AJA_Pnp_PciVideoDevices
@ AJA_Pnp_PciVideoDevices
Definition: pnp.h:16
NTV2FrameGrabber::CheckFor4kInput
void CheckFor4kInput(const bool inCheckFor4K)
Enables or disables checking for 4K/UHD video (on devices that supported 4K/UHD).
Definition: ntv2framegrabber.h:86
NTV2_IOKINDS_ANALOG
@ NTV2_IOKINDS_ANALOG
Specifies analog input/output kinds.
Definition: ntv2enums.h:1285
CNTV2Card::features
virtual class DeviceCapabilities & features(void)
Definition: ntv2card.h:141
NTV2_INPUTSOURCE_SDI1
@ NTV2_INPUTSOURCE_SDI1
Identifies the 1st SDI video input.
Definition: ntv2enums.h:1260
CNTV2Card::GetDisplayName
virtual std::string GetDisplayName(void)
Answers with this device's display name.
Definition: ntv2card.cpp:86
AJAPnp::Uninstall
virtual AJAStatus Uninstall()
Uninstalls any previously-installed callback notifier.
Definition: pnp.cpp:58
NTV2_IOKINDS_SDI
@ NTV2_IOKINDS_SDI
Specifies SDI input/output kinds.
Definition: ntv2enums.h:1283
NTV2InputSourceToString
std::string NTV2InputSourceToString(const NTV2InputSource inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7263
NTV2FrameGrabber::SetWithAudio
void SetWithAudio(const bool inWithAudio)
Enables or disables host audio playback.
Definition: ntv2framegrabber.h:70
ULWord
uint32_t ULWord
Definition: ajatypes.h:255
NTV2_CC608_ChannelInvalid
@ NTV2_CC608_ChannelInvalid
Definition: ntv2caption608types.h:98
FGWARN
#define FGWARN(_expr_)
Definition: ntv2qtpreview.cpp:23
ntv2qtpreview.h
Header file for NTV2QtPreview demo application. Demonstrates how to capture audio/video from NTV2-bas...
NTV2_INPUTSOURCE_INVALID
@ NTV2_INPUTSOURCE_INVALID
The invalid video input.
Definition: ntv2enums.h:1268
NTV2_IS_VALID_INPUT_SOURCE
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1275
GetNTV2InputSourceForIndex
NTV2InputSource GetNTV2InputSourceForIndex(const ULWord inIndex0, const NTV2IOKinds inKinds=NTV2_IOKINDS_SDI)
Definition: ntv2utils.cpp:5289
ntv2utils.h
Declares numerous NTV2 utility functions.
NTV2VideoFormatToString
std::string NTV2VideoFormatToString(const NTV2VideoFormat inValue, const bool inUseFrameRate=false)
Definition: ntv2utils.cpp:6798
QTPREVIEW_WIDGET_Y
#define QTPREVIEW_WIDGET_Y
Definition: ntv2framegrabber.h:36
CNTV2Card
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:28
AJA_Pnp_DeviceRemoved
@ AJA_Pnp_DeviceRemoved
Definition: pnp.h:25
DeviceCapabilities::CanDoInputSource
bool CanDoInputSource(const NTV2InputSource inSrc)
Definition: ntv2devicecapabilities.h:236
NTV2InputSource
NTV2InputSource
Identifies a specific video input source.
Definition: ntv2enums.h:1253
NTV2FrameGrabber
A QThread that captures audio/video from NTV2-compatible AJA devices and uses Qt signals to emit ARGB...
Definition: ntv2framegrabber.h:46
CNTV2DeviceScanner::GetDeviceAtIndex
static bool GetDeviceAtIndex(const ULWord inDeviceIndexNumber, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the AJA device having the given zero-bas...
Definition: ntv2devicescanner.cpp:191
QButtonIterator
QListIterator< QAbstractButton * > QButtonIterator
Definition: ntv2qtpreview.cpp:29
NTV2FrameGrabber::SetInputSource
void SetInputSource(const NTV2InputSource inInputSource)
Sets the input to be used for capture on the AJA device being used.
Definition: ntv2framegrabber.cpp:74
NTV2Line21Channel
NTV2Line21Channel
The CEA-608 caption channels: CC1 thru CC4, TX1 thru TX4, plus XDS.
Definition: ntv2caption608types.h:82
std
Definition: json.hpp:5362
AJAPreviewWidget
Definition: ajapreviewwidget.h:36
NTV2FrameGrabber::SetDeviceIndex
void SetDeviceIndex(const UWord inDeviceIndex)
Sets the AJA device to be used for capture.
Definition: ntv2framegrabber.cpp:88
AJAPnp::Install
virtual AJAStatus Install(AJAPnpCallback pInCallback, void *inRefCon=NULL, uint32_t inDeviceMask=0xFFFFFFFF)
Installs the given plug & play notification callback function, replacing any callback function that m...
Definition: pnp.cpp:51
FGNOTE
#define FGNOTE(_expr_)
Definition: ntv2qtpreview.cpp:25
AJA_Pnp_DeviceAdded
@ AJA_Pnp_DeviceAdded
Definition: pnp.h:24
NTV2FrameGrabber::SetFixedReference
void SetFixedReference(bool fixed)
Definition: ntv2framegrabber.h:96
debug.h
Declares the AJADebug class.
QTPREVIEW_WIDGET_X
#define QTPREVIEW_WIDGET_X
Definition: ntv2framegrabber.h:35