Add implementation of MediaCodec
authorcoderhyme <jhyo.kim@samsung.com>
Fri, 28 Oct 2016 04:11:09 +0000 (13:11 +0900)
committercoderhyme <jhyo.kim@samsung.com>
Tue, 1 Nov 2016 02:42:56 +0000 (11:42 +0900)
Change-Id: I4eaa26db4e251bc88fd3366ad917f98b23fc2e06
Signed-off-by: coderhyme <jhyo.kim@samsung.com>
14 files changed:
src/Tizen.Multimedia/Interop/Interop.MediaCodec.cs
src/Tizen.Multimedia/MediaCodec/BufferStatusChangedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/EosReachedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/ErrorOccurredEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/InputProcessedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/MediaCodec.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/MediaCodecDebug.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/MediaCodecError.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/MediaCodecStatus.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/MediaCodecType.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/OutputAvailableEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaCodec/SupportedCodecType.cs [new file with mode: 0644]
src/Tizen.Multimedia/Tizen.Multimedia.Net45.csproj
src/Tizen.Multimedia/Tizen.Multimedia.csproj

index e65bf8b..149079d 100644 (file)
@@ -99,8 +99,7 @@ internal static partial class Interop
         internal static extern int GetSupportedType(IntPtr handle, int codecType, bool isEncoder,
             out int value);
 
-        // TODO the native method name needs to get replaced with new one which will be added
-        [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_foreach_supported_codec")]
+        [DllImport(Libraries.MediaCodec, EntryPoint = "mediacodec_foreach_supported_codec_static")]
         internal static extern int ForeachSupportedCodec(SupportedCodecCallback cb, IntPtr arg);
     }
 }
