[MM-VideoUtil] Added base code for Video utility
authorDinesh Dwivedi <dinesh.d@samsung.com>
Wed, 22 Feb 2017 10:32:55 +0000 (16:02 +0530)
committerDinesh Dwivedi <dinesh.d@samsung.com>
Wed, 22 Feb 2017 10:37:07 +0000 (16:07 +0530)
Change-Id: Ib1a7f7298b79a85536d4cd4ac513cdde4bad2292
Signed-off-by: Dinesh Dwivedi <dinesh.d@samsung.com>
src/Tizen.Multimedia/Interop/Interop.ErrorCode.cs
src/Tizen.Multimedia/Interop/Interop.Libraries.cs
src/Tizen.Multimedia/Interop/Interop.VideoUtil.cs [new file with mode: 0755]
src/Tizen.Multimedia/Utility/AudioCodec.cs [new file with mode: 0755]
src/Tizen.Multimedia/Utility/VideoCodec.cs [new file with mode: 0755]
src/Tizen.Multimedia/Utility/VideoFileFormat.cs [new file with mode: 0755]
src/Tizen.Multimedia/Utility/VideoTranscoder.cs [new file with mode: 0755]

index ec477d6..b941043 100755 (executable)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.IO;
 using System.Runtime.CompilerServices;
 using Tizen;
 
@@ -28,10 +29,16 @@ internal static partial class Interop
         InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
         PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
         NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+        ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+        NoSuchFile = Tizen.Internals.Errors.ErrorCode.NoSuchFile,
 
+        // Radio
         InvalidState = -0x019A0000 | 0x01, // RADIO_ERROR_INVALID_STATE
         SoundPolicy = -0x019A0000 | 0x02, // RADIO_ERROR_SOUND_POLICY
         NoAntenna = -0x019A0000 | 0x03, // RADIO_ERROR_NO_ANTENNA
+
+        // Image/ Video Utility
+        NotSupportedFormat = -0x01980000 | 0x01, // VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT
     }
 }
 
@@ -85,12 +92,14 @@ internal static class ErrorCodeExtensions
             //case ErrorCode.None:
             case Interop.ErrorCode.PermissionDenied: return new UnauthorizedAccessException(errMessage);
             case Interop.ErrorCode.InvalidParameter: return new ArgumentException(errMessage);
+            case Interop.ErrorCode.NoSuchFile: return new FileNotFoundException(errMessage);
             case Interop.ErrorCode.OutOfMemory: return new OutOfMemoryException(errMessage);
             case Interop.ErrorCode.NotSupported: return new NotSupportedException(errMessage);
             case Interop.ErrorCode.NoAntenna: return new NotSupportedException(errMessage);
             case Interop.ErrorCode.InvalidOperation:
             case Interop.ErrorCode.InvalidState:
             case Interop.ErrorCode.SoundPolicy:
+            case Interop.ErrorCode.ResourceBusy:
             default: return new InvalidOperationException(errMessage);
         }
     }
index 54a147b..a78e4d7 100755 (executable)
@@ -32,6 +32,7 @@ internal static partial class Interop
         public const string Camera = "libcapi-media-camera.so.0";
         public const string StreamRecorder = "libcapi-media-streamrecorder.so.0";
         public const string Radio = "libcapi-media-radio.so.0";
+        public const string VideoUtil = "libcapi-media-video-util.so.0";
         public const string ThumbnailExtractor = "libcapi-media-thumbnail-util.so";
         public const string WavPlayer = "libcapi-media-wav-player.so.0";
         public const string TonePlayer = "libcapi-media-tone-player.so.0";
