[MediaTool] Add audio channel mapping APIs for PCM format (#1000)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia / MediaTool / MediaPacket.cs
index ffecc12..43ba0c4 100644 (file)
 
 using System;
 using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Threading;
 using Tizen.Internals.Errors;
+using Native = Tizen.Multimedia.Interop.MediaPacket;
+using NativeFormat = Tizen.Multimedia.Interop.MediaFormat;
 
 namespace Tizen.Multimedia
 {
     /// <summary>
     /// Represents a packet for multimedia.
     /// </summary>
-    public abstract class MediaPacket : IDisposable
+    public abstract partial class MediaPacket : IBufferOwner, IDisposable
     {
         private IntPtr _handle = IntPtr.Zero;
 
@@ -33,10 +33,11 @@ namespace Tizen.Multimedia
         /// Initializes a new instance of the MediaPacket class with the specified media format.
         /// </summary>
         /// <param name="format">The media format containing properties for the packet.</param>
-        /// <exception cref="System.ArgumentNullException">format is null.</exception>
-        /// <exception cref="System.ArgumentException">
-        ///     <see cref="MediaFormatType"/> of the specified format is <see cref="MediaFormatType.Container"/>.</exception>
-        /// <exception cref="System.InvalidOperationException">Operation failed.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="format"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     The <see cref="MediaFormatType"/> of the specified format is <see cref="MediaFormatType.Container"/>.
+        /// </exception>
+        /// <exception cref="InvalidOperationException">Operation failed.</exception>
         internal MediaPacket(MediaFormat format)
         {
             if (format == null)
@@ -44,13 +45,10 @@ namespace Tizen.Multimedia
                 throw new ArgumentNullException(nameof(format));
             }
 
-            if (format.Type == MediaFormatType.Container)
-            {
-                throw new ArgumentException("Container format can't be used to create a new packet.");
-            }
-
             Initialize(format);
+
             _format = format;
+            _buffer = new Lazy<IMediaBuffer>(GetBuffer);
         }
 
         /// <summary>
@@ -61,8 +59,7 @@ namespace Tizen.Multimedia
         {
             _handle = handle;
 
-            IntPtr formatHandle;
-            int ret = Interop.MediaPacket.GetFormat(handle, out formatHandle);
+            int ret = Native.GetFormat(handle, out IntPtr formatHandle);
 
             MultimediaDebug.AssertNoError(ret);
 
@@ -75,10 +72,13 @@ namespace Tizen.Multimedia
             }
             finally
             {
-                Interop.MediaFormat.Unref(formatHandle);
+                NativeFormat.Unref(formatHandle);
             }
         }
 
+        /// <summary>
+        /// Finalizes an instance of the MediaPacket class.
+        /// </summary>
         ~MediaPacket()
         {
             Dispose(false);
@@ -88,12 +88,13 @@ namespace Tizen.Multimedia
         /// Creates and initializes a native handle for the current object.
         /// </summary>
         /// <param name="format">The format to be set to the media format.</param>
-        /// <exception cref="System.InvalidOperationException">Operation failed.</exception>
+        /// <exception cref="InvalidOperationException">Operation failed.</exception>
         private void Initialize(MediaFormat format)
         {
             if (format.Type == MediaFormatType.Container)
             {
-                throw new ArgumentException("Creating a packet for container is not supported.");
+                throw new ArgumentException("Container format can't be used to create a new packet.",
+                    nameof(format));
             }
 
             IntPtr formatHandle = IntPtr.Zero;
@@ -102,7 +103,7 @@ namespace Tizen.Multimedia
             {
                 formatHandle = format.AsNativeHandle();
 
-                int ret = Interop.MediaPacket.Create(formatHandle, IntPtr.Zero, IntPtr.Zero, out _handle);
+                int ret = Native.Create(formatHandle, IntPtr.Zero, IntPtr.Zero, out _handle);
                 MultimediaDebug.AssertNoError(ret);
 
                 Debug.Assert(_handle != IntPtr.Zero, "Created handle must not be null");
@@ -113,7 +114,7 @@ namespace Tizen.Multimedia
             {
                 if (_handle != IntPtr.Zero)
                 {
-                    Interop.MediaPacket.Destroy(_handle);
+                    Native.Destroy(_handle);
                     _handle = IntPtr.Zero;
                 }
 
@@ -123,7 +124,7 @@ namespace Tizen.Multimedia
             {
                 if (formatHandle != IntPtr.Zero)
                 {
-                    Interop.MediaFormat.Unref(formatHandle);
+                    NativeFormat.Unref(formatHandle);
                 }
             }
         }
@@ -131,15 +132,17 @@ namespace Tizen.Multimedia
         /// <summary>
         /// Allocates internal buffer.
         /// </summary>
-        /// <exception cref="System.InvalidOperationException">Operation failed.</exception>
+        /// <exception cref="InvalidOperationException">Operation failed.</exception>
         private void Alloc()
         {
-            ErrorCode ret = (ErrorCode)Interop.MediaPacket.Alloc(_handle);
+            ErrorCode ret = (ErrorCode)Native.Alloc(_handle);
             if (ret == ErrorCode.None)
             {
                 return;
             }
 
+            _handle = IntPtr.Zero;
+
             switch (ret)
             {
                 case ErrorCode.OutOfMemory:
@@ -156,6 +159,7 @@ namespace Tizen.Multimedia
         /// <summary>
         /// Gets the media format of the current packet.
         /// </summary>
+        /// <since_tizen> 3 </since_tizen>
         public MediaFormat Format
         {
             get
@@ -168,17 +172,18 @@ namespace Tizen.Multimedia
         /// <summary>
         /// Gets or sets the PTS(Presentation Time Stamp) value of the current packet.
         /// </summary>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         /// <exception cref="InvalidOperationException">
-        ///     The MediaPacket is not writable state which means it being used by another module.</exception>
+        ///     The MediaPacket is not in the writable state, which means it is being used by another module.
+        /// </exception>
+        /// <since_tizen> 3 </since_tizen>
         public ulong Pts
         {
             get
             {
                 ValidateNotDisposed();
 
-                ulong value = 0;
-                int ret = Interop.MediaPacket.GetPts(_handle, out value);
+                int ret = Native.GetPts(_handle, out var value);
 
                 MultimediaDebug.AssertNoError(ret);
 
@@ -189,7 +194,7 @@ namespace Tizen.Multimedia
                 ValidateNotDisposed();
                 ValidateNotLocked();
 
-                int ret = Interop.MediaPacket.SetPts(_handle, value);
+                int ret = Native.SetPts(_handle, value);
 
                 MultimediaDebug.AssertNoError(ret);
             }
@@ -198,18 +203,18 @@ namespace Tizen.Multimedia
         /// <summary>
         /// Gets or sets the DTS(Decoding Time Stamp) value of the current packet.
         /// </summary>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         /// <exception cref="InvalidOperationException">
-        ///     The MediaPacket is not in writable state which means it being used by another module.</exception>
+        ///     The MediaPacket is not in the writable state, which means it is being used by another module.
+        /// </exception>
+        /// <since_tizen> 3 </since_tizen>
         public ulong Dts
         {
             get
             {
                 ValidateNotDisposed();
 
-                ulong value = 0;
-                int ret = Interop.MediaPacket.GetDts(_handle, out value);
-
+                int ret = Native.GetDts(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 return value;
@@ -219,43 +224,150 @@ namespace Tizen.Multimedia
                 ValidateNotDisposed();
                 ValidateNotLocked();
 
-                int ret = Interop.MediaPacket.SetDts(_handle, value);
+                int ret = Native.SetDts(_handle, value);
+                MultimediaDebug.AssertNoError(ret);
+            }
+        }
 
+        /// <summary>
+        /// Gets or sets the duration value of the current packet.
+        /// </summary>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
+        /// <exception cref="InvalidOperationException">
+        ///     The MediaPacket is not in the writable state, which means it is being used by another module.
+        /// </exception>
+        /// <since_tizen> 6 </since_tizen>
+        public ulong Duration
+        {
+            get
+            {
+                ValidateNotDisposed();
+
+                int ret = Native.GetDuration(_handle, out var value);
+                MultimediaDebug.AssertNoError(ret);
+
+                return value;
+            }
+            set
+            {
+                ValidateNotDisposed();
+                ValidateNotLocked();
+
+                int ret = Native.SetDuration(_handle, value);
                 MultimediaDebug.AssertNoError(ret);
             }
         }
 
         /// <summary>
-        /// Gets a value indicating whether the packet is encoded type.
+        /// Gets a value indicating whether the packet is the encoded type.
         /// </summary>
-        /// <value>true if the packet is encoded type; otherwise, false.</value>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+        /// <value>true if the packet is the encoded type; otherwise, false.</value>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
+        /// <since_tizen> 3 </since_tizen>
         public bool IsEncoded
         {
             get
             {
                 ValidateNotDisposed();
 
-                bool value = false;
-                int ret = Interop.MediaPacket.IsEncoded(_handle, out value);
-
+                int ret = Native.IsEncoded(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 return value;
             }
         }
 
-        private MediaPacketBuffer _buffer;
+        /// <summary>
+        /// Gets or sets the rotation value of the current packet.
+        /// </summary>
+        /// <exception cref="ArgumentException">The specified value to set is invalid.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
+        /// <exception cref="InvalidOperationException">
+        ///     The MediaPacket is not in the writable state, which means it is being used by another module.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public Rotation Rotation
+        {
+            get
+            {
+                ValidateNotDisposed();
+
+                int ret = Native.GetRotation(_handle, out var value);
+                MultimediaDebug.AssertNoError(ret);
+
+                var rotation = value < RotationFlip.HorizontalFlip ? (Rotation)value : Rotation.Rotate0;
+
+                return rotation;
+            }
+            set
+            {
+                ValidateNotDisposed();
+                ValidateNotLocked();
+                ValidationUtil.ValidateEnum(typeof(Rotation), value, nameof(value));
+
+                int ret = Native.SetRotation(_handle, (RotationFlip)value);
+                MultimediaDebug.AssertNoError(ret);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the flip value of the current packet.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="Flips.None"/> will be ignored in set case. It's not supported in Native FW.
+        /// </remarks>
+        /// <exception cref="ArgumentException">The specified value to set is invalid.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
+        /// <exception cref="InvalidOperationException">
+        ///     The MediaPacket is not in the writable state, which means it is being used by another module.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public Flips Flip
+        {
+            get
+            {
+                ValidateNotDisposed();
+
+                int ret = Native.GetRotation(_handle, out var value);
+                MultimediaDebug.AssertNoError(ret);
+
+                var flip = (value < RotationFlip.HorizontalFlip) ? Flips.None :
+                    (value == RotationFlip.HorizontalFlip ? Flips.Horizontal : Flips.Vertical);
+
+                return flip;
+            }
+            set
+            {
+                ValidateNotDisposed();
+                ValidateNotLocked();
+                ValidationUtil.ValidateEnum(typeof(Flips), value, nameof(value));
+
+                if (value == Flips.None)
+                {
+                    return;
+                }
+
+                var flip = value == Flips.Horizontal ? RotationFlip.HorizontalFlip : RotationFlip.VerticalFlip;
+
+                int ret = Native.SetRotation(_handle, flip);
+                MultimediaDebug.AssertNoError(ret);
+            }
+        }
+
+        private Lazy<IMediaBuffer> _buffer;
 
         /// <summary>
         /// Gets the buffer of the packet.
         /// </summary>
-        /// <value>The <see cref="MediaPacketBuffer"/> allocated to the packet.
-        ///     This property will return null if the packet is raw video format.</value>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+        /// <value>
+        /// The <see cref="IMediaBuffer"/> allocated to the packet.
+        /// This property will return null if the packet is in the raw video format.
+        /// </value>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         /// <seealso cref="IsEncoded"/>
         /// <seealso cref="VideoPlanes"/>
-        public MediaPacketBuffer Buffer
+        /// <since_tizen> 3 </since_tizen>
+        public IMediaBuffer Buffer
         {
             get
             {
@@ -266,34 +378,29 @@ namespace Tizen.Multimedia
                     return null;
                 }
 
-                if (_buffer == null)
-                {
-                    _buffer = GetBuffer();
-                }
-
-                return _buffer;
+                return _buffer.Value;
             }
         }
 
         /// <summary>
         /// Gets or sets a length of data written in the <see cref="Buffer"/>.
         /// </summary>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         /// <exception cref="ArgumentOutOfRangeException">
-        ///     The value specified for this property is less than zero or greater than <see cref="MediaPacketBuffer.Length"/>.</exception>
+        ///     The value specified for this property is less than zero or greater than the length of the <see cref="Buffer"/>.</exception>
         /// <exception cref="InvalidOperationException">
-        ///     The MediaPacket has <see cref="VideoPlanes"/> instead of <see cref="Buffer"/>.\n
-        ///     -or-\n
-        ///     The MediaPacket is not in writable state which means it being used by another module.
+        ///     The MediaPacket has <see cref="VideoPlanes"/> instead of <see cref="Buffer"/>.<br/>
+        ///     -or-<br/>
+        ///     The MediaPacket is not in the writable state, which means it is being used by another module.
         ///     </exception>
+        /// <since_tizen> 3 </since_tizen>
         public int BufferWrittenLength
         {
             get
             {
                 ValidateNotDisposed();
 
-                ulong value = 0;
-                int ret = Interop.MediaPacket.GetBufferSize(_handle, out value);
+                int ret = Native.GetBufferSize(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 Debug.Assert(value < int.MaxValue);
@@ -315,10 +422,11 @@ namespace Tizen.Multimedia
 
                 if (value < 0 || value >= Buffer.Length)
                 {
-                    throw new ArgumentOutOfRangeException("value must be less than Buffer.Size.");
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "value must be less than Buffer.Size.");
                 }
 
-                int ret = Interop.MediaPacket.SetBufferSize(_handle, (ulong)value);
+                int ret = Native.SetBufferSize(_handle, (ulong)value);
                 MultimediaDebug.AssertNoError(ret);
             }
         }
@@ -329,10 +437,11 @@ namespace Tizen.Multimedia
         /// Gets the video planes of the packet.
         /// </summary>
         /// <value>The <see cref="MediaPacketVideoPlane"/>s allocated to the packet.
-        ///     This property will return null if the packet is not raw video format.</value>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+        ///     This property will return null if the packet is not in the raw video format.</value>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         /// <seealso cref="IsEncoded"/>
         /// <seealso cref="Buffer"/>
+        /// <since_tizen> 3 </since_tizen>
         public MediaPacketVideoPlane[] VideoPlanes
         {
             get
@@ -356,23 +465,22 @@ namespace Tizen.Multimedia
         /// <summary>
         /// Gets or sets the buffer flags of the packet.
         /// </summary>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         /// <exception cref="InvalidOperationException">
-        ///     The MediaPacket is not in writable state which means it being used by another module.
-        ///     </exception>
+        ///     The MediaPacket is not in the writable state, which means it is being used by another module.
+        /// </exception>
+        /// <since_tizen> 3 </since_tizen>
         public MediaPacketBufferFlags BufferFlags
         {
             get
             {
                 ValidateNotDisposed();
 
-                int value = 0;
-
-                int ret = Interop.MediaPacket.GetBufferFlags(_handle, out value);
+                int ret = Native.GetBufferFlags(_handle, out var value);
 
                 MultimediaDebug.AssertNoError(ret);
 
-                return (MediaPacketBufferFlags)value;
+                return value;
             }
 
             set
@@ -380,36 +488,33 @@ namespace Tizen.Multimedia
                 ValidateNotDisposed();
                 ValidateNotLocked();
 
-                int ret = Interop.MediaPacket.ResetBufferFlags(_handle);
+                int ret = Native.ResetBufferFlags(_handle);
 
                 MultimediaDebug.AssertNoError(ret);
 
-                ret = Interop.MediaPacket.SetBufferFlags(_handle, (int)value);
+                ret = Native.SetBufferFlags(_handle, (int)value);
 
                 MultimediaDebug.AssertNoError(ret);
             }
         }
 
+        #region Dispose support
         /// <summary>
         /// Gets a value indicating whether the packet has been disposed of.
         /// </summary>
         /// <value>true if the packet has been disposed of; otherwise, false.</value>
-        public bool IsDisposed
-        {
-            get
-            {
-                return _isDisposed;
-            }
-        }
+        /// <since_tizen> 3 </since_tizen>
+        public bool IsDisposed => _isDisposed;
 
         private bool _isDisposed = false;
 
         /// <summary>
-        /// Releases all resources.
+        /// Releases all resources used by the <see cref="MediaPacket"/> object.
         /// </summary>
         /// <exception cref="InvalidOperationException">
-        ///     The MediaPacket can not be disposed which means it being used by another module.
-        ///     </exception>
+        ///     The MediaPacket can not be disposed, which means it is being used by another module.
+        /// </exception>
+        /// <since_tizen> 3 </since_tizen>
         public void Dispose()
         {
             if (_isDisposed)
@@ -422,6 +527,13 @@ namespace Tizen.Multimedia
             GC.SuppressFinalize(this);
         }
 
+        /// <summary>
+        /// Releases the resources used by the <see cref="MediaPacket"/> object.
+        /// </summary>
+        /// <param name="disposing">
+        /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+        /// </param>
+        /// <since_tizen> 3 </since_tizen>
         protected virtual void Dispose(bool disposing)
         {
             if (_isDisposed)
@@ -431,24 +543,15 @@ namespace Tizen.Multimedia
 
             if (_handle != IntPtr.Zero)
             {
-                Interop.MediaPacket.Destroy(_handle);
+                Native.Destroy(_handle);
                 _handle = IntPtr.Zero;
             }
 
             _isDisposed = true;
         }
 
-        internal IntPtr GetHandle()
-        {
-            ValidateNotDisposed();
-
-            Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
-
-            return _handle;
-        }
-
         /// <summary>
-        /// Validate the current object has not been disposed of.
+        /// Validates the current object has not been disposed of.
         /// </summary>
         /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         private void ValidateNotDisposed()
@@ -458,26 +561,21 @@ namespace Tizen.Multimedia
                 throw new ObjectDisposedException("This packet has already been disposed of.");
             }
         }
+        #endregion
 
-        /// <summary>
-        /// Validate the current object is not locked.
-        /// </summary>
-        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
-        /// <exception cref="InvalidOperationException">The MediaPacket is in use by another module.</exception>
-        private void ValidateNotLocked()
+        internal IntPtr GetHandle()
         {
             ValidateNotDisposed();
 
-            if (_lock.IsLocked)
-            {
-                throw new InvalidOperationException("Can't perform any writing operation." +
-                    "The packet is in use, internally.");
-            }
+            Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
+
+            return _handle;
         }
+
         /// <summary>
         /// Ensures whether the packet is writable.
         /// </summary>
-        /// <exception cref="ObjectDisposedException">The MediaPacket already has been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         /// <exception cref="InvalidOperationException">The MediaPacket is being used by another module.</exception>
         internal void EnsureWritableState()
         {
@@ -488,23 +586,17 @@ namespace Tizen.Multimedia
         /// <summary>
         /// Ensures whether the packet is readable.
         /// </summary>
-        /// <exception cref="ObjectDisposedException">The MediaPacket already has been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The MediaPacket has already been disposed of.</exception>
         internal void EnsureReadableState()
         {
             ValidateNotDisposed();
         }
 
         /// <summary>
-        /// Gets a value indicating whether the packet is raw video format.
+        /// Gets a value indicating whether the packet is in the raw video format.
         /// </summary>
-        /// <value>true if the packet is raw video format; otherwise, false.</value>
-        private bool IsVideoPlaneSupported
-        {
-            get
-            {
-                return !IsEncoded && Format.Type == MediaFormatType.Video;
-            }
-        }
+        /// <value>true if the packet is in the raw video format; otherwise, false.</value>
+        private bool IsVideoPlaneSupported => !IsEncoded && Format.Type == MediaFormatType.Video;
 
         /// <summary>
         /// Retrieves video planes of the current packet.
@@ -514,8 +606,7 @@ namespace Tizen.Multimedia
         {
             Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
 
-            uint numberOfPlanes = 0;
-            int ret = Interop.MediaPacket.GetNumberOfVideoPlanes(_handle, out numberOfPlanes);
+            int ret = Native.GetNumberOfVideoPlanes(_handle, out var numberOfPlanes);
 
             MultimediaDebug.AssertNoError(ret);
 
@@ -532,194 +623,32 @@ namespace Tizen.Multimedia
         /// <summary>
         /// Retrieves the buffer of the current packet.
         /// </summary>
-        /// <returns>The <see cref="MediaPacketBuffer"/> allocated to the current MediaPacket.</returns>
-        private MediaPacketBuffer GetBuffer()
+        /// <returns>The <see cref="IMediaBuffer"/> allocated to the current MediaPacket.</returns>
+        private IMediaBuffer GetBuffer()
         {
-            Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
+            Debug.Assert(!IsDisposed, "Packet is already disposed!");
 
-            IntPtr dataHandle;
+            Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
 
-            int ret = Interop.MediaPacket.GetBufferData(_handle, out dataHandle);
+            int ret = Native.GetBufferData(_handle, out var dataHandle);
             MultimediaDebug.AssertNoError(ret);
 
             Debug.Assert(dataHandle != IntPtr.Zero, "Data handle is invalid!");
 
-            int size = 0;
-            ret = Interop.MediaPacket.GetAllocatedBufferSize(_handle, out size);
+            ret = Native.GetAllocatedBufferSize(_handle, out var size);
             MultimediaDebug.AssertNoError(ret);
 
-            return new MediaPacketBuffer(this, dataHandle, size);
-        }
-
-        #region Lock operations
-        private readonly LockState _lock = new LockState();
+            Debug.Assert(size >= 0, "size must not be negative!");
 
-        /// <summary>
-        /// Provides a thread-safe lock state controller.
-        /// </summary>
-        private sealed class LockState
-        {
-            const int LOCKED = 1;
-            const int UNLOCKED = 0;
-
-            private int _locked = UNLOCKED;
-
-            internal void SetLock()
-            {
-                if (Interlocked.CompareExchange(ref _locked, LOCKED, UNLOCKED) == LOCKED)
-                {
-                    throw new InvalidOperationException("The packet is already locked.");
-                }
-            }
-
-            internal void SetUnlock()
-            {
-                if (Interlocked.CompareExchange(ref _locked, UNLOCKED, LOCKED) == UNLOCKED)
-                {
-                    Debug.Fail("The packet to unlock is not locked. " +
-                        "There must be an error somewhere that a lock isn't disposed correctly.");
-                }
-            }
-
-            internal bool IsLocked
-            {
-                get
-                {
-                    return Interlocked.CompareExchange(ref _locked, 0, 0) == LOCKED;
-                }
-            }
+            return new DependentMediaBuffer(this, dataHandle, size);
         }
 
         /// <summary>
-        /// Provides a thread-safe lock controller.
-        /// </summary>
-        /// <example>
-        /// using (var lock = BaseMeadiPacket.Lock(mediaPacket))
-        /// {
-        ///     ....
-        /// }
-        /// </example>
-        internal sealed class Lock : IDisposable
-        {
-            private readonly MediaPacket _packet;
-            private readonly GCHandle _gcHandle;
-            private int _lockCount;
-
-            internal static Lock Get(MediaPacket packet)
-            {
-                Debug.Assert(packet != null);
-
-                lock (packet)
-                {
-                    Lock lck = FromHandle(packet._handle);
-
-                    if (lck == null)
-                    {
-                        lck = new Lock(packet);
-                    }
-
-                    lck._lockCount++;
-
-                    return lck;
-                }
-            }
-
-            private Lock(MediaPacket packet)
-            {
-                Debug.Assert(packet != null, "The packet is null!");
-
-                packet.ValidateNotDisposed();
-
-                _packet = packet;
-
-                _packet._lock.SetLock();
-
-                _gcHandle = GCHandle.Alloc(this);
-
-                SetExtra(GCHandle.ToIntPtr(_gcHandle));
-            }
-
-            internal static Lock FromHandle(IntPtr handle)
-            {
-                Debug.Assert(handle != IntPtr.Zero);
-
-                IntPtr extra = GetExtra(handle);
-
-                if (extra == IntPtr.Zero)
-                {
-                    return null;
-                }
-
-                return (Lock)GCHandle.FromIntPtr(extra).Target;
-            }
-
-            private void SetExtra(IntPtr ptr)
-            {
-                int ret = Interop.MediaPacket.SetExtra(_packet._handle, ptr);
-
-                MultimediaDebug.AssertNoError(ret);
-            }
-
-            private static IntPtr GetExtra(IntPtr handle)
-            {
-                IntPtr value;
-
-                int ret = Interop.MediaPacket.GetExtra(handle, out value);
-
-                MultimediaDebug.AssertNoError(ret);
-
-                return value;
-            }
-
-            internal IntPtr GetHandle()
-            {
-                return _packet.GetHandle();
-            }
-
-            internal MediaPacket MediaPacket
-            {
-                get
-                {
-                    return _packet;
-                }
-            }
-
-            private bool _isDisposed = false;
-
-            public void Dispose()
-            {
-                if (!_isDisposed)
-                {
-                    lock (_packet)
-                    {
-                        _lockCount--;
-
-                        if (_lockCount == 0)
-                        {
-                            // TODO rollback after the corresponding native api is fixed.
-                            //SetExtra(IntPtr.Zero);
-
-                            if (_gcHandle.IsAllocated)
-                            {
-                                _gcHandle.Free();
-                            }
-
-                            //We can assure that at this point '_packet' is always locked by this lock.
-                            _packet._lock.SetUnlock();
-                        }
-                    }
-
-                    _isDisposed = true;
-                }
-            }
-        }
-        #endregion
-
-        /// <summary>
-        /// Creates an object of the MediaPacekt with the specified <see cref="MediaFormat"/>.
+        /// Creates an object of the MediaPacket with the specified <see cref="MediaFormat"/>.
         /// </summary>
         /// <param name="format">The media format for the new packet.</param>
         /// <returns>A new MediaPacket object.</returns>
+        /// <since_tizen> 3 </since_tizen>
         public static MediaPacket Create(MediaFormat format)
         {
             return new SimpleMediaPacket(format);
@@ -729,6 +658,10 @@ namespace Tizen.Multimedia
         {
             return new SimpleMediaPacket(handle);
         }
+
+        bool IBufferOwner.IsDisposed => IsDisposed;
+
+        bool IBufferOwner.IsBufferAccessible(object buffer, MediaBufferAccessMode accessMode) => true;
     }
 
     internal class SimpleMediaPacket : MediaPacket