AJA NTV2 SDK  17.0.1.1246
NTV2 SDK 17.0.1.1246
ntv2streampreview.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 "ntv2streampreview.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 NTV2StreamPreview::NTV2StreamPreview (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 (STREAMPREVIEW_WIDGET_X);
64  mVideoPreviewWidget->setFixedHeight (STREAMPREVIEW_WIDGET_Y);
65 
66  mStreamGrabber = new NTV2StreamGrabber (this);
67  mStreamGrabber->SetDeviceIndex (mBoardChoiceCombo->currentIndex ());
68  mStreamGrabber->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 (mStreamGrabber, SIGNAL (newFrame (const QImage &, bool)), mVideoPreviewWidget, SLOT (updateFrame (const QImage &, bool)));
121  connect (mStreamGrabber, 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  mStreamGrabber->SetInputSource (NTV2_NUM_INPUTSOURCES);
128  mStreamGrabber->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 mStreamGrabber;
140 
141 } // destructor
142 
143 
144 void NTV2StreamPreview::RequestDeviceChange (const int inDeviceIndexNum)
145 {
146  // Notify my frame grabber to change devices...
147  if (mStreamGrabber)
148  mStreamGrabber->SetDeviceIndex (inDeviceIndexNum);
149  qDebug ("## NOTE: Device changed to %d", inDeviceIndexNum);
150 
151 } // RequestDeviceChange
152 
153 
154 void NTV2StreamPreview::inputChanged (int inputRadioButtonId)
155 {
156  const NTV2InputSource chosenInputSource (static_cast <NTV2InputSource> (inputRadioButtonId));
157 
158  CNTV2Card device;
159  CNTV2DeviceScanner::GetDeviceAtIndex (mBoardChoiceCombo->currentIndex (), device);
160 
161  const NTV2DeviceID deviceID (device.GetDeviceID ());
162 
163  if (!NTV2_IS_VALID_INPUT_SOURCE (chosenInputSource))
164  {
165  mStreamGrabber->SetInputSource (NTV2_INPUTSOURCE_INVALID);
166  qDebug ("## DEBUG: NTV2StreamPreview::inputChanged: off");
167  }
168  else if (::NTV2DeviceCanDoInputSource (deviceID, chosenInputSource))
169  {
170  mStreamGrabber->SetInputSource (chosenInputSource);
171  cerr << "## DEBUG: NTV2StreamPreview::inputChanged: " << ::NTV2InputSourceToString (chosenInputSource) << endl;
172  }
173 } // inputChanged
174 
175 
176 void NTV2StreamPreview::withAudioChanged (int state)
177 {
178  mStreamGrabber->SetWithAudio (state == Qt::Checked ? true : false);
179 
180 } // withAudioChanged
181 
182 
183 void NTV2StreamPreview::fixedRefChanged (bool checked)
184 {
185  mStreamGrabber->SetFixedReference(checked);
186 
187 }
188 
189 
190 void NTV2StreamPreview::checkFor4kChanged (int state)
191 {
192  mStreamGrabber->CheckFor4kInput (state == Qt::Checked ? true : false);
193 
194 } // checkFor4kChanged
195 
196 
197 void NTV2StreamPreview::updateInputs (void)
198 {
199  CNTV2Card ntv2Card (mBoardChoiceCombo->currentIndex());
200  if (ntv2Card.IsOpen())
201  {
202  const NTV2DeviceID deviceID (ntv2Card.GetDeviceID());
203 
204  for (QButtonIterator iter (mInputButtonGroup->buttons()); iter.hasNext (); )
205  {
206  QRadioButton * pButton (reinterpret_cast <QRadioButton*> (iter.next ()));
207  const NTV2InputSource inputSource (static_cast <NTV2InputSource> (mInputButtonGroup->id (pButton)));
208  if (NTV2_IS_VALID_INPUT_SOURCE (inputSource))
209  {
210  const bool hasInputSource (::NTV2DeviceCanDoInputSource (deviceID, inputSource));
211  const string videoFormatStr (hasInputSource ? ::NTV2VideoFormatToString (ntv2Card.GetInputVideoFormat (inputSource)) : "");
212  const QString buttonLabel (QString ("%1 %2").arg (::NTV2InputSourceToString (inputSource, true).c_str(), videoFormatStr.empty() ? "No Detected Input" : videoFormatStr.c_str()));
213  pButton->setText (buttonLabel);
214  pButton->setEnabled (hasInputSource);
215  }
216  }
217 
218  #if defined (INCLUDE_AJACC)
219  const bool hasCustomAnc (::NTV2DeviceCanDoCustomAnc (deviceID));
220  for (QButtonIterator iter (mCaptionButtonGroup->buttons()); iter.hasNext (); )
221  iter.next()->setEnabled (hasCustomAnc);
222  #endif // defined (INCLUDE_AJACC)
223 
224  } // if board opened ok
225 
226 } // updateInputs
227 
228 
229 void NTV2StreamPreview::timerEvent (QTimerEvent * event)
230 {
231  if (event->timerId () == mTimerID)
232  updateInputs ();
233  else
234  QWidget::timerEvent (event);
235 
236 } // timerEvent
237 
238 
239 void NTV2StreamPreview::devicesChanged (void)
240 {
241  qDebug () << QString ("devicesChanged");
242  mInputButtonGroup->button (NTV2_INPUTSOURCE_INVALID)->setChecked (true);
243  inputChanged (NTV2_INPUTSOURCE_INVALID); // necessary?
244 
245  mBoardChoiceCombo->clear ();
246  for (ULWord ndx (0); ndx < 100; ndx++)
247  {
248  CNTV2Card device;
249  if (CNTV2DeviceScanner::GetDeviceAtIndex (ndx, device))
250  mBoardChoiceCombo->addItem (tr (device.GetDisplayName ().c_str ()));
251  else if (ndx == 0)
252  {mBoardChoiceCombo->addItem (tr ("No Devices Found")); break;}
253  else
254  break;
255  }
256  mBoardChoiceCombo->setCurrentIndex (0);
257 
258 } // devicesChanged
259 
260 
261 void NTV2StreamPreview::PnpCallback (AJAPnpMessage inMessage, void * pUserData) // static
262 {
263  if (pUserData)
264  {
265  if (inMessage == AJA_Pnp_DeviceAdded || inMessage == AJA_Pnp_DeviceRemoved)
266  {
267  NTV2StreamPreview * pMainWindow (reinterpret_cast <NTV2StreamPreview *>(pUserData));
268  pMainWindow->devicesChanged ();
269  }
270  }
271 
272 } // PnpCallback
ntv2devicefeatures.h
Declares device capability functions.
types.h
Declares common types used in the ajabase library.
AJAPnpMessage
AJAPnpMessage
Definition: pnp.h:22
NTV2StreamGrabber::SetWithAudio
void SetWithAudio(const bool inWithAudio)
Enables or disables host audio playback.
Definition: ntv2streamgrabber.h:66
NTV2DeviceID
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
Definition: ntv2enums.h:20
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
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
ntv2streampreview.h
Header file for NTV2StreamPreview demo application. Demonstrates how to capture audio/video from NTV2...
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:84
AJAPnp::Uninstall
virtual AJAStatus Uninstall()
Uninstalls any previously-installed callback notifier.
Definition: pnp.cpp:45
NTV2StreamPreview
I am a QDialog that displays whatever video is present on the SDI inputs of an AJA device....
Definition: ntv2streampreview.h:30
NTV2InputSourceToString
std::string NTV2InputSourceToString(const NTV2InputSource inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:7215
ULWord
uint32_t ULWord
Definition: ajatypes.h:246
NTV2StreamGrabber::SetFixedReference
void SetFixedReference(bool fixed)
Definition: ntv2streamgrabber.h:92
NTV2_CC608_ChannelInvalid
@ NTV2_CC608_ChannelInvalid
Definition: ntv2caption608types.h:98
NTV2_INPUTSOURCE_INVALID
@ NTV2_INPUTSOURCE_INVALID
The invalid video input.
Definition: ntv2enums.h:1236
QButtonIterator
QListIterator< QAbstractButton * > QButtonIterator
Definition: ntv2streampreview.cpp:25
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
CNTV2Card
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:262
AJA_Pnp_DeviceRemoved
@ AJA_Pnp_DeviceRemoved
Definition: pnp.h:25
NTV2_NUM_INPUTSOURCES
@ NTV2_NUM_INPUTSOURCES
Definition: ntv2enums.h:1237
NTV2StreamPreview::~NTV2StreamPreview
~NTV2StreamPreview()
Definition: ntv2streampreview.cpp:136
NTV2InputSource
NTV2InputSource
Identifies a specific video input source.
Definition: ntv2enums.h:1221
NTV2StreamGrabber::SetInputSource
void SetInputSource(const NTV2InputSource inInputSource)
Sets the input to be used for capture on the AJA device being used.
Definition: ntv2streamgrabber.cpp:77
NTV2StreamGrabber
A QThread that captures audio/video from NTV2-compatible AJA devices and uses Qt signals to emit ARGB...
Definition: ntv2streamgrabber.h:42
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:237
QButtonIterator
QListIterator< QAbstractButton * > QButtonIterator
Definition: ntv2qtpreview.cpp:25
NTV2DeviceCanDoInputSource
bool NTV2DeviceCanDoInputSource(const NTV2DeviceID inDeviceID, const NTV2InputSource inInputSource)
Definition: ntv2devicefeatures.hpp:17462
NTV2Line21Channel
NTV2Line21Channel
The CEA-608 caption channels: CC1 thru CC4, TX1 thru TX4, plus XDS.
Definition: ntv2caption608types.h:82
NTV2StreamPreview::NTV2StreamPreview
NTV2StreamPreview(QWidget *parent=NULL, Qt::WindowFlags flags=Qt::WindowFlags())
Definition: ntv2streampreview.cpp:28
AJAPreviewWidget
Definition: ajapreviewwidget.h:36
STREAMPREVIEW_WIDGET_Y
#define STREAMPREVIEW_WIDGET_Y
Definition: ntv2streamgrabber.h:32
CNTV2DriverInterface::GetDeviceID
virtual NTV2DeviceID GetDeviceID(void)
Definition: ntv2driverinterface.cpp:371
NTV2_IOKINDS_SDI
@ NTV2_IOKINDS_SDI
Specifies SDI input/output kinds.
Definition: ntv2enums.h:1251
NTV2DeviceCanDoCustomAnc
bool NTV2DeviceCanDoCustomAnc(const NTV2DeviceID inDeviceID)
Definition: ntv2devicefeatures.hpp:2087
AJA_Pnp_DeviceAdded
@ AJA_Pnp_DeviceAdded
Definition: pnp.h:24
NTV2StreamGrabber::CheckFor4kInput
void CheckFor4kInput(const bool inCheckFor4K)
Enables or disables checking for 4K/UHD video (on devices that supported 4K/UHD).
Definition: ntv2streamgrabber.h:82
NTV2StreamGrabber::SetDeviceIndex
void SetDeviceIndex(const UWord inDeviceIndex)
Sets the AJA device to be used for capture.
Definition: ntv2streamgrabber.cpp:91
STREAMPREVIEW_WIDGET_X
#define STREAMPREVIEW_WIDGET_X
Definition: ntv2streamgrabber.h:31