Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia / MediaTool / MediaFormat.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 using System;
17 using System.Diagnostics;
18 using Tizen.Internals.Errors;
19
20 namespace Tizen.Multimedia
21 {
22     /// <summary>
23     /// MediaFormat is a base class for media formats.
24     /// </summary>
25     public abstract class MediaFormat
26     {
27         /// <summary>
28         /// Initializes a new instance of the ContainerMediaFormat class with a type.
29         /// </summary>
30         /// <param name="type">A type for the format.</param>
31         internal MediaFormat(MediaFormatType type)
32         {
33             Type = type;
34         }
35
36         /// <summary>
37         /// Gets the type of the current format.
38         /// </summary>
39         public MediaFormatType Type
40         {
41             get;
42         }
43
44         /// <summary>
45         /// Creates a media format from a native handle.
46         /// </summary>
47         /// <param name="handle">A native handle.</param>
48         /// <returns>An object of one of subclasses of <see cref="MediaFormat"/>.</returns>
49         internal static MediaFormat FromHandle(IntPtr handle)
50         {
51             if (handle == IntPtr.Zero)
52             {
53                 throw new ArgumentException("The handle value is invalid.");
54             }
55
56             int type = 0;
57             int ret = Interop.MediaFormat.GetType(handle, out type);
58
59             if (ret != (int)ErrorCode.InvalidOperation)
60             {
61                 MultimediaDebug.AssertNoError(ret);
62
63                 switch ((MediaFormatType)type)
64                 {
65                     case MediaFormatType.Container:
66                         return new ContainerMediaFormat(handle);
67
68                     case MediaFormatType.Video:
69                         return new VideoMediaFormat(handle);
70
71                     case MediaFormatType.Audio:
72                         return new AudioMediaFormat(handle);
73
74                     case MediaFormatType.Text:
75                         return new TextMediaFormat(handle);
76                 }
77             }
78
79             throw new ArgumentException("looks like handle is corrupted.");
80         }
81
82         /// <summary>
83         /// Create a native media format from this object.
84         /// </summary>
85         /// <returns>A converted native handle.</returns>
86         /// <remarks>The returned handle must be destroyed using <see cref="Interop.MediaFormat.Unref(IntPtr)"/>.</remarks>
87         internal IntPtr AsNativeHandle()
88         {
89             IntPtr handle;
90             int ret = Interop.MediaFormat.Create(out handle);
91
92             MultimediaDebug.AssertNoError(ret);
93
94             AsNativeHandle(handle);
95
96             return handle;
97         }
98
99         internal static void ReleaseNativeHandle(IntPtr handle)
100         {
101             Interop.MediaFormat.Unref(handle);
102         }
103
104         /// <summary>
105         /// Fill out properties of a native media format with the current media format object.
106         /// </summary>
107         /// <param name="handle">A native handle to be written.</param>
108         internal abstract void AsNativeHandle(IntPtr handle);
109     }
110
111     /// <summary>
112     /// Represents a container media format. This class cannot be inherited.
113     /// </summary>
114     public sealed class ContainerMediaFormat : MediaFormat
115     {
116         /// <summary>
117         /// Initializes a new instance of the ContainerMediaFormat class.
118         /// </summary>
119         /// <param name="mimeType">The mime type of the container format.</param>
120         /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
121         public ContainerMediaFormat(MediaFormatContainerMimeType mimeType)
122             : base(MediaFormatType.Container)
123         {
124             if (!Enum.IsDefined(typeof(MediaFormatContainerMimeType), mimeType))
125             {
126                 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
127             }
128             MimeType = mimeType;
129         }
130
131         /// <summary>
132         /// Initializes a new instance of the ContainerMediaFormat class from a native handle.
133         /// </summary>
134         /// <param name="handle">A native media format handle.</param>
135         internal ContainerMediaFormat(IntPtr handle)
136             : base(MediaFormatType.Container)
137         {
138             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
139
140             int mimeType = 0;
141
142             int ret = Interop.MediaFormat.GetContainerMimeType(handle, out mimeType);
143
144             MultimediaDebug.AssertNoError(ret);
145
146             Debug.Assert(Enum.IsDefined(typeof(MediaFormatContainerMimeType), mimeType),
147                 "Invalid container mime type!");
148
149             MimeType = (MediaFormatContainerMimeType)mimeType;
150         }
151
152         /// <summary>
153         /// Gets the mime type of the current format.
154         /// </summary>
155         public MediaFormatContainerMimeType MimeType
156         {
157             get;
158         }
159
160         internal override void AsNativeHandle(IntPtr handle)
161         {
162             Debug.Assert(Type == MediaFormatType.Container);
163
164             int ret = Interop.MediaFormat.SetContainerMimeType(handle, (int)MimeType);
165
166             MultimediaDebug.AssertNoError(ret);
167         }
168
169         public override string ToString()
170         {
171             return $"MimeType={ MimeType.ToString() }";
172         }
173
174         public override bool Equals(object obj)
175         {
176             var rhs = obj as ContainerMediaFormat;
177             if (rhs == null)
178             {
179                 return false;
180             }
181
182             return MimeType == rhs.MimeType;
183         }
184
185         public override int GetHashCode()
186         {
187             return (int)MimeType;
188         }
189     }
190
191     /// <summary>
192     /// Represents a video media format. This class cannot be inherited.
193     /// </summary>
194     public sealed class VideoMediaFormat : MediaFormat
195     {
196         private const int DefaultFrameRate = 0;
197         private const int DefaultBitRate = 0;
198
199         /// <summary>
200         /// Initializes a new instance of the VideoMediaFormat class with the specified mime type, width and height.
201         /// </summary>
202         /// <param name="mimeType">The mime type of the format.</param>
203         /// <param name="width">The width value of the format.</param>
204         /// <param name="height">The height value of the format</param>
205         /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
206         /// <exception cref="ArgumentOutOfRangeException">width, or height is less than zero.</exception>
207         public VideoMediaFormat(MediaFormatVideoMimeType mimeType, int width, int height)
208             : this(mimeType, width, height, DefaultFrameRate)
209         {
210         }
211
212         /// <summary>
213         /// Initializes a new instance of the VideoMediaFormat class with the specified mime type and size.
214         /// </summary>
215         /// <param name="mimeType">The mime type of the format.</param>
216         /// <param name="size">The size of the format.</param>
217         /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
218         /// <exception cref="ArgumentOutOfRangeException">width, or height is less than zero.</exception>
219         public VideoMediaFormat(MediaFormatVideoMimeType mimeType, Size size)
220             : this(mimeType, size, DefaultFrameRate)
221         {
222         }
223
224         /// <summary>
225         /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
226         /// width, height and frame rate.
227         /// </summary>
228         /// <param name="mimeType">The mime type of the format.</param>
229         /// <param name="width">The width value of the format.</param>
230         /// <param name="height">The height value of the format</param>
231         /// <param name="frameRate">The frame rate of the format.</param>
232         /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
233         /// <exception cref="ArgumentOutOfRangeException">width, height or frameRate is less than zero.</exception>
234         public VideoMediaFormat(MediaFormatVideoMimeType mimeType, int width, int height,
235             int frameRate)
236             : this(mimeType, width, height, frameRate, DefaultBitRate)
237         {
238         }
239
240         /// <summary>
241         /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
242         /// width, height and frame rate.
243         /// </summary>
244         /// <param name="mimeType">The mime type of the format.</param>
245         /// <param name="size">The video size of the format.</param>
246         /// <param name="frameRate">The frame rate of the format.</param>
247         /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
248         /// <exception cref="ArgumentOutOfRangeException">width, height or frameRate is less than zero.</exception>
249         public VideoMediaFormat(MediaFormatVideoMimeType mimeType, Size size,
250             int frameRate)
251             : this(mimeType, size, frameRate, DefaultBitRate)
252         {
253         }
254
255         /// <summary>
256         /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
257         /// width, height, frame rate and bit rate.
258         /// </summary>
259         /// <param name="mimeType">The mime type of the format.</param>
260         /// <param name="width">The width value of the format.</param>
261         /// <param name="height">The height value of the format</param>
262         /// <param name="frameRate">The frame rate of the format.</param>
263         /// <param name="bitRate">The bit rate of the format.</param>
264         /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
265         /// <exception cref="ArgumentOutOfRangeException">width, height, frameRate or bitRate is less than zero.</exception>
266         public VideoMediaFormat(MediaFormatVideoMimeType mimeType, int width, int height,
267             int frameRate, int bitRate)
268             : this(mimeType, new Size(width, height), frameRate, bitRate)
269         {
270         }
271
272         /// <summary>
273         /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
274         /// size, frame rate and bit rate.
275         /// </summary>
276         /// <param name="mimeType">The mime type of the format.</param>
277         /// <param name="size">The size of the format.</param>
278         /// <param name="frameRate">The frame rate of the format.</param>
279         /// <param name="bitRate">The bit rate of the format.</param>
280         /// <exception cref="ArgumentException">mimeType is invalid(i.e. undefined value).</exception>
281         /// <exception cref="ArgumentOutOfRangeException">width, height, frameRate or bitRate is less than zero.</exception>
282         public VideoMediaFormat(MediaFormatVideoMimeType mimeType, Size size,
283             int frameRate, int bitRate)
284             : base(MediaFormatType.Video)
285         {
286             if (!Enum.IsDefined(typeof(MediaFormatVideoMimeType), mimeType))
287             {
288                 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
289             }
290             if (size.Width < 0)
291             {
292                 throw new ArgumentOutOfRangeException(nameof(size), size.Width, "Size.Width value can't be less than zero.");
293             }
294             if (size.Height < 0)
295             {
296                 throw new ArgumentOutOfRangeException(nameof(size), size.Height, "Size.Height value can't be less than zero.");
297             }
298             if (frameRate < 0)
299             {
300                 throw new ArgumentOutOfRangeException(nameof(frameRate), frameRate, "Frame rate can't be less than zero.");
301             }
302             if (bitRate < 0)
303             {
304                 throw new ArgumentOutOfRangeException(nameof(bitRate), bitRate, "Bit rate value can't be less than zero.");
305             }
306
307             MimeType = mimeType;
308             Size = size;
309             FrameRate = frameRate;
310             BitRate = bitRate;
311         }
312
313         /// <summary>
314         /// Initializes a new instance of the VideoMediaForma class from a native handle.
315         /// </summary>
316         /// <param name="handle">A native handle.</param>
317         internal VideoMediaFormat(IntPtr handle)
318             : base(MediaFormatType.Video)
319         {
320             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
321
322             int width = 0;
323             int height = 0;
324             int bitRate = 0;
325             int frameRate = 0;
326             MediaFormatVideoMimeType mimeType;
327             GetInfo(handle, out width, out height, out bitRate, out mimeType);
328
329             GetFrameRate(handle, out frameRate);
330
331             MimeType = mimeType;
332             Size = new Size(width, height);
333             FrameRate = frameRate;
334             BitRate = bitRate;
335         }
336
337         /// <summary>
338         /// Retrieves video properties of media format from a native handle.
339         /// </summary>
340         /// <param name="handle">A native handle that properties are retrieved from.</param>
341         /// <param name="width">An out parameter for width.</param>
342         /// <param name="height">An out parameter for height.</param>
343         /// <param name="bitRate">An out parameter for bit rate.</param>
344         /// <param name="mimeType">An out parameter for mime type.</param>
345         private static void GetInfo(IntPtr handle, out int width, out int height, out int bitRate,
346             out MediaFormatVideoMimeType mimeType)
347         {
348             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
349
350             int mimeTypeValue = 0;
351             int maxBps = 0;
352
353             int ret = Interop.MediaFormat.GetVideoInfo(handle,
354                 out mimeTypeValue, out width, out height, out bitRate, out maxBps);
355
356             MultimediaDebug.AssertNoError(ret);
357
358             mimeType = (MediaFormatVideoMimeType)mimeTypeValue;
359
360             Debug.Assert(Enum.IsDefined(typeof(MediaFormatVideoMimeType), mimeType),
361                 "Invalid video mime type!");
362         }
363
364         /// <summary>
365         /// Retrieves frame rate from a native handle.
366         /// </summary>
367         /// <param name="handle">A native handle that properties are retrieved from.</param>
368         /// <param name="frameRate">An out parameter for frame rate.</param>
369         private static void GetFrameRate(IntPtr handle, out int frameRate)
370         {
371             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
372
373             int ret = Interop.MediaFormat.GetVideoFrameRate(handle, out frameRate);
374
375             MultimediaDebug.AssertNoError(ret);
376         }
377
378         internal override void AsNativeHandle(IntPtr handle)
379         {
380             Debug.Assert(Type == MediaFormatType.Video);
381
382             int ret = Interop.MediaFormat.SetVideoMimeType(handle, (int)MimeType);
383             MultimediaDebug.AssertNoError(ret);
384
385             ret = Interop.MediaFormat.SetVideoWidth(handle, Size.Width);
386             MultimediaDebug.AssertNoError(ret);
387
388             ret = Interop.MediaFormat.SetVideoHeight(handle, Size.Height);
389             MultimediaDebug.AssertNoError(ret);
390
391             ret = Interop.MediaFormat.SetVideoAverageBps(handle, BitRate);
392             MultimediaDebug.AssertNoError(ret);
393
394             ret = Interop.MediaFormat.SetVideoFrameRate(handle, FrameRate);
395             MultimediaDebug.AssertNoError(ret);
396         }
397
398         /// <summary>
399         /// Gets the mime type of the current format.
400         /// </summary>
401         public MediaFormatVideoMimeType MimeType { get; }
402
403         /// <summary>
404         /// Gets the size of the current format.
405         /// </summary>
406         public Size Size { get; }
407
408         /// <summary>
409         /// Gets the frame rate value of the current format.
410         /// </summary>
411         public int FrameRate { get; }
412
413         /// <summary>
414         /// Gets the bit rate value of the current format.
415         /// </summary>
416         public int BitRate { get; }
417
418         public override string ToString()
419         {
420             return $@"MimeType={ MimeType.ToString() }, Size=({ Size.ToString() }), FrameRate=
421                 { FrameRate.ToString() }, BitRate={ BitRate.ToString() }";
422         }
423
424         public override bool Equals(object obj)
425         {
426             var rhs = obj as VideoMediaFormat;
427             if (rhs == null)
428             {
429                 return false;
430             }
431
432             return MimeType == rhs.MimeType && Size == rhs.Size &&
433                 FrameRate == rhs.FrameRate && BitRate == rhs.BitRate;
434         }
435
436         public override int GetHashCode()
437         {
438             return new { MimeType, Size, FrameRate, BitRate }.GetHashCode();
439         }
440     }
441
442     /// <summary>
443     /// Represents an audio media format. This class cannot be inherited.
444     /// </summary>
445     public sealed class AudioMediaFormat : MediaFormat
446     {
447
448         /// <summary>
449         /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
450         ///     channel, sample rate, bit and bit rate.
451         /// </summary>
452         /// <param name="mimeType">The mime type of the format.</param>
453         /// <param name="channel">The channel value of the format.</param>
454         /// <param name="sampleRate">The sample rate value of the format.</param>
455         /// <param name="bit">The bit value of the format.</param>
456         /// <param name="bitRate">The bit rate value of the format.</param>
457         /// <exception cref="ArgumentException"><paramref name="mimeType"/> is invalid(i.e. undefined value).</exception>
458         /// <exception cref="ArgumentOutOfRangeException">
459         ///     <paramref name="channel"/>, <paramref name="sampleRate"/>, <paramref name="bit"/> or <paramref name="bitRate"/> is less than zero.
460         /// </exception>
461         public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
462             int channel, int sampleRate, int bit, int bitRate)
463         : this(mimeType, channel, sampleRate, bit, bitRate, MediaFormatAacType.None)
464         {
465         }
466
467         /// <summary>
468         /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
469         ///     channel, sample rate, bit, bit rate and aac type.
470         /// </summary>
471         /// <param name="mimeType">The mime type of the format.</param>
472         /// <param name="channel">The channel value of the format.</param>
473         /// <param name="sampleRate">The sample rate value of the format.</param>
474         /// <param name="bit">The bit value of the format.</param>
475         /// <param name="bitRate">The bit rate value of the format.</param>
476         /// <param name="aacType">The AAC bitstream format(ADIF or ADTS).</param>
477         /// <exception cref="ArgumentException">
478         ///     <paramref name="mimeType"/> or <paramref name="aacType"/> is invalid(i.e. undefined value).\n
479         ///     -or-\n
480         ///     <paramref name="aacType"/> is not <see cref="MediaFormatAacType.None"/>, but <paramref name="mimeType"/> is one of aac types.
481         ///     </exception>
482         /// <exception cref="ArgumentOutOfRangeException">
483         ///     <paramref name="channel"/>, <paramref name="sampleRate"/>, <paramref name="bit"/> or <paramref name="bitRate"/> is less than zero.
484         /// </exception>
485         public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
486             int channel, int sampleRate, int bit, int bitRate, MediaFormatAacType aacType)
487             : base(MediaFormatType.Audio)
488         {
489             if (!Enum.IsDefined(typeof(MediaFormatAudioMimeType), mimeType))
490             {
491                 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
492             }
493             if (channel < 0)
494             {
495                 throw new ArgumentOutOfRangeException("Channel value can't be negative.");
496             }
497             if (sampleRate < 0)
498             {
499                 throw new ArgumentOutOfRangeException("Sample rate value can't be negative.");
500             }
501             if (bit < 0)
502             {
503                 throw new ArgumentOutOfRangeException("Bit value can't be negative.");
504             }
505             if (bitRate < 0)
506             {
507                 throw new ArgumentOutOfRangeException("Bit rate value can't be negative.");
508             }
509             if (!Enum.IsDefined(typeof(MediaFormatAacType), aacType))
510             {
511                 throw new ArgumentException($"Invalid aac type value : { (int)aacType }");
512             }
513             if (!IsAacSupportedMimeType(mimeType) && aacType != MediaFormatAacType.None)
514             {
515                 throw new ArgumentException("Aac is supported only with aac mime types.");
516             }
517
518             MimeType = mimeType;
519             Channel = channel;
520             SampleRate = sampleRate;
521             Bit = bit;
522             BitRate = bitRate;
523             AacType = aacType;
524         }
525
526         /// <summary>
527         /// Initializes a new instance of the AudioMediaFormat class from a native handle.
528         /// </summary>
529         /// <param name="handle">A native handle.</param>
530         internal AudioMediaFormat(IntPtr handle)
531             : base(MediaFormatType.Audio)
532         {
533             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
534
535             MediaFormatAudioMimeType mimeType;
536             int channel = 0;
537             int sampleRate = 0;
538             int bit = 0;
539             int bitRate = 0;
540             MediaFormatAacType aacType;
541             GetInfo(handle, out mimeType, out channel, out sampleRate, out bit, out bitRate);
542
543             if (IsAacSupportedMimeType(mimeType))
544             {
545                 GetAacType(handle, out aacType);
546             }
547             else
548             {
549                 aacType = MediaFormatAacType.None;
550             }
551
552             MimeType = mimeType;
553             Channel = channel;
554             SampleRate = sampleRate;
555             Bit = bit;
556             BitRate = bitRate;
557             AacType = aacType;
558         }
559
560         /// <summary>
561         /// Returns an indication whether a specified mime type is a aac type.
562         /// </summary>
563         /// <param name="mimeType">A mime type.</param>
564         private static bool IsAacSupportedMimeType(MediaFormatAudioMimeType mimeType)
565         {
566             return mimeType == MediaFormatAudioMimeType.AacLC ||
567                 mimeType == MediaFormatAudioMimeType.AacHE ||
568                 mimeType == MediaFormatAudioMimeType.AacHEPS;
569         }
570
571         /// <summary>
572         /// Retrieves audio properties of media format from a native handle.
573         /// </summary>
574         /// <param name="handle">A native handle that properties are retrieved from.</param>
575         /// <param name="mimeType">An out parameter for mime type.</param>
576         /// <param name="channel">An out parameter for channel.</param>
577         /// <param name="sampleRate">An out parameter for sample rate.</param>
578         /// <param name="bit">An out parameter for bit.</param>
579         /// <param name="bitRate">An out parameter for bit rate.</param>
580         private static void GetInfo(IntPtr handle, out MediaFormatAudioMimeType mimeType,
581             out int channel, out int sampleRate, out int bit, out int bitRate)
582         {
583             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
584
585             int mimeTypeValue = 0;
586
587             int ret = Interop.MediaFormat.GetAudioInfo(handle,
588                 out mimeTypeValue, out channel, out sampleRate, out bit, out bitRate);
589
590             mimeType = (MediaFormatAudioMimeType)mimeTypeValue;
591
592             MultimediaDebug.AssertNoError(ret);
593
594             Debug.Assert(Enum.IsDefined(typeof(MediaFormatAudioMimeType), mimeType),
595                 "Invalid audio mime type!");
596         }
597
598         /// <summary>
599         /// Retrieves aac type value from a native handle.
600         /// </summary>
601         /// <param name="handle">A native handle that properties are retrieved from.</param>
602         /// <param name="aacType">An out parameter for aac type.</param>
603         private static void GetAacType(IntPtr handle, out MediaFormatAacType aacType)
604         {
605             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
606
607             int aacTypeValue = 0;
608
609             int ret = Interop.MediaFormat.GetAudioAacType(handle, out aacTypeValue);
610
611             MultimediaDebug.AssertNoError(ret);
612
613             aacType = (MediaFormatAacType)aacTypeValue;
614
615             Debug.Assert(Enum.IsDefined(typeof(MediaFormatAacType), aacType), "Invalid aac type!");
616         }
617
618         internal override void AsNativeHandle(IntPtr handle)
619         {
620             Debug.Assert(Type == MediaFormatType.Audio);
621
622             int ret = Interop.MediaFormat.SetAudioMimeType(handle, (int)MimeType);
623             MultimediaDebug.AssertNoError(ret);
624
625             ret = Interop.MediaFormat.SetAudioChannel(handle, Channel);
626             MultimediaDebug.AssertNoError(ret);
627
628             ret = Interop.MediaFormat.SetAudioSampleRate(handle, SampleRate);
629             MultimediaDebug.AssertNoError(ret);
630
631             ret = Interop.MediaFormat.SetAudioBit(handle, Bit);
632             MultimediaDebug.AssertNoError(ret);
633
634             ret = Interop.MediaFormat.SetAudioAverageBps(handle, BitRate);
635             MultimediaDebug.AssertNoError(ret);
636
637             ret = Interop.MediaFormat.SetAudioAacType(handle, (int)AacType);
638             MultimediaDebug.AssertNoError(ret);
639         }
640
641         /// <summary>
642         /// Gets the mime type of the current format.
643         /// </summary>
644         public MediaFormatAudioMimeType MimeType { get; }
645
646         /// <summary>
647         /// Gets the channel value of the current format.
648         /// </summary>
649         public int Channel { get; }
650
651         /// <summary>
652         /// Gets the sample rate value of the current format.
653         /// </summary>
654         public int SampleRate { get; }
655
656         /// <summary>
657         /// Gets the bit value of the current format.
658         /// </summary>
659         public int Bit { get; }
660
661         /// <summary>
662         /// Gets the bit rate value of the current format.
663         /// </summary>
664         public int BitRate { get; }
665
666         /// <summary>
667         /// Gets the aac type of the current format.
668         /// </summary>
669         public MediaFormatAacType AacType { get; }
670
671         public override string ToString()
672         {
673             return $@"MimeTyp={ MimeType.ToString() }, Channel={ Channel.ToString() }, SampleRate=
674                 { SampleRate }, Bit={ Bit.ToString() }, BitRate={ BitRate.ToString() }, AacType={ AacType.ToString() }";
675         }
676
677         public override bool Equals(object obj)
678         {
679             var rhs = obj as AudioMediaFormat;
680             if (rhs == null)
681             {
682                 return false;
683             }
684
685             return MimeType == rhs.MimeType && Channel == rhs.Channel && SampleRate == rhs.SampleRate &&
686                 Bit == rhs.Bit && BitRate == rhs.BitRate;
687         }
688
689         public override int GetHashCode()
690         {
691             return new { MimeType, Channel, SampleRate, Bit, BitRate }.GetHashCode();
692         }
693     }
694
695     /// <summary>
696     /// Represents a text media format. This class cannot be inherited.
697     /// </summary>
698     public sealed class TextMediaFormat : MediaFormat
699     {
700         /// <summary>
701         /// Initializes a new instance of the TextMediaFormat class with the specified mime type
702         ///     and text type.
703         /// </summary>
704         /// <param name="mimeType">The mime type of the format.</param>
705         /// <param name="textType">The text type of the format.</param>
706         /// <exception cref="ArgumentException">
707         ///                     mimeType or textType is invalid(i.e. undefined value).</exception>
708         public TextMediaFormat(MediaFormatTextMimeType mimeType, MediaFormatTextType textType)
709             : base(MediaFormatType.Text)
710         {
711             if (!Enum.IsDefined(typeof(MediaFormatTextMimeType), mimeType))
712             {
713                 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
714             }
715             if (!Enum.IsDefined(typeof(MediaFormatTextType), textType))
716             {
717                 throw new ArgumentException($"Invalid text type value : { (int)textType }");
718             }
719             MimeType = mimeType;
720             TextType = textType;
721         }
722
723         /// <summary>
724         /// Initializes a new instance of the TextMediaFormat class from a native handle.
725         /// </summary>
726         /// <param name="handle">A native handle.</param>
727         internal TextMediaFormat(IntPtr handle)
728             : base(MediaFormatType.Text)
729         {
730             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
731
732             MediaFormatTextMimeType mimeType;
733             MediaFormatTextType textType;
734
735             GetInfo(handle, out mimeType, out textType);
736
737             MimeType = mimeType;
738             TextType = textType;
739         }
740
741         /// <summary>
742         /// Retrieves text properties of media format from a native handle.
743         /// </summary>
744         /// <param name="handle">A native handle that properties are retrieved from.</param>
745         /// <param name="mimeType">An out parameter for mime type.</param>
746         /// <param name="textType">An out parameter for text type.</param>
747         private static void GetInfo(IntPtr handle, out MediaFormatTextMimeType mimeType,
748             out MediaFormatTextType textType)
749         {
750             int mimeTypeValue = 0;
751             int textTypeValue = 0;
752
753             int ret = Interop.MediaFormat.GetTextInfo(handle, out mimeTypeValue, out textTypeValue);
754
755             MultimediaDebug.AssertNoError(ret);
756
757             mimeType = (MediaFormatTextMimeType)mimeTypeValue;
758             textType = (MediaFormatTextType)textTypeValue;
759
760             Debug.Assert(Enum.IsDefined(typeof(MediaFormatTextMimeType), mimeType),
761                 "Invalid text mime type!");
762             Debug.Assert(Enum.IsDefined(typeof(MediaFormatTextType), textType),
763                 "Invalid text type!");
764         }
765
766         internal override void AsNativeHandle(IntPtr handle)
767         {
768             Debug.Assert(Type == MediaFormatType.Text);
769
770             int ret = Interop.MediaFormat.SetTextMimeType(handle, (int)MimeType);
771             MultimediaDebug.AssertNoError(ret);
772
773             ret = Interop.MediaFormat.SetTextType(handle, (int)TextType);
774             MultimediaDebug.AssertNoError(ret);
775         }
776
777         /// <summary>
778         /// Gets the mime type of the current format.
779         /// </summary>
780         public MediaFormatTextMimeType MimeType { get; }
781
782         /// <summary>
783         /// Gets the text type of the current format.
784         /// </summary>
785         public MediaFormatTextType TextType { get; }
786
787         public override string ToString()
788         {
789             return $"MimeType={ MimeType.ToString() }, TextType={ TextType.ToString() }";
790         }
791
792         public override bool Equals(object obj)
793         {
794             var rhs = obj as TextMediaFormat;
795             if (rhs == null)
796             {
797                 return false;
798             }
799
800             return MimeType == rhs.MimeType && TextType == rhs.TextType;
801         }
802
803         public override int GetHashCode()
804         {
805             return new { MimeType, TextType }.GetHashCode();
806         }
807     }
808 }