[Multimedia] Redesigned StreamRecorder API. 71/144971/4
authorcoderhyme <jhyo.kim@samsung.com>
Sat, 19 Aug 2017 03:38:21 +0000 (12:38 +0900)
committerSeokHoon LEE <andy.shlee@samsung.com>
Mon, 11 Sep 2017 02:27:04 +0000 (02:27 +0000)
Change-Id: I0e6f3a65a3681facb810dfd1534acc605c67578b
Signed-off-by: coderhyme <jhyo.kim@samsung.com>
17 files changed:
src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Capabilities.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Events.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Settings.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.cs
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.Capabilities.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.Events.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.cs
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderAudioOptions.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderBufferConsumedEventArgs.cs [moved from src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingBufferConsumedEventArgs.cs with 67% similarity]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderEnums.cs
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderError.cs [moved from src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderErrorFactory.cs with 58% similarity]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderErrorOccurredEventArgs.cs [moved from src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingLimitReachedEventArgs.cs with 60% similarity]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderNotifiedEventArgs.cs [deleted file]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderOptions.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderStateChangedEventArgs.cs [moved from src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecordingErrorOccurredEventArgs.cs with 50% similarity]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoOptions.cs [new file with mode: 0644]
src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoResolution.cs [deleted file]

diff --git a/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Capabilities.cs b/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Capabilities.cs
new file mode 100644 (file)
index 0000000..133674e
--- /dev/null
@@ -0,0 +1,37 @@
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+    internal static partial class StreamRecorder
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool VideoResolutionCallback(int width, int height, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool FileFormatCallback(StreamRecorderFileFormat format, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool AudioEncoderCallback(StreamRecorderAudioCodec codec, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool VideoEncoderCallback(StreamRecorderVideoCodec codec, IntPtr userData);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_file_format")]
+        internal static extern StreamRecorderErrorCode FileFormats(StreamRecorderHandle handle,
+            FileFormatCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_audio_encoder")]
+        internal static extern StreamRecorderErrorCode AudioEncoders(StreamRecorderHandle handle,
+            AudioEncoderCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_video_encoder")]
+        internal static extern StreamRecorderErrorCode VideoEncoders(StreamRecorderHandle handle,
+            VideoEncoderCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_video_resolution")]
+        internal static extern StreamRecorderErrorCode VideoResolution(StreamRecorderHandle handle,
+            VideoResolutionCallback callback, IntPtr userData = default(IntPtr));
+    }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Events.cs b/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Events.cs
new file mode 100644 (file)
index 0000000..e7febae
--- /dev/null
@@ -0,0 +1,61 @@
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+    internal static partial class StreamRecorder
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void RecordingLimitReachedCallback(RecordingLimitType type, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void RecordingStatusCallback(ulong elapsedTime, ulong fileSize, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void NotifiedCallback(int previous, int current,
+            StreamRecorderNotify notify, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void RecorderErrorCallback(StreamRecorderErrorCode error,
+            RecorderState current, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void BufferConsumedCallback(IntPtr buffer, IntPtr userData);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_notify_cb")]
+        internal static extern StreamRecorderErrorCode SetNotifiedCallback(StreamRecorderHandle handle,
+            NotifiedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_notify_cb")]
+        internal static extern int UnsetNotifiedCallback(StreamRecorderHandle handle);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_status_cb")]
+        internal static extern StreamRecorderErrorCode SetStatusChangedCallback(StreamRecorderHandle handle,
+            RecordingStatusCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_recording_status_cb")]
+        internal static extern int UnsetStatusChangedCallback(StreamRecorderHandle handle);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_limit_reached_cb")]
+        internal static extern StreamRecorderErrorCode SetLimitReachedCallback(StreamRecorderHandle handle,
+            RecordingLimitReachedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_recording_limit_reached_cb")]
+        internal static extern int UnsetLimitReachedCallback(StreamRecorderHandle handle);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_error_cb")]
+        internal static extern StreamRecorderErrorCode SetErrorCallback(StreamRecorderHandle handle,
+            RecorderErrorCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_error_cb")]
+        internal static extern int UnsetErrorCallback(StreamRecorderHandle handle);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_buffer_consume_completed_cb")]
+        internal static extern StreamRecorderErrorCode SetBufferConsumedCallback(StreamRecorderHandle handle,
+            BufferConsumedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_buffer_consume_completed_cb")]
+        internal static extern int UnsetBufferConsumedCallback(StreamRecorderHandle handle);
+    }
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Settings.cs b/src/Tizen.Multimedia.StreamRecorder/Interop/Interop.StreamRecorder.Settings.cs
new file mode 100644 (file)
index 0000000..a8fabbb
--- /dev/null
@@ -0,0 +1,88 @@
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Multimedia;
+
+internal static partial class Interop
+{
+    internal static partial class StreamRecorder
+    {
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_filename")]
+        internal static extern StreamRecorderErrorCode SetFileName(StreamRecorderHandle handle, string path);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_filename")]
+        internal static extern int GetFileName(StreamRecorderHandle handle, out IntPtr path);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_file_format")]
+        internal static extern StreamRecorderErrorCode SetFileFormat(StreamRecorderHandle handle,
+            StreamRecorderFileFormat format);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_file_format")]
+        internal static extern int GetFileFormat(StreamRecorderHandle handle, out int format);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_encoder")]
+        internal static extern StreamRecorderErrorCode SetAudioEncoder(StreamRecorderHandle handle,
+            StreamRecorderAudioCodec codec);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_encoder")]
+        internal static extern int GetAudioEncoder(StreamRecorderHandle handle, out int codec);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_encoder")]
+        internal static extern StreamRecorderErrorCode SetVideoEncoder(StreamRecorderHandle handle,
+            StreamRecorderVideoCodec codec);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_encoder")]
+        internal static extern int GetVideoEncoder(StreamRecorderHandle handle, out int codec);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_resolution")]
+        internal static extern StreamRecorderErrorCode SetVideoResolution(StreamRecorderHandle handle,
+            int width, int height);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_resolution")]
+        internal static extern StreamRecorderErrorCode GetVideoResolution(StreamRecorderHandle handle,
+            out int width, out int height);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_framerate")]
+        internal static extern StreamRecorderErrorCode SetVideoFrameRate(StreamRecorderHandle handle, int framerate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_framerate")]
+        internal static extern int GetVideoFramerate(StreamRecorderHandle handle, out int framerate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_source_format")]
+        internal static extern StreamRecorderErrorCode SetVideoSourceFormat(StreamRecorderHandle handle,
+            StreamRecorderVideoFormat format);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_source_format")]
+        internal static extern int GetVideoSourceFormat(StreamRecorderHandle handle, out int format);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_limit")]
+        internal static extern StreamRecorderErrorCode SetRecordingLimit(StreamRecorderHandle handle,
+            RecordingLimitType type, int limit);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_recording_limit")]
+        internal static extern int GetRecordingLimit(StreamRecorderHandle handle, int type, out int format);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_samplerate")]
+        internal static extern StreamRecorderErrorCode SetAudioSampleRate(StreamRecorderHandle handle, int samplerate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_samplerate")]
+        internal static extern int GetAudioSampleRate(StreamRecorderHandle handle, out int samplerate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_encoder_bitrate")]
+        internal static extern StreamRecorderErrorCode SetAudioEncoderBitrate(StreamRecorderHandle handle, int bitrate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_encoder_bitrate")]
+        internal static extern int GetAudioEncoderBitrate(StreamRecorderHandle handle, out int bitrate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_encoder_bitrate")]
+        internal static extern StreamRecorderErrorCode SetVideoEncoderBitRate(StreamRecorderHandle handle, int bitrate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_encoder_bitrate")]
+        internal static extern int GetVideoEncoderBitrate(StreamRecorderHandle handle, out int bitrate);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_channel")]
+        internal static extern StreamRecorderErrorCode SetAudioChannel(StreamRecorderHandle handle, int channel);
+
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_channel")]
+        internal static extern int GetAudioChannel(StreamRecorderHandle handle, out int channel);
+    }
+}
index dd79eab..e7f061b 100644 (file)
@@ -6,181 +6,72 @@ internal static partial class Interop
 {
     internal static partial class StreamRecorder
     {
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void RecordingLimitReachedCallback(StreamRecordingLimitType type, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void RecordingStatusCallback(ulong elapsedTime, ulong fileSize, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void NotifiedCallback(StreamRecorderState previous, StreamRecorderState current, StreamRecorderNotify notfication, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void RecorderErrorCallback(StreamRecorderErrorCode error, StreamRecorderState current, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void BufferConsumedCallback(IntPtr buffer, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool VideoResolutionCallback(int width, int height, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool FileFormatCallback(StreamRecorderFileFormat format, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool AudioEncoderCallback(StreamRecorderAudioCodec codec, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool VideoEncoderCallback(StreamRecorderVideoCodec codec, IntPtr userData);
-
-        /* begin of method */
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_create")]
-        internal static extern int Create(out IntPtr handle);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_destroy")]
-        internal static extern int Destroy(IntPtr handle);
+        internal static extern StreamRecorderErrorCode Create(out StreamRecorderHandle handle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_prepare")]
-        internal static extern int Prepare(IntPtr handle);
+        internal static extern StreamRecorderErrorCode Prepare(StreamRecorderHandle handle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unprepare")]
-        internal static extern int Unprepare(IntPtr handle);
+        internal static extern StreamRecorderErrorCode Unprepare(StreamRecorderHandle handle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_start")]
-        internal static extern int Start(IntPtr handle);
+        internal static extern StreamRecorderErrorCode Start(StreamRecorderHandle handle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_pause")]
-        internal static extern int Pause(IntPtr handle);
+        internal static extern StreamRecorderErrorCode Pause(StreamRecorderHandle handle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_commit")]
-        internal static extern int Commit(IntPtr handle);
+        internal static extern StreamRecorderErrorCode Commit(StreamRecorderHandle handle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_cancel")]
-        internal static extern int Cancel(IntPtr handle);
+        internal static extern StreamRecorderErrorCode Cancel(StreamRecorderHandle handle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_push_stream_buffer")]
-        internal static extern int PushStreamBuffer(IntPtr handle, IntPtr/*  media_packet_h */ inbuf);
+        internal static extern StreamRecorderErrorCode PushStreamBuffer(StreamRecorderHandle handle,
+            IntPtr mediaPacketHandle);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_enable_source_buffer")]
-        internal static extern int EnableSourceBuffer(IntPtr handle, int type);
+        internal static extern StreamRecorderErrorCode EnableSourceBuffer(StreamRecorderHandle handle,
+            StreamRecorderSourceType type);
 
         [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_state")]
-        internal static extern int GetState(IntPtr handle, out int state);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_filename")]
-        internal static extern int SetFileName(IntPtr handle, string path);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_filename")]
-        internal static extern int GetFileName(IntPtr handle, out IntPtr path);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_file_format")]
-        internal static extern int SetFileFormat(IntPtr handle, int format);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_file_format")]
-        internal static extern int GetFileFormat(IntPtr handle, out int format);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_encoder")]
-        internal static extern int SetAudioEncoder(IntPtr handle, int codec);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_encoder")]
-        internal static extern int GetAudioEncoder(IntPtr handle, out int codec);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_encoder")]
-        internal static extern int SetVideoEncoder(IntPtr handle, int codec);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_encoder")]
-        internal static extern int GetVideoEncoder(IntPtr handle, out int codec);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_resolution")]
-        internal static extern int SetVideoResolution(IntPtr handle, int width, int height);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_resolution")]
-        internal static extern int GetVideoResolution(IntPtr handle, out int width, out int height);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_framerate")]
-        internal static extern int SetVideoFramerate(IntPtr handle, int framerate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_framerate")]
-        internal static extern int GetVideoFramerate(IntPtr handle, out int framerate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_source_format")]
-        internal static extern int SetVideoSourceFormat(IntPtr handle, int format);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_source_format")]
-        internal static extern int GetVideoSourceFormat(IntPtr handle, out int format);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_limit")]
-        internal static extern int SetRecordingLimit(IntPtr handle, int type, int limit);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_recording_limit")]
-        internal static extern int GetRecordingLimit(IntPtr handle, int type, out int format);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_samplerate")]
-        internal static extern int SetAudioSampleRate(IntPtr handle, int samplerate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_samplerate")]
-        internal static extern int GetAudioSampleRate(IntPtr handle, out int samplerate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_encoder_bitrate")]
-        internal static extern int SetAudioEncoderBitrate(IntPtr handle, int bitrate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_encoder_bitrate")]
-        internal static extern int GetAudioEncoderBitrate(IntPtr handle, out int bitrate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_video_encoder_bitrate")]
-        internal static extern int SetVideoEncoderBitrate(IntPtr handle, int bitrate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_video_encoder_bitrate")]
-        internal static extern int GetVideoEncoderBitrate(IntPtr handle, out int bitrate);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_audio_channel")]
-        internal static extern int SetAudioChannel(IntPtr handle, int channel);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_get_audio_channel")]
-        internal static extern int GetAudioChannel(IntPtr handle, out int channel);
-        /* End of method */
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_file_format")]
-        internal static extern int FileFormats(IntPtr handle, FileFormatCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_audio_encoder")]
-        internal static extern int AudioEncoders(IntPtr handle, AudioEncoderCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_video_encoder")]
-        internal static extern int VideoEncoders(IntPtr handle, VideoEncoderCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_foreach_supported_video_resolution")]
-        internal static extern int VideoResolution(IntPtr handle, VideoResolutionCallback callback, IntPtr userData);
-        /* End of foreach method */
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_notify_cb")]
-        internal static extern int SetNotifiedCallback(IntPtr handle, NotifiedCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_notify_cb")]
-        internal static extern int UnsetNotifiedCallback(IntPtr handle);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_status_cb")]
-        internal static extern int SetStatusChangedCallback(IntPtr handle, RecordingStatusCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_recording_status_cb")]
-        internal static extern int UnsetStatusChangedCallback(IntPtr handle);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_recording_limit_reached_cb")]
-        internal static extern int SetLimitReachedCallback(IntPtr handle, RecordingLimitReachedCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_recording_limit_reached_cb")]
-        internal static extern int UnsetLimitReachedCallback(IntPtr handle);
-
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_error_cb")]
-        internal static extern int SetErrorCallback(IntPtr handle, RecorderErrorCallback callback, IntPtr userData);
+        internal static extern StreamRecorderErrorCode GetState(StreamRecorderHandle handle, out RecorderState state);
+    }
 
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_error_cb")]
-        internal static extern int UnsetErrorCallback(IntPtr handle);
+    internal class StreamRecorderHandle : SafeHandle
+    {
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_destroy")]
+        private static extern StreamRecorderErrorCode Destroy(IntPtr handle);
 
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_set_buffer_consume_completed_cb")]
-        internal static extern int SetBufferConsumedCallback(IntPtr handle, BufferConsumedCallback callback, IntPtr userDat);
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_cancel")]
+        private static extern StreamRecorderErrorCode Cancel(IntPtr handle);
 
-        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unset_buffer_consume_completed_cb")]
-        internal static extern int UnsetBufferConsumedCallback(IntPtr handle);
+        [DllImport(Libraries.StreamRecorder, EntryPoint = "streamrecorder_unprepare")]
+        private static extern StreamRecorderErrorCode Unprepare(IntPtr handle);
+
+        protected StreamRecorderHandle() : base(IntPtr.Zero, true)
+        {
+        }
+
+        public override bool IsInvalid => handle == IntPtr.Zero;
+
+        protected override bool ReleaseHandle()
+        {
+            try
+            {
+                Cancel(handle).Ignore(StreamRecorderErrorCode.InvalidState).ThrowIfError("Failed to cancel.");
+                Unprepare(handle).Ignore(StreamRecorderErrorCode.InvalidState).ThrowIfError("Failed to unprepare.");
+                Destroy(handle).ThrowIfError("Failed to destory.");
+
+                return true;
+            }
+            catch (Exception e)
+            {
+                Tizen.Log.Debug(GetType().FullName, $"Failed to release native RecorderHandle; {e.Message}");
+
+                return false;
+            }
+        }
     }
 }
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.Capabilities.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.Capabilities.cs
new file mode 100644 (file)
index 0000000..4ba2137
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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;
+using Native = Interop.StreamRecorder;
+
+namespace Tizen.Multimedia
+{
+    public partial class StreamRecorder
+    {
+        internal void LoadCapabilities()
+        {
+            _videoCodecs = LoadVideoCodecs(this);
+            _audioCodecs = LoadAudioCodecs(this);
+            _fileFormats = LoadFileFormats(this);
+            _videoResolutions = LoadResolutions(this);
+        }
+
+        private static IEnumerable<RecorderVideoCodec> LoadVideoCodecs(StreamRecorder recorder)
+        {
+            var result = new List<RecorderVideoCodec>();
+            Native.VideoEncoderCallback callback = (codec, _) =>
+            {
+                result.Add(codec.ToRecorderEnum());
+                return true;
+            };
+
+            Native.VideoEncoders(recorder.Handle, callback).ThrowIfError("Failed to get the supported video codecs.");
+
+            return result.AsReadOnly();
+        }
+
+        private static IEnumerable<RecorderAudioCodec> LoadAudioCodecs(StreamRecorder recorder)
+        {
+            var result = new List<RecorderAudioCodec>();
+
+            Native.AudioEncoders(recorder.Handle, (codec, _) =>
+            {
+                result.Add(codec.ToRecorderEnum());
+                return true;
+            }).ThrowIfError("Failed to get the supported audio codecs.");
+
+            return result.AsReadOnly();
+        }
+
+        private static IEnumerable<RecorderFileFormat> LoadFileFormats(StreamRecorder recorder)
+        {
+            var result = new List<RecorderFileFormat>();
+
+            Native.FileFormats(recorder.Handle, (fileFormat, _) =>
+            {
+                result.Add(fileFormat.ToRecorderEnum());
+                return true;
+            }).ThrowIfError("Failed to get the supported file formats.");
+
+            return result.AsReadOnly();
+        }
+
+        private static IEnumerable<Size> LoadResolutions(StreamRecorder recorder)
+        {
+            List<Size> result = new List<Size>();
+
+            Native.VideoResolutionCallback callback = (width, height, _) =>
+            {
+                result.Add(new Size(width, height));
+                return true;
+            };
+
+            Native.VideoResolution(recorder.Handle, callback).
+                ThrowIfError("Failed to get the supported video resolutions.");
+
+            return result.AsReadOnly();
+        }
+
+        private IEnumerable<RecorderFileFormat> _fileFormats;
+
+        /// <summary>
+        /// Gets the file formats that the current device supports.
+        /// </summary>
+        /// <returns>An IEnumerable of <see cref="RecorderFileFormat"/> representing the supported file formats.</returns>
+        public IEnumerable<RecorderFileFormat> GetSupportedFileFormats() => _fileFormats;
+
+        private IEnumerable<RecorderAudioCodec> _audioCodecs;
+
+        /// <summary>
+        /// Gets the audio codecs that the current device supports.
+        /// </summary>
+        /// <returns>An IEnumerable of <see cref="RecorderAudioCodec"/> representing the supported audio codecs.</returns>
+        public IEnumerable<RecorderAudioCodec> GetSupportedAudioCodecs() => _audioCodecs;
+
+        private IEnumerable<RecorderVideoCodec> _videoCodecs;
+
+        /// <summary>
+        /// Gets the video codecs that the current device supports.
+        /// </summary>
+        /// <returns>An IEnumerable of <see cref="RecorderVideoCodec"/> representing the supported video codecs.</returns>
+        public IEnumerable<RecorderVideoCodec> GetSupportedVideoCodecs() => _videoCodecs;
+
+        private IEnumerable<Size> _videoResolutions;
+
+        /// <summary>
+        /// Gets the video resolutions that the current device supports.
+        /// </summary>
+        /// <returns>An IEnumerable of <see cref="Size"/> representing the supported resolutions.</returns>
+        public IEnumerable<Size> GetSupportedVideoResolutions() => _videoResolutions;
+
+        internal void ValidateFileFormat(RecorderFileFormat format)
+        {
+            if (_fileFormats.Contains(format) == false)
+            {
+                throw new NotSupportedException($"{format.ToString()} is not supported.");
+            }
+        }
+
+        internal void ValidateAudioCodec(RecorderAudioCodec codec)
+        {
+            if (_audioCodecs.Contains(codec) == false)
+            {
+                throw new NotSupportedException($"{codec.ToString()} is not supported.");
+            }
+        }
+
+        internal void ValidateVideoCodec(RecorderVideoCodec codec)
+        {
+            if (_videoCodecs.Contains(codec) == false)
+            {
+                throw new NotSupportedException($"{codec.ToString()} is not supported.");
+            }
+        }
+
+        internal void ValidateVideoResolution(Size resolution)
+        {
+            if (_videoResolutions.Contains(resolution) == false)
+            {
+                throw new NotSupportedException($"Resolution({resolution.ToString()}) is not supported.");
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.Events.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorder.Events.cs
new file mode 100644 (file)
index 0000000..647e3ab
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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.Diagnostics;
+using Native = Interop.StreamRecorder;
+
+namespace Tizen.Multimedia
+{
+    public partial class StreamRecorder
+    {
+        /// <summary>
+        /// Occurs when <see cref="StreamRecorder"/> state is changed.
+        /// </summary>
+        public event EventHandler<StreamRecorderStateChangedEventArgs> StateChanged;
+
+
+        /// <summary>
+        /// Occurs when a buffer had consumed completely.
+        /// </summary>
+        public event EventHandler<StreamRecorderBufferConsumedEventArgs> BufferConsumed;
+
+        /// <summary>
+        /// Occurs when recording status is changed.
+        /// </summary>
+        public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged;
+
+        /// <summary>
+        /// Occurs when recording limit is reached.
+        /// </summary>
+        public event EventHandler<RecordingLimitReachedEventArgs> RecordingLimitReached;
+
+        /// <summary>
+        /// Occurs when an error occurred during a recorder operation.
+        /// </summary>
+        public event EventHandler<StreamRecorderErrorOccurredEventArgs> ErrorOccurred;
+
+        private Native.RecordingLimitReachedCallback _recordingLimitReachedCallback;
+        private Native.RecorderErrorCallback _recorderErrorCallback;
+        private Native.RecordingStatusCallback _recordingStatusCallback;
+        private Native.BufferConsumedCallback _bufferConsumedCallback;
+        private Native.NotifiedCallback _notifiedCallback;
+
+        private void RegisterStreamRecorderNotifiedEvent()
+        {
+            _notifiedCallback = (previous, current, notify, _) =>
+            {
+                if (previous == 0)
+                {
+                    return;
+                }
+
+                StateChanged?.Invoke(this, new StreamRecorderStateChangedEventArgs(
+                    (RecorderState)previous, (RecorderState)current));
+            };
+
+            Native.SetNotifiedCallback(_handle, _notifiedCallback).
+                ThrowIfError("Failed to initialize state changed event.");
+        }
+
+        private void RegisterBufferConsumedEvent()
+        {
+            _bufferConsumedCallback = (lockedPacketHandle, _) =>
+            {
+                MediaPacket packet = null;
+
+                // Lock must be disposed here, note that the packet won't be disposed.
+                using (MediaPacket.Lock packetLock =
+                    MediaPacket.Lock.FromHandle(lockedPacketHandle))
+                {
+                    Debug.Assert(packetLock != null);
+
+                    packet = packetLock.MediaPacket;
+                }
+
+                BufferConsumed?.Invoke(this, new StreamRecorderBufferConsumedEventArgs(packet));
+            };
+
+            Native.SetBufferConsumedCallback(_handle, _bufferConsumedCallback).
+                ThrowIfError("Failed to initialize buffer consumed event.");
+        }
+
+        private void RegisterRecordingStatusChangedEvent()
+        {
+            _recordingStatusCallback = (elapsedTime, fileSize, _) =>
+            {
+                RecordingStatusChanged?.Invoke(this, new RecordingStatusChangedEventArgs((long)elapsedTime, (long)fileSize));
+            };
+            Native.SetStatusChangedCallback(_handle, _recordingStatusCallback).
+                ThrowIfError("Failed to initialize status changed event.");
+        }
+
+        private void RegisterRecordingLimitReachedEvent()
+        {
+            _recordingLimitReachedCallback = (type, _) =>
+            {
+                RecordingLimitReached?.Invoke(this, new RecordingLimitReachedEventArgs(type));
+            };
+
+            Native.SetLimitReachedCallback(_handle, _recordingLimitReachedCallback).
+                ThrowIfError("Failed to initialize limit reached event.");
+        }
+
+        private void RegisterRecordingErrorOccurredEvent()
+        {
+            _recorderErrorCallback = (error, currentState, _) =>
+            {
+                ErrorOccurred?.Invoke(this, new StreamRecorderErrorOccurredEventArgs(
+                    error == StreamRecorderErrorCode.OutOfStorage ?
+                    StreamRecorderError.OutOfStorage : StreamRecorderError.InternalError, currentState));
+            };
+            Native.SetErrorCallback(_handle, _recorderErrorCallback).
+                ThrowIfError("Failed to set error callback");
+        }
+    }
+}
index 91cf1ee..99fd6d8 100644 (file)
  */
 
 using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using Tizen.Internals.Errors;
+using System.Diagnostics;
+using System.Linq;
+using NativeHandle = Interop.StreamRecorderHandle;
 using Native = Interop.StreamRecorder;
 
 namespace Tizen.Multimedia
 {
-    static internal class StreamRecorderLog
-    {
-        internal const string Tag = "Tizen.Multimedia.StreamRecorder";
-    }
-
     /// <summary>
-    /// Provides methods to control stream recorder.
+    /// Provides the ability to record user buffer from application.
     /// </summary>
-    /// <remarks>
-    /// StreamRecorder class provides functions to record raw image frame
-    /// also provides recording start, stop and save the content etc.
-    /// </remarks>
-    public class StreamRecorder : IDisposable
+    /// <seealso cref="Recorder"/>
+    public partial class StreamRecorder : IDisposable
     {
-        private IntPtr _handle;
+        private NativeHandle _handle;
         private bool _disposed = false;
-        /// <summary>
-        /// Occurred when recording is progressing for recording status.
-        /// </summary>
-        private EventHandler<RecordingStatusChangedEventArgs> _recordingStatusChanged;
-        private Native.RecordingStatusCallback _recordingStatusCallback;
-        /// <summary>
-        /// Occurred when recording time or size reach limit.
-        /// </summary>
-        private EventHandler<StreamRecordingLimitReachedEventArgs> _recordingLimitReached;
-        private Native.RecordingLimitReachedCallback _recordingLimitReachedCallback;
-        /// <summary>
-        /// Occurred when streamrecorder complete to use pushed buffer.
-        /// </summary>
-        private EventHandler<StreamRecordingBufferConsumedEventArgs> _bufferConsumed;
-        private Native.BufferConsumedCallback _bufferConsumedCallback;
-        /// <summary>
-        /// Occurred when streamrecorder state is changed.
-        /// </summary>
-        private EventHandler<StreamRecorderNotifiedEventArgs> _recorderNotified;
-        private Native.NotifiedCallback _notifiedCallback;
-        /// <summary>
-        /// Occurred when error is occured.
-        /// </summary>
-        private EventHandler<StreamRecordingErrorOccurredEventArgs> _recordingErrorOccurred;
-        private Native.RecorderErrorCallback _recorderErrorCallback;
 
-        private List<StreamRecorderFileFormat> _formats;
-        private List<StreamRecorderAudioCodec> _audioCodec;
-        private List<StreamRecorderVideoCodec> _videoCodec;
-        private List<StreamRecorderVideoResolution> _resolutions;
-        StreamRecorderVideoResolution _videoResolution = null;
+        private bool _audioEnabled;
+        private bool _videoEnabled;
+        private StreamRecorderVideoFormat _sourceFormat;
 
         /// <summary>
-        /// Stream recorder constructor.
+        /// Initialize a new instance of the <see cref="StreamRecorder"/> class.
         /// </summary>
+        /// <exception cref="NotSupportedException">The feature is not supported.</exception>
         public StreamRecorder()
         {
-            int ret = Native.Create(out _handle);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to create stream recorder");
-            }
-            _formats = new List<StreamRecorderFileFormat>();
-            _audioCodec = new List<StreamRecorderAudioCodec>();
-            _videoCodec = new List<StreamRecorderVideoCodec>();
-            _resolutions = new List<StreamRecorderVideoResolution>();
-            _videoResolution = new StreamRecorderVideoResolution(_handle);
-        }
-
-        /// <summary>
-        /// Stream recorder destructor.
-        /// </summary>
-        ~StreamRecorder()
-        {
-            Dispose(false);
-        }
-
-        /// <summary>
-        /// Event that occurs when streamrecorder state is changed.
-        /// </summary>
-        public event EventHandler<StreamRecorderNotifiedEventArgs> RecorderNotified
-        {
-            add
-            {
-                if (_recorderNotified == null)
-                {
-                    RegisterStreamRecorderNotifiedEvent();
-                }
-                _recorderNotified += value;
-            }
-            remove
-            {
-                _recorderNotified -= value;
-                if (_recorderNotified == null)
-                {
-                    UnregisterStreamRecorderNotifiedEvent();
-                }
-            }
-        }
-
-        /// <summary>
-        /// Event that occurs when buffer had comsumed completely.
-        /// </summary>
-        public event EventHandler<StreamRecordingBufferConsumedEventArgs> BufferConsumed
-        {
-            add
+            try
             {
-                if (_bufferConsumed == null)
-                {
-                    RegisterBufferComsumedEvent();
-                }
-                _bufferConsumed += value;
+                Native.Create(out _handle).ThrowIfError("Failed to create stream recorder.");
             }
-            remove
+            catch (TypeLoadException)
             {
-                _bufferConsumed -= value;
-                if (_bufferConsumed == null)
-                {
-                    UnregisterBufferComsumedEvent();
-                }
-            }
-        }
-
-        /// <summary>
-        /// Event that occurs when recording status changed.
-        /// </summary>
-        public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged
-        {
-            add
-            {
-                if (_recordingStatusChanged == null)
-                {
-                    RegisterRecordingStatusChangedEvent();
-                }
-                _recordingStatusChanged += value;
-            }
-            remove
-            {
-                _recordingStatusChanged -= value;
-                if (_recordingStatusChanged == null)
-                {
-                    UnregisterRecordingStatusChangedEvent();
-                }
+                throw new NotSupportedException("StreamRecorder is not supported.");
             }
-        }
 
-        /// <summary>
-        /// Event that occurs when recording limit is reached.
-        /// </summary>
-        public event EventHandler<StreamRecordingLimitReachedEventArgs> RecordingLimitReached
-        {
-            add
-            {
-                if (_recordingLimitReached == null)
-                {
-                    RegisterRecordingLimitReachedEvent();
-                }
-                _recordingLimitReached += value;
-            }
-            remove
-            {
-                _recordingLimitReached -= value;
-                if (_recordingLimitReached == null)
-                {
-                    UnregisterRecordingLimitReachedEvent();
-                }
-            }
-        }
+            LoadCapabilities();
 
-        /// <summary>
-        /// Event that occurs when an error occured during recorder operation.
-        /// </summary>
-        public event EventHandler<StreamRecordingErrorOccurredEventArgs> RecordingErrorOccurred
-        {
-            add
-            {
-                if (_recordingErrorOccurred == null)
-                {
-                    RegisterRecordingErrorOccurredEvent();
-                }
-                _recordingErrorOccurred += value;
-            }
-            remove
-            {
-                _recordingErrorOccurred -= value;
-                if (_recordingErrorOccurred == null)
-                {
-                    UnregisterRecordingErrorOccurredEvent();
-                }
-            }
+            RegisterStreamRecorderNotifiedEvent();
+            RegisterBufferConsumedEvent();
+            RegisterRecordingStatusChangedEvent();
+            RegisterRecordingErrorOccurredEvent();
+            RegisterRecordingLimitReachedEvent();
         }
 
-        /// <summary>
-        /// The file path to record.
-        /// </summary>
-        /// <remarks>
-        /// If the same file already exists in the file system, then old file
-        /// will be overwritten.
-        /// </remarks>
-        public string FilePath
+        internal NativeHandle Handle
         {
             get
             {
-                IntPtr val;
-                int ret = Native.GetFileName(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
+                if (_disposed)
                 {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get filepath, " + (StreamRecorderError)ret);
+                    throw new ObjectDisposedException(nameof(StreamRecorder));
                 }
-                string result = Marshal.PtrToStringAnsi(val);
-                LibcSupport.Free(val);
-                return result;
-            }
-            set
-            {
-                int ret = Native.SetFileName(_handle, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set filepath, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret, "Failed to set filepath");
-                }
-            }
-        }
-
-        /// <summary>
-        /// Get the current state of the stream recorder.
-        /// </summary>
-        /// <value> The current state of stream recorder.
-        public StreamRecorderState State
-        {
-            get
-            {
-                int val = 0;
 
-                int ret = Native.GetState(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get stream recorder state, " + (StreamRecorderError)ret);
-                }
-                return (StreamRecorderState)val;
+                return _handle;
             }
         }
 
         /// <summary>
-        /// Get/Set the file format for recording media stream.
+        /// Gets the current state of the stream recorder.
         /// </summary>
-        /// <remarks>
-        /// Must set <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>.
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// </remarks>
-        /// <exception cref="ArgumentException">The format does not valid.</exception>
-        /// <seealso cref="SupportedFileFormats"/>
-        public StreamRecorderFileFormat FileFormat
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
+        public RecorderState State
         {
             get
             {
-                int val = 0;
-
-                int ret = Native.GetFileFormat(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get file format, " + (StreamRecorderError)ret);
-                }
-                return (StreamRecorderFileFormat)val;
-            }
-            set
-            {
-                int ret = Native.SetFileFormat(_handle, (int)value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set file format, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret);
-                }
-            }
-        }
+                Native.GetState(Handle, out var val).ThrowIfError("Failed to get the stream recorder state.");
 
-        /// <summary>
-        /// The audio codec for encoding an audio stream.
-        /// </summary>
-        /// <remarks>
-        /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
-        /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
-        /// </remarks>
-        /// <exception cref="ArgumentException">The codec does not valid.</exception>
-        /// <seealso cref="SupportedAudioEncodings"/>
-        public StreamRecorderAudioCodec AudioCodec
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetAudioEncoder(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get audio codec, " + (StreamRecorderError)ret);
-                }
-                return (StreamRecorderAudioCodec)val;
-            }
-            set
-            {
-                int ret = Native.SetAudioEncoder(_handle, (int)value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set audio codec, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret);
-                }
-            }
-        }
-
-        /// <summary>
-        /// The video codec for encoding video stream.
-        /// </summary>
-        /// <remarks>
-        /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
-        /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
-        /// </remarks>
-        /// <exception cref="ArgumentException">The codec does not valid.</exception>
-        /// <seealso cref="SupportedVideoEncodings"/>
-        public StreamRecorderVideoCodec VideoCodec
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetVideoEncoder(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get video codec, " + (StreamRecorderError)ret);
-                }
-                return (StreamRecorderVideoCodec)val;
-            }
-            set
-            {
-                int ret = Native.SetVideoEncoder(_handle, (int)value);
-
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set video codec, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret);
-                }
-            }
-        }
-
-        /// <summary>
-        /// The maximum size of a recording file in KB(kilobytes). If 0, means
-        /// unlimited recording size.
-        /// </summary>
-        /// <remarks>
-        /// After reaching the limitation, the data which is being recorded will
-        /// be discarded and not written to the file.
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// </remarks>
-        /// <exception cref="ArgumentException">The value set to below 0.</exception>
-        /// <seealso cref="StreamRecordingLimitReachedEventArgs"/>
-        public int SizeLimit
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetRecordingLimit(_handle, 1, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get size limit, " + (StreamRecorderError)ret);
-                }
                 return val;
             }
-            set
-            {
-                int ret = Native.SetRecordingLimit(_handle, 1, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set sizelimit, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret, "Failed to set size limit");
-                }
-            }
         }
 
-        /// <summary>
-        /// The time limit of a recording file in Seconds. If 0, means unlimited recording
-        /// time.
-        /// </summary>
-        /// <remarks>
-        /// After reaching the limitation, the data which is being recorded will
-        /// be discarded and not written to the file.
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// </remarks>
-        /// <exception cref="ArgumentException">The value set to below 0.</exception>
-        /// <seealso cref="StreamRecordingLimitReachedEventArgs"/>
-        public int TimeLimit
+        private void ValidateState(params RecorderState[] required)
         {
-            get
-            {
-                int val = 0;
+            Debug.Assert(required.Length > 0);
 
-                int ret = Native.GetRecordingLimit(_handle, 0, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get time limit, " + (StreamRecorderError)ret);
-                }
-                return val;
-            }
-            set
+            var curState = State;
+            if (!required.Contains(curState))
             {
-                int ret = Native.SetRecordingLimit(_handle, 0, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set timelimit, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret, "Failed to set time limit");
-                }
+                throw new InvalidOperationException($"The stream recorder is not in a valid state. " +
+                    $"Current State : { curState }, Valid State : { string.Join(", ", required) }.");
             }
         }
 
+        #region Operation methods
         /// <summary>
-        /// The sampling rate of an audio stream in hertz.
+        /// Prepares the stream recorder with the specified options.
         /// </summary>
-        /// <remarks>
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
-        /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>.
-        /// </remarks>
-        /// <exception cref="ArgumentException">The value set to below 0.</exception>
-        public int AudioSampleRate
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetAudioSampleRate(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get audio samplerate, " + (StreamRecorderError)ret);
-                }
-                return val;
-            }
-            set
-            {
-                int ret = Native.SetAudioSampleRate(_handle, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set audio samplerate, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio samplerate");
-                }
-            }
-        }
-
-        /// <summary>
-        /// The bitrate of an audio encoder in bits per second.
-        /// </summary>
-        /// <remarks>
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
-        /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
-        /// </remarks>
-        /// <exception cref="ArgumentException">The value set to below 0.</exception>
-        public int AudioBitRate
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetAudioEncoderBitrate(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get audio bitrate, " + (StreamRecorderError)ret);
-                }
-                return val;
-            }
-            set
-            {
-                int ret = Native.SetAudioEncoderBitrate(_handle, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set audio bitrate, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio bitrate");
-                }
-            }
-        }
-
-        /// <summary>
-        /// The bitrate of an video encoder in bits per second.
-        /// </summary>
-        /// <remarks>
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
-        /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
-        /// </remarks>
-        /// <exception cref="ArgumentException">The value set to below 0.</exception>
-        public int VideoBitRate
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetVideoEncoderBitrate(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get video bitrate, " + (StreamRecorderError)ret);
-                }
-                return val;
-            }
-            set
-            {
-                int ret = Native.SetVideoEncoderBitrate(_handle, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set video bitrate, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret, "Failed to set video bitrate");
-                }
-            }
-        }
-
-        /// <summary>
-        /// The video frame rate for recording media stream.
-        /// </summary>
-        /// <remarks>
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
-        /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
-        /// </remarks>
-        /// <exception cref="NotSupportedException">The value set to below 0.</exception>
-        public int VideoFrameRate
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetVideoFramerate(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get video framerate, " + (StreamRecorderError)ret);
-                }
-                return val;
-            }
-            set
-            {
-                int ret = Native.SetVideoFramerate(_handle, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set video framerate, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Get or Set the video source format for recording media stream.
-        /// </summary>
-        /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
-        /// <seealso cref="StreamRecorderVideoSourceFormat"/>
-        public StreamRecorderVideoSourceFormat VideoSourceFormat
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetVideoSourceFormat(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get video framerate, " + (StreamRecorderError)ret);
-                }
-                return (StreamRecorderVideoSourceFormat)val;
-            }
-            set
-            {
-                int ret = Native.SetVideoSourceFormat(_handle, (int)value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set video framerate, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret);
-                }
-            }
-        }
-
-        /// <summary>
-        /// The number of audio channel.
-        /// </summary>
-        /// <remarks>
-        /// The attribute is applied only in Created state.
-        /// For mono recording, set channel to 1.
-        /// For stereo recording, set channel to 2.
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// </remarks>
-        /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
-        public int AudioChannel
-        {
-            get
-            {
-                int val = 0;
-
-                int ret = Native.GetAudioChannel(_handle, out val);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to get audio channel, " + (StreamRecorderError)ret);
-                }
-                return val;
-            }
-            set
-            {
-                int ret = Native.SetAudioChannel(_handle, value);
-                if ((StreamRecorderError)ret != StreamRecorderError.None)
-                {
-                    Log.Error(StreamRecorderLog.Tag, "Failed to set audio channel, " + (StreamRecorderError)ret);
-                    StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio channel");
-                }
-            }
-        }
-
-        /// <summary>
-        /// Video resolution of the video recording.
-        /// </summary>
-        /// <remarks>
-        /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
-        /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
-        /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
-        /// </remarks>
-        /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
-        /// <seealso cref="SupportedVideoResolutions"/>
-        public StreamRecorderVideoResolution Resolution
+        /// <remarks>The recorder must be <see cref="RecorderState.Idle"/>.</remarks>
+        /// <param name="options">The options for recording.</param>
+        /// <exception cref="InvalidOperationException">The recorder is not in the valid state.</exception>
+        /// <exception cref="ArgumentException">Both <see cref="StreamRecorderOptions.Audio"/> and
+        ///     <see cref="StreamRecorderOptions.Video"/> are null.
+        /// </exception>
+        /// <exception cref="NotSupportedException"><paramref name="options"/> contains a value which is not supported.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
+        /// <seealso cref="Unprepare"/>
+        /// <seealso cref="Start"/>
+        /// <seealso cref="StreamRecorderOptions"/>
+        /// <seealso cref="StreamRecorderAudioOptions"/>
+        /// <seealso cref="StreamRecorderVideoOptions"/>
+        public void Prepare(StreamRecorderOptions options)
         {
-            get
+            if (options == null)
             {
-                return _videoResolution;
+                throw new ArgumentNullException(nameof(options));
             }
-        }
 
-        /// <summary>
-        /// Retrieves all the file formats supported by the stream recorder.
-        /// </summary>
-        /// <returns>
-        /// It returns a list containing all the supported file
-        /// formats by Stream recorder.
-        /// </returns>
-        /// <seealso cref="StreamRecorderFileFormat"/>
-        public IEnumerable<StreamRecorderFileFormat> SupportedFileFormats
-        {
-            get
-            {
-                if (_formats.Count == 0)
-                {
-                    Native.FileFormatCallback callback = (StreamRecorderFileFormat format, IntPtr userData) =>
-                    {
-                        _formats.Add(format);
-                        return true;
-                    };
-                    int ret = Native.FileFormats(_handle, callback, IntPtr.Zero);
-                    if (ret != (int)StreamRecorderError.None)
-                    {
-                        StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported fileformats");
-                    }
-                }
-                return _formats;
-            }
-        }
+            ValidateState(RecorderState.Idle);
 
-        /// <summary>
-        /// Retrieves all the audio encoders supported by the recorder.
-        /// </summary>
-        /// <returns>
-        /// It returns a list containing all the supported audio encoders
-        /// by recorder.
-        /// </returns>
-        /// <seealso cref="StreamRecorderAudioCodec"/>
-        public IEnumerable<StreamRecorderAudioCodec> SupportedAudioEncodings
-        {
-            get
-            {
-                if (_audioCodec.Count == 0)
-                {
-                    Native.AudioEncoderCallback callback = (StreamRecorderAudioCodec codec, IntPtr userData) =>
-                    {
-                        _audioCodec.Add(codec);
-                        return true;
-                    };
-                    int ret = Native.AudioEncoders(_handle, callback, IntPtr.Zero);
-                    if (ret != (int)StreamRecorderError.None)
-                    {
-                        StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported audio encoders");
-                    }
-                }
-                return _audioCodec;
-            }
-        }
+            options.Apply(this);
 
-        /// <summary>
-        /// Retrieves all the video encoders supported by the recorder.
-        /// </summary>
-        /// <returns>
-        /// It returns a list containing all the supported video encoders
-        /// by recorder.
-        /// </returns>
-        /// <seealso cref="StreamRecorderVideoCodec"/>
-        public IEnumerable<StreamRecorderVideoCodec> SupportedVideoEncodings
-        {
-            get
-            {
-                if (_videoCodec.Count == 0)
-                {
-                    Native.VideoEncoderCallback callback = (StreamRecorderVideoCodec codec, IntPtr userData) =>
-                    {
-                        _videoCodec.Add(codec);
-                        return true;
-                    };
-                    int ret = Native.VideoEncoders(_handle, callback, IntPtr.Zero);
-                    if (ret != (int)StreamRecorderError.None)
-                    {
-                        StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported video encoders");
-                    }
-                }
-                return _videoCodec;
-            }
-        }
+            Native.Prepare(Handle).ThrowIfError("Failed to prepare stream recorder.");
 
-        /// <summary>
-        /// Retrieves all the video resolutions supported by the recorder.
-        /// </summary>
-        /// <returns>
-        /// It returns videoresolution list containing the width and height of
-        /// different resolutions supported by recorder.
-        /// </returns>
-        /// <seealso cref="StreamRecorderVideoResolution"/>
-        public IEnumerable<StreamRecorderVideoResolution> SupportedVideoResolutions
-        {
-            get
-            {
-                if (_resolutions.Count == 0)
-                {
-                    Native.VideoResolutionCallback callback = (int width, int height, IntPtr userData) =>
-                    {
-                        StreamRecorderVideoResolution temp = new StreamRecorderVideoResolution(width, height);
-                        _resolutions.Add(temp);
-                        return true;
-                    };
-                    int ret = Native.VideoResolution(_handle, callback, IntPtr.Zero);
-                    if (ret != (int)StreamRecorderError.None)
-                    {
-                        StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported video resolutions");
-                    }
-                }
-                return _resolutions;
-            }
-        }
+            _audioEnabled = options.Audio != null;
+            _videoEnabled = options.Video != null;
 
-        /// <summary>
-        /// Prepare the stream recorder.
-        /// </summary>
-        /// <remarks>
-        /// Before calling the function, it is required to set <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>,
-        /// <see cref="StreamRecorderAudioCodec"/>, <see cref="StreamRecorderVideoCodec"/> and <see cref="StreamRecorderFileFormat"/> properties of recorder.
-        /// </remarks>
-        /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
-        /// <seealso cref="Unprepare"/>
-        public void Prepare()
-        {
-            int ret = Native.Prepare(_handle);
-            if (ret != (int)StreamRecorderError.None)
+            if (options.Video != null)
             {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to prepare stream recorder");
+                _sourceFormat = options.Video.SourceFormat;
             }
         }
 
         /// <summary>
-        /// Resets the stream recorder.
+        /// Unprepares the stream recorder.
         /// </summary>
         /// <remarks>
-        /// The recorder state must be <see cref="StreamRecorderState.Prepared"/> state by <see cref="Prepare"/>, <see cref="Cancel"/> and <see cref="Commit"/>.
-        /// The StreamRecorder state will be <see cref="StreamRecorderState.Created"/>.
+        /// The recorder state must be <see cref="RecorderState.Ready"/> state by
+        /// <see cref="Prepare(StreamRecorderOptions)"/>, <see cref="Cancel"/> and <see cref="Commit"/>.\n
+        /// The recorder state will be <see cref="RecorderState.Idle"/>.\n
+        /// \n
+        /// It has no effect if the recorder is already in the <see cref="RecorderState.Idle"/> state.
         /// </remarks>
-        /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
+        /// <exception cref="InvalidOperationException">The recorder is not in the valid state.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
         /// <seealso cref="Prepare"/>
         public void Unprepare()
         {
-            int ret = Native.Unprepare(_handle);
-            if (ret != (int)StreamRecorderError.None)
+            if (State == RecorderState.Idle)
             {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to reset the stream recorder");
+                return;
             }
+
+            ValidateState(RecorderState.Ready);
+
+            Native.Unprepare(Handle).ThrowIfError("Failed to reset the stream recorder.");
         }
 
         /// <summary>
-        /// Starts the recording.
+        /// Starts recording.
         /// </summary>
         /// <remarks>
-        /// If file path has been set to an existing file, this file is removed automatically and updated by new one.
-        ///    The filename should be set before this function is invoked.
-        ///    The recorder state must be <see cref="StreamRecorderState.Prepared"/> state by <see cref="Prepare"/> or
-        ///    <see cref="StreamRecorderState.Paused"/> state by <see cref="Pause"/>.
-        ///    The filename shuild be set by <see cref="FilePath"/>
+        ///    The recorder state must be <see cref="RecorderState.Ready"/> state by
+        ///    <see cref="Prepare(StreamRecorderOptions)"/> or
+        ///    <see cref="RecorderState.Paused"/> state by <see cref="Pause"/>.\n
+        /// \n
+        /// It has no effect if the recorder is already in the <see cref="RecorderState.Recording"/> state.
         /// </remarks>
-        /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
-        /// <exception cref="UnauthorizedAccessException">The access ot the resources can not be granted.</exception>
+        /// <exception cref="InvalidOperationException">The recorder is not in the valid state.</exception>
+        /// <exception cref="UnauthorizedAccessException">The access of the resources can not be granted.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
         /// <seealso cref="Pause"/>
         /// <seealso cref="Commit"/>
         /// <seealso cref="Cancel"/>
-        /// <seealso cref="FilePath"/>
-        /// <seealso cref="FileFormat"/>
         public void Start()
         {
-            int ret = Native.Start(_handle);
-            if (ret != (int)StreamRecorderError.None)
+            if (State == RecorderState.Recording)
             {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to start the stream recorder");
+                return;
             }
+
+            ValidateState(RecorderState.Ready, RecorderState.Paused);
+
+            Native.Start(Handle).ThrowIfError("Failed to start the stream recorder.");
         }
 
         /// <summary>
-        /// Pause the recording.
+        /// Pauses recording.
         /// </summary>
         /// <remarks>
-        /// Recording can be resumed with <see cref="Start"/>.
+        /// Recording can be resumed with <see cref="Start"/>.\n
+        /// \n
+        ///    The recorder state must be <see cref="RecorderState.Recording"/> state by <see cref="Start"/> \n
+        /// \n
+        /// It has no effect if the recorder is already in the <see cref="RecorderState.Paused"/> state.
         /// </remarks>
-        /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
+        /// <exception cref="InvalidOperationException">The recorder is not in the valid state.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
         /// <seealso cref="Start"/>
         /// <seealso cref="Commit"/>
         /// <seealso cref="Cancel"/>
         public void Pause()
         {
-            int ret = Native.Pause(_handle);
-            if (ret != (int)StreamRecorderError.None)
+            if (State == RecorderState.Paused)
             {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to pause the stream recorder");
+                return;
             }
+
+            ValidateState(RecorderState.Recording);
+
+            Native.Pause(Handle).ThrowIfError("Failed to pause the stream recorder.");
         }
 
         /// <summary>
         /// Stops recording and saves the result.
         /// </summary>
         /// <remarks>
-        /// The recorder state must be <see cref="StreamRecorderState.Recording"/> state by <see cref="Start"/> or
-        ///  <see cref="StreamRecorderState.Paused"/> state by <see cref="Pause"/>
-        /// When you want to record audio or video file, you need to add privilege according to rules below additionally.
+        /// The recorder state must be <see cref="RecorderState.Recording"/> state by <see cref="Start"/> or
+        /// <see cref="RecorderState.Paused"/> state by <see cref="Pause"/>.\n
+        /// \n
+        /// The recorder state will be <see cref="RecorderState.Ready"/> after commit.\n
         /// <para>
-        /// http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage.
-        /// http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage.
+        /// http://tizen.org/privilege/mediastorage is needed if the save path are relevant to media storage.
+        /// http://tizen.org/privilege/externalstorage is needed if the save path are relevant to external storage.
         /// </para>
         /// </remarks>
-        /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
-        /// <exception cref="UnauthorizedAccessException">The access ot the resources can not be granted.</exception>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <exception cref="InvalidOperationException">The recorder is not in the valid state.</exception>
+        /// <exception cref="UnauthorizedAccessException">The access to the resources can not be granted.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
         /// <seealso cref="Start"/>
         /// <seealso cref="Pause"/>
         public void Commit()
         {
-            int ret = Native.Commit(_handle);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to save the recorded content");
-            }
+            ValidateState(RecorderState.Paused, RecorderState.Recording);
+
+            Native.Commit(Handle).ThrowIfError("Failed to commit.");
         }
 
         /// <summary>
-        /// Cancels the recording.
-        /// The recording data is discarded and not written in the recording file.
+        /// Cancels recording.
+        /// The recording data is discarded and not written.
         /// </summary>
+        /// <remarks>
+        /// The recorder state must be <see cref="RecorderState.Recording"/> state by <see cref="Start"/> or
+        /// <see cref="RecorderState.Paused"/> state by <see cref="Pause"/>.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">The recorder is not in the valid state.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
         /// <seealso cref="Start"/>
         /// <seealso cref="Pause"/>
         public void Cancel()
         {
-            int ret = Native.Cancel(_handle);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to cancel the recording");
-            }
-        }
-
-        /// <summary>
-        /// Push stream buffer as recording raw data.
-        /// </summary>
-        public void PushBuffer(MediaPacket packet)
-        {
-            IntPtr _packet_h = packet.GetHandle();
+            ValidateState(RecorderState.Paused, RecorderState.Recording);
 
-            Log.Info("Tizen.Multimedia.StreamRecorder", "PUSH stream buffer");
-            int ret = Native.PushStreamBuffer(_handle, _packet_h);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to push buffer");
-            }
-            Log.Info("Tizen.Multimedia.StreamRecorder", "PUSH stream buffer END");
+            Native.Cancel(Handle).ThrowIfError("Failed to cancel recording.");
         }
 
-        /// <summary>
-        /// Set the source type of pushed data.
-        /// </summary>
-        public void EnableSourceBuffer(StreamRecorderSourceType type)
+        private static bool AreVideoTypesMatched(StreamRecorderVideoFormat videoFormat, MediaFormatVideoMimeType mimeType)
         {
-            int ret = Native.EnableSourceBuffer(_handle, (int)type);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Failed to set EnableSourceBuffer");
-            }
+            return (videoFormat == StreamRecorderVideoFormat.Nv12 && mimeType == MediaFormatVideoMimeType.NV12) ||
+                (videoFormat == StreamRecorderVideoFormat.Nv21 && mimeType == MediaFormatVideoMimeType.NV21) ||
+                (videoFormat == StreamRecorderVideoFormat.I420 && mimeType == MediaFormatVideoMimeType.I420);
         }
 
         /// <summary>
-        /// Release any unmanaged resources used by this object.
+        /// Pushes a packet as recording raw data.
         /// </summary>
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
+        /// <param name="packet">An audio or video packet to record.</param>
+        /// <remarks>
+        /// The recorder state must be <see cref="RecorderState.Recording"/> state by <see cref="Start"/>.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">
+        ///     The recorder is not in the valid state.\n
+        ///     -or-\n
+        ///     <paramref name="packet"/> is an audio packet but audio recording is not enabled(See <see cref="StreamRecorderOptions.Audio"/>).\n
+        ///     -or-\n
+        ///     <paramref name="packet"/> is a video packet but video recording is not enabled(See <see cref="StreamRecorderOptions.Video"/>).\n
+        ///     -or-\n
+        ///     <paramref name="packet"/> is a video packet but the <see cref="VideoMediaFormat.MimeType"/> does not match the video source format.\n
+        ///     -or-\n
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="StreamRecorder"/> has already been disposed.</exception>
+        /// <see cref="Prepare(StreamRecorderOptions)"/>
+        /// <seealso cref="StreamRecorderOptions.Audio"/>
+        /// <seealso cref="StreamRecorderOptions.Video"/>
+        /// <seealso cref="StreamRecorderVideoOptions.SourceFormat"/>
+        public void PushBuffer(MediaPacket packet)
         {
-            if (!_disposed)
+            if (packet == null)
             {
-                if (disposing)
-                {
-                    // to be used if there are any other disposable objects
-                }
-                if (_handle != IntPtr.Zero)
-                {
-                    Native.Destroy(_handle);
-                    _handle = IntPtr.Zero;
-                }
-                _disposed = true;
+                throw new ArgumentNullException(nameof(packet));
             }
-        }
 
-        private void RegisterStreamRecorderNotifiedEvent()
-        {
-            _notifiedCallback = (StreamRecorderState previous, StreamRecorderState current, StreamRecorderNotify notify, IntPtr userData) =>
-            {
-                StreamRecorderNotifiedEventArgs eventArgs = new StreamRecorderNotifiedEventArgs(previous, current, notify);
-                _recorderNotified?.Invoke(this, eventArgs);
-            };
-            int ret = Native.SetNotifiedCallback(_handle, _notifiedCallback, IntPtr.Zero);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Setting notify callback failed");
-            }
-        }
+            ValidateState(RecorderState.Recording);
 
-        private void UnregisterStreamRecorderNotifiedEvent()
-        {
-            int ret = Native.UnsetNotifiedCallback(_handle);
-            if (ret != (int)StreamRecorderError.None)
+            switch (packet.Format.Type)
             {
-                StreamRecorderErrorFactory.ThrowException(ret, "Unsetting notify callback failed");
-            }
-        }
+                case MediaFormatType.Audio:
+                    if (_audioEnabled == false)
+                    {
+                        throw new InvalidOperationException("Audio option is not set.");
+                    }
+                    break;
 
-        private void RegisterBufferComsumedEvent()
-        {
-            _bufferConsumedCallback = (IntPtr buffer, IntPtr userData) =>
-            {
-                StreamRecordingBufferConsumedEventArgs eventArgs = new StreamRecordingBufferConsumedEventArgs(buffer);
-                _bufferConsumed?.Invoke(this, eventArgs);
-            };
-            int ret = Native.SetBufferConsumedCallback(_handle, _bufferConsumedCallback, IntPtr.Zero);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Setting buffer consumed callback failed");
-            }
-        }
+                case MediaFormatType.Video:
+                    if (_videoEnabled == false)
+                    {
+                        throw new InvalidOperationException("Video option is not set.");
+                    }
 
-        private void UnregisterBufferComsumedEvent()
-        {
-            int ret = Native.UnsetBufferConsumedCallback(_handle);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Unsetting buffer consumed callback failed");
-            }
-        }
+                    if (AreVideoTypesMatched(_sourceFormat, (packet.Format as VideoMediaFormat).MimeType) == false)
+                    {
+                        throw new InvalidOperationException("Video format does not match.");
+                    }
 
-        private void RegisterRecordingStatusChangedEvent()
-        {
-            _recordingStatusCallback = (ulong elapsedTime, ulong fileSize, IntPtr userData) =>
-            {
-                RecordingStatusChangedEventArgs eventArgs = new RecordingStatusChangedEventArgs((long)elapsedTime, (long)fileSize);
-                _recordingStatusChanged?.Invoke(this, eventArgs);
-            };
-            int ret = Native.SetStatusChangedCallback(_handle, _recordingStatusCallback, IntPtr.Zero);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Setting status changed callback failed");
-            }
-        }
+                    break;
 
-        private void UnregisterRecordingStatusChangedEvent()
-        {
-            int ret = Native.UnsetStatusChangedCallback(_handle);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Unsetting status changed callback failed");
+                default:
+                    throw new ArgumentException("Packet is not valid.");
             }
-        }
 
-        private void RegisterRecordingLimitReachedEvent()
-        {
-            _recordingLimitReachedCallback = (StreamRecordingLimitType type, IntPtr userData) =>
-            {
-                StreamRecordingLimitReachedEventArgs eventArgs = new StreamRecordingLimitReachedEventArgs(type);
-                _recordingLimitReached?.Invoke(this, eventArgs);
-            };
-            int ret = Native.SetLimitReachedCallback(_handle, _recordingLimitReachedCallback, IntPtr.Zero);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Setting limit reached callback failed");
-            }
+            Native.PushStreamBuffer(Handle, MediaPacket.Lock.Get(packet).GetHandle())
+                .ThrowIfError("Failed to push buffer.");
         }
 
-        private void UnregisterRecordingLimitReachedEvent()
-        {
-            int ret = Native.UnsetLimitReachedCallback(_handle);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Unsetting limit reached callback failed");
-            }
-        }
+        #endregion
 
-        private void RegisterRecordingErrorOccurredEvent()
+        #region Dispose support
+        /// <summary>
+        /// Release any unmanaged resources used by this object.
+        /// </summary>
+        public void Dispose()
         {
-            _recorderErrorCallback = (StreamRecorderErrorCode error, StreamRecorderState current, IntPtr userData) =>
-            {
-                StreamRecordingErrorOccurredEventArgs eventArgs = new StreamRecordingErrorOccurredEventArgs(error, current);
-                _recordingErrorOccurred?.Invoke(this, eventArgs);
-            };
-            int ret = Native.SetErrorCallback(_handle, _recorderErrorCallback, IntPtr.Zero);
-            if (ret != (int)StreamRecorderError.None)
-            {
-                StreamRecorderErrorFactory.ThrowException(ret, "Setting Error callback failed");
-            }
+            Dispose(true);
         }
 
-        private void UnregisterRecordingErrorOccurredEvent()
+        /// <summary>
+        /// Releases the resources used by the StreamRecorder.
+        /// </summary>
+        /// <param name="disposing">
+        /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+        /// </param>
+        protected virtual void Dispose(bool disposing)
         {
-            int ret = Native.UnsetErrorCallback(_handle);
-            if (ret != (int)StreamRecorderError.None)
+            if (!_disposed)
             {
-                StreamRecorderErrorFactory.ThrowException(ret, "Unsetting Error callback failed");
+                _handle?.Dispose();
+
+                _disposed = true;
             }
         }
+        #endregion
     }
 }
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderAudioOptions.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderAudioOptions.cs
new file mode 100644 (file)
index 0000000..911cf34
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * 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 Native = Interop.StreamRecorder;
+
+namespace Tizen.Multimedia
+{
+    /// <summary>
+    /// Specifies the options associated with audio recording.
+    /// </summary>
+    /// <seealso cref="StreamRecorder"/>
+    /// <seealso cref="StreamRecorderOptions"/>
+    /// <seealso cref="StreamRecorderVideoOptions"/>
+    public class StreamRecorderAudioOptions
+    {
+        private const int DefaultSampleRate = 0;
+        private const int DefaultBitRate = 128000;
+        private const int DefaultChannels = 2;
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="StreamRecorderAudioOptions"/> class with the specified codec.
+        /// </summary>
+        /// <param name="codec">The <see cref="RecorderAudioCodec"/> for encoding audio stream.</param>
+        /// <remarks>
+        /// <see cref="SampleRate"/>, <see cref="BitRate"/> and <see cref="Channels"/> will be set as default.
+        /// </remarks>
+        /// <exception cref="ArgumentException"><paramref name="codec"/> is not valid.</exception>
+        public StreamRecorderAudioOptions(RecorderAudioCodec codec) :
+            this(codec, DefaultSampleRate, DefaultBitRate, DefaultChannels)
+        {
+        }
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="StreamRecorderAudioOptions"/> class with the specified
+        /// codec, sample rate, bit rate and channel value.
+        /// </summary>
+        /// <param name="codec">The <see cref="RecorderAudioCodec"/> for encoding audio stream.</param>
+        /// <param name="sampleRate">The sample rate for encoding audio stream.</param>
+        /// <param name="bitRate">The bit rate for encoding audio stream.</param>
+        /// <param name="channels">The number of channels for encoding audio stream.</param>
+        /// <exception cref="ArgumentException"><paramref name="codec"/> is not valid.</exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="sampleRate"/> is less than zero.\n
+        ///     -or-\n
+        ///     <paramref name="bitRate"/> is less than or equal to zero.\n
+        ///     -or-\n
+        ///     <paramref name="channels"/> is less than or equal to zero.
+        /// </exception>
+        public StreamRecorderAudioOptions(RecorderAudioCodec codec, int sampleRate, int bitRate, int channels)
+        {
+            Codec = codec;
+            SampleRate = sampleRate;
+            BitRate = bitRate;
+            Channels = channels;
+        }
+
+        private RecorderAudioCodec _codec;
+
+        /// <summary>
+        /// Gets or sets the audio codec for encoding an audio stream.
+        /// </summary>
+        /// <value>The codec for audio stream recording.</value>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is not valid.</exception>
+        /// <seealso cref="StreamRecorder.GetSupportedAudioCodecs"/>
+        public RecorderAudioCodec Codec
+        {
+            get => _codec;
+            set
+            {
+                ValidationUtil.ValidateEnum(typeof(RecorderAudioCodec), value, nameof(value));
+
+                _codec = value;
+            }
+        }
+
+        private int _sampleRate;
+
+        /// <summary>
+        /// Gets or sets the sampling rate of the audio stream in hertz.
+        /// </summary>
+        /// <remarks>If the value is zero, the sample rate will be decided based on input buffers.</remarks>
+        /// <value>The sample rate value for stream recorder. The default is zero.</value>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+        public int SampleRate
+        {
+            get => _sampleRate;
+            set
+            {
+                if (value < 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Sample rate can't be less than or equal to zero.");
+                }
+
+                _sampleRate = value;
+            }
+        }
+
+        private int _bitRate;
+
+        /// <summary>
+        /// Gets or sets the bit rate of the audio encoder in bits per second.
+        /// </summary>
+        /// <value>The bit rate value for audio stream recording. The default is 128000.</value>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than or equal to zero.</exception>
+        public int BitRate
+        {
+            get => _bitRate;
+            set
+            {
+                if (value <= 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Bit rate can't be less than or equal to zero.");
+                }
+
+                _bitRate = value;
+            }
+        }
+
+        private int _channels;
+
+        /// <summary>
+        /// Gets or sets the number of audio channels.
+        /// </summary>
+        /// <value>The number of audio channels for audio stream recording. The default is 2.</value>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than or equal to zero.</exception>
+        public int Channels
+        {
+            get => _channels;
+            set
+            {
+                if (value <= 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Channels can't be less than or equal to zero.");
+                }
+
+                _channels = value;
+            }
+        }
+
+        internal void Apply(StreamRecorder recorder)
+        {
+            recorder.ValidateAudioCodec(Codec);
+
+            Native.SetAudioEncoder(recorder.Handle, Codec.ToStreamRecorderEnum()).
+                ThrowIfError("Failed to set audio codec.");
+
+            Native.SetAudioSampleRate(recorder.Handle, SampleRate).
+                ThrowIfError("Failed to set audio sample rate.");
+
+            Native.SetAudioEncoderBitrate(recorder.Handle, BitRate).
+                ThrowIfError("Failed to set audio bit rate.");
+
+            Native.SetAudioChannel(recorder.Handle, Channels).
+                ThrowIfError("Failed to set audio channels.");
+        }
+    }
+
+}
@@ -18,25 +18,20 @@ using System;
 
 namespace Tizen.Multimedia
 {
+
     /// <summary>
-    /// An extended EventArgs.
+    /// Provides data for the <see cref="StreamRecorder.BufferConsumed"/> event.
     /// </summary>
-    public class StreamRecordingBufferConsumedEventArgs : EventArgs
+    public class StreamRecorderBufferConsumedEventArgs : EventArgs
     {
-        private IntPtr _buffer = IntPtr.Zero;
-
-        internal StreamRecordingBufferConsumedEventArgs(IntPtr buffer)
+        internal StreamRecorderBufferConsumedEventArgs(MediaPacket packet)
         {
-            _buffer = buffer;
+            Packet = packet;
         }
 
         /// <summary>
-        /// Consumed buffer.
+        /// Gets the packet that has consumed.
         /// </summary>
-        public IntPtr Buffer {
-            get {
-                return _buffer;
-            }
-        }
+        public MediaPacket Packet { get; }
     }
 }
index 58b6511..041d0f0 100644 (file)
  * limitations under the License.
  */
 
+using System;
+using System.Diagnostics;
+
 namespace Tizen.Multimedia
 {
+
+    /// <summary>
+    /// Specifies errors for <see cref="StreamRecorder"/>/
+    /// </summary>
+    public enum StreamRecorderError
+    {
+        /// <summary>
+        /// Internal error.
+        /// </summary>
+        InternalError = StreamRecorderErrorCode.InvalidOperation,
+        /// <summary>
+        /// Out of storage.
+        /// </summary>
+        OutOfStorage = StreamRecorderErrorCode.OutOfStorage
+    }
+
+    /// <summary>
+    /// Specifies the video source formats for <see cref="StreamRecorder"/>.
+    /// </summary>
+    public enum StreamRecorderVideoFormat
+    {
+        /// <summary>
+        /// Nv12 format.
+        /// </summary>
+        Nv12,
+        /// <summary>
+        /// Nv21 format.
+        /// </summary>
+        Nv21,
+        /// <summary>
+        /// I420 format.
+        /// </summary>
+        I420
+    }
+
+    #region Internal enums
+
     /// <summary>
     /// Enumeration for Audio Codec.
     /// </summary>
-    public enum StreamRecorderAudioCodec
+    internal enum StreamRecorderAudioCodec
     {
         /// <summary>
         /// AMR codec.
@@ -38,7 +78,7 @@ namespace Tizen.Multimedia
     /// <summary>
     /// Enumeration for the file container format.
     /// </summary>
-    public enum StreamRecorderFileFormat
+    internal enum StreamRecorderFileFormat
     {
         /// <summary>
         /// 3GP file format.
@@ -65,64 +105,22 @@ namespace Tizen.Multimedia
     /// <summary>
     /// Enumeration for the recorder notify type.
     /// </summary>
-    public enum StreamRecorderNotify
+    internal enum StreamRecorderNotify
     {
         /// <summary>
         /// None.
         /// </summary>
         None = 0,
         /// <summary>
-        /// State changed noti.
+        /// State changed.
         /// </summary>
         StateChanged
     }
 
     /// <summary>
-    /// Enumeration for the recording limit type.
-    /// </summary>
-    public enum StreamRecordingLimitType
-    {
-        /// <summary>
-        /// Time limit in seconds of recording file
-        /// </summary>
-        Time,
-        /// <summary>
-        /// Size limit in KB(KiloBytes) of recording file.
-        /// </summary>
-        Size
-    }
-
-    /// <summary>
-    /// Enumeration for stream recorder states.
-    /// </summary>
-    public enum StreamRecorderState
-    {
-        /// <summary>
-        /// Stream recorder is not created.
-        /// </summary>
-        None,
-        /// <summary>
-        /// Stream recorder is created, but not prepared.
-        /// </summary>
-        Created,
-        /// <summary>
-        /// Stream recorder is ready to record.
-        /// </summary>
-        Prepared,
-        /// <summary>
-        /// Stream recorder is recording pushed packet.
-        /// </summary>
-        Recording,
-        /// <summary>
-        /// Stream recorder is paused.
-        /// </summary>
-        Paused
-    }
-
-    /// <summary>
     /// Enumeration for video codec.
     /// </summary>
-    public enum StreamRecorderVideoCodec
+    internal enum StreamRecorderVideoCodec
     {
         /// <summary>
         /// H263 codec.
@@ -137,7 +135,7 @@ namespace Tizen.Multimedia
     /// <summary>
     /// Enumeration for source type.
     /// </summary>
-    public enum StreamRecorderSourceType
+    internal enum StreamRecorderSourceType
     {
         /// <summary>
         /// Video source
@@ -153,45 +151,122 @@ namespace Tizen.Multimedia
         VideoAudio
     }
 
-    /// <summary>
-    /// Enumeration for video source format.
-    /// </summary>
-    public enum StreamRecorderVideoSourceFormat
+    internal static class StreamRecorderEnumExtensions
     {
-        /// <summary>
-        /// Nv12 Video source format
-        /// </summary>
-        Nv12,
-        /// <summary>
-        /// Nv21 video source format
-        /// </summary>
-        Nv21,
-        /// <summary>
-        /// I420 video source format
-        /// </summary>
-        I420
-    }
+        internal static RecorderVideoCodec ToRecorderEnum(this StreamRecorderVideoCodec value)
+        {
+            switch (value)
+            {
+                case StreamRecorderVideoCodec.H263:
+                    return RecorderVideoCodec.H263;
 
-    /// <summary>
-    /// Enumeration for stream recorder failure error.
-    /// </summary>
-    public enum StreamRecorderErrorCode
-    {
-        /// <summary>
-        /// Sucessful.
-        /// </summary>
-        None = StreamRecorderError.None,
-        /// <summary>
-        /// Internal error.
-        /// </summary>
-        InvalidParameter = StreamRecorderError.InvalidParameter,
-        /// <summary>
-        /// Internal error.
-        /// </summary>
-        InvalidOperation = StreamRecorderError.InvalidOperation,
-        /// <summary>
-        /// Out of memory.
-        /// </summary>
-        OutOfMemory = StreamRecorderError.OutOfMemory
+                case StreamRecorderVideoCodec.Mpeg4:
+                    return RecorderVideoCodec.Mpeg4;
+            }
+
+            Debug.Fail("Unknown video codec value.");
+            return 0;
+        }
+
+        internal static StreamRecorderVideoCodec ToStreamRecorderEnum(this RecorderVideoCodec value)
+        {
+            switch (value)
+            {
+                case RecorderVideoCodec.H263:
+                    return StreamRecorderVideoCodec.H263;
+
+                case RecorderVideoCodec.Mpeg4:
+                    return StreamRecorderVideoCodec.Mpeg4;
+            }
+
+            throw new NotSupportedException($"{value.ToString()} is not supported.");
+        }
+
+
+        internal static RecorderAudioCodec ToRecorderEnum(this StreamRecorderAudioCodec value)
+        {
+            switch (value)
+            {
+                case StreamRecorderAudioCodec.Aac:
+                    return RecorderAudioCodec.Aac;
+
+                case StreamRecorderAudioCodec.Amr:
+                    return RecorderAudioCodec.Amr;
+
+                case StreamRecorderAudioCodec.Pcm:
+                    return RecorderAudioCodec.Pcm;
+            }
+
+            Debug.Fail("Unknown audio codec value.");
+            return 0;
+        }
+
+
+        internal static StreamRecorderAudioCodec ToStreamRecorderEnum(this RecorderAudioCodec value)
+        {
+            switch (value)
+            {
+                case RecorderAudioCodec.Aac:
+                    return StreamRecorderAudioCodec.Aac;
+
+                case RecorderAudioCodec.Amr:
+                    return StreamRecorderAudioCodec.Amr;
+
+                case RecorderAudioCodec.Pcm:
+                    return StreamRecorderAudioCodec.Pcm;
+            }
+
+            throw new NotSupportedException($"{value.ToString()} is not supported.");
+        }
+
+
+        internal static RecorderFileFormat ToRecorderEnum(this StreamRecorderFileFormat value)
+        {
+            switch (value)
+            {
+                case StreamRecorderFileFormat.ThreeGp:
+                    return RecorderFileFormat.ThreeGp;
+
+                case StreamRecorderFileFormat.Mp4:
+                    return RecorderFileFormat.Mp4;
+
+                case StreamRecorderFileFormat.Amr:
+                    return RecorderFileFormat.Amr;
+
+                case StreamRecorderFileFormat.Adts:
+                    return RecorderFileFormat.Adts;
+
+                case StreamRecorderFileFormat.Wav:
+                    return RecorderFileFormat.Wav;
+            }
+
+            Debug.Fail("Unknown file format value.");
+            return 0;
+        }
+
+
+        internal static StreamRecorderFileFormat ToStreamRecorderEnum(this RecorderFileFormat value)
+        {
+            switch (value)
+            {
+                case RecorderFileFormat.ThreeGp:
+                    return StreamRecorderFileFormat.ThreeGp;
+
+                case RecorderFileFormat.Mp4:
+                    return StreamRecorderFileFormat.Mp4;
+
+                case RecorderFileFormat.Amr:
+                    return StreamRecorderFileFormat.Amr;
+
+                case RecorderFileFormat.Adts:
+                    return StreamRecorderFileFormat.Adts;
+
+                case RecorderFileFormat.Wav:
+                    return StreamRecorderFileFormat.Wav;
+            }
+
+            throw new NotSupportedException($"{value.ToString()} is not supported.");
+        }
     }
+    #endregion
 }
  */
 
 using System;
+using System.IO;
 using Tizen.Internals.Errors;
 
 namespace Tizen.Multimedia
 {
-    internal enum StreamRecorderError
+    internal enum StreamRecorderErrorCode
     {
         None = ErrorCode.None,
         InvalidParameter = ErrorCode.InvalidParameter,
@@ -32,29 +33,40 @@ namespace Tizen.Multimedia
         NotSupported = ErrorCode.NotSupported,
     }
 
-    internal static class StreamRecorderErrorFactory
+    internal static class StreamRecorderErrorExtensions
     {
-        internal static void ThrowException(int errorCode, string errorMessage = null, string paramName = null)
+        internal static StreamRecorderErrorCode Ignore(this StreamRecorderErrorCode errorCode, StreamRecorderErrorCode ignore)
         {
-            StreamRecorderError err = (StreamRecorderError)errorCode;
-            if (string.IsNullOrEmpty(errorMessage))
+            return (ignore == errorCode) ? StreamRecorderErrorCode.None : errorCode;
+        }
+
+        internal static void ThrowIfError(this StreamRecorderErrorCode err, string errorMessage)
+        {
+            if (err == StreamRecorderErrorCode.None)
             {
-                errorMessage = err.ToString();
+                return;
             }
-            switch ((StreamRecorderError)errorCode)
+
+            switch (err)
             {
-                case StreamRecorderError.InvalidParameter:
-                    throw new ArgumentException(errorMessage, paramName);
-                case StreamRecorderError.OutOfMemory:
+                case StreamRecorderErrorCode.InvalidParameter:
+                    throw new ArgumentException(errorMessage);
+
+                case StreamRecorderErrorCode.OutOfMemory:
                     throw new OutOfMemoryException(errorMessage);
-                case StreamRecorderError.PermissionDenied:
+
+                case StreamRecorderErrorCode.PermissionDenied:
                     throw new UnauthorizedAccessException(errorMessage);
-                case StreamRecorderError.NotSupported:
+
+                case StreamRecorderErrorCode.NotSupported:
                     throw new NotSupportedException(errorMessage);
-                case StreamRecorderError.InvalidState:
-                case StreamRecorderError.InvalidOperation:
-                case StreamRecorderError.OutOfStorage:
+
+                case StreamRecorderErrorCode.InvalidState:
+                case StreamRecorderErrorCode.InvalidOperation:
                     throw new InvalidOperationException(errorMessage);
+
+                case StreamRecorderErrorCode.OutOfStorage:
+                    throw new IOException(errorMessage);
             }
         }
     }
@@ -19,24 +19,25 @@ using System;
 namespace Tizen.Multimedia
 {
     /// <summary>
-    /// An extended EventArgs class containing details about the recording limit.
+    /// Provides data for the <see cref="StreamRecorder.ErrorOccurred"/> event.
     /// </summary>
-    public class StreamRecordingLimitReachedEventArgs : EventArgs
+    public class StreamRecorderErrorOccurredEventArgs : EventArgs
     {
-        private StreamRecordingLimitType _type = StreamRecordingLimitType.Size;
-
-        internal StreamRecordingLimitReachedEventArgs(StreamRecordingLimitType type)
+        internal StreamRecorderErrorOccurredEventArgs(StreamRecorderError error, RecorderState state)
         {
-            _type = type;
+            Error = error;
+            State = state;
         }
 
         /// <summary>
-        /// The limitation type.
+        /// Gets the error code.
         /// </summary>
-        public StreamRecordingLimitType Type {
-            get {
-                return _type;
-            }
-        }
+        public StreamRecorderError Error { get; }
+
+        /// <summary>
+        /// Gets the state of the recorder.
+        /// </summary>
+        public RecorderState State { get; }
+
     }
 }
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderNotifiedEventArgs.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderNotifiedEventArgs.cs
deleted file mode 100644 (file)
index 0ac92f7..0000000
+++ /dev/null
@@ -1,66 +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;
-using System.Collections.Generic;
-
-namespace Tizen.Multimedia
-{
-    /// <summary>
-    /// An extended Eventargs class which contains interrupted policy details, previous and current
-    /// state of the recorder.
-    /// </summary>
-    public class StreamRecorderNotifiedEventArgs : EventArgs
-    {
-        private StreamRecorderState _previous = StreamRecorderState.None;
-        private StreamRecorderState _current = StreamRecorderState.None;
-        private StreamRecorderNotify _notify = StreamRecorderNotify.None;
-
-        internal StreamRecorderNotifiedEventArgs(StreamRecorderState previous, StreamRecorderState current, StreamRecorderNotify notify)
-        {
-            _previous = previous;
-            _current = current;
-            _notify = notify;
-        }
-
-        /// <summary>
-        /// The previous state of the stream recorder.
-        /// </summary>
-        public StreamRecorderState Previous {
-            get {
-                return _previous;
-            }
-        }
-
-        /// <summary>
-        /// The current state of the stream recorder.
-        /// </summary>
-        public StreamRecorderState Current {
-            get {
-                return _current;
-            }
-        }
-
-        /// <summary>
-        /// The notify of the event.
-        /// </summary>
-        public StreamRecorderNotify Notify {
-            get {
-                return _notify;
-            }
-        }
-    }
-}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderOptions.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderOptions.cs
new file mode 100644 (file)
index 0000000..49d9098
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * 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.Diagnostics;
+using Native = Interop.StreamRecorder;
+
+namespace Tizen.Multimedia
+{
+    /// <summary>
+    /// Specifies the options associated with <see cref="StreamRecorder"/>.
+    /// </summary>
+    /// <seealso cref="StreamRecorder"/>
+    /// <seealso cref="StreamRecorder.Prepare(StreamRecorderOptions)"/>
+    /// <seealso cref="StreamRecorderAudioOptions"/>
+    /// <seealso cref="StreamRecorderVideoOptions"/>
+    public class StreamRecorderOptions
+    {
+        /// <summary>
+        /// Initialize a new instance of the <see cref="StreamRecorderOptions"/> class with the specified
+        /// save path and file format.
+        /// </summary>
+        /// <param name="savePath">The path that the recording result is saved.</param>
+        /// <param name="fileFormat">The file format of output file.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="savePath"/>is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="savePath"/>is an empty string.\n
+        ///     -or-\n
+        ///     <paramref name="fileFormat"/> is not valid.
+        /// </exception>
+        public StreamRecorderOptions(string savePath, RecorderFileFormat fileFormat)
+        {
+            SavePath = savePath;
+            FileFormat = fileFormat;
+        }
+
+        private string _savePath;
+
+        /// <summary>
+        /// Gets or sets the file path to record.
+        /// </summary>
+        /// <remarks>
+        /// If the same file already exists in the file system, then old file will be overwritten.
+        /// </remarks>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/>is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="value"/>is an empty string.</exception>
+        public string SavePath
+        {
+            get => _savePath;
+            set
+            {
+                if (value == null)
+                {
+                    throw new ArgumentNullException(nameof(value));
+                }
+
+                if (string.IsNullOrWhiteSpace(value))
+                {
+                    throw new ArgumentException("Path can't be an empty string.", nameof(value));
+                }
+
+                _savePath = value;
+            }
+        }
+
+        private RecorderFileFormat _fileFormat;
+
+        /// <summary>
+        /// Gets or sets the file format for recording media stream.
+        /// </summary>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is not valid.</exception>
+        /// <seealso cref="StreamRecorder.GetSupportedFileFormats"/>
+        public RecorderFileFormat FileFormat
+        {
+            get => _fileFormat;
+            set
+            {
+                ValidationUtil.ValidateEnum(typeof(RecorderFileFormat), value, nameof(value));
+
+                _fileFormat = value;
+            }
+        }
+
+        private int _timeLimit;
+
+        /// <summary>
+        /// Gets or sets the time limit of recording.
+        /// </summary>
+        /// <value>
+        /// The maximum time of recording in seconds, or 0 for unlimited time.
+        /// </value>
+        /// <remarks>
+        /// After reaching the limitation, the data which is being recorded will
+        /// be discarded and not written to the file.
+        /// The recorder state must be <see cref="RecorderState.Idle"/> state.
+        /// </remarks>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+        /// <seealso cref="StreamRecorder.RecordingLimitReached"/>
+        /// <seealso cref="SizeLimit"/>
+        public int TimeLimit
+        {
+            get => _timeLimit;
+            set
+            {
+                if (value < 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Time limit can't be less than zero.");
+                }
+
+                _timeLimit = value;
+            }
+        }
+
+        private int _sizeLimit;
+
+        /// <summary>
+        /// Gets or sets the maximum size of a recording file.
+        /// </summary>
+        /// <value>
+        /// The maximum size of a recording file in kilobytes, or 0 for unlimited size.
+        /// </value>
+        /// <remarks>
+        /// After reaching the limitation, the data which is being recorded will
+        /// be discarded and not written to the file.
+        /// </remarks>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+        /// <seealso cref="StreamRecorder.RecordingLimitReached"/>
+        /// <seealso cref="TimeLimit"/>
+        public int SizeLimit
+        {
+            get => _sizeLimit;
+            set
+            {
+                if (value < 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Size limit can't be less than zero.");
+                }
+
+                _sizeLimit = value;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the options for audio recording.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="Audio"/> or <see cref="Video"/> must be set for recording.
+        /// </remarks>
+        /// <seealso cref="Video"/>
+        public StreamRecorderAudioOptions Audio { get; set; }
+
+        /// <summary>
+        /// Gets or sets the options for video recording.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="Audio"/> or <see cref="Video"/> must be set for recording.
+        /// </remarks>
+        /// <seealso cref="Audio"/>
+        public StreamRecorderVideoOptions Video { get; set; }
+
+        private StreamRecorderSourceType GetSourceType()
+        {
+            Debug.Assert(Audio != null || Video != null);
+
+            if (Audio != null && Video != null)
+            {
+                return StreamRecorderSourceType.VideoAudio;
+            }
+
+            return Audio != null ? StreamRecorderSourceType.Audio : StreamRecorderSourceType.Video;
+        }
+
+        internal void Apply(StreamRecorder recorder)
+        {
+            if (Audio == null && Video == null)
+            {
+                throw new ArgumentException("Both Audio and Video are not set.");
+            }
+
+            Native.EnableSourceBuffer(recorder.Handle, GetSourceType()).ThrowIfError("Failed to apply options.");
+
+            Native.SetFileName(recorder.Handle, SavePath).ThrowIfError("Failed to set save path.");
+
+            recorder.ValidateFileFormat(FileFormat);
+            Native.SetFileFormat(recorder.Handle, FileFormat.ToStreamRecorderEnum())
+                .ThrowIfError("Failed to set file format.");
+
+            Native.SetRecordingLimit(recorder.Handle, RecordingLimitType.Size, SizeLimit).
+                ThrowIfError("Failed to set size limit.");
+
+            Native.SetRecordingLimit(recorder.Handle, RecordingLimitType.Time, TimeLimit).
+                ThrowIfError("Failed to set time limit.");
+
+            Audio?.Apply(recorder);
+
+            Video?.Apply(recorder);
+        }
+    }
+}
@@ -19,37 +19,24 @@ using System;
 namespace Tizen.Multimedia
 {
     /// <summary>
-    /// An extended EventArgs class which contains details about error status and
-    /// state of the recorder when it failed.
+    /// Provides data for the <see cref="StreamRecorder.StateChanged"/> event.
     /// </summary>
-    public class StreamRecordingErrorOccurredEventArgs : EventArgs
+    public class StreamRecorderStateChangedEventArgs : EventArgs
     {
-        private StreamRecorderErrorCode _error = StreamRecorderErrorCode.InvalidOperation;
-        private StreamRecorderState _state = StreamRecorderState.None;
-
-        internal StreamRecordingErrorOccurredEventArgs(StreamRecorderErrorCode error, StreamRecorderState state)
+        internal StreamRecorderStateChangedEventArgs(RecorderState previous, RecorderState current)
         {
-            _error = error;
-            _state = state;
+            Previous = previous;
+            Current = current;
         }
 
         /// <summary>
-        /// The error code.
+        /// Gets the previous state of the stream recorder.
         /// </summary>
-        public StreamRecorderErrorCode Error {
-            get {
-                return _error;
-            }
-        }
+        public RecorderState Previous { get; }
 
         /// <summary>
-        /// The state of the recorder.
+        /// Gets the current state of the stream recorder.
         /// </summary>
-        public StreamRecorderState State {
-            get {
-                return _state;
-            }
-        }
-
+        public RecorderState Current { get; }
     }
 }
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoOptions.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoOptions.cs
new file mode 100644 (file)
index 0000000..3460532
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * 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 Native = Interop.StreamRecorder;
+
+namespace Tizen.Multimedia
+{
+    /// <summary>
+    /// Specifies the options associated with video recording.
+    /// </summary>
+    /// <seealso cref="StreamRecorder"/>
+    /// <seealso cref="StreamRecorderOptions"/>
+    /// <seealso cref="StreamRecorderAudioOptions"/>
+    public class StreamRecorderVideoOptions
+    {
+        private const int DefaultBitRate = 0;
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="StreamRecorderVideoOptions"/> class with the specified
+        /// codec, resolution, source format and frame rate.
+        /// </summary>
+        /// <param name="codec">The <see cref="RecorderVideoCodec"/> for encoding video stream.</param>
+        /// <param name="resolution">The resolution of video recording.</param>
+        /// <param name="sourceFormat">The format of source stream.</param>
+        /// <param name="frameRate">The frame rate for encoding video stream.</param>
+        /// <remarks>
+        /// <see cref="BitRate"/> will be set as default.
+        /// </remarks>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="codec"/> is not valid.\n
+        ///     -or-\n
+        ///     <paramref name="sourceFormat"/> is not valid.\n
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     Width or height of <paramref name="resolution"/> is less than or equal to zero.\n
+        ///     -or-\n
+        ///     <paramref name="frameRate"/> is less than or equal to zero.\n
+        /// </exception>
+        public StreamRecorderVideoOptions(RecorderVideoCodec codec, Size resolution,
+            StreamRecorderVideoFormat sourceFormat, int frameRate) :
+            this(codec, resolution, sourceFormat, frameRate, DefaultBitRate)
+        {
+        }
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="StreamRecorderVideoOptions"/> class with the specified
+        /// codec, resolution, source format, frame rate and bit rate.
+        /// </summary>
+        /// <param name="codec">The <see cref="RecorderVideoCodec"/> for encoding video stream.</param>
+        /// <param name="resolution">The resolution of video recording.</param>
+        /// <param name="sourceFormat">The format of source stream.</param>
+        /// <param name="frameRate">The frame rate for encoding video stream.</param>
+        /// <param name="bitRate">The bit rate for encoding video stream.</param>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="codec"/> is not valid.\n
+        ///     -or-\n
+        ///     <paramref name="sourceFormat"/> is not valid.\n
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     Width or height of <paramref name="resolution"/> is less than or equal to zero.\n
+        ///     -or-\n
+        ///     <paramref name="frameRate"/> is less than or equal to zero.\n
+        ///     -or-\n
+        ///     <paramref name="bitRate"/> is less than zero.
+        /// </exception>
+        public StreamRecorderVideoOptions(RecorderVideoCodec codec, Size resolution,
+            StreamRecorderVideoFormat sourceFormat, int frameRate, int bitRate)
+        {
+            Codec = codec;
+            Resolution = resolution;
+            SourceFormat = sourceFormat;
+            FrameRate = frameRate;
+            BitRate = bitRate;
+        }
+
+        private RecorderVideoCodec _codec;
+
+        /// <summary>
+        /// Gets or sets the video codec for encoding video stream.
+        /// </summary>
+        /// <value>The codec for video stream recording.</value>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is not valid.</exception>
+        /// <seealso cref="StreamRecorder.GetSupportedVideoCodecs"/>
+        public RecorderVideoCodec Codec
+        {
+            get => _codec;
+            set
+            {
+                ValidationUtil.ValidateEnum(typeof(RecorderVideoCodec), value, nameof(value));
+
+                _codec = value;
+            }
+        }
+
+        private Size _resolution;
+
+        /// <summary>
+        /// Gets or sets the resolution of the video recording.
+        /// </summary>
+        /// <value>The output resolution for video stream recording.</value>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     Width or height of <paramref name="value"/> is less than or equal to zero.
+        /// </exception>
+        /// <seealso cref="StreamRecorder.GetSupportedVideoResolutions"/>
+        public Size Resolution
+        {
+            get => _resolution;
+            set
+            {
+                if (value.Width <= 0 || value.Height <= 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Resolution can't be less than or equal to zero.");
+                }
+
+                _resolution = value;
+            }
+        }
+
+        private int _frameRate;
+
+        /// <summary>
+        /// Gets or sets the frame rate for recording media stream.
+        /// </summary>
+        /// <value>The frame rate value for video stream recording.</value>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than or equal to zero.</exception>
+        public int FrameRate
+        {
+            get => _frameRate;
+            set
+            {
+                if (value <= 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Frame rate can't be less than or equal to zero.");
+                }
+                _frameRate = value;
+            }
+        }
+
+        private StreamRecorderVideoFormat _sourceFormat;
+
+        /// <summary>
+        /// Gets or sets the video source format for recording media stream.
+        /// </summary>
+        /// <value>The source format of buffers for video stream recording.</value>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is not valid.</exception>
+        public StreamRecorderVideoFormat SourceFormat
+        {
+            get => _sourceFormat;
+            set
+            {
+                ValidationUtil.ValidateEnum(typeof(StreamRecorderVideoFormat), value, nameof(value));
+
+                _sourceFormat = value;
+            }
+        }
+
+        private int _bitRate;
+
+        /// <summary>
+        /// The bit rate of the video encoder in bits per second.
+        /// </summary>
+        /// <value>The bit rate value for video stream recording. The default is 0.</value>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+        public int BitRate
+        {
+            get => _bitRate;
+            set
+            {
+                if (value < 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Bit rate can't be less than or equal to zero.");
+                }
+                _bitRate = value;
+            }
+        }
+
+        internal void Apply(StreamRecorder recorder)
+        {
+            recorder.ValidateVideoCodec(Codec);
+
+            Native.SetVideoEncoder(recorder.Handle, Codec.ToStreamRecorderEnum()).
+                ThrowIfError("Failed to set video codec.");
+
+            recorder.ValidateVideoResolution(Resolution);
+
+            Native.SetVideoResolution(recorder.Handle, Resolution.Width, Resolution.Height).
+                ThrowIfError("Failed to set video resolution.");
+
+            Native.SetVideoFrameRate(recorder.Handle, FrameRate).
+                ThrowIfError("Failed to set video frame rate.");
+
+            Native.SetVideoEncoderBitRate(recorder.Handle, BitRate).
+                ThrowIfError("Failed to set video bit rate.");
+
+            Native.SetVideoSourceFormat(recorder.Handle, SourceFormat).
+                ThrowIfError("Failed to set video source format.");
+        }
+    }
+
+}
diff --git a/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoResolution.cs b/src/Tizen.Multimedia.StreamRecorder/StreamRecorder/StreamRecorderVideoResolution.cs
deleted file mode 100644 (file)
index 8523098..0000000
+++ /dev/null
@@ -1,87 +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;
-using Native = Interop.StreamRecorder;
-
-namespace Tizen.Multimedia
-{
-    /// <summary>
-    /// Resolution for stream recorder.
-    /// </summary>
-    public class StreamRecorderVideoResolution
-    {
-        private int _width, _height;
-        private bool _interopFlag;
-        internal IntPtr _Handle;
-
-        internal StreamRecorderVideoResolution(IntPtr handle)
-        {
-            _Handle = handle;
-            _interopFlag = true;
-            int ret = Native.GetVideoResolution(_Handle, out _width, out _height);
-            StreamRecorderError err = (StreamRecorderError)ret;
-            Log.Info(StreamRecorderLog.Tag, "width " + _width + " height " + _height + "return " + err.ToString());
-        }
-
-        internal StreamRecorderVideoResolution(int width, int height)
-        {
-            _interopFlag = false;
-            _width = width;
-            _height = height;
-        }
-
-        /// <summary>
-        /// The video width.
-        /// </summary>
-        /// <value>The width.</value>
-        public int Width {
-            get {
-                if(_interopFlag == true)
-                    Native.GetVideoResolution(_Handle, out _width, out _height);
-                return _width;
-            }
-            set {
-                _width = value;
-                if(_interopFlag == true) {
-                    int ret = Native.SetVideoResolution(_Handle, _width, _height);
-                    StreamRecorderError err = (StreamRecorderError)ret;
-                    Log.Info(StreamRecorderLog.Tag, " set width " + _width + " height " + _height + "set return " + err.ToString());
-                }
-            }
-        }
-
-        /// <summary>
-        /// The video height.
-        /// </summary>
-        /// <value>The height.</value>
-        public int Height {
-            get {
-                if(_interopFlag == true)
-                    Native.GetVideoResolution(_Handle, out _width, out _height);
-                return _height;
-            }
-            set {
-                _height = value;
-                if(_interopFlag == true) {
-                    int ret = Native.SetVideoResolution(_Handle, _width, _height);
-                    StreamRecorderError err = (StreamRecorderError)ret;
-                    Log.Info(StreamRecorderLog.Tag, " set width " + _width + " height " + _height + "set return " + err.ToString());
-                }
-            }
-        }
-    }
-}