AJA NTV2 SDK  18.1.0.2262
NTV2 SDK 18.1.0.2262
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  { // Instantiate and initialize the NTV2Capture object...
130  NTV2Capture capturer(config);
131  AJAStatus status = capturer.Init();
132  if (AJA_FAILURE(status))
133  {cout << "## ERROR: Initialization failed: " << ::AJAStatusToString(status) << endl; return 1;}
134 
135  ::signal (SIGINT, SignalHandler);
136  #if defined(AJAMac)
137  ::signal (SIGHUP, SignalHandler);
138  ::signal (SIGQUIT, SignalHandler);
139  #endif
140 
141  // Run it...
142  capturer.Run();
143 
144  cout << " Frames Frames Buffer" << endl
145  << " Captured Dropped Level" << endl;
146  do
147  { // Poll its status until stopped...
148  ULWord framesProcessed, framesDropped, bufferLevel;
149  capturer.GetACStatus (framesProcessed, framesDropped, bufferLevel);
150  cout << setw(9) << framesProcessed << setw(9) << framesDropped << setw(9) << bufferLevel << "\r" << flush;
151  AJATime::Sleep(2000);
152  } while (!gGlobalQuit); // loop til done
153  cout << endl;
154  } // NTV2Capture scope
155  return 0;
156 
157 } // 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:1294
Declares the NTV2Capture class.
static void SignalHandler(int inSignal)
Definition: main.cpp:22
AJAStatus
Definition: types.h:380
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)
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:1359
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:1286
#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.
std::string AJAStatusToString(const AJAStatus inStatus, const bool inDetailed)
Definition: debug.cpp:987
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
Definition: ntv2capture.cpp:73
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:265
bool valid(void) const
Definition: ntv2utils.h:987
std::string NTV2ChannelToString(const NTV2Channel inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:5730
#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:225