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, 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 /* static */ bool AppModuleGeneric::device(void *userPtr, const char *optArg)
99 {
100 PROPAGATE_ERROR(Dispatcher::getInstance().m_deviceIndex.setFromString(optArg));
101 return true;
102 }
103
104 /* static */ bool AppModuleGeneric::exposureTimeRange(void *userPtr, const char *optArg)
105 {
106 PROPAGATE_ERROR(Dispatcher::getInstance().m_exposureTimeRange.setFromString(optArg));
107 return true;
108 }
109
110 /* static */ bool AppModuleGeneric::focusPosition(void *userPtr, const char *optArg)
111 {
112 PROPAGATE_ERROR(Dispatcher::getInstance().m_focusPosition.setFromString(optArg));
113 return true;
114 }
115
116 /* static */ bool AppModuleGeneric::gainRange(void *userPtr, const char *optArg)
117 {
118 PROPAGATE_ERROR(Dispatcher::getInstance().m_gainRange.setFromString(optArg));
119 return true;
120 }
121
122 /* static */ bool AppModuleGeneric::sensorMode(void *userPtr, const char *optArg)
123 {
124 PROPAGATE_ERROR(Dispatcher::getInstance().m_sensorModeIndex.setFromString(optArg));
125 return true;
126 }
127
128 /* static */ bool AppModuleGeneric::frameRate(void *userPtr, const char *optArg)
129 {
130 PROPAGATE_ERROR(Dispatcher::getInstance().m_frameRate.setFromString(optArg));
131
132 return true;
133 }
134
135 /* static */ bool AppModuleGeneric::outputSize(void *userPtr, const char *optArg)
136 {
137 PROPAGATE_ERROR(Dispatcher::getInstance().m_outputSize.setFromString(optArg));
138 return true;
139 }
140
141 /* static */ bool AppModuleGeneric::outputPath(void *userPtr, const char *optArg)
142 {
143 PROPAGATE_ERROR(Dispatcher::getInstance().m_outputPath.set(optArg));
144 return true;
145 }
146
147 /* static */ bool AppModuleGeneric::vstab(void *userPtr, const char *optArg)
148 {
149 PROPAGATE_ERROR(Dispatcher::getInstance().m_vstabMode.setFromString(optArg));
150 return true;
151 }
152
153 /* static */ bool AppModuleGeneric::deNoise(void *userPtr, const char *optArg)
154 {
155 PROPAGATE_ERROR(Dispatcher::getInstance().m_denoiseMode.setFromString(optArg));
156 return true;
157 }
158
159 /* static */ bool AppModuleGeneric::aeAntibanding(void *userPtr, const char *optArg)
160 {
161 PROPAGATE_ERROR(Dispatcher::getInstance().m_aeAntibandingMode.setFromString(optArg));
162 return true;
163 }
164
165 /* static */ bool AppModuleGeneric::aeLock(void *userPtr, const char *optArg)
166 {
167 PROPAGATE_ERROR(Dispatcher::getInstance().m_aeLock.setFromString(optArg));
168 return true;
169 }
170
171 /* static */ bool AppModuleGeneric::awbLock(void *userPtr, const char *optArg)
172 {
173 PROPAGATE_ERROR(Dispatcher::getInstance().m_awbLock.setFromString(optArg));
174 return true;
175 }
176
177 /* static */ bool AppModuleGeneric::awb(void *userPtr, const char *optArg)
178 {
179 PROPAGATE_ERROR(Dispatcher::getInstance().m_awbMode.setFromString(optArg));
180 return true;
181 }
182
183 /* static */ bool AppModuleGeneric::exposureCompensation(void *userPtr, const char *optArg)
184 {
185 PROPAGATE_ERROR(Dispatcher::getInstance().m_exposureCompensation.setFromString(optArg));
186 return true;
187 }
188
189 /* static */ bool AppModuleGeneric::deFogEnable(void *userPtr, const char *optArg)
190 {
191 PROPAGATE_ERROR(Dispatcher::getInstance().m_deFogEnable.setFromString(optArg));
192 return true;
193 }
194
195 /* static */ bool AppModuleGeneric::deFogAmount(void *userPtr, const char *optArg)
196 {
197 PROPAGATE_ERROR(Dispatcher::getInstance().m_deFogAmount.setFromString(optArg));
198 return true;
199 }
200
201 /* static */ bool AppModuleGeneric::deFogQuality(void *userPtr, const char *optArg)
202 {
203 PROPAGATE_ERROR(Dispatcher::getInstance().m_deFogQuality.setFromString(optArg));
204 return true;
205 }
206
207 AppModuleGeneric::AppModuleGeneric()
208 : m_initialized(false)
209 , m_running(false)
210 , m_guiMenuBar(NULL)
211 , m_guiContainerConfig(NULL)
212 , m_guiConfig(NULL)
213 {
214 }
215
216 AppModuleGeneric::~AppModuleGeneric()
217 {
218 shutdown();
219 }
220
221 bool AppModuleGeneric::initialize(Options &options)
222 {
223 if (m_initialized)
224 return true;
225
226 PROPAGATE_ERROR(options.addDescription(
227 "The supported value range of some settings is device or sensor mode dependent.\n"
228 "Use the '--info' option to get a list of the supported values.\n"));
229
230 PROPAGATE_ERROR(options.addOption(
231 Options::Option("info", 'i', "",
232 Options::Option::TYPE_ACTION, Options::Option::FLAG_NO_ARGUMENT,
233 "print information on devices.", info)));
234
235 PROPAGATE_ERROR(options.addOption(
236 Options::Option("loadconfig", 0, "FILE",
237 Options::Option::TYPE_ACTION, Options::Option::FLAG_OPTIONAL_ARGUMENT,
238 "load configuration from XML FILE. Default for file is '" DEFAULT_CONFIG_FILE "'.",
239 loadConfig)));
240 PROPAGATE_ERROR(options.addOption(
241 Options::Option("saveconfig", 0, "FILE",
242 Options::Option::TYPE_ACTION, Options::Option::FLAG_OPTIONAL_ARGUMENT,
243 "save configuration to XML FILE. Default for file is '" DEFAULT_CONFIG_FILE "'.",
244 saveConfig)));
245
246 PROPAGATE_ERROR(options.addOption(
247 Options::Option("verbose", 0, "", Dispatcher::getInstance().m_verbose,
248 "enable verbose mode.", verbose)));
249 PROPAGATE_ERROR(options.addOption(
250 Options::Option("kpi", 0, "", Dispatcher::getInstance().m_kpi,
251 "enable kpi mode.", kpi)));
252 PROPAGATE_ERROR(options.addOption(
253 Options::Option("device", 'd', "INDEX", Dispatcher::getInstance().m_deviceIndex,
254 "select camera device with INDEX.", device)));
255
256 // source settings
257 PROPAGATE_ERROR(options.addOption(
258 Options::Option("exposuretimerange", 0, "RANGE",
259 Dispatcher::getInstance().m_exposureTimeRange,
260 "sets the exposure time range to RANGE, in nanoseconds.",
261 exposureTimeRange)));
262 PROPAGATE_ERROR(options.addOption(
263 Options::Option("gainrange", 0, "RANGE", Dispatcher::getInstance().m_gainRange,
264 "sets the gain range to RANGE.", gainRange)));
265 PROPAGATE_ERROR(options.addOption(
266 Options::Option("sensormode", 0, "INDEX", Dispatcher::getInstance().m_sensorModeIndex,
267 "set sensor mode to INDEX.", sensorMode)));
268 PROPAGATE_ERROR(options.addOption(
269 Options::Option("framerate", 0, "RATE", Dispatcher::getInstance().m_frameRate,
270 "set the sensor frame rate to RATE. If RATE is 0 then VFR (variable frame rate) is "
271 "enabled.", frameRate)));
272 PROPAGATE_ERROR(options.addOption(
273 Options::Option("focusposition", 0, "POSITION", Dispatcher::getInstance().m_focusPosition,
274 "sets the focus position to POSITION, in focuser units.",
275 focusPosition)));
276
277 // output settings
278 PROPAGATE_ERROR(options.addOption(
279 Options::Option("outputsize", 0, "WIDTHxHEIGHT", Dispatcher::getInstance().m_outputSize,
280 "set the still and video output size to WIDTHxHEIGHT (e.g. 1920x1080). If WIDTHxHEIGHT "
281 "is '0x0' the output size is the sensor mode size.", outputSize)));
282 PROPAGATE_ERROR(options.addOption(
283 Options::Option("outputpath", 0, "PATH", Dispatcher::getInstance().m_outputPath,
284 "set the output file path. A file name, an incrementing index and the file extension will "
285 "be appended. E.g. setting 'folder/' will result in 'folder/image0.jpg' or "
286 "'folder/video0.mp4'. '/dev/null' can be used to discard output.",
287 outputPath)));
288
289 // stream settings
290 PROPAGATE_ERROR(options.addOption(
291 Options::Option("vstab", 0, "MODE", Dispatcher::getInstance().m_vstabMode,
292 "set the video stabilization mode.", vstab)));
293 PROPAGATE_ERROR(options.addOption(
294 Options::Option("denoise", 0, "MODE", Dispatcher::getInstance().m_denoiseMode,
295 "set the denoising mode.", deNoise)));
296
297 // auto control settings
298 PROPAGATE_ERROR(options.addOption(
299 Options::Option("aeantibanding", 0, "MODE", Dispatcher::getInstance().m_aeAntibandingMode,
300 "set the auto exposure antibanding mode.", aeAntibanding)));
301 PROPAGATE_ERROR(options.addOption(
302 Options::Option("aelock", 0, "LOCK", Dispatcher::getInstance().m_aeLock,
303 "set the auto exposure lock.", aeLock)));
304 PROPAGATE_ERROR(options.addOption(
305 Options::Option("awblock", 0, "LOCK", Dispatcher::getInstance().m_awbLock,
306 "set the auto white balance lock.", awbLock)));
307 PROPAGATE_ERROR(options.addOption(
308 Options::Option("awb", 0, "MODE", Dispatcher::getInstance().m_awbMode,
309 "set the auto white balance mode.", awb)));
310 PROPAGATE_ERROR(options.addOption(
311 Options::Option("exposurecompensation", 0, "COMPENSATION",
312 Dispatcher::getInstance().m_exposureCompensation,
313 "set the exposure compensation to COMPENSATION.",
314 exposureCompensation)));
315
316 if (Dispatcher::getInstance().supportsExtension(Argus::EXT_DE_FOG))
317 {
318 // DeFog extension settings
319 PROPAGATE_ERROR(options.addOption(
320 Options::Option("defog", 0, "ENABLE", Dispatcher::getInstance().m_deFogEnable,
321 "set the DeFog enable flag to ENABLE.", deFogEnable)));
322 PROPAGATE_ERROR(options.addOption(
323 Options::Option("defogamount", 0, "AMOUNT", Dispatcher::getInstance().m_deFogAmount,
324 "sets the amount of fog to be removed to AMOUNT.", deFogAmount)));
325 PROPAGATE_ERROR(options.addOption(
326 Options::Option("defogquality", 0, "QUALITY", Dispatcher::getInstance().m_deFogQuality,
327 "sets the quality of the DeFog effect to QUALITY.",
328 deFogQuality)));
329 }
330
331 m_initialized = true;
332
333 return true;
334 }
335
336 bool AppModuleGeneric::shutdown()
337 {
338 if (!m_initialized)
339 return true;
340
341 PROPAGATE_ERROR_CONTINUE(stop());
342
343 delete m_guiConfig;
344 m_guiConfig = NULL;
345
346 m_initialized = false;
347
348 return true;
349 }
350
351 bool AppModuleGeneric::start(Window::IGuiMenuBar *iGuiMenuBar,
352 Window::IGuiContainer *iGuiContainerConfig)
353 {
354 if (m_running)
355 return true;
356
357 if (iGuiMenuBar && !m_guiMenuBar)
358 {
359 // initialize the menu
360
361 UniquePointer<Window::IGuiMenu> menu;
362 UniquePointer<Window::IGuiMenuItem> item;
363
364 // create the elements
365 Window::IGuiMenu *fileMenu = iGuiMenuBar->getMenu("File");
366 if (!fileMenu)
367 {
368 PROPAGATE_ERROR(Window::IGuiMenu::create("File", &menu));
369 PROPAGATE_ERROR(iGuiMenuBar->add(menu.get()));
370 fileMenu = menu.get();
371 menu.release();
372 }
373 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Load config", AppModuleGeneric::loadConfig,
374 NULL, &item));
375 PROPAGATE_ERROR(fileMenu->add(item.get()));
376 item.release();
377 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Save Config", AppModuleGeneric::saveConfig,
378 NULL, &item));
379 PROPAGATE_ERROR(fileMenu->add(item.get()));
380 item.release();
381 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Quit", AppModuleGeneric::quit, NULL,
382 &item));
383 PROPAGATE_ERROR(fileMenu->add(item.get()));
384 item.release();
385
386 Window::IGuiMenu *helpMenu = iGuiMenuBar->getMenu("Help");
387 if (!helpMenu)
388 {
389 PROPAGATE_ERROR(Window::IGuiMenu::create("Help", &menu));
390 PROPAGATE_ERROR(iGuiMenuBar->add(menu.get()));
391 helpMenu = menu.get();
392 menu.release();
393 }
394 PROPAGATE_ERROR(Window::IGuiMenuItem::create("Info", AppModuleGeneric::info, NULL,
395 &item));
396 PROPAGATE_ERROR(helpMenu->add(item.get()));
397 item.release();
398
399 m_guiMenuBar = iGuiMenuBar;
400 }
401
402 if (iGuiContainerConfig && !m_guiContainerConfig)
403 {
404 // initialize the GUI
405
406 // create a grid container
407 PROPAGATE_ERROR(Window::IGuiContainerGrid::create(&m_guiConfig));
408
409 // create the elements
410 UniquePointer<Window::IGuiElement> element;
411 Dispatcher &dispatcher = Dispatcher::getInstance();
412
413 Window::IGuiContainerGrid::BuildHelper buildHelper(m_guiConfig);
414
415 #define CREATE_GUI_ELEMENT(_NAME, _VALUE) \
416 PROPAGATE_ERROR(Window::IGuiElement::createValue(&dispatcher._VALUE, &element));\
417 PROPAGATE_ERROR(buildHelper.append(_NAME, element.get())); \
418 element.release();
419
420 #define CREATE_GUI_ELEMENT_COMBO_BOX(_NAME, _VALUE, _FROMTYPE, _TOTYPE) \
421 assert(sizeof(_FROMTYPE) == sizeof(_TOTYPE)); \
422 PROPAGATE_ERROR(Window::IGuiElement::createValue(reinterpret_cast< \
423 Value<_TOTYPE>*>(&dispatcher._VALUE), &element)); \
424 PROPAGATE_ERROR(buildHelper.append(_NAME, element.get())); \
425 element.release();
426
427 #define CREATE_GUI_ELEMENT_PATH_CHOOSER(_NAME, _VALUE) \
428 PROPAGATE_ERROR(Window::IGuiElement::createFileChooser(&dispatcher._VALUE, \
429 true, &element)); \
430 PROPAGATE_ERROR(buildHelper.append(_NAME, element.get())); \
431 element.release();
432
433 CREATE_GUI_ELEMENT("Verbose", m_verbose);
434 CREATE_GUI_ELEMENT("KPI", m_kpi);
435 CREATE_GUI_ELEMENT("Device", m_deviceIndex);
436
437 CREATE_GUI_ELEMENT("Exposure time range (ns)", m_exposureTimeRange);
438 CREATE_GUI_ELEMENT("Gain range", m_gainRange);
439
440 CREATE_GUI_ELEMENT_COMBO_BOX("Sensor mode index", m_sensorModeIndex,
441 uint32_t, Window::IGuiElement::ValueTypeEnum);
442 CREATE_GUI_ELEMENT("Frame rate", m_frameRate);
443 CREATE_GUI_ELEMENT("Focus position", m_focusPosition);
444 CREATE_GUI_ELEMENT("Output size", m_outputSize);
445
446 CREATE_GUI_ELEMENT_PATH_CHOOSER("Output path", m_outputPath);
447
448 CREATE_GUI_ELEMENT_COMBO_BOX("Video stabilization mode", m_vstabMode,
449 Argus::VideoStabilizationMode, Argus::NamedUUID);
450 CREATE_GUI_ELEMENT_COMBO_BOX("De-Noise mode", m_denoiseMode,
451 Argus::DenoiseMode, Argus::NamedUUID);
452
453 CREATE_GUI_ELEMENT_COMBO_BOX("AE antibanding mode", m_aeAntibandingMode,
454 Argus::AeAntibandingMode, Window::IGuiElement::ValueTypeEnum);
455
456 CREATE_GUI_ELEMENT("AE Lock", m_aeLock);
457 CREATE_GUI_ELEMENT("AWB Lock", m_awbLock);
458 CREATE_GUI_ELEMENT_COMBO_BOX("AWB mode", m_awbMode,
459 Argus::AwbMode, Argus::NamedUUID);
460 CREATE_GUI_ELEMENT("Exposure compensation (ev)", m_exposureCompensation);
461
462 #undef CREATE_GUI_ELEMENT
463 #undef CREATE_GUI_ELEMENT_COMBO_BOX
464 #undef CREATE_GUI_ELEMENT_PATH_CHOOSER
465
466 m_guiContainerConfig = iGuiContainerConfig;
467 }
468
469 if (m_guiContainerConfig)
470 PROPAGATE_ERROR(m_guiContainerConfig->add(m_guiConfig));
471
472 m_running = true;
473
474 return true;
475 }
476
477 bool AppModuleGeneric::stop()
478 {
479 if (!m_running)
480 return true;
481
482 if (m_guiContainerConfig)
483 PROPAGATE_ERROR(m_guiContainerConfig->remove(m_guiConfig));
484
485 m_running = true;
486
487 return true;
488 }
489
490 }; // namespace ArgusSamples