From 4c64f92a56b40a099bde1747b463da998fa409f1 Mon Sep 17 00:00:00 2001 From: Haesu Gwon Date: Wed, 22 Mar 2017 16:56:59 +0900 Subject: [PATCH] [Recorder] refactoring Change-Id: Ie4a5aac6be084e944cffc5b39993818adebb169f Signed-off-by: Haesu Gwon --- src/Tizen.Multimedia/Camera/CameraErrorFactory.cs | 4 +- src/Tizen.Multimedia/Camera/DoublePlane.cs | 3 +- src/Tizen.Multimedia/Camera/EncodedPlane.cs | 3 +- .../{FaceDetectedData.cs => FaceDetectionData.cs} | 0 src/Tizen.Multimedia/Camera/PreviewData.cs | 2 +- src/Tizen.Multimedia/Camera/SinglePlane.cs | 3 +- src/Tizen.Multimedia/Camera/TriplePlane.cs | 3 +- src/Tizen.Multimedia/Interop/Interop.Recorder.cs | 73 +- .../Interop/Interop.RecorderAttribute.cs | 70 -- .../Interop/Interop.RecorderCapability.cs | 33 - .../Interop/Interop.RecorderFeatures.cs | 33 + .../Interop/Interop.RecorderSettings.cs | 103 ++ .../Recorder/AudioStreamDeliveredEventArgs.cs | 43 +- src/Tizen.Multimedia/Recorder/Recorder.cs | 1265 +++++--------------- src/Tizen.Multimedia/Recorder/RecorderEnums.cs | 5 +- .../Recorder/RecorderErrorFactory.cs | 36 +- src/Tizen.Multimedia/Recorder/RecorderFeatures.cs | 153 +++ .../Recorder/RecorderInterruptedEventArgs.cs | 30 +- src/Tizen.Multimedia/Recorder/RecorderSettings.cs | 423 +++++++ .../Recorder/RecorderStateChangedEventArgs.cs | 32 +- .../Recorder/RecordingErrorOccurredEventArgs.cs | 21 +- .../Recorder/RecordingLimitReachedEventArgs.cs | 12 +- ...dEventArgs.cs => RecordingProgressEventArgs.cs} | 25 +- src/Tizen.Multimedia/Recorder/VideoResolution.cs | 86 -- .../StreamRecorder/StreamRecorder.cs | 6 +- 25 files changed, 1076 insertions(+), 1391 deletions(-) rename src/Tizen.Multimedia/Camera/{FaceDetectedData.cs => FaceDetectionData.cs} (100%) delete mode 100755 src/Tizen.Multimedia/Interop/Interop.RecorderAttribute.cs delete mode 100644 src/Tizen.Multimedia/Interop/Interop.RecorderCapability.cs create mode 100755 src/Tizen.Multimedia/Interop/Interop.RecorderFeatures.cs create mode 100755 src/Tizen.Multimedia/Interop/Interop.RecorderSettings.cs mode change 100644 => 100755 src/Tizen.Multimedia/Recorder/AudioStreamDeliveredEventArgs.cs create mode 100755 src/Tizen.Multimedia/Recorder/RecorderFeatures.cs mode change 100644 => 100755 src/Tizen.Multimedia/Recorder/RecorderInterruptedEventArgs.cs create mode 100755 src/Tizen.Multimedia/Recorder/RecorderSettings.cs mode change 100644 => 100755 src/Tizen.Multimedia/Recorder/RecorderStateChangedEventArgs.cs mode change 100644 => 100755 src/Tizen.Multimedia/Recorder/RecordingErrorOccurredEventArgs.cs mode change 100644 => 100755 src/Tizen.Multimedia/Recorder/RecordingLimitReachedEventArgs.cs rename src/Tizen.Multimedia/Recorder/{RecordingStatusChangedEventArgs.cs => RecordingProgressEventArgs.cs} (67%) mode change 100644 => 100755 delete mode 100644 src/Tizen.Multimedia/Recorder/VideoResolution.cs diff --git a/src/Tizen.Multimedia/Camera/CameraErrorFactory.cs b/src/Tizen.Multimedia/Camera/CameraErrorFactory.cs index 984e707..bc99d4e 100755 --- a/src/Tizen.Multimedia/Camera/CameraErrorFactory.cs +++ b/src/Tizen.Multimedia/Camera/CameraErrorFactory.cs @@ -69,14 +69,14 @@ namespace Tizen.Multimedia case CameraError.SecurityRestricted: case CameraError.PermissionDenied: - throw new UnauthorizedAccessException(errorMessage); + throw new UnauthorizedAccessException(errorMessage); case CameraError.NotSupported: throw new NotSupportedException(errorMessage); case CameraError.InvalidState: case CameraError.InvalidOperation: - case CameraError.ResourceConflict: + case CameraError.ResourceConflict: case CameraError.ServiceDisconnected: throw new InvalidOperationException(errorMessage); diff --git a/src/Tizen.Multimedia/Camera/DoublePlane.cs b/src/Tizen.Multimedia/Camera/DoublePlane.cs index 739e249..087cd23 100755 --- a/src/Tizen.Multimedia/Camera/DoublePlane.cs +++ b/src/Tizen.Multimedia/Camera/DoublePlane.cs @@ -41,5 +41,4 @@ namespace Tizen.Multimedia /// public byte[] UV { get; } } -} - +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Camera/EncodedPlane.cs b/src/Tizen.Multimedia/Camera/EncodedPlane.cs index 650ccc2..76db75c 100755 --- a/src/Tizen.Multimedia/Camera/EncodedPlane.cs +++ b/src/Tizen.Multimedia/Camera/EncodedPlane.cs @@ -34,5 +34,4 @@ namespace Tizen.Multimedia /// public byte[] Data { get; } } -} - +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Camera/FaceDetectedData.cs b/src/Tizen.Multimedia/Camera/FaceDetectionData.cs similarity index 100% rename from src/Tizen.Multimedia/Camera/FaceDetectedData.cs rename to src/Tizen.Multimedia/Camera/FaceDetectionData.cs diff --git a/src/Tizen.Multimedia/Camera/PreviewData.cs b/src/Tizen.Multimedia/Camera/PreviewData.cs index 72d604f..7a23e90 100755 --- a/src/Tizen.Multimedia/Camera/PreviewData.cs +++ b/src/Tizen.Multimedia/Camera/PreviewData.cs @@ -109,4 +109,4 @@ namespace Tizen.Multimedia public PlaneType PlaneType { get; } } -} +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Camera/SinglePlane.cs b/src/Tizen.Multimedia/Camera/SinglePlane.cs index e436c95..bd402e2 100755 --- a/src/Tizen.Multimedia/Camera/SinglePlane.cs +++ b/src/Tizen.Multimedia/Camera/SinglePlane.cs @@ -34,5 +34,4 @@ namespace Tizen.Multimedia /// public byte[] Data { get; } } -} - +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Camera/TriplePlane.cs b/src/Tizen.Multimedia/Camera/TriplePlane.cs index e7a29bb..481b629 100755 --- a/src/Tizen.Multimedia/Camera/TriplePlane.cs +++ b/src/Tizen.Multimedia/Camera/TriplePlane.cs @@ -48,5 +48,4 @@ namespace Tizen.Multimedia /// public byte[] V { get; } } -} - +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Interop/Interop.Recorder.cs b/src/Tizen.Multimedia/Interop/Interop.Recorder.cs index f0d279c..f6f1ca6 100755 --- a/src/Tizen.Multimedia/Interop/Interop.Recorder.cs +++ b/src/Tizen.Multimedia/Interop/Interop.Recorder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using Tizen.Multimedia; @@ -13,29 +13,29 @@ internal static partial class Interop internal static partial class Recorder { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void RecordingLimitReachedCallback(RecordingLimitType type, IntPtr userData); + internal delegate void RecorderErrorCallback(RecorderErrorCode error, RecorderState current, IntPtr userData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void RecordingStatusCallback(ulong elapsedTime, ulong fileSize, IntPtr userData); + internal delegate void InterruptedCallback(RecorderPolicy policy, RecorderState previous, RecorderState current, IntPtr userData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void StatechangedCallback(RecorderState previous, RecorderState current, bool byPolicy, IntPtr userData); + internal delegate void RecordingLimitReachedCallback(RecordingLimitType type, IntPtr userData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void InterruptedCallback(RecorderPolicy policy, RecorderState previous, RecorderState current, IntPtr userData); + internal delegate void RecordingProgressCallback(ulong elapsedTime, ulong fileSize, IntPtr userData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void AudioStreamCallback(IntPtr stream, int size, AudioSampleType type, int channel, uint timeStamp, IntPtr userData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate void RecorderErrorCallback(RecorderErrorCode error, RecorderState current, IntPtr userData); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_create_videorecorder")] - internal static extern int CreateVideo(IntPtr cameraHandle, out IntPtr handle); + internal delegate void StatechangedCallback(RecorderState previous, RecorderState current, bool byPolicy, IntPtr userData); [DllImport(Libraries.Recorder, EntryPoint = "recorder_create_audiorecorder")] internal static extern int Create(out IntPtr handle); + [DllImport(Libraries.Recorder, EntryPoint = "recorder_create_videorecorder")] + internal static extern int CreateVideo(IntPtr cameraHandle, out IntPtr handle); + [DllImport(Libraries.Recorder, EntryPoint = "recorder_destroy")] internal static extern int Destroy(IntPtr handle); @@ -58,43 +58,22 @@ internal static partial class Interop internal static extern int Cancel(IntPtr handle); [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_state")] - internal static extern int GetState(IntPtr handle, out int state); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_audio_level")] - internal static extern int GetAudioLevel(IntPtr handle, out double dB); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_filename")] - internal static extern int SetFileName(IntPtr handle, string path); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_filename")] - internal static extern int GetFileName(IntPtr handle, out IntPtr path); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_file_format")] - internal static extern int SetFileFormat(IntPtr handle, int format); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_file_format")] - internal static extern int GetFileFormat(IntPtr handle, out int format); + internal static extern int GetState(IntPtr handle, out RecorderState state); [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_sound_stream_info")] internal static extern int SetAudioStreamPolicy(IntPtr handle, IntPtr streamInfoHandle); - [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_audio_encoder")] - internal static extern int SetAudioEncoder(IntPtr handle, int codec); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_audio_encoder")] - internal static extern int GetAudioEncoder(IntPtr handle, out int codec); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_video_encoder")] - internal static extern int SetVideoEncoder(IntPtr handle, int codec); + [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_error_cb")] + internal static extern int SetErrorCallback(IntPtr handle, RecorderErrorCallback callback, IntPtr userData); - [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_video_encoder")] - internal static extern int GetVideoEncoder(IntPtr handle, out int codec); + [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_error_cb")] + internal static extern int UnsetErrorCallback(IntPtr handle); - [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_video_resolution")] - internal static extern int SetVideoResolution(IntPtr handle, int width, int height); + [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_interrupted_cb")] + internal static extern int SetInterruptedCallback(IntPtr handle, InterruptedCallback callback, IntPtr userData); - [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_video_resolution")] - internal static extern int GetVideoResolution(IntPtr handle, out int width, out int height); + [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_interrupted_cb")] + internal static extern int UnsetInterruptedCallback(IntPtr handle); [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_state_changed_cb")] internal static extern int SetStateChangedCallback(IntPtr handle, StatechangedCallback callback, IntPtr userData); @@ -103,16 +82,10 @@ internal static partial class Interop internal static extern int UnsetStateChangedCallback(IntPtr handle); [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_recording_status_cb")] - internal static extern int SetStatusChangedCallback(IntPtr handle, RecordingStatusCallback callback, IntPtr userData); + internal static extern int SetRecordingProgressCallback(IntPtr handle, RecordingProgressCallback callback, IntPtr userData); [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_recording_status_cb")] - internal static extern int UnsetStatusChangedCallback(IntPtr handle); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_interrupted_cb")] - internal static extern int SetInterruptedCallback(IntPtr handle, InterruptedCallback callback, IntPtr userData); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_interrupted_cb")] - internal static extern int UnsetInterruptedCallback(IntPtr handle); + internal static extern int UnsetRecordingProgressCallback(IntPtr handle); [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_audio_stream_cb")] internal static extern int SetAudioStreamCallback(IntPtr handle, AudioStreamCallback callback, IntPtr userData); @@ -125,11 +98,5 @@ internal static partial class Interop [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_recording_limit_reached_cb")] internal static extern int UnsetLimitReachedCallback(IntPtr handle); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_error_cb")] - internal static extern int SetErrorCallback(IntPtr handle, RecorderErrorCallback callback, IntPtr userData); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_unset_error_cb")] - internal static extern int UnsetErrorCallback(IntPtr handle); } } diff --git a/src/Tizen.Multimedia/Interop/Interop.RecorderAttribute.cs b/src/Tizen.Multimedia/Interop/Interop.RecorderAttribute.cs deleted file mode 100755 index fb4be09..0000000 --- a/src/Tizen.Multimedia/Interop/Interop.RecorderAttribute.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using Tizen.Multimedia; - -internal static partial class Interop -{ - internal static partial class RecorderAttribute - { - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_size_limit")] - internal static extern int SetSizeLimit(IntPtr handle, int kbyte); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_size_limit")] - internal static extern int GetSizeLimit(IntPtr handle, out int kbyte); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_time_limit")] - internal static extern int SetTimeLimit(IntPtr handle, int second); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_time_limit")] - internal static extern int GetTimeLimit(IntPtr handle, out int second); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_device")] - internal static extern int SetAudioDevice(IntPtr handle, int device); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_device")] - internal static extern int GetAudioDevice(IntPtr handle, out int device); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_samplerate")] - internal static extern int SetAudioSampleRate(IntPtr handle, int sampleRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_samplerate")] - internal static extern int GetAudioSampleRate(IntPtr handle, out int sampleRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_encoder_bitrate")] - internal static extern int SetAudioEncoderBitrate(IntPtr handle, int bitRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_encoder_bitrate")] - internal static extern int GetAudioEncoderBitrate(IntPtr handle, out int bitRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_video_encoder_bitrate")] - internal static extern int SetVideoEncoderBitrate(IntPtr handle, int bitRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_video_encoder_bitrate")] - internal static extern int GetVideoEncoderBitrate(IntPtr handle, out int bitRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_mute")] - internal static extern int SetMute(IntPtr handle, bool enable); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_is_muted")] - [return: MarshalAs(UnmanagedType.I1)] - internal static extern bool GetMute(IntPtr handle); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_recording_motion_rate")] - internal static extern int SetMotionRate(IntPtr handle, double motionRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_recording_motion_rate")] - internal static extern int GetMotionRate(IntPtr handle, out double motionRate); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_channel")] - internal static extern int SetAudioChannel(IntPtr handle, int channelCount); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_channel")] - internal static extern int GetAudioChannel(IntPtr handle, out int channelCount); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_orientation_tag")] - internal static extern int SetOrientationTag(IntPtr handle, int orientation); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_orientation_tag")] - internal static extern int GetOrientationTag(IntPtr handle, out int orientation); - } -} diff --git a/src/Tizen.Multimedia/Interop/Interop.RecorderCapability.cs b/src/Tizen.Multimedia/Interop/Interop.RecorderCapability.cs deleted file mode 100644 index 7c2d834..0000000 --- a/src/Tizen.Multimedia/Interop/Interop.RecorderCapability.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using Tizen.Multimedia; - -internal static partial class Interop -{ - internal static partial class RecorderCapablity - { - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate bool VideoResolutionCallback(int width, int height, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate bool FileFormatCallback(RecorderFileFormat format, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate bool AudioEncoderCallback(RecorderAudioCodec codec, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate bool VideoEncoderCallback(RecorderVideoCodec codec, IntPtr userData); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_file_format")] - internal static extern int FileFormats(IntPtr handle, FileFormatCallback callback, IntPtr userData); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_audio_encoder")] - internal static extern int AudioEncoders(IntPtr handle, AudioEncoderCallback callback, IntPtr userData); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_video_encoder")] - internal static extern int VideoEncoders(IntPtr handle, VideoEncoderCallback callback, IntPtr userData); - - [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_video_resolution")] - internal static extern int VideoResolution(IntPtr handle, VideoResolutionCallback callback, IntPtr userData); - } -} diff --git a/src/Tizen.Multimedia/Interop/Interop.RecorderFeatures.cs b/src/Tizen.Multimedia/Interop/Interop.RecorderFeatures.cs new file mode 100755 index 0000000..5899e1c --- /dev/null +++ b/src/Tizen.Multimedia/Interop/Interop.RecorderFeatures.cs @@ -0,0 +1,33 @@ +using System; +using System.Runtime.InteropServices; +using Tizen.Multimedia; + +internal static partial class Interop +{ + internal static partial class RecorderFeatures + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool VideoResolutionCallback(int width, int height, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool FileFormatCallback(RecorderFileFormat format, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool AudioEncoderCallback(RecorderAudioCodec codec, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool VideoEncoderCallback(RecorderVideoCodec codec, IntPtr userData); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_file_format")] + internal static extern int FileFormats(IntPtr handle, FileFormatCallback callback, IntPtr userData); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_audio_encoder")] + internal static extern int AudioEncoders(IntPtr handle, AudioEncoderCallback callback, IntPtr userData); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_video_encoder")] + internal static extern int VideoEncoders(IntPtr handle, VideoEncoderCallback callback, IntPtr userData); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_foreach_supported_video_resolution")] + internal static extern int VideoResolution(IntPtr handle, VideoResolutionCallback callback, IntPtr userData); + } +} diff --git a/src/Tizen.Multimedia/Interop/Interop.RecorderSettings.cs b/src/Tizen.Multimedia/Interop/Interop.RecorderSettings.cs new file mode 100755 index 0000000..46c822b --- /dev/null +++ b/src/Tizen.Multimedia/Interop/Interop.RecorderSettings.cs @@ -0,0 +1,103 @@ +using System; +using System.Runtime.InteropServices; +using Tizen.Multimedia; + +internal static partial class Interop +{ + internal static partial class RecorderSettings + { + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_channel")] + internal static extern int GetAudioChannel(IntPtr handle, out int channelCount); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_channel")] + internal static extern int SetAudioChannel(IntPtr handle, int channelCount); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_device")] + internal static extern int GetAudioDevice(IntPtr handle, out RecorderAudioDevice device); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_device")] + internal static extern int SetAudioDevice(IntPtr handle, RecorderAudioDevice device); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_audio_level")] + internal static extern int GetAudioLevel(IntPtr handle, out double dB); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_samplerate")] + internal static extern int GetAudioSampleRate(IntPtr handle, out int sampleRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_samplerate")] + internal static extern int SetAudioSampleRate(IntPtr handle, int sampleRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_audio_encoder_bitrate")] + internal static extern int GetAudioEncoderBitrate(IntPtr handle, out int bitRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_audio_encoder_bitrate")] + internal static extern int SetAudioEncoderBitrate(IntPtr handle, int bitRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_video_encoder_bitrate")] + internal static extern int GetVideoEncoderBitrate(IntPtr handle, out int bitRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_video_encoder_bitrate")] + internal static extern int SetVideoEncoderBitrate(IntPtr handle, int bitRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_audio_encoder")] + internal static extern int GetAudioEncoder(IntPtr handle, out RecorderAudioCodec codec); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_audio_encoder")] + internal static extern int SetAudioEncoder(IntPtr handle, RecorderAudioCodec codec); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_video_encoder")] + internal static extern int GetVideoEncoder(IntPtr handle, out RecorderVideoCodec codec); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_video_encoder")] + internal static extern int SetVideoEncoder(IntPtr handle, RecorderVideoCodec codec); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_file_format")] + internal static extern int GetFileFormat(IntPtr handle, out RecorderFileFormat format); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_file_format")] + internal static extern int SetFileFormat(IntPtr handle, RecorderFileFormat format); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_filename")] + internal static extern int GetFileName(IntPtr handle, out IntPtr path); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_filename")] + internal static extern int SetFileName(IntPtr handle, string path); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_size_limit")] + internal static extern int GetSizeLimit(IntPtr handle, out int kbyte); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_size_limit")] + internal static extern int SetSizeLimit(IntPtr handle, int kbyte); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_time_limit")] + internal static extern int GetTimeLimit(IntPtr handle, out int second); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_time_limit")] + internal static extern int SetTimeLimit(IntPtr handle, int second); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_is_muted")] + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool GetMute(IntPtr handle); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_mute")] + internal static extern int SetMute(IntPtr handle, bool enable); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_recording_motion_rate")] + internal static extern int GetMotionRate(IntPtr handle, out double motionRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_recording_motion_rate")] + internal static extern int SetMotionRate(IntPtr handle, double motionRate); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_get_orientation_tag")] + internal static extern int GetOrientationTag(IntPtr handle, out RecorderOrientation orientation); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_attr_set_orientation_tag")] + internal static extern int SetOrientationTag(IntPtr handle, RecorderOrientation orientation); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_get_video_resolution")] + internal static extern int GetVideoResolution(IntPtr handle, out int width, out int height); + + [DllImport(Libraries.Recorder, EntryPoint = "recorder_set_video_resolution")] + internal static extern int SetVideoResolution(IntPtr handle, int width, int height); + } +} diff --git a/src/Tizen.Multimedia/Recorder/AudioStreamDeliveredEventArgs.cs b/src/Tizen.Multimedia/Recorder/AudioStreamDeliveredEventArgs.cs old mode 100644 new mode 100755 index 73580e9..2fb736f --- a/src/Tizen.Multimedia/Recorder/AudioStreamDeliveredEventArgs.cs +++ b/src/Tizen.Multimedia/Recorder/AudioStreamDeliveredEventArgs.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -15,6 +15,7 @@ */ using System; +using System.Runtime.InteropServices; namespace Tizen.Multimedia { @@ -23,53 +24,33 @@ namespace Tizen.Multimedia /// public class AudioStreamDeliveredEventArgs : EventArgs { - private byte[] _stream = null; - private AudioSampleType _type = AudioSampleType.S16Le; - private int _channel = 0; - private uint _recordingTime = 0; - - internal AudioStreamDeliveredEventArgs(byte[] stream, AudioSampleType type, int channel, uint recordingTime) + internal AudioStreamDeliveredEventArgs(IntPtr stream, int streamSize, AudioSampleType type, int channel, uint recordingTime) { - _stream = stream; - _type = type; - _channel = channel; - _recordingTime = recordingTime; + Stream = new byte[streamSize]; + Marshal.Copy(stream, Stream, 0, streamSize); + Type = type; + Channel = channel; + RecordingTime = recordingTime; } /// /// The audio stream data. /// - public byte[] Stream { - get { - return _stream; - } - } + public byte[] Stream { get; } /// /// The audio format type. /// - public AudioSampleType Type { - get { - return _type; - } - } + public AudioSampleType Type { get; } /// /// The number of channels. /// - public int Channel { - get { - return _channel; - } - } + public int Channel { get; } /// /// The recording time of the stream buffer in milliseconds. /// - public uint RecordingTime { - get { - return _recordingTime; - } - } + public uint RecordingTime { get; } } } diff --git a/src/Tizen.Multimedia/Recorder/Recorder.cs b/src/Tizen.Multimedia/Recorder/Recorder.cs index 041ada2..d3314c8 100755 --- a/src/Tizen.Multimedia/Recorder/Recorder.cs +++ b/src/Tizen.Multimedia/Recorder/Recorder.cs @@ -16,62 +16,43 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Runtime.InteropServices; using Tizen.Internals.Errors; namespace Tizen.Multimedia { - static internal class RecorderLog - { - internal const string Tag = "Tizen.Multimedia.Recorder"; - } + static internal class RecorderLog + { + internal const string Tag = "Tizen.Multimedia.Recorder"; + } /// /// The recorder class provides methods to create audio/video recorder, - /// to start, stop and save the recorded content. It also provides methods - /// to get/set various attributes and capabilities of recorder. + /// to start, stop and save the recorded content. It also provides methods + /// to get/set various attributes and capabilities of recorder. /// - /// - /// http://tizen.org/privilege/recorder - /// - public class Recorder : IDisposable - { - private IntPtr _handle; + /// + /// http://tizen.org/privilege/recorder + /// + public class Recorder : IDisposable + { + private IntPtr _handle = IntPtr.Zero; private bool _disposed = false; - private EventHandler _recorderStateChanged; - private Interop.Recorder.StatechangedCallback _recorderStateChangedCallback; - private EventHandler _recordingStatusChanged; - private Interop.Recorder.RecordingStatusCallback _recordingStatusCallback; - private EventHandler _recordingLimitReached; - private Interop.Recorder.RecordingLimitReachedCallback _recordingLimitReachedCallback; - private EventHandler _audioStreamDelivered; - private Interop.Recorder.AudioStreamCallback _audioStreamCallback; - private EventHandler _recorderInterrupted; - private Interop.Recorder.InterruptedCallback _interruptedCallback; - private EventHandler _recordingErrorOccured; - private Interop.Recorder.RecorderErrorCallback _recorderErrorCallback; - private List _formats; - private List _audioCodec; - private List _videoCodec; - private List _resolutions; - RecorderVideoResolution _videoResolution = null; + private RecorderState _state = RecorderState.None; /// /// Audio recorder constructor. /// - public Recorder() - { - int ret = Interop.Recorder.Create (out _handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to create Audio recorder"); - } - _formats = new List(); - _audioCodec = new List(); - _videoCodec = new List (); - _resolutions = new List (); - _videoResolution = new RecorderVideoResolution (_handle); - } + public Recorder() + { + RecorderErrorFactory.ThrowIfError (Interop.Recorder.Create(out _handle), + "Failed to create Audio recorder"); + + Feature = new RecorderFeatures(this); + Setting = new RecorderSettings(this); + } /// /// Video recorder constructor. @@ -81,16 +62,11 @@ namespace Tizen.Multimedia /// public Recorder(Camera camera) { - int ret = Interop.Recorder.CreateVideo (camera.GetHandle(), out _handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to create Video recorder"); - } - _formats = new List(); - _audioCodec = new List(); - _videoCodec = new List (); - _resolutions = new List (); - _videoResolution = new RecorderVideoResolution (_handle); + RecorderErrorFactory.ThrowIfError(Interop.Recorder.CreateVideo(camera.GetHandle(), out _handle), + "Failed to create Video recorder."); + + Feature = new RecorderFeatures(this); + Setting = new RecorderSettings(this); } /// @@ -98,1003 +74,306 @@ namespace Tizen.Multimedia /// ~Recorder() { - Dispose (false); + Dispose (false); } - /// - /// Event that occurs when recorder is interrupted. - /// - public event EventHandler RecorderInterrupted - { - add - { - if (_recorderInterrupted == null) - { - RegisterRecorderInterruptedEvent(); - } - _recorderInterrupted += value; - } - remove - { - _recorderInterrupted -= value; - if (_recorderInterrupted == null) - { - UnregisterRecorderInterruptedEvent (); - } - } - } - - /// - /// Event that occurs when audio stream data is being delivered. - /// - public event EventHandler AudioStreamDelivered - { - add - { - if (_audioStreamDelivered == null) - { - RegisterAudioStreamDeliveredEvent(); - } - _audioStreamDelivered += value; - } - remove - { - _audioStreamDelivered -= value; - if (_audioStreamDelivered == null) - { - UnregisterAudioStreamDeliveredEvent (); - } - } - } - - /// - /// This event occurs when recorder state is changed. - /// - public event EventHandler RecorderStateChanged - { - add - { - if (_recorderStateChanged == null) - { - RegisterStateChangedEvent(); - } - _recorderStateChanged += value; - } - remove - { - _recorderStateChanged -= value; - if (_recorderStateChanged == null) - { - UnregisterStateChangedEvent (); - } - } - } - - /// - /// Event that occurs when recording information changes. - /// - public event EventHandler RecordingStatusChanged - { - add - { - if (_recordingStatusChanged == null) - { - RegisterRecordingStatusChangedEvent(); - } - _recordingStatusChanged += value; - } - remove - { - _recordingStatusChanged -= value; - if (_recordingStatusChanged == null) - { - UnregisterRecordingStatusChangedEvent (); - } - } - } - - /// - /// Event that occurs when recording limit is reached. - /// - public event EventHandler RecordingLimitReached - { - add - { - if (_recordingLimitReached == null) - { - RegisterRecordingLimitReachedEvent(); - } - _recordingLimitReached += value; - } - remove - { - _recordingLimitReached -= value; - if (_recordingLimitReached == null) - { - UnregisterRecordingLimitReachedEvent (); - } - } - } - - /// - /// Event that occurs when an error occurs during recorder operation. - /// - public event EventHandler RecordingErrorOccurred - { - add - { - if (_recordingErrorOccured == null) - { - RegisterRecordingErrorOccuredEvent(); - } - _recordingErrorOccured += value; - } - remove - { - _recordingErrorOccured -= value; - if (_recordingErrorOccured == null) - { - UnregisterRecordingErrorOccuredEvent (); - } - } - } - - /// - /// The file path to record. - /// - /// - /// If the same file already exists in the file system, then old file - /// will be overwritten. - /// - public string FilePath + internal IntPtr GetHandle() { - get - { - IntPtr val; - int ret = Interop.Recorder.GetFileName (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get filepath, " + (RecorderError)ret); - } - string result = Marshal.PtrToStringAnsi (val); - Interop.Libc.Free (val); - return result; - } - set - { - int ret = Interop.Recorder.SetFileName (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set filepath, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set filepath"); - } - } + ValidateNotDisposed(); + return _handle; } +#region Dispose support /// - /// Get the peak audio input level in dB + /// Release any unmanaged resources used by this object. /// - /// - /// 0dB indicates maximum input level, -300dB indicates minimum input level. - /// - public double AudioLevel + public void Dispose() { - get - { - double level = 0; - - int ret = Interop.Recorder.GetAudioLevel (_handle, out level); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get Audio level, " + (RecorderError)ret); - } - return level; - } + Dispose(true); + GC.SuppressFinalize(this); } - /// - /// The current state of the recorder. - /// - public RecorderState State + protected virtual void Dispose(bool disposing) { - get + if (!_disposed) { - int val = 0; - - int ret = Interop.Recorder.GetState (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get recorder state, " + (RecorderError)ret); - } - return (RecorderState)val; + if (disposing) + { + // to be used if there are any other disposable objects + } + if (_handle != IntPtr.Zero) + { + Interop.Recorder.Destroy(_handle); + _handle = IntPtr.Zero; + } + _disposed = true; } } - /// - /// The file format for recording media stream. - /// - public RecorderFileFormat FileFormat + internal void ValidateNotDisposed() { - get + if (_disposed) { - int val = 0; - - int ret = Interop.Recorder.GetFileFormat (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get file format, " + (RecorderError)ret); - } - return (RecorderFileFormat)val; - } - set - { - int ret = Interop.Recorder.SetFileFormat (_handle, (int)value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set file format, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret); - } + throw new ObjectDisposedException(nameof(Recorder)); } } +#endregion Dispose support - /// - /// The audio codec for encoding an audio stream. - /// - public RecorderAudioCodec AudioCodec +#region Check recorder state + internal void ValidateState(params RecorderState[] required) { - get - { - int val = 0; + ValidateNotDisposed(); - int ret = Interop.Recorder.GetAudioEncoder (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get audio codec, " + (RecorderError)ret); - } - return (RecorderAudioCodec)val; - } - set + Debug.Assert(required.Length > 0); + + var curState = _state; + if (!required.Contains(curState)) { - int ret = Interop.Recorder.SetAudioEncoder (_handle, (int)value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set audio codec, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret); - } + throw new InvalidOperationException($"The recorder is not in a valid state. " + + $"Current State : { curState }, Valid State : { string.Join(", ", required) }."); } } - /// - /// The video codec for encoding video stream. - /// - public RecorderVideoCodec VideoCodec + internal void SetState(RecorderState state) { - get - { - int val = 0; - - int ret = Interop.Recorder.GetVideoEncoder (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error( RecorderLog.Tag, "Failed to get video codec, " + (RecorderError)ret); - } - return (RecorderVideoCodec)val; - } - set - { - int ret = Interop.Recorder.SetVideoEncoder (_handle, (int)value); - - if ((RecorderError)ret != RecorderError.None) - { - Log.Error(RecorderLog.Tag, "Failed to set video codec, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException(ret); - } - } + _state = state; } +#endregion Check recorder state - /// - /// The maximum size of a recording file in KB(kilobytes). If 0, means - /// unlimited recording size. - /// - /// - /// After reaching the limitation, the data which is being recorded will - /// be discarded and not written to the file. - /// The recorder state must be in 'Ready' or 'Created' state. - /// - /// - public int SizeLimit - { - get - { - int val = 0; - - int ret = Interop.RecorderAttribute.GetSizeLimit (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get sizelimit, " + (RecorderError)ret); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetSizeLimit (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set sizelimit, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set sizelimit"); - } - } - } - - /// - /// The time limit of a recording file in Seconds. If 0, means unlimited recording - /// time. - /// - /// - /// After reaching the limitation, the data which is being recorded will - /// be discarded and not written to the file. - /// The recorder state must be in 'Ready' or 'Created' state. - /// - public int TimeLimit - { - get - { - int val = 0; - - int ret = Interop.RecorderAttribute.GetTimeLimit (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get timelimit, " + (RecorderError)ret); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetTimeLimit (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set timelimit, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set timelimit"); - } - } - } - - /// - /// The sampling rate of an audio stream in hertz. - /// - public int AudioSampleRate - { - get - { - int val = 0; - - int ret = Interop.RecorderAttribute.GetAudioSampleRate (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get audio samplerate, " + (RecorderError)ret); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetAudioSampleRate (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set audio samplerate, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set audio samplerate"); - } - } - } - - /// - /// The bitrate of an audio encoder in bits per second. - /// - public int AudioBitRate - { - get - { - int val = 0; - - int ret = Interop.RecorderAttribute.GetAudioEncoderBitrate (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get audio bitrate, " + (RecorderError)ret); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetAudioEncoderBitrate (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set audio bitrate, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set audio bitrate"); - } - } - } - - /// - /// The bitrate of an video encoder in bits per second. - /// - public int VideoBitRate - { - get - { - int val = 0; - - int ret = Interop.RecorderAttribute.GetVideoEncoderBitrate (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get video bitrate, " + (RecorderError)ret); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetVideoEncoderBitrate (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set video bitrate, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set video bitrate"); - } - } - } - - /// - /// The mute state of a recorder. - /// - public bool Mute - { - get - { - bool val; - - val = Interop.RecorderAttribute.GetMute (_handle); - int ret = ErrorFacts.GetLastResult (); - if ((RecorderError)ret != RecorderError.None) - { - RecorderError err; - err = (RecorderError) ret; - Log.Error (RecorderLog.Tag, "Failed to get the mute state of recorder, return " + err.ToString()); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetMute (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set mute, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set mute"); - } - } - } - - /// - /// The video recording motion rate - /// - /// - /// The attribute is valid only in a video recorder. - /// If the rate is in range of 0-1, video is recorded in a slow motion mode. - /// If the rate is bigger than 1, video is recorded in a fast motion mode. - /// - public double MotionRate - { - get - { - double val = 0.0; +#region EventHandlers + /// + /// Event that occurs when an error occurs during recorder operation. + /// + public event EventHandler ErrorOccurred; + private Interop.Recorder.RecorderErrorCallback _errorOccuredCallback; - int ret = Interop.RecorderAttribute.GetMotionRate (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get video motionrate, " + (RecorderError)ret); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetMotionRate (_handle, (double)value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set video motionrate, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set video motionrate"); - } - } - } + /// + /// Event that occurs when recorder is interrupted. + /// + public event EventHandler Interrupted; + private Interop.Recorder.InterruptedCallback _interruptedCallback; - /// - /// The number of audio channel. - /// - /// - /// The attribute is applied only in Created state. - /// For mono recording, set channel to 1. - /// For stereo recording, set channel to 2. - /// - public int AudioChannel - { - get - { - int val = 0; + /// + /// This event occurs when recorder state is changed. + /// + public event EventHandler StateChanged; + private Interop.Recorder.StatechangedCallback _stateChangedCallback; - int ret = Interop.RecorderAttribute.GetAudioChannel (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get audio channel, " + (RecorderError)ret); - } - return val; - } - set - { - int ret = Interop.RecorderAttribute.SetAudioChannel (_handle, value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set audio channel, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set audio channel"); - } - } - } + /// + /// Event that occurs when recording information changes. + /// + public event EventHandler RecordingProgress; + private Interop.Recorder.RecordingProgressCallback _recordingProgressCallback; - /// - /// The audio device for recording. - /// - public RecorderAudioDevice AudioDevice - { - get - { - int val = 0; + /// + /// Event that occurs when audio stream data is being delivered. + /// + public event EventHandler AudioStreamDelivered; + private Interop.Recorder.AudioStreamCallback _audioStreamCallback; - int ret = Interop.RecorderAttribute.GetAudioDevice (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get audio device, " + (RecorderError)ret); - } - return (RecorderAudioDevice)val; - } - set - { - int ret = Interop.RecorderAttribute.SetAudioDevice (_handle, (int)value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set audio device, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set audio device"); - } - } - } + /// + /// Event that occurs when recording limit is reached. + /// + public event EventHandler RecordingLimitReached; + private Interop.Recorder.RecordingLimitReachedCallback _recordingLimitReachedCallback; +#endregion EventHandlers - /// - /// The orientation in a video metadata tag. - /// - public RecorderOrientation OrientationTag - { - get - { - int val = 0; +#region Properties + /// + /// Gets the various recorder features. + /// + public RecorderFeatures Feature { get; } - int ret = Interop.RecorderAttribute.GetOrientationTag (_handle, out val); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to get recorder orientation, " + (RecorderError)ret); - } - return (RecorderOrientation)val; - } - set - { - int ret = Interop.RecorderAttribute.SetOrientationTag (_handle, (int)value); - if ((RecorderError)ret != RecorderError.None) - { - Log.Error (RecorderLog.Tag, "Failed to set recorder orientation, " + (RecorderError)ret); - RecorderErrorFactory.ThrowException (ret, "Failed to set audio orientation"); - } - } - } + /// + /// Get/Set the various recorder settings. + /// + public RecorderSettings Setting { get; } /// - /// Video resolution of the video recording. + /// The current state of the recorder. /// - public RecorderVideoResolution Resolution + public RecorderState State { get { - return _videoResolution; - } - } - - /// - /// Retrieves all the file formats supported by the recorder. - /// - /// - /// It returns a list containing all the supported file - /// formats by recorder. - /// - public IEnumerable SupportedFileFormats - { - get - { - if (_formats.Count == 0) - { - Interop.RecorderCapablity.FileFormatCallback callback = (RecorderFileFormat format, IntPtr userData) => - { - _formats.Add (format); - return true; - }; - int ret = Interop.RecorderCapablity.FileFormats (_handle, callback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to get the supported fileformats"); - } - } - return _formats; - } - } - - /// - /// Retrieves all the audio encoders supported by the recorder. - /// - /// - /// It returns a list containing all the supported audio encoders - /// by recorder. - /// - public IEnumerable SupportedAudioEncodings - { - get - { - if (_audioCodec.Count == 0) - { - Interop.RecorderCapablity.AudioEncoderCallback callback = (RecorderAudioCodec codec, IntPtr userData) => - { - _audioCodec.Add(codec); - return true; - }; - int ret = Interop.RecorderCapablity.AudioEncoders (_handle, callback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to get the supported audio encoders"); - } - } - return _audioCodec; - } - } - - /// - /// Retrieves all the video encoders supported by the recorder. - /// - /// - /// It returns a list containing all the supported video encoders - /// by recorder. - /// - public IEnumerable SupportedVideoEncodings - { - get - { - if (_videoCodec.Count == 0) - { - Interop.RecorderCapablity.VideoEncoderCallback callback = (RecorderVideoCodec codec, IntPtr userData) => - { - _videoCodec.Add(codec); - return true; - }; - int ret = Interop.RecorderCapablity.VideoEncoders (_handle, callback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to get the supported video encoders"); - } - } - return _videoCodec; - } - } - - /// - /// Retrieves all the video resolutions supported by the recorder. - /// - /// - /// It returns videoresolution list containing the width and height of - /// different resolutions supported by recorder. - /// - public IEnumerable SupportedVideoResolutions - { - get - { - if (_resolutions.Count == 0) - { - Interop.RecorderCapablity.VideoResolutionCallback callback = (int width, int height, IntPtr userData) => - { - RecorderVideoResolution temp = new RecorderVideoResolution(width, height); - _resolutions.Add(temp); - return true; - }; - int ret = Interop.RecorderCapablity.VideoResolution (_handle, callback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to get the supported video resolutions"); - } - } - return _resolutions; - } - } - - /// - /// Prepare the media recorder for recording. - /// - /// - /// Before calling the function, it is required to set AudioEncoder, - /// videoencoder and fileformat properties of recorder. - /// - /// - /// http://tizen.org/privilege/recorder - /// - public void Prepare() - { - int ret = Interop.Recorder.Prepare (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to prepare media recorder for recording"); - } - } - - /// - /// Resets the media recorder. - /// - /// - /// http://tizen.org/privilege/recorder - /// - public void Unprepare() - { - int ret = Interop.Recorder.Unprepare (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to reset the media recorder"); - } - } - - /// - /// Starts the recording. - /// - /// - /// If file path has been set to an existing file, this file is removed automatically and updated by new one. - /// In the video recorder, some preview format does not support record mode. It will return InvalidOperation error. - /// You should use default preview format or CameraPixelFormatNv12 in the record mode. - /// The filename should be set before this function is invoked. - /// - /// - /// http://tizen.org/privilege/recorder - /// - public void Start() - { - int ret = Interop.Recorder.Start (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to start the media recorder"); - } - } - - /// - /// Pause the recording. - /// - /// - /// Recording can be resumed with Start(). - /// - /// - /// http://tizen.org/privilege/recorder - /// - public void Pause() - { - int ret = Interop.Recorder.Pause (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to pause the media recorder"); - } - } - - /// - /// Stops recording and saves the result. - /// - /// - /// http://tizen.org/privilege/recorder - /// - public void Commit() - { - int ret = Interop.Recorder.Commit (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to save the recorded content"); - } - } - - /// - /// Cancels the recording. - /// The recording data is discarded and not written in the recording file. - /// - /// - /// http://tizen.org/privilege/recorder - /// - public void Cancel() - { - int ret = Interop.Recorder.Cancel (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to cancel the recording"); - } - } + RecorderState val = 0; - /// - /// Sets the audio stream policy. - /// - /// Policy. - public void SetAudioStreamPolicy(AudioStreamPolicy policy) - { - int ret = Interop.Recorder.SetAudioStreamPolicy (_handle, policy.Handle); + RecorderErrorFactory.ThrowIfError(Interop.Recorder.GetState(_handle, out val), + "Failed to get recorder state."); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Failed to set audio stream policy"); - } - } + return val; + } + } +#endregion Properties - /// - /// Release any unmanaged resources used by this object. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } +#region Methods + /// + /// Prepare the media recorder for recording. + /// + /// + /// Before calling the function, it is required to set AudioEncoder, + /// videoencoder and fileformat properties of recorder. + /// + /// + /// http://tizen.org/privilege/recorder + /// + public void Prepare() + { + RecorderErrorFactory.ThrowIfError(Interop.Recorder.Prepare(_handle), + "Failed to prepare media recorder for recording"); + } - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - // to be used if there are any other disposable objects - } - if (_handle != IntPtr.Zero) - { - Interop.Recorder.Destroy (_handle); - _handle = IntPtr.Zero; - } - _disposed = true; - } - } + /// + /// Resets the media recorder. + /// + /// + /// http://tizen.org/privilege/recorder + /// + public void Unprepare() + { + RecorderErrorFactory.ThrowIfError(Interop.Recorder.Unprepare(_handle), + "Failed to reset the media recorder"); + } - private void RegisterRecorderInterruptedEvent() - { - _interruptedCallback = (RecorderPolicy policy, RecorderState previous, RecorderState current, IntPtr userData) => - { - RecorderInterruptedEventArgs eventArgs = new RecorderInterruptedEventArgs(policy, previous, current); - _recorderInterrupted?.Invoke(this, eventArgs); - }; - int ret = Interop.Recorder.SetInterruptedCallback (_handle, _interruptedCallback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Setting Interrupted callback failed"); - } - } + /// + /// Starts the recording. + /// + /// + /// If file path has been set to an existing file, this file is removed automatically and updated by new one. + /// In the video recorder, some preview format does not support record mode. It will return InvalidOperation error. + /// You should use default preview format or CameraPixelFormatNv12 in the record mode. + /// The filename should be set before this function is invoked. + /// + /// + /// http://tizen.org/privilege/recorder + /// + public void Start() + { + RecorderErrorFactory.ThrowIfError(Interop.Recorder.Start(_handle), + "Failed to start the media recorder"); + } - private void UnregisterRecorderInterruptedEvent() - { - int ret = Interop.Recorder.UnsetInterruptedCallback (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Unsetting Interrupted callback failed"); - } - } + /// + /// Pause the recording. + /// + /// + /// Recording can be resumed with Start(). + /// + /// + /// http://tizen.org/privilege/recorder + /// + public void Pause() + { + RecorderErrorFactory.ThrowIfError(Interop.Recorder.Pause(_handle), + "Failed to pause the media recorder"); + } - private void RegisterAudioStreamDeliveredEvent() - { - _audioStreamCallback = (IntPtr stream, int size, AudioSampleType type, int channel, uint recordingTime, IntPtr userData) => - { - byte[] streamArray = new byte[size]; - Marshal.Copy(stream, streamArray, 0, size); - AudioStreamDeliveredEventArgs eventArgs = new AudioStreamDeliveredEventArgs(streamArray, type, channel, recordingTime); - _audioStreamDelivered?.Invoke(this, eventArgs); - }; - int ret = Interop.Recorder.SetAudioStreamCallback (_handle, _audioStreamCallback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Setting audiostream callback failed"); - } - } + /// + /// Stops recording and saves the result. + /// + /// + /// http://tizen.org/privilege/recorder + /// + public void Commit() + { + RecorderErrorFactory.ThrowIfError(Interop.Recorder.Commit(_handle), + "Failed to save the recorded content"); + } - private void UnregisterAudioStreamDeliveredEvent() - { - int ret = Interop.Recorder.UnsetAudioStreamCallback (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Unsetting audiostream callback failed"); - } - } + /// + /// Cancels the recording. + /// The recording data is discarded and not written in the recording file. + /// + /// + /// http://tizen.org/privilege/recorder + /// + public void Cancel() + { + RecorderErrorFactory.ThrowIfError(Interop.Recorder.Cancel(_handle), + "Failed to cancel the recording"); + } - private void RegisterStateChangedEvent() - { - _recorderStateChangedCallback = (RecorderState previous, RecorderState current, bool byPolicy, IntPtr userData) => - { - RecorderStateChangedEventArgs eventArgs = new RecorderStateChangedEventArgs(previous, current, byPolicy); - _recorderStateChanged?.Invoke(this, eventArgs); - }; - int ret = Interop.Recorder.SetStateChangedCallback (_handle, _recorderStateChangedCallback , IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Setting state changed callback failed"); - } - } + /// + /// Sets the audio stream policy. + /// + /// Policy. + public void SetAudioStreamPolicy(AudioStreamPolicy policy) + { + RecorderErrorFactory.ThrowIfError(Interop.Recorder.SetAudioStreamPolicy(_handle, policy.Handle), + "Failed to set audio stream policy"); + } +#endregion Methods - private void UnregisterStateChangedEvent() - { - int ret = Interop.Recorder.UnsetStateChangedCallback (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Unsetting state changed callback failed"); - } - } +#region Callback registrations + private void RegisterCallbacks() + { + RegisterErrorCallback(); + RegisterInterruptedCallback(); + RegisterStateChangedCallback(); + RegisterRecordingProgressCallback(); + RegisterAudioStreamDeliveredCallback(); + RegisterRecordingLimitReachedEvent(); + } - private void RegisterRecordingStatusChangedEvent() - { - _recordingStatusCallback = (ulong elapsedTime, ulong fileSize, IntPtr userData) => - { - RecordingStatusChangedEventArgs eventArgs = new RecordingStatusChangedEventArgs(elapsedTime, fileSize); - _recordingStatusChanged?.Invoke(this, eventArgs); - }; - int ret = Interop.Recorder.SetStatusChangedCallback (_handle, _recordingStatusCallback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Setting status changed callback failed"); - } - } + private void RegisterErrorCallback() + { + _errorOccuredCallback = (RecorderErrorCode error, RecorderState current, IntPtr userData) => + { + ErrorOccurred?.Invoke(this, new RecordingErrorOccurredEventArgs(error, current)); + }; + RecorderErrorFactory.ThrowIfError(Interop.Recorder.SetErrorCallback(_handle, _errorOccuredCallback, IntPtr.Zero), + "Setting Error callback failed"); + } - private void UnregisterRecordingStatusChangedEvent() - { - int ret = Interop.Recorder.UnsetStatusChangedCallback (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Unsetting status changed callback failed"); - } - } + private void RegisterInterruptedCallback() + { + _interruptedCallback = (RecorderPolicy policy, RecorderState previous, RecorderState current, IntPtr userData) => + { + Interrupted?.Invoke(this, new RecorderInterruptedEventArgs(policy, previous, current)); + }; + RecorderErrorFactory.ThrowIfError(Interop.Recorder.SetInterruptedCallback(_handle, _interruptedCallback, IntPtr.Zero), + "Setting Interrupted callback failed"); + } - private void RegisterRecordingLimitReachedEvent() - { - _recordingLimitReachedCallback = (RecordingLimitType type, IntPtr userData) => - { - RecordingLimitReachedEventArgs eventArgs = new RecordingLimitReachedEventArgs(type); - _recordingLimitReached?.Invoke(this, eventArgs); - }; - int ret = Interop.Recorder.SetLimitReachedCallback (_handle, _recordingLimitReachedCallback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Setting limit reached callback failed"); - } - } + private void RegisterStateChangedCallback() + { + _stateChangedCallback = (RecorderState previous, RecorderState current, bool byPolicy, IntPtr userData) => + { + StateChanged?.Invoke(this, new RecorderStateChangedEventArgs(previous, current, byPolicy)); + }; + RecorderErrorFactory.ThrowIfError(Interop.Recorder.SetStateChangedCallback(_handle, _stateChangedCallback, IntPtr.Zero), + "Setting state changed callback failed"); + } - private void UnregisterRecordingLimitReachedEvent() - { - int ret = Interop.Recorder.UnsetLimitReachedCallback (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException(ret, "Unsetting limit reached callback failed"); - } - } + private void RegisterRecordingProgressCallback() + { + _recordingProgressCallback = (ulong elapsedTime, ulong fileSize, IntPtr userData) => + { + RecordingProgress?.Invoke(this, new RecordingProgressEventArgs(elapsedTime, fileSize)); + }; + RecorderErrorFactory.ThrowIfError(Interop.Recorder.SetRecordingProgressCallback(_handle, _recordingProgressCallback, IntPtr.Zero), + "Setting status changed callback failed"); + } - private void RegisterRecordingErrorOccuredEvent() - { - _recorderErrorCallback = (RecorderErrorCode error, RecorderState current, IntPtr userData) => - { - RecordingErrorOccurredEventArgs eventArgs = new RecordingErrorOccurredEventArgs(error, current); - _recordingErrorOccured?.Invoke(this, eventArgs); - }; - int ret = Interop.Recorder.SetErrorCallback (_handle, _recorderErrorCallback, IntPtr.Zero); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Setting Error callback failed"); - } - } + private void RegisterAudioStreamDeliveredCallback() + { + _audioStreamCallback = (IntPtr stream, int streamSize, AudioSampleType type, int channel, uint recordingTime, IntPtr userData) => + { + AudioStreamDelivered?.Invoke(this, new AudioStreamDeliveredEventArgs(stream, streamSize, type, channel, recordingTime)); + }; + RecorderErrorFactory.ThrowIfError(Interop.Recorder.SetAudioStreamCallback(_handle, _audioStreamCallback, IntPtr.Zero), + "Setting audiostream callback failed"); + } - private void UnregisterRecordingErrorOccuredEvent() - { - int ret = Interop.Recorder.UnsetErrorCallback (_handle); - if (ret != (int)RecorderError.None) - { - RecorderErrorFactory.ThrowException (ret, "Unsetting Error callback failed"); - } - } - } + private void RegisterRecordingLimitReachedEvent() + { + _recordingLimitReachedCallback = (RecordingLimitType type, IntPtr userData) => + { + RecordingLimitReached?.Invoke(this, new RecordingLimitReachedEventArgs(type)); + }; + RecorderErrorFactory.ThrowIfError(Interop.Recorder.SetLimitReachedCallback(_handle, _recordingLimitReachedCallback, IntPtr.Zero), + "Setting limit reached callback failed"); + } +#endregion Callback registrations + } } - diff --git a/src/Tizen.Multimedia/Recorder/RecorderEnums.cs b/src/Tizen.Multimedia/Recorder/RecorderEnums.cs index 6cbcb61..3adaeeb 100755 --- a/src/Tizen.Multimedia/Recorder/RecorderEnums.cs +++ b/src/Tizen.Multimedia/Recorder/RecorderEnums.cs @@ -219,7 +219,7 @@ namespace Tizen.Multimedia /// /// Device Error. /// - DeviceError = RecorderError.ErrorDevice, + DeviceError = RecorderError.DeviceError, /// /// Internal error. /// @@ -229,5 +229,4 @@ namespace Tizen.Multimedia /// OutOfMemory = RecorderError.OutOfMemory } -} - +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Recorder/RecorderErrorFactory.cs b/src/Tizen.Multimedia/Recorder/RecorderErrorFactory.cs index e497d4d..48605f2 100755 --- a/src/Tizen.Multimedia/Recorder/RecorderErrorFactory.cs +++ b/src/Tizen.Multimedia/Recorder/RecorderErrorFactory.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -21,49 +21,45 @@ namespace Tizen.Multimedia { internal enum RecorderError { - None = ErrorCode.None, - InvalidParameter = ErrorCode.InvalidParameter, TizenErrorRecorder = -0x01950000, RecorderErrorClass = TizenErrorRecorder | 0x10, + None = ErrorCode.None, + InvalidParameter = ErrorCode.InvalidParameter, InvalidState = RecorderErrorClass | 0x02, OutOfMemory = ErrorCode.OutOfMemory, - ErrorDevice = RecorderErrorClass | 0x04, + DeviceError = RecorderErrorClass | 0x04, InvalidOperation = ErrorCode.InvalidOperation, - SoundPolicy = RecorderErrorClass | 0x06, SecurityRestricted = RecorderErrorClass | 0x07, - SoundPolicyByCall = RecorderErrorClass | 0x08, - SoundPolicyByAlarm = RecorderErrorClass | 0x09, Esd = RecorderErrorClass | 0x0a, OutOfStorage = RecorderErrorClass | 0x0b, PermissionDenied = ErrorCode.PermissionDenied, NotSupported = ErrorCode.NotSupported, - ResourceConflict = RecorderErrorClass | 0x0c + ResourceConflict = RecorderErrorClass | 0x0c, + ServiceDisconnected = RecorderErrorClass | 0x0d } internal static class RecorderErrorFactory { - internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null) + internal static void ThrowIfError(int errorCode, string errorMessage = null) { RecorderError err = (RecorderError)errorCode; if(string.IsNullOrEmpty(errorMessage)) { errorMessage = err.ToString(); } - switch((RecorderError)errorCode) + Log.Info(RecorderLog.Tag, "errorCode : " + errorMessage); + + switch (err) { case RecorderError.InvalidParameter: - throw new ArgumentException(errorMessage, paramName); + throw new ArgumentException(errorMessage); case RecorderError.OutOfMemory: throw new OutOfMemoryException(errorMessage); - case RecorderError.ErrorDevice: - case RecorderError.SoundPolicy: - case RecorderError.SecurityRestricted: - case RecorderError.SoundPolicyByCall: - case RecorderError.SoundPolicyByAlarm: + case RecorderError.DeviceError: case RecorderError.Esd: - case RecorderError.OutOfStorage: + case RecorderError.SecurityRestricted: case RecorderError.PermissionDenied: throw new UnauthorizedAccessException(errorMessage); @@ -73,9 +69,13 @@ namespace Tizen.Multimedia case RecorderError.InvalidState: case RecorderError.InvalidOperation: case RecorderError.ResourceConflict: + case RecorderError.ServiceDisconnected: + case RecorderError.OutOfStorage: //TODO need to alloc new proper exception class throw new InvalidOperationException(errorMessage); + + default: + throw new Exception("Unknown error : " + errorCode.ToString()); } } } } - diff --git a/src/Tizen.Multimedia/Recorder/RecorderFeatures.cs b/src/Tizen.Multimedia/Recorder/RecorderFeatures.cs new file mode 100755 index 0000000..ee6a4e9 --- /dev/null +++ b/src/Tizen.Multimedia/Recorder/RecorderFeatures.cs @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Tizen.Multimedia +{ + /// + /// The camera setting class provides methods/properties to get and + /// set basic camera attributes. + /// + public class RecorderFeatures + { + internal readonly Recorder _recorder = null; + + private List _fileFormats; + private List _audioCodec; + private List _videoCodec; + private List _videoResolution; + + internal RecorderFeatures(Recorder recorder) + { + _recorder = recorder; + } + + /// + /// Retrieves all the file formats supported by the recorder. + /// + /// + /// It returns a list containing all the supported file + /// formats by recorder. + /// + public IEnumerable SupportedFileFormats + { + get + { + if (_fileFormats == null) + { + _fileFormats = new List(); + + Interop.RecorderFeatures.FileFormatCallback callback = (RecorderFileFormat format, IntPtr userData) => + { + _fileFormats.Add(format); + return true; + }; + RecorderErrorFactory.ThrowIfError(Interop.RecorderFeatures.FileFormats(_recorder.GetHandle(), callback, IntPtr.Zero), + "Failed to get the supported fileformats"); + } + + return _fileFormats; + } + } + + /// + /// Retrieves all the audio encoders supported by the recorder. + /// + /// + /// It returns a list containing all the supported audio encoders + /// by recorder. + /// + public IEnumerable SupportedAudioEncodings + { + get + { + if (_audioCodec == null) + { + _audioCodec = new List(); + + Interop.RecorderFeatures.AudioEncoderCallback callback = (RecorderAudioCodec codec, IntPtr userData) => + { + _audioCodec.Add(codec); + return true; + }; + RecorderErrorFactory.ThrowIfError(Interop.RecorderFeatures.AudioEncoders(_recorder.GetHandle(), callback, IntPtr.Zero), + "Failed to get the supported audio encoders"); + } + + return _audioCodec; + } + } + + /// + /// Retrieves all the video encoders supported by the recorder. + /// + /// + /// It returns a list containing all the supported video encoders + /// by recorder. + /// + public IEnumerable SupportedVideoEncodings + { + get + { + if (_videoCodec == null) + { + _videoCodec = new List(); + + Interop.RecorderFeatures.VideoEncoderCallback callback = (RecorderVideoCodec codec, IntPtr userData) => + { + _videoCodec.Add(codec); + return true; + }; + RecorderErrorFactory.ThrowIfError(Interop.RecorderFeatures.VideoEncoders(_recorder.GetHandle(), callback, IntPtr.Zero), + "Failed to get the supported video encoders"); + } + + return _videoCodec; + } + } + + /// + /// Retrieves all the video resolutions supported by the recorder. + /// + /// + /// It returns videoresolution list containing the width and height of + /// different resolutions supported by recorder. + /// + public IEnumerable SupportedVideoResolutions + { + get + { + if (_videoResolution == null) + { + _videoResolution = new List(); + + Interop.RecorderFeatures.VideoResolutionCallback callback = (int width, int height, IntPtr userData) => + { + _videoResolution.Add(new Size(width, height)); + return true; + }; + RecorderErrorFactory.ThrowIfError(Interop.RecorderFeatures.VideoResolution(_recorder.GetHandle(), callback, IntPtr.Zero), + "Failed to get the supported video resolutions."); + } + + return _videoResolution; + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Recorder/RecorderInterruptedEventArgs.cs b/src/Tizen.Multimedia/Recorder/RecorderInterruptedEventArgs.cs old mode 100644 new mode 100755 index afa856d..15540f0 --- a/src/Tizen.Multimedia/Recorder/RecorderInterruptedEventArgs.cs +++ b/src/Tizen.Multimedia/Recorder/RecorderInterruptedEventArgs.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -25,42 +25,26 @@ namespace Tizen.Multimedia /// public class RecorderInterruptedEventArgs : EventArgs { - private RecorderPolicy _policy = RecorderPolicy.None; - private RecorderState _previous = RecorderState.None; - private RecorderState _current = RecorderState.None; - internal RecorderInterruptedEventArgs(RecorderPolicy policy, RecorderState previous, RecorderState current) { - _policy = policy; - _previous = previous; - _current = current; + Policy = policy; + Previous = previous; + Current = current; } /// /// The policy that interrupted the recorder. /// - public RecorderPolicy Policy { - get { - return _policy; - } - } + public RecorderPolicy Policy { get; } /// /// The previous state of the recorder. /// - public RecorderState Previous { - get { - return _previous; - } - } + public RecorderState Previous { get; } /// /// The current state of the recorder. /// - public RecorderState Current { - get { - return _current; - } - } + public RecorderState Current { get; } } } diff --git a/src/Tizen.Multimedia/Recorder/RecorderSettings.cs b/src/Tizen.Multimedia/Recorder/RecorderSettings.cs new file mode 100755 index 0000000..fb08e59 --- /dev/null +++ b/src/Tizen.Multimedia/Recorder/RecorderSettings.cs @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Linq; +using System.Runtime.InteropServices; +using Tizen.Internals.Errors; + +namespace Tizen.Multimedia +{ + /// + /// The camera setting class provides methods/properties to get and + /// set basic camera attributes. + /// + public class RecorderSettings + { + internal readonly Recorder _recorder = null; + + internal RecorderSettings(Recorder recorder) + { + _recorder = recorder; + } + + /// + /// The number of audio channel. + /// + /// + /// The attribute is applied only in Created state. + /// For mono recording, set channel to 1. + /// For stereo recording, set channel to 2. + /// + public int AudioChannel + { + get + { + int val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetAudioChannel(_recorder.GetHandle(), out val), + "Failed to get audio channel."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetAudioChannel(_recorder.GetHandle(), value), + "Failed to set audio channel"); + } + } + + /// + /// The audio device for recording. + /// + public RecorderAudioDevice AudioDevice + { + get + { + RecorderAudioDevice val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetAudioDevice(_recorder.GetHandle(), out val), + "Failed to get audio device."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetAudioDevice(_recorder.GetHandle(), value), + "Failed to set audio device."); + } + } + + /// + /// Get the peak audio input level in dB + /// + /// + /// 0dB indicates maximum input level, -300dB indicates minimum input level. + /// + public double AudioLevel + { + get + { + double level = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetAudioLevel(_recorder.GetHandle(), out level), + "Failed to get Audio level."); + + return level; + } + } + + /// + /// The sampling rate of an audio stream in hertz. + /// + public int AudioSampleRate + { + get + { + int val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetAudioSampleRate(_recorder.GetHandle(), out val), + "Failed to get audio sample rate."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetAudioSampleRate(_recorder.GetHandle(), value), + "Failed to set audio sample rate."); + } + } + + /// + /// The bitrate of an audio encoder in bits per second. + /// + public int AudioBitRate + { + get + { + int val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetAudioEncoderBitrate(_recorder.GetHandle(), out val), + "Failed to get audio bitrate."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetAudioEncoderBitrate(_recorder.GetHandle(), value), + "Failed to set audio bitrate"); + } + } + + /// + /// The bitrate of an video encoder in bits per second. + /// + public int VideoBitRate + { + get + { + int val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetVideoEncoderBitrate(_recorder.GetHandle(), out val), + "Failed to get video bitrate."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetVideoEncoderBitrate(_recorder.GetHandle(), value), + "Failed to set video bitrate"); + } + } + + /// + /// The audio codec for encoding an audio stream. + /// + public RecorderAudioCodec AudioCodec + { + get + { + RecorderAudioCodec val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetAudioEncoder(_recorder.GetHandle(), out val), + "Failed to get audio codec"); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetAudioEncoder(_recorder.GetHandle(), value), + "Failed to set audio codec"); + } + } + + /// + /// The video codec for encoding video stream. + /// + public RecorderVideoCodec VideoCodec + { + get + { + RecorderVideoCodec val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetVideoEncoder(_recorder.GetHandle(), out val), + "Failed to get video codec"); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetVideoEncoder(_recorder.GetHandle(), value), + "Failed to set video codec"); + } + } + + /// + /// The file format for recording media stream. + /// + public RecorderFileFormat FileFormat + { + get + { + RecorderFileFormat val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetFileFormat(_recorder.GetHandle(), out val), + "Failed to get file format."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetFileFormat(_recorder.GetHandle(), value), + "Failed to set file format"); + } + } + + /// + /// The file path to record. + /// + /// + /// If the same file already exists in the file system, then old file + /// will be overwritten. + /// + public string FilePath + { + get + { + IntPtr val; + int ret = Interop.RecorderSettings.GetFileName(_recorder.GetHandle(), out val); + if ((RecorderError)ret != RecorderError.None) + { + Log.Error(RecorderLog.Tag, "Failed to get filepath, " + (RecorderError)ret); + } + string result = Marshal.PtrToStringAnsi(val); + Interop.Libc.Free(val); + return result; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetFileName(_recorder.GetHandle(), value), + "Failed to set filepath"); + } + } + + /// + /// The maximum size of a recording file in KB(kilobytes). If 0, means + /// unlimited recording size. + /// + /// + /// After reaching the limitation, the data which is being recorded will + /// be discarded and not written to the file. + /// The recorder state must be in 'Ready' or 'Created' state. + /// + /// + public int SizeLimit + { + get + { + int val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetSizeLimit(_recorder.GetHandle(), out val), + "Failed to get size limit."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetSizeLimit(_recorder.GetHandle(), value), + "Failed to set size limit"); + } + } + + /// + /// The time limit of a recording file in Seconds. If 0, means unlimited recording + /// time. + /// + /// + /// After reaching the limitation, the data which is being recorded will + /// be discarded and not written to the file. + /// The recorder state must be in 'Ready' or 'Created' state. + /// + public int TimeLimit + { + get + { + int val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetTimeLimit(_recorder.GetHandle(), out val), + "Failed to get time limit."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetTimeLimit(_recorder.GetHandle(), value), + "Failed to set time limit."); + } + } + + /// + /// The mute state of a recorder. + /// + public bool Mute + { + get + { + bool ret = Interop.RecorderSettings.GetMute(_recorder.GetHandle()); + + RecorderErrorFactory.ThrowIfError(ErrorFacts.GetLastResult(), + "Failed to get the mute state of recorder"); + + return ret; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetMute(_recorder.GetHandle(), value), + "Failed to set mute"); + } + } + + /// + /// The video recording motion rate + /// + /// + /// The attribute is valid only in a video recorder. + /// If the rate is in range of 0-1, video is recorded in a slow motion mode. + /// If the rate is bigger than 1, video is recorded in a fast motion mode. + /// + public double MotionRate + { + get + { + double val = 0.0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetMotionRate(_recorder.GetHandle(), out val), + "Failed to get video motion rate."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetMotionRate(_recorder.GetHandle(), value), + "Failed to set video motion rate"); + } + } + + /// + /// The orientation in a video metadata tag. + /// + public RecorderOrientation OrientationTag + { + get + { + RecorderOrientation val = 0; + + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.GetOrientationTag(_recorder.GetHandle(), out val), + "Failed to get recorder orientation."); + + return val; + } + + set + { + RecorderErrorFactory.ThrowIfError(Interop.RecorderSettings.SetOrientationTag(_recorder.GetHandle(), value), + "Failed to set recorder orientation"); + } + } + + /// + /// Resolution of the video. + /// + /// + /// http://tizen.org/privilege/recorder + /// + /// In case of invalid parameters + public Size VideoResolution + { + get + { + int width = 0; + int height = 0; + + CameraErrorFactory.ThrowIfError(Interop.RecorderSettings.GetVideoResolution(_recorder.GetHandle(), out width, out height), + "Failed to get camera video resolution"); + + return new Size(width, height); + } + + set + { + Size res = value; + + CameraErrorFactory.ThrowIfError(Interop.RecorderSettings.SetVideoResolution(_recorder.GetHandle(), res.Width, res.Height), + "Failed to set video resolution."); + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.Multimedia/Recorder/RecorderStateChangedEventArgs.cs b/src/Tizen.Multimedia/Recorder/RecorderStateChangedEventArgs.cs old mode 100644 new mode 100755 index 3c33371..ad5af93 --- a/src/Tizen.Multimedia/Recorder/RecorderStateChangedEventArgs.cs +++ b/src/Tizen.Multimedia/Recorder/RecorderStateChangedEventArgs.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -24,43 +24,27 @@ namespace Tizen.Multimedia /// public class RecorderStateChangedEventArgs : EventArgs { - private RecorderState _previous = RecorderState.None; - private RecorderState _current = RecorderState.None; - private bool _policy = false; - - internal RecorderStateChangedEventArgs(RecorderState previous, RecorderState current, bool policy) + internal RecorderStateChangedEventArgs(RecorderState previous, RecorderState current, bool byPolicy) { - _previous = previous; - _current = current; - _policy = policy; + Previous = previous; + Current = current; + IsStateChangedByPolicy = byPolicy; } /// /// Previous state of the recorder. /// - public RecorderState Previous { - get { - return _previous; - } - } + public RecorderState Previous { get; } /// /// Current state of the recorder. /// - public RecorderState Current { - get { - return _current; - } - } + public RecorderState Current { get; } /// /// true if the state changed by policy such as Resource Conflict or Security, otherwise false /// in normal state change. /// - public bool ByPolicy { - get { - return _policy; - } - } + public bool IsStateChangedByPolicy { get; } } } diff --git a/src/Tizen.Multimedia/Recorder/RecordingErrorOccurredEventArgs.cs b/src/Tizen.Multimedia/Recorder/RecordingErrorOccurredEventArgs.cs old mode 100644 new mode 100755 index 604bf87..95c0dfa --- a/src/Tizen.Multimedia/Recorder/RecordingErrorOccurredEventArgs.cs +++ b/src/Tizen.Multimedia/Recorder/RecordingErrorOccurredEventArgs.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -24,32 +24,21 @@ namespace Tizen.Multimedia /// public class RecordingErrorOccurredEventArgs : EventArgs { - private RecorderErrorCode _error = RecorderErrorCode.DeviceError; - private RecorderState _state = RecorderState.None; - internal RecordingErrorOccurredEventArgs(RecorderErrorCode error, RecorderState state) { - _error = error; - _state = state; + Error = error; + State = state; } /// /// The error code. /// - public RecorderErrorCode Error { - get { - return _error; - } - } + public RecorderErrorCode Error { get; } /// /// The state of the recorder. /// - public RecorderState State { - get { - return _state; - } - } + public RecorderState State { get; } } } diff --git a/src/Tizen.Multimedia/Recorder/RecordingLimitReachedEventArgs.cs b/src/Tizen.Multimedia/Recorder/RecordingLimitReachedEventArgs.cs old mode 100644 new mode 100755 index 07851d2..a6e0567 --- a/src/Tizen.Multimedia/Recorder/RecordingLimitReachedEventArgs.cs +++ b/src/Tizen.Multimedia/Recorder/RecordingLimitReachedEventArgs.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -23,20 +23,14 @@ namespace Tizen.Multimedia /// public class RecordingLimitReachedEventArgs : EventArgs { - private RecordingLimitType _type = RecordingLimitType.Size; - internal RecordingLimitReachedEventArgs(RecordingLimitType type) { - _type = type; + Type = type; } /// /// The limitation type. /// - public RecordingLimitType Type { - get { - return _type; - } - } + public RecordingLimitType Type { get; } } } diff --git a/src/Tizen.Multimedia/Recorder/RecordingStatusChangedEventArgs.cs b/src/Tizen.Multimedia/Recorder/RecordingProgressEventArgs.cs old mode 100644 new mode 100755 similarity index 67% rename from src/Tizen.Multimedia/Recorder/RecordingStatusChangedEventArgs.cs rename to src/Tizen.Multimedia/Recorder/RecordingProgressEventArgs.cs index c4195c8..09f193b --- a/src/Tizen.Multimedia/Recorder/RecordingStatusChangedEventArgs.cs +++ b/src/Tizen.Multimedia/Recorder/RecordingProgressEventArgs.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -21,33 +21,22 @@ namespace Tizen.Multimedia /// /// An extened EventArgs class which contain the details of current recording status. /// - public class RecordingStatusChangedEventArgs : EventArgs + public class RecordingProgressEventArgs : EventArgs { - private ulong _time = 0; - private ulong _fileSize = 0; - - internal RecordingStatusChangedEventArgs(ulong time, ulong fileSize) + internal RecordingProgressEventArgs(ulong elapsedTime, ulong fileSize) { - _time = time; - _fileSize = fileSize; + ElapsedTime = elapsedTime; + FileSize = fileSize; } /// /// The time of recording in milliseconds. /// - public ulong ElapsedTime { - get { - return _time; - } - } + public ulong ElapsedTime { get; } /// /// The size of the recording file in Kilobyte. /// - public ulong FileSize { - get { - return _fileSize; - } - } + public ulong FileSize { get; } } } diff --git a/src/Tizen.Multimedia/Recorder/VideoResolution.cs b/src/Tizen.Multimedia/Recorder/VideoResolution.cs deleted file mode 100644 index 2c9f81c..0000000 --- a/src/Tizen.Multimedia/Recorder/VideoResolution.cs +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Tizen.Multimedia -{ - /// - /// Resolution for video recording. - /// - public class RecorderVideoResolution - { - private int _width, _height; - private bool _interopFlag; - internal IntPtr _videoHandle; - - internal RecorderVideoResolution(IntPtr handle) - { - _videoHandle = handle; - _interopFlag = true; - int ret = Interop.Recorder.GetVideoResolution(_videoHandle, out _width, out _height); - RecorderError err = (RecorderError)ret; - Log.Info(RecorderLog.Tag, "width " + _width + " height " + _height + "return " + err.ToString()); - } - - internal RecorderVideoResolution(int width, int height) - { - _interopFlag = false; - _width = width; - _height = height; - } - - /// - /// The video width. - /// - /// The width. - public int Width { - get { - if(_interopFlag == true) - Interop.Recorder.GetVideoResolution(_videoHandle, out _width, out _height); - return _width; - } - set { - _width = value; - if(_interopFlag == true) { - int ret = Interop.Recorder.SetVideoResolution(_videoHandle, _width, _height); - RecorderError err = (RecorderError)ret; - Log.Info(RecorderLog.Tag, " set width " + _width + " height " + _height + "set return " + err.ToString()); - } - } - } - - /// - /// The video height. - /// - /// The height. - public int Height { - get { - if(_interopFlag == true) - Interop.Recorder.GetVideoResolution(_videoHandle, out _width, out _height); - return _height; - } - set { - _height = value; - if(_interopFlag == true) { - int ret = Interop.Recorder.SetVideoResolution(_videoHandle, _width, _height); - RecorderError err = (RecorderError)ret; - Log.Info(RecorderLog.Tag, " set width " + _width + " height " + _height + "set return " + err.ToString()); - } - } - } - } -} diff --git a/src/Tizen.Multimedia/StreamRecorder/StreamRecorder.cs b/src/Tizen.Multimedia/StreamRecorder/StreamRecorder.cs index 6ae38f7..9d24d62 100755 --- a/src/Tizen.Multimedia/StreamRecorder/StreamRecorder.cs +++ b/src/Tizen.Multimedia/StreamRecorder/StreamRecorder.cs @@ -40,7 +40,7 @@ namespace Tizen.Multimedia /// /// Occurred when recording is progressing for recording status. /// - private EventHandler _recordingStatusChanged; + private EventHandler _recordingStatusChanged; private Interop.StreamRecorder.RecordingStatusCallback _recordingStatusCallback; /// /// Occurred when recording time or size reach limit. @@ -143,7 +143,7 @@ namespace Tizen.Multimedia /// /// Event that occurs when recording status changed. /// - public event EventHandler RecordingStatusChanged + public event EventHandler RecordingStatusChanged { add { @@ -985,7 +985,7 @@ namespace Tizen.Multimedia { _recordingStatusCallback = (ulong elapsedTime, ulong fileSize, IntPtr userData) => { - RecordingStatusChangedEventArgs eventArgs = new RecordingStatusChangedEventArgs(elapsedTime, fileSize); + RecordingProgressEventArgs eventArgs = new RecordingProgressEventArgs(elapsedTime, fileSize); _recordingStatusChanged?.Invoke(this, eventArgs); }; int ret = Interop.StreamRecorder.SetStatusChangedCallback(_handle, _recordingStatusCallback, IntPtr.Zero); -- 2.7.4