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