AJA NTV2 SDK  18.1.0.2439
NTV2 SDK 18.1.0.2439
main.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
9 // Includes
10 #include "ntv2capture.h"
11 #include "ajabase/system/process.h" // for GetPID
12 #include "ajabase/common/common.h" // for strip
13 #include <signal.h>
14 
15 using namespace std;
16 
17 
18 // Globals
19 static bool gGlobalQuit (false); // Set this "true" to exit gracefully
20 
21 
22 static void SignalHandler (int inSignal)
23 {
24  (void) inSignal;
25  gGlobalQuit = true;
26 }
27 
28 
29 int main (int argc, const char ** argv)
30 {
31  int showVersion (0); // Show version?
32  char * pDeviceSpec (AJA_NULL); // Device specifier string, if any
33  char * pPixelFormat (AJA_NULL); // Pixel format argument
34  char * pFramesSpec (AJA_NULL); // AutoCirculate frames spec
35  char * pAncFilePath (AJA_NULL); // Anc data filepath to record
36  char * pInputSrcSpec (AJA_NULL); // SDI source spec
37  int channelNumber (1); // Channel/FrameStore to use
38  int doMultiFormat (0); // MultiFormat mode?
39  int noAudio (0); // Disable audio capture?
40  int captureAnc (0); // Capture anc?
42 
43  // Command line option descriptions:
44  const CNTV2DemoCommon::PoptOpts optionsTable [] =
45  {
46  {"version", 0, POPT_ARG_NONE, &showVersion, 0, "show version & exit", AJA_NULL },
47  {"device", 'd', POPT_ARG_STRING, &pDeviceSpec, 0, "device to use", "index#, serial#, or model" },
48  {"channel", 'c', POPT_ARG_INT, &channelNumber, 0, "channel to use", "1-8" },
49  {"multiFormat", 'm', POPT_ARG_NONE, &doMultiFormat, 0, "use multi-format/channel", AJA_NULL },
50  {"pixelFormat", 'p', POPT_ARG_STRING, &pPixelFormat, 0, "pixel format to use", "'?' or 'list' to list" },
51  {"frames", 0, POPT_ARG_STRING, &pFramesSpec, 0, "frames to AutoCirculate", "num[@min] or min-max" },
52  {"input", 'i', POPT_ARG_STRING, &pInputSrcSpec, 0, "which SDI input", "1-8, ?=list" },
53  {"anc", 0, POPT_ARG_STRING, &pAncFilePath, 0, "record anc to file", "path/to/binary/data/file" },
54  {AJA_NULL, 'a', POPT_ARG_NONE, &captureAnc, 0, "capture anc?", AJA_NULL },
55  {"noaudio", 0, POPT_ARG_NONE, &noAudio, 0, "disable audio capture", AJA_NULL },
58  };
59  CNTV2DemoCommon::Popt popt(argc, argv, optionsTable);
60  if (!popt)
61  {cerr << "## ERROR: " << popt.errorStr() << endl; return 2;}
62  if (!popt.otherArgs().empty())
63  {cerr << "## WARNING: ignored argument(s): '" << aja::join(popt.otherArgs(), "', '") << "'" << endl; return 2;}
64  if (showVersion)
65  {cout << argv[0] << ", NTV2 SDK " << ::NTV2Version() << endl; return 0;}
66 
67  // Device
68  const string deviceSpec (pDeviceSpec ? pDeviceSpec : "0");
69  CaptureConfig config(deviceSpec);
70 
71  // Channel
72  if ((channelNumber < 1) || (channelNumber > 8))
73  {cerr << "## ERROR: Invalid channel number " << channelNumber << " -- expected 1 thru 8" << endl; return 1;}
74  config.fInputChannel = NTV2Channel(channelNumber - 1);
75 
76  // Input source
77  const string legalSources (CNTV2DemoCommon::GetInputSourceStrings(NTV2_IOKINDS_SDI, deviceSpec));
78  const string inputSourceStr (pInputSrcSpec ? CNTV2DemoCommon::ToLower(string(pInputSrcSpec)) : "");
79  if (inputSourceStr == "?" || inputSourceStr == "list")
80  {cout << legalSources << endl; return 0;}
81  if (!inputSourceStr.empty())
82  {
85  {cerr << "## ERROR: Input source '" << inputSourceStr << "' not one of:" << endl << legalSources << endl; return 1;}
86  } // if input source specified
87 
88  // Pixel Format
89  const string pixelFormatStr (pPixelFormat ? pPixelFormat : "");
90  config.fPixelFormat = pixelFormatStr.empty() ? NTV2_FBF_8BIT_YCBCR : CNTV2DemoCommon::GetPixelFormatFromString(pixelFormatStr);
91  if (pixelFormatStr == "?" || pixelFormatStr == "list")
92  {cout << CNTV2DemoCommon::GetPixelFormatStrings(PIXEL_FORMATS_ALL, pDeviceSpec ? deviceSpec : "") << endl; return 0;}
93  else if (!pixelFormatStr.empty() && !NTV2_IS_VALID_FRAME_BUFFER_FORMAT(config.fPixelFormat))
94  {
95  cerr << "## ERROR: Invalid '--pixelFormat' value '" << pixelFormatStr << "' -- expected values:" << endl
97  return 2;
98  }
99 
100  // AutoCirculate Frames
101  static const string legalFramesSpec ("{frameCount}[@{firstFrameNum}] or {firstFrameNum}-{lastFrameNum}");
102  const string framesSpec (pFramesSpec ? pFramesSpec : "");
103  if (!framesSpec.empty())
104  {
105  const string parseResult(config.fFrames.setFromString(framesSpec));
106  if (!parseResult.empty())
107  {cerr << "## ERROR: Bad 'frames' spec '" << framesSpec << "'\n## " << parseResult << endl; return 1;}
108  }
109  if (!config.fFrames.valid())
110  {cerr << "## ERROR: Bad 'frames' spec '" << framesSpec << "'\n## Expected " << legalFramesSpec << endl; return 1;}
111 
112  // Anc Capture
113  string ancFilePath (pAncFilePath ? pAncFilePath : "");
114  ancFilePath = aja::strip(ancFilePath);
115  if (ancFilePath.empty() && pAncFilePath)
116  { // User specified an empty filePath -- invent a file name...
117  ostringstream fileName; fileName << "ntv2capture-" << deviceSpec << "-"
118  << ::NTV2ChannelToString(config.fInputChannel,true) << "-" << AJAProcess::GetPid() << ".anc";
119  ancFilePath = fileName.str();
120  }
121  if (pAncFilePath)
122  captureAnc = 1; // Specifying target anc file automatically enables anc capture
123 
124  config.fWithAudio = noAudio ? false : true; // Capture audio?
125  config.fAncDataFilePath = ancFilePath; // Anc capture file path
126  config.fWithAnc = captureAnc ? true : false; // Capture anc?
127  config.fDoMultiFormat = doMultiFormat ? true : false; // Multiformat mode?
128 
129  int result (0);
130  do
131  { // Instantiate and initialize the NTV2Capture object...
132  NTV2Capture capturer(config);
133  if (AJA_FAILURE(capturer.Init()))
134  {result = 1; break;}
135 
136  ::signal (SIGINT, SignalHandler);
137  #if defined(AJAMac)
138  ::signal (SIGHUP, SignalHandler);
139  ::signal (SIGQUIT, SignalHandler);
140  #endif
141 
142  // Run it...
143  capturer.Run();
144 
145  cout << " Frames Frames Buffer" << endl
146  << " Captured Dropped Level" << endl;
147  do
148  { // Poll its status until stopped...
149  ULWord framesProcessed, framesDropped, bufferLevel;
150  capturer.GetACStatus (framesProcessed, framesDropped, bufferLevel);
151  cout << setw(9) << framesProcessed << setw(9) << framesDropped << setw(9) << bufferLevel << "\r" << flush;
152  AJATime::Sleep(2000);
153  } while (!gGlobalQuit); // loop til done
154  cout << endl;
155  } while (false); // NTV2Capture scope
156  return result;
157 
158 } // main
int main(int argc, const char **argv)
Definition: main.cpp:30
Instances of me capture frames in real time from a video signal provided to an input of an AJA device...
Definition: ntv2capture.h:19
Specifies SDI input/output kinds.
Definition: ntv2enums.h:1296
Declares the NTV2Capture class.
static void SignalHandler(int inSignal)
Definition: main.cpp:22
bool fDoMultiFormat
If true, use multi-format/multi-channel mode, if device supports it; otherwise normal mode...
static AJAStatus Open(bool incrementRefCount=false)
Definition: debug.cpp:44
static uint64_t GetPid()
Definition: process.cpp:35
#define AJA_FAILURE(_status_)
Definition: types.h:373
static std::string GetInputSourceStrings(const NTV2IOKinds inKinds=NTV2_IOKINDS_ALL, const std::string inDevSpec=std::string())
static std::string GetPixelFormatStrings(const NTV2PixelFormatKinds inKinds=PIXEL_FORMATS_ALL, const std::string inDevSpec=std::string())
bool fWithAnc
If true, also capture Anc.
std::string setFromString(const std::string &inStr)
Resets me from the given character string that should contain a human-readable frame range...
Definition: ntv2utils.cpp:4256
Definition: json.hpp:5362
#define POPT_ARG_INT
Definition: options_popt.h:58
#define false
uint32_t ULWord
Definition: ajatypes.h:236
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They&#39;re also commonly use...
Definition: ntv2enums.h:1361
virtual AJAStatus Run(void)
Runs me.
bool fWithAudio
If true, also capture Audio.
#define POPT_AUTOHELP
Definition: options_popt.h:227
virtual void GetACStatus(ULWord &outGoodFrames, ULWord &outDroppedFrames, ULWord &outBufferLevel)
Provides status information about my input (capture) process.
NTV2Channel fInputChannel
The device channel to use.
#define true
std::string NTV2Version(const bool inDetailed=false)
Definition: ntv2version.cpp:41
std::string fAncDataFilePath
Optional path to Anc binary data file.
This class is used to configure an NTV2Capture instance.
#define AJA_NULL
Definition: ajatypes.h:180
virtual const NTV2StringList & otherArgs(void) const
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
static std::string ToLower(const std::string &inStr)
Returns the given string after converting it to lower case.
virtual const std::string & errorStr(void) const
static bool gGlobalQuit((0))
Declares the AJAProcess class.
std::string & strip(std::string &str, const std::string &ws)
Definition: common.cpp:461
NTV2InputSource fInputSource
The device input connector to use.
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1288
#define POPT_TABLEEND
Definition: options_popt.h:222
static NTV2InputSource GetInputSourceFromString(const std::string &inStr, const NTV2IOKinds inKinds=NTV2_IOKINDS_ALL, const std::string inDevSpec=std::string())
Returns the NTV2InputSource that matches the given string.
NTV2ACFrameRange fFrames
AutoCirculate frame count or range.
NTV2PixelFormat fPixelFormat
Pixel format to use.
Private include file for all ajabase sources.
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
Definition: ntv2capture.cpp:72
std::string join(const std::vector< std::string > &parts, const std::string &delim)
Definition: common.cpp:468
#define NTV2_IS_VALID_FRAME_BUFFER_FORMAT(__s__)
Definition: ntv2enums.h:267
bool valid(void) const
Definition: ntv2utils.h:1005
std::string NTV2ChannelToString(const NTV2Channel inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:5731
#define POPT_ARG_STRING
Definition: options_popt.h:57
#define POPT_ARG_NONE
Definition: options_popt.h:56
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.
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:227