Argus Camera Sample Argus Camera Sample

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

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-2023, 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 */
77 class DenoiseSettingsObserver : public IObserverForInterface
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>(
87 &DenoiseSettingsObserver::onDenoiseModeChanged)));
88 PROPAGATE_ERROR_CONTINUE(dispatcher.m_denoiseStrength.registerObserver(this,
89 static_cast<IObserver::CallbackFunction>(
90 &DenoiseSettingsObserver::onDenoiseStrengthChanged)));
91 }
92
93 virtual ~DenoiseSettingsObserver()
94 {
95 Dispatcher &dispatcher = Dispatcher::getInstance();
96
97 PROPAGATE_ERROR_CONTINUE(dispatcher.m_denoiseStrength.unregisterObserver(this,
98 static_cast<IObserver::CallbackFunction>(
99 &DenoiseSettingsObserver::onDenoiseStrengthChanged)));
100 PROPAGATE_ERROR_CONTINUE(dispatcher.m_denoiseMode.unregisterObserver(this,
101 static_cast<IObserver::CallbackFunction>(
102 &DenoiseSettingsObserver::onDenoiseModeChanged)));
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 */
148 class EdgeEnhanceSettingsObserver : public IObserverForInterface
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>(
158 &EdgeEnhanceSettingsObserver::onEdgeEnhanceModeChanged)));
159 PROPAGATE_ERROR_CONTINUE(dispatcher.m_edgeEnhanceStrength.registerObserver(this,
160 static_cast<IObserver::CallbackFunction>(
161 &EdgeEnhanceSettingsObserver::onEdgeEnhanceStrengthChanged)));
162 }
163
164 virtual ~EdgeEnhanceSettingsObserver()
165 {
166 Dispatcher &dispatcher = Dispatcher::getInstance();
167
168 PROPAGATE_ERROR_CONTINUE(dispatcher.m_edgeEnhanceStrength.unregisterObserver(this,
169 static_cast<IObserver::CallbackFunction>(
170 &EdgeEnhanceSettingsObserver::onEdgeEnhanceStrengthChanged)));
171 PROPAGATE_ERROR_CONTINUE(dispatcher.m_edgeEnhanceMode.unregisterObserver(this,
172 static_cast<IObserver::CallbackFunction>(
173 &EdgeEnhanceSettingsObserver::onEdgeEnhanceModeChanged)));
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 */
223 class SourceSettingsObserver : public IObserverForInterface
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>(
233 &SourceSettingsObserver::onExposureTimeRangeChanged)));
234 PROPAGATE_ERROR_CONTINUE(dispatcher.m_gainRange.registerObserver(this,
235 static_cast<IObserver::CallbackFunction>(
236 &SourceSettingsObserver::onGainRangeChanged)));
237 PROPAGATE_ERROR_CONTINUE(dispatcher.m_sensorModeIndex.registerObserver(this,
238 static_cast<IObserver::CallbackFunction>(
239 &SourceSettingsObserver::onSensorModeChanged)));
240 PROPAGATE_ERROR_CONTINUE(dispatcher.m_frameRate.registerObserver(this,
241 static_cast<IObserver::CallbackFunction>(
242 &SourceSettingsObserver::onFrameRateChanged)));
243 PROPAGATE_ERROR_CONTINUE(dispatcher.m_frameRateRange.registerObserver(this,
244 static_cast<IObserver::CallbackFunction>(
245 &SourceSettingsObserver::onFrameRateRangeChanged)));
246 PROPAGATE_ERROR_CONTINUE(dispatcher.m_focusPosition.registerObserver(this,
247 static_cast<IObserver::CallbackFunction>(
248 &SourceSettingsObserver::onFocusPositionChanged)));
249 PROPAGATE_ERROR_CONTINUE(dispatcher.m_aperturePosition.registerObserver(this,
250 static_cast<IObserver::CallbackFunction>(
251 &SourceSettingsObserver::onAperturePositionChanged)));
252 PROPAGATE_ERROR_CONTINUE(dispatcher.m_apertureFnum.registerObserver(this,
253 static_cast<IObserver::CallbackFunction>(
254 &SourceSettingsObserver::onApertureFnumChanged)));
255 PROPAGATE_ERROR_CONTINUE(dispatcher.m_apertureMotorSpeed.registerObserver(this,
256 static_cast<IObserver::CallbackFunction>(
257 &SourceSettingsObserver::onApertureMotorSpeedChanged)));
258 PROPAGATE_ERROR_CONTINUE(dispatcher.m_captureYuvFormat.registerObserver(this,
259 static_cast<IObserver::CallbackFunction>(
260 &SourceSettingsObserver::onCaptureYuvFormatChanged)));
261 }
262
263 virtual ~SourceSettingsObserver()
264 {
265 Dispatcher &dispatcher = Dispatcher::getInstance();
266
267 PROPAGATE_ERROR_CONTINUE(dispatcher.m_apertureMotorSpeed.unregisterObserver(this,
268 static_cast<IObserver::CallbackFunction>(
269 &SourceSettingsObserver::onApertureMotorSpeedChanged)));
270 PROPAGATE_ERROR_CONTINUE(dispatcher.m_aperturePosition.unregisterObserver(this,
271 static_cast<IObserver::CallbackFunction>(
272 &SourceSettingsObserver::onAperturePositionChanged)));
273 PROPAGATE_ERROR_CONTINUE(dispatcher.m_apertureFnum.unregisterObserver(this,
274 static_cast<IObserver::CallbackFunction>(
275 &SourceSettingsObserver::onApertureFnumChanged)));
276 PROPAGATE_ERROR_CONTINUE(dispatcher.m_focusPosition.unregisterObserver(this,
277 static_cast<IObserver::CallbackFunction>(
278 &SourceSettingsObserver::onFocusPositionChanged)));
279 PROPAGATE_ERROR_CONTINUE(dispatcher.m_frameRate.unregisterObserver(this,
280 static_cast<IObserver::CallbackFunction>(
281 &SourceSettingsObserver::onFrameRateChanged)));
282 PROPAGATE_ERROR_CONTINUE(dispatcher.m_frameRateRange.unregisterObserver(this,
283 static_cast<IObserver::CallbackFunction>(
284 &SourceSettingsObserver::onFrameRateRangeChanged)));
285 PROPAGATE_ERROR_CONTINUE(dispatcher.m_sensorModeIndex.unregisterObserver(this,
286 static_cast<IObserver::CallbackFunction>(
287 &SourceSettingsObserver::onSensorModeChanged)));
288 PROPAGATE_ERROR_CONTINUE(dispatcher.m_gainRange.unregisterObserver(this,
289 static_cast<IObserver::CallbackFunction>(
290 &SourceSettingsObserver::onGainRangeChanged)));
291 PROPAGATE_ERROR_CONTINUE(dispatcher.m_exposureTimeRange.unregisterObserver(this,
292 static_cast<IObserver::CallbackFunction>(
293 &SourceSettingsObserver::onExposureTimeRangeChanged)));
294 PROPAGATE_ERROR_CONTINUE(dispatcher.m_captureYuvFormat.unregisterObserver(this,
295 static_cast<IObserver::CallbackFunction>(
296 &SourceSettingsObserver::onCaptureYuvFormatChanged)));
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 */
522 class AutoControlSettingsObserver : public IObserverForInterface
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>(
532 &AutoControlSettingsObserver::onAeAntibandingModeChanged)));
533 PROPAGATE_ERROR_CONTINUE(dispatcher.m_aeLock.registerObserver(this,
534 static_cast<IObserver::CallbackFunction>(
535 &AutoControlSettingsObserver::onAeLockChanged)));
536 PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbLock.registerObserver(this,
537 static_cast<IObserver::CallbackFunction>(
538 &AutoControlSettingsObserver::onAwbLockChanged)));
539 PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbMode.registerObserver(this,
540 static_cast<IObserver::CallbackFunction>(
541 &AutoControlSettingsObserver::onAwbModeChanged)));
542 PROPAGATE_ERROR_CONTINUE(dispatcher.m_exposureCompensation.registerObserver(this,
543 static_cast<IObserver::CallbackFunction>(
544 &AutoControlSettingsObserver::onExposureCompensationChanged)));
545 PROPAGATE_ERROR_CONTINUE(dispatcher.m_ispDigitalGainRange.registerObserver(this,
546 static_cast<IObserver::CallbackFunction>(
547 &AutoControlSettingsObserver::onIspDigitalGainRangeChanged)));
548 PROPAGATE_ERROR_CONTINUE(dispatcher.m_acRegionHorizontal.registerObserver(this,
549 static_cast<IObserver::CallbackFunction>(
550 &AutoControlSettingsObserver::onAcRegionChanged)));
551 PROPAGATE_ERROR_CONTINUE(dispatcher.m_acRegionVertical.registerObserver(this,
552 static_cast<IObserver::CallbackFunction>(
553 &AutoControlSettingsObserver::onAcRegionChanged)));
554 }
555
556 virtual ~AutoControlSettingsObserver()
557 {
558 Dispatcher &dispatcher = Dispatcher::getInstance();
559
560 PROPAGATE_ERROR_CONTINUE(dispatcher.m_ispDigitalGainRange.unregisterObserver(this,
561 static_cast<IObserver::CallbackFunction>(
562 &AutoControlSettingsObserver::onIspDigitalGainRangeChanged)));
563 PROPAGATE_ERROR_CONTINUE(dispatcher.m_exposureCompensation.unregisterObserver(this,
564 static_cast<IObserver::CallbackFunction>(
565 &AutoControlSettingsObserver::onExposureCompensationChanged)));
566 PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbMode.unregisterObserver(this,
567 static_cast<IObserver::CallbackFunction>(
568 &AutoControlSettingsObserver::onAwbModeChanged)));
569 PROPAGATE_ERROR_CONTINUE(dispatcher.m_awbLock.unregisterObserver(this,
570 static_cast<IObserver::CallbackFunction>(
571 &AutoControlSettingsObserver::onAwbLockChanged)));
572 PROPAGATE_ERROR_CONTINUE(dispatcher.m_aeLock.unregisterObserver(this,
573 static_cast<IObserver::CallbackFunction>(
574 &AutoControlSettingsObserver::onAeLockChanged)));
575 PROPAGATE_ERROR_CONTINUE(dispatcher.m_aeAntibandingMode.unregisterObserver(this,
576 static_cast<IObserver::CallbackFunction>(
577 &AutoControlSettingsObserver::onAeAntibandingModeChanged)));
578 PROPAGATE_ERROR_CONTINUE(dispatcher.m_acRegionHorizontal.unregisterObserver(this,
579 static_cast<IObserver::CallbackFunction>(
580 &AutoControlSettingsObserver::onAcRegionChanged)));
581 PROPAGATE_ERROR_CONTINUE(dispatcher.m_acRegionVertical.unregisterObserver(this,
582 static_cast<IObserver::CallbackFunction>(
583 &AutoControlSettingsObserver::onAcRegionChanged)));
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 */
730 class DeFogSettingsObserver : public IObserverForInterface
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
746 virtual ~DeFogSettingsObserver()
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 {
858 { ArgusSamples::STILL_FILE_TYPE_JPG, "jpg" },
859 { ArgusSamples::STILL_FILE_TYPE_HEADERLESS, "headerless" }
860 };
861
862 // valid video formats
863 static const ValidatorEnum<VideoPipeline::VideoFormat>::ValueStringPair s_videoFormats[] =
864 {
865 { VideoPipeline::VIDEO_FORMAT_H264, "h264" },
866 { VideoPipeline::VIDEO_FORMAT_H265, "h265" },
867 { VideoPipeline::VIDEO_FORMAT_VP8, "vp8" },
868 { VideoPipeline::VIDEO_FORMAT_VP9, "vp9" }
869 };
870
871 // valid video file types
872 static const ValidatorEnum<VideoPipeline::VideoFileType>::ValueStringPair s_videoFileTypes[] =
873 {
874 { VideoPipeline::VIDEO_FILE_TYPE_MP4, "mp4" },
875 { VideoPipeline::VIDEO_FILE_TYPE_3GP, "3gp" },
876 { VideoPipeline::VIDEO_FILE_TYPE_AVI, "avi" },
877 { VideoPipeline::VIDEO_FILE_TYPE_MKV, "mkv" },
878 { VideoPipeline::VIDEO_FILE_TYPE_H265, "h265" }
879 };
880
881 // valid video file types
882 static const ValidatorEnum<
883 VideoPipeline::VideoControlRateMode>::ValueStringPair s_videoControlRateModes[] =
884 {
885 { VideoPipeline::VIDEO_CONTROLRATE_DISABLE, "disable" },
886 { VideoPipeline::VIDEO_CONTROLRATE_VARIABLE, "variable" },
887 { VideoPipeline::VIDEO_CONTROLRATE_CONSTANT, "constant" }
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
901 Dispatcher::Dispatcher()
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])),
955 STILL_FILE_TYPE_JPG)
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
981 Dispatcher::~Dispatcher()
982 {
983 if (!shutdown())
984 REPORT_ERROR("Failed to shutdown");
985 }
986
987 Dispatcher &Dispatcher::getInstance()
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
1008 bool Dispatcher::initialize()
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 m_iCameraProvider->setSyncSensorSessionsCount(0, 0);
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
1040 bool Dispatcher::shutdown()
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
1462 Argus::Range<float> Dispatcher::getDeviceApertureMotorSpeedRange() const
1463 {
1464 return m_deviceApertureMotorSpeedRange.get();
1465 }
1466
1467 uint32_t Dispatcher::getDeviceCount() const
1468 {
1469 assert(m_deviceOpen);
1470
1471 return m_cameraDevices.size();
1472 }
1473
1474 bool Dispatcher::createSession(TrackedUniqueObj<Argus::CaptureSession> &session,
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
1497 bool Dispatcher::dumpSessionInfo() const
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 */
1518 bool Dispatcher::createSession()
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 */
1531 bool Dispatcher::closeSession()
1532 {
1533 m_captureSession.reset();
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
1580 bool Dispatcher::createRequest(TrackedUniqueObj<Argus::Request> &request,
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
1862 bool Dispatcher::restartActiveRequests()
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