2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 using System.Diagnostics;
18 using Tizen.Internals.Errors;
20 namespace Tizen.Multimedia
23 /// MediaFormat is a base class for media formats.
25 public abstract class MediaFormat
28 /// Initializes a new instance of the ContainerMediaFormat class with a type.
30 /// <param name="type">A type for the format.</param>
31 internal MediaFormat(MediaFormatType type)
37 /// Gets the type of the current format.
39 public MediaFormatType Type
45 /// Creates a media format from a native handle.
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)
51 if (handle == IntPtr.Zero)
53 throw new ArgumentException("The handle value is invalid.");
57 int ret = Interop.MediaFormat.GetType(handle, out type);
59 if (ret != (int)ErrorCode.InvalidOperation)
61 MultimediaDebug.AssertNoError(ret);
63 switch ((MediaFormatType)type)
65 case MediaFormatType.Container:
66 return new ContainerMediaFormat(handle);
68 case MediaFormatType.Video:
69 return new VideoMediaFormat(handle);
71 case MediaFormatType.Audio:
72 return new AudioMediaFormat(handle);
74 case MediaFormatType.Text:
75 return new TextMediaFormat(handle);
79 throw new ArgumentException("looks like handle is corrupted.");
83 /// Create a native media format from this object.
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()
90 int ret = Interop.MediaFormat.Create(out handle);
92 MultimediaDebug.AssertNoError(ret);
94 AsNativeHandle(handle);
99 internal static void ReleaseNativeHandle(IntPtr handle)
101 Interop.MediaFormat.Unref(handle);
105 /// Fill out properties of a native media format with the current media format object.
107 /// <param name="handle">A native handle to be written.</param>
108 internal abstract void AsNativeHandle(IntPtr handle);
112 /// Represents a container media format. This class cannot be inherited.
114 public sealed class ContainerMediaFormat : MediaFormat
117 /// Initializes a new instance of the ContainerMediaFormat class.
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)
124 if (!Enum.IsDefined(typeof(MediaFormatContainerMimeType), mimeType))
126 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
132 /// Initializes a new instance of the ContainerMediaFormat class from a native handle.
134 /// <param name="handle">A native media format handle.</param>
135 internal ContainerMediaFormat(IntPtr handle)
136 : base(MediaFormatType.Container)
138 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
142 int ret = Interop.MediaFormat.GetContainerMimeType(handle, out mimeType);
144 MultimediaDebug.AssertNoError(ret);
146 Debug.Assert(Enum.IsDefined(typeof(MediaFormatContainerMimeType), mimeType),
147 "Invalid container mime type!");
149 MimeType = (MediaFormatContainerMimeType)mimeType;
153 /// Gets the mime type of the current format.
155 public MediaFormatContainerMimeType MimeType
160 internal override void AsNativeHandle(IntPtr handle)
162 Debug.Assert(Type == MediaFormatType.Container);
164 int ret = Interop.MediaFormat.SetContainerMimeType(handle, (int)MimeType);
166 MultimediaDebug.AssertNoError(ret);
169 public override string ToString()
171 return $"MimeType={ MimeType.ToString() }";
174 public override bool Equals(object obj)
176 var rhs = obj as ContainerMediaFormat;
182 return MimeType == rhs.MimeType;
185 public override int GetHashCode()
187 return (int)MimeType;
192 /// Represents a video media format. This class cannot be inherited.
194 public sealed class VideoMediaFormat : MediaFormat
196 private const int DefaultFrameRate = 0;
197 private const int DefaultBitRate = 0;
200 /// Initializes a new instance of the VideoMediaFormat class with the specified mime type, width and height.
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)
213 /// Initializes a new instance of the VideoMediaFormat class with the specified mime type and size.
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)
225 /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
226 /// width, height and frame rate.
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,
236 : this(mimeType, width, height, frameRate, DefaultBitRate)
241 /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
242 /// width, height and frame rate.
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,
251 : this(mimeType, size, frameRate, DefaultBitRate)
256 /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
257 /// width, height, frame rate and bit rate.
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)
273 /// Initializes a new instance of the VideoMediaFormat class with the specified mime type,
274 /// size, frame rate and bit rate.
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)
286 if (!Enum.IsDefined(typeof(MediaFormatVideoMimeType), mimeType))
288 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
292 throw new ArgumentOutOfRangeException(nameof(size), size.Width, "Size.Width value can't be less than zero.");
296 throw new ArgumentOutOfRangeException(nameof(size), size.Height, "Size.Height value can't be less than zero.");
300 throw new ArgumentOutOfRangeException(nameof(frameRate), frameRate, "Frame rate can't be less than zero.");
304 throw new ArgumentOutOfRangeException(nameof(bitRate), bitRate, "Bit rate value can't be less than zero.");
309 FrameRate = frameRate;
314 /// Initializes a new instance of the VideoMediaForma class from a native handle.
316 /// <param name="handle">A native handle.</param>
317 internal VideoMediaFormat(IntPtr handle)
318 : base(MediaFormatType.Video)
320 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
326 MediaFormatVideoMimeType mimeType;
327 GetInfo(handle, out width, out height, out bitRate, out mimeType);
329 GetFrameRate(handle, out frameRate);
332 Size = new Size(width, height);
333 FrameRate = frameRate;
338 /// Retrieves video properties of media format from a native handle.
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)
348 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
350 int mimeTypeValue = 0;
353 int ret = Interop.MediaFormat.GetVideoInfo(handle,
354 out mimeTypeValue, out width, out height, out bitRate, out maxBps);
356 MultimediaDebug.AssertNoError(ret);
358 mimeType = (MediaFormatVideoMimeType)mimeTypeValue;
360 Debug.Assert(Enum.IsDefined(typeof(MediaFormatVideoMimeType), mimeType),
361 "Invalid video mime type!");
365 /// Retrieves frame rate from a native handle.
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)
371 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
373 int ret = Interop.MediaFormat.GetVideoFrameRate(handle, out frameRate);
375 MultimediaDebug.AssertNoError(ret);
378 internal override void AsNativeHandle(IntPtr handle)
380 Debug.Assert(Type == MediaFormatType.Video);
382 int ret = Interop.MediaFormat.SetVideoMimeType(handle, (int)MimeType);
383 MultimediaDebug.AssertNoError(ret);
385 ret = Interop.MediaFormat.SetVideoWidth(handle, Size.Width);
386 MultimediaDebug.AssertNoError(ret);
388 ret = Interop.MediaFormat.SetVideoHeight(handle, Size.Height);
389 MultimediaDebug.AssertNoError(ret);
391 ret = Interop.MediaFormat.SetVideoAverageBps(handle, BitRate);
392 MultimediaDebug.AssertNoError(ret);
394 ret = Interop.MediaFormat.SetVideoFrameRate(handle, FrameRate);
395 MultimediaDebug.AssertNoError(ret);
399 /// Gets the mime type of the current format.
401 public MediaFormatVideoMimeType MimeType { get; }
404 /// Gets the size of the current format.
406 public Size Size { get; }
409 /// Gets the frame rate value of the current format.
411 public int FrameRate { get; }
414 /// Gets the bit rate value of the current format.
416 public int BitRate { get; }
418 public override string ToString()
420 return $@"MimeType={ MimeType.ToString() }, Size=({ Size.ToString() }), FrameRate=
421 { FrameRate.ToString() }, BitRate={ BitRate.ToString() }";
424 public override bool Equals(object obj)
426 var rhs = obj as VideoMediaFormat;
432 return MimeType == rhs.MimeType && Size == rhs.Size &&
433 FrameRate == rhs.FrameRate && BitRate == rhs.BitRate;
436 public override int GetHashCode()
438 return new { MimeType, Size, FrameRate, BitRate }.GetHashCode();
443 /// Represents an audio media format. This class cannot be inherited.
445 public sealed class AudioMediaFormat : MediaFormat
449 /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
450 /// channel, sample rate, bit and bit rate.
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.
461 public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
462 int channel, int sampleRate, int bit, int bitRate)
463 : this(mimeType, channel, sampleRate, bit, bitRate, MediaFormatAacType.None)
468 /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
469 /// channel, sample rate, bit, bit rate and aac type.
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
480 /// <paramref name="aacType"/> is not <see cref="MediaFormatAacType.None"/>, but <paramref name="mimeType"/> is one of aac types.
482 /// <exception cref="ArgumentOutOfRangeException">
483 /// <paramref name="channel"/>, <paramref name="sampleRate"/>, <paramref name="bit"/> or <paramref name="bitRate"/> is less than zero.
485 public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
486 int channel, int sampleRate, int bit, int bitRate, MediaFormatAacType aacType)
487 : base(MediaFormatType.Audio)
489 if (!Enum.IsDefined(typeof(MediaFormatAudioMimeType), mimeType))
491 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
495 throw new ArgumentOutOfRangeException("Channel value can't be negative.");
499 throw new ArgumentOutOfRangeException("Sample rate value can't be negative.");
503 throw new ArgumentOutOfRangeException("Bit value can't be negative.");
507 throw new ArgumentOutOfRangeException("Bit rate value can't be negative.");
509 if (!Enum.IsDefined(typeof(MediaFormatAacType), aacType))
511 throw new ArgumentException($"Invalid aac type value : { (int)aacType }");
513 if (!IsAacSupportedMimeType(mimeType) && aacType != MediaFormatAacType.None)
515 throw new ArgumentException("Aac is supported only with aac mime types.");
520 SampleRate = sampleRate;
527 /// Initializes a new instance of the AudioMediaFormat class from a native handle.
529 /// <param name="handle">A native handle.</param>
530 internal AudioMediaFormat(IntPtr handle)
531 : base(MediaFormatType.Audio)
533 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
535 MediaFormatAudioMimeType mimeType;
540 MediaFormatAacType aacType;
541 GetInfo(handle, out mimeType, out channel, out sampleRate, out bit, out bitRate);
543 if (IsAacSupportedMimeType(mimeType))
545 GetAacType(handle, out aacType);
549 aacType = MediaFormatAacType.None;
554 SampleRate = sampleRate;
561 /// Returns an indication whether a specified mime type is a aac type.
563 /// <param name="mimeType">A mime type.</param>
564 private static bool IsAacSupportedMimeType(MediaFormatAudioMimeType mimeType)
566 return mimeType == MediaFormatAudioMimeType.AacLC ||
567 mimeType == MediaFormatAudioMimeType.AacHE ||
568 mimeType == MediaFormatAudioMimeType.AacHEPS;
572 /// Retrieves audio properties of media format from a native handle.
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)
583 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
585 int mimeTypeValue = 0;
587 int ret = Interop.MediaFormat.GetAudioInfo(handle,
588 out mimeTypeValue, out channel, out sampleRate, out bit, out bitRate);
590 mimeType = (MediaFormatAudioMimeType)mimeTypeValue;
592 MultimediaDebug.AssertNoError(ret);
594 Debug.Assert(Enum.IsDefined(typeof(MediaFormatAudioMimeType), mimeType),
595 "Invalid audio mime type!");
599 /// Retrieves aac type value from a native handle.
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)
605 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
607 int aacTypeValue = 0;
609 int ret = Interop.MediaFormat.GetAudioAacType(handle, out aacTypeValue);
611 MultimediaDebug.AssertNoError(ret);
613 aacType = (MediaFormatAacType)aacTypeValue;
615 Debug.Assert(Enum.IsDefined(typeof(MediaFormatAacType), aacType), "Invalid aac type!");
618 internal override void AsNativeHandle(IntPtr handle)
620 Debug.Assert(Type == MediaFormatType.Audio);
622 int ret = Interop.MediaFormat.SetAudioMimeType(handle, (int)MimeType);
623 MultimediaDebug.AssertNoError(ret);
625 ret = Interop.MediaFormat.SetAudioChannel(handle, Channel);
626 MultimediaDebug.AssertNoError(ret);
628 ret = Interop.MediaFormat.SetAudioSampleRate(handle, SampleRate);
629 MultimediaDebug.AssertNoError(ret);
631 ret = Interop.MediaFormat.SetAudioBit(handle, Bit);
632 MultimediaDebug.AssertNoError(ret);
634 ret = Interop.MediaFormat.SetAudioAverageBps(handle, BitRate);
635 MultimediaDebug.AssertNoError(ret);
637 ret = Interop.MediaFormat.SetAudioAacType(handle, (int)AacType);
638 MultimediaDebug.AssertNoError(ret);
642 /// Gets the mime type of the current format.
644 public MediaFormatAudioMimeType MimeType { get; }
647 /// Gets the channel value of the current format.
649 public int Channel { get; }
652 /// Gets the sample rate value of the current format.
654 public int SampleRate { get; }
657 /// Gets the bit value of the current format.
659 public int Bit { get; }
662 /// Gets the bit rate value of the current format.
664 public int BitRate { get; }
667 /// Gets the aac type of the current format.
669 public MediaFormatAacType AacType { get; }
671 public override string ToString()
673 return $@"MimeTyp={ MimeType.ToString() }, Channel={ Channel.ToString() }, SampleRate=
674 { SampleRate }, Bit={ Bit.ToString() }, BitRate={ BitRate.ToString() }, AacType={ AacType.ToString() }";
677 public override bool Equals(object obj)
679 var rhs = obj as AudioMediaFormat;
685 return MimeType == rhs.MimeType && Channel == rhs.Channel && SampleRate == rhs.SampleRate &&
686 Bit == rhs.Bit && BitRate == rhs.BitRate;
689 public override int GetHashCode()
691 return new { MimeType, Channel, SampleRate, Bit, BitRate }.GetHashCode();
696 /// Represents a text media format. This class cannot be inherited.
698 public sealed class TextMediaFormat : MediaFormat
701 /// Initializes a new instance of the TextMediaFormat class with the specified mime type
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)
711 if (!Enum.IsDefined(typeof(MediaFormatTextMimeType), mimeType))
713 throw new ArgumentException($"Invalid mime type value : { (int)mimeType }");
715 if (!Enum.IsDefined(typeof(MediaFormatTextType), textType))
717 throw new ArgumentException($"Invalid text type value : { (int)textType }");
724 /// Initializes a new instance of the TextMediaFormat class from a native handle.
726 /// <param name="handle">A native handle.</param>
727 internal TextMediaFormat(IntPtr handle)
728 : base(MediaFormatType.Text)
730 Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
732 MediaFormatTextMimeType mimeType;
733 MediaFormatTextType textType;
735 GetInfo(handle, out mimeType, out textType);
742 /// Retrieves text properties of media format from a native handle.
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)
750 int mimeTypeValue = 0;
751 int textTypeValue = 0;
753 int ret = Interop.MediaFormat.GetTextInfo(handle, out mimeTypeValue, out textTypeValue);
755 MultimediaDebug.AssertNoError(ret);
757 mimeType = (MediaFormatTextMimeType)mimeTypeValue;
758 textType = (MediaFormatTextType)textTypeValue;
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!");
766 internal override void AsNativeHandle(IntPtr handle)
768 Debug.Assert(Type == MediaFormatType.Text);
770 int ret = Interop.MediaFormat.SetTextMimeType(handle, (int)MimeType);
771 MultimediaDebug.AssertNoError(ret);
773 ret = Interop.MediaFormat.SetTextType(handle, (int)TextType);
774 MultimediaDebug.AssertNoError(ret);
778 /// Gets the mime type of the current format.
780 public MediaFormatTextMimeType MimeType { get; }
783 /// Gets the text type of the current format.
785 public MediaFormatTextType TextType { get; }
787 public override string ToString()
789 return $"MimeType={ MimeType.ToString() }, TextType={ TextType.ToString() }";
792 public override bool Equals(object obj)
794 var rhs = obj as TextMediaFormat;
800 return MimeType == rhs.MimeType && TextType == rhs.TextType;
803 public override int GetHashCode()
805 return new { MimeType, TextType }.GetHashCode();