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