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