diff --git a/src/Tizen.Multimedia/MediaCodec/BufferStatusChangedEventArgs.cs b/src/Tizen.Multimedia/MediaCodec/BufferStatusChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..ebbf589
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaCodec.BufferStatusChanged"/> event.
+    /// </summary>
+    public class BufferStatusChangedEventArgs : EventArgs
+    {
+        private readonly MediaCodecStatus _status;
+
+        /// <summary>
+        /// Initializes a new instance of the BufferStatusChangedEventArgs class.
+        /// </summary>
+        /// <param name="status">The value representing new status of the codec.</param>
+        public BufferStatusChangedEventArgs(MediaCodecStatus status)
+        {
+            _status = status;
+        }
+
+        /// <summary>
+        /// Gets the value indicating new status of the codec.
+        /// </summary>
+        public MediaCodecStatus Status
+        {
+            get
+            {
+                return _status;
+            }
+        }
+
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/EosReachedEventArgs.cs b/src/Tizen.Multimedia/MediaCodec/EosReachedEventArgs.cs
new file mode 100644 (file)
index 0000000..a5d5c0e
--- /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.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaCodec.EosReached"/> event.
+    /// </summary>
+    public class EosReachedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the EosReachedEventArgs class.
+        /// </summary>
+        public EosReachedEventArgs()
+        {
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/ErrorOccurredEventArgs.cs b/src/Tizen.Multimedia/MediaCodec/ErrorOccurredEventArgs.cs
new file mode 100644 (file)
index 0000000..db54681
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaCodec.ErrorOccurred"/> event.
+    /// </summary>
+    public class ErrorOccurredEventArgs : EventArgs
+    {
+        private readonly MediaCodecError _error;
+
+        /// <summary>
+        /// Initializes a new instance of the ErrorOccurredEventArgs class.
+        /// </summary>
+        /// <param name="error">The value representing the type of the error.</param>
+        public ErrorOccurredEventArgs(MediaCodecError error)
+        {
+            _error = error;
+        }
+
+        /// <summary>
+        /// Gets the value indicating what kind of the error.
+        /// </summary>
+        public MediaCodecError Error
+        {
+            get
+            {
+                return _error;
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/InputProcessedEventArgs.cs b/src/Tizen.Multimedia/MediaCodec/InputProcessedEventArgs.cs
new file mode 100644 (file)
index 0000000..95fffb9
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaCodec.InputProcessed"/> event.
+    /// </summary>
+    public class InputProcessedEventArgs : EventArgs
+    {
+        private readonly MediaPacket _packet;
+
+        /// <summary>
+        /// Initializes a new instance of the InputProcessedEventArgs class.
+        /// </summary>
+        /// <param name="packet">The packet that the codec has processed.</param>
+        public InputProcessedEventArgs(MediaPacket packet)
+        {
+            Debug.Assert(packet != null);
+
+            _packet = packet;
+        }
+
+        /// <summary>
+        /// Gets the packet that the codec has processed.
+        /// </summary>
+        public MediaPacket Packet
+        {
+            get
+            {
+                return _packet;
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/MediaCodec.cs b/src/Tizen.Multimedia/MediaCodec/MediaCodec.cs
new file mode 100644 (file)
index 0000000..50db753
--- /dev/null
@@ -0,0 +1,725 @@
+/*
+ * 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.Diagnostics;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    /// <summary>
+    /// Provides the means to encode and decode video and audio data.
+    /// </summary>
+    public class MediaCodec : IDisposable
+    {
+        private static readonly int CodecTypeMask = 0xFFFF;
+        private static readonly int CodecKindMask = 0x3000;
+        private static readonly int CodecKindAudio = 0x1000;
+        private static readonly int CodecKindVideo = 0x2000;
+
+        private IntPtr _handle;
+
+        /// <summary>
+        /// Initialize a new instance of the MediaCodec class.
+        /// </summary>
+        public MediaCodec()
+        {
+            int ret = Interop.MediaCodec.Create(out _handle);
+
+            if (ret == (int)MediaCodecErrorCode.InvalidOperation)
+            {
+                throw new InvalidOperationException("Not able to initiate a new media codec.");
+            }
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        #region IDisposable-support
+        private bool _isDisposed = false;
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_isDisposed)
+            {
+                if (_handle != IntPtr.Zero)
+                {
+                    Interop.MediaCodec.Destroy(_handle);
+                    _handle = IntPtr.Zero;
+                }
+
+                _isDisposed = true;
+            }
+        }
+
+        ~MediaCodec()
+        {
+            Dispose(false);
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+
+            GC.SuppressFinalize(this);
+        }
+        #endregion
+
+        /// <summary>
+        /// Validates if the object already has been disposed of.
+        /// </summary>
+        /// <exception cref="ObjectDisposedException">The current object has been disposed of.</exception>
+        private void ValidateNotDisposed()
+        {
+            if (_isDisposed)
+            {
+                throw new ObjectDisposedException(nameof(MediaCodec));
+            }
+        }
+
+        private static IEnumerable<MediaFormatVideoMimeType> _supportedVideoCodecs;
+
+        /// <summary>
+        /// Gets the audio codec list that the current device supports.
+        /// </summary>
+        public static IEnumerable<MediaFormatVideoMimeType> SupportedVideoCodecs
+        {
+            get
+            {
+                if (_supportedVideoCodecs == null)
+                {
+                    LoadSupportedCodec();
+                }
+
+                return _supportedVideoCodecs;
+            }
+        }
+
+        private static IEnumerable<MediaFormatAudioMimeType> _supportedAudioCodecs;
+
+
+        /// <summary>
+        /// Gets the audio codec list that the current device supports.
+        /// </summary>
+        public static IEnumerable<MediaFormatAudioMimeType> SupportedAudioCodecs
+        {
+            get
+            {
+                if (_supportedAudioCodecs == null)
+                {
+                    LoadSupportedCodec();
+                }
+
+                return _supportedAudioCodecs;
+            }
+        }
+
+        private static bool TryGetMimeTypeFromCodecType<T>(int codecType, ref T result)
+        {
+            foreach (T value in Enum.GetValues(typeof(T)))
+            {
+                if ((Convert.ToInt32(value) & CodecTypeMask) == codecType)
+                {
+                    result = value;
+                    return true;
+                }
+            }
+
+            Debug.Fail($"Unknown codec : { codecType }.");
+            return false;
+        }
+
+        private static void LoadSupportedCodec()
+        {
+            var videoCodecList = new List<MediaFormatVideoMimeType>();
+            var audioCodecList = new List<MediaFormatAudioMimeType>();
+
+            Interop.MediaCodec.SupportedCodecCallback cb = (int codecType, IntPtr arg) =>
+            {
+                if ((codecType & CodecKindMask) == CodecKindVideo)
+                {
+                    MediaFormatVideoMimeType mimeType = 0;
+                    if (TryGetMimeTypeFromCodecType(codecType, ref mimeType))
+                    {
+                        videoCodecList.Add(mimeType);
+                    }
+                }
+                else
+                {
+                    MediaFormatAudioMimeType mimeType = 0;
+                    if (TryGetMimeTypeFromCodecType(codecType, ref mimeType))
+                    {
+                        audioCodecList.Add(mimeType);
+                    }
+                }
+
+                return true;
+            };
+
+            int ret = Interop.MediaCodec.ForeachSupportedCodec(cb, IntPtr.Zero);
+
+            MediaCodecDebug.AssertNoError(ret);
+
+            _supportedVideoCodecs = videoCodecList.AsReadOnly();
+            _supportedAudioCodecs = audioCodecList.AsReadOnly();
+        }
+
+        /// <summary>
+        /// Prepares the MediaCodec for encoding or decoding.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">
+        ///     The codec is not configured, yet.
+        ///     <para>-or-</para>
+        ///     Internal error.
+        /// </exception>
+        public void Prepare()
+        {
+            ValidateNotDisposed();
+
+            int ret = Interop.MediaCodec.Prepare(_handle);
+
+            if (ret == (int)MediaCodecErrorCode.NotInitialized)
+            {
+                throw new InvalidOperationException("The codec is not configured.");
+            }
+            if (ret != (int)MediaCodecErrorCode.None)
+            {
+                throw new InvalidOperationException("Operation failed.");
+            }
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        /// <summary>
+        /// Unprepares the MediaCodec.
+        /// </summary>
+        public void Unprepare()
+        {
+            ValidateNotDisposed();
+
+            int ret = Interop.MediaCodec.Unprepare(_handle);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        /// <summary>
+        /// Configures the MediaCodec.
+        /// </summary>
+        /// <param name="format">The <see cref="MediaFormat"/> for properties of media data to decode or encode.</param>
+        /// <param name="encoder">The value indicating whether the codec works as a encoder or a decoder.</param>
+        /// <param name="codecType">The value indicating whether the codec uses hardware acceleration.</param>
+        /// <exception cref="ArgumentNullException">format is null</exception>
+        /// <exception cref="ArgumentException">
+        ///     codecType is invalid.
+        ///     <para>-or-</para>
+        ///     format is neither audio type or video type.
+        ///     </exception>
+        /// <exception cref="NotSupportedException">the mime type of the format is not supported.</exception>
+        /// <see cref="SupportedAudioCodecs"/>
+        /// <see cref="SupportedVideoCodecs"/>
+        public void Configure(MediaFormat format, bool encoder, MediaCodecTypes codecType)
+        {
+            ValidateNotDisposed();
+
+            if (format == null)
+            {
+                throw new ArgumentNullException("Format can't be null.");
+            }
+
+            if (codecType != MediaCodecTypes.Hardware && codecType != MediaCodecTypes.Software)
+            {
+                throw new ArgumentException("codecType is invalid.");
+            }
+
+            if (format.Type == MediaFormatType.Audio)
+            {
+                ConfigureAudio((AudioMediaFormat)format, encoder, codecType);
+            }
+            else if (format.Type == MediaFormatType.Video)
+            {
+                ConfigureVideo((VideoMediaFormat)format, encoder, codecType);
+            }
+            else
+            {
+                throw new ArgumentException("Only video and audio formats are allowed.");
+            }
+        }
+
+        private void ConfigureAudio(AudioMediaFormat format, bool encoder,
+            MediaCodecTypes supportType)
+        {
+            int codecType = (int)format.MimeType & CodecTypeMask;
+
+            if (!Enum.IsDefined(typeof(SupportedCodecType), codecType))
+            {
+                throw new NotSupportedException("The format is not supported " +
+                    $"mime type : { Enum.GetName(typeof(MediaFormatAudioMimeType), format.MimeType) }");
+            }
+
+            DoConfigure(codecType, encoder, supportType);
+
+            if (encoder)
+            {
+                int ret = Interop.MediaCodec.SetAudioEncoderInfo(_handle, format.SampleRate,
+                    format.Channel, format.Bit, format.BitRate);
+
+                MediaCodecDebug.AssertNoError(ret);
+            }
+            else
+            {
+                int ret = Interop.MediaCodec.SetAudioDecoderInfo(_handle, format.SampleRate,
+                    format.Channel, format.Bit);
+
+                MediaCodecDebug.AssertNoError(ret);
+            }
+        }
+
+        private void ConfigureVideo(VideoMediaFormat format, bool encoder,
+            MediaCodecTypes supportType)
+        {
+            int codecType = (int)format.MimeType & CodecTypeMask;
+
+            if (!Enum.IsDefined(typeof(SupportedCodecType), codecType))
+            {
+                throw new NotSupportedException("The format is not supported." +
+                    $"mime type : { Enum.GetName(typeof(MediaFormatVideoMimeType), format.MimeType) }");
+            }
+
+            DoConfigure(codecType, encoder, supportType);
+
+            if (encoder)
+            {
+                int ret = Interop.MediaCodec.SetVideoEncoderInfo(_handle, format.Width,
+                    format.Height, format.FrameRate, format.BitRate / 1000);
+
+                MediaCodecDebug.AssertNoError(ret);
+            }
+            else
+            {
+                int ret = Interop.MediaCodec.SetVideoDecoderInfo(_handle, format.Width, format.Height);
+
+                MediaCodecDebug.AssertNoError(ret);
+            }
+        }
+
+        private void DoConfigure(int codecType, bool encoder, MediaCodecTypes supportType)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(SupportedCodecType), codecType));
+
+            int flags = (int)(encoder ? MediaCodecCodingType.Encoder : MediaCodecCodingType.Decoder);
+
+            flags |= (int)supportType;
+
+            int ret = Interop.MediaCodec.Configure(_handle, codecType, flags);
+
+            if (ret == (int)MediaCodecErrorCode.NotSupportedOnDevice)
+            {
+                throw new NotSupportedException("The format is not supported.");
+            }
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        /// <summary>
+        /// Add the packet to the internal queue of the codec.
+        /// </summary>
+        /// <param name="packet">The packet to be encoded or decoded.</param>
+        /// <exception cref="ArgumentNullException">packet is null.</exception>
+        /// <exception cref="InvalidOperationException">the current codec is not prepared, yet.</exception>
+        /// <remarks>Any attempts to modify the packet will be failed until the <see cref="InputProcessed"/> event for the packet is invoked.</remarks>
+        public void ProcessInput(MediaPacket packet)
+        {
+            ValidateNotDisposed();
+
+            if (packet == null)
+            {
+                throw new ArgumentNullException("Packet can't be null");
+            }
+
+            MediaPacket.Lock packetLock = new MediaPacket.Lock(packet);
+
+            int ret = Interop.MediaCodec.Process(_handle, packetLock.GetHandle(), 0);
+
+            if (ret == (int)MediaCodecErrorCode.InvalidState)
+            {
+                throw new InvalidOperationException("The codec is in invalid state.");
+            }
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        /// <summary>
+        /// Flush both input and output buffers.
+        /// </summary>
+        public void FlushBuffers()
+        {
+            ValidateNotDisposed();
+
+            int ret = Interop.MediaCodec.FlushBuffers(_handle);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        /// <summary>
+        /// Retrieves supported codec types for the specified params.
+        /// </summary>
+        /// <param name="encoder">The value indicating encoder or decoder.</param>
+        /// <param name="type">The mime type to query.</param>
+        /// <returns>The values indicating which codec types are supported on the current device.</returns>
+        /// <exception cref="ArgumentException">type is invalid.</exception>
+        public MediaCodecTypes GetCodecType(bool encoder, MediaFormatVideoMimeType type)
+        {
+            ValidateNotDisposed();
+
+            if (CheckMimeType(typeof(MediaFormatVideoMimeType), (int)type) == false)
+            {
+                return 0;
+            }
+
+            return GetCodecType((int)type, encoder);
+        }
+
+        /// <summary>
+        /// Retrieves supported codec types for the specified params.
+        /// </summary>
+        /// <param name="encoder">The value indicating encoder or decoder.</param>
+        /// <param name="type">The mime type to query.</param>
+        /// <returns>The values indicating which codec types are supported on the current device.</returns>
+        /// <exception cref="ArgumentException">type is invalid.</exception>
+        public MediaCodecTypes GetCodecType(bool encoder, MediaFormatAudioMimeType type)
+        {
+            ValidateNotDisposed();
+
+            if (CheckMimeType(typeof(MediaFormatAudioMimeType), (int)type) == false)
+            {
+                return 0;
+            }
+
+            return GetCodecType((int)type, encoder);
+        }
+
+        private MediaCodecTypes GetCodecType(int mimeType, bool isEncoder)
+        {
+            int codecType = mimeType & CodecTypeMask;
+            int value = 0;
+
+            int ret = Interop.MediaCodec.GetSupportedType(_handle, codecType, isEncoder, out value);
+
+            MediaCodecDebug.AssertNoError(ret);
+
+            return (MediaCodecTypes)value;
+        }
+
+        private bool CheckMimeType(Type type, int value)
+        {
+            int codecType = value & CodecTypeMask;
+
+            if (!Enum.IsDefined(type, value))
+            {
+                throw new ArgumentException($"The mime type value is invalid : { value }.");
+            }
+
+            return Enum.IsDefined(typeof(SupportedCodecType), codecType);
+        }
+
+        #region OutputAvailable event
+        private EventHandler<OutputAvailableEventArgs> _outputAvailable;
+        private Interop.MediaCodec.OutputBufferAvailableCallback _outputBufferAvailableCb;
+
+        /// <summary>
+        /// Occurs when an output buffer is available.
+        /// </summary>
+        /// <remarks>The output packet needs to be disposed after it is used to clean up unmanaged resources.</remarks>
+        public event EventHandler<OutputAvailableEventArgs> OutputAvailable
+        {
+            add
+            {
+                ValidateNotDisposed();
+
+                if (_outputAvailable == null)
+                {
+                    RegisterOutputAvailableCallback();
+                }
+                _outputAvailable += value;
+
+            }
+            remove
+            {
+                ValidateNotDisposed();
+
+                _outputAvailable -= value;
+                if (_outputAvailable == null)
+                {
+                    UnregisterOutputAvailableCallback();
+                }
+            }
+        }
+
+        private void RegisterOutputAvailableCallback()
+        {
+            _outputBufferAvailableCb = (IntPtr packetHandle, IntPtr arg) =>
+            {
+                OutputAvailableEventArgs args = null;
+
+                try
+                {
+                    args = new OutputAvailableEventArgs(packetHandle);
+                }
+                catch (Exception)
+                {
+                    Interop.MediaPacket.Destroy(packetHandle);
+                    throw;
+                }
+
+                _outputAvailable?.Invoke(this, args);
+            };
+
+            int ret = Interop.MediaCodec.SetOutputBufferAvaiableCb(_handle,
+                _outputBufferAvailableCb, IntPtr.Zero);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        private void UnregisterOutputAvailableCallback()
+        {
+            int ret = Interop.MediaCodec.UnsetOutputBufferAvaiableCb(_handle);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+        #endregion
+
+        #region InputProcessed event
+        private EventHandler<InputProcessedEventArgs> _inputProcessed;
+        private Interop.MediaCodec.InputBufferUsedCallback _inputBufferUsedCb;
+
+        /// <summary>
+        /// Occurs when an input packet is processed.
+        /// </summary>
+        /// <see cref="ProcessInput(MediaPacket)"/>
+        public event EventHandler<InputProcessedEventArgs> InputProcessed
+        {
+            add
+            {
+                ValidateNotDisposed();
+
+                if (_inputProcessed == null)
+                {
+                    RegisterInputProcessed();
+                }
+                _inputProcessed += value;
+
+            }
+            remove
+            {
+                ValidateNotDisposed();
+
+                _inputProcessed -= value;
+                if (_inputProcessed == null)
+                {
+                    UnregisterInputProcessed();
+                }
+            }
+        }
+
+        private void RegisterInputProcessed()
+        {
+            _inputBufferUsedCb = (IntPtr lockedPacketHandle, IntPtr arg) =>
+            {
+                MediaPacket packet = null;
+
+                // Lock must be disposed here, note that the packet won't be disposed.
+                using (MediaPacket.Lock packetLock =
+                    MediaPacket.Lock.FromHandle(lockedPacketHandle))
+                {
+                    packet = packetLock.MediaPacket;
+                }
+                Debug.Assert(packet != null);
+
+                _inputProcessed?.Invoke(this, new InputProcessedEventArgs(packet));
+            };
+
+            int ret = Interop.MediaCodec.SetInputBufferUsedCb(_handle,
+                _inputBufferUsedCb, IntPtr.Zero);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        private void UnregisterInputProcessed()
+        {
+            int ret = Interop.MediaCodec.UnsetInputBufferUsedCb(_handle);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+        #endregion
+
+        #region ErrorOccurred event
+        private EventHandler<ErrorOccurredEventArgs> _errorOccurred;
+        private Interop.MediaCodec.ErrorCallback _errorCb;
+
+        /// <summary>
+        /// Occurs whenever an error is produced in the codec.
+        /// </summary>
+        public event EventHandler<ErrorOccurredEventArgs> ErrorOccurred
+        {
+            add
+            {
+                ValidateNotDisposed();
+
+                if (_errorOccurred == null)
+                {
+                    RegisterErrorOccurred();
+                }
+                _errorOccurred += value;
+
+            }
+            remove
+            {
+                ValidateNotDisposed();
+
+                _errorOccurred -= value;
+                if (_errorOccurred == null)
+                {
+                    UnregisterErrorOccurred();
+                }
+            }
+        }
+
+        private void RegisterErrorOccurred()
+        {
+            _errorCb = (int errorCode, IntPtr arg) =>
+            {
+                MediaCodecError error = (Enum.IsDefined(typeof(MediaCodecError), errorCode)) ?
+                    (MediaCodecError)errorCode : MediaCodecError.InternalError;
+
+                _errorOccurred?.Invoke(this, new ErrorOccurredEventArgs(error));
+            };
+            int ret = Interop.MediaCodec.SetErrorCb(_handle, _errorCb, IntPtr.Zero);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        private void UnregisterErrorOccurred()
+        {
+            int ret = Interop.MediaCodec.UnsetErrorCb(_handle);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+        #endregion
+
+        #region EosReached event
+        private EventHandler<EosReachedEventArgs> _eosReached;
+        private Interop.MediaCodec.EosCallback _eosCb;
+
+        /// <summary>
+        /// Occurs when the codec processes all input data.
+        /// </summary>
+        public event EventHandler<EosReachedEventArgs> EosReached
+        {
+            add
+            {
+                ValidateNotDisposed();
+
+                if (_eosReached == null)
+                {
+                    RegisterEosReached();
+                }
+                _eosReached += value;
+
+            }
+            remove
+            {
+                ValidateNotDisposed();
+
+                _eosReached -= value;
+                if (_eosReached == null)
+                {
+                    UnregisterEosReached();
+                }
+            }
+        }
+
+        private void RegisterEosReached()
+        {
+            _eosCb = (IntPtr arg) => _eosReached?.Invoke(this, new EosReachedEventArgs());
+
+            int ret = Interop.MediaCodec.SetEosCb(_handle, _eosCb, IntPtr.Zero);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        private void UnregisterEosReached()
+        {
+            int ret = Interop.MediaCodec.UnsetEosCb(_handle);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+        #endregion
+
+        #region BufferStatusChanged event
+        private EventHandler<BufferStatusChangedEventArgs> _bufferStatusChanged;
+        private Interop.MediaCodec.BufferStatusCallback _bufferStatusCb;
+
+        /// <summary>
+        /// Occurs when the codec needs more data or has enough data.
+        /// </summary>
+        public event EventHandler<BufferStatusChangedEventArgs> BufferStatusChanged
+        {
+            add
+            {
+                ValidateNotDisposed();
+
+                if (_bufferStatusChanged == null)
+                {
+                    RegisterBufferStatusChanged();
+                }
+                _bufferStatusChanged += value;
+
+            }
+            remove
+            {
+                ValidateNotDisposed();
+
+                _bufferStatusChanged -= value;
+                if (_bufferStatusChanged == null)
+                {
+                    UnregisterBufferStatusChanged();
+                }
+            }
+        }
+
+        private void RegisterBufferStatusChanged()
+        {
+            _bufferStatusCb = (int statusCode, IntPtr arg) =>
+            {
+                Debug.Assert(Enum.IsDefined(typeof(MediaCodecStatus), statusCode),
+                    $"{ statusCode } is not defined in MediaCodecStatus!");
+
+                _bufferStatusChanged?.Invoke(this,
+                    new BufferStatusChangedEventArgs((MediaCodecStatus)statusCode));
+            };
+
+            int ret = Interop.MediaCodec.SetBufferStatusCb(_handle, _bufferStatusCb, IntPtr.Zero);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+
+        private void UnregisterBufferStatusChanged()
+        {
+            int ret = Interop.MediaCodec.UnsetBufferStatusCb(_handle);
+
+            MediaCodecDebug.AssertNoError(ret);
+        }
+        #endregion
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/MediaCodecDebug.cs b/src/Tizen.Multimedia/MediaCodec/MediaCodecDebug.cs
new file mode 100644 (file)
index 0000000..75d409c
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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.Diagnostics;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    internal class MediaCodecDebug
+    {
+
+        [ConditionalAttribute("DEBUG")]
+        internal static void AssertNoError(int errorCode)
+        {
+            Debug.Assert(errorCode == (int)MediaCodecErrorCode.None,
+                $"The API is supposed not to return an error! But it returns error({ errorCode}).",
+                "Implementation of core may have been changed, modify the call to throw if the return code is not ok.");
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/MediaCodecError.cs b/src/Tizen.Multimedia/MediaCodec/MediaCodecError.cs
new file mode 100644 (file)
index 0000000..14508f2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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 Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    internal enum MediaCodecErrorCode
+    {
+        CodecDefinedBase = -0x019B0000,
+
+        None = ErrorCode.None,
+        OutOfMemory = ErrorCode.OutOfMemory,
+        InvalidParameter = ErrorCode.InvalidParameter,
+        InvalidOperation = ErrorCode.InvalidParameter,
+        NotSupportedOnDevice = ErrorCode.NotSupported,
+        PermissionDenied = ErrorCode.PermissionDenied,
+
+        InvalidState = CodecDefinedBase | 0x01,
+        InvalidInBuffer = CodecDefinedBase | 0x02,
+        InvalidOutBuffer = CodecDefinedBase | 0x03,
+        Internal = CodecDefinedBase | 0x04,
+        NotInitialized = CodecDefinedBase | 0x05,
+        InvalidStream = CodecDefinedBase | 0x06,
+        CodecNotFound = CodecDefinedBase | 0x07,
+        DecodingError = CodecDefinedBase | 0x08,
+        OutOfStorage = CodecDefinedBase | 0x09,
+        StreamNotFound = CodecDefinedBase | 0x0a,
+        NotSupportedFormat = CodecDefinedBase | 0x0b,
+        NoAvailableBuffer = CodecDefinedBase | 0x0c,
+        OverflowInBuffer = CodecDefinedBase | 0x0d,
+    }
+
+    public enum MediaCodecError
+    {
+        NotSupportedFormat = MediaCodecErrorCode.NotSupportedFormat,
+        InternalError = MediaCodecErrorCode.Internal,
+        OutOfStorage = MediaCodecErrorCode.OutOfStorage,
+        InvalidStream = MediaCodecErrorCode.InvalidStream,
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/MediaCodecStatus.cs b/src/Tizen.Multimedia/MediaCodec/MediaCodecStatus.cs
new file mode 100644 (file)
index 0000000..32e453d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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.MediaCodec
+{
+    /// <summary>
+    /// Specifies the status of a codec.
+    /// </summary>
+    public enum MediaCodecStatus
+    {
+        /// <summary>
+        /// Not enough data to decode or encode.
+        /// </summary>
+        LackOfData,
+
+        /// <summary>
+        /// Enough data to decode or encode.
+        /// </summary>
+        EnoughData
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/MediaCodecType.cs b/src/Tizen.Multimedia/MediaCodec/MediaCodecType.cs
new file mode 100644 (file)
index 0000000..34da665
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    [Flags]
+    internal enum MediaCodecCodingType
+    {
+        Encoder = 0x1,
+        Decoder = 0x2
+    }
+
+    /// <summary>
+    /// Specifies types of codec.
+    /// </summary>
+    [Flags]
+    public enum MediaCodecTypes
+    {
+        /// <summary>
+        /// The hardware-accelerated codec.
+        /// </summary>
+        Hardware = 0x4,
+
+        /// <summary>
+        /// The software codec.
+        /// </summary>
+        Software = 0x8
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/OutputAvailableEventArgs.cs b/src/Tizen.Multimedia/MediaCodec/OutputAvailableEventArgs.cs
new file mode 100644 (file)
index 0000000..2afd587
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.MediaCodec
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaCodec.OutputAvailable"/> event.
+    /// </summary>
+    /// <remarks>The output packet needs to be disposed after it is used to clean up unmanaged resources.</remarks>
+    public class OutputAvailableEventArgs : EventArgs
+    {
+        private readonly MediaPacket _packet;
+
+        internal OutputAvailableEventArgs(IntPtr packetHandle)
+        {
+            _packet = MediaPacket.From(packetHandle);
+        }
+
+        /// <summary>
+        /// Gets the result packet.
+        /// </summary>
+        public MediaPacket Packet
+        {
+            get
+            {
+                return _packet;
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia/MediaCodec/SupportedCodecType.cs b/src/Tizen.Multimedia/MediaCodec/SupportedCodecType.cs
new file mode 100644 (file)
index 0000000..999808f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.MediaCodec
+{
+    internal enum SupportedCodecType
+    {
+        // L16 = 0x1010,
+        // ALaw = 0x1020,
+        // ULaw = 0x1030,
+        Amr = 0x1040,
+        AmrNB = 0x1040,
+        AmrWb = 0x1041,
+        // G729 = 0x1050,
+        Aac = 0x1060,
+        AacLC = 0x1060,
+        AacHE = 0x1061,
+        AacHEPS = 0x1062,
+        MP3 = 0x1070,
+        Vorbis = 0x1080,
+        Flac = 0x1090,
+        Wma1 = 0x10A0,
+        Wma2 = 0x10A1,
+        WmaPro = 0x10A2,
+        WmaLossless = 0x10A3,
+
+        H261 = 0x2010,
+        H263 = 0x2020,
+        H264 = 0x2030,
+        MJpeg = 0x2040,
+        Mpeg1 = 0x2050,
+        Mpeg2 = 0x2060,
+        Mpeg4 = 0x2070,
+        // Hevc = 0x2080,
+        // VP8 = 0x2090,
+        // VP9 = 0x20A0,
+        // VC1 = 0x20B0,
+    }
+}
index bd71381..2745d8c 100755 (executable)
     <Compile Include="Interop\Interop.MediaTool.cs" />
     <Compile Include="Interop\Interop.EvasObject.cs" />
     <Compile Include="Interop\Interop.Player.cs" />
+       <Compile Include="MediaCodec\BufferStatusChangedEventArgs.cs" />
+    <Compile Include="MediaCodec\EosReachedEventArgs.cs" />
+    <Compile Include="MediaCodec\ErrorOccurredEventArgs.cs" />
+    <Compile Include="MediaCodec\InputProcessedEventArgs.cs" />
+    <Compile Include="MediaCodec\MediaCodec.cs" />
+    <Compile Include="MediaCodec\MediaCodecDebug.cs" />
+    <Compile Include="MediaCodec\MediaCodecError.cs" />
+    <Compile Include="MediaCodec\MediaCodecStatus.cs" />
+    <Compile Include="MediaCodec\MediaCodecType.cs" />
+    <Compile Include="MediaCodec\OutputAvailableEventArgs.cs" />
+    <Compile Include="MediaCodec\SupportedCodecType.cs" /
     <Compile Include="MediaTool\MediaFormat.cs" />
     <Compile Include="MediaTool\MediaFormatAacType.cs" />
     <Compile Include="MediaTool\MediaFormatMimeType.cs" />
index a46db69..d8fb310 100755 (executable)
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{0CE698B0-4849-4096-9D7F-30E611F50DAD}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Tizen.Multimedia</RootNamespace>
-    <AssemblyName>Tizen.Multimedia</AssemblyName>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup>
-    <TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
-    <TargetFrameworkVersion>v1.3</TargetFrameworkVersion>
-    <NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>
-    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
-    <NoStdLib>true</NoStdLib>
-    <NoWarn>$(NoWarn);1701;1702</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SignAssembly>true</SignAssembly>
-  </PropertyGroup>
-  <PropertyGroup>
-    <AssemblyOriginatorKeyFile>Tizen.Multimedia.snk</AssemblyOriginatorKeyFile>
-  </PropertyGroup>
-  <ItemGroup>
-    <Compile Include="AudioIO\AudioErrorHelper.cs" />
-    <Compile Include="AudioIO\AudioInput.cs" />
-    <Compile Include="AudioIO\AudioIOEnumerations.cs" />
-    <Compile Include="AudioIO\AudioOutput.cs" />
-    <Compile Include="AudioIO\AudioStateChangedEventArgs.cs" />
-    <Compile Include="AudioIO\AudioStreamLengthChangedEventArgs.cs" />
-    <Compile Include="AudioIO\BaseAudio.cs" />
-    <Compile Include="Interop\Interop.AudioIO.cs" />
-    <Compile Include="Interop\Interop.MediaCodec.cs" />
-    <Compile Include="Interop\Interop.MediaTool.cs" />
-    <Compile Include="Interop\Interop.Player.cs" />
-    <Compile Include="Interop\Interop.MetadataExtractor.cs" />
-    <Compile Include="MediaTool\MediaFormat.cs" />
-    <Compile Include="MediaTool\MediaFormatAacType.cs" />
-    <Compile Include="MediaTool\MediaFormatMimeType.cs" />
-    <Compile Include="MediaTool\MediaFormatTextType.cs" />
-    <Compile Include="MediaTool\MediaPacket.cs" />
-    <Compile Include="MediaTool\MediaPacketBuffer.cs" />
-    <Compile Include="MediaTool\MediaPacketBufferFlags.cs" />
-    <Compile Include="MediaTool\MediaPacketVideoPlane.cs" />
-    <Compile Include="MediaTool\MediaToolDebug.cs" />
-    <Compile Include="MediaTool\NotEnoughMemoryException.cs" />
-    <Compile Include="MetadataExtractor\MetadataEnums.cs" />
-    <Compile Include="MetadataExtractor\MetadataExtractorErrorFactory.cs" />
-    <Compile Include="MetadataExtractor\Synclyrics.cs" />
-    <Compile Include="MetadataExtractor\Frame.cs" />
-    <Compile Include="MetadataExtractor\Artwork.cs" />
-    <Compile Include="MetadataExtractor\Metadata.cs" />
-    <Compile Include="MetadataExtractor\MetadataExtractor.cs" />
-    <Compile Include="Interop\Interop.EvasObject.cs" />
-    <Compile Include="MediaView\MediaView.cs" />
-    <Compile Include="Player\PlayerEnums.cs" />
-    <Compile Include="Player\MediaStreamConfiguration.cs" />
-    <Compile Include="Player\SubtitleTrack.cs" />
-    <Compile Include="Player\AudioEffect.cs" />
-    <Compile Include="Player\BufferingProgressChangedEventArgs.cs" />
-    <Compile Include="Player\BufferStatusEventArgs.cs" />
-    <Compile Include="Player\DownloadProgress.cs" />
-    <Compile Include="Player\EqualizerBand.cs" />
-    <Compile Include="Player\ProgressiveDownloadMessageEventArgs.cs" />
-    <Compile Include="Player\ProgressiveDownloadStatus.cs" />
-    <Compile Include="Player\SeekOffsetEventArgs.cs" />
-    <Compile Include="Player\SubtitleUpdatedEventArgs.cs" />
-    <Compile Include="Player\Display.cs" />
-    <Compile Include="Player\PlaybackCompletedEventArgs.cs" />
-    <Compile Include="Player\PlaybackErrorEventArgs.cs" />
-    <Compile Include="Player\PlaybackInterruptedEventArgs.cs" />
-    <Compile Include="Player\Player.cs" />
-    <Compile Include="Player\PlayerContentInfo.cs" />
-    <Compile Include="Player\StreamInformation.cs" />
-    <Compile Include="Player\StreamingConfiguration.cs" />
-    <Compile Include="Player\Subtitle.cs" />
-    <Compile Include="Player\VideoFrameDecodedEventArgs.cs" />
-    <Compile Include="Player\VideoFrameCapture.cs" />
-    <Compile Include="Player\VideoStreamEventArgs.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Player\MediaSource.cs" />
-    <Compile Include="Player\MediaUriSource.cs" />
-    <Compile Include="Player\MediaBufferSource.cs" />
-    <Compile Include="Player\MediaStreamSource.cs" />
-    <Compile Include="Interop\Interop.Libraries.cs" />
-    <Compile Include="Player\PlayerErrorFactory.cs" />
-    <Compile Include="Recorder\AudioStreamDeliveredEventArgs.cs" />
-    <Compile Include="Recorder\Camera.cs" />
-    <Compile Include="Recorder\Recorder.cs" />
-    <Compile Include="Recorder\RecorderEnums.cs" />
-    <Compile Include="Recorder\RecorderErrorFactory.cs" />
-    <Compile Include="Recorder\RecorderInterruptedEventArgs.cs" />
-    <Compile Include="Recorder\RecorderStateChangedEventArgs.cs" />
-    <Compile Include="Recorder\RecordingErrorOccurredEventArgs.cs" />
-    <Compile Include="Recorder\RecordingLimitReachedEventArgs.cs" />
-    <Compile Include="Recorder\RecordingStatusChangedEventArgs.cs" />
-    <Compile Include="Recorder\VideoResolution.cs" />
-    <Compile Include="Interop\Interop.Recorder.cs" />
-    <Compile Include="Interop\Interop.RecorderAttribute.cs" />
-    <Compile Include="Interop\Interop.RecorderCapability.cs" />
-    <Compile Include="AudioManager\AudioDevice.cs" />
-    <Compile Include="AudioManager\AudioDeviceConnectionChangedEventArgs.cs" />
-    <Compile Include="AudioManager\AudioDevicePropertyChangedEventArgs.cs" />
-    <Compile Include="AudioManager\AudioManager.cs" />
-    <Compile Include="AudioManager\AudioManagerEnumerations.cs" />
-    <Compile Include="AudioManager\AudioManagerErrorFactory.cs" />
-    <Compile Include="AudioManager\AudioStreamPolicy.cs" />
-    <Compile Include="AudioManager\AudioVolume.cs" />
-    <Compile Include="AudioManager\FocusStateChangedEventArgs.cs" />
-    <Compile Include="AudioManager\MaxVolumeLevel.cs" />
-    <Compile Include="AudioManager\StreamFocusStateChangedEventArgs.cs" />
-    <Compile Include="AudioManager\VolumeChangedEventArgs.cs" />
-    <Compile Include="AudioManager\VolumeLevel.cs" />
-    <Compile Include="Interop\Interop.Device.cs" />
-    <Compile Include="Interop\Interop.StreamPolicy.cs" />
-    <Compile Include="Interop\Interop.Volume.cs" />
-    <Compile Include="Interop\Interop.MediaController.cs" />
-    <Compile Include="MediaController\Playback.cs" />
-    <Compile Include="MediaController\Metadata.cs" />
-    <Compile Include="MediaController\ServerInformation.cs" />
-    <Compile Include="MediaController\CustomCommandEventArgs.cs" />
-    <Compile Include="MediaController\PlaybackStateCommandEventArgs.cs" />
-    <Compile Include="MediaController\ServerUpdatedEventArgs.cs" />
-    <Compile Include="MediaController\PlaybackUpdatedEventArgs.cs" />
-    <Compile Include="MediaController\MetadataUpdatedEventArgs.cs" />
-    <Compile Include="MediaController\ShuffleModeUpdatedEventArgs.cs" />
-    <Compile Include="MediaController\RepeatModeUpdatedEventArgs.cs" />
-    <Compile Include="MediaController\MediaControllerErrorFactory.cs" />
-    <Compile Include="MediaController\MediaControllerEnums.cs" />
-    <Compile Include="MediaController\MediaControllerLog.cs" />
-    <Compile Include="MediaController\Client.cs" />
-    <Compile Include="MediaController\Server.cs" />
-    <Compile Include="MediaController\CommandReplyEventArgs.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Tizen.Multimedia.nuspec" />
-    <None Include="Tizen.Multimedia.project.json" />
-    <None Include="Tizen.Multimedia.snk" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProjectGuid>{0CE698B0-4849-4096-9D7F-30E611F50DAD}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <RootNamespace>Tizen.Multimedia</RootNamespace>\r
+    <AssemblyName>Tizen.Multimedia</AssemblyName>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup>\r
+    <TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>\r
+    <TargetFrameworkVersion>v1.3</TargetFrameworkVersion>\r
+    <NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>\r
+    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
+    <NoStdLib>true</NoStdLib>\r
+    <NoWarn>$(NoWarn);1701;1702</NoWarn>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <OutputPath>bin\Debug\</OutputPath>\r
+    <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <OutputPath>bin\Release\</OutputPath>\r
+    <DefineConstants>TRACE</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup>\r
+    <SignAssembly>true</SignAssembly>\r
+  </PropertyGroup>\r
+  <PropertyGroup>\r
+    <AssemblyOriginatorKeyFile>Tizen.Multimedia.snk</AssemblyOriginatorKeyFile>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Compile Include="AudioIO\AudioErrorHelper.cs" />\r
+    <Compile Include="AudioIO\AudioInput.cs" />\r
+    <Compile Include="AudioIO\AudioIOEnumerations.cs" />\r
+    <Compile Include="AudioIO\AudioOutput.cs" />\r
+    <Compile Include="AudioIO\AudioStateChangedEventArgs.cs" />\r
+    <Compile Include="AudioIO\AudioStreamLengthChangedEventArgs.cs" />\r
+    <Compile Include="AudioIO\BaseAudio.cs" />\r
+    <Compile Include="Interop\Interop.AudioIO.cs" />\r
+    <Compile Include="Interop\Interop.MediaCodec.cs" />\r
+    <Compile Include="Interop\Interop.MediaTool.cs" />\r
+    <Compile Include="Interop\Interop.Player.cs" />\r
+    <Compile Include="Interop\Interop.MetadataExtractor.cs" />\r
+    <Compile Include="MediaCodec\BufferStatusChangedEventArgs.cs" />\r
+    <Compile Include="MediaCodec\EosReachedEventArgs.cs" />\r
+    <Compile Include="MediaCodec\ErrorOccurredEventArgs.cs" />\r
+    <Compile Include="MediaCodec\InputProcessedEventArgs.cs" />\r
+    <Compile Include="MediaCodec\MediaCodec.cs" />\r
+    <Compile Include="MediaCodec\MediaCodecDebug.cs" />\r
+    <Compile Include="MediaCodec\MediaCodecError.cs" />\r
+    <Compile Include="MediaCodec\MediaCodecStatus.cs" />\r
+    <Compile Include="MediaCodec\MediaCodecType.cs" />\r
+    <Compile Include="MediaCodec\OutputAvailableEventArgs.cs" />\r
+    <Compile Include="MediaCodec\SupportedCodecType.cs" />\r
+    <Compile Include="MediaTool\MediaFormat.cs" />\r
+    <Compile Include="MediaTool\MediaFormatAacType.cs" />\r
+    <Compile Include="MediaTool\MediaFormatMimeType.cs" />\r
+    <Compile Include="MediaTool\MediaFormatTextType.cs" />\r
+    <Compile Include="MediaTool\MediaPacket.cs" />\r
+    <Compile Include="MediaTool\MediaPacketBuffer.cs" />\r
+    <Compile Include="MediaTool\MediaPacketBufferFlags.cs" />\r
+    <Compile Include="MediaTool\MediaPacketVideoPlane.cs" />\r
+    <Compile Include="MediaTool\MediaToolDebug.cs" />\r
+    <Compile Include="MediaTool\NotEnoughMemoryException.cs" />\r
+    <Compile Include="MetadataExtractor\MetadataEnums.cs" />\r
+    <Compile Include="MetadataExtractor\MetadataExtractorErrorFactory.cs" />\r
+    <Compile Include="MetadataExtractor\Synclyrics.cs" />\r
+    <Compile Include="MetadataExtractor\Frame.cs" />\r
+    <Compile Include="MetadataExtractor\Artwork.cs" />\r
+    <Compile Include="MetadataExtractor\Metadata.cs" />\r
+    <Compile Include="MetadataExtractor\MetadataExtractor.cs" />\r
+    <Compile Include="Interop\Interop.EvasObject.cs" />\r
+    <Compile Include="MediaView\MediaView.cs" />\r
+    <Compile Include="Player\PlayerEnums.cs" />\r
+    <Compile Include="Player\MediaStreamConfiguration.cs" />\r
+    <Compile Include="Player\SubtitleTrack.cs" />\r
+    <Compile Include="Player\AudioEffect.cs" />\r
+    <Compile Include="Player\BufferingProgressChangedEventArgs.cs" />\r
+    <Compile Include="Player\BufferStatusEventArgs.cs" />\r
+    <Compile Include="Player\DownloadProgress.cs" />\r
+    <Compile Include="Player\EqualizerBand.cs" />\r
+    <Compile Include="Player\ProgressiveDownloadMessageEventArgs.cs" />\r
+    <Compile Include="Player\ProgressiveDownloadStatus.cs" />\r
+    <Compile Include="Player\SeekOffsetEventArgs.cs" />\r
+    <Compile Include="Player\SubtitleUpdatedEventArgs.cs" />\r
+    <Compile Include="Player\Display.cs" />\r
+    <Compile Include="Player\PlaybackCompletedEventArgs.cs" />\r
+    <Compile Include="Player\PlaybackErrorEventArgs.cs" />\r
+    <Compile Include="Player\PlaybackInterruptedEventArgs.cs" />\r
+    <Compile Include="Player\Player.cs" />\r
+    <Compile Include="Player\PlayerContentInfo.cs" />\r
+    <Compile Include="Player\StreamInformation.cs" />\r
+    <Compile Include="Player\StreamingConfiguration.cs" />\r
+    <Compile Include="Player\Subtitle.cs" />\r
+    <Compile Include="Player\VideoFrameDecodedEventArgs.cs" />\r
+    <Compile Include="Player\VideoFrameCapture.cs" />\r
+    <Compile Include="Player\VideoStreamEventArgs.cs" />\r
+    <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="Player\MediaSource.cs" />\r
+    <Compile Include="Player\MediaUriSource.cs" />\r
+    <Compile Include="Player\MediaBufferSource.cs" />\r
+    <Compile Include="Player\MediaStreamSource.cs" />\r
+    <Compile Include="Interop\Interop.Libraries.cs" />\r
+    <Compile Include="Player\PlayerErrorFactory.cs" />\r
+    <Compile Include="Recorder\AudioStreamDeliveredEventArgs.cs" />\r
+    <Compile Include="Recorder\Camera.cs" />\r
+    <Compile Include="Recorder\Recorder.cs" />\r
+    <Compile Include="Recorder\RecorderEnums.cs" />\r
+    <Compile Include="Recorder\RecorderErrorFactory.cs" />\r
+    <Compile Include="Recorder\RecorderInterruptedEventArgs.cs" />\r
+    <Compile Include="Recorder\RecorderStateChangedEventArgs.cs" />\r
+    <Compile Include="Recorder\RecordingErrorOccurredEventArgs.cs" />\r
+    <Compile Include="Recorder\RecordingLimitReachedEventArgs.cs" />\r
+    <Compile Include="Recorder\RecordingStatusChangedEventArgs.cs" />\r
+    <Compile Include="Recorder\VideoResolution.cs" />\r
+    <Compile Include="Interop\Interop.Recorder.cs" />\r
+    <Compile Include="Interop\Interop.RecorderAttribute.cs" />\r
+    <Compile Include="Interop\Interop.RecorderCapability.cs" />\r
+    <Compile Include="AudioManager\AudioDevice.cs" />\r
+    <Compile Include="AudioManager\AudioDeviceConnectionChangedEventArgs.cs" />\r
+    <Compile Include="AudioManager\AudioDevicePropertyChangedEventArgs.cs" />\r
+    <Compile Include="AudioManager\AudioManager.cs" />\r
+    <Compile Include="AudioManager\AudioManagerEnumerations.cs" />\r
+    <Compile Include="AudioManager\AudioManagerErrorFactory.cs" />\r
+    <Compile Include="AudioManager\AudioStreamPolicy.cs" />\r
+    <Compile Include="AudioManager\AudioVolume.cs" />\r
+    <Compile Include="AudioManager\FocusStateChangedEventArgs.cs" />\r
+    <Compile Include="AudioManager\MaxVolumeLevel.cs" />\r
+    <Compile Include="AudioManager\StreamFocusStateChangedEventArgs.cs" />\r
+    <Compile Include="AudioManager\VolumeChangedEventArgs.cs" />\r
+    <Compile Include="AudioManager\VolumeLevel.cs" />\r
+    <Compile Include="Interop\Interop.Device.cs" />\r
+    <Compile Include="Interop\Interop.StreamPolicy.cs" />\r
+    <Compile Include="Interop\Interop.Volume.cs" />\r
+    <Compile Include="Interop\Interop.MediaController.cs" />\r
+    <Compile Include="MediaController\Playback.cs" />\r
+    <Compile Include="MediaController\Metadata.cs" />\r
+    <Compile Include="MediaController\ServerInformation.cs" />\r
+    <Compile Include="MediaController\CustomCommandEventArgs.cs" />\r
+    <Compile Include="MediaController\PlaybackStateCommandEventArgs.cs" />\r
+    <Compile Include="MediaController\ServerUpdatedEventArgs.cs" />\r
+    <Compile Include="MediaController\PlaybackUpdatedEventArgs.cs" />\r
+    <Compile Include="MediaController\MetadataUpdatedEventArgs.cs" />\r
+    <Compile Include="MediaController\ShuffleModeUpdatedEventArgs.cs" />\r
+    <Compile Include="MediaController\RepeatModeUpdatedEventArgs.cs" />\r
+    <Compile Include="MediaController\MediaControllerErrorFactory.cs" />\r
+    <Compile Include="MediaController\MediaControllerEnums.cs" />\r
+    <Compile Include="MediaController\MediaControllerLog.cs" />\r
+    <Compile Include="MediaController\Client.cs" />\r
+    <Compile Include="MediaController\Server.cs" />\r
+    <Compile Include="MediaController\CommandReplyEventArgs.cs" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="Tizen.Multimedia.nuspec" />\r
+    <None Include="Tizen.Multimedia.project.json" />\r
+    <None Include="Tizen.Multimedia.snk" />\r
+  </ItemGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
-  <PropertyGroup>
+  -->\r
+  <PropertyGroup>\r
     <!-- https://github.com/dotnet/corefxlab/tree/master/samples/NetCoreSample and
        https://docs.microsoft.com/en-us/dotnet/articles/core/tutorials/target-dotnetcore-with-msbuild
-    -->
+    -->\r
     <!-- We don't use any of MSBuild's resolution logic for resolving the framework, so just set these two
        properties to any folder that exists to skip the GetReferenceAssemblyPaths task (not target) and
        to prevent it from outputting a warning (MSB3644).
-    -->
-    <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)</_TargetFrameworkDirectories>
-    <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>
-    <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>
-  </PropertyGroup>
+    -->\r
+    <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)</_TargetFrameworkDirectories>\r
+    <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>\r
+    <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>\r
+  </PropertyGroup>\r
 </Project>
\ No newline at end of file