Merge "Added CodecNotSupportedException." into tizen
[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     public class MediaVisionSource : IBufferOwner, IDisposable
27     {
28         private IntPtr _handle = IntPtr.Zero;
29         private bool _disposed = false;
30
31         internal MediaVisionSource()
32         {
33             InteropSource.Create(out _handle).Validate("Failed to create media vision source");
34         }
35
36         private MediaVisionSource(Action<IntPtr> fillAction)
37             : this()
38         {
39             try
40             {
41                 fillAction(_handle);
42             }
43             catch(Exception)
44             {
45                 InteropSource.Destroy(_handle);
46                 _disposed = true;
47                 throw;
48             }
49         }
50
51         private static void FillMediaPacket(IntPtr handle, MediaPacket mediaPacket)
52         {
53             Debug.Assert(handle != IntPtr.Zero);
54
55             if (mediaPacket == null)
56             {
57                 throw new ArgumentNullException(nameof(mediaPacket));
58             }
59
60             InteropSource.FillMediaPacket(handle, mediaPacket.GetHandle()).
61                 Validate("Failed to fill media packet");
62         }
63
64         /// <summary>
65         /// Initializes a new instance of the <see cref="MediaVisionSource"/> class based on the <see cref="MediaPacket"/>.
66         /// </summary>
67         /// <param name="mediaPacket">The <see cref="MediaPacket"/> from which the source will be filled.</param>
68         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
69         /// <exception cref="ArgumentNullException"><paramref name="mediaPacket"/> is null.</exception>
70         /// <exception cref="ObjectDisposedException"><paramref name="mediaPacket"/> has already been disposed of.</exception>
71         public MediaVisionSource(MediaPacket mediaPacket)
72             : this(handle => FillMediaPacket(handle, mediaPacket))
73         {
74         }
75
76         private static void FillBuffer(IntPtr handle, byte[] buffer, uint width, uint height, Colorspace colorspace)
77         {
78             Debug.Assert(handle != IntPtr.Zero);
79
80             if (buffer == null)
81             {
82                 throw new ArgumentNullException(nameof(buffer));
83             }
84
85             if (buffer.Length == 0)
86             {
87                 throw new ArgumentException("Buffer.Length is zero.", nameof(buffer));
88             }
89
90             if (colorspace == Colorspace.Invalid)
91             {
92                 throw new ArgumentException($"color space must not be {Colorspace.Invalid}.", nameof(colorspace));
93             }
94
95             ValidationUtil.ValidateEnum(typeof(Colorspace), colorspace, nameof(colorspace));
96
97             InteropSource.FillBuffer(handle, buffer, buffer.Length, width, height, colorspace).
98                 Validate("Failed to fill buffer");
99         }
100
101         /// <summary>
102         /// Initializes a new instance of the <see cref="MediaVisionSource"/> class based on the buffer and <see cref="Colorspace"/>.
103         /// </summary>
104         /// <param name="buffer">The buffer of image data.</param>
105         /// <param name="width">The width of image.</param>
106         /// <param name="height">The height of image.</param>
107         /// <param name="colorspace">The image <see cref="Colorspace"/>.</param>
108         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
109         /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
110         /// <exception cref="ArgumentException">
111         ///     <paramref name="buffer"/> has no element.(The length is zero.)\n
112         ///     -or-\n
113         ///     <paramref name="colorspace"/> is invalid.
114         /// </exception>
115         public MediaVisionSource(byte[] buffer, uint width, uint height, Colorspace colorspace)
116             : this(handle => FillBuffer(handle, buffer, width, height, colorspace))
117         {
118         }
119
120         ~MediaVisionSource()
121         {
122             Dispose(false);
123         }
124
125         private IMediaBuffer _buffer;
126
127         /// <summary>
128         /// Gets the buffer of the media source.
129         /// </summary>
130         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
131         public IMediaBuffer Buffer
132         {
133             get
134             {
135                 if (_buffer == null)
136                 {
137                     IntPtr bufferHandle = IntPtr.Zero;
138                     int bufferSize = 0;
139
140                     InteropSource.GetBuffer(Handle, out bufferHandle, out bufferSize).
141                         Validate("Failed to get buffer");
142
143                     _buffer = new DependentMediaBuffer(this, bufferHandle, bufferSize);
144                 }
145                 return _buffer;
146             }
147         }
148
149         /// <summary>
150         /// Gets height of the media source.
151         /// </summary>
152         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
153         public uint Height
154         {
155             get
156             {
157                 uint height = 0;
158                 var ret = InteropSource.GetHeight(Handle, out height);
159                 MultimediaDebug.AssertNoError(ret);
160                 return height;
161             }
162         }
163
164         /// <summary>
165         /// Gets width of the media source.
166         /// </summary>
167         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
168         public uint Width
169         {
170             get
171             {
172                 uint width = 0;
173                 var ret = InteropSource.GetWidth(Handle, out width);
174                 MultimediaDebug.AssertNoError(ret);
175                 return width;
176             }
177         }
178
179         /// <summary>
180         /// Gets <see cref="Colorspace"/> of the media source.
181         /// </summary>
182         /// <exception cref="ObjectDisposedException">The <see cref="MediaVisionSource"/> has already been disposed of.</exception>
183         public Colorspace Colorspace
184         {
185             get
186             {
187                 Colorspace colorspace = Colorspace.Invalid;
188                 var ret = InteropSource.GetColorspace(Handle, out colorspace);
189                 MultimediaDebug.AssertNoError(ret);
190                 return colorspace;
191             }
192         }
193
194         public void Dispose()
195         {
196             Dispose(true);
197             GC.SuppressFinalize(this);
198         }
199
200         protected virtual void Dispose(bool disposing)
201         {
202             if (_disposed)
203             {
204                 return;
205             }
206             InteropSource.Destroy(_handle);
207             _disposed = true;
208         }
209
210         internal IntPtr Handle
211         {
212             get
213             {
214                 if (_disposed)
215                 {
216                     throw new ObjectDisposedException(nameof(MediaVisionSource));
217                 }
218                 return _handle;
219             }
220         }
221
222         bool IBufferOwner.IsBufferAccessible(object buffer, MediaBufferAccessMode accessMode)
223         {
224             return true;
225         }
226
227         bool IBufferOwner.IsDisposed
228         {
229             get { return _disposed; }
230         }
231     }
232 }