diff --git a/src/Tizen.Multimedia/Interop/Interop.VideoUtil.cs b/src/Tizen.Multimedia/Interop/Interop.VideoUtil.cs
new file mode 100755 (executable)
index 0000000..f62e6f4
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * 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.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal enum VideoCodec
+    {
+        Mpeg4, // VIDEO_UTIL_VIDEO_CODEC_MPEG4
+        H263, // VIDEO_UTIL_VIDEO_CODEC_H263
+        H264, // VIDEO_UTIL_VIDEO_CODEC_H264
+        None, // VIDEO_UTIL_VIDEO_CODEC_NONE
+    }
+
+    internal enum AudioCodec
+    {
+        Aac, // VIDEO_UTIL_AUDIO_CODEC_AAC
+        Amrnb, // VIDEO_UTIL_AUDIO_CODEC_AMRNB
+        None, // VIDEO_UTIL_AUDIO_CODEC_NONE
+    }
+
+    internal enum VideoFileFormat
+    {
+        Format3Gp, // VIDEO_UTIL_FILE_FORMAT_3GP
+        FormatMp4, // VIDEO_UTIL_FILE_FORMAT_MP4
+        FormatMax, // VIDEO_UTIL_FILE_FORMAT_MAX
+    }
+
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_foreach_supported_file_format")]
+    internal static extern ErrorCode ForeachSupportedFileFormat(this VideoTranscoderHandle /* video_util_h */ handle, VideoTranscoderHandle.SupportedFileFormatCallback callback, IntPtr /* void */ userData);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_foreach_supported_video_codec")]
+    internal static extern ErrorCode ForeachSupportedVideoCodec(this VideoTranscoderHandle /* video_util_h */ handle, VideoTranscoderHandle.SupportedVideoEncoderCallback callback, IntPtr /* void */ userData);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_foreach_supported_audio_codec")]
+    internal static extern ErrorCode ForeachSupportedAudioCodec(this VideoTranscoderHandle /* video_util_h */ handle, VideoTranscoderHandle.SupportedAudioEncoderCallback callback, IntPtr /* void */ userData);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_start_transcoding")]
+    internal static extern ErrorCode StartTranscoding(this VideoTranscoderHandle /* video_util_h */ handle, ulong start, ulong duration,
+        string outPath, VideoTranscoderHandle.TranscodingProgressCallback progressCb, VideoTranscoderHandle.TranscodingCompletedCallback completedCb, IntPtr /* void */ userData);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_cancel_transcoding")]
+    internal static extern ErrorCode CancelTranscoding(this VideoTranscoderHandle /* video_util_h */ handle);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_get_progress_transcoding")]
+    internal static extern ErrorCode GetProgressTranscoding(this VideoTranscoderHandle /* video_util_h */ handle, out ulong currentPosition, out ulong duration);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_set_resolution")]
+    internal static extern ErrorCode SetResolution(this VideoTranscoderHandle /* video_util_h */ handle, int width, int height);
+
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_set_file_path")]
+    internal static extern ErrorCode SetFilePath(this VideoTranscoderHandle /* video_util_h */ handle, string path);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_set_accurate_mode")]
+    internal static extern ErrorCode SetAccurateMode(this VideoTranscoderHandle /* video_util_h */ handle, bool mode);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_set_video_codec")]
+    internal static extern ErrorCode SetVideoCodec(this VideoTranscoderHandle /* video_util_h */ handle, VideoCodec /* video_util_video_codec_e */ codec);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_set_audio_codec")]
+    internal static extern ErrorCode SetAudioCodec(this VideoTranscoderHandle /* video_util_h */ handle, AudioCodec /* video_util_audio_codec_e */ codec);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_set_file_format")]
+    internal static extern ErrorCode SetFileFormat(this VideoTranscoderHandle /* video_util_h */ handle, VideoFileFormat /* video_util_file_format_e */ format);
+
+    [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_set_fps")]
+    internal static extern ErrorCode SetFps(this VideoTranscoderHandle /* video_util_h */ handle, int fps);
+
+    internal class VideoTranscoderHandle : SafeMultimediaHandle
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void TranscodingProgressCallback(ulong currentPosition, ulong duration, IntPtr /* void */ userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void TranscodingCompletedCallback(ErrorCode /* video_util_error_e */ errorCode, IntPtr /* void */ userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool SupportedFileFormatCallback(VideoFileFormat /* video_util_file_format_e */ format, IntPtr /* void */ userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool SupportedVideoEncoderCallback(VideoCodec /* video_util_video_codec_e */ codec, IntPtr /* void */ userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool SupportedAudioEncoderCallback(AudioCodec /* video_util_audio_codec_e */ codec, IntPtr /* void */ userData);
+
+        [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_create")]
+        internal static extern ErrorCode Create(out IntPtr /* video_util_h */ handle);
+
+        [DllImport(Libraries.VideoUtil, EntryPoint = "video_util_destroy")]
+        internal static extern ErrorCode Destroy(IntPtr /* video_util_h */ handle);
+
+        internal string InputFile
+        {
+            set { NativeSet(this.SetFilePath, value); }
+        }
+
+        internal bool AccurateModeEnabled
+        {
+            set { NativeSet(this.SetAccurateMode, value); }
+        }
+
+        internal VideoCodec VideoCodec
+        {
+            set { NativeSet(this.SetVideoCodec, value); }
+        }
+
+        internal AudioCodec AudioCodec
+        {
+            set { NativeSet(this.SetAudioCodec, value); }
+        }
+
+        internal VideoFileFormat FileFormat
+        {
+            set { NativeSet(this.SetFileFormat, value); }
+        }
+
+        internal int Fps
+        {
+            set { NativeSet(this.SetFps, value); }
+        }
+
+        internal VideoTranscoderHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease)
+        {
+        }
+
+        internal VideoTranscoderHandle() : this(CreateNativeHandle(), true)
+        {
+        }
+
+        internal static IntPtr CreateNativeHandle()
+        {
+            IntPtr handle;
+            Create(out handle).ThrowIfFailed("Failed to create native handle");
+            return handle;
+        }
+
+        internal override ErrorCode DisposeNativeHandle()
+        {
+            return Destroy(handle);
+        }
+
+        internal void ForeachSupportedFileFormat(Action<VideoFileFormat> action)
+        {
+            SupportedFileFormatCallback callback = (codec, userData) =>
+            {
+                action(codec);
+                return true;
+            };
+
+            this.ForeachSupportedFileFormat(callback, IntPtr.Zero).ThrowIfFailed("Failed to get supported file format list from native handle");
+        }
+
+        internal void ForeachSupportedVideoCodec(Action<VideoCodec> action)
+        {
+            SupportedVideoEncoderCallback callback = (codec, userData) =>
+            {
+                action(codec);
+                return true;
+            };
+
+            this.ForeachSupportedVideoCodec(callback, IntPtr.Zero).ThrowIfFailed("Failed to get supported video codec list from native handle");
+        }
+
+        internal void ForeachSupportedAudioCodec(Action<AudioCodec> action)
+        {
+            SupportedAudioEncoderCallback callback = (codec, userData) =>
+            {
+                action(codec);
+                return true;
+            };
+
+            this.ForeachSupportedAudioCodec(callback, IntPtr.Zero).ThrowIfFailed("Failed to get supported audio codec list from native handle");
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia/Utility/AudioCodec.cs b/src/Tizen.Multimedia/Utility/AudioCodec.cs
new file mode 100755 (executable)
index 0000000..47cb060
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+namespace Tizen.Multimedia.Utility
+{
+    /// <summary>
+    /// Audio codec
+    /// </summary>
+    public enum AudioCodec
+    {
+        /// <summary>
+        /// No trans-coding for audio
+        /// </summary>
+        None = Interop.AudioCodec.None,
+        /// <summary>
+        /// AAC
+        /// </summary>
+        Aac = Interop.AudioCodec.Aac,
+        /// <summary>
+        /// AMRNB
+        /// </summary>
+        Amrnb = Interop.AudioCodec.Amrnb,
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia/Utility/VideoCodec.cs b/src/Tizen.Multimedia/Utility/VideoCodec.cs
new file mode 100755 (executable)
index 0000000..718507d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+namespace Tizen.Multimedia.Utility
+{
+    /// <summary>
+    /// Video codec for trans-coding
+    /// </summary>
+    public enum VideoCodec
+    {
+        /// <summary>
+        /// No trans-coding for video
+        /// </summary>
+        None = Interop.VideoCodec.None,
+        /// <summary>
+        /// MPEG4
+        /// </summary>
+        Mpeg4 = Interop.VideoCodec.Mpeg4,
+        /// <summary>
+        /// H263
+        /// </summary>
+        H263 = Interop.VideoCodec.H263,
+        /// <summary>
+        /// H264
+        /// </summary>
+        H264 = Interop.VideoCodec.H264,
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia/Utility/VideoFileFormat.cs b/src/Tizen.Multimedia/Utility/VideoFileFormat.cs
new file mode 100755 (executable)
index 0000000..5afe29a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+namespace Tizen.Multimedia.Utility
+{
+    /// <summary>
+    /// Video file format
+    /// </summary>
+    public enum VideoFileFormat
+    {
+        /// <summary>
+        /// 3GP file
+        /// </summary>
+        ThreeGp = Interop.VideoFileFormat.Format3Gp,
+        /// <summary>
+        /// MP4 file
+        /// </summary>
+        Mp4 = Interop.VideoFileFormat.FormatMp4,
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia/Utility/VideoTranscoder.cs b/src/Tizen.Multimedia/Utility/VideoTranscoder.cs
new file mode 100755 (executable)
index 0000000..719bd8a
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * 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.Threading;
+using System.Threading.Tasks;
+
+namespace Tizen.Multimedia.Utility
+{
+    /// <summary>
+    /// Video trans-coding utility
+    /// </summary>
+    public class VideoTranscoder : IDisposable
+    {
+        public const AudioCodec DetaultAudioCodec = AudioCodec.Aac;
+        public const VideoCodec DetaultVideoCodec = VideoCodec.Mpeg4;
+        public const VideoFileFormat DetaultFileFormat = VideoFileFormat.ThreeGp;
+        public const bool DefaultAccurateModeEnabled = false;
+        public static Size DefaultResolution = new Size(0, 0);
+        public const int DefaultFps = 0;
+
+        internal Interop.VideoTranscoderHandle _handle;
+        private Size _resolution = DefaultResolution;
+        private int _fps = DefaultFps;
+
+        /// <summary>
+        /// Creates Video trans-coder
+        /// </summary>
+        /// <exception cref="OutOfMemoryException">Thrown if framework failed to allocate memory</exception>
+        /// <exception cref="NotSupportedException">Thrown if video trans-coding is not supported in device</exception>
+        public VideoTranscoder()
+        {
+            _handle = new Interop.VideoTranscoderHandle();
+        }
+
+        /// <summary>
+        /// Indicate if trans-coder is busy trans-coding
+        /// </summary>
+        public bool IsBusy { get; private set; }
+
+        /// <summary>
+        /// Indicates if accurate mode is enabled
+        /// </summary>
+        /// <remarks>Default is false, if set to true, next trans-coding will start from accurate frame for given the duration, otherwise from nearest i-frame</remarks>
+        public bool IsAccurateModeEnabled { get; set; } = DefaultAccurateModeEnabled;
+
+        /// <summary>
+        /// Audio codec for encoding stream for next trans-coding
+        /// </summary>
+        /// <remarks>Default is AudioCodec.Aac</remarks>
+        public AudioCodec AudioCodec { get; set; } = DetaultAudioCodec;
+
+        /// <summary>
+        /// Video codec for encoding stream for next trans-coding
+        /// </summary>
+        /// <remarks>Default is VideoCodec.Mpeg4</remarks>
+        public VideoCodec VideoCodec { get; set; } = DetaultVideoCodec;
+
+        /// <summary>
+        /// File format for trans-coding media stream for next trans-coding
+        /// </summary>
+        /// <remarks>Default is VideoFileFormat.ThreeGp</remarks>
+        public VideoFileFormat Format { get; set; } = DetaultFileFormat;
+
+        /// <summary>
+        /// Media resolution for next trans-coding
+        /// </summary>
+        /// <remarks>
+        /// Default value is Size(0, 0)
+        /// If the width is 0, it set original size.(minimum value is 128)
+        /// If the height is 0, it set original size.(minimum value is 96)
+        /// </remarks>
+        /// <exception cref="ArgumentOutOfRangeException">Thrown if value is not in valid range</exception>
+        public Size Resolution
+        {
+            get { return _resolution; }
+            set
+            {
+                ValidateInputRange(value.Width, () => value.Width >= 128 || value.Width == 0, "Width", "Valid value is 0 and value >= 128");
+                ValidateInputRange(value.Height, () => value.Width >= 96 || value.Width == 0, "Height", "Valid value is 0 and value >= 96");
+                _resolution = value;
+            }
+        }
+
+        /// <summary>
+        /// Frame rate, in range [5-30] for next trans-coding
+        /// </summary>
+        /// <remarks>
+        /// Default value is 0
+        /// If fps is set 0, the default is original fps from source.
+        /// </remarks>
+        /// <exception cref="ArgumentOutOfRangeException">Thrown if value is not in valid range</exception>
+        public int Fps
+        {
+            get { return _fps; }
+            set
+            {
+                ValidateInputRange(value, 5, 30, "Fps");
+                _fps = value;
+            }
+        }
+
+        /// <summary>
+        /// Supported audio codecs
+        /// </summary>
+        public IEnumerable<AudioCodec> SupportedAudioCodecs
+        {
+            get
+            {
+                var audioCodecs = new List<AudioCodec>();
+                _handle.ForeachSupportedAudioCodec((codec) => audioCodecs.Add((AudioCodec)codec));
+                return audioCodecs;
+            }
+        }
+
+        /// <summary>
+        /// Supported video codecs
+        /// </summary>
+        public IEnumerable<VideoCodec> SupportedVideoCodecs
+        {
+            get
+            {
+                var videoCodecs = new List<VideoCodec>();
+                _handle.ForeachSupportedVideoCodec((codec) => videoCodecs.Add((VideoCodec)codec));
+                return videoCodecs;
+            }
+        }
+
+        /// <summary>
+        /// Supported video file formats
+        /// </summary>
+        public IEnumerable<VideoFileFormat> SupportedVideoFileFormats
+        {
+            get
+            {
+                var videoFileFormats = new List<VideoFileFormat>();
+                _handle.ForeachSupportedFileFormat((codec) => videoFileFormats.Add((VideoFileFormat)codec));
+                return videoFileFormats;
+            }
+        }
+
+        /// <summary>
+        /// Trans-code video
+        /// </summary>
+        /// <param name="sourceFilePath">Source video file to trans-code</param>
+        /// <param name="startPosition">Position to start trans-code in seconds</param>
+        /// <param name="totalDuration">Total duration to trans-code, in seconds, if set to 0, trans-coding happens until end of the video</param>
+        /// <param name="outputFile">Output file path</param>
+        /// <param name="progress">progress update provider</param>
+        /// <param name="cancelToken">Cancellation token, to be used to cancel trans-coding</param>
+        /// <privilege>http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage</privilege>
+        /// <exception cref="UnauthorizedAccessException">Thrown if application does not have required privilege</exception>
+        /// <exception cref="ArgumentNullException">Thrown if sourceFilePath or outputFile is null</exception>
+        /// <exception cref="System.IO.FileNotFoundException">Thrown if sourceFilePath does not exist</exception>
+        /// <exception cref="NotSupportedException">Thrown if video file format is not supported</exception>
+        /// <exception cref="InvalidOperationException">Thrown if Trans-coder is busy trans-coding previous file</exception>
+        /// <exception cref="TaskCanceledException">Thrown if trans-coding is canceled</exception>
+        /// <returns>Trans-coding task</returns>
+        public Task TranscodeAsync(string sourceFilePath, ulong startPosition, ulong totalDuration, string outputFile, IProgress<int> progress, CancellationToken cancelToken)
+        {
+            ValidateObjectNotDisposed();
+
+            if (sourceFilePath == null) throw new ArgumentNullException(nameof(sourceFilePath));
+            if (outputFile == null) throw new ArgumentNullException(nameof(outputFile));
+
+            // CAPI does not allow setting properties or start another trans-coding if trans-coder is busy
+            if (IsBusy) throw new InvalidOperationException("Previous trans-coding is still going on");
+
+            ConfigureNativeHandle(sourceFilePath);
+
+            var transcodingTask = new TaskCompletionSource<bool>();
+            if (cancelToken != CancellationToken.None)
+            {
+                if (cancelToken.IsCancellationRequested)
+                {
+                    IsBusy = false;
+                    transcodingTask.TrySetCanceled();
+                }
+
+                cancelToken.Register(() =>
+                {
+                    _handle.CancelTranscoding().ThrowIfFailed("Failed to cancel trans-coding");
+                    IsBusy = false;
+                    transcodingTask.SetResult(false);
+                });
+            }
+
+            Interop.VideoTranscoderHandle.TranscodingProgressCallback progressCb = (currentPosition, duration, userData) =>
+            {
+                progress?.Report((int)((currentPosition - startPosition) / duration));
+            };
+
+            Interop.VideoTranscoderHandle.TranscodingCompletedCallback completedCb = (errorCode, userData) =>
+            {
+                if (IsBusy)
+                {
+                    IsBusy = false;
+                    if (errorCode.IsSuccess())
+                    {
+                        transcodingTask.TrySetResult(true);
+                    }
+                    else
+                    {
+                        transcodingTask.TrySetException(errorCode.GetException("Failed to trans-code"));
+                    }
+                }
+            };
+
+            var err = _handle.StartTranscoding(startPosition, totalDuration, outputFile, progressCb, completedCb, IntPtr.Zero);
+            err.ThrowIfFailed("Failed to start trans-coding");
+
+            IsBusy = !transcodingTask.Task.IsCanceled;
+            return Interop.PinnedTask(transcodingTask);
+        }
+
+        /// <summary>
+        /// Trans-code video from start position in input file till end of file.
+        /// </summary>
+        /// <param name="sourceFilePath">Source video file to trans-code</param>
+        /// <param name="startPosition">Position to start trans-code in seconds</param>
+        /// <param name="outputFile">Output file path</param>
+        /// <param name="progress">progress update provider</param>
+        /// <param name="cancelToken">Cancellation token, to be used to cancel trans-coding</param>
+        /// <privilege>http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage</privilege>
+        /// <exception cref="UnauthorizedAccessException">Thrown if application does not have required privilege</exception>
+        /// <exception cref="ArgumentNullException">Thrown if sourceFilePath or outputFile is null</exception>
+        /// <exception cref="System.IO.FileNotFoundException">Thrown if sourceFilePath does not exist</exception>
+        /// <exception cref="NotSupportedException">Thrown if video file format is not supported</exception>
+        /// <exception cref="InvalidOperationException">Thrown if Trans-coder is busy trans-coding previous file</exception>
+        /// <exception cref="TaskCanceledException">Thrown if trans-coding is canceled</exception>
+        /// <returns>Trans-coding task</returns>
+        public Task TranscodeAsync(string sourceFilePath, ulong startPosition, string outputFile, IProgress<int> progress, CancellationToken cancelToken)
+        {
+            return TranscodeAsync(sourceFilePath, startPosition, 0, outputFile, progress, cancelToken);
+        }
+
+        /// <summary>
+        /// Trans-code video
+        /// </summary>
+        /// <param name="sourceFilePath">Source video file to trans-code</param>
+        /// <param name="startPosition">Position to start trans-code in seconds</param>
+        /// <param name="duration">Total duration to trans-code, in seconds, if set to 0, trans-coding happens until end of the video</param>
+        /// <param name="outputFile">Output file path</param>
+        /// <param name="progress">progress update provider</param>
+        /// <privilege>http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage</privilege>
+        /// <exception cref="UnauthorizedAccessException">Thrown if application does not have required privilege</exception>
+        /// <exception cref="ArgumentNullException">Thrown if sourceFilePath or outputFile is null</exception>
+        /// <exception cref="System.IO.FileNotFoundException">Thrown if sourceFilePath does not exist</exception>
+        /// <exception cref="NotSupportedException">Thrown if video file format is not supported</exception>
+        /// <exception cref="InvalidOperationException">Thrown if Trans-coder is busy trans-coding previous file</exception>
+        /// <returns>Trans-coding task</returns>
+        public Task TranscodeAsync(string sourceFilePath, ulong startPosition, ulong duration, string outputFile, IProgress<int> progress)
+        {
+            return TranscodeAsync(sourceFilePath, startPosition, duration, outputFile, progress, CancellationToken.None);
+        }
+
+        /// <summary>
+        /// Trans-code video
+        /// </summary>
+        /// <param name="sourceFilePath">Source video file to trans-code</param>
+        /// <param name="startPosition">Position to start trans-code in seconds</param>
+        /// <param name="outputFile">Output file path</param>
+        /// <param name="progress">progress update provider</param>
+        /// <privilege>http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage</privilege>
+        /// <exception cref="UnauthorizedAccessException">Thrown if application does not have required privilege</exception>
+        /// <exception cref="ArgumentNullException">Thrown if sourceFilePath or outputFile is null</exception>
+        /// <exception cref="System.IO.FileNotFoundException">Thrown if sourceFilePath does not exist</exception>
+        /// <exception cref="NotSupportedException">Thrown if video file format is not supported</exception>
+        /// <exception cref="InvalidOperationException">Thrown if Trans-coder is busy trans-coding previous file</exception>
+        /// <returns>Trans-coding task</returns>
+        public Task TranscodeAsync(string sourceFilePath, ulong startPosition, string outputFile, IProgress<int> progress)
+        {
+            return TranscodeAsync(sourceFilePath, startPosition, 0, outputFile, progress, CancellationToken.None);
+        }
+
+        private void ConfigureNativeHandle(string sourceFilePath)
+        {
+            _handle.InputFile = sourceFilePath;
+
+            if (AudioCodec != DetaultAudioCodec) _handle.AudioCodec = (Interop.AudioCodec)AudioCodec;
+            if (VideoCodec != DetaultVideoCodec) _handle.VideoCodec = (Interop.VideoCodec)VideoCodec;
+            if (Format != DetaultFileFormat) _handle.FileFormat = (Interop.VideoFileFormat)Format;
+            if (IsAccurateModeEnabled != DefaultAccurateModeEnabled) _handle.AccurateModeEnabled = IsAccurateModeEnabled;
+            if (Fps != DefaultFps) _handle.Fps = Fps;
+            if (Resolution.Width != DefaultResolution.Width || Resolution.Height != DefaultResolution.Height)
+            {
+                _handle.SetResolution(Resolution.Width, Resolution.Height).ThrowIfFailed($"Failed to set resolution to {Resolution}");
+            }
+        }
+
+        private void ValidateObjectNotDisposed()
+        {
+            if (_disposedValue)
+            {
+                throw new ObjectDisposedException(GetType().Name);
+            }
+        }
+
+        internal static void ValidateInputRange<T>(T actualValue, T min, T max, string paramName) where T : IComparable<T>
+        {
+            if (min.CompareTo(actualValue) == 1 || max.CompareTo(actualValue) == -1)
+            {
+                throw new ArgumentOutOfRangeException(paramName, actualValue, $"Valid Range [{min} - {max}]");
+            }
+        }
+
+        internal static void ValidateInputRange<T>(T actualValue, Func<bool> verifier, string paramName, string message)
+        {
+            if (verifier() == false)
+            {
+                throw new ArgumentOutOfRangeException(paramName, actualValue, message);
+            }
+        }
+
+        #region IDisposable Support
+        private bool _disposedValue = false;
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposedValue)
+            {
+                if (IsBusy)
+                {
+                    _handle.CancelTranscoding();
+                }
+                _handle.Dispose();
+                _disposedValue = true;
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+        #endregion
+    }
+}
\ No newline at end of file