2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.ComponentModel;
19 using Native = Interop.Camera;
21 namespace Tizen.Multimedia
24 /// This camera class provides methods to capture photos and supports setting up notifications
25 /// for state changes of capturing, previewing, focusing, and informing about the resolution and the binary format,
26 /// and functions for picture manipulations like sepia, negative, and many more.
27 /// It also notifies you when a significant picture parameter changes, (For example, focus).
29 /// <since_tizen> 3 </since_tizen>
30 /// <feature> http://tizen.org/feature/camera </feature>
31 public partial class Camera : IDisposable, IDisplayable<CameraError>
34 /// An event that occurs when the camera interrupt is started by the policy.
36 /// <since_tizen> 4 </since_tizen>
37 public event EventHandler<CameraInterruptStartedEventArgs> InterruptStarted;
38 private Native.InterruptStartedCallback _interruptStartedCallback;
41 /// An event that occurs when an camera is interrupted by the policy.
43 /// <since_tizen> 3 </since_tizen>
44 public event EventHandler<CameraInterruptedEventArgs> Interrupted;
45 private Native.InterruptedCallback _interruptedCallback;
48 /// An event that occurs when there is an asynchronous error.
50 /// <since_tizen> 3 </since_tizen>
51 public event EventHandler<CameraErrorOccurredEventArgs> ErrorOccurred;
52 private Native.ErrorCallback _errorCallback;
55 /// An event that occurs when the auto focus state is changed.
57 /// <since_tizen> 3 </since_tizen>
58 public event EventHandler<CameraFocusStateChangedEventArgs> FocusStateChanged;
59 private Native.FocusStateChangedCallback _focusStateChangedCallback;
62 /// An event that occurs when a face is detected in the preview frame.
64 /// <since_tizen> 3 </since_tizen>
65 public event EventHandler<FaceDetectedEventArgs> FaceDetected;
66 private Native.FaceDetectedCallback _faceDetectedCallback;
69 /// An event that occurs during capture of an image.
71 /// <since_tizen> 3 </since_tizen>
72 public event EventHandler<CameraCapturingEventArgs> Capturing;
73 private Native.CapturingCallback _capturingCallback;
76 /// An event that occurs after the capture of the image.
78 /// <since_tizen> 3 </since_tizen>
79 public event EventHandler<EventArgs> CaptureCompleted;
80 private Native.CaptureCompletedCallback _captureCompletedCallback;
82 private Native.HdrCaptureProgressCallback _hdrCaptureProgressCallback;
83 private event EventHandler<HdrCaptureProgressEventArgs> _hdrCaptureProgress;
84 private object _hdrCaptureProgressEventLock = new object();
87 /// An event that occurs when there is a change in the HDR capture progress.
88 /// Checks whether the <see cref="CameraCapabilities.IsHdrCaptureSupported"/> is supported or not before adding this EventHandler.
90 /// <since_tizen> 3 </since_tizen>
91 /// <exception cref="NotSupportedException">In case of HDR feature is not supported.</exception>
92 public event EventHandler<HdrCaptureProgressEventArgs> HdrCaptureProgress
96 lock (_hdrCaptureProgressEventLock)
98 if (_hdrCaptureProgress == null)
100 RegisterHdrCaptureProgress();
103 _hdrCaptureProgress += value;
109 lock (_hdrCaptureProgressEventLock)
111 _hdrCaptureProgress -= value;
113 if (_hdrCaptureProgress == null)
115 UnregisterHdrCaptureProgress();
122 /// An event that occurs when the camera state is changed.
124 /// <since_tizen> 3 </since_tizen>
125 public event EventHandler<CameraStateChangedEventArgs> StateChanged;
126 private Native.StateChangedCallback _stateChangedCallback;
128 private static Native.DeviceStateChangedCallback _deviceStateChangedCallback;
129 private static event EventHandler<CameraDeviceStateChangedEventArgs> _deviceStateChanged;
130 private static object _deviceStateChangedEventLock = new object();
131 private static int _deviceStateCallbackId;
134 /// An event that occurs after the <see cref="CameraDeviceState"/> is changed.
136 /// <since_tizen> 3 </since_tizen>
137 /// <exception cref="InvalidOperationException">In case of any invalid operations.</exception>
138 /// <exception cref="NotSupportedException">In case of this feature is not supported.</exception>
139 /// <exception cref="ArgumentException">In case of invalid parameters.</exception>
140 public static event EventHandler<CameraDeviceStateChangedEventArgs> DeviceStateChanged
144 lock (_deviceStateChangedEventLock)
146 if (_deviceStateChanged == null)
148 RegisterDeviceStateChangedCallback();
151 _deviceStateChanged += value;
157 lock (_deviceStateChangedEventLock)
159 _deviceStateChanged -= value;
161 if (_deviceStateChanged == null)
163 UnregisterDeviceStateChangedCallback();
169 private Native.PreviewCallback _previewCallback;
170 private event EventHandler<PreviewEventArgs> _preview;
171 private object _previewEventLock = new object();
173 /// An event that occurs once per frame when previewing.
174 /// Preview callback is registered when an user adds a callback explicitly to avoid useless P/Invoke.
176 /// <since_tizen> 3 </since_tizen>
177 public event EventHandler<PreviewEventArgs> Preview
181 lock (_previewEventLock)
183 if (_preview == null)
185 RegisterPreviewCallback();
194 lock (_previewEventLock)
198 if (_preview == null)
200 UnregisterPreviewCallback();
206 private Native.MediaPacketPreviewCallback _mediaPacketPreviewCallback;
207 private EventHandler<MediaPacketPreviewEventArgs> _mediaPacketPreview;
208 private object _mediaPacketPreviewEventLock = new object();
211 /// An event that occurs once per frame when previewing.
212 /// Preview callback is registered when an user adds a callback explicitly to avoid useless P/Invoke.
214 /// <since_tizen> 3 </since_tizen>
215 public event EventHandler<MediaPacketPreviewEventArgs> MediaPacketPreview
219 lock (_mediaPacketPreviewEventLock)
221 if (_mediaPacketPreview == null)
223 RegisterMediaPacketPreviewCallback();
226 _mediaPacketPreview += value;
232 lock (_mediaPacketPreviewEventLock)
234 _mediaPacketPreview -= value;
236 if (_mediaPacketPreview == null)
238 UnregisterMediaPacketPreviewCallback();
244 private Native.ExtraPreviewCallback _extraPreviewCallback;
245 private event EventHandler<ExtraPreviewEventArgs> _extraPreview;
247 /// An event that occurs once per frame when previewing.
248 /// Preview callback is registered when an user adds a callback explicitly to avoid useless P/Invoke.
250 /// <since_tizen> 9 </since_tizen>
251 [EditorBrowsable(EditorBrowsableState.Never)]
252 public event EventHandler<ExtraPreviewEventArgs> ExtraPreview
256 if (_extraPreview == null)
258 RegisterExtraPreviewCallback();
261 _extraPreview += value;
266 _extraPreview -= value;
268 if (_extraPreview == null)
270 UnregisterExtraPreviewCallback();
276 /// An event that occurs when there is a change in the camera device list.
278 /// <since_tizen> 9 </since_tizen>
279 [EditorBrowsable(EditorBrowsableState.Never)]
280 public event EventHandler<CameraDeviceListChangedEventArgs> CameraDeviceListChanged;
282 private void RegisterCallbacks()
284 RegisterErrorCallback();
285 RegisterFocusStateChanged();
286 RegisterInterruptStartedCallback();
287 RegisterInterruptedCallback();
288 RegisterStateChangedCallback();
290 //Define capturing callback
291 _capturingCallback = (main, postview, thumbnail, userData) =>
293 Capturing?.Invoke(this, new CameraCapturingEventArgs(new StillImage(main),
294 postview == IntPtr.Zero ? null : new StillImage(postview),
295 thumbnail == IntPtr.Zero ? null : new StillImage(thumbnail)));
298 //Define captureCompleted callback
299 _captureCompletedCallback = _ =>
301 SetState(CameraState.Captured);
302 CaptureCompleted?.Invoke(this, EventArgs.Empty);
306 private void RegisterInterruptStartedCallback()
308 _interruptStartedCallback = (policy, state, _) =>
310 InterruptStarted?.Invoke(this, new CameraInterruptStartedEventArgs(policy, state));
313 Native.SetInterruptStartedCallback(_handle, _interruptStartedCallback).
314 ThrowIfFailed("Failed to set interrupt callback.");
317 private void RegisterInterruptedCallback()
319 _interruptedCallback = (policy, previous, current, _) =>
321 Interrupted?.Invoke(this, new CameraInterruptedEventArgs(policy, previous, current));
324 Native.SetInterruptedCallback(_handle, _interruptedCallback).
325 ThrowIfFailed("Failed to set interrupt callback.");
328 private void RegisterErrorCallback()
330 _errorCallback = (error, current, _) =>
332 ErrorOccurred?.Invoke(this, new CameraErrorOccurredEventArgs(error, current));
335 Native.SetErrorCallback(_handle, _errorCallback).
336 ThrowIfFailed("Setting error callback failed");
339 private void RegisterStateChangedCallback()
341 _stateChangedCallback = (previous, current, byPolicy, _) =>
344 Log.Info(CameraLog.Tag, "Camera state changed " + previous.ToString() + " -> " + current.ToString());
345 StateChanged?.Invoke(this, new CameraStateChangedEventArgs(previous, current, byPolicy));
348 Native.SetStateChangedCallback(_handle, _stateChangedCallback).
349 ThrowIfFailed("Failed to set state changed callback.");
352 private static void RegisterDeviceStateChangedCallback()
354 _deviceStateChangedCallback = (device, state, _) =>
356 _deviceStateChanged?.Invoke(null, new CameraDeviceStateChangedEventArgs(device, state));
359 Native.SetDeviceStateChangedCallback(_deviceStateChangedCallback, IntPtr.Zero, out _deviceStateCallbackId).
360 ThrowIfFailed("Failed to set device state changed callback.");
362 Log.Info(CameraLog.Tag, "add callbackId " + _deviceStateCallbackId.ToString());
365 private static void UnregisterDeviceStateChangedCallback()
367 Native.UnsetDeviceStateChangedCallback(_deviceStateCallbackId).
368 ThrowIfFailed("Failed to unset device state changed callback.");
370 _deviceStateChangedCallback = null;
371 _deviceStateCallbackId = 0;
374 private void RegisterFocusStateChanged()
376 _focusStateChangedCallback = (state, _) =>
378 FocusStateChanged?.Invoke(this, new CameraFocusStateChangedEventArgs(state));
381 Native.SetFocusStateChangedCallback(_handle, _focusStateChangedCallback).
382 ThrowIfFailed("Failed to set focus changed callback.");
385 private void RegisterHdrCaptureProgress()
387 _hdrCaptureProgressCallback = (percent, _) =>
389 _hdrCaptureProgress?.Invoke(this, new HdrCaptureProgressEventArgs(percent));
392 Native.SetHdrCaptureProgressCallback(_handle, _hdrCaptureProgressCallback).
393 ThrowIfFailed("Failed to set Hdr capture progress callback.");
396 private void UnregisterHdrCaptureProgress()
398 Native.UnsetHdrCaptureProgressCallback(_handle).
399 ThrowIfFailed("Failed to unset hdr capture progres callback.");
401 _hdrCaptureProgressCallback = null;
404 private void RegisterPreviewCallback()
406 _previewCallback = (frame, _) =>
408 _preview?.Invoke(this, new PreviewEventArgs(new PreviewFrame(frame)));
411 Native.SetPreviewCallback(_handle, _previewCallback).
412 ThrowIfFailed("Failed to set preview callback.");
415 private void UnregisterPreviewCallback()
417 Native.UnsetPreviewCallback(_handle).
418 ThrowIfFailed("Failed to unset preview callback.");
420 _previewCallback = null;
423 private void RegisterMediaPacketPreviewCallback()
425 _mediaPacketPreviewCallback = (mediaPacket, _) =>
427 MediaPacket packet = MediaPacket.From(mediaPacket);
429 var eventHandler = _mediaPacketPreview;
431 if (eventHandler != null)
433 eventHandler.Invoke(this, new MediaPacketPreviewEventArgs(packet));
439 Native.SetMediaPacketPreviewCallback(_handle, _mediaPacketPreviewCallback).
440 ThrowIfFailed("Failed to set media packet preview callback.");
443 private void UnregisterMediaPacketPreviewCallback()
445 Native.UnsetMediaPacketPreviewCallback(_handle).
446 ThrowIfFailed("Failed to unset media packet preview callback.");
448 _mediaPacketPreviewCallback = null;
451 private void RegisterExtraPreviewCallback()
453 _extraPreviewCallback = (frame, streamId, _) =>
455 _extraPreview?.Invoke(this, new ExtraPreviewEventArgs(new PreviewFrame(frame), streamId));
458 Native.SetExtraPreviewCallback(_handle, _extraPreviewCallback).
459 ThrowIfFailed("Failed to set extra preview callback.");
462 private void UnregisterExtraPreviewCallback()
464 Native.UnsetPreviewCallback(_handle).
465 ThrowIfFailed("Failed to unset preview callback.");
467 _extraPreviewCallback = null;