[Camera] Fixed possible memory leak and Add some descriptions
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia / Camera / CameraFeatures.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using Tizen.Internals.Errors;
20
21
22 namespace Tizen.Multimedia
23 {
24     /// <summary>
25     /// The CameraFeatures class provides properties
26     /// to get various capability information of the camera device.
27     /// </summary>
28     public class CameraFeatures
29     {
30         internal readonly Camera _camera;
31
32         private List<Size> _previewResolutions;
33         private List<Size> _cameraResolutions;
34         private List<CameraPixelFormat> _captureFormats;
35         private List<CameraPixelFormat> _previewFormats;
36         private List<CameraFps> _fps;
37         private List<CameraFps> _fpsByResolution;
38         private List<CameraAutoFocusMode> _autoFocusModes;
39         private List<CameraExposureMode> _exposureModes;
40         private List<CameraIsoLevel> _isoLevels;
41         private List<CameraTheaterMode> _theaterModes;
42         private List<CameraWhiteBalance> _whitebalances;
43         private List<CameraFlashMode> _flashModes;
44         private List<CameraSceneMode> _sceneModes;
45         private List<CameraEffectMode> _effectModes;
46         private List<CameraRotation> _streamRotations;
47         private List<CameraFlip> _streamFlips;
48         private List<CameraPtzType> _ptzTypes;
49
50         private delegate CameraError GetRangeDelegate(IntPtr handle, out int min, out int max);
51         private delegate bool IsSupportedDelegate(IntPtr handle);
52
53         internal CameraFeatures(Camera camera)
54         {
55             _camera = camera;
56
57             IsFaceDetectionSupported = IsFeatureSupported(Interop.CameraFeatures.IsFaceDetectionSupported);
58             IsMediaPacketPreviewCallbackSupported = IsFeatureSupported(Interop.CameraFeatures.IsMediaPacketPreviewCallbackSupported);
59             IsZeroShutterLagSupported = IsFeatureSupported(Interop.CameraFeatures.IsZeroShutterLagSupported);
60             IsContinuousCaptureSupported = IsFeatureSupported(Interop.CameraFeatures.IsContinuousCaptureSupported);
61             IsHdrCaptureSupported = IsFeatureSupported(Interop.CameraFeatures.IsHdrCaptureSupported);
62             IsAntiShakeSupported = IsFeatureSupported(Interop.CameraFeatures.IsAntiShakeSupported);
63             IsVideoStabilizationSupported = IsFeatureSupported(Interop.CameraFeatures.IsVideoStabilizationSupported);
64             IsAutoContrastSupported = IsFeatureSupported(Interop.CameraFeatures.IsAutoContrastSupported);
65             IsBrigtnessSupported = CheckRangeValid(Interop.CameraSettings.GetBrightnessRange);
66             IsExposureSupported = CheckRangeValid(Interop.CameraSettings.GetExposureRange);
67             IsZoomSupported = CheckRangeValid(Interop.CameraSettings.GetZoomRange);
68             IsPanSupported = CheckRangeValid(Interop.CameraSettings.GetPanRange);
69             IsTiltSupported = CheckRangeValid(Interop.CameraSettings.GetTiltRange);
70         }
71
72         private bool IsFeatureSupported(IsSupportedDelegate func)
73         {
74             return func(_camera.GetHandle());
75         }
76
77         private bool CheckRangeValid(GetRangeDelegate func)
78         {
79             int min = 0;
80             int max = 0;
81
82             CameraErrorFactory.ThrowIfError(func(_camera.GetHandle(), out min, out max),
83                 "Failed to check feature is suported or not.");
84
85             return min < max;
86         }
87
88         /// <summary>
89         /// Gets the face detection feature's supported state.
90         /// true if supported, otherwise false.
91         /// </summary>
92         public bool IsFaceDetectionSupported { get; }
93
94         /// <summary>
95         /// Gets the media packet preview callback feature's supported state.
96         /// true if supported, otherwise false.
97         /// </summary>
98         public bool IsMediaPacketPreviewCallbackSupported { get; }
99
100         /// <summary>
101         /// Gets the zero shutter lag feature's supported state.
102         /// true if supported, otherwise false.
103         /// </summary>
104         public bool IsZeroShutterLagSupported { get; }
105
106         /// <summary>
107         /// Gets continuous capture feature's supported state.
108         /// true if supported, otherwise false.
109         /// </summary>
110         public bool IsContinuousCaptureSupported { get; }
111
112         /// <summary>
113         /// Gets the support state of HDR capture.
114         /// true if supported, otherwise false.
115         /// </summary>
116         public bool IsHdrCaptureSupported { get; }
117
118         /// <summary>
119         /// Gets the support state of the anti-shake feature.
120         /// true if supported, otherwise false.
121         /// </summary>
122         public bool IsAntiShakeSupported { get; }
123
124         /// <summary>
125         /// Gets the support state of the video stabilization feature.
126         /// true if supported, otherwise false.
127         /// </summary>
128         public bool IsVideoStabilizationSupported { get; }
129
130         /// <summary>
131         /// Gets the support state of auto contrast feature.
132         /// true if supported, otherwise false.
133         /// </summary>
134         public bool IsAutoContrastSupported { get; }
135
136         /// <summary>
137         /// Gets the support state of brightness feature.
138         /// true if supported, otherwise false.
139         /// </summary>
140         public bool IsBrigtnessSupported { get; }
141
142         /// <summary>
143         /// Gets the support state of exposure feature.
144         /// true if supported, otherwise false.
145         /// </summary>
146         public bool IsExposureSupported { get; }
147
148         /// <summary>
149         /// Gets the support state of zoom feature.
150         /// true if supported, otherwise false.
151         /// </summary>
152         public bool IsZoomSupported { get; }
153
154         /// <summary>
155         /// Gets the support state of pan feature.
156         /// true if supported, otherwise false.
157         /// </summary>
158         public bool IsPanSupported { get; }
159
160         /// <summary>
161         /// Gets the support state of tilt feature.
162         /// true if supported, otherwise false.
163         /// </summary>
164         public bool IsTiltSupported { get; }
165
166         /// <summary>
167         /// Retrieves all the preview resolutions supported by the camera.
168         /// </summary>
169         /// <returns>
170         /// It returns a list containing all the supported preview resolutions.
171         /// by recorder.
172         /// </returns>
173         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
174         public IEnumerable<Size> SupportedPreviewResolutions
175         {
176             get
177             {
178                 if (_previewResolutions == null)
179                 {
180                     try
181                     {
182                         _previewResolutions = new List<Size>();
183
184                         Interop.CameraFeatures.PreviewResolutionCallback callback = (int width, int height, IntPtr userData) =>
185                         {
186                             _previewResolutions.Add(new Size(width, height));
187                             return true;
188                         };
189                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedPreviewResolutions(_camera.GetHandle(), callback, IntPtr.Zero),
190                             "Failed to get the supported preview resolutions");
191                     }
192                     catch
193                     {
194                         _previewResolutions = null;
195                         throw;
196                     }
197                 }
198
199                 return _previewResolutions;
200             }
201         }
202
203         /// <summary>
204         /// Retrieves all the capture resolutions supported by the camera.
205         /// </summary>
206         /// <returns>
207         /// It returns a list containing all the supported capture resolutions.
208         /// </returns>
209         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
210         public IEnumerable<Size> SupportedCaptureResolutions
211         {
212             get
213             {
214                 if (_cameraResolutions == null)
215                 {
216                     try
217                     {
218                         _cameraResolutions = new List<Size>();
219
220                         Interop.CameraFeatures.CaptureResolutionCallback callback = (int width, int height, IntPtr userData) =>
221                         {
222                             _cameraResolutions.Add(new Size(width, height));
223                             return true;
224                         };
225                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedCaptureResolutions(_camera.GetHandle(), callback, IntPtr.Zero),
226                             "Failed to get the supported capture resolutions");
227                     }
228                     catch
229                     {
230                         _cameraResolutions = null;
231                         throw;
232                     }
233                 }
234
235                 return _cameraResolutions;
236             }
237         }
238
239         /// <summary>
240         /// Retrieves all the capture formats supported by the camera.
241         /// </summary>
242         /// <returns>
243         /// It returns a list containing all the supported <see cref="CameraPixelFormat"/>.
244         /// </returns>
245         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
246         public IEnumerable<CameraPixelFormat> SupportedCapturePixelFormats
247         {
248             get
249             {
250                 if (_captureFormats == null)
251                 {
252                     try
253                     {
254                         _captureFormats = new List<CameraPixelFormat>();
255
256                         Interop.CameraFeatures.CaptureFormatCallback callback = (CameraPixelFormat format, IntPtr userData) =>
257                         {
258                             _captureFormats.Add(format);
259                             return true;
260                         };
261                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedCapturePixelFormats(_camera.GetHandle(), callback, IntPtr.Zero),
262                             "Failed to get the supported capture formats.");
263                     }
264                     catch
265                     {
266                         _captureFormats = null;
267                         throw;
268                     }
269                 }
270
271                 return _captureFormats;
272             }
273         }
274
275         /// <summary>
276         /// Retrieves all the preview formats supported by the camera.
277         /// </summary>
278         /// <returns>
279         /// It returns a list containing all the supported <see cref="CameraPixelFormat"/>.
280         /// </returns>
281         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
282         public IEnumerable<CameraPixelFormat> SupportedPreviewPixelFormats
283         {
284             get
285             {
286                 if (_previewFormats == null)
287                 {
288                     try
289                     {
290                         _previewFormats = new List<CameraPixelFormat>();
291
292                         Interop.CameraFeatures.PreviewFormatCallback callback = (CameraPixelFormat format, IntPtr userData) =>
293                         {
294                             _previewFormats.Add(format);
295                             return true;
296                         };
297                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedPreviewPixelFormats(_camera.GetHandle(), callback, IntPtr.Zero),
298                             "Failed to get the supported preview formats.");
299                     }
300                     catch
301                     {
302                         _previewFormats = null;
303                         throw;
304                     }
305                 }
306
307                 return _previewFormats;
308             }
309         }
310
311         /// <summary>
312         /// Retrieves all the fps supported by the camera.
313         /// </summary>
314         /// <returns>
315         /// It returns a list containing all the supported <see cref="CameraFps"/>.
316         /// </returns>
317         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
318         public IEnumerable<CameraFps> SupportedPreviewFps
319         {
320             get
321             {
322                 if (_fps == null)
323                 {
324                     try
325                     {
326                         _fps = new List<CameraFps>();
327
328                         Interop.CameraFeatures.FpsCallback callback = (CameraFps fps, IntPtr userData) =>
329                         {
330                             _fps.Add(fps);
331                             return true;
332                         };
333                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedPreviewFps(_camera.GetHandle(), callback, IntPtr.Zero),
334                             "Failed to get the supported camera fps");
335                     }
336                     catch
337                     {
338                         _fps = null;
339                         throw;
340                     }
341                 }
342
343                 return _fps;
344             }
345         }
346
347         /// <summary>
348         /// Retrieves all the fps by resolution supported by the camera.
349         /// </summary>
350         /// <returns>
351         /// It returns a list containing all the supported <see cref="CameraFps"/> by resolution.
352         /// </returns>
353         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
354         public IEnumerable<CameraFps> GetSupportedPreviewFpsByResolution(int width, int height)
355         {
356             if (_fpsByResolution == null)
357             {
358                 try
359                 {
360                     _fpsByResolution = new List<CameraFps>();
361
362                     Interop.CameraFeatures.FpsByResolutionCallback callback = (CameraFps fps, IntPtr userData) =>
363                     {
364                         _fpsByResolution.Add(fps);
365                         return true;
366                     };
367                     CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedPreviewFpsByResolution(_camera.GetHandle(),
368                         width, height, callback, IntPtr.Zero), "Failed to get the supported fps by resolutions.");
369                 }
370                 catch
371                 {
372                     _fpsByResolution = null;
373                     throw;
374                 }
375             }
376
377             return _fpsByResolution;
378         }
379
380         /// <summary>
381         /// Retrieves all the fps by resolution supported by the camera.
382         /// </summary>
383         /// <returns>
384         /// It returns a list containing all the supported <see cref="CameraFps"/> by resolution.
385         /// </returns>
386         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
387         public IEnumerable<CameraFps> GetSupportedPreviewFpsByResolution(Size size)
388         {
389             return GetSupportedPreviewFpsByResolution(size.Width, size.Height);
390         }
391
392         /// <summary>
393         /// Retrieves all the auto focus modes supported by the camera.
394         /// </summary>
395         /// <returns>
396         /// It returns a list containing all the supported <see cref="CameraAutoFocusMode"/>.
397         /// </returns>
398         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
399         public IEnumerable<CameraAutoFocusMode> SupportedAutoFocusModes
400         {
401             get
402             {
403                 if (_autoFocusModes == null)
404                 {
405                     try
406                     {
407                         _autoFocusModes = new List<CameraAutoFocusMode>();
408
409                         Interop.CameraFeatures.AfModeCallback callback = (CameraAutoFocusMode mode, IntPtr userData) =>
410                         {
411                             _autoFocusModes.Add(mode);
412                             return true;
413                         };
414                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedAfModes(_camera.GetHandle(), callback, IntPtr.Zero),
415                         "Failed to get the supported Auto focus modes.");
416                     }
417                     catch
418                     {
419                         _autoFocusModes = null;
420                         throw;
421                     }
422                 }
423
424                 return _autoFocusModes;
425             }
426         }
427
428         /// <summary>
429         /// Retrieves all the exposure modes supported by the camera.
430         /// </summary>
431         /// <returns>
432         /// It returns a list containing all the supported <see cref="CameraExposureMode"/>.
433         /// </returns>
434         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
435         public IEnumerable<CameraExposureMode> SupportedExposureModes
436         {
437             get
438             {
439                 if (_exposureModes == null)
440                 {
441                     try
442                     {
443                         _exposureModes = new List<CameraExposureMode>();
444
445                         Interop.CameraFeatures.ExposureModeCallback callback = (CameraExposureMode mode, IntPtr userData) =>
446                         {
447                             _exposureModes.Add(mode);
448                             return true;
449                         };
450                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedExposureModes(_camera.GetHandle(), callback, IntPtr.Zero),
451                         "Failed to get the supported Exposure modes.");
452                     }
453                     catch
454                     {
455                         _exposureModes = null;
456                         throw;
457                     }
458                 }
459
460                 return _exposureModes;
461             }
462         }
463
464         /// <summary>
465         /// Retrieves all the Iso level supported by the camera.
466         /// </summary>
467         /// <returns>
468         /// It returns a list containing all the supported <see cref="CameraIsoLevel"/>.
469         /// </returns>
470         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
471         public IEnumerable<CameraIsoLevel> SupportedIsoLevels
472         {
473             get
474             {
475                 if (_isoLevels == null)
476                 {
477                     try
478                     {
479                         _isoLevels = new List<CameraIsoLevel>();
480
481                         Interop.CameraFeatures.IsoCallback callback = (CameraIsoLevel iso, IntPtr userData) =>
482                         {
483                             _isoLevels.Add(iso);
484                             return true;
485                         };
486                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedIso(_camera.GetHandle(), callback, IntPtr.Zero),
487                         "Failed to get the supported Iso levels.");
488                     }
489                     catch
490                     {
491                         _isoLevels = null;
492                         throw;
493                     }
494                 }
495
496                 return _isoLevels;
497             }
498         }
499
500         /// <summary>
501         /// Retrieves all the theater modes supported by the camera.
502         /// </summary>
503         /// <returns>
504         /// It returns a list containing all the supported <see cref="CameraTheaterMode"/>.
505         /// </returns>
506         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
507         public IEnumerable<CameraTheaterMode> SupportedTheaterModes
508         {
509             get
510             {
511                 if (_theaterModes == null)
512                 {
513                     try
514                     {
515                         _theaterModes = new List<CameraTheaterMode>();
516
517                         Interop.CameraFeatures.TheaterModeCallback callback = (CameraTheaterMode theaterMode, IntPtr userData) =>
518                         {
519                             _theaterModes.Add(theaterMode);
520                             return true;
521                         };
522                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedTheaterModes(_camera.GetHandle(), callback, IntPtr.Zero),
523                         "Failed to get the supported theater modes.");
524                     }
525                     catch
526                     {
527                         _theaterModes = null;
528                         throw;
529                     }
530                 }
531
532                 return _theaterModes;
533             }
534         }
535
536         /// <summary>
537         /// Retrieves all the whitebalance modes supported by the camera.
538         /// </summary>
539         /// <returns>
540         /// It returns a list containing all the supported <see cref="CameraWhiteBalance"/>.
541         /// </returns>
542         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
543         public IEnumerable<CameraWhiteBalance> SupportedWhiteBalances
544         {
545             get
546             {
547                 if (_whitebalances == null)
548                 {
549                     try
550                     {
551                         _whitebalances = new List<CameraWhiteBalance>();
552
553                         Interop.CameraFeatures.WhitebalanceCallback callback = (CameraWhiteBalance whiteBalance, IntPtr userData) =>
554                         {
555                             _whitebalances.Add(whiteBalance);
556                             return true;
557                         };
558                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedWhitebalance(_camera.GetHandle(), callback, IntPtr.Zero),
559                         "Failed to get the supported white balance.");
560                     }
561                     catch
562                     {
563                         _whitebalances = null;
564                         throw;
565                     }
566                 }
567
568                 return _whitebalances;
569             }
570         }
571
572         /// <summary>
573         /// Retrieves all the flash modes supported by the camera.
574         /// </summary>
575         /// <returns>
576         /// It returns a list containing all the supported <see cref="CameraFlashMode"/>.
577         /// </returns>
578         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
579         public IEnumerable<CameraFlashMode> SupportedFlashModes
580         {
581             get
582             {
583                 if (_flashModes == null)
584                 {
585                     try
586                     {
587                         _flashModes = new List<CameraFlashMode>();
588
589                         Interop.CameraFeatures.FlashModeCallback callback = (CameraFlashMode flashMode, IntPtr userData) =>
590                         {
591                             _flashModes.Add(flashMode);
592                             return true;
593                         };
594                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedFlashModes(_camera.GetHandle(), callback, IntPtr.Zero),
595                         "Failed to get the supported flash modes.");
596                     }
597                     catch
598                     {
599                         _flashModes = null;
600                         throw;
601                     }
602                 }
603
604                 return _flashModes;
605             }
606         }
607
608         /// <summary>
609         /// Retrieves all the scene modes supported by the camera.
610         /// </summary>
611         /// <returns>
612         /// It returns a list containing all the supported <see cref="CameraSceneMode"/>.
613         /// </returns>
614         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
615         public IEnumerable<CameraSceneMode> SupportedSceneModes
616         {
617             get
618             {
619                 if (_sceneModes == null)
620                 {
621                     try
622                     {
623                         _sceneModes = new List<CameraSceneMode>();
624
625                         Interop.CameraFeatures.SceneModeCallback callback = (CameraSceneMode sceneMode, IntPtr userData) =>
626                         {
627                             _sceneModes.Add(sceneMode);
628                             return true;
629                         };
630                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedSceneModes(_camera.GetHandle(), callback, IntPtr.Zero),
631                         "Failed to get the supported scene modes.");
632                     }
633                     catch
634                     {
635                         _sceneModes = null;
636                         throw;
637                     }
638                 }
639
640                 return _sceneModes;
641             }
642         }
643
644         /// <summary>
645         /// Retrieves all the effect modes supported by the camera.
646         /// </summary>
647         /// <returns>
648         /// It returns a list containing all the supported <see cref="CameraEffectMode"/>.
649         /// </returns>
650         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
651         public IEnumerable<CameraEffectMode> SupportedEffects
652         {
653             get
654             {
655                 if (_effectModes == null)
656                 {
657                     try
658                     {
659                         _effectModes = new List<CameraEffectMode>();
660
661                         Interop.CameraFeatures.EffectCallback callback = (CameraEffectMode effect, IntPtr userData) =>
662                         {
663                             _effectModes.Add(effect);
664                             return true;
665                         };
666                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedEffects(_camera.GetHandle(), callback, IntPtr.Zero),
667                         "Failed to get the supported camera effects.");
668                     }
669                     catch
670                     {
671                         _effectModes = null;
672                         throw;
673                     }
674                 }
675
676                 return _effectModes;
677             }
678         }
679
680         /// <summary>
681         /// Retrieves all the stream rotation supported by the camera.
682         /// </summary>
683         /// <returns>
684         /// It returns a list containing all the supported <see cref="CameraRotation"/>.
685         /// </returns>
686         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
687         public IEnumerable<CameraRotation> SupportedStreamRotations
688         {
689             get
690             {
691                 if (_streamRotations == null)
692                 {
693                     try
694                     {
695                         _streamRotations = new List<CameraRotation>();
696
697                         Interop.CameraFeatures.StreamRotationCallback callback = (CameraRotation streamRotation, IntPtr userData) =>
698                         {
699                             _streamRotations.Add(streamRotation);
700                             return true;
701                         };
702                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedStreamRotations(_camera.GetHandle(), callback, IntPtr.Zero),
703                         "Failed to get the supported camera rotations.");
704                     }
705                     catch
706                     {
707                         _streamRotations = null;
708                         throw;
709                     }
710                 }
711
712                 return _streamRotations;
713             }
714         }
715
716         /// <summary>
717         /// Retrieves all the flips supported by the camera.
718         /// </summary>
719         /// <returns>
720         /// It returns a list containing all the supported <see cref="CameraFlip"/>.
721         /// </returns>
722         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
723         public IEnumerable<CameraFlip> SupportedStreamFlips
724         {
725             get
726             {
727                 if (_streamFlips == null)
728                 {
729                     try
730                     {
731                         _streamFlips = new List<CameraFlip>();
732
733                         Interop.CameraFeatures.StreamFlipCallback callback = (CameraFlip streamFlip, IntPtr userData) =>
734                         {
735                             _streamFlips.Add(streamFlip);
736                             return true;
737                         };
738                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedStreamFlips(_camera.GetHandle(), callback, IntPtr.Zero),
739                         "Failed to get the supported camera flips.");
740                     }
741                     catch
742                     {
743                         _streamFlips = null;
744                         throw;
745                     }
746                 }
747
748                 return _streamFlips;
749             }
750         }
751
752         /// <summary>
753         /// Retrieves all the ptz types by the camera.
754         /// </summary>
755         /// <returns>
756         /// It returns a list containing all the supported <see cref="CameraPtzType"/>.
757         /// </returns>
758         /// <exception cref="ObjectDisposedException">The camera already has been disposed.</exception>
759         public IEnumerable<CameraPtzType> SupportedPtzTypes
760         {
761             get
762             {
763                 if (_ptzTypes.Count == 0)
764                 {
765                     try
766                     {
767                         _ptzTypes = new List<CameraPtzType>();
768
769                         Interop.CameraFeatures.PtzTypeCallback callback = (CameraPtzType ptzType, IntPtr userData) =>
770                         {
771                             _ptzTypes.Add(ptzType);
772                             return true;
773                         };
774                         CameraErrorFactory.ThrowIfError(Interop.CameraFeatures.SupportedPtzTypes(_camera.GetHandle(), callback, IntPtr.Zero),
775                         "Failed to get the supported Ptz types.");
776                     }
777                     catch
778                     {
779                         _ptzTypes = null;
780                         throw;
781                     }
782                 }
783
784                 return _ptzTypes;
785             }
786         }
787     }
788 }