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 */
9 // Includes
10 #include "ntv2dolbycapture.h"
11 #include "ajabase/system/process.h"
12 #include <signal.h>
13 
14 using namespace std;
15 
16 
17 // Globals
18 static bool gGlobalQuit (false); // Set this "true" to exit gracefully
19 
20 
21 static void SignalHandler (int inSignal)
22 {
23  (void) inSignal;
24  gGlobalQuit = true;
25 }
26 
27 
28 int main (int argc, const char ** argv)
29 {
30  int showVersion (0); // Show version?
31  char * pDeviceSpec (AJA_NULL); // Device specifier string, if any
32  char * pPixelFormat (AJA_NULL); // Pixel format argument
33  char * pFramesSpec (AJA_NULL); // AutoCirculate frames spec
34  char * pInputSrcSpec (AJA_NULL); // SDI source spec
35  uint32_t channelNumber (1); // Channel/FrameStore to use
36  int doMultiFormat (0); // Enable multi-format?
37  int doRecordAux (0); // Record aux?
38  int doRecordAudio (0); // Record audio?
39  int doRecordDolby (0); // Record dolby?
40  int doAudioFilter (0); // Enable anc audio filter?
41  int doFrameStats (0); // Output per frame data?
44 
45  // Command line option descriptions:
46  const CNTV2DemoCommon::PoptOpts optionsTable [] =
47  {
48  {"version", 0, POPT_ARG_NONE, &showVersion, 0, "show version & exit", AJA_NULL },
49  {"device", 'd', POPT_ARG_STRING, &pDeviceSpec, 0, "device to use", "index#, serial#, or model" },
50  {"channel", 'c', POPT_ARG_INT, &channelNumber, 0, "channel to use", "1-8" },
51  {"multiFormat", 'm', POPT_ARG_NONE, &doMultiFormat, 0, "use multi-format/channel", AJA_NULL },
52  {"pixelFormat", 'p', POPT_ARG_STRING, &pPixelFormat, 0, "pixel format to use", "'?' or 'list' to list" },
53  {"frames", 0, POPT_ARG_STRING, &pFramesSpec, 0, "frames to AutoCirculate", "num[@min] or min-max" },
54  {"input", 'i', POPT_ARG_STRING, &pInputSrcSpec, 0, "which HDMI input", "?=list" },
55  {"aux", 0, POPT_ARG_NONE, &doRecordAux, 0, "record all aux to file", AJA_NULL },
56  {"audio", 0, POPT_ARG_NONE, &doRecordAudio, 0, "record aux audio to file", AJA_NULL },
57  {"dolby", 0, POPT_ARG_NONE, &doRecordDolby, 0, "record dolby to file", AJA_NULL },
58  {"filter", 'x', POPT_ARG_NONE, &doAudioFilter, 0, "only capture audio anc", AJA_NULL },
59  {"stats", 's', POPT_ARG_NONE, &doFrameStats, 0, "show per-frame stats", AJA_NULL },
62  };
63 
64  CNTV2DemoCommon::Popt popt(argc, argv, optionsTable);
65  if (!popt)
66  {cerr << "## ERROR: " << popt.errorStr() << endl; return 2;}
67  if (showVersion)
68  {cout << argv[0] << ", NTV2 SDK " << ::NTV2Version() << endl; return 0;}
69 
70  // Device
71  const string deviceSpec (pDeviceSpec ? pDeviceSpec : "0");
72  if (!CNTV2DemoCommon::IsValidDevice(deviceSpec))
73  return 1;
74 
75  DolbyCaptureConfig config(deviceSpec);
76 
77  // Channel
78  if ((channelNumber < 1) || (channelNumber > 8))
79  {cerr << "## ERROR: Invalid channel number " << channelNumber << " -- expected 1 thru 8" << endl; return 1;}
80  config.fInputChannel = NTV2Channel(channelNumber - 1);
81 
82  // Input source
83  const string legalSources (CNTV2DemoCommon::GetInputSourceStrings(NTV2_IOKINDS_HDMI, deviceSpec));
84  const string inputSourceStr (pInputSrcSpec ? CNTV2DemoCommon::ToLower(string(pInputSrcSpec)) : "");
85  if (inputSourceStr == "?" || inputSourceStr == "list")
86  {cout << legalSources << endl; return 0;}
87  if (!inputSourceStr.empty())
88  {
91  {cerr << "## ERROR: Input source '" << inputSourceStr << "' not one of:" << endl << legalSources << endl; return 1;}
92  } // if input source specified
93 
94  // Pixel Format
95  const string pixelFormatStr (pPixelFormat ? pPixelFormat : "");
96  config.fPixelFormat = pixelFormatStr.empty() ? NTV2_FBF_8BIT_YCBCR : CNTV2DemoCommon::GetPixelFormatFromString(pixelFormatStr);
97  if (pixelFormatStr == "?" || pixelFormatStr == "list")
98  {cout << CNTV2DemoCommon::GetPixelFormatStrings(PIXEL_FORMATS_ALL, pDeviceSpec ? deviceSpec : "") << endl; return 0;}
99  else if (!pixelFormatStr.empty() && !NTV2_IS_VALID_FRAME_BUFFER_FORMAT(config.fPixelFormat))
100  {
101  cerr << "## ERROR: Invalid '--pixelFormat' value '" << pixelFormatStr << "' -- expected values:" << endl
103  return 2;
104  }
105 
106  // AutoCirculate Frames
107  static const string legalFramesSpec("{frameCount}[@{firstFrameNum}] or {firstFrameNum}-{lastFrameNum}");
108  const string framesSpec (pFramesSpec ? pFramesSpec : "");
109  if (!framesSpec.empty())
110  {
111  const string parseResult(config.fFrames.setFromString(framesSpec));
112  if (!parseResult.empty())
113  {cerr << "## ERROR: Bad 'frames' spec '" << framesSpec << "'\n## " << parseResult << endl; return 1;}
114  }
115  if (!config.fFrames.valid())
116  {cerr << "## ERROR: Bad 'frames' spec '" << framesSpec << "'\n## Expected " << legalFramesSpec << endl; return 1;}
117 
118  // HDMI Aux Capture
119  if (doRecordAux)
120  { // invent a file name...
121  ostringstream fileName; fileName << "ntv2dolbycapture-" << deviceSpec << "-"
122  << ::NTV2ChannelToString(config.fInputChannel,true) << "-" << AJAProcess::GetPid() << ".aux";
123  config.fAncDataFilePath = fileName.str();
124  }
125 
126  // Audio Capture
127  if (doRecordAudio)
128  { // invent a file name...
129  ostringstream fileName; fileName << "ntv2dolbycapture-" << deviceSpec << "-"
130  << ::NTV2ChannelToString(config.fInputChannel,true) << "-" << AJAProcess::GetPid() << ".raw";
131  config.fAudioDataFilePath = fileName.str();
132  }
133 
134  // Dolby Capture
135  if (doRecordDolby)
136  { // invent a file name...
137  ostringstream fileName; fileName << "ntv2dolbycapture-" << deviceSpec << "-"
138  << ::NTV2ChannelToString(config.fInputChannel,true) << "-" << AJAProcess::GetPid() << ".ec3";
139  config.fDolbyDataFilePath = fileName.str();
140  }
141 
142  config.fDoAudioFilter = doAudioFilter ? true : false;
143  config.fDoFrameStats = doFrameStats ? true : false;
144  config.fDoMultiFormat = doMultiFormat ? true : false;
145  config.fWithAnc = doRecordAux ? true : false;
146  config.fWithAudio = doRecordAudio ? true : false;
147 
148  // Instantiate and initialize the ntv2dolbycapture object
149  NTV2DolbyCapture capturer(config);
150  status = capturer.Init();
151  if (AJA_FAILURE(status))
152  {cout << "## ERROR: Initialization failed: " << ::AJAStatusToString(status) << endl; return 1;}
153 
154  ::signal (SIGINT, SignalHandler);
155  #if defined (AJAMac)
156  ::signal (SIGHUP, SignalHandler);
157  ::signal (SIGQUIT, SignalHandler);
158  #endif
159 
160  // Run the capturer...
161  capturer.Run();
162 
163  cout << " Frames Frames Buffer" << endl
164  << " Captured Dropped Level" << endl;
165  do
166  { // Poll its status until stopped...
167  ULWord framesProcessed, framesDropped, bufferLevel;
168  capturer.GetACStatus (framesProcessed, framesDropped, bufferLevel);
169  cout << setw(9) << framesProcessed << setw(9) << framesDropped << setw(9) << bufferLevel << "\r" << flush;
170  AJATime::Sleep(2000);
171  } while (!gGlobalQuit); // loop til quit time
172 
173  cout << endl;
174  return 0;
175 
176 } // main
int main(int argc, const char **argv)
Definition: main.cpp:30
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())
Specifies HDMI input/output kinds.
Definition: ntv2enums.h:1293
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
void SignalHandler(int inSignal)
Definition: main.cpp:26
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
bool fDoFrameStats
if true, output per frame statistics
bool fWithAudio
If true, also capture Audio.
#define POPT_AUTOHELP
Definition: options_popt.h:227
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.
#define AJA_NULL
Definition: ajatypes.h:167
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
bool fDoAudioFilter
If true, capture only audio anc.
std::string fDolbyDataFilePath
Optional path to Dolby binary data file.
Declares the AJAProcess class.
virtual AJAStatus Run(void)
Runs me.
NTV2InputSource fInputSource
The device input connector to use.
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1284
Declares the NTV2DolbyCapture class.
#define POPT_TABLEEND
Definition: options_popt.h:222
I capture HDMI Dolby audio from an HDMI input of an AJA device.
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.
static bool IsValidDevice(const std::string &inDeviceSpec)
std::string AJAStatusToString(const AJAStatus inStatus, const bool inDetailed)
Definition: debug.cpp:981
virtual void GetACStatus(ULWord &outGoodFrames, ULWord &outDroppedFrames, ULWord &outBufferLevel)
Provides status information about my input (capture) process.
#define NTV2_IS_VALID_FRAME_BUFFER_FORMAT(__s__)
Definition: ntv2enums.h:263
bool valid(void) const
Definition: ntv2utils.h:988
std::string NTV2ChannelToString(const NTV2Channel inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:5727
#define POPT_ARG_STRING
Definition: options_popt.h:57
This class is used to configure an NTV2Capture instance.
std::string fAudioDataFilePath
Optional path to Audio binary data file.
#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.
static bool gGlobalQuit((0))
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:223