Argus Camera Sample
Argus Camera Sample
 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-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 // For Bug 200239385 and Bug 200243017
30 // There are asserts while operating the gallery.
31 // With the following #define commented out, access to the gallery is disabled until it can be fixed
32 //#define GALLERY_SUPPORTED
33 
34 #include <stdlib.h>
35 
36 #include <list>
37 
38 #include "Error.h"
39 #include "UniquePointer.h"
40 #include "Window.h"
41 #include "Value.h"
42 #include "Validator.h"
43 #include "IObserver.h"
44 
45 #include "App.h"
46 #include "AppModuleCapture.h"
47 #include "AppModuleVideo.h"
48 #include "AppModuleMultiExposure.h"
49 #include "AppModuleMultiSession.h"
50 #include "AppModuleGallery.h"
51 #include "AppModuleGeneric.h"
52 
53 namespace ArgusSamples
54 {
55 
56 #if (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
57 /**
58  * GTK UI builder string
59  */
60 static const char builderString[] =
61 {
62 #include "cameraBuilder.h"
63  , 0x00
64 };
65 #endif // (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
66 
67 /**
68  * Supported modules
69  */
70 enum Modules
71 {
76 #ifdef GALLERY_SUPPORTED
77  MODULE_GALLERY,
78 #endif
80 #ifdef GALLERY_SUPPORTED
81  MODULE_LAST = MODULE_GALLERY,
82 #else
83  MODULE_LAST = MODULE_MULTI_SESSION,
84 #endif
87 };
88 
89 // valid module values
90 static const ValidatorEnum<Modules>::ValueStringPair s_modules[] =
91 {
92  { MODULE_CAPTURE, "Capture" },
93  { MODULE_VIDEO, "Video" },
94  { MODULE_MULTI_EXPOSURE, "Multi Exposure" },
95 #ifdef GALLERY_SUPPORTED
96  { MODULE_MULTI_SESSION, "Multi Session" },
97  { MODULE_GALLERY, "Gallery" }
98 #else
99  { MODULE_MULTI_SESSION, "Multi Session" }
100 #endif
101 };
102 
103 class CameraApp : public App, public IObserver
104 {
105 public:
106  explicit CameraApp(const char *appName);
107  ~CameraApp();
108 
109  /** @name App methods */
110  /**@{*/
111  virtual bool initialize();
112  virtual bool shutdown();
113  virtual bool start();
114  /**@}*/
115 
116 private:
117  /**
118  * Hide default constructor
119  */
120  CameraApp();
121 
122  /** @name IKeyObserver methods */
123  /**@{*/
124  virtual bool onKey(const Key &key);
125  /**@}*/
126 
127  bool onModuleChanged(const Observed &source);
128 
130 
131  Value<Modules> m_module; ///< active module
132  Modules m_prevModule; ///< previously active module
133 
134  Modules m_activeModuleBeforeGallery; ///< active module when switching to gallery
135 
136  std::vector<IAppModule*> m_modules; ///< all modules
137 
138  Window::IGuiMenuBar *m_iGuiMenuBar; ///< menu bar
139  Window::IGuiContainer *m_iGuiContainerConfig; ///< container for config GUI elements
140 };
141 
142 CameraApp::CameraApp(const char *appName)
143  : App(appName)
144  , m_module(new ValidatorEnum<Modules>(
145  s_modules, sizeof(s_modules) / sizeof(s_modules[0])),
146  MODULE_FIRST)
147  , m_prevModule(MODULE_INVALID)
148  , m_activeModuleBeforeGallery(MODULE_INVALID)
149  , m_iGuiMenuBar(NULL)
150  , m_iGuiContainerConfig(NULL)
151 {
152 }
153 
155 {
156  shutdown();
157 }
158 
160 {
161  PROPAGATE_ERROR(App::initialize());
162 
163  const char *description =
164  "Press 'm' to toggle between modules (still capture, video recording, multi exposure, \n"
165  "multi session).\n"
166 #ifdef GALLERY_SUPPORTED
167  "Press 'g' to switch to gallery and back. Use left and right arrow keys to move to next\n"
168  "and previous image or video.\n"
169 #endif
170  "Press 'space' to execute the module action (capture an image, start and stop recording,\n"
171  "start and stop video playback.\n";
172  PROPAGATE_ERROR(m_options.addDescription(description));
173 
174  PROPAGATE_ERROR(m_options.addOption(
175  createValueOption("module", 0, "MODULE", "switch to module MODULE.", m_module)));
176 
177 #if (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
178  Window::IGuiBuilder *builder = NULL;
179  PROPAGATE_ERROR(Window::IGuiBuilder::create(builderString, &builder));
180 
181  UniquePointer<Window::IGuiBuilder> createdBuilder(builder);
182  UniquePointer<Window::IGuiElement> createdWindow(createdBuilder->createElement("window"));
183  UniquePointer<Window::IGuiElement> createdView(createdBuilder->createElement("view"));
184 
185  m_iGuiMenuBar =
186  static_cast<Window::IGuiMenuBar*>(createdBuilder->createElement("menuBar"));
188  static_cast<Window::IGuiContainer*>(createdBuilder->createElement("config"));
189 
190  // set the window GUI
191  PROPAGATE_ERROR(Window::getInstance().setWindowGui(createdBuilder.get(), createdWindow.get(),
192  createdView.get()));
193 
194  createdView.release();
195  createdWindow.release();
196  createdBuilder.release();
197 #endif // (WINDOW_GUI_SUPPORT == WINDOW_GUI_GTK)
198 
199  m_modules.resize(MODULE_COUNT);
200 
201  // create modules
202  UniquePointer<IAppModule> module;
203  module.reset(new AppModuleCapture);
204  if (!module)
205  ORIGINATE_ERROR("Out of memory");
206  m_modules[MODULE_CAPTURE] = module.release();
207 
208  module.reset(new AppModuleVideo);
209  if (!module)
210  ORIGINATE_ERROR("Out of memory");
211  m_modules[MODULE_VIDEO] = module.release();
212 
213  module.reset(new AppModuleMultiExposure);
214  if (!module)
215  ORIGINATE_ERROR("Out of memory");
216  m_modules[MODULE_MULTI_EXPOSURE] = module.release();
217 
218  module.reset(new AppModuleMultiSession);
219  if (!module)
220  ORIGINATE_ERROR("Out of memory");
221  m_modules[MODULE_MULTI_SESSION] = module.release();
222 
223 #ifdef GALLERY_SUPPORTED
224  module.reset(new AppModuleGallery);
225  if (!module)
226  ORIGINATE_ERROR("Out of memory");
227  m_modules[MODULE_GALLERY] = module.release();
228 #endif
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 
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 
264 {
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
279 
280  // register an observer, this will stop/start modules if m_module changes
281  PROPAGATE_ERROR(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 #ifdef GALLERY_SUPPORTED
295  // switch to next module but skip gallery
296  do
297  {
298 #endif
299  if (curModule == MODULE_LAST)
300  curModule = MODULE_FIRST;
301  else
302  curModule = static_cast<Modules>(curModule + 1);
303 #ifdef GALLERY_SUPPORTED
304  }
305  while (curModule == MODULE_GALLERY);
306 #endif
307 
308  m_module.set(curModule);
309  }
310 #ifdef GALLERY_SUPPORTED
311  else if (key == Key("g"))
312  {
313  // switch to gallery on/off
314  Modules curModule = m_module.get();
315 
316  if (curModule == MODULE_GALLERY)
317  {
318  curModule = m_activeModuleBeforeGallery;
319  }
320  else
321  {
322  m_activeModuleBeforeGallery = curModule;
323  curModule = MODULE_GALLERY;
324  }
325 
326  m_module.set(curModule);
327  }
328 #endif
329  // call parent
330  PROPAGATE_ERROR(App::onKey(key));
331 
332  return true;
333 }
334 
335 bool CameraApp::onModuleChanged(const Observed &source)
336 {
337  assert(static_cast<const Value<Modules>&>(source).get() == m_module);
338 
340  PROPAGATE_ERROR(m_modules[m_prevModule]->stop());
341 
342  m_prevModule = m_module.get();
343 
344  PROPAGATE_ERROR(m_modules[m_module.get()]->start(m_iGuiMenuBar, m_iGuiContainerConfig));
345 
346  return true;
347 }
348 
349 }; // namespace ArgusSamples
350 
351 int main(int argc, char **argv)
352 {
353  printf("Executing Argus Sample Application (%s)\n", basename(argv[0]));
354 
355  ArgusSamples::CameraApp cameraApp(basename(argv[0]));
356 
357  if (!cameraApp.run(argc, argv))
358  return EXIT_FAILURE;
359 
360  return EXIT_SUCCESS;
361 }