Argus Camera Sample
Argus Camera Sample
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Dispatcher.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 <stdio.h>
30 #include <unistd.h>
31 #include <stdarg.h>
32 #include <assert.h>
33 
34 #include <sstream>
35 #include <limits>
36 
37 #include "Dispatcher.h"
38 #include "InitOnce.h"
39 #include "UniquePointer.h"
40 #include "Error.h"
41 #include "Util.h"
42 #include "Renderer.h"
43 #include "Validator.h"
44 #include <Argus/Ext/BayerSharpnessMap.h>
45 #include <Argus/Ext/DebugCaptureMetadata.h>
46 #include <Argus/Ext/DebugCaptureSession.h>
47 #include <Argus/Ext/DeFog.h>
48 #include <Argus/Ext/FaceDetect.h>
49 #include <Argus/Ext/SensorPrivateMetadata.h>
50 #include <Argus/Ext/DebugCaptureSession.h>
51 #include <Argus/Ext/PwlWdrSensorMode.h>
52 
53 namespace ArgusSamples
54 {
55 
56 /**
57  * An observer for an Argus interface.
58  */
59 class IObserverForInterface : public IObserver
60 {
61 public:
62  virtual ~IObserverForInterface() { };
63 
64  /**
65  * Check if this is the observer for the given interface.
66  *
67  * @param interface [in]
68  */
69  virtual bool isInterface(Argus::Interface *interface) const = 0;
70 };
71 
72 /**
73  * Denoise settings observer. Update Argus denoise settings when values change.
74  */
76 {
77 public:
78  DenoiseSettingsObserver(Argus::IDenoiseSettings *iDenoiseSettings)
79  : m_iDenoiseSettings(iDenoiseSettings)
80  {
81  Dispatcher &dispatcher = Dispatcher::getInstance();
82 
83  PROPAGATE_ERROR_CONTINUE(dispatcher.m_denoiseMode.registerObserver(this,
84  static_cast<IObserver::CallbackFunction>(
86  PROPAGATE_ERROR_CONTINUE(dispatcher.m_denoiseStrength.registerObserver(this,
87  static_cast<IObserver::CallbackFunction>(
89  }
90 
92  {
93  Dispatcher &dispatcher = Dispatcher::getInstance();
94 
95  PROPAGATE_ERROR_CONTINUE(dispatcher.m_denoiseMode.unregisterObserver(this,
96  static_cast<IObserver::CallbackFunction>(
98  PROPAGATE_ERROR_CONTINUE(dispatcher.m_denoiseStrength.unregisterObserver(this,
99  static_cast<IObserver::CallbackFunction>(
101  }
102 
103  virtual bool isInterface(Argus::Interface *interface) const
104  {
105  return (interface == m_iDenoiseSettings);
106  }
107 
108 private:
109  bool onDenoiseModeChanged(const Observed &source)
110  {
111  Dispatcher &dispatcher = Dispatcher::getInstance();
112 
113  assert(&source == &dispatcher.m_denoiseMode);
114 
115  if (m_iDenoiseSettings->setDenoiseMode(dispatcher.m_denoiseMode.get()) != Argus::STATUS_OK)
116  ORIGINATE_ERROR("Failed to set the denoising mode");
117 
118  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
119 
120  return true;
121  }
122 
123  bool onDenoiseStrengthChanged(const Observed &source)
124  {
125  Dispatcher &dispatcher = Dispatcher::getInstance();
126 
127  assert(&source == &dispatcher.m_denoiseStrength);
128 
129  if (m_iDenoiseSettings->setDenoiseStrength(dispatcher.m_denoiseStrength.get()) !=
130  Argus::STATUS_OK)
131  {
132  ORIGINATE_ERROR("Failed to set the denoise strength");
133  }
134 
135  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
136 
137  return true;
138  }
139 
140  Argus::IDenoiseSettings *m_iDenoiseSettings;
141 };
142 
143 /**
144  * Edge enhancement settings observer. Update Argus edge enhance settings when values change.
145  */
147 {
148 public:
149  EdgeEnhanceSettingsObserver(Argus::IEdgeEnhanceSettings *iEdgeEnhanceSettings)
150  : m_iEdgeEnhanceSettings(iEdgeEnhanceSettings)
151  {
152  Dispatcher &dispatcher = Dispatcher::getInstance();
153 
154  PROPAGATE_ERROR_CONTINUE(dispatcher.m_edgeEnhanceMode.registerObserver(this,
155  static_cast<IObserver::CallbackFunction>(
157  PROPAGATE_ERROR_CONTINUE(dispatcher.m_edgeEnhanceStrength.registerObserver(this,
158  static_cast<IObserver::CallbackFunction>(
160  }
161 
163  {
164  Dispatcher &dispatcher = Dispatcher::getInstance();
165 
166  PROPAGATE_ERROR_CONTINUE(dispatcher.m_edgeEnhanceMode.unregisterObserver(this,
167  static_cast<IObserver::CallbackFunction>(
169  PROPAGATE_ERROR_CONTINUE(dispatcher.m_edgeEnhanceStrength.unregisterObserver(this,
170  static_cast<IObserver::CallbackFunction>(
172  }
173 
174  virtual bool isInterface(Argus::Interface *interface) const
175  {
176  return (interface == m_iEdgeEnhanceSettings);
177  }
178 
179 private:
180  bool onEdgeEnhanceModeChanged(const Observed &source)
181  {
182  Dispatcher &dispatcher = Dispatcher::getInstance();
183 
184  assert(&source == &dispatcher.m_edgeEnhanceMode);
185 
186  if (m_iEdgeEnhanceSettings->setEdgeEnhanceMode(dispatcher.m_edgeEnhanceMode.get())
187  != Argus::STATUS_OK)
188  {
189  ORIGINATE_ERROR("Failed to set the edge enhancement mode");
190  }
191 
192  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
193 
194  return true;
195  }
196 
197  bool onEdgeEnhanceStrengthChanged(const Observed &source)
198  {
199  Dispatcher &dispatcher = Dispatcher::getInstance();
200 
201  assert(&source == &dispatcher.m_edgeEnhanceStrength);
202 
203  if (m_iEdgeEnhanceSettings->setEdgeEnhanceStrength(dispatcher.m_edgeEnhanceStrength.get())
204  != Argus::STATUS_OK)
205  {
206  ORIGINATE_ERROR("Failed to set the edge enhancement strength");
207  }
208 
209  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
210 
211  return true;
212  }
213 
214  Argus::IEdgeEnhanceSettings *m_iEdgeEnhanceSettings;
215 };
216 
217 /**
218  * Video stabilization settings observer. Update Argus video stabilization settings when changed.
219  */
221 {
222 public:
223  VideoStabilizationSettingsObserver(Argus::IVideoStabilizationSettings *iVStabSettings)
224  : m_iVideoStabilizationSettings(iVStabSettings)
225  {
226  Dispatcher &dispatcher = Dispatcher::getInstance();
227 
228  PROPAGATE_ERROR_CONTINUE(dispatcher.m_vstabMode.registerObserver(this,
229  static_cast<IObserver::CallbackFunction>(
231  }
232 
234  {
235  Dispatcher &dispatcher = Dispatcher::getInstance();
236 
237  PROPAGATE_ERROR_CONTINUE(dispatcher.m_vstabMode.unregisterObserver(this,
238  static_cast<IObserver::CallbackFunction>(
240  }
241 
242  virtual bool isInterface(Argus::Interface *interface) const
243  {
244  return (interface == m_iVideoStabilizationSettings);
245  }
246 
247 private:
248  bool onVideoStabilizationModeChanged(const Observed &source)
249  {
250  Dispatcher &dispatcher = Dispatcher::getInstance();
251 
252  assert(&source == &dispatcher.m_vstabMode);
253 
254  if (m_iVideoStabilizationSettings->setVideoStabilizationMode(dispatcher.m_vstabMode.get())
255  != Argus::STATUS_OK)
256  {
257  ORIGINATE_ERROR("Failed to set the video stabilization mode");
258  }
259 
260  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
261 
262  return true;
263  }
264 
265  Argus::IVideoStabilizationSettings *m_iVideoStabilizationSettings;
266 };
267 
268 /**
269  * Source settings observer. Update Argus source settings if values which are set through the
270  * source settings change.
271  */
273 {
274 public:
275  SourceSettingsObserver(Argus::ISourceSettings *iSourceSettings)
276  : m_iSourceSettings(iSourceSettings)
277  {
278  Dispatcher &dispatcher = Dispatcher::getInstance();
279 
280  PROPAGATE_ERROR_CONTINUE(dispatcher.m_exposureTimeRange.registerObserver(this,
281  static_cast<IObserver::CallbackFunction>(
283  PROPAGATE_ERROR_CONTINUE(dispatcher.m_gainRange.registerObserver(this,
284  static_cast<IObserver::CallbackFunction>(
286  PROPAGATE_ERROR_CONTINUE(dispatcher.m_sensorModeIndex.registerObserver(this,
287  static_cast<IObserver::CallbackFunction>(
289  PROPAGATE_ERROR_CONTINUE(dispatcher.m_frameRate.registerObserver(this,
290  static_cast<IObserver::CallbackFunction>(
292  PROPAGATE_ERROR_CONTINUE(dispatcher.m_focusPosition.registerObserver(this,
293  static_cast<IObserver::CallbackFunction>(
295  }
296 
298  {
299  Dispatcher &dispatcher = Dispatcher::getInstance();
300 
301  PROPAGATE_ERROR_CONTINUE(dispatcher.m_exposureTimeRange.unregisterObserver(this,
302  static_cast<IObserver::CallbackFunction>(
304  PROPAGATE_ERROR_CONTINUE(dispatcher.m_gainRange.unregisterObserver(this,
305  static_cast<IObserver::CallbackFunction>(
307  PROPAGATE_ERROR_CONTINUE(dispatcher.m_sensorModeIndex.unregisterObserver(this,
308  static_cast<IObserver::CallbackFunction>(
310  PROPAGATE_ERROR_CONTINUE(dispatcher.m_frameRate.unregisterObserver(this,
311  static_cast<IObserver::CallbackFunction>(
313  PROPAGATE_ERROR_CONTINUE(dispatcher.m_focusPosition.unregisterObserver(this,
314  static_cast<IObserver::CallbackFunction>(
316  }
317 
318  virtual bool isInterface(Argus::Interface *interface) const
319  {
320  return (interface == m_iSourceSettings);
321  }
322 
323 private:
324  bool onExposureTimeRangeChanged(const Observed &source)
325  {
326  Dispatcher &dispatcher = Dispatcher::getInstance();
327 
328  assert(&source == &dispatcher.m_exposureTimeRange);
329 
330  if (m_iSourceSettings->setExposureTimeRange(dispatcher.m_exposureTimeRange.get()) !=
331  Argus::STATUS_OK)
332  {
333  ORIGINATE_ERROR("Failed to set exposure time range");
334  }
335 
336  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
337 
338  return true;
339  }
340 
341  bool onGainRangeChanged(const Observed &source)
342  {
343  Dispatcher &dispatcher = Dispatcher::getInstance();
344 
345  assert(&source == &dispatcher.m_gainRange);
346 
347  if (m_iSourceSettings->setGainRange(dispatcher.m_gainRange.get()) != Argus::STATUS_OK)
348  ORIGINATE_ERROR("Failed to set gain range");
349 
350  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
351 
352  return true;
353  }
354 
355  bool onSensorModeChanged(const Observed &source)
356  {
357  Dispatcher &dispatcher = Dispatcher::getInstance();
358 
359  assert(&source == &dispatcher.m_sensorModeIndex);
360 
361  Argus::SensorMode *sensorMode = NULL;
362  PROPAGATE_ERROR(dispatcher.getSensorMode(dispatcher.m_sensorModeIndex.get(), &sensorMode));
363 
364  if (m_iSourceSettings->setSensorMode(sensorMode) != Argus::STATUS_OK)
365  ORIGINATE_ERROR("Failed to set sensor mode");
366 
367  PROPAGATE_ERROR(dispatcher.restartActiveRequests());
368 
369  return true;
370  }
371 
372  bool onFocusPositionChanged(const Observed &source)
373  {
374  Dispatcher &dispatcher = Dispatcher::getInstance();
375 
376  assert(&source == &dispatcher.m_focusPosition);
377 
378  if (m_iSourceSettings->setFocusPosition(dispatcher.m_focusPosition.get()) !=
379  Argus::STATUS_OK)
380  {
381  ORIGINATE_ERROR("Failed to set focus position");
382  }
383 
384  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
385 
386  return true;
387  }
388 
389  bool onFrameRateChanged(const Observed &source)
390  {
391  Dispatcher &dispatcher = Dispatcher::getInstance();
392 
393  assert(&source == &dispatcher.m_frameRate);
394 
395  Argus::Range<uint64_t> frameDurationRangeNs(0);
396 
397  if (dispatcher.m_frameRate.get() == 0.0f)
398  {
399  // a frame rate of zero means VFR, get the sensor frame duration and apply it to
400  // the source
401  Argus::SensorMode *sensorMode = NULL;
402  PROPAGATE_ERROR(dispatcher.getSensorMode(dispatcher.m_sensorModeIndex.get(),
403  &sensorMode));
404 
405  Argus::ISensorMode *iSensorMode =
406  Argus::interface_cast<Argus::ISensorMode>(sensorMode);
407 
408  frameDurationRangeNs = iSensorMode->getFrameDurationRange();
409  }
410  else
411  {
412  // frame rate is frames per second, frameduration is in nanoseconds
413  frameDurationRangeNs =
414  TimeValue::fromCycelsPerSec(dispatcher.m_frameRate.get()).toNSec();
415  }
416 
417  if (m_iSourceSettings->setFrameDurationRange(frameDurationRangeNs) != Argus::STATUS_OK)
418  ORIGINATE_ERROR("Failed to set frame duration range");
419 
420  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
421 
422  return true;
423  }
424 
425  Argus::ISourceSettings *m_iSourceSettings;
426 };
427 
428 /**
429  * Auto control settings observer. Update Argus auto control settings if values which are set
430  * through the auto control settings change.
431  */
433 {
434 public:
435  AutoControlSettingsObserver(Argus::IAutoControlSettings *iAutoControlSettings)
436  : m_iAutoControlSettings(iAutoControlSettings)
437  {
438  Dispatcher &dispatcher = Dispatcher::getInstance();
439 
440  PROPAGATE_ERROR_CONTINUE(dispatcher.m_aeAntibandingMode.registerObserver(this,
441  static_cast<IObserver::CallbackFunction>(
443  PROPAGATE_ERROR_CONTINUE(dispatcher.m_aeLock.registerObserver(this,
444  static_cast<IObserver::CallbackFunction>(
446  PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbLock.registerObserver(this,
447  static_cast<IObserver::CallbackFunction>(
449  PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbMode.registerObserver(this,
450  static_cast<IObserver::CallbackFunction>(
452  PROPAGATE_ERROR_CONTINUE(dispatcher.m_exposureCompensation.registerObserver(this,
453  static_cast<IObserver::CallbackFunction>(
455  PROPAGATE_ERROR_CONTINUE(dispatcher.m_ispDigitalGainRange.registerObserver(this,
456  static_cast<IObserver::CallbackFunction>(
458 
459  }
460 
462  {
463  Dispatcher &dispatcher = Dispatcher::getInstance();
464 
465  PROPAGATE_ERROR_CONTINUE(dispatcher.m_aeAntibandingMode.unregisterObserver(this,
466  static_cast<IObserver::CallbackFunction>(
468  PROPAGATE_ERROR_CONTINUE(dispatcher.m_aeLock.unregisterObserver(this,
469  static_cast<IObserver::CallbackFunction>(
471  PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbLock.unregisterObserver(this,
472  static_cast<IObserver::CallbackFunction>(
474  PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbMode.unregisterObserver(this,
475  static_cast<IObserver::CallbackFunction>(
477  PROPAGATE_ERROR_CONTINUE(dispatcher.m_exposureCompensation.unregisterObserver(this,
478  static_cast<IObserver::CallbackFunction>(
480  PROPAGATE_ERROR_CONTINUE(dispatcher.m_ispDigitalGainRange.unregisterObserver(this,
481  static_cast<IObserver::CallbackFunction>(
483 
484  }
485 
486  virtual bool isInterface(Argus::Interface *interface) const
487  {
488  return (interface == m_iAutoControlSettings);
489  }
490 
491 private:
492  bool onAeAntibandingModeChanged(const Observed &source)
493  {
494  Dispatcher &dispatcher = Dispatcher::getInstance();
495 
496  assert(&source == &dispatcher.m_aeAntibandingMode);
497 
498  if (m_iAutoControlSettings->setAeAntibandingMode(dispatcher.m_aeAntibandingMode.get()) !=
499  Argus::STATUS_OK)
500  {
501  ORIGINATE_ERROR("Failed to set the AE antibanding mode");
502  }
503 
504  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
505 
506  return true;
507  }
508 
509  bool onAeLockChanged(const Observed &source)
510  {
511  Dispatcher &dispatcher = Dispatcher::getInstance();
512 
513  assert(&source == &dispatcher.m_aeLock);
514 
515  if (m_iAutoControlSettings->setAeLock(dispatcher.m_aeLock.get()) != Argus::STATUS_OK)
516  ORIGINATE_ERROR("Failed to set the AE lock");
517 
518  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
519 
520  return true;
521  }
522 
523  bool onAwbLockChanged(const Observed &source)
524  {
525  Dispatcher &dispatcher = Dispatcher::getInstance();
526 
527  assert(&source == &dispatcher.m_awbLock);
528 
529  if (m_iAutoControlSettings->setAwbLock(dispatcher.m_awbLock.get()) != Argus::STATUS_OK)
530  ORIGINATE_ERROR("Failed to set the AWB lock");
531 
532  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
533 
534  return true;
535  }
536 
537  bool onAwbModeChanged(const Observed &source)
538  {
539  Dispatcher &dispatcher = Dispatcher::getInstance();
540 
541  assert(&source == &dispatcher.m_awbMode);
542 
543  if (m_iAutoControlSettings->setAwbMode(dispatcher.m_awbMode.get()) != Argus::STATUS_OK)
544  ORIGINATE_ERROR("Failed to set the AWB mode");
545 
546  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
547 
548  return true;
549  }
550 
551  bool onExposureCompensationChanged(const Observed &source)
552  {
553  Dispatcher &dispatcher = Dispatcher::getInstance();
554 
555  assert(&source == &dispatcher.m_exposureCompensation);
556 
557  if (m_iAutoControlSettings->setExposureCompensation(
558  dispatcher.m_exposureCompensation.get()) != Argus::STATUS_OK)
559  {
560  ORIGINATE_ERROR("Failed to set the exposure compensation");
561  }
562 
563  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
564 
565  return true;
566  }
567 
568  bool onIspDigitalGainRangeChanged(const Observed &source)
569  {
570  Dispatcher &dispatcher = Dispatcher::getInstance();
571 
572  assert(&source == &dispatcher.m_ispDigitalGainRange);
573 
574  if (m_iAutoControlSettings->setIspDigitalGainRange(
575  dispatcher.m_ispDigitalGainRange.get()) != Argus::STATUS_OK)
576  {
577  ORIGINATE_ERROR("Failed to set the Isp Digital Gain Range");
578  }
579  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
580 
581  return true;
582  }
583 
584  Argus::IAutoControlSettings *m_iAutoControlSettings;
585 };
586 
587 /**
588  * DeFog settings observer. Update Argus DeFog settings if values which are set through the
589  * DeFog settings change.
590  */
592 {
593 public:
594  DeFogSettingsObserver(Argus::Ext::IDeFogSettings *iDeFogSettings)
595  : m_iDeFogSettings(iDeFogSettings)
596  {
597  Dispatcher &dispatcher = Dispatcher::getInstance();
598 
599  PROPAGATE_ERROR_CONTINUE(dispatcher.m_deFogEnable.registerObserver(this,
600  static_cast<IObserver::CallbackFunction>(&DeFogSettingsObserver::onDeFogEnableChanged)));
601  PROPAGATE_ERROR_CONTINUE(dispatcher.m_deFogAmount.registerObserver(this,
602  static_cast<IObserver::CallbackFunction>(&DeFogSettingsObserver::onDeFogAmountChanged)));
603  PROPAGATE_ERROR_CONTINUE(dispatcher.m_deFogQuality.registerObserver(this,
604  static_cast<IObserver::CallbackFunction>(&DeFogSettingsObserver::onDeFogQualityChanged)));
605  }
606 
608  {
609  Dispatcher &dispatcher = Dispatcher::getInstance();
610 
611  PROPAGATE_ERROR_CONTINUE(dispatcher.m_deFogEnable.unregisterObserver(this,
612  static_cast<IObserver::CallbackFunction>(&DeFogSettingsObserver::onDeFogEnableChanged)));
613  PROPAGATE_ERROR_CONTINUE(dispatcher.m_deFogAmount.unregisterObserver(this,
614  static_cast<IObserver::CallbackFunction>(&DeFogSettingsObserver::onDeFogAmountChanged)));
615  PROPAGATE_ERROR_CONTINUE(dispatcher.m_deFogQuality.unregisterObserver(this,
616  static_cast<IObserver::CallbackFunction>(&DeFogSettingsObserver::onDeFogQualityChanged)));
617  }
618 
619  virtual bool isInterface(Argus::Interface *interface) const
620  {
621  return (interface == m_iDeFogSettings);
622  }
623 
624 private:
625  bool onDeFogEnableChanged(const Observed &source)
626  {
627  Dispatcher &dispatcher = Dispatcher::getInstance();
628 
629  assert(&source == &dispatcher.m_deFogEnable);
630 
631  m_iDeFogSettings->setDeFogEnable(dispatcher.m_deFogEnable.get());
632 
633  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
634 
635  return true;
636  }
637 
638  bool onDeFogAmountChanged(const Observed &source)
639  {
640  Dispatcher &dispatcher = Dispatcher::getInstance();
641 
642  assert(&source == &dispatcher.m_deFogAmount);
643 
644  if (m_iDeFogSettings->setDeFogAmount(dispatcher.m_deFogAmount.get()) != Argus::STATUS_OK)
645  ORIGINATE_ERROR("Failed to set the DeFog amount");
646 
647  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
648 
649  return true;
650  }
651 
652  bool onDeFogQualityChanged(const Observed &source)
653  {
654  Dispatcher &dispatcher = Dispatcher::getInstance();
655 
656  assert(&source == &dispatcher.m_deFogQuality);
657 
658  if (m_iDeFogSettings->setDeFogQuality(dispatcher.m_deFogQuality.get()) != Argus::STATUS_OK)
659  ORIGINATE_ERROR("Failed to set the DeFog quality");
660 
661  PROPAGATE_ERROR(Dispatcher::getInstance().restartActiveRequests());
662 
663  return true;
664  }
665 
666  Argus::Ext::IDeFogSettings *m_iDeFogSettings;
667 };
668 
669 // valid denoise modes
670 static const ValidatorEnum<Argus::DenoiseMode>::ValueStringPair s_denoiseModes[] =
671 {
672  { Argus::DENOISE_MODE_OFF, "off" },
673  { Argus::DENOISE_MODE_FAST, "fast" },
674  { Argus::DENOISE_MODE_HIGH_QUALITY, "highquality" }
675 };
676 
677 // valid edge enhance modes
678 static const ValidatorEnum<Argus::EdgeEnhanceMode>::ValueStringPair s_edgeEnhanceModes[] =
679 {
680  { Argus::EDGE_ENHANCE_MODE_OFF, "off" },
681  { Argus::EDGE_ENHANCE_MODE_FAST, "fast" },
682  { Argus::EDGE_ENHANCE_MODE_HIGH_QUALITY, "highquality" }
683 };
684 
685 // valid vstab modes
686 static const ValidatorEnum<Argus::VideoStabilizationMode>::ValueStringPair s_vstabModes[] =
687 {
688  { Argus::VIDEO_STABILIZATION_MODE_OFF, "off" },
689  { Argus::VIDEO_STABILIZATION_MODE_ON, "on" }
690 };
691 
692 // valid AE antibanding modes
693 static const ValidatorEnum<Argus::AeAntibandingMode>::ValueStringPair s_aeAntibandingModes[] =
694 {
695  { Argus::AE_ANTIBANDING_MODE_OFF, "off" },
696  { Argus::AE_ANTIBANDING_MODE_AUTO, "auto" },
697  { Argus::AE_ANTIBANDING_MODE_50HZ, "50hz" },
698  { Argus::AE_ANTIBANDING_MODE_60HZ, "60hz" }
699 };
700 
701 // valid AWB modes
702 static const ValidatorEnum<Argus::AwbMode>::ValueStringPair s_awbModes[] =
703 {
704  { Argus::AWB_MODE_OFF, "off" },
705  { Argus::AWB_MODE_AUTO, "auto" },
706  { Argus::AWB_MODE_INCANDESCENT, "incandescent" },
707  { Argus::AWB_MODE_FLUORESCENT, "fluorescent" },
708  { Argus::AWB_MODE_WARM_FLUORESCENT, "warmfluorescent" },
709  { Argus::AWB_MODE_DAYLIGHT, "daylight" },
710  { Argus::AWB_MODE_CLOUDY_DAYLIGHT, "cloudydaylight" },
711  { Argus::AWB_MODE_TWILIGHT, "twilight" },
712  { Argus::AWB_MODE_SHADE, "shade" },
713  { Argus::AWB_MODE_MANUAL, "manual" }
714 };
715 
716 // valid video formats
717 static const ValidatorEnum<VideoPipeline::VideoFormat>::ValueStringPair s_videoFormats[] =
718 {
722 };
723 
724 // valid video file types
725 static const ValidatorEnum<VideoPipeline::VideoFileType>::ValueStringPair s_videoFileTypes[] =
726 {
732 };
733 
734 static const Argus::Size2D<uint32_t> s_outputSizes[] =
735 {
736  Argus::Size2D<uint32_t>(0, 0), // if size is 0,0 take the current sensor size
737  Argus::Size2D<uint32_t>(176, 144), // QCIF
738  Argus::Size2D<uint32_t>(320, 240),
739  Argus::Size2D<uint32_t>(640, 480),
740  Argus::Size2D<uint32_t>(1280, 720), // 720p HDTV
741  Argus::Size2D<uint32_t>(1920, 1080), // 1080p HDTV
742  Argus::Size2D<uint32_t>(3840, 2160), // 2160p 4K UHDTV
743 };
744 
746  : m_deviceFocusPositionRange(0)
747  , m_deviceIspDigitalGainRange(Argus::Range<float>(0.0f))
748  , m_sensorExposureTimeRange(Argus::Range<uint64_t>(0))
749  , m_sensorAnalogGainRange(Argus::Range<float>(0.0f))
750  , m_sensorFrameRateRange(0.0f)
751  , m_deviceIndex(new ValidatorStdVector<uint32_t, Argus::CameraDevice*>(&m_cameraDevices), 0)
752  , m_deviceOpen(false)
753  , m_verbose(false)
754  , m_kpi(false)
755  , m_exposureTimeRange(new ValidatorRange<Argus::Range<uint64_t> >(&m_sensorExposureTimeRange),
756  Argus::Range<uint64_t>(0))
757  , m_gainRange(new ValidatorRange<Argus::Range<float > >(&m_sensorAnalogGainRange),
758  Argus::Range<float>(0.0f))
759  , m_sensorModeIndex(new ValidatorEnum<uint32_t>(), 0)
760  , m_frameRate(new ValidatorRange<float>(&m_sensorFrameRateRange), 0.0f)
761  , m_focusPosition(new ValidatorRange<int32_t>(&m_deviceFocusPositionRange), 0)
762  , m_denoiseMode(new ValidatorEnum<Argus::DenoiseMode>(
763  s_denoiseModes, sizeof(s_denoiseModes) / sizeof(s_denoiseModes[0])),
764  Argus::DENOISE_MODE_OFF)
765  , m_denoiseStrength(new ValidatorRange<float>(0.0f, 1.0f), 1.0f)
766  , m_edgeEnhanceMode(new ValidatorEnum<Argus::EdgeEnhanceMode>(
767  s_edgeEnhanceModes, sizeof(s_edgeEnhanceModes) / sizeof(s_edgeEnhanceModes[0])),
768  Argus::EDGE_ENHANCE_MODE_OFF)
769  , m_edgeEnhanceStrength(new ValidatorRange<float>(0.0f, 1.0f), 1.0f)
770  , m_vstabMode(new ValidatorEnum<Argus::VideoStabilizationMode>(
771  s_vstabModes, sizeof(s_vstabModes) / sizeof(s_vstabModes[0])),
772  Argus::VIDEO_STABILIZATION_MODE_OFF)
773  , m_aeAntibandingMode(new ValidatorEnum<Argus::AeAntibandingMode>(
774  s_aeAntibandingModes, sizeof(s_aeAntibandingModes) / sizeof(s_aeAntibandingModes[0])),
775  Argus::AE_ANTIBANDING_MODE_AUTO)
776  , m_aeLock(false)
777  , m_awbLock(false)
778  , m_awbMode(new ValidatorEnum<Argus::AwbMode>(
779  s_awbModes, sizeof(s_awbModes) / sizeof(s_awbModes[0])),
780  Argus::AWB_MODE_AUTO)
781  , m_exposureCompensation(new ValidatorRange<float>(-10.0f, 10.0f), 0.0f)
782  , m_ispDigitalGainRange(new ValidatorRange<Argus::Range<float> >(&m_deviceIspDigitalGainRange),
783  Argus::Range<float>(1.0f))
784  , m_videoFormat(new ValidatorEnum<VideoPipeline::VideoFormat>(
785  s_videoFormats, sizeof(s_videoFormats) / sizeof(s_videoFormats[0])),
786  VideoPipeline::VIDEO_FORMAT_H264)
787  , m_videoFileType(new ValidatorEnum<VideoPipeline::VideoFileType>(
788  s_videoFileTypes, sizeof(s_videoFileTypes) / sizeof(s_videoFileTypes[0])),
789  VideoPipeline::VIDEO_FILE_TYPE_MP4)
790  , m_videoBitRate(new ValidatorRange<uint32_t>(0, std::numeric_limits<uint32_t>::max()), 0)
791  , m_outputSize(new ValidatorSize2D<uint32_t>(s_outputSizes,
792  sizeof(s_outputSizes) / sizeof(s_outputSizes[0]), true /*allowArbitrarySizes*/),
793  Argus::Size2D<uint32_t>(0, 0))
794  , m_outputPath(".")
795  , m_deFogEnable(false)
796  , m_deFogAmount(new ValidatorRange<float>(0.0f, 1.0f), 0.9f)
797  , m_deFogQuality(new ValidatorRange<float>(0.0f, 1.0f), 0.14285f)
798  , m_initialized(false)
799  , m_iCameraProvider(NULL)
800 {
801  PROPAGATE_ERROR_CONTINUE(initialize());
802 }
803 
805 {
806  if (!shutdown())
807  REPORT_ERROR("Failed to shutdown");
808 }
809 
811 {
812  static InitOnce initOnce;
813  static Dispatcher instance;
814 
815  if (initOnce.begin())
816  {
817  if (instance.initialize())
818  {
819  initOnce.complete();
820  }
821  else
822  {
823  initOnce.failed();
824  REPORT_ERROR("Initalization failed");
825  }
826  }
827 
828  return instance;
829 }
830 
832 {
833  if (m_initialized)
834  return true;
835 
836  // Create the CameraProvider object and obtain its interface.
837  m_cameraProvider = Argus::UniqueObj<Argus::CameraProvider>(Argus::CameraProvider::create());
838  m_iCameraProvider = Argus::interface_cast<Argus::ICameraProvider>(m_cameraProvider);
839  if (!m_iCameraProvider)
840  ORIGINATE_ERROR("Failed to create CameraProvider");
841 
842  // Get the camera devices
843  m_iCameraProvider->getCameraDevices(&m_cameraDevices);
844  if (m_cameraDevices.size() == 0)
845  {
846  PROPAGATE_ERROR(shutdown());
847  ORIGINATE_ERROR("No cameras available");
848  }
849 
850  m_initialized = true;
851 
852  // register the device index observer after 'm_initialize' is set, the call back will be
853  // called immediately and assert that 'm_initialize' is set
854  PROPAGATE_ERROR_CONTINUE(m_deviceIndex.registerObserver(this,
855  static_cast<IObserver::CallbackFunction>(&Dispatcher::onDeviceIndexChanged)));
856  PROPAGATE_ERROR_CONTINUE(m_sensorModeIndex.registerObserver(this,
857  static_cast<IObserver::CallbackFunction>(&Dispatcher::onSensorModeIndexChanged)));
858 
859  return true;
860 }
861 
863 {
864  PROPAGATE_ERROR_CONTINUE(closeSession());
865 
866  m_cameraProvider.reset();
867  m_cameraDevices.clear();
868 
869  return true;
870 }
871 
872 bool Dispatcher::onDeviceIndexChanged(const Observed &source)
873 {
874  assert(static_cast<const Value<uint32_t>&>(source).get() == m_deviceIndex);
875  assert(m_initialized);
876 
877  // close the currently open device
878  if (m_deviceOpen)
879  {
880  PROPAGATE_ERROR(m_deviceOpen.set(false));
881 
882  PROPAGATE_ERROR(closeSession());
883 
884  // reset the current device properties
885  }
886 
887  // open the new device
888  const Argus::ICameraProperties *iCameraProperties =
889  Argus::interface_cast<Argus::ICameraProperties>(m_cameraDevices[m_deviceIndex]);
890  if (!iCameraProperties)
891  ORIGINATE_ERROR("Failed to get ICameraProperties interface");
892 
893  // get the sensor modes
894  if (iCameraProperties->getAllSensorModes(&m_sensorModes) != Argus::STATUS_OK)
895  ORIGINATE_ERROR("Failed to get sensor modes");
896 
897  if (m_sensorModes.size() == 0)
898  ORIGINATE_ERROR("No sensor modes found");
899 
900  // get the focus position range
901  PROPAGATE_ERROR(m_deviceFocusPositionRange.set(iCameraProperties->getFocusPositionRange()));
902 
903  // get new limits
904  Argus::Range<float> digitalGainRange = iCameraProperties->getIspDigitalGainRange();
905 
906  // set ranges to unified range (to avoid errors when setting new values)
907  Argus::Range<float> unifiedDigitalGainRange(0);
908  unifiedDigitalGainRange.min() =
909  std::min(m_deviceIspDigitalGainRange.get().min().min(), digitalGainRange.min());
910  unifiedDigitalGainRange.max() =
911  std::max(m_deviceIspDigitalGainRange.get().max().max(), digitalGainRange.max());
912 
913  PROPAGATE_ERROR(m_deviceIspDigitalGainRange.set(
914  Argus::Range<Argus::Range<float> >(unifiedDigitalGainRange)));
915 
916  // update dependent values
917  PROPAGATE_ERROR(m_ispDigitalGainRange.set(digitalGainRange));
918 
919  // set to final range
920  PROPAGATE_ERROR(m_deviceIspDigitalGainRange.set(Argus::Range<Argus::Range<float> >(
921  digitalGainRange, digitalGainRange)));
922 
923  // add value/string pairs for each sensor mode index
924  std::vector<ValidatorEnum<uint32_t>::ValueStringPair> valueStringPairs;
925  valueStringPairs.resize(m_sensorModes.size());
926  for (size_t index = 0; index < m_sensorModes.size(); ++index)
927  {
928  Argus::ISensorMode *sensorMode =
929  Argus::interface_cast<Argus::ISensorMode>(m_sensorModes[index]);
930 
931  valueStringPairs[index].value = (uint32_t)index;
932 
933  std::ostringstream stream;
934  stream << index+1 << ": "
935  << sensorMode->getResolution().width() << "x" << sensorMode->getResolution().height();
936 
937  Argus::Ext::IPwlWdrSensorMode* pwlMode =
938  Argus::interface_cast<Argus::Ext::IPwlWdrSensorMode>(m_sensorModes[index]);
939  if (pwlMode)
940  {
941  stream << " @" << sensorMode->getInputBitDepth() << "bpp -> " <<
942  sensorMode->getOutputBitDepth() << "bpp";
943  }
944  else
945  {
946  stream << " @" << sensorMode->getOutputBitDepth() << "bpp";
947  }
948  valueStringPairs[index].string = stream.str();
949  }
950  // update the validator with the new value/string pairs
951  ValidatorEnum<uint32_t> *validator =
952  static_cast<ValidatorEnum<uint32_t>*>(m_sensorModeIndex.getValidator());
953  PROPAGATE_ERROR(validator->setValidValues(valueStringPairs.data(), valueStringPairs.size()));
954 
955  // set the sensor mode index (force notify observer because the sensor modes are different now
956  // although the sensor mode index could be the same)
957  PROPAGATE_ERROR(m_sensorModeIndex.set(0, true /*forceNotify*/));
958 
959  PROPAGATE_ERROR(m_deviceOpen.set(true));
960 
961  return true;
962 }
963 
964 bool Dispatcher::onSensorModeIndexChanged(const Observed &source)
965 {
966  assert(static_cast<const Value<uint32_t>&>(source).get() == m_sensorModeIndex);
967  assert(m_initialized);
968 
969  Argus::ISensorMode *iSensorMode =
970  Argus::interface_cast<Argus::ISensorMode>(m_sensorModes[m_sensorModeIndex.get()]);
971  if (!iSensorMode)
972  ORIGINATE_ERROR("Failed to get ISensorMode interface");
973 
974  // get new limits
975  Argus::Range<uint64_t> sensorExposureTimeRange = iSensorMode->getExposureTimeRange();
976  Argus::Range<float> sensorAnalogGainRange = iSensorMode->getAnalogGainRange();
977  Argus::Range<TimeValue> sensorFrameDurationRange(
978  TimeValue::fromNSec(iSensorMode->getFrameDurationRange().min()),
979  TimeValue::fromNSec(iSensorMode->getFrameDurationRange().max()));
980  Argus::Range<float> sensorFrameRateRange(
981  sensorFrameDurationRange.max().toCyclesPerSec(),
982  sensorFrameDurationRange.min().toCyclesPerSec());
983 
984  // set ranges to unified range (to avoid errors when setting new values)
985  Argus::Range<uint64_t> unifiedSensorExposureTimeRange(0);
986  unifiedSensorExposureTimeRange.min() =
987  std::min(m_sensorExposureTimeRange.get().min().min(), sensorExposureTimeRange.min());
988  unifiedSensorExposureTimeRange.max() =
989  std::max(m_sensorExposureTimeRange.get().max().max(), sensorExposureTimeRange.max());
990  Argus::Range<float> unifiedSensorAnalogGainRange(0);
991  unifiedSensorAnalogGainRange.min() =
992  std::min(m_sensorAnalogGainRange.get().min().min(), sensorAnalogGainRange.min());
993  unifiedSensorAnalogGainRange.max() =
994  std::max(m_sensorAnalogGainRange.get().max().max(), sensorAnalogGainRange.max());
995  Argus::Range<float> unifiedSensorFrameRateRange(0.0f);
996  unifiedSensorFrameRateRange.min() =
997  std::min(m_sensorFrameRateRange.get().min(), sensorFrameRateRange.min());
998  unifiedSensorFrameRateRange.max() =
999  std::max(m_sensorFrameRateRange.get().max(), sensorFrameRateRange.max());
1000 
1001  PROPAGATE_ERROR(m_sensorExposureTimeRange.set(
1002  Argus::Range<Argus::Range<uint64_t> >(unifiedSensorExposureTimeRange)));
1003  PROPAGATE_ERROR(m_sensorAnalogGainRange.set(
1004  Argus::Range<Argus::Range<float> >(unifiedSensorAnalogGainRange)));
1005  PROPAGATE_ERROR(m_sensorFrameRateRange.set(unifiedSensorFrameRateRange));
1006 
1007  // update dependent values
1008  PROPAGATE_ERROR(m_exposureTimeRange.set(sensorExposureTimeRange));
1009  PROPAGATE_ERROR(m_gainRange.set(sensorAnalogGainRange));
1010  PROPAGATE_ERROR(m_frameRate.set(sensorFrameRateRange.max()));
1011 
1012  // set to final ranges
1013  PROPAGATE_ERROR(m_sensorExposureTimeRange.set(Argus::Range<Argus::Range<uint64_t> >(
1014  sensorExposureTimeRange, sensorExposureTimeRange)));
1015  PROPAGATE_ERROR(m_sensorAnalogGainRange.set(Argus::Range<Argus::Range<float> >(
1016  sensorAnalogGainRange, sensorAnalogGainRange)));
1017  PROPAGATE_ERROR(m_sensorFrameRateRange.set(sensorFrameRateRange));
1018 
1019  return true;
1020 }
1021 
1022 bool Dispatcher::supportsExtension(const Argus::ExtensionName& extension) const
1023 {
1024  return m_iCameraProvider->supportsExtension(extension);
1025 }
1026 
1027 bool Dispatcher::getInfo(std::string &info) const
1028 {
1029  std::ostringstream stream;
1030 
1031  assert(m_initialized);
1032 
1033  stream << "Argus extensions:" << std::endl;
1034  stream << " BayerSharpnessMap: " <<
1035  (supportsExtension(Argus::EXT_BAYER_SHARPNESS_MAP) ?
1036  "supported" : "not supported") << std::endl;
1037  stream << " DebugCaptureMetadata: " <<
1038  (supportsExtension(Argus::EXT_DEBUG_CAPTURE_METADATA) ?
1039  "supported" : "not supported") << std::endl;
1040  stream << " DebugCaptureSession: " <<
1041  (supportsExtension(Argus::EXT_DEBUG_CAPTURE_SESSION) ?
1042  "supported" : "not supported") << std::endl;
1043  stream << " DeFog: " <<
1044  (supportsExtension(Argus::EXT_DE_FOG) ?
1045  "supported" : "not supported") << std::endl;
1046  stream << " FaceDetect: " <<
1047  (supportsExtension(Argus::EXT_FACE_DETECT) ?
1048  "supported" : "not supported") << std::endl;
1049  stream << " SensorPrivateMetadata: " <<
1050  (supportsExtension(Argus::EXT_SENSOR_PRIVATE_METADATA) ?
1051  "supported" : "not supported") << std::endl;
1052 
1053  stream << "Number of camera devices: " << m_cameraDevices.size() << std::endl;
1054 
1055  for (uint32_t deviceIndex = 0; deviceIndex < m_cameraDevices.size(); ++deviceIndex)
1056  {
1057  stream << "Device: " << deviceIndex << std::endl;
1058 
1059  const Argus::ICameraProperties *iCameraProperties =
1060  Argus::interface_cast<Argus::ICameraProperties>(m_cameraDevices[deviceIndex]);
1061  if (!iCameraProperties)
1062  ORIGINATE_ERROR("Failed to get ICameraProperties interface");
1063 
1064  stream << " Max AE Regions: " <<
1065  iCameraProperties->getMaxAeRegions() << std::endl;
1066  stream << " Max AWB Regions: " <<
1067  iCameraProperties->getMaxAwbRegions() << std::endl;
1068  stream << " Focus Position Range: " <<
1069  iCameraProperties->getFocusPositionRange().min() << " - " <<
1070  iCameraProperties->getFocusPositionRange().max() << std::endl;
1071  stream << " Lens Aperture Range: " <<
1072  iCameraProperties->getLensApertureRange().min() << " - " <<
1073  iCameraProperties->getLensApertureRange().max() << std::endl;
1074  stream << " Isp Digital Gain Range: " <<
1075  iCameraProperties->getIspDigitalGainRange().min() << " - " <<
1076  iCameraProperties->getIspDigitalGainRange().max() << std::endl;
1077 
1078  // print the sensor modes
1079  std::vector<Argus::SensorMode*> sensorModes;
1080  iCameraProperties->getAllSensorModes(&sensorModes);
1081  stream << " Number of sensor modes: " << sensorModes.size() << std::endl;
1082  for (uint32_t sensorModeIndex = 0; sensorModeIndex < sensorModes.size(); ++sensorModeIndex)
1083  {
1084  Argus::ISensorMode *sensorMode =
1085  Argus::interface_cast<Argus::ISensorMode>(sensorModes[sensorModeIndex]);
1086  if (!sensorMode)
1087  ORIGINATE_ERROR("Failed to get ISensorMode interface");
1088 
1089  // convert ns to fps
1090  float maximum_fps = TimeValue::fromNSec(
1091  sensorMode->getFrameDurationRange().min()).toCyclesPerSec();
1092  float minimum_fps = TimeValue::fromNSec(
1093  sensorMode->getFrameDurationRange().max()).toCyclesPerSec();
1094 
1095  stream << " Sensor mode: " << sensorModeIndex << std::endl;
1096  stream << " Resolution: " <<
1097  sensorMode->getResolution().width() << "x" <<
1098  sensorMode->getResolution().height() << std::endl;
1099  stream << " Exposure time range: " <<
1100  sensorMode->getExposureTimeRange().min() << " - " <<
1101  sensorMode->getExposureTimeRange().max() << " ns" << std::endl;
1102  stream << " Frame duration range: " <<
1103  sensorMode->getFrameDurationRange().min() << " - " <<
1104  sensorMode->getFrameDurationRange().max() << " ns" << std::endl;
1105  stream << " Framerate range: " <<
1106  minimum_fps << " - " <<
1107  maximum_fps << " fps" << std::endl;
1108  stream << " InputBitDepth: " <<
1109  sensorMode->getInputBitDepth() << std::endl;
1110  stream << " OutputBitDepth: " <<
1111  sensorMode->getOutputBitDepth() << std::endl;
1112  stream << " Analog gain range: " <<
1113  sensorMode->getAnalogGainRange().min() << " - " <<
1114  sensorMode->getAnalogGainRange().max() << std::endl;
1115 
1116  stream << " SensorModeType: " <<
1117  sensorMode->getSensorModeType().getName() << std::endl;
1118 
1119  Argus::Ext::IPwlWdrSensorMode* pwlMode =
1120  Argus::interface_cast<Argus::Ext::IPwlWdrSensorMode>(sensorModes[sensorModeIndex]);
1121  if (pwlMode)
1122  {
1123  stream << " Piecewise Linear WDR Extension supported with: " <<
1124  pwlMode->getControlPointCount() << " control points." << std::endl;
1125  std::vector< Argus::Point2D<float> > points;
1126  Argus::Status status = pwlMode->getControlPoints(&points);
1127  if (status != Argus::STATUS_OK)
1128  ORIGINATE_ERROR("Error obtaining control points");
1129  stream << " Control Points: " << std::endl;
1130  for (uint32_t j = 0; j < pwlMode->getControlPointCount(); j++)
1131  {
1132  stream << " (" << points[j].x() << ", " <<
1133  points[j].y() << ")" << std::endl;
1134  }
1135  }
1136 
1137  stream << std::endl;
1138  }
1139  }
1140 
1141  info = stream.str();
1142 
1143  return true;
1144 }
1145 
1146 bool Dispatcher::getSensorMode(uint32_t sensorModeIndex, Argus::SensorMode **sensorMode) const
1147 {
1148  assert(m_deviceOpen);
1149 
1150  if (sensorModeIndex >= m_sensorModes.size())
1151  ORIGINATE_ERROR("Invalid sensor mode index");
1152 
1153  *sensorMode = m_sensorModes[sensorModeIndex];
1154 
1155  return true;
1156 }
1157 
1158 Argus::Range<int32_t> Dispatcher::getDeviceFocusPositionRange() const
1159 {
1160  return m_deviceFocusPositionRange.get();
1161 }
1162 
1164 {
1165  assert(m_deviceOpen);
1166 
1167  return m_cameraDevices.size();
1168 }
1169 
1171  uint32_t deviceIndex)
1172 {
1173  assert(m_deviceOpen);
1174 
1175  if (deviceIndex > m_cameraDevices.size())
1176  ORIGINATE_ERROR("Invalid device index");
1177 
1178  // close the internal session, it might be using the device which will be used by the new
1179  // session
1180  PROPAGATE_ERROR(closeSession());
1181 
1182  // create the new capture session
1183  Argus::UniqueObj<Argus::CaptureSession> newSession(
1184  m_iCameraProvider->createCaptureSession(m_cameraDevices[deviceIndex]));
1185  if (!newSession)
1186  ORIGINATE_ERROR("Failed to create CaptureSession");
1187 
1188  PROPAGATE_ERROR(session.reset(newSession.release(), this));
1189 
1190  return true;
1191 }
1192 
1194 {
1195  for (ActiveSessionList::const_iterator it = m_activeSessions.begin(); it != m_activeSessions.end();
1196  ++it)
1197  {
1198  Argus::Ext::IDebugCaptureSession *iDebugCaptureSession =
1199  Argus::interface_cast<Argus::Ext::IDebugCaptureSession>(it->m_session);
1200  if (!iDebugCaptureSession)
1201  ORIGINATE_ERROR("DebugCaptureSession extension not supported");
1202 
1203  const Argus::Status status = iDebugCaptureSession->dump(STDOUT_FILENO);
1204  if (status != Argus::STATUS_OK)
1205  ORIGINATE_ERROR("Failed to get dump runtime info");
1206  }
1207 
1208  return true;
1209 }
1210 
1211 /**
1212  * Create the internal session
1213  */
1215 {
1216  if (m_captureSession)
1217  return true;
1218 
1219  PROPAGATE_ERROR(createSession(m_captureSession, m_deviceIndex));
1220 
1221  return true;
1222 }
1223 
1224 /**
1225  * Close the internal session
1226  */
1228 {
1230  return true;
1231 }
1232 
1233 bool Dispatcher::track(Argus::CaptureSession *session)
1234 {
1235  m_activeSessions.push_back(ActiveSession(session));
1236  return true;
1237 }
1238 
1239 bool Dispatcher::untrack(Argus::CaptureSession *session)
1240 {
1241  for (ActiveSessionList::iterator it = m_activeSessions.begin(); it != m_activeSessions.end();
1242  ++it)
1243  {
1244  if (it->m_session == session)
1245  {
1246  m_activeSessions.erase(it);
1247  return true;
1248  }
1249  }
1250 
1251  ORIGINATE_ERROR("Session not found");
1252 }
1253 
1254 bool Dispatcher::waitForEvents(Argus::EventQueue *eventQueue, TimeValue timeout,
1255  Argus::CaptureSession *session)
1256 {
1257  if (!session)
1258  {
1259  // use the internal session
1260  PROPAGATE_ERROR(createSession());
1261  session = m_captureSession.get();
1262  }
1263 
1264  Argus::IEventProvider *iEventProvider = Argus::interface_cast<Argus::IEventProvider>(session);
1265  if (!iEventProvider)
1266  ORIGINATE_ERROR("Failed to get iEventProvider interface");
1267 
1268  // wait for the events
1269  const Argus::Status status = iEventProvider->waitForEvents(eventQueue, timeout.toNSec());
1270  if ((status != Argus::STATUS_OK) && (status != Argus::STATUS_TIMEOUT))
1271  ORIGINATE_ERROR("Failed to get events");
1272 
1273  return true;
1274 }
1275 
1277  Argus::CaptureIntent captureIntent, Argus::CaptureSession *session)
1278 {
1279  if (!session)
1280  {
1281  // use the internal session
1282  PROPAGATE_ERROR(createSession());
1283  session = m_captureSession.get();
1284  }
1285 
1286  Argus::ICaptureSession *iCaptureSession =
1287  Argus::interface_cast<Argus::ICaptureSession>(session);
1288  if (!iCaptureSession)
1289  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1290 
1291  // Create request
1292  Argus::UniqueObj<Argus::Request> newRequest =
1293  Argus::UniqueObj<Argus::Request>(iCaptureSession->createRequest(captureIntent));
1294  if (!newRequest)
1295  ORIGINATE_ERROR("Failed to create request");
1296 
1297  // Setup request
1298  Argus::IRequest *iRequest = Argus::interface_cast<Argus::IRequest>(newRequest);
1299  if (!iRequest)
1300  ORIGINATE_ERROR("Failed to get IRequest interface");
1301 
1302  // get source settings interface
1303  Argus::ISourceSettings *iSourceSettings =
1304  Argus::interface_cast<Argus::ISourceSettings>(iRequest->getSourceSettings());
1305  if (!iSourceSettings)
1306  ORIGINATE_ERROR("Failed to get ISourceSettings interface");
1307 
1308  // register the source settings observer
1309  PROPAGATE_ERROR(registerObserver(iSourceSettings));
1310 
1311  // get auto control settings interface
1312  Argus::IAutoControlSettings *iAutoControlSettings =
1313  Argus::interface_cast<Argus::IAutoControlSettings>(iRequest->getAutoControlSettings());
1314  if (!iAutoControlSettings)
1315  ORIGINATE_ERROR("Failed to get IAutoControlSettings interface");
1316 
1317  // register the auto control settings observer
1318  PROPAGATE_ERROR(registerObserver(iAutoControlSettings));
1319 
1320  // register denoise settings interface
1321  Argus::IDenoiseSettings *iDenoiseSettings =
1322  Argus::interface_cast<Argus::IDenoiseSettings>(newRequest);
1323  if (!iDenoiseSettings)
1324  ORIGINATE_ERROR("Failed to get IDenoiseSettings interface");
1325  PROPAGATE_ERROR(registerObserver(iDenoiseSettings));
1326 
1327  // register edge enhance settings interface
1328  Argus::IEdgeEnhanceSettings *iEdgeEnhanceSettings =
1329  Argus::interface_cast<Argus::IEdgeEnhanceSettings>(newRequest);
1330  if (!iEdgeEnhanceSettings)
1331  ORIGINATE_ERROR("Failed to get IEdgeEnhanceSettings interface");
1332  PROPAGATE_ERROR(registerObserver(iEdgeEnhanceSettings));
1333 
1334  // register video stabilization settings interface
1335  Argus::IVideoStabilizationSettings *iVideoStabilizationSettings =
1336  Argus::interface_cast<Argus::IVideoStabilizationSettings>(newRequest);
1337  if (!iVideoStabilizationSettings)
1338  ORIGINATE_ERROR("Failed to get IVideoStabilizationSettings interface");
1339  PROPAGATE_ERROR(registerObserver(iVideoStabilizationSettings));
1340 
1341  if (supportsExtension(Argus::EXT_DE_FOG))
1342  {
1343  // get DeFog settings interface
1344  Argus::Ext::IDeFogSettings *iDeFogSettings =
1345  Argus::interface_cast<Argus::Ext::IDeFogSettings>(newRequest);
1346  if (iDeFogSettings)
1347  {
1348  // register the DeFog settings observer
1349  PROPAGATE_ERROR(registerObserver(iDeFogSettings));
1350  }
1351  }
1352 
1353  PROPAGATE_ERROR(request.reset(newRequest.release(), this));
1354 
1355  return true;
1356 }
1357 
1358 bool Dispatcher::track(Argus::Request *request)
1359 {
1360  return true;
1361 }
1362 
1363 bool Dispatcher::untrack(Argus::Request *request)
1364 {
1365  Argus::IRequest *iRequest = Argus::interface_cast<Argus::IRequest>(request);
1366  if (!iRequest)
1367  ORIGINATE_ERROR("Failed to get IRequest interface");
1368 
1369  // get source settings interface
1370  Argus::ISourceSettings *iSourceSettings =
1371  Argus::interface_cast<Argus::ISourceSettings>(iRequest->getSourceSettings());
1372  if (!iSourceSettings)
1373  ORIGINATE_ERROR("Failed to get ISourceSettings interface");
1374 
1375  // unregister the source settings observer
1376  PROPAGATE_ERROR(unregisterObserver(iSourceSettings));
1377 
1378  // get auto control settings interface
1379  Argus::IAutoControlSettings *iAutoControlSettings =
1380  Argus::interface_cast<Argus::IAutoControlSettings>(iRequest->getAutoControlSettings());
1381  if (!iAutoControlSettings)
1382  ORIGINATE_ERROR("Failed to get IAutoControlSettings interface");
1383 
1384  // unregister the auto control settings observer
1385  PROPAGATE_ERROR(unregisterObserver(iAutoControlSettings));
1386 
1387  // unregister denoise settings interface
1388  Argus::IDenoiseSettings *iDenoiseSettings =
1389  Argus::interface_cast<Argus::IDenoiseSettings>(request);
1390  if (!iDenoiseSettings)
1391  ORIGINATE_ERROR("Failed to get IDenoiseSettings interface");
1392  PROPAGATE_ERROR(unregisterObserver(iDenoiseSettings));
1393 
1394  // unregister edge enhance settings interface
1395  Argus::IEdgeEnhanceSettings *iEdgeEnhanceSettings =
1396  Argus::interface_cast<Argus::IEdgeEnhanceSettings>(request);
1397  if (!iEdgeEnhanceSettings)
1398  ORIGINATE_ERROR("Failed to get IEdgeEnhanceSettings interface");
1399  PROPAGATE_ERROR(unregisterObserver(iEdgeEnhanceSettings));
1400 
1401  // unregister video stabilization settings interface
1402  Argus::IVideoStabilizationSettings *iVideoStabilizationSettings =
1403  Argus::interface_cast<Argus::IVideoStabilizationSettings>(request);
1404  if (!iVideoStabilizationSettings)
1405  ORIGINATE_ERROR("Failed to get IVideoStabilizationSettings interface");
1406  PROPAGATE_ERROR(unregisterObserver(iVideoStabilizationSettings));
1407 
1408  if (supportsExtension(Argus::EXT_DE_FOG))
1409  {
1410  // get DeFog settings interface
1411  Argus::Ext::IDeFogSettings *iDeFogSettings =
1412  Argus::interface_cast<Argus::Ext::IDeFogSettings>(request);
1413  if (iDeFogSettings)
1414  {
1415  // unregister the DeFog settings observer
1416  PROPAGATE_ERROR(unregisterObserver(iDeFogSettings));
1417  }
1418  }
1419 
1420  return true;
1421 }
1422 
1423 bool Dispatcher::createEventQueue(const std::vector<Argus::EventType> &eventTypes,
1424  Argus::UniqueObj<Argus::EventQueue>& eventQueue, Argus::CaptureSession *session)
1425 {
1426  if (!session)
1427  {
1428  // use the internal session
1429  PROPAGATE_ERROR(createSession());
1430  session = m_captureSession.get();
1431  }
1432 
1433  Argus::IEventProvider *iEventProvider =
1434  Argus::interface_cast<Argus::IEventProvider>(session);
1435  if (!iEventProvider)
1436  ORIGINATE_ERROR("Failed to get IEventProvider interface");
1437 
1438  Argus::EventQueue *newEventQueue = iEventProvider->createEventQueue(eventTypes);
1439  if (!newEventQueue)
1440  ORIGINATE_ERROR("Failed to create eventQueue");
1441 
1442  eventQueue.reset(newEventQueue);
1443 
1444  return true;
1445 }
1446 
1447 bool Dispatcher::capture(Argus::Request *request, Argus::CaptureSession *session)
1448 {
1449  if (!session)
1450  {
1451  // use the internal session
1452  PROPAGATE_ERROR(createSession());
1453  session = m_captureSession.get();
1454  }
1455 
1456  Argus::ICaptureSession *iCaptureSession =
1457  Argus::interface_cast<Argus::ICaptureSession>(session);
1458  if (!iCaptureSession)
1459  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1460 
1461  if (iCaptureSession->capture(request, Argus::TIMEOUT_INFINITE) == 0)
1462  ORIGINATE_ERROR("Failed to submit the still capture request");
1463 
1464  return true;
1465 }
1466 
1467 bool Dispatcher::startRepeat(Argus::Request *request, Argus::CaptureSession *session)
1468 {
1469  if (!session)
1470  {
1471  // use the internal session
1472  PROPAGATE_ERROR(createSession());
1473  session = m_captureSession.get();
1474  }
1475 
1476  Argus::ICaptureSession *iCaptureSession =
1477  Argus::interface_cast<Argus::ICaptureSession>(session);
1478  if (!iCaptureSession)
1479  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1480 
1481  if (iCaptureSession->repeat(request) != Argus::STATUS_OK)
1482  ORIGINATE_ERROR("Failed to submit repeating capture request");
1483 
1484  // add the request to the list of active requests for the session
1485  bool found = false;
1486  for (ActiveSessionList::iterator it = m_activeSessions.begin(); it != m_activeSessions.end();
1487  ++it)
1488  {
1489  if (it->m_session == session)
1490  {
1491  it->m_requests.push_back(request);
1492  found = true;
1493  break;
1494  }
1495  }
1496  if (!found)
1497  ORIGINATE_ERROR("Did not find the session in the list of active sessions");
1498 
1499  return true;
1500 }
1501 
1502 bool Dispatcher::startRepeatBurst(const std::vector<const Argus::Request*>& requestList,
1503  Argus::CaptureSession *session)
1504 {
1505  if (!session)
1506  {
1507  // use the internal session
1508  PROPAGATE_ERROR(createSession());
1509  session = m_captureSession.get();
1510  }
1511 
1512  Argus::ICaptureSession *iCaptureSession =
1513  Argus::interface_cast<Argus::ICaptureSession>(session);
1514  if (!iCaptureSession)
1515  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1516 
1517  if (iCaptureSession->repeatBurst(requestList) != Argus::STATUS_OK)
1518  ORIGINATE_ERROR("Failed to submit repeating burst request");
1519 
1520  // add the requests to the list of active requests for the session
1521  bool found = false;
1522  for (ActiveSessionList::iterator it = m_activeSessions.begin(); it != m_activeSessions.end();
1523  ++it)
1524  {
1525  if (it->m_session == session)
1526  {
1527  it->m_requests.insert(it->m_requests.end(), requestList.begin(), requestList.end());
1528  found = true;
1529  break;
1530  }
1531  }
1532  if (!found)
1533  ORIGINATE_ERROR("Did not find the session in the list of active sessions");
1534 
1535  return true;
1536 }
1537 
1538 bool Dispatcher::stopRepeat(Argus::CaptureSession *session)
1539 {
1540  if (!session)
1541  {
1542  // use the internal session
1543  PROPAGATE_ERROR(createSession());
1544  session = m_captureSession.get();
1545  }
1546 
1547  Argus::ICaptureSession *iCaptureSession =
1548  Argus::interface_cast<Argus::ICaptureSession>(session);
1549  if (!iCaptureSession)
1550  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1551 
1552  iCaptureSession->stopRepeat();
1553 
1554  // clear the list of active requests for the session
1555  bool found = false;
1556  for (ActiveSessionList::iterator it = m_activeSessions.begin(); it != m_activeSessions.end();
1557  ++it)
1558  {
1559  if (it->m_session == session)
1560  {
1561  it->m_requests.clear();
1562  found = true;
1563  break;
1564  }
1565  }
1566  if (!found)
1567  ORIGINATE_ERROR("Did not find the session in the list of active sessions");
1568 
1569  return true;
1570 }
1571 
1573 {
1574  for (ActiveSessionList::iterator it = m_activeSessions.begin(); it != m_activeSessions.end();
1575  ++it)
1576  {
1577  if (!it->m_requests.empty())
1578  {
1579  Argus::ICaptureSession *iCaptureSession =
1580  Argus::interface_cast<Argus::ICaptureSession>(it->m_session);
1581  if (!iCaptureSession)
1582  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1583 
1584  iCaptureSession->stopRepeat();
1585 
1586  if (iCaptureSession->repeatBurst(it->m_requests) != Argus::STATUS_OK)
1587  ORIGINATE_ERROR("Failed to submit repeating burst request");
1588  }
1589  }
1590 
1591  return true;
1592 }
1593 
1594 uint32_t Dispatcher::maxBurstRequests(Argus::CaptureSession *session)
1595 {
1596  if (!session)
1597  {
1598  // use the internal session
1599  PROPAGATE_ERROR(createSession());
1600  session = m_captureSession.get();
1601  }
1602 
1603  Argus::ICaptureSession *iCaptureSession =
1604  Argus::interface_cast<Argus::ICaptureSession>(session);
1605  if (!iCaptureSession)
1606  {
1607  REPORT_ERROR("Failed to get ICaptureSession interface");
1608  return 0;
1609  }
1610 
1611  return iCaptureSession->maxBurstRequests();
1612 }
1613 
1614 bool Dispatcher::waitForIdle(Argus::CaptureSession *session)
1615 {
1616  if (!session)
1617  {
1618  // use the internal session
1619  PROPAGATE_ERROR(createSession());
1620  session = m_captureSession.get();
1621  }
1622 
1623  Argus::ICaptureSession *iCaptureSession =
1624  Argus::interface_cast<Argus::ICaptureSession>(session);
1625  if (!iCaptureSession)
1626  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1627 
1628  if (iCaptureSession->waitForIdle() != Argus::STATUS_OK)
1629  ORIGINATE_ERROR("Waiting for idle failed");
1630 
1631  return true;
1632 }
1633 
1634 bool Dispatcher::getOutputSize(Argus::Size2D<uint32_t> *size) const
1635 {
1636  // if width or height is 0 take the sensor size
1637  if ((m_outputSize.get().width() == 0) || (m_outputSize.get().height() == 0))
1638  {
1639  // the device needs to be open to get sensor modes
1640  assert(m_deviceOpen);
1641 
1642  Argus::ISensorMode *sensorMode =
1643  Argus::interface_cast<Argus::ISensorMode>(m_sensorModes[m_sensorModeIndex.get()]);
1644  if (!sensorMode)
1645  ORIGINATE_ERROR("Failed to get ISensorMode interface");
1646  *size = sensorMode->getResolution();
1647  }
1648  else
1649  {
1650  *size = m_outputSize;
1651  }
1652 
1653  return true;
1654 }
1655 
1656 bool Dispatcher::createOutputStream(Argus::Request *request,
1657  Argus::UniqueObj<Argus::OutputStream> &stream, Argus::CaptureSession *session)
1658 {
1659  if (!session)
1660  {
1661  // use the internal session
1662  PROPAGATE_ERROR(createSession());
1663  session = m_captureSession.get();
1664  }
1665 
1666  Argus::IRequest *iRequest = Argus::interface_cast<Argus::IRequest>(request);
1667  if (!iRequest)
1668  ORIGINATE_ERROR("Failed to get IRequest interface");
1669 
1670  Argus::Size2D<uint32_t> outputSize;
1671  PROPAGATE_ERROR(getOutputSize(&outputSize));
1672 
1673  Argus::ICaptureSession *iCaptureSession =
1674  Argus::interface_cast<Argus::ICaptureSession>(session);
1675  if (!iCaptureSession)
1676  ORIGINATE_ERROR("Failed to get ICaptureSession interface");
1677 
1678  Argus::UniqueObj<Argus::OutputStreamSettings> outputStreamSettings(
1679  iCaptureSession->createOutputStreamSettings());
1680  Argus::IOutputStreamSettings* iOutputStreamSettings =
1681  Argus::interface_cast<Argus::IOutputStreamSettings>(outputStreamSettings);
1682  if (!iOutputStreamSettings)
1683  ORIGINATE_ERROR("Failed to get IOutputStreamSettings interface");
1684 
1685  iOutputStreamSettings->setPixelFormat(Argus::PIXEL_FMT_YCbCr_420_888);
1686  iOutputStreamSettings->setResolution(outputSize);
1687  iOutputStreamSettings->setEGLDisplay(Renderer::getInstance().getEGLDisplay());
1688 
1689  Argus::UniqueObj<Argus::OutputStream> outputStream(
1690  iCaptureSession->createOutputStream(outputStreamSettings.get()));
1691  if (!outputStream)
1692  ORIGINATE_ERROR("Failed to create OutputStream");
1693 
1694  stream.reset(outputStream.release());
1695 
1696  return true;
1697 }
1698 
1699 bool Dispatcher::enableOutputStream(Argus::Request *request, Argus::OutputStream *stream)
1700 {
1701  Argus::IRequest *iRequest = Argus::interface_cast<Argus::IRequest>(request);
1702  if (!iRequest)
1703  ORIGINATE_ERROR("Failed to get IRequest interface");
1704 
1705  // Enable the stream
1706  if (iRequest->enableOutputStream(stream) != Argus::STATUS_OK)
1707  ORIGINATE_ERROR("Failed to enable the output stream");
1708 
1709  return true;
1710 }
1711 
1712 bool Dispatcher::disableOutputStream(Argus::Request *request, Argus::OutputStream *stream)
1713 {
1714  Argus::IRequest *iRequest = Argus::interface_cast<Argus::IRequest>(request);
1715  if (!iRequest)
1716  ORIGINATE_ERROR("Failed to get IRequest interface");
1717 
1718  // Disable the stream
1719  if (iRequest->disableOutputStream(stream) != Argus::STATUS_OK)
1720  ORIGINATE_ERROR("Failed to disable the output stream");
1721 
1722  return true;
1723 }
1724 
1725 bool Dispatcher::registerObserver(Argus::IDenoiseSettings *iDenoiseSettings)
1726 {
1727  UniquePointer<DenoiseSettingsObserver> denoiseSettings;
1728 
1729  denoiseSettings.reset(new DenoiseSettingsObserver(iDenoiseSettings));
1730  if (!denoiseSettings)
1731  ORIGINATE_ERROR("Out of memory");
1732 
1733  m_observers.push_front(denoiseSettings.release());
1734  return true;
1735 }
1736 
1737 bool Dispatcher::registerObserver(Argus::IEdgeEnhanceSettings *iEdgeEnhanceSettings)
1738 {
1739  UniquePointer<EdgeEnhanceSettingsObserver> edgeEnhanceSettings;
1740 
1741  edgeEnhanceSettings.reset(new EdgeEnhanceSettingsObserver(iEdgeEnhanceSettings));
1742  if (!edgeEnhanceSettings)
1743  ORIGINATE_ERROR("Out of memory");
1744 
1745  m_observers.push_front(edgeEnhanceSettings.release());
1746  return true;
1747 }
1748 
1749 bool Dispatcher::registerObserver(Argus::IVideoStabilizationSettings *iVideoStabilizationSettings)
1750 {
1751  UniquePointer<VideoStabilizationSettingsObserver> vStabSettings;
1752 
1753  vStabSettings.reset(new VideoStabilizationSettingsObserver(iVideoStabilizationSettings));
1754  if (!vStabSettings)
1755  ORIGINATE_ERROR("Out of memory");
1756 
1757  m_observers.push_front(vStabSettings.release());
1758  return true;
1759 }
1760 
1761 bool Dispatcher::registerObserver(Argus::ISourceSettings *iSourceSettings)
1762 {
1763  UniquePointer<SourceSettingsObserver> sourceSettings;
1764 
1765  sourceSettings.reset(new SourceSettingsObserver(iSourceSettings));
1766  if (!sourceSettings)
1767  ORIGINATE_ERROR("Out of memory");
1768 
1769  m_observers.push_front(sourceSettings.release());
1770  return true;
1771 }
1772 
1773 bool Dispatcher::registerObserver(Argus::IAutoControlSettings *iAutoControlSettings)
1774 {
1775  UniquePointer<AutoControlSettingsObserver> autoControlSettings;
1776 
1777  autoControlSettings.reset(new AutoControlSettingsObserver(iAutoControlSettings));
1778  if (!autoControlSettings)
1779  ORIGINATE_ERROR("Out of memory");
1780 
1781  m_observers.push_front(autoControlSettings.release());
1782  return true;
1783 }
1784 
1785 bool Dispatcher::registerObserver(Argus::Ext::IDeFogSettings *iDeFogSettings)
1786 {
1787  UniquePointer<DeFogSettingsObserver> deFogSettings;
1788 
1789  deFogSettings.reset(new DeFogSettingsObserver(iDeFogSettings));
1790  if (!deFogSettings)
1791  ORIGINATE_ERROR("Out of memory");
1792 
1793  m_observers.push_front(deFogSettings.release());
1794  return true;
1795 }
1796 
1797 bool Dispatcher::unregisterObserver(Argus::Interface *interface)
1798 {
1799  for (std::list<IObserverForInterface*>::iterator it = m_observers.begin();
1800  it != m_observers.end(); ++it)
1801  {
1802  if ((*it)->isInterface(interface))
1803  {
1804  delete *it;
1805  m_observers.erase(it);
1806  return true;
1807  }
1808  }
1809 
1810  ORIGINATE_ERROR("Observer not found");
1811 }
1812 
1813 bool Dispatcher::message(const char *msg, ...)
1814 {
1815  if (m_verbose)
1816  {
1817  va_list list;
1818 
1819  va_start(list, msg);
1820 
1821  if (vprintf(msg, list) < 0)
1822  {
1823  va_end(list);
1824  ORIGINATE_ERROR("Failed to print message");
1825  }
1826 
1827  va_end(list);
1828  }
1829 
1830  return true;
1831 }
1832 
1833 }; // namespace ArgusSamples