AJA NTV2 SDK  18.0.0.2122
NTV2 SDK 18.0.0.2122
main.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 // Includes
9 #include "ntv2utils.h"
10 #include "ajatypes.h"
11 #include "ntv2m31publicinterface.h"
14 #include "ntv2encodehevc.h"
15 #include <signal.h>
16 #include <iostream>
17 #include <iomanip>
18 
19 using namespace std;
20 
21 
22 // Globals
23 static const M31VideoPreset kCodecPreset[] = {
27 
31 
42 
53 
62 
71 
80 
84 
93 
102 
108 
112 
116 
120 
123 
127 
131 
135 };
136 
142 };
143 
144 static const size_t gNumCodecPresets (sizeof(kCodecPreset)/sizeof(M31VideoPreset));
145 static const size_t gNumCodecFormats (sizeof(kCodecFormat)/sizeof(NTV2FrameBufferFormat));
146 static const size_t kNoSelection (1000000000);
147 static bool gGlobalQuit (false); // Set this "true" to exit gracefully
148 
149 
150 static void SignalHandler (int inSignal)
151 {
152  (void) inSignal;
153  gGlobalQuit = true;
154 }
155 
156 static int printPresets (void)
157 {
158  cout << "M31 Presets" << endl;
159  for (size_t ndx(0); ndx < gNumCodecPresets; ndx++)
160  {
161  const string presetStr (::NTV2M31VideoPresetToString (kCodecPreset[ndx], true));
162  if (!presetStr.empty())
163  cout << ndx << ": " << presetStr << endl;
164  }
165  return 0;
166 }
167 
168 static int printFormats (void)
169 {
170  cout << "M31 Formats" << endl;
171  for (size_t ndx(0); ndx < gNumCodecFormats; ndx++)
172  {
173  const string pixFormatStr (::NTV2FrameBufferFormatToString (kCodecFormat[ndx], true));
174  if (!pixFormatStr.empty())
175  cout << ndx << ": " << pixFormatStr << endl;
176  }
177  return 0;
178 }
179 
180 
181 int main (int argc, const char ** argv)
182 {
183  M31VideoPreset m31Preset (M31_NUMVIDEOPRESETS); // Codec preset
184  NTV2FrameBufferFormat pixelFormat (NTV2_FBF_NUMFRAMEBUFFERFORMATS); // Codec frame format
185  char * pWhatToList (AJA_NULL); // Value of --list argument
186  char * pDeviceSpec (AJA_NULL); // Device specifier string, if any
187  size_t codecFormat (kNoSelection); // Codec format index
188  size_t codecPreset (kNoSelection); // Codec preset index
189  ULWord channelNumber (1); // Number of the input channel to use
190  int codecQuad (0); // Codec quad mode
191  int timeCode (0); // Timecode burn mode
192  int tsiData (0); // Two sample interleave mode
193  int infoData (0); // Picture and encoded information
194  size_t maxFrames (kNoSelection); // Maximum number of catpured frames
195  UWord audioChannels (0); // Number of audio channels
196  poptContext optionsContext; // Context for parsing command line arguments
197 
198  AJADebug::Open();
199 
200  // Command line option descriptions:
201  const struct poptOption userOptionsTable [] =
202  {
203  {"audio", 'a', POPT_ARG_SHORT, &audioChannels, 0, "number of audio channels", "1-16"},
204  {"device", 'd', POPT_ARG_STRING, &pDeviceSpec, 0, "device to use", "index#, serial#, or model"},
205  {"channel", 'c', POPT_ARG_INT, &channelNumber, 0, "channel to use", "1-4"},
206  {"format", 'f', POPT_ARG_INT, &codecFormat, 0, "format to use", "use '-lf' for list"},
207  {"preset", 'p', POPT_ARG_INT, &codecPreset, 0, "codec preset to use", "use '-lp' for list"},
208  {"quad", 'q', POPT_ARG_NONE, &codecQuad, 0, "interpret 4 inputs as UHD", ""},
209  {"list", 'l', POPT_ARG_STRING, &pWhatToList, 0, "list options", "p or f (presets or formats)"},
210  {"tcb", 'b', POPT_ARG_NONE, &timeCode, 0, "add timecode burn to video", ""},
211  {"tsi", 't', POPT_ARG_NONE, &tsiData, 0, "two sample interleave mode", ""},
212  {"info", 'i', POPT_ARG_NONE, &infoData, 0, "write encoded info file", ""},
213  {"maxframes", 'x', POPT_ARG_INT |
214  POPT_ARGFLAG_OPTIONAL, &maxFrames, 0, "limit output file frames", ""},
217  };
218 
219  // Read command line arguments...
220  optionsContext = ::poptGetContext (AJA_NULL, argc, argv, userOptionsTable, 0);
221  ::poptGetNextOpt (optionsContext);
222  optionsContext = ::poptFreeContext (optionsContext);
223 
224  if (pWhatToList && string(pWhatToList) == "p")
225  return printPresets ();
226  else if (pWhatToList && string(pWhatToList) == "f")
227  return printFormats ();
228  else if (pWhatToList)
229  {cerr << "## ERROR: Invalid argument to --list option, expected 'p' or 'f'" << endl; return 2;}
230 
231  if ((codecFormat != kNoSelection) && (codecFormat >= int(gNumCodecFormats)))
232  {cerr << "## ERROR: Invalid M31 format " << codecFormat << " -- expected 0 thru " << (gNumCodecFormats) << endl; return 2;}
233 
234  if (codecFormat < int(gNumCodecFormats))
235  pixelFormat = kCodecFormat[codecFormat];
236 
237  if ((codecPreset != kNoSelection) && (codecPreset >= int(gNumCodecPresets)))
238  {cerr << "## ERROR: Invalid M31 preset " << codecPreset << " -- expected 0 thru " << (gNumCodecPresets) << endl; return 2;}
239 
240  if (codecPreset < int(gNumCodecPresets))
241  m31Preset = kCodecPreset[codecPreset];
242 
243  const NTV2Channel inputChannel (::GetNTV2ChannelForIndex(channelNumber - 1));
244  if (!NTV2_IS_VALID_CHANNEL(inputChannel) || inputChannel > NTV2_CHANNEL4)
245  {cerr << "## ERROR: Invalid channel number " << channelNumber << " -- expected 1 thru 4" << endl; return 2;}
246 
247  ::signal (SIGINT, SignalHandler);
248  #if defined (AJAMac)
249  ::signal (SIGHUP, SignalHandler);
250  ::signal (SIGQUIT, SignalHandler);
251  #endif
252 
253  // Instantiate the NTV2Capture object, using the specified AJA device...
254  const uint32_t hevcMaxFrames (maxFrames >= kNoSelection ? 0xffffffff : uint32_t(maxFrames));
255  NTV2EncodeHEVC hevcEncoder (pDeviceSpec ? string (pDeviceSpec) : "0", inputChannel,
256  m31Preset, pixelFormat, codecQuad ? true : false,
257  audioChannels, timeCode ? true : false,
258  infoData ? true : false, tsiData ? true : false, hevcMaxFrames);
259 
260  // Initialize the NTV2Capture instance...
261  if (AJA_FAILURE(hevcEncoder.Init()))
262  {cerr << "## ERROR: Initialization failed" << endl; return 1;}
263 
264  cout << endl
265  << "Capture: " << ::NTV2M31VideoPresetToString (hevcEncoder.GetCodecPreset(), false) << endl
266  << endl;
267 
268  // Run the capturer...
269  hevcEncoder.Run();
270 
271  cout << " Capture Capture" << endl
272  << " Frames Frames Buffer" << endl
273  << "Processed Dropped Level" << endl;
274 
275  // Loop til time to stop...
276  do
277  {
278  AVHevcStatus inputStatus;
279  hevcEncoder.GetStatus(inputStatus);
280  cout << setw(9) << inputStatus.framesProcessed
281  << setw(9) << inputStatus.framesDropped
282  << setw(9) << inputStatus.bufferLevel
283  << "\r" << flush;
284  AJATime::Sleep(1000);
285  } while (!gGlobalQuit);
286  cout << endl;
287 
288  // Quit the capturer...
289  hevcEncoder.Quit();
290 
291  return 0;
292 
293 } // main
int main(int argc, const char **argv)
Definition: main.cpp:30
static const M31VideoPreset kCodecPreset[]
Definition: main.cpp:23
NTV2Channel GetNTV2ChannelForIndex(const ULWord inIndex0)
Definition: ntv2utils.cpp:4697
NTV2FrameBufferFormat
Identifies a particular video frame buffer pixel format. See Device Frame Buffer Formats for details...
Definition: ntv2enums.h:219
10-Bit 4:2:2 2-Plane YCbCr
Definition: ntv2enums.h:252
#define POPT_ARG_SHORT
Definition: options_popt.h:82
static AJAStatus Open(bool incrementRefCount=false)
Definition: debug.cpp:44
#define AJA_FAILURE(_status_)
Definition: types.h:373
Declares the AJATime class.
virtual M31VideoPreset GetCodecPreset(void)
Get the codec preset.
Definition: json.hpp:5362
#define POPT_ARG_INT
Definition: options_popt.h:58
void SignalHandler(int inSignal)
Definition: main.cpp:26
Declares the NTV2EncodeHEVC class.
uint32_t ULWord
Definition: ajatypes.h:223
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1357
#define POPT_AUTOHELP
Definition: options_popt.h:227
poptContext poptGetContext(const char *name, int argc, const char **argv, const struct poptOption *options, unsigned int flags)
M31VideoPreset
Definition: ntv2m31enums.h:13
8-Bit 4:2:2 2-Plane YCbCr
Definition: ntv2enums.h:254
static int printFormats(void)
Definition: main.cpp:168
#define AJA_NULL
Definition: ajatypes.h:167
Declares the most fundamental data types used by NTV2. Since Windows NT was the first principal devel...
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
virtual void Quit(void)
Gracefully stops me from running.
virtual void GetStatus(AVHevcStatus &outStatus)
Provides status information about my input (capture) process.
#define POPT_ARGFLAG_OPTIONAL
Definition: options_popt.h:94
static const NTV2FrameBufferFormat kCodecFormat[]
Definition: main.cpp:137
#define NTV2_IS_VALID_CHANNEL(__x__)
Definition: ntv2enums.h:1371
static int printPresets(void)
Definition: main.cpp:156
10-Bit 4:2:0 2-Plane YCbCr
Definition: ntv2enums.h:251
virtual AJAStatus Run(void)
Runs me.
static const size_t gNumCodecFormats(sizeof(kCodecFormat)/sizeof(NTV2FrameBufferFormat))
std::string NTV2M31VideoPresetToString(const M31VideoPreset val, const bool retailDisplay=false)
Definition: ntv2utils.cpp:7144
Declares numerous NTV2 utility functions.
#define POPT_TABLEEND
Definition: options_popt.h:222
Instances of me capture frames in real time from a video signal provided to an input of an AJA device...
uint16_t UWord
Definition: ajatypes.h:221
std::string NTV2FrameBufferFormatToString(const NTV2FrameBufferFormat inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:6936
Specifies channel or FrameStore 4 (or the 4th item).
Definition: ntv2enums.h:1362
poptContext poptFreeContext(poptContext con)
int poptGetNextOpt(poptContext con)
static const size_t kNoSelection(1000000000)
#define POPT_ARG_STRING
Definition: options_popt.h:57
static bool gGlobalQuit((0))
8-Bit 4:2:0 2-Plane YCbCr
Definition: ntv2enums.h:253
#define POPT_ARG_NONE
Definition: options_popt.h:56
static const size_t gNumCodecPresets(sizeof(kCodecPreset)/sizeof(M31VideoPreset))
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.