Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Vision / MediaVision / MediaVisionSource.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Diagnostics;
19 using InteropSource = Interop.MediaVision.MediaSource;
20
21 namespace Tizen.Multimedia
22 {
23     /// <summary>
24     /// Represents the media vision source to keep information on image or video frame data as raw buffer.
25     /// </summary>
26     /// <since_tizen> 3</since_tizen>
27     public class MediaVisionSource : IBufferOwner, IDisposable
28     {
29         private IntPtr _handle = IntPtr.Zero;
30         private bool _disposed = false;
31
32         internal MediaVisionSource()
33         {
34             InteropSource.Create(out _handle).Validate("Failed to create media vision source");
35         }
36
37         private MediaVisionSource(Action<IntPtr> fillAction)
38             : this()
39         {
40             try
41             {
42                 fillAction(_handle);
43             }
44             catch(Exception)
45             {
46                 InteropSource.Destroy(_handle);
47                 _disposed = true;
48                 throw;
49             }
50         }
51
52         private static void FillMediaPacket(IntPtr handle, MediaPacket mediaPacket)
53         {
54             Debug.Assert(handle != IntPtr.Zero);
55
56             if (mediaPacket == null)
57             {
58                 throw new ArgumentNullException(nameof(mediaPacket));
59             }
60
61             InteropSource.FillMediaPacket(handle, mediaPacket.GetHandle()).
62                 Validate("Failed to fill media packet");
63         }
64
65         /// <summary>
66         /// Initializes a new instance of the <see cref="MediaVisionSource"/> class based on the <see cref="MediaPacket"/>.
67         /// </summary>
68         /// <param name="mediaPacket">The <see cref="MediaPacket"/> from which the source will be filled.</param>
69         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
70         /// <exception cref="ArgumentNullException"><paramref name="mediaPacket"/> is null.</exception>
71         /// <exception cref="ObjectDisposedException"><paramref name="mediaPacket"/> has already been disposed of.</exception>
72         /// <since_tizen> 3</since_tizen>
73         public MediaVisionSource(MediaPacket mediaPacket)
74             : this(handle => FillMediaPacket(handle, mediaPacket))
75         {
76         }
77
78         private static void FillBuffer(IntPtr handle, byte[] buffer, uint width, uint height, Colorspace colorspace)
79         {
80             Debug.Assert(handle != IntPtr.Zero);
81
82             if (buffer == null)
83             {
84                 throw new ArgumentNullException(nameof(buffer));
85             }
86
87             if (buffer.Length == 0)
88             {
89                 throw new ArgumentException("Buffer.Length is zero.", nameof(buffer));
90             }
91
92             if (colorspace == Colorspace.Invalid)
93             {
94                 throw new ArgumentException($"color space must not be {Colorspace.Invalid}.", nameof(colorspace));
95             }
96
97             ValidationUtil.ValidateEnum(typeof(Colorspace), colorspace, nameof(colorspace));
98
99             InteropSource.FillBuffer(handle, buffer, buffer.Length, width, height, colorspace).
100                 Validate("Failed to fill buffer");
101         }
102
103         /// <summary>
104         /// Initializes a new instance of the <see cref="MediaVisionSource"/> class based on the buffer and <see cref="Colorspace"/>.
105         /// </summary>
106         /// <param name="buffer">The buffer of image data.</param>
107         /// <param name="width">The width of image.</param>
108         /// <param name="height">The height of image.</param>
109         /// <param name="colorspace">The image <see cref="Colorspace"/>.</param>
110         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
111         /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
112         /// <exception cref="ArgumentException">
113         ///     <paramref name="buffer"/> has no element.(The length is zero.)\n
114         ///     -or-\n
115         ///     <paramref name="colorspace"/> is invalid.
116         /// </exception>
117         /// <since_tizen> 3</since_tizen>
118         public MediaVisionSource(byte[] buffer, uint width, uint height, Colorspace colorspace)
119             : this(handle => FillBuffer(handle, buffer, width, height, colorspace))
120         {
121         }
122
123         ~MediaVisionSource()
124         {
125             Dispose(false);
126         }
127
128         private IMediaBuffer _buffer;
129
130         /// <summary>
131         /// Gets the buffer of the media source.
132         /// </summary>
133         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
134         /// <since_tizen> 3</since_tizen>
135         public IMediaBuffer Buffer
136         {
137             get
138             {
139                 if (_buffer == null)
140                 {
141                     IntPtr bufferHandle = IntPtr.Zero;
142                     int bufferSize = 0;
143
144                     InteropSource.GetBuffer(Handle, out bufferHandle, out bufferSize).
145                         Validate("Failed to get buffer");
146
147                     _buffer = new DependentMediaBuffer(this, bufferHandle, bufferSize);
148                 }
149                 return _buffer;
150             }
151         }
152
153         /// <summary>
154         /// Gets height of the media source.
155         /// </summary>
156         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
157         /// <since_tizen> 3</since_tizen>
158         public uint Height
159         {
160             get
161             {
162                 uint height = 0;
163                 var ret = InteropSource.GetHeight(Handle, out height);
164                 MultimediaDebug.AssertNoError(ret);
165                 return height;
166             }
167         }
168
169         /// <summary>
170         /// Gets width of the media source.
171         /// </summary>
172         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
173         /// <since_tizen> 3</since_tizen>
174         public uint Width
175         {
176             get
177             {
178                 uint width = 0;
179                 var ret = InteropSource.GetWidth(Handle, out width);
180                 MultimediaDebug.AssertNoError(ret);
181                 return width;
182             }
183         }
184
185         /// <summary>
186         /// Gets <see cref="Colorspace"/> of the media source.
187         /// </summary>
188         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
189         /// <since_tizen> 3</since_tizen>
190         public Colorspace Colorspace
191         {
192             get
193             {
194                 Colorspace colorspace = Colorspace.Invalid;
195                 var ret = InteropSource.GetColorspace(Handle, out colorspace);
196                 MultimediaDebug.AssertNoError(ret);
197                 return colorspace;
198             }
199         }
200
201         /// <summary>
202         /// Releases all resources used by the <see cref="MediaVisionSource"/> object.
203         /// </summary>
204         public void Dispose()
205         {
206             Dispose(true);
207             GC.SuppressFinalize(this);
208         }
209
210         /// <summary>
211         /// Releases the resources used by the <see cref="MediaVisionSource"/> object.
212         /// </summary>
213         /// <param name="disposing">
214         /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
215         /// </param>
216         protected virtual void Dispose(bool disposing)
217         {
218             if (_disposed)
219             {
220                 return;
221             }
222             InteropSource.Destroy(_handle);
223             _disposed = true;
224         }
225
226         internal IntPtr Handle
227         {
228             get
229             {
230                 if (_disposed)
231                 {
232                     throw new ObjectDisposedException(nameof(MediaVisionSource));
233                 }
234                 return _handle;
235             }
236         }
237
238         bool IBufferOwner.IsBufferAccessible(object buffer, MediaBufferAccessMode accessMode)
239         {
240             return true;
241         }
242
243         bool IBufferOwner.IsDisposed
244         {
245             get { return _disposed; }
246         }
247     }
248 }