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, 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 {
72 
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 
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 
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 
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"));
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 
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_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 
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 }