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
Main.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
31 #include <list>
32
33 #include "Error.h"
34 #include "UniquePointer.h"
35 #include "Window.h"
36 #include "Value.h"
37 #include "Validator.h"
38 #include "IObserver.h"
39
40 #include "App.h"
41 #include "AppModuleCapture.h"
42 #include "AppModuleVideo.h"
43 #include "AppModuleMultiExposure.h"
44 #include "AppModuleMultiSession.h"
45 #include "AppModuleGallery.h"
46 #include "AppModuleGeneric.h"
47
48 namespace ArgusSamples
49 {
50
51 #if (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
52 /**
53 * GTK UI builder string
54 */
55 static const char builderString[] =
56 {
57 #include "cameraBuilder.h"
58 , 0x00
59 };
60 #endif // (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
61
62 /**
63 * Supported modules
64 */
65 enum Modules
66 {
67 MODULE_CAPTURE,
68 MODULE_VIDEO,
69 MODULE_MULTI_EXPOSURE,
70 MODULE_MULTI_SESSION,
71 MODULE_GALLERY,
72
73 MODULE_FIRST = MODULE_CAPTURE,
74 MODULE_LAST = MODULE_GALLERY,
75 MODULE_COUNT,
76 MODULE_INVALID = -1
77 };
78
79 // valid module values
80 static const ValidatorEnum<Modules>::ValueStringPair s_modules[] =
81 {
82 { MODULE_CAPTURE, "Capture" },
83 { MODULE_VIDEO, "Video" },
84 { MODULE_MULTI_EXPOSURE, "Multi Exposure" },
85 { MODULE_MULTI_SESSION, "Multi Session" },
86 { MODULE_GALLERY, "Gallery" }
87 };
88
89 class CameraApp : public App, public IObserver
90 {
91 public:
92 explicit CameraApp(const char *appName);
93 ~CameraApp();
94
95 /** @name App methods */
96 /**@{*/
97 virtual bool initialize();
98 virtual bool shutdown();
99 virtual bool start();
100 /**@}*/
101
102 /** @name option callbacks */
103 /**@{*/
104 static bool module(void *userPtr, const char *optArg);
105 /**@}*/
106
107 private:
108 /**
109 * Hide default constructor
110 */
111 CameraApp();
112
113 /** @name IKeyObserver methods */
114 /**@{*/
115 virtual bool onKey(const Key &key);
116 /**@}*/
117
118 bool onModuleChanged(const Observed &source);
119
120 AppModuleGeneric m_moduleGeneric;
121
122 Value<Modules> m_module; ///< active module
123 Modules m_prevModule; ///< previously active module
124
125 Modules m_activeModuleBeforeGallery; ///< active module when switching to gallery
126
127 std::vector<IAppModule*> m_modules; ///< all modules
128
129 Window::IGuiMenuBar *m_iGuiMenuBar; ///< menu bar
130 Window::IGuiContainer *m_iGuiContainerConfig; ///< container for config GUI elements
131 };
132
133 CameraApp::CameraApp(const char *appName)
134 : App(appName)
135 , m_module(new ValidatorEnum<Modules>(
136 s_modules, sizeof(s_modules) / sizeof(s_modules[0])),
137 MODULE_FIRST)
138 , m_prevModule(MODULE_INVALID)
139 , m_activeModuleBeforeGallery(MODULE_INVALID)
140 , m_iGuiMenuBar(NULL)
141 , m_iGuiContainerConfig(NULL)
142 {
143 }
144
145 CameraApp::~CameraApp()
146 {
147 shutdown();
148 }
149
150 /* static */ bool CameraApp::module(void *userPtr, const char *optArg)
151 {
152 CameraApp *cameraApp = reinterpret_cast< CameraApp*>(userPtr);
153 PROPAGATE_ERROR(cameraApp->m_module.setFromString(optArg));
154 return true;
155 }
156
157 bool CameraApp::initialize()
158 {
159 PROPAGATE_ERROR(App::initialize());
160
161 const char *description =
162 "Press 'm' to toggle between modules (still capture, video recording, multi exposure, \n"
163 "multi session).\n"
164 // For Bug 200239385
165 // There are asserts while operating the gallery.
166 // This "#if" will disable access to the gallery until it can be fixed
167 #if 0
168 "Press 'g' to switch to gallery and back. Use left and right arrow keys to move to next\n"
169 "and previous image or video.\n"
170 #endif
171 "Press 'space' to execute the module action (capture an image, start and stop recording,\n"
172 "start and stop video playback.\n";
173 PROPAGATE_ERROR(m_options.addDescription(description));
174
175 PROPAGATE_ERROR(m_options.addOption(
176 Options::Option("module", 0, "MODULE", m_module, "switch to module MODULE.",
177 module, this)));
178
179 #if (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
180 Window::IGuiBuilder *builder = NULL;
181 PROPAGATE_ERROR(Window::IGuiBuilder::create(builderString, &builder));
182
183 UniquePointer<Window::IGuiBuilder> createdBuilder(builder);
184 UniquePointer<Window::IGuiElement> createdWindow(createdBuilder->createElement("window"));
185 UniquePointer<Window::IGuiElement> createdView(createdBuilder->createElement("view"));
186
187 m_iGuiMenuBar =
188 static_cast<Window::IGuiMenuBar*>(createdBuilder->createElement("menuBar"));
189 m_iGuiContainerConfig =
190 static_cast<Window::IGuiContainer*>(createdBuilder->createElement("config"));
191
192 // set the window GUI
193 PROPAGATE_ERROR(Window::getInstance().setWindowGui(createdBuilder.get(), createdWindow.get(),
194 createdView.get()));
195
196 createdView.release();
197 createdWindow.release();
198 createdBuilder.release();
199 #endif // (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
200
201 m_modules.resize(MODULE_COUNT);
202
203 // create modules
204 UniquePointer<IAppModule> module;
205 module.reset(new AppModuleCapture);
206 if (!module)
207 ORIGINATE_ERROR("Out of memory");
208 m_modules[MODULE_CAPTURE] = module.release();
209
210 module.reset(new AppModuleVideo);
211 if (!module)
212 ORIGINATE_ERROR("Out of memory");
213 m_modules[MODULE_VIDEO] = module.release();
214
215 module.reset(new AppModuleMultiExposure);
216 if (!module)
217 ORIGINATE_ERROR("Out of memory");
218 m_modules[MODULE_MULTI_EXPOSURE] = module.release();
219
220 module.reset(new AppModuleMultiSession);
221 if (!module)
222 ORIGINATE_ERROR("Out of memory");
223 m_modules[MODULE_MULTI_SESSION] = module.release();
224
225 module.reset(new AppModuleGallery);
226 if (!module)
227 ORIGINATE_ERROR("Out of memory");
228 m_modules[MODULE_GALLERY] = module.release();
229
230 // initialize generic module, this has options common to all modules
231 PROPAGATE_ERROR(m_moduleGeneric.initialize(m_options));
232
233 // initializes modules
234 for (std::vector<IAppModule*>::iterator it = m_modules.begin(); it != m_modules.end(); ++it)
235 PROPAGATE_ERROR((*it)->initialize(m_options));
236
237 return true;
238 }
239
240 bool CameraApp::shutdown()
241 {
242 // shutdown the modules
243 for (std::vector<IAppModule*>::iterator it = m_modules.begin(); it != m_modules.end(); ++it)
244 {
245 PROPAGATE_ERROR((*it)->shutdown());
246 delete *it;
247 }
248 m_modules.clear();
249
250 PROPAGATE_ERROR(m_moduleGeneric.shutdown());
251
252 delete m_iGuiContainerConfig;
253 m_iGuiContainerConfig = NULL;
254
255 delete m_iGuiMenuBar;
256 m_iGuiMenuBar = NULL;
257
258 PROPAGATE_ERROR(App::shutdown());
259
260 return true;
261 }
262
263 bool CameraApp::start()
264 {
265 if (m_iGuiContainerConfig)
266 {
267 // add GUI elements
268 UniquePointer<Window::IGuiElement> element;
269
270 assert(sizeof(Modules) == sizeof(Window::IGuiElement::ValueTypeEnum));
271 PROPAGATE_ERROR(Window::IGuiElement::createValue(
272 reinterpret_cast<Value<Window::IGuiElement::ValueTypeEnum>*>(&m_module), &element));
273 PROPAGATE_ERROR(m_iGuiContainerConfig->add(element.get()));
274 element.release();
275 }
276
277 // Start the generic module, it's always active
278 PROPAGATE_ERROR(m_moduleGeneric.start(m_iGuiMenuBar, m_iGuiContainerConfig));
279
280 // register an observer, this will stop/start modules if m_module changes
281 PROPAGATE_ERROR_CONTINUE(m_module.registerObserver(this,
282 static_cast<IObserver::CallbackFunction>(&CameraApp::onModuleChanged)));
283
284 return true;
285 }
286
287 bool CameraApp::onKey(const Key &key)
288 {
289 if (key == Key("m"))
290 {
291 // switch to next module
292 Modules curModule = m_module.get();
293
294 // switch to next module but skip gallery
295 do
296 {
297 if (curModule == MODULE_LAST)
298 curModule = MODULE_FIRST;
299 else
300 curModule = static_cast< Modules >(curModule + 1);
301 }
302 while (curModule == MODULE_GALLERY);
303
304 m_module.set(curModule);
305 }
306 // For Bug 200239385
307 // There are asserts while operating the gallery.
308 // This "#if" will disable access to the gallery until it can be fixed
309 #if 0
310 else if (key == Key("g"))
311 {
312 // switch to gallery on/off
313 Modules curModule = m_module.get();
314
315 if (curModule == MODULE_GALLERY)
316 {
317 curModule = m_activeModuleBeforeGallery;
318 }
319 else
320 {
321 m_activeModuleBeforeGallery = curModule;
322 curModule = MODULE_GALLERY;
323 }
324
325 m_module.set(curModule);
326 }
327 #endif
328 // call parent
329 PROPAGATE_ERROR(App::onKey(key));
330
331 return true;
332 }
333
334 bool CameraApp::onModuleChanged(const Observed &source)
335 {
336 assert(static_cast<const Value<Modules>&>(source).get() == m_module);
337
338 if (m_prevModule != MODULE_INVALID)
339 PROPAGATE_ERROR(m_modules[m_prevModule]->stop());
340
341 m_prevModule = m_module.get();
342
343 PROPAGATE_ERROR(m_modules[m_module.get()]->start(m_iGuiMenuBar, m_iGuiContainerConfig));
344
345 return true;
346 }
347
348 }; // namespace ArgusSamples
349
350 int main(int argc, char **argv)
351 {
352 ArgusSamples::CameraApp cameraApp(argv[0]);
353
354 if (!cameraApp.run(argc, argv))
355 return EXIT_FAILURE;
356
357 return EXIT_SUCCESS;
358 }