AJA NTV2 SDK  17.1.1.1245
NTV2 SDK 17.1.1.1245
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 
16 #include "ntv2qtpreview.h"
17 #include "ntv2devicefeatures.h"
18 #include "ajabase/common/types.h"
19 #include "ntv2utils.h"
20 
21 
22 using namespace std;
23 
24 
25 typedef QListIterator <QAbstractButton *> QButtonIterator;
26 
27 
28 NTV2QtPreview::NTV2QtPreview (QWidget * parent, Qt::WindowFlags flags)
29  : QDialog (parent, flags)
30 {
31  if (objectName ().isEmpty ())
32  setObjectName (QString::fromUtf8 ("Dialog"));
33 
34  mBoardChoiceCombo = new QComboBox;
35  for (ULWord ndx (0); ndx < 100; ndx++)
36  {
37  CNTV2Card device;
38  if (CNTV2DeviceScanner::GetDeviceAtIndex (ndx, device))
39  mBoardChoiceCombo->addItem (tr (device.GetDisplayName ().c_str ()));
40  else if (ndx == 0)
41  {mBoardChoiceCombo->addItem (tr ("No Devices Found")); break;}
42  else
43  break;
44  }
45  mBoardChoiceCombo->setCurrentIndex (0);
46 
47  // Input selection radio button group...
48  mInputButtonGroup = new QButtonGroup ();
49  mInputButtonGroup->addButton (new QRadioButton (tr ("Off")), NTV2_INPUTSOURCE_INVALID);
50  for (unsigned ndx (0); ndx < 8; ndx++)
51  mInputButtonGroup->addButton (new QRadioButton ((QString ("SDI %1").arg (string (1, char (ndx + '1')).c_str ()))), ::GetNTV2InputSourceForIndex(ndx, NTV2_IOKINDS_SDI));
52  for (unsigned ndx (0); ndx < 4; ndx++)
53  mInputButtonGroup->addButton (new QRadioButton ((QString ("HDMI %1").arg (string (1, char (ndx + '1')).c_str ()))), ::GetNTV2InputSourceForIndex(ndx, NTV2_IOKINDS_HDMI));
54  mInputButtonGroup->addButton (new QRadioButton (tr ("Analog")), ::GetNTV2InputSourceForIndex(0, NTV2_IOKINDS_ANALOG));
55  mInputButtonGroup->button (NTV2_INPUTSOURCE_INVALID)->setChecked (true);
56 
57  // Checkboxes...
58  mWithAudioCheckBox = new QCheckBox ("With Audio", this);
59  mCheckFor4kCheckBox = new QCheckBox ("Check for 4K Input", this);
60  mCheckFixedReference = new QCheckBox ("Fixed Reference", this);
61 
62  mVideoPreviewWidget = new AJAPreviewWidget (this);
63  mVideoPreviewWidget->setFixedWidth (QTPREVIEW_WIDGET_X);
64  mVideoPreviewWidget->setFixedHeight (QTPREVIEW_WIDGET_Y);
65 
66  mFrameGrabber = new NTV2FrameGrabber (this);
67  mFrameGrabber->SetDeviceIndex (mBoardChoiceCombo->currentIndex ());
68  mFrameGrabber->SetInputSource (NTV2_INPUTSOURCE_SDI1);
69 
70  QVBoxLayout * layout (new QVBoxLayout);
71  layout->addWidget (mBoardChoiceCombo);
72  layout->addWidget (mVideoPreviewWidget);
73 
74  #if defined (INCLUDE_AJACC)
75  QVBoxLayout * bottomLeftLayout (new QVBoxLayout);
76  bottomLeftLayout->setContentsMargins (0, 0, 0, 0);
77 
78  for (QButtonIterator iter (mInputButtonGroup->buttons()); iter.hasNext (); )
79  bottomLeftLayout->addWidget (iter.next());
80 
81  bottomLeftLayout->addWidget (mWithAudioCheckBox);
82  bottomLeftLayout->addWidget (mCheckFor4kCheckBox);
83  bottomLeftLayout->addStretch (1);
84 
85  QVBoxLayout * bottomRightLayout (new QVBoxLayout);
86  bottomRightLayout->setContentsMargins (0, 0, 0, 0);
87 
88  mCaptionButtonGroup = new QButtonGroup ();
89  mCaptionButtonGroup->addButton (new QRadioButton (tr ("CC Off")), NTV2_CC608_ChannelInvalid);
90  for (unsigned ndx (1); ndx <= 8; ndx++)
91  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())),
92  NTV2Line21Channel (ndx-1));
93  mCaptionButtonGroup->button (NTV2_CC608_ChannelInvalid)->setChecked (true);
94 
95  for (QButtonIterator iter (mCaptionButtonGroup->buttons()); iter.hasNext (); )
96  bottomRightLayout->addWidget (iter.next());
97 
98  QHBoxLayout * bottomLayout (new QHBoxLayout);
99  bottomLayout->setContentsMargins (0, 0, 0, 0);
100 
101  bottomLayout->addLayout (bottomLeftLayout);
102  bottomLayout->addLayout (bottomRightLayout);
103  layout->addLayout (bottomLayout);
104  #else // !defined (INCLUDE_AJACC)
105  for (QButtonIterator iter (mInputButtonGroup->buttons()); iter.hasNext (); )
106  layout->addWidget (iter.next());
107  layout->addWidget (mWithAudioCheckBox);
108  layout->addWidget (mCheckFor4kCheckBox);
109  layout->addWidget (mCheckFixedReference);
110  #endif // !defined (INCLUDE_AJACC)
111 
112  layout->addStretch (1);
113  setLayout (layout);
114 
115  QObject::connect (mBoardChoiceCombo, SIGNAL (currentIndexChanged (int)), this, SLOT (RequestDeviceChange (const int)));
116  QObject::connect (mInputButtonGroup, SIGNAL (buttonReleased (int)), this, SLOT (inputChanged (int)));
117  QObject::connect (mWithAudioCheckBox, SIGNAL (stateChanged (int)), this, SLOT (withAudioChanged (int)));
118  QObject::connect (mCheckFixedReference, SIGNAL (toggled (bool)), this, SLOT (fixedRefChanged (bool)));
119  QObject::connect (mCheckFor4kCheckBox, SIGNAL (stateChanged (int)), this, SLOT (checkFor4kChanged (int)));
120  connect (mFrameGrabber, SIGNAL (newFrame (const QImage &, bool)), mVideoPreviewWidget, SLOT (updateFrame (const QImage &, bool)));
121  connect (mFrameGrabber, SIGNAL (newStatusString (const QString)), mVideoPreviewWidget, SLOT (updateStatusString (const QString)));
122  #if defined (INCLUDE_AJACC)
123  connect (mFrameGrabber, SIGNAL (captionScreenChanged (const ushort *)), mVideoPreviewWidget, SLOT (updateCaptionScreen (const ushort *)));
124  QObject::connect (mCaptionButtonGroup, SIGNAL (buttonReleased (int)), mFrameGrabber, SLOT (changeCaptionChannel (int)));
125  #endif // defined (INCLUDE_AJACC)
126 
127  mFrameGrabber->SetInputSource (NTV2_NUM_INPUTSOURCES);
128  mFrameGrabber->start ();
129  mTimerID = startTimer (100);
130 
131  mPnp.Install (PnpCallback, this, AJA_Pnp_PciVideoDevices);
132 
133 } // constructor
134 
135 
137 {
138  mPnp.Uninstall ();
139  delete mFrameGrabber;
140 
141 } // destructor
142 
143 
144 void NTV2QtPreview::RequestDeviceChange (const int inDeviceIndexNum)
145 {
146  // Notify my frame grabber to change devices...
147  if (mFrameGrabber)
148  mFrameGrabber->SetDeviceIndex (inDeviceIndexNum);
149  qDebug ("## NOTE: Device changed to %d", inDeviceIndexNum);
150 
151 } // RequestDeviceChange
152 
153 
154 void NTV2QtPreview::inputChanged (int inputRadioButtonId)
155 {
156  const NTV2InputSource chosenInputSource (static_cast <NTV2InputSource> (inputRadioButtonId));
157 
158  CNTV2Card device;
159  CNTV2DeviceScanner::GetDeviceAtIndex (mBoardChoiceCombo->currentIndex (), device);
160 
161  if (!NTV2_IS_VALID_INPUT_SOURCE (chosenInputSource))
162  {
163  mFrameGrabber->SetInputSource (NTV2_INPUTSOURCE_INVALID);
164  qDebug ("## DEBUG: NTV2QtPreview::inputChanged: off");
165  }
166  else if (device.features().CanDoInputSource(chosenInputSource))
167  {
168  mFrameGrabber->SetInputSource (chosenInputSource);
169  cerr << "## DEBUG: NTV2QtPreview::inputChanged: " << ::NTV2InputSourceToString (chosenInputSource) << endl;
170  }
171 
172 } // inputChanged
173 
174 
175 void NTV2QtPreview::withAudioChanged (int state)
176 {
177  mFrameGrabber->SetWithAudio (state == Qt::Checked ? true : false);
178 
179 } // withAudioChanged
180 
181 
182 void NTV2QtPreview::fixedRefChanged (bool checked)
183 {
184  mFrameGrabber->SetFixedReference(checked);
185 
186 }
187 
188 
189 void NTV2QtPreview::checkFor4kChanged (int state)
190 {
191  mFrameGrabber->CheckFor4kInput (state == Qt::Checked ? true : false);
192 
193 } // checkFor4kChanged
194 
195 
196 void NTV2QtPreview::updateInputs (void)
197 {
198  CNTV2Card ntv2Card (mBoardChoiceCombo->currentIndex());
199  if (ntv2Card.IsOpen())
200  {
201  for (QButtonIterator iter(mInputButtonGroup->buttons()); iter.hasNext(); )
202  {
203  QRadioButton * pButton (reinterpret_cast<QRadioButton*>(iter.next()));
204  const NTV2InputSource inputSource (NTV2InputSource(mInputButtonGroup->id(pButton)));
205  if (NTV2_IS_VALID_INPUT_SOURCE(inputSource))
206  {
207  const bool hasInputSource (ntv2Card.features().CanDoInputSource(inputSource));
208  const string videoFormatStr (hasInputSource ? ::NTV2VideoFormatToString(ntv2Card.GetInputVideoFormat(inputSource)) : "");
209  const QString buttonLabel (QString("%1 %2").arg(::NTV2InputSourceToString(inputSource, true).c_str(), videoFormatStr.empty() ? "No Detected Input" : videoFormatStr.c_str()));
210  pButton->setText (buttonLabel);
211  pButton->setEnabled (hasInputSource);
212  }
213  }
214 
215  #if defined (INCLUDE_AJACC)
216  const bool hasCustomAnc (mDevice.features().CanDoCustomAnc());
217  for (QButtonIterator iter (mCaptionButtonGroup->buttons()); iter.hasNext(); )
218  iter.next()->setEnabled(hasCustomAnc);
219  #endif // defined (INCLUDE_AJACC)
220 
221  } // if board opened ok
222 
223 } // updateInputs
224 
225 
226 void NTV2QtPreview::timerEvent (QTimerEvent * event)
227 {
228  if (event->timerId () == mTimerID)
229  updateInputs ();
230  else
231  QWidget::timerEvent (event);
232 
233 } // timerEvent
234 
235 
236 void NTV2QtPreview::devicesChanged (void)
237 {
238  qDebug () << QString ("devicesChanged");
239  mInputButtonGroup->button (NTV2_INPUTSOURCE_INVALID)->setChecked (true);
240  inputChanged (NTV2_INPUTSOURCE_INVALID); // necessary?
241 
242  mBoardChoiceCombo->clear ();
243  for (ULWord ndx (0); ndx < 100; ndx++)
244  {
245  CNTV2Card device;
246  if (CNTV2DeviceScanner::GetDeviceAtIndex (ndx, device))
247  mBoardChoiceCombo->addItem (tr (device.GetDisplayName ().c_str ()));
248  else if (ndx == 0)
249  {mBoardChoiceCombo->addItem (tr ("No Devices Found")); break;}
250  else
251  break;
252  }
253  mBoardChoiceCombo->setCurrentIndex (0);
254 
255 } // devicesChanged
256 
257 
258 void NTV2QtPreview::PnpCallback (AJAPnpMessage inMessage, void * pUserData) // static
259 {
260  if (pUserData)
261  {
262  if (inMessage == AJA_Pnp_DeviceAdded || inMessage == AJA_Pnp_DeviceRemoved)
263  {
264  NTV2QtPreview * pMainWindow (reinterpret_cast <NTV2QtPreview *>(pUserData));
265  pMainWindow->devicesChanged ();
266  }
267  }
268 
269 } // PnpCallback
NTV2QtPreview
I am a QDialog that displays whatever video is present on the SDI inputs of an AJA device....
Definition: ntv2qtpreview.h:30
ntv2devicefeatures.h
Declares device capability functions.
types.h
Declares common types used in the ajabase library.
NTV2QtPreview::NTV2QtPreview
NTV2QtPreview(QWidget *parent=NULL, Qt::WindowFlags flags=Qt::WindowFlags())
Definition: ntv2qtpreview.cpp:28
AJAPnpMessage
AJAPnpMessage
Definition: pnp.h:22
NTV2QtPreview::~NTV2QtPreview
~NTV2QtPreview()
Definition: ntv2qtpreview.cpp:136
NTV2_IOKINDS_HDMI
@ NTV2_IOKINDS_HDMI
Specifies HDMI input/output kinds.
Definition: ntv2enums.h:1252
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:1253
AJAPnp::Install
virtual AJAStatus Install(AJAPnpCallback callback, void *refCon=NULL, uint32_t devices=0)
Installs the given plug-n-play notification callback function, replacing any callback function that m...
Definition: pnp.cpp:38
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:1228
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:45
NTV2InputSourceToString
std::string NTV2InputSourceToString(const NTV2InputSource inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7215
NTV2FrameGrabber::SetWithAudio
void SetWithAudio(const bool inWithAudio)
Enables or disables host audio playback.
Definition: ntv2framegrabber.h:70
ULWord
uint32_t ULWord
Definition: ajatypes.h:253
NTV2_CC608_ChannelInvalid
@ NTV2_CC608_ChannelInvalid
Definition: ntv2caption608types.h:98
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:1236
NTV2_IS_VALID_INPUT_SOURCE
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1243
GetNTV2InputSourceForIndex
NTV2InputSource GetNTV2InputSourceForIndex(const ULWord inIndex0, const NTV2IOKinds inKinds=NTV2_IOKINDS_SDI)
Definition: ntv2utils.cpp:5268
ntv2utils.h
Declares numerous NTV2 utility functions.
NTV2VideoFormatToString
std::string NTV2VideoFormatToString(const NTV2VideoFormat inValue, const bool inUseFrameRate=false)
Definition: ntv2utils.cpp:6750
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
NTV2_NUM_INPUTSOURCES
@ NTV2_NUM_INPUTSOURCES
Definition: ntv2enums.h:1237
DeviceCapabilities::CanDoInputSource
bool CanDoInputSource(const NTV2InputSource inSrc)
Definition: ntv2devicecapabilities.h:233
NTV2InputSource
NTV2InputSource
Identifies a specific video input source.
Definition: ntv2enums.h:1221
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:274
QButtonIterator
QListIterator< QAbstractButton * > QButtonIterator
Definition: ntv2qtpreview.cpp:25
NTV2FrameGrabber::SetInputSource
void SetInputSource(const NTV2InputSource inInputSource)
Sets the input to be used for capture on the AJA device being used.
Definition: ntv2framegrabber.cpp:77
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:91
NTV2_IOKINDS_SDI
@ NTV2_IOKINDS_SDI
Specifies SDI input/output kinds.
Definition: ntv2enums.h:1251
AJA_Pnp_DeviceAdded
@ AJA_Pnp_DeviceAdded
Definition: pnp.h:24
NTV2FrameGrabber::SetFixedReference
void SetFixedReference(bool fixed)
Definition: ntv2framegrabber.h:96
QTPREVIEW_WIDGET_X
#define QTPREVIEW_WIDGET_X
Definition: ntv2framegrabber.h:35