AJA NTV2 SDK  17.5.0.1242
NTV2 SDK 17.5.0.1242
main.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
10 // Includes
11 #include "ntv2burn.h"
12 #include <signal.h>
13 #include <iostream>
14 #include <iomanip>
15 
16 using namespace std;
17 
18 
19 // Globals
20 static bool gGlobalQuit (false);
21 
22 
23 static void SignalHandler (int inSignal)
24 {
25  (void) inSignal;
26  gGlobalQuit = true;
27 }
28 
29 
30 int main (int argc, const char ** argv)
31 {
32  char * pDeviceSpec (AJA_NULL); // Which device to use
33  char * pInputSrcSpec (AJA_NULL); // SDI source spec
34  char * pOutputDest (AJA_NULL); // SDI output spec (sdi1 ... sdi8)
35  char * pTcSource (AJA_NULL); // Time code source string
36  char * pPixelFormat (AJA_NULL); // Pixel format spec
37  char * pInFramesSpec (AJA_NULL); // Input AutoCirculate frames spec
38  char * pOutFramesSpec (AJA_NULL); // Output AutoCirculate frames spec
39  int doMultiFormat (0); // MultiFormat mode?
40  int showVersion (0); // Show version?
41  int noAudio (0); // Disable audio?
42  int noVideo (0); // Disable video?
43  int noAnc (0); // Disable capture/playback of anc data?
44  int doVanc (0); // Use tall-frame VANC?
45  int verbose (0); // Verbose mode?
47 
48  // Command line option descriptions:
49  const struct poptOption optionsTable [] =
50  {
51  {"version", 0, POPT_ARG_NONE, &showVersion, 0, "show version & exit", AJA_NULL },
52  {"device", 'd', POPT_ARG_STRING, &pDeviceSpec, 0, "device to use", "index#, serial#, or model" },
53  {"multiFormat", 'm', POPT_ARG_NONE, &doMultiFormat, 0, "use multi-format/channel", AJA_NULL },
54  {"pixelFormat", 'p', POPT_ARG_STRING, &pPixelFormat, 0, "pixel format to use", "'?' or 'list' to list" },
55  {"input", 'i', POPT_ARG_STRING, &pInputSrcSpec, 0, "input to use", "1-8, ?=list" },
56  {"output", 'o', POPT_ARG_STRING, &pOutputDest, 0, "output to use", "'?' or 'list' to list" },
57  {"noaudio", 0, POPT_ARG_NONE, &noAudio, 0, "disable audio?", AJA_NULL },
58  {"novideo", 0, POPT_ARG_NONE, &noVideo, 0, "disable video?", AJA_NULL },
59  {"noanc", 0, POPT_ARG_NONE, &noAnc, 0, "disable anc?", AJA_NULL },
60  {"vanc", 0, POPT_ARG_NONE, &doVanc, 0, "enable tall-frame VANC?", AJA_NULL },
61  {"verbose", 0, POPT_ARG_NONE, &verbose, 0, "verbose mode?", AJA_NULL },
62  {"iframes", 0, POPT_ARG_STRING, &pInFramesSpec, 0, "input AutoCirc frames", "num[@min] or min-max" },
63  {"oframes", 0, POPT_ARG_STRING, &pOutFramesSpec,0, "output AutoCirc frames", "num[@min] or min-max" },
64  {"tcsource", 't', POPT_ARG_STRING, &pTcSource, 0, "time code source", "'?' to list" },
67  };
68  CNTV2DemoCommon::Popt popt(argc, argv, optionsTable);
69  if (!popt)
70  {cerr << "## ERROR: " << popt.errorStr() << endl; return 2;}
71  if (showVersion)
72  {cout << argv[0] << ", NTV2 SDK " << ::NTV2Version() << endl; return 0;}
73 
74  // Device
75  const string deviceSpec (pDeviceSpec ? pDeviceSpec : "0");
76  if (!CNTV2DemoCommon::IsValidDevice(deviceSpec))
77  return 1;
78 
79  BurnConfig config(deviceSpec);
80 
81  // Input source
82  const string inputSourceStr (pInputSrcSpec ? CNTV2DemoCommon::ToLower(string(pInputSrcSpec)) : "");
83  const string legalSources (CNTV2DemoCommon::GetInputSourceStrings(NTV2_IOKINDS_ALL, pDeviceSpec ? deviceSpec : ""));
84  config.fInputSource = CNTV2DemoCommon::GetInputSourceFromString(inputSourceStr, NTV2_IOKINDS_ALL, pDeviceSpec ? deviceSpec : "");
85  if (inputSourceStr == "?" || inputSourceStr == "list")
86  {cout << legalSources << endl; return 0;}
87  if (!inputSourceStr.empty() && !NTV2_IS_VALID_INPUT_SOURCE(config.fInputSource))
88  {cerr << "## ERROR: Input source '" << inputSourceStr << "' not one of:" << endl << legalSources << endl; return 1;}
89 
90  // Output destination
91  const string outputDestStr (pOutputDest ? CNTV2DemoCommon::ToLower(string(pOutputDest)) : "");
92  const string legalOutputs (CNTV2DemoCommon::GetOutputDestinationStrings(NTV2_IOKINDS_ALL, pDeviceSpec ? deviceSpec : ""));
93  config.fOutputDest = CNTV2DemoCommon::GetOutputDestinationFromString(outputDestStr, NTV2_IOKINDS_ALL, pDeviceSpec ? deviceSpec : "");
94  if (outputDestStr == "?" || outputDestStr == "list")
95  {cout << legalOutputs << endl; return 0;}
96  if (!outputDestStr.empty() && !NTV2_IS_VALID_OUTPUT_DEST(config.fOutputDest))
97  {cerr << "## ERROR: Output '" << outputDestStr << "' not of:" << endl << legalOutputs << endl; return 1;}
98 
99  // Pixel Format
100  const string pixelFormatStr (pPixelFormat ? pPixelFormat : "");
101  config.fPixelFormat = pixelFormatStr.empty() ? NTV2_FBF_8BIT_YCBCR : CNTV2DemoCommon::GetPixelFormatFromString(pixelFormatStr);
102  if (pixelFormatStr == "?" || pixelFormatStr == "list")
103  {cout << CNTV2DemoCommon::GetPixelFormatStrings(PIXEL_FORMATS_ALL, pDeviceSpec ? deviceSpec : "") << endl; return 0;}
104  if (!pixelFormatStr.empty() && !NTV2_IS_VALID_FRAME_BUFFER_FORMAT(config.fPixelFormat))
105  {
106  cerr << "## ERROR: Invalid '--pixelFormat' value '" << pixelFormatStr << "' -- expected values:" << endl
108  return 2;
109  }
110 
111  // Timecode source...
112  const string tcSourceStr (pTcSource ? CNTV2DemoCommon::ToLower(pTcSource) : "");
113  const string legalTCSources (CNTV2DemoCommon::GetTCIndexStrings(TC_INDEXES_ALL, pDeviceSpec ? deviceSpec : ""));
115  if (tcSourceStr == "?" || tcSourceStr == "list")
116  {cout << legalTCSources << endl; return 0;}
117  if (!tcSourceStr.empty() && !NTV2_IS_VALID_TIMECODE_INDEX(config.fTimecodeSource))
118  {cerr << "## ERROR: Timecode source '" << tcSourceStr << "' not one of these:" << endl << legalTCSources << endl; return 1;}
119 
120  // InputFrames
121  string framesSpec(pInFramesSpec ? pInFramesSpec : "");
122  static const string legalFrmSpec("{frameCount}[@{firstFrameNum}] or {firstFrameNum}-{lastFrameNum}");
123  if (!framesSpec.empty())
124  { const string parseResult(config.fInputFrames.setFromString(framesSpec));
125  if (!parseResult.empty())
126  {cerr << "## ERROR: Bad '--iframes' spec '" << framesSpec << "'" << endl << "## " << parseResult << endl; return 1;}
127  }
128  if (!config.fInputFrames.valid())
129  {cerr << "## ERROR: Bad '--iframes' spec '" << framesSpec << "'" << endl << "## Expected " << legalFrmSpec << endl; return 1;}
130 
131  // OutputFrames
132  framesSpec = pOutFramesSpec ? pOutFramesSpec : "";
133  if (!framesSpec.empty())
134  { const string parseResult(config.fOutputFrames.setFromString(framesSpec));
135  if (!parseResult.empty())
136  {cerr << "## ERROR: Bad '--oframes' spec '" << framesSpec << "'" << endl << "## " << parseResult << endl; return 1;}
137  }
138  if (!config.fOutputFrames.valid())
139  {cerr << "## ERROR: Bad '--oframes' spec '" << framesSpec << "'" << endl << "## Expected " << legalFrmSpec << endl; return 1;}
140 
141  if (noVideo && noAudio)
142  {cerr << "## ERROR: '--novideo' and '--noaudio' cannot both be specified" << endl; return 1;}
143  config.fDoMultiFormat = doMultiFormat ? true : false;
144  config.fSuppressAudio = noAudio ? true : false;
145  config.fSuppressVideo = noVideo ? true : false;
146  config.fVerbose = verbose ? true : false;
147  config.fWithAnc = noAnc ? false : true;
148  config.fWithTallFrames = doVanc ? true : false;
149  if (!config.fWithAnc && config.fWithTallFrames)
150  {cerr << "## ERROR: '--noanc' and '--vanc' are contradictory" << endl; return 1;}
151  if (!config.fWithAnc && config.fWithHanc)
152  {cerr << "## ERROR: '--noanc' and '--hanc' are contradictory" << endl; return 1;}
153 
154  // Instantiate the NTV2Burn object...
155  NTV2Burn burner (config);
156 
157  // Initialize the NTV2Burn instance...
158  AJAStatus status (burner.Init());
159  if (AJA_FAILURE(status))
160  {cerr << "## ERROR: Initialization failed, status=" << status << endl; return 4;}
161 
162  ::signal (SIGINT, SignalHandler);
163  #if defined (AJAMac)
164  ::signal (SIGHUP, SignalHandler);
165  ::signal (SIGQUIT, SignalHandler);
166  #endif
167 
168  // Start the burner's capture and playout threads...
169  burner.Run();
170 
171  // Loop until told to stop...
172  cout << " Capture Playout Capture Playout" << endl
173  << " Frames Frames Frames Buffer Buffer" << endl
174  << "Processed Dropped Dropped Level Level" << endl;
175  do
176  {
177  AUTOCIRCULATE_STATUS inputStatus, outputStatus;
178  burner.GetStatus (inputStatus, outputStatus);
179  cout << setw(9) << inputStatus.GetProcessedFrameCount()
180  << setw(9) << inputStatus.GetDroppedFrameCount()
181  << setw(9) << outputStatus.GetDroppedFrameCount()
182  << setw(9) << inputStatus.GetBufferLevel()
183  << setw(9) << outputStatus.GetBufferLevel()
184  << "\r" << flush;
185  AJATime::Sleep(2000);
186  } while (!gGlobalQuit); // loop until signaled
187 
188  cout << endl;
189  return 0;
190 
191 } // main
BurnConfig::fVerbose
bool fVerbose
If true, emit explanatory messages to stdout/stderr. Defaults to false.
Definition: ntv2democommon.h:405
gGlobalQuit
static bool gGlobalQuit((0))
Set this "true" to exit gracefully.
NTV2Burn::Init
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
Definition: ntv2burn.cpp:72
poptOption
Definition: options_popt.h:148
CNTV2DemoCommon::GetPixelFormatFromString
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.
Definition: ntv2democommon.cpp:637
BurnConfig::fOutputDest
NTV2OutputDest fOutputDest
The device output connector to use (NTV2_OUTPUTDESTINATION_INVALID means unspecified)
Definition: ntv2democommon.h:393
AUTOCIRCULATE_STATUS::GetProcessedFrameCount
ULWord GetProcessedFrameCount(void) const
Definition: ntv2publicinterface.h:7249
BurnConfig::fWithTallFrames
bool fWithTallFrames
If true && fWithAnc, use "taller" VANC mode for anc. Defaults to false.
Definition: ntv2democommon.h:403
NTV2_IS_VALID_TIMECODE_INDEX
#define NTV2_IS_VALID_TIMECODE_INDEX(__x__)
Definition: ntv2enums.h:3937
BurnConfig::fDoMultiFormat
bool fDoMultiFormat
If true, enables device-sharing; otherwise takes exclusive control of the device.
Definition: ntv2democommon.h:398
BurnConfig::fSuppressAudio
bool fSuppressAudio
If true, suppress audio; otherwise include audio.
Definition: ntv2democommon.h:399
BurnConfig::fTimecodeSource
NTV2TCIndex fTimecodeSource
Timecode source to use.
Definition: ntv2democommon.h:397
AUTOCIRCULATE_STATUS::GetBufferLevel
ULWord GetBufferLevel(void) const
Definition: ntv2publicinterface.h:7254
main
int main(int argc, const char **argv)
Definition: main.cpp:30
NTV2_IS_VALID_OUTPUT_DEST
#define NTV2_IS_VALID_OUTPUT_DEST(_dest_)
Definition: ntv2enums.h:1324
BurnConfig::fSuppressVideo
bool fSuppressVideo
If true, suppress video; otherwise include video.
Definition: ntv2democommon.h:400
NTV2ACFrameRange::setFromString
std::string setFromString(const std::string &inStr)
Definition: ntv2utils.cpp:4155
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::void
j template void())
Definition: json.hpp:4893
CNTV2DemoCommon::GetOutputDestinationStrings
static std::string GetOutputDestinationStrings(const NTV2IOKinds inKinds, const std::string inDevSpec=std::string())
Definition: ntv2democommon.cpp:769
BurnConfig::fPixelFormat
NTV2PixelFormat fPixelFormat
The pixel format to use.
Definition: ntv2democommon.h:396
NTV2Burn::GetStatus
virtual void GetStatus(AUTOCIRCULATE_STATUS &outInputStatus, AUTOCIRCULATE_STATUS &outOutputStatus)
Provides status information about my input (capture) and output (playout) processes.
Definition: ntv2burn.cpp:840
BurnConfig::fOutputFrames
NTV2ACFrameRange fOutputFrames
Playout frame count or range.
Definition: ntv2democommon.h:395
POPT_AUTOHELP
#define POPT_AUTOHELP
Definition: options_popt.h:220
CNTV2DemoCommon::IsValidDevice
static bool IsValidDevice(const std::string &inDeviceSpec)
Definition: ntv2democommon.cpp:455
AJAStatus
AJAStatus
Definition: types.h:378
AJATime::Sleep
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
CNTV2DemoCommon::ToLower
static std::string ToLower(const std::string &inStr)
Returns the given string after converting it to lower case.
Definition: ntv2democommon.cpp:1033
AUTOCIRCULATE_STATUS
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
Definition: ntv2publicinterface.h:7193
BurnConfig::fWithHanc
bool fWithHanc
If true, capture & play HANC data, including audio (LLBurn). Defaults to false.
Definition: ntv2democommon.h:404
CNTV2DemoCommon::GetPixelFormatStrings
static std::string GetPixelFormatStrings(const NTV2PixelFormatKinds inKinds=PIXEL_FORMATS_ALL, const std::string inDevSpec=std::string())
Definition: ntv2democommon.cpp:605
NTV2_IS_VALID_INPUT_SOURCE
#define NTV2_IS_VALID_INPUT_SOURCE(_inpSrc_)
Definition: ntv2enums.h:1266
NTV2_FBF_8BIT_YCBCR
@ NTV2_FBF_8BIT_YCBCR
See 8-Bit YCbCr Format.
Definition: ntv2enums.h:214
CNTV2DemoCommon::GetOutputDestinationFromString
static NTV2OutputDestination GetOutputDestinationFromString(const std::string &inStr, const NTV2IOKinds inKinds=NTV2_IOKINDS_ALL, const std::string inDevSpec=std::string())
Returns the NTV2OutputDestination that matches the given string.
Definition: ntv2democommon.cpp:801
CNTV2DemoCommon::Popt
Definition: ntv2democommon.h:848
CNTV2DemoCommon::Popt::errorStr
virtual const std::string & errorStr(void) const
Definition: ntv2democommon.h:856
NTV2Version
std::string NTV2Version(const bool inDetailed=false)
Definition: ntv2version.cpp:41
CNTV2DemoCommon::GetTCIndexStrings
static std::string GetTCIndexStrings(const NTV2TCIndexKinds inKinds=TC_INDEXES_ALL, const std::string inDeviceSpecifier=std::string(), const bool inIsInputOnly=(!(0)))
Definition: ntv2democommon.cpp:852
BurnConfig::fWithAnc
bool fWithAnc
If true, capture & play anc data (LLBurn). Defaults to false.
Definition: ntv2democommon.h:402
AJADebug::Open
static AJAStatus Open(bool incrementRefCount=false)
Definition: debug.cpp:44
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:199
SignalHandler
static void SignalHandler(int inSignal)
Definition: main.cpp:23
BurnConfig::fInputSource
NTV2InputSource fInputSource
The device input connector to use.
Definition: ntv2democommon.h:392
NTV2Burn
I capture frames from a video signal provided to an AJA device's video input. I burn timecode into th...
Definition: ntv2burn.h:30
CNTV2DemoCommon::GetInputSourceStrings
static std::string GetInputSourceStrings(const NTV2IOKinds inKinds=NTV2_IOKINDS_ALL, const std::string inDevSpec=std::string())
Definition: ntv2democommon.cpp:689
NTV2_IOKINDS_ALL
@ NTV2_IOKINDS_ALL
Specifies any/all input/output kinds.
Definition: ntv2enums.h:1277
false
#define false
Definition: ntv2devicefeatures.h:25
ntv2burn.h
Header file for the NTV2Burn demonstration class.
std
Definition: json.hpp:5362
AUTOCIRCULATE_STATUS::GetDroppedFrameCount
ULWord GetDroppedFrameCount(void) const
Definition: ntv2publicinterface.h:7244
POPT_TABLEEND
#define POPT_TABLEEND
Definition: options_popt.h:215
true
#define true
Definition: ntv2devicefeatures.h:26
NTV2ACFrameRange::valid
bool valid(void) const
Definition: ntv2utils.h:985
NTV2Burn::Run
virtual AJAStatus Run(void)
Runs me.
Definition: ntv2burn.cpp:546
CNTV2DemoCommon::GetTCIndexFromString
static NTV2TCIndex GetTCIndexFromString(const std::string &inStr, const NTV2TCIndexKinds inKinds=TC_INDEXES_ALL, const std::string inDevSpec=std::string())
Returns the NTV2TCIndex that matches the given string.
Definition: ntv2democommon.cpp:887
CNTV2DemoCommon::GetInputSourceFromString
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.
Definition: ntv2democommon.cpp:721
NTV2_IS_VALID_FRAME_BUFFER_FORMAT
#define NTV2_IS_VALID_FRAME_BUFFER_FORMAT(__s__)
Definition: ntv2enums.h:254
AJA_FAILURE
#define AJA_FAILURE(_status_)
Definition: types.h:371
BurnConfig::fInputFrames
NTV2ACFrameRange fInputFrames
Ingest frame count or range.
Definition: ntv2democommon.h:394
BurnConfig
Configures an NTV2Burn or NTV2FieldBurn instance.
Definition: ntv2democommon.h:385
POPT_ARG_STRING
#define POPT_ARG_STRING
Definition: options_popt.h:57
POPT_ARG_NONE
#define POPT_ARG_NONE
Definition: options_popt.h:56
TC_INDEXES_ALL
@ TC_INDEXES_ALL
Definition: ntv2democommon.h:267
PIXEL_FORMATS_ALL
@ PIXEL_FORMATS_ALL
Definition: ntv2democommon.h:252