Argus Camera Sample Argus Camera Sample

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AppModuleGeneric.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of NVIDIA CORPORATION nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "AppModuleGeneric.h"
33 #include "XMLConfig.h"
34 #include "Dispatcher.h"
35 #include "Error.h"
36 #include "Options.h"
37 #include "Window.h"
38
39 #include <Argus/Ext/DeFog.h>
40
41 namespace ArgusSamples
42 {
43
44 /**
45 * Default configuration file name
46 */
47 #define DEFAULT_CONFIG_FILE "argusAppConfig.xml"
48
49 /* static */ bool AppModuleGeneric::info(void *userPtr, const char *optArg)
50 {
51 std::string info;
52 PROPAGATE_ERROR(Dispatcher::getInstance().getInfo(info));
53 printf("%s\n", info.c_str());
54
55 return true;
56 }
57
58 /* static */ bool AppModuleGeneric::loadConfig(void *userPtr, const char *optArg)
59 {
60 /// @todo ask for file if called from GUI
61
62 const char *configFile = DEFAULT_CONFIG_FILE;
63 if (optArg)
64 configFile = optArg;
65 PROPAGATE_ERROR(ArgusSamples::loadConfig(configFile));
66 return true;
67 }
68
69 /* static */ bool AppModuleGeneric::saveConfig(void *userPtr, const char *optArg)
70 {
71 /// @todo ask for file if called from GUI
72
73 const char *configFile = DEFAULT_CONFIG_FILE;
74 if (optArg)
75 configFile = optArg;
76 PROPAGATE_ERROR(ArgusSamples::saveConfig(configFile));
77 return true;
78 }
79
80 /* static */ bool AppModuleGeneric::quit(void *userPtr, const char *optArg)
81 {
82 PROPAGATE_ERROR(Window::getInstance().requestExit());
83 return true;
84 }
85
86 /* static */ bool AppModuleGeneric::verbose(void *userPtr, const char *optArg)
87 {
88 PROPAGATE_ERROR(Dispatcher::getInstance().m_verbose.set(true));
89 return true;
90 }
91
92 /* static */ bool AppModuleGeneric::kpi(void *userPtr, const char *optArg)
93 {
94 PROPAGATE_ERROR(Dispatcher::getInstance().m_kpi.set(true));
95 return true;
96 }
97
98 AppModuleGeneric::AppModuleGeneric()
99 : m_initialized(false)
100 , m_running(false)
101 , m_guiMenuBar(NULL)
102 , m_guiContainerConfig(NULL)
103 , m_guiConfig(NULL)
104 {
105 }
106
107 AppModuleGeneric::~AppModuleGeneric()
108 {
109 shutdown();
110 }
111
112 bool AppModuleGeneric::initialize(Options &options)
113 {
114 if (m_initialized)
115 return true;
116
117 PROPAGATE_ERROR(options.addDescription(
118 "The supported value range of some settings is device or sensor mode dependent.\n"
119 "Use the '--info' option to get a list of the supported values.\n"));
120
121 PROPAGATE_ERROR(options.addOption(
122 Options::Option("info", 'i', "",
123 Options::Option::TYPE_ACTION, Options::Option::FLAG_NO_ARGUMENT,
124 "print information on devices.", info)));
125
126 PROPAGATE_ERROR(options.addOption(
127 Options::Option("loadconfig", 0, "FILE",
128 Options::Option::TYPE_ACTION, Options::Option::FLAG_OPTIONAL_ARGUMENT,
129 "load configuration from XML FILE. Default for file is '" DEFAULT_CONFIG_FILE "'.",
130 loadConfig)));
131 PROPAGATE_ERROR(options.addOption(
132 Options::Option("saveconfig", 0, "FILE",
133 Options::Option::TYPE_ACTION, Options::Option::FLAG_OPTIONAL_ARGUMENT,
134 "save configuration to XML FILE. Default for file is '" DEFAULT_CONFIG_FILE "'.",
135 saveConfig)));
136
137 PROPAGATE_ERROR(options.addOption(
138 Options::Option("verbose", 0, "", Dispatcher::getInstance().m_verbose,
139 "enable verbose mode.", verbose)));
140 PROPAGATE_ERROR(options.addOption(
141 Options::Option("kpi", 0, "", Dispatcher::getInstance().m_kpi,
142 "enable kpi mode.", kpi)));
143 PROPAGATE_ERROR(options.addOption(
144 createValueOption("device", 'd', "INDEX", "select camera device with INDEX.",
145 Dispatcher::getInstance().m_deviceIndex)));
146
147 // source settings
148 PROPAGATE_ERROR(options.addOption(
149 createValueOption("exposuretimerange", 0, "RANGE",
150 "sets the exposure time range to RANGE, in nanoseconds.",
151 Dispatcher::getInstance().m_exposureTimeRange)));
152 PROPAGATE_ERROR(options.addOption(
153 createValueOption("gainrange", 0, "RANGE", "sets the gain range to RANGE.",
154 Dispatcher::getInstance().m_gainRange)));
155 PROPAGATE_ERROR(options.addOption(
156 createValueOption("sensormode", 0, "INDEX", "set sensor mode to INDEX.",
157 Dispatcher::getInstance().m_sensorModeIndex)));
158 PROPAGATE_ERROR(options.addOption(
159 createValueOption("framerate", 0, "RATE",
160 "set the sensor frame rate to RATE. If RATE is 0 then VFR (variable frame rate) is "
161 "enabled.", Dispatcher::getInstance().m_frameRate)));
162 PROPAGATE_ERROR(options.addOption(
163 createValueOption("focusposition", 0, "POSITION",
164 "sets the focus position to POSITION, in focuser units.",
165 Dispatcher::getInstance().m_focusPosition)));
166
167 // output settings
168 PROPAGATE_ERROR(options.addOption(
169 createValueOption("outputsize", 0, "WIDTHxHEIGHT",
170 "set the still and video output size to WIDTHxHEIGHT (e.g. 1920x1080). If WIDTHxHEIGHT "
171 "is '0x0' the output size is the sensor mode size.",
172 Dispatcher::getInstance().m_outputSize)));
173 PROPAGATE_ERROR(options.addOption(
174 createValueOption("outputpath", 0, "PATH",
175 "set the output file path. A file name, an incrementing index and the file extension will "
176 "be appended. E.g. setting 'folder/' will result in 'folder/image0.jpg' or "
177 "'folder/video0.mp4'. '/dev/null' can be used to discard output.",
178 Dispatcher::getInstance().m_outputPath)));
179
180 // stream settings
181 PROPAGATE_ERROR(options.addOption(
182 createValueOption("vstab", 0, "MODE", "set the video stabilization mode.",
183 Dispatcher::getInstance().m_vstabMode)));
184 PROPAGATE_ERROR(options.addOption(
185 createValueOption("denoise", 0, "MODE", "set the denoising mode.",
186 Dispatcher::getInstance().m_denoiseMode)));
187 PROPAGATE_ERROR(options.addOption(
188 createValueOption("denoisestrength", 0, "POSITION", "set the denoising strength.",
189 Dispatcher::getInstance().m_denoiseStrength)));
190 PROPAGATE_ERROR(options.addOption(
191 createValueOption("edgeenhance", 0, "MODE", "set the edge enhancement mode.",
192 Dispatcher::getInstance().m_edgeEnhanceMode)));
193 PROPAGATE_ERROR(options.addOption(
194 createValueOption("edgeenhancestrength", 0, "POSITION",
195 "set the edge enhancement strength.",
196 Dispatcher::getInstance().m_edgeEnhanceStrength)));
197
198 // auto control settings
199 PROPAGATE_ERROR(options.addOption(
200 createValueOption("aeantibanding", 0, "MODE", "set the auto exposure antibanding mode.",
201 Dispatcher::getInstance().m_aeAntibandingMode)));
202 PROPAGATE_ERROR(options.addOption(
203 createValueOption("aelock", 0, "LOCK", "set the auto exposure lock.",
204 Dispatcher::getInstance().m_aeLock)));
205 PROPAGATE_ERROR(options.addOption(
206 createValueOption("awblock", 0, "LOCK", "set the auto white balance lock.",
207 Dispatcher::getInstance().m_awbLock)));
208 PROPAGATE_ERROR(options.addOption(
209 createValueOption("awb", 0, "MODE", "set the auto white balance mode.",
210 Dispatcher::getInstance().m_awbMode)));
211 PROPAGATE_ERROR(options.addOption(
212 createValueOption("exposurecompensation", 0, "COMPENSATION",
213 "set the exposure compensation to COMPENSATION.",
214 Dispatcher::getInstance().m_exposureCompensation)));
215 PROPAGATE_ERROR(options.addOption(
216 createValueOption("ispdigitalgainrange", 0, "RANGE",
217 "sets the ISP digital gain range.",
218 Dispatcher::getInstance().m_ispDigitalGainRange)));
219
220 if (Dispatcher::getInstance().supportsExtension(Argus::EXT_DE_FOG))
221 {
222 // DeFog extension settings
223 PROPAGATE_ERROR(options.addOption(
224 createValueOption("defog", 0, "ENABLE",
225 "set the DeFog enable flag to ENABLE.",
226 Dispatcher::getInstance().m_deFogEnable)));
227 PROPAGATE_ERROR(options.addOption(
228 createValueOption("defogamount", 0, "AMOUNT",
229 "sets the amount of fog to be removed to AMOUNT.",
230 Dispatcher::getInstance().m_deFogAmount)));
231 PROPAGATE_ERROR(options.addOption(
232 createValueOption("defogquality", 0, "QUALITY",
233 "sets the quality of the DeFog effect to QUALITY.",
234 Dispatcher::getInstance().m_deFogQuality)));
235 }
236
237 m_initialized = true;
238
239 return true;
240 }
241
242 bool AppModuleGeneric::shutdown()
243 {
244 if (!m_initialized)
245 return true;
246
247 PROPAGATE_ERROR_CONTINUE(stop());
248
249 delete m_guiConfig;
250 m_guiConfig = NULL;
251
252 m_initialized = false;
253
254 return true;
255 }
256
257 bool AppModuleGeneric::start(Window::IGuiMenuBar *iGuiMenuBar,
258 Window::IGuiContainer *iGuiContainerConfig)
259 {
260 if (m_running)
261 return true;
262
263 if (iGuiMenuBar && !m_guiMenuBar)
264 {
265 // initialize the menu
266
267 UniquePointer<Window::IGuiMenu> menu;
268 UniquePointer<Window::IGuiMenuItem> item;
269
270 // create the elements
271 Window::IGuiMenu *fileMenu = iGuiMenuBar->getMenu("File");
272 if (!fileMenu)
273 {
274 PROPAGATE_ERROR(Window::IGuiMenu::create("File", &menu));
275 PROPAGATE_ERROR(iGuiMenuBar->add(menu.get()));
276 fileMenu = menu.get();
277 menu.release();
278 }
279 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Load config", AppModuleGeneric::loadConfig,
280 NULL, &item));
281 PROPAGATE_ERROR(fileMenu->add(item.get()));
282 item.release();
283 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Save Config", AppModuleGeneric::saveConfig,
284 NULL, &item));
285 PROPAGATE_ERROR(fileMenu->add(item.get()));
286 item.release();
287 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Quit", AppModuleGeneric::quit, NULL,
288 &item));
289 PROPAGATE_ERROR(fileMenu->add(item.get()));
290 item.release();
291
292 Window::IGuiMenu *helpMenu = iGuiMenuBar->getMenu("Help");
293 if (!helpMenu)
294 {
295 PROPAGATE_ERROR(Window::IGuiMenu::create("Help", &menu));
296 PROPAGATE_ERROR(iGuiMenuBar->add(menu.get()));
297 helpMenu = menu.get();
298 menu.release();
299 }
300 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Info", AppModuleGeneric::info, NULL,
301 &item));
302 PROPAGATE_ERROR(helpMenu->add(item.get()));
303 item.release();
304
305 m_guiMenuBar = iGuiMenuBar;
306 }
307
308 if (iGuiContainerConfig && !m_guiContainerConfig)
309 {
310 // initialize the GUI
311
312 // create a grid container
313 PROPAGATE_ERROR(Window::IGuiContainerGrid::create(&m_guiConfig));
314
315 // create the elements
316 UniquePointer<Window::IGuiElement> element;
317 Dispatcher &dispatcher = Dispatcher::getInstance();
318
319 Window::IGuiContainerGrid::BuildHelper buildHelper(m_guiConfig);
320
321 #define CREATE_GUI_ELEMENT(_NAME, _VALUE) \
322 PROPAGATE_ERROR(Window::IGuiElement::createValue(&dispatcher._VALUE, &element));\
323 PROPAGATE_ERROR(buildHelper.append(_NAME, element.get())); \
324 element.release();
325
326 #define CREATE_GUI_ELEMENT_COMBO_BOX(_NAME, _VALUE, _FROMTYPE, _TOTYPE) \
327 assert(sizeof(_FROMTYPE) == sizeof(_TOTYPE)); \
328 PROPAGATE_ERROR(Window::IGuiElement::createValue(reinterpret_cast< \
329 Value<_TOTYPE>*>(&dispatcher._VALUE), &element)); \
330 PROPAGATE_ERROR(buildHelper.append(_NAME, element.get())); \
331 element.release();
332
333 #define CREATE_GUI_ELEMENT_PATH_CHOOSER(_NAME, _VALUE) \
334 PROPAGATE_ERROR(Window::IGuiElement::createFileChooser(&dispatcher._VALUE, \
335 true, &element)); \
336 PROPAGATE_ERROR(buildHelper.append(_NAME, element.get())); \
337 element.release();
338
339 CREATE_GUI_ELEMENT("Verbose", m_verbose);
340 CREATE_GUI_ELEMENT("KPI", m_kpi);
341 CREATE_GUI_ELEMENT("Device", m_deviceIndex);
342
343 CREATE_GUI_ELEMENT("Exposure time range (ns)", m_exposureTimeRange);
344 CREATE_GUI_ELEMENT("Gain range", m_gainRange);
345 CREATE_GUI_ELEMENT("ISP digital gain range", m_ispDigitalGainRange);
346
347 CREATE_GUI_ELEMENT_COMBO_BOX("Sensor mode index", m_sensorModeIndex,
348 uint32_t, Window::IGuiElement::ValueTypeEnum);
349 CREATE_GUI_ELEMENT("Frame rate", m_frameRate);
350 CREATE_GUI_ELEMENT("Focus position", m_focusPosition);
351 CREATE_GUI_ELEMENT("Output size", m_outputSize);
352
353 CREATE_GUI_ELEMENT_PATH_CHOOSER("Output path", m_outputPath);
354
355 CREATE_GUI_ELEMENT_COMBO_BOX("Video stabilization mode", m_vstabMode,
356 Argus::VideoStabilizationMode, Argus::NamedUUID);
357 CREATE_GUI_ELEMENT_COMBO_BOX("De-Noise mode", m_denoiseMode,
358 Argus::DenoiseMode, Argus::NamedUUID);
359 CREATE_GUI_ELEMENT("De-Noise strength", m_denoiseStrength);
360 CREATE_GUI_ELEMENT_COMBO_BOX("Edge Enhance mode", m_edgeEnhanceMode,
361 Argus::EdgeEnhanceMode, Argus::NamedUUID);
362 CREATE_GUI_ELEMENT("Edge Enhance strength", m_edgeEnhanceStrength);
363
364 CREATE_GUI_ELEMENT_COMBO_BOX("AE antibanding mode", m_aeAntibandingMode,
365 Argus::AeAntibandingMode, Window::IGuiElement::ValueTypeEnum);
366
367 CREATE_GUI_ELEMENT("AE Lock", m_aeLock);
368 CREATE_GUI_ELEMENT("AWB Lock", m_awbLock);
369 CREATE_GUI_ELEMENT_COMBO_BOX("AWB mode", m_awbMode,
370 Argus::AwbMode, Argus::NamedUUID);
371 CREATE_GUI_ELEMENT("Exposure compensation (ev)", m_exposureCompensation);
372
373 #undef CREATE_GUI_ELEMENT
374 #undef CREATE_GUI_ELEMENT_COMBO_BOX
375 #undef CREATE_GUI_ELEMENT_PATH_CHOOSER
376
377 m_guiContainerConfig = iGuiContainerConfig;
378 }
379
380 if (m_guiContainerConfig)
381 PROPAGATE_ERROR(m_guiContainerConfig->add(m_guiConfig));
382
383 m_running = true;
384
385 return true;
386 }
387
388 bool AppModuleGeneric::stop()
389 {
390 if (!m_running)
391 return true;
392
393 if (m_guiContainerConfig)
394 PROPAGATE_ERROR(m_guiContainerConfig->remove(m_guiConfig));
395
396 m_running = true;
397
398 return true;
399 }
400
401 }; // namespace ArgusSamples