Decompiled source of CSCore v1.0.0

plugins/CSCore/CSCore.Ffmpeg.dll

Decompiled a month ago
#define DEBUG
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using CSCore.Ffmpeg.Interops;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5de75590-74ff-4c8c-bb0c-26164ed01e3d")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace CSCore.Ffmpeg
{
	public enum AvCodecId
	{
		None = 0,
		Mpeg1Video = 1,
		Mpeg2Video = 2,
		Mpeg2VideoXvmc = 3,
		H261 = 4,
		H263 = 5,
		Rv10 = 6,
		Rv20 = 7,
		Mjpeg = 8,
		Mjpegb = 9,
		Ljpeg = 10,
		Sp5X = 11,
		Jpegls = 12,
		Mpeg4 = 13,
		Rawvideo = 14,
		Msmpeg4V1 = 15,
		Msmpeg4V2 = 16,
		Msmpeg4V3 = 17,
		Wmv1 = 18,
		Wmv2 = 19,
		H263P = 20,
		H263I = 21,
		Flv1 = 22,
		Svq1 = 23,
		Svq3 = 24,
		Dvvideo = 25,
		Huffyuv = 26,
		Cyuv = 27,
		H264 = 28,
		Indeo3 = 29,
		Vp3 = 30,
		Theora = 31,
		Asv1 = 32,
		Asv2 = 33,
		Ffv1 = 34,
		_4Xm = 35,
		Vcr1 = 36,
		Cljr = 37,
		Mdec = 38,
		Roq = 39,
		InterplayVideo = 40,
		XanWc3 = 41,
		XanWc4 = 42,
		Rpza = 43,
		Cinepak = 44,
		WsVqa = 45,
		Msrle = 46,
		Msvideo1 = 47,
		Idcin = 48,
		_8Bps = 49,
		Smc = 50,
		Flic = 51,
		Truemotion1 = 52,
		Vmdvideo = 53,
		Mszh = 54,
		Zlib = 55,
		Qtrle = 56,
		Tscc = 57,
		Ulti = 58,
		Qdraw = 59,
		Vixl = 60,
		Qpeg = 61,
		Png = 62,
		Ppm = 63,
		Pbm = 64,
		Pgm = 65,
		Pgmyuv = 66,
		Pam = 67,
		Ffvhuff = 68,
		Rv30 = 69,
		Rv40 = 70,
		Vc1 = 71,
		Wmv3 = 72,
		Loco = 73,
		Wnv1 = 74,
		Aasc = 75,
		Indeo2 = 76,
		Fraps = 77,
		Truemotion2 = 78,
		Bmp = 79,
		Cscd = 80,
		Mmvideo = 81,
		Zmbv = 82,
		Avs = 83,
		Smackvideo = 84,
		Nuv = 85,
		Kmvc = 86,
		Flashsv = 87,
		Cavs = 88,
		Jpeg2000 = 89,
		Vmnc = 90,
		Vp5 = 91,
		Vp6 = 92,
		Vp6F = 93,
		Targa = 94,
		Dsicinvideo = 95,
		Tiertexseqvideo = 96,
		Tiff = 97,
		Gif = 98,
		Dxa = 99,
		Dnxhd = 100,
		Thp = 101,
		Sgi = 102,
		C93 = 103,
		Bethsoftvid = 104,
		Ptx = 105,
		Txd = 106,
		Vp6A = 107,
		Amv = 108,
		Vb = 109,
		Pcx = 110,
		Sunrast = 111,
		Indeo4 = 112,
		Indeo5 = 113,
		Mimic = 114,
		Rl2 = 115,
		Escape124 = 116,
		Dirac = 117,
		Bfi = 118,
		Cmv = 119,
		Motionpixels = 120,
		Tgv = 121,
		Tgq = 122,
		Tqi = 123,
		Aura = 124,
		Aura2 = 125,
		V210X = 126,
		Tmv = 127,
		V210 = 128,
		Dpx = 129,
		Mad = 130,
		Frwu = 131,
		Flashsv2 = 132,
		Cdgraphics = 133,
		R210 = 134,
		Anm = 135,
		Binkvideo = 136,
		IffIlbm = 137,
		Kgv1 = 138,
		Yop = 139,
		Vp8 = 140,
		Pictor = 141,
		Ansi = 142,
		A64Multi = 143,
		A64Multi5 = 144,
		R10K = 145,
		Mxpeg = 146,
		Lagarith = 147,
		Prores = 148,
		Jv = 149,
		Dfa = 150,
		Wmv3Image = 151,
		Vc1Image = 152,
		Utvideo = 153,
		BmvVideo = 154,
		Vble = 155,
		Dxtory = 156,
		V410 = 157,
		Xwd = 158,
		Cdxl = 159,
		Xbm = 160,
		Zerocodec = 161,
		Mss1 = 162,
		Msa1 = 163,
		Tscc2 = 164,
		Mts2 = 165,
		Cllc = 166,
		Mss2 = 167,
		Vp9 = 168,
		Aic = 169,
		Escape130 = 170,
		G2M = 171,
		Webp = 172,
		Hnm4Video = 173,
		Hevc = 174,
		Fic = 175,
		AliasPix = 176,
		BrenderPix = 177,
		PafVideo = 178,
		Exr = 179,
		Vp7 = 180,
		Sanm = 181,
		Sgirle = 182,
		Mvc1 = 183,
		Mvc2 = 184,
		Hqx = 185,
		Tdsc = 186,
		HqHqa = 187,
		Hap = 188,
		Dds = 189,
		Dxv = 190,
		Screenpresso = 191,
		Rscc = 192,
		Y41P = 32768,
		Avrp = 32769,
		_012V = 32770,
		Avui = 32771,
		Ayuv = 32772,
		TargaY216 = 32773,
		V308 = 32774,
		V408 = 32775,
		Yuv4 = 32776,
		Avrn = 32777,
		Cpia = 32778,
		Xface = 32779,
		Snow = 32780,
		Smvjpeg = 32781,
		Apng = 32782,
		Daala = 32783,
		Cfhd = 32784,
		Truemotion2Rt = 32785,
		M101 = 32786,
		Magicyuv = 32787,
		Sheervideo = 32788,
		Ylc = 32789,
		FirstAudio = 65536,
		PcmS16Le = 65536,
		PcmS16Be = 65537,
		PcmU16Le = 65538,
		PcmU16Be = 65539,
		PcmS8 = 65540,
		PcmU8 = 65541,
		PcmMulaw = 65542,
		PcmAlaw = 65543,
		PcmS32Le = 65544,
		PcmS32Be = 65545,
		PcmU32Le = 65546,
		PcmU32Be = 65547,
		PcmS24Le = 65548,
		PcmS24Be = 65549,
		PcmU24Le = 65550,
		PcmU24Be = 65551,
		PcmS24Daud = 65552,
		PcmZork = 65553,
		PcmS16LePlanar = 65554,
		PcmDvd = 65555,
		PcmF32Be = 65556,
		PcmF32Le = 65557,
		PcmF64Be = 65558,
		PcmF64Le = 65559,
		PcmBluray = 65560,
		PcmLxf = 65561,
		S302M = 65562,
		PcmS8Planar = 65563,
		PcmS24LePlanar = 65564,
		PcmS32LePlanar = 65565,
		PcmS16BePlanar = 65566,
		PcmS64Le = 67584,
		PcmS64Be = 67585,
		AdpcmImaQt = 69632,
		AdpcmImaWav = 69633,
		AdpcmImaDk3 = 69634,
		AdpcmImaDk4 = 69635,
		AdpcmImaWs = 69636,
		AdpcmImaSmjpeg = 69637,
		AdpcmMs = 69638,
		Adpcm_4Xm = 69639,
		AdpcmXa = 69640,
		AdpcmAdx = 69641,
		AdpcmEa = 69642,
		AdpcmG726 = 69643,
		AdpcmCt = 69644,
		AdpcmSwf = 69645,
		AdpcmYamaha = 69646,
		AdpcmSbpro4 = 69647,
		AdpcmSbpro3 = 69648,
		AdpcmSbpro2 = 69649,
		AdpcmThp = 69650,
		AdpcmImaAmv = 69651,
		AdpcmEaR1 = 69652,
		AdpcmEaR3 = 69653,
		AdpcmEaR2 = 69654,
		AdpcmImaEaSead = 69655,
		AdpcmImaEaEacs = 69656,
		AdpcmEaXas = 69657,
		AdpcmEaMaxisXa = 69658,
		AdpcmImaIss = 69659,
		AdpcmG722 = 69660,
		AdpcmImaApc = 69661,
		AdpcmVima = 69662,
		Vima = 69662,
		AdpcmAfc = 71680,
		AdpcmImaOki = 71681,
		AdpcmDtk = 71682,
		AdpcmImaRad = 71683,
		AdpcmG726Le = 71684,
		AdpcmThpLe = 71685,
		AdpcmPsx = 71686,
		AdpcmAica = 71687,
		AdpcmImaDat4 = 71688,
		AdpcmMtaf = 71689,
		AmrNb = 73728,
		AmrWb = 73729,
		Ra144 = 77824,
		Ra288 = 77825,
		RoqDpcm = 81920,
		InterplayDpcm = 81921,
		XanDpcm = 81922,
		SolDpcm = 81923,
		Sdx2Dpcm = 83968,
		Mp2 = 86016,
		Mp3 = 86017,
		Aac = 86018,
		Ac3 = 86019,
		Dts = 86020,
		Vorbis = 86021,
		Dvaudio = 86022,
		Wmav1 = 86023,
		Wmav2 = 86024,
		Mace3 = 86025,
		Mace6 = 86026,
		Vmdaudio = 86027,
		Flac = 86028,
		Mp3Adu = 86029,
		Mp3On4 = 86030,
		Shorten = 86031,
		Alac = 86032,
		WestwoodSnd1 = 86033,
		Gsm = 86034,
		Qdm2 = 86035,
		Cook = 86036,
		Truespeech = 86037,
		Tta = 86038,
		Smackaudio = 86039,
		Qcelp = 86040,
		Wavpack = 86041,
		Dsicinaudio = 86042,
		Imc = 86043,
		Musepack7 = 86044,
		Mlp = 86045,
		GsmMs = 86046,
		Atrac3 = 86047,
		Voxware = 86048,
		Ape = 86049,
		Nellymoser = 86050,
		Musepack8 = 86051,
		Speex = 86052,
		Wmavoice = 86053,
		Wmapro = 86054,
		Wmalossless = 86055,
		Atrac3P = 86056,
		Eac3 = 86057,
		Sipr = 86058,
		Mp1 = 86059,
		Twinvq = 86060,
		Truehd = 86061,
		Mp4Als = 86062,
		Atrac1 = 86063,
		BinkaudioRdft = 86064,
		BinkaudioDct = 86065,
		AacLatm = 86066,
		Qdmc = 86067,
		Celt = 86068,
		G7231 = 86069,
		G729 = 86070,
		_8SvxExp = 86071,
		_8SvxFib = 86072,
		BmvAudio = 86073,
		Ralf = 86074,
		Iac = 86075,
		Ilbc = 86076,
		Opus = 86077,
		ComfortNoise = 86078,
		Tak = 86079,
		Metasound = 86080,
		PafAudio = 86081,
		On2Avc = 86082,
		DssSp = 86083,
		Ffwavesynth = 88064,
		Sonic = 88065,
		SonicLs = 88066,
		Evrc = 88067,
		Smv = 88068,
		DsdLsbf = 88069,
		DsdMsbf = 88070,
		DsdLsbfPlanar = 88071,
		DsdMsbfPlanar = 88072,
		_4Gv = 88073,
		InterplayAcm = 88074,
		Xma1 = 88075,
		Xma2 = 88076,
		Dst = 88077,
		FirstSubtitle = 94208,
		DvdSubtitle = 94208,
		DvbSubtitle = 94209,
		Text = 94210,
		Xsub = 94211,
		Ssa = 94212,
		MovText = 94213,
		HdmvPgsSubtitle = 94214,
		DvbTeletext = 94215,
		Srt = 94216,
		Microdvd = 96256,
		Eia608 = 96257,
		Jacosub = 96258,
		Sami = 96259,
		Realtext = 96260,
		Stl = 96261,
		Subviewer1 = 96262,
		Subviewer = 96263,
		Subrip = 96264,
		Webvtt = 96265,
		Mpl2 = 96266,
		Vplayer = 96267,
		Pjs = 96268,
		Ass = 96269,
		HdmvTextSubtitle = 96270,
		FirstUnknown = 98304,
		Ttf = 98304,
		Scte35 = 98305,
		Bintext = 100352,
		Xbin = 100353,
		Idf = 100354,
		Otf = 100355,
		SmpteKlv = 100356,
		DvdNav = 100357,
		TimedId3 = 100358,
		BinData = 100359,
		Probe = 102400,
		Mpeg2Ts = 131072,
		Mpeg4Systems = 131073,
		Ffmetadata = 135168,
		WrappedAvframe = 135169
	}
	internal class AvFormatContext : IDisposable
	{
		private unsafe AVFormatContext* _formatContext;

		private AvStream _stream;

		public unsafe IntPtr FormatPtr => (IntPtr)_formatContext;

		public int BestAudioStreamIndex { get; private set; }

		public AvStream SelectedStream => _stream;

		public unsafe bool CanSeek
		{
			get
			{
				if (_formatContext == null || _formatContext->pb == null)
				{
					return false;
				}
				return _formatContext->pb->seekable == 1;
			}
		}

		public double LengthInSeconds
		{
			get
			{
				if (SelectedStream == null || SelectedStream.Stream.duration < 0)
				{
					return 0.0;
				}
				AVRational time_base = SelectedStream.Stream.time_base;
				if (time_base.den == 0)
				{
					return 0.0;
				}
				return (double)(SelectedStream.Stream.duration * time_base.num) / (double)time_base.den;
			}
		}

		public unsafe AVFormatContext FormatContext
		{
			get
			{
				if (_formatContext == null)
				{
					return default(AVFormatContext);
				}
				return *_formatContext;
			}
		}

		public Dictionary<string, string> Metadata { get; private set; }

		public unsafe AvFormatContext(FfmpegStream stream)
		{
			_formatContext = FfmpegCalls.AvformatAllocContext();
			fixed (AVFormatContext** formatContext = &_formatContext)
			{
				FfmpegCalls.AvformatOpenInput(formatContext, stream.AvioContext);
			}
			Initialize();
		}

		public unsafe AvFormatContext(string url)
		{
			_formatContext = FfmpegCalls.AvformatAllocContext();
			fixed (AVFormatContext** formatContext = &_formatContext)
			{
				FfmpegCalls.AvformatOpenInput(formatContext, url);
			}
			Initialize();
		}

		private unsafe void Initialize()
		{
			FfmpegCalls.AvFormatFindStreamInfo(_formatContext);
			BestAudioStreamIndex = FfmpegCalls.AvFindBestStreamInfo(_formatContext);
			_stream = new AvStream((IntPtr)_formatContext->streams[BestAudioStreamIndex]);
			Metadata = new Dictionary<string, string>();
			if (_formatContext->metadata != null)
			{
				AVDictionaryEntry[] elements = _formatContext->metadata->Elements;
				AVDictionaryEntry[] array = elements;
				for (int i = 0; i < array.Length; i++)
				{
					AVDictionaryEntry aVDictionaryEntry = array[i];
					Metadata.Add(aVDictionaryEntry.Key, aVDictionaryEntry.Value);
				}
			}
		}

		public void SeekFile(double seconds)
		{
			AVRational time_base = SelectedStream.Stream.time_base;
			double time = seconds * (double)time_base.den / (double)time_base.num;
			FfmpegCalls.AvFormatSeekFile(this, time);
		}

		public unsafe void Dispose()
		{
			GC.SuppressFinalize(this);
			if (SelectedStream != null)
			{
				SelectedStream.Dispose();
				_stream = null;
			}
			if (_formatContext != null)
			{
				fixed (AVFormatContext** formatContext = &_formatContext)
				{
					FfmpegCalls.AvformatCloseInput(formatContext);
				}
				_formatContext = null;
				BestAudioStreamIndex = 0;
			}
		}

		~AvFormatContext()
		{
			Dispose();
		}
	}
	internal sealed class AvFrame : IDisposable
	{
		private readonly AvFormatContext _formatContext;

		private unsafe AVFrame* _frame;

		public unsafe AvFrame(AvFormatContext formatContext)
		{
			_formatContext = formatContext;
			_frame = FfmpegCalls.AvFrameAlloc();
		}

		public unsafe int ReadNextFrame(out double seconds, ref byte[] buffer)
		{
			AVStream stream = _formatContext.SelectedStream.Stream;
			AVPacket aVPacket = default(AVPacket);
			FfmpegCalls.InitPacket(&aVPacket);
			int num = 0;
			do
			{
				try
				{
					aVPacket.data = null;
					aVPacket.size = 0;
					seconds = 0.0;
					if (!FfmpegCalls.AvReadFrame(_formatContext, &aVPacket))
					{
						break;
					}
					if (aVPacket.stream_index != _formatContext.SelectedStream.Stream.index)
					{
						continue;
					}
					seconds = (double)(aVPacket.pts * stream.time_base.num) / (double)stream.time_base.den;
					do
					{
						int bytesConsumed;
						try
						{
							int num2 = DecodePacket(ref buffer, num, &aVPacket, out bytesConsumed);
							if (num2 == 0)
							{
								break;
							}
							num += num2;
							goto IL_00d5;
						}
						catch (FfmpegException)
						{
						}
						break;
						IL_00d5:
						aVPacket.data += bytesConsumed;
						aVPacket.size -= bytesConsumed;
					}
					while (aVPacket.size > 0);
					continue;
				}
				finally
				{
					FfmpegCalls.FreePacket(&aVPacket);
				}
			}
			while (num <= 0);
			return num;
		}

		private unsafe int DecodePacket(ref byte[] buffer, int offset, AVPacket* packet, out int bytesConsumed)
		{
			AvStream selectedStream = _formatContext.SelectedStream;
			AVCodecContext* codec = selectedStream.Stream.codec;
			bool flag = FfmpegCalls.AvCodecDecodeAudio4(codec, _frame, packet, out bytesConsumed);
			bytesConsumed = Math.Min(bytesConsumed, packet->size);
			if (flag)
			{
				int num = FfmpegCalls.AvGetBytesPerSample((AVSampleFormat)_frame->format);
				int num2 = FfmpegCalls.AvSamplesGetBufferSize(_frame);
				if (buffer == null || buffer.Length < offset + num2)
				{
					byte[] array = new byte[offset + num2];
					if (buffer != null)
					{
						Buffer.BlockCopy(buffer, 0, array, 0, buffer.Length);
					}
					buffer = array;
				}
				if (IsPlanar((AVSampleFormat)_frame->format))
				{
					for (int i = 0; i < _frame->channels; i++)
					{
						for (int j = 0; j < _frame->nb_samples; j++)
						{
							switch (num)
							{
							case 1:
								buffer[offset + j * _frame->channels + i] = _frame->extended_data[i][j];
								break;
							case 2:
								buffer[offset + j * num * _frame->channels + i * num] = _frame->extended_data[i][j * num];
								buffer[offset + j * num * _frame->channels + i * num + 1] = _frame->extended_data[i][j * num + 1];
								break;
							case 4:
								buffer[offset + j * num * _frame->channels + i * num] = _frame->extended_data[i][j * num];
								buffer[offset + j * num * _frame->channels + i * num + 1] = _frame->extended_data[i][j * num + 1];
								buffer[offset + j * num * _frame->channels + i * num + 2] = _frame->extended_data[i][j * num + 2];
								buffer[offset + j * num * _frame->channels + i * num + 3] = _frame->extended_data[i][j * num + 3];
								break;
							case 8:
								buffer[offset + j * num * _frame->channels + i * num] = _frame->extended_data[i][j * num];
								buffer[offset + j * num * _frame->channels + i * num + 1] = _frame->extended_data[i][j * num + 1];
								buffer[offset + j * num * _frame->channels + i * num + 2] = _frame->extended_data[i][j * num + 2];
								buffer[offset + j * num * _frame->channels + i * num + 3] = _frame->extended_data[i][j * num + 3];
								buffer[offset + j * num * _frame->channels + i * num + 4] = _frame->extended_data[i][j * num + 4];
								buffer[offset + j * num * _frame->channels + i * num + 5] = _frame->extended_data[i][j * num + 5];
								buffer[offset + j * num * _frame->channels + i * num + 6] = _frame->extended_data[i][j * num + 6];
								buffer[offset + j * num * _frame->channels + i * num + 7] = _frame->extended_data[i][j * num + 7];
								break;
							}
						}
					}
					num2 = num * _frame->channels * _frame->nb_samples;
				}
				else
				{
					for (int k = 0; k < num2; k++)
					{
						buffer[k + offset] = (*_frame->extended_data)[k];
					}
				}
				if (num == 8)
				{
					num2 = ConvertDblToFloat(buffer, offset, num2);
				}
				return num2;
			}
			return 0;
		}

		private unsafe int ConvertDblToFloat(byte[] buffer, int offset, int count)
		{
			byte[] array = new byte[count / 2];
			fixed (byte* ptr = &buffer[offset])
			{
				void* ptr2 = ptr;
				fixed (byte* ptr3 = &array[0])
				{
					void* ptr4 = ptr3;
					float* ptr5 = (float*)ptr4;
					double* ptr6 = (double*)ptr2;
					for (int i = 0; i < count / 8; i++)
					{
						ptr5[i] = (float)ptr6[i];
					}
				}
			}
			Array.Clear(buffer, offset, count);
			Buffer.BlockCopy(array, 0, buffer, offset, array.Length);
			return array.Length;
		}

		private bool IsPlanar(AVSampleFormat sampleFormat)
		{
			return sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_U8P || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_S16P || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_S32P || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_FLTP || sampleFormat == AVSampleFormat.AV_SAMPLE_FMT_DBLP;
		}

		public unsafe void Dispose()
		{
			GC.SuppressFinalize(this);
			if (_frame != null)
			{
				FfmpegCalls.AvFrameFree(_frame);
				_frame = null;
			}
		}

		~AvFrame()
		{
			Dispose();
		}
	}
	internal sealed class AvioBuffer : IDisposable
	{
		public int BufferSize { get; private set; }

		public IntPtr Buffer { get; private set; }

		public bool SuppressAvFree { get; set; }

		public AvioBuffer()
			: this(4096)
		{
		}

		public AvioBuffer(int bufferSize)
		{
			if (bufferSize <= 0)
			{
				throw new ArgumentOutOfRangeException("bufferSize");
			}
			BufferSize = bufferSize;
			Buffer = FfmpegCalls.AvMalloc(bufferSize);
			SuppressAvFree = false;
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			if (!SuppressAvFree)
			{
				FfmpegCalls.AvFree(Buffer);
			}
		}

		~AvioBuffer()
		{
			Dispose();
		}
	}
	internal sealed class AvioContext : IDisposable
	{
		private readonly FfmpegCalls.AvioReadData _readDataCallback;

		private readonly FfmpegCalls.AvioSeek _seekCallback;

		private readonly FfmpegCalls.AvioWriteData _writeDataCallback;

		private unsafe AVIOContext* _context;

		private AvioBuffer _buffer;

		public unsafe IntPtr ContextPtr => (IntPtr)_context;

		public unsafe AVIOContext Context
		{
			get
			{
				if (_context == null)
				{
					return default(AVIOContext);
				}
				return *_context;
			}
		}

		public AvioContext(FfmpegCalls.AvioReadData readDataCallback, FfmpegCalls.AvioSeek seekCallback)
			: this(readDataCallback, seekCallback, null)
		{
		}

		public unsafe AvioContext(FfmpegCalls.AvioReadData readDataCallback, FfmpegCalls.AvioSeek seekCallback, FfmpegCalls.AvioWriteData writeDataCallback)
		{
			_readDataCallback = readDataCallback;
			_seekCallback = seekCallback;
			_writeDataCallback = writeDataCallback;
			_buffer = new AvioBuffer
			{
				SuppressAvFree = true
			};
			_context = FfmpegCalls.AvioAllocContext(_buffer, _writeDataCallback != null, IntPtr.Zero, _readDataCallback, _writeDataCallback, _seekCallback);
		}

		public unsafe void Dispose()
		{
			GC.SuppressFinalize(this);
			if (_context != null)
			{
				FfmpegCalls.AvFree((IntPtr)_context->buffer);
				FfmpegCalls.AvFree((IntPtr)_context);
				_context = null;
			}
		}

		~AvioContext()
		{
			Dispose();
		}
	}
	internal sealed class AvStream : IDisposable
	{
		private unsafe readonly AVStream* _stream;

		public unsafe AVStream Stream
		{
			get
			{
				if (_stream == null)
				{
					return default(AVStream);
				}
				return *_stream;
			}
		}

		public unsafe WaveFormat GetSuggestedWaveFormat()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			if (_stream == null)
			{
				throw new InvalidOperationException("No stream selected.");
			}
			int num;
			AudioEncoding val;
			switch (_stream->codec->sample_fmt)
			{
			case AVSampleFormat.AV_SAMPLE_FMT_U8:
			case AVSampleFormat.AV_SAMPLE_FMT_U8P:
				num = 8;
				val = (AudioEncoding)1;
				break;
			case AVSampleFormat.AV_SAMPLE_FMT_S16:
			case AVSampleFormat.AV_SAMPLE_FMT_S16P:
				num = 16;
				val = (AudioEncoding)1;
				break;
			case AVSampleFormat.AV_SAMPLE_FMT_S32:
			case AVSampleFormat.AV_SAMPLE_FMT_S32P:
				num = 32;
				val = (AudioEncoding)1;
				break;
			case AVSampleFormat.AV_SAMPLE_FMT_FLT:
			case AVSampleFormat.AV_SAMPLE_FMT_FLTP:
				num = 32;
				val = (AudioEncoding)3;
				break;
			case AVSampleFormat.AV_SAMPLE_FMT_DBL:
			case AVSampleFormat.AV_SAMPLE_FMT_DBLP:
				num = 32;
				val = (AudioEncoding)3;
				break;
			default:
				throw new NotSupportedException("Audio Sample Format not supported.");
			}
			return new WaveFormat(_stream->codec->sample_rate, num, _stream->codec->channels, val);
		}

		public unsafe AvStream(IntPtr stream)
		{
			if (stream == IntPtr.Zero)
			{
				throw new ArgumentNullException("stream");
			}
			_stream = (AVStream*)(void*)stream;
			AVCodecContext* codec = _stream->codec;
			AVCodec* codec2 = FfmpegCalls.AvCodecFindDecoder(codec->codec_id);
			FfmpegCalls.AvCodecOpen(codec, codec2);
		}

		public unsafe void Dispose()
		{
			GC.SuppressFinalize(this);
			if (_stream != null)
			{
				FfmpegCalls.AvCodecClose(_stream->codec);
			}
		}

		~AvStream()
		{
			Dispose();
		}
	}
	internal class FfmpegCalls
	{
		[Flags]
		public enum SeekFlags
		{
			SeekSet = 0,
			SeekCur = 1,
			SeekEnd = 2,
			SeekSize = 0x10000,
			SeekForce = 0x20000
		}

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate int AvioReadData(IntPtr opaque, IntPtr buffer, int bufferSize);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate int AvioWriteData(IntPtr opaque, IntPtr buffer, int bufferSize);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate long AvioSeek(IntPtr opaque, long offset, SeekFlags whence);

		internal unsafe delegate void LogCallback(void* ptr, int level, byte* fmt, IntPtr vl);

		static FfmpegCalls()
		{
			string path;
			switch (Environment.OSVersion.Platform)
			{
			case PlatformID.Win32S:
			case PlatformID.Win32Windows:
			case PlatformID.Win32NT:
				path = "windows";
				break;
			case PlatformID.Unix:
			case PlatformID.MacOSX:
				path = "unix";
				break;
			default:
				throw new PlatformNotSupportedException();
			}
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (directoryName != null)
			{
				string path2 = Path.Combine(directoryName, Path.Combine("FFmpeg", Path.Combine("bin", Path.Combine(path, (IntPtr.Size == 8) ? "x64" : "x86"))));
				InteropHelper.RegisterLibrariesSearchPath(path2);
			}
			FfmpegConfigurationSection ffmpegConfigurationSection = (FfmpegConfigurationSection)ConfigurationManager.GetSection("ffmpeg");
			if (ffmpegConfigurationSection != null)
			{
				if (!string.IsNullOrEmpty(ffmpegConfigurationSection.HttpProxy))
				{
					Environment.SetEnvironmentVariable("http_proxy", ffmpegConfigurationSection.HttpProxy);
					Environment.SetEnvironmentVariable("no_proxy", ffmpegConfigurationSection.ProxyWhitelist);
				}
				if (ffmpegConfigurationSection.LogLevel.HasValue)
				{
					FfmpegUtils.LogLevel = ffmpegConfigurationSection.LogLevel.Value;
				}
			}
			ffmpeg.av_register_all();
			ffmpeg.avcodec_register_all();
			ffmpeg.avformat_network_init();
		}

		internal unsafe static AVOutputFormat[] GetOutputFormats()
		{
			List<AVOutputFormat> list = new List<AVOutputFormat>();
			for (AVOutputFormat* ptr = ffmpeg.av_oformat_next(null); ptr != null; ptr = ffmpeg.av_oformat_next(ptr))
			{
				list.Add(*ptr);
			}
			return list.ToArray();
		}

		internal unsafe static AVInputFormat[] GetInputFormats()
		{
			List<AVInputFormat> list = new List<AVInputFormat>();
			for (AVInputFormat* ptr = ffmpeg.av_iformat_next(null); ptr != null; ptr = ffmpeg.av_iformat_next(ptr))
			{
				list.Add(*ptr);
			}
			return list.ToArray();
		}

		internal unsafe static List<AvCodecId> GetCodecOfCodecTag(AVCodecTag** codecTag)
		{
			List<AvCodecId> list = new List<AvCodecId>();
			uint num = 0u;
			AvCodecId item;
			while ((item = ffmpeg.av_codec_get_id(codecTag, num++)) != 0)
			{
				list.Add(item);
			}
			return list;
		}

		internal unsafe static IntPtr AvMalloc(int bufferSize)
		{
			void* value = ffmpeg.av_malloc((ulong)bufferSize);
			IntPtr intPtr = new IntPtr(value);
			if (intPtr == IntPtr.Zero)
			{
				throw new OutOfMemoryException("Could not allocate memory.");
			}
			return intPtr;
		}

		internal unsafe static void AvFree(IntPtr buffer)
		{
			ffmpeg.av_free((void*)buffer);
		}

		internal unsafe static AVIOContext* AvioAllocContext(AvioBuffer buffer, bool writeable, IntPtr userData, AvioReadData readData, AvioWriteData writeData, AvioSeek seek)
		{
			byte* buffer2 = (byte*)(void*)buffer.Buffer;
			AVIOContext* ptr = ffmpeg.avio_alloc_context(buffer2, buffer.BufferSize, writeable ? 1 : 0, (void*)userData, readData, writeData, seek);
			if (ptr == null)
			{
				throw new FfmpegException("Could not allocate avio-context.", "avio_alloc_context");
			}
			return ptr;
		}

		internal unsafe static AVFormatContext* AvformatAllocContext()
		{
			AVFormatContext* ptr = ffmpeg.avformat_alloc_context();
			if (ptr == null)
			{
				throw new FfmpegException("Could not allocate avformat-context.", "avformat_alloc_context");
			}
			return ptr;
		}

		internal unsafe static void AvformatOpenInput(AVFormatContext** formatContext, AvioContext avioContext)
		{
			(*formatContext)->pb = (AVIOContext*)(void*)avioContext.ContextPtr;
			int errorCode = ffmpeg.avformat_open_input(formatContext, "DUMMY-FILENAME", null, null);
			FfmpegException.Try(errorCode, "avformat_open_input");
		}

		internal unsafe static void AvformatOpenInput(AVFormatContext** formatContext, string url)
		{
			int errorCode = ffmpeg.avformat_open_input(formatContext, url, null, null);
			FfmpegException.Try(errorCode, "avformat_open_input");
		}

		internal unsafe static void AvformatCloseInput(AVFormatContext** formatContext)
		{
			ffmpeg.avformat_close_input(formatContext);
		}

		internal unsafe static void AvFormatFindStreamInfo(AVFormatContext* formatContext)
		{
			int errorCode = ffmpeg.avformat_find_stream_info(formatContext, null);
			FfmpegException.Try(errorCode, "avformat_find_stream_info");
		}

		internal unsafe static int AvFindBestStreamInfo(AVFormatContext* formatContext)
		{
			int num = ffmpeg.av_find_best_stream(formatContext, AVMediaType.AVMEDIA_TYPE_AUDIO, -1, -1, null, 0);
			FfmpegException.Try(num, "av_find_best_stream");
			return num;
		}

		internal unsafe static AVCodec* AvCodecFindDecoder(AvCodecId codecId)
		{
			AVCodec* ptr = ffmpeg.avcodec_find_decoder(codecId);
			if (ptr == null)
			{
				throw new FfmpegException($"Failed to find a decoder for CodecId {codecId}.", "avcodec_find_decoder");
			}
			return ptr;
		}

		internal unsafe static void AvCodecOpen(AVCodecContext* codecContext, AVCodec* codec)
		{
			int errorCode = ffmpeg.avcodec_open2(codecContext, codec, null);
			FfmpegException.Try(errorCode, "avcodec_open2");
		}

		internal unsafe static void AvCodecClose(AVCodecContext* codecContext)
		{
			ffmpeg.avcodec_close(codecContext);
		}

		internal unsafe static AVFrame* AvFrameAlloc()
		{
			AVFrame* ptr = ffmpeg.av_frame_alloc();
			if (ptr == null)
			{
				throw new FfmpegException("Could not allocate frame.", "av_frame_alloc");
			}
			return ptr;
		}

		internal unsafe static void AvFrameFree(AVFrame* frame)
		{
			ffmpeg.av_frame_free(&frame);
		}

		internal unsafe static void InitPacket(AVPacket* packet)
		{
			ffmpeg.av_init_packet(packet);
		}

		internal unsafe static void FreePacket(AVPacket* packet)
		{
			ffmpeg.av_packet_unref(packet);
		}

		internal unsafe static bool AvReadFrame(AvFormatContext formatContext, AVPacket* packet)
		{
			int num = ffmpeg.av_read_frame((AVFormatContext*)(void*)formatContext.FormatPtr, packet);
			return num >= 0;
		}

		internal unsafe static bool AvCodecDecodeAudio4(AVCodecContext* codecContext, AVFrame* frame, AVPacket* packet, out int bytesConsumed)
		{
			int num = default(int);
			int num2 = ffmpeg.avcodec_decode_audio4(codecContext, frame, &num, packet);
			FfmpegException.Try(num2, "avcodec_decode_audio4");
			bytesConsumed = num2;
			return num != 0;
		}

		internal static int AvGetBytesPerSample(AVSampleFormat sampleFormat)
		{
			int num = ffmpeg.av_get_bytes_per_sample(sampleFormat);
			if (num <= 0)
			{
				throw new FfmpegException("Could not calculate data size.");
			}
			return num;
		}

		internal unsafe static int AvSamplesGetBufferSize(AVFrame* frame)
		{
			int num = ffmpeg.av_samples_get_buffer_size(null, frame->channels, frame->nb_samples, (AVSampleFormat)frame->format, 1);
			FfmpegException.Try(num, "av_samples_get_buffer_size");
			return num;
		}

		internal unsafe static void AvFormatSeekFile(AvFormatContext formatContext, double time)
		{
			int errorCode = ffmpeg.avformat_seek_file((AVFormatContext*)(void*)formatContext.FormatPtr, formatContext.BestAudioStreamIndex, long.MinValue, (long)time, (long)time, 0);
			FfmpegException.Try(errorCode, "avformat_seek_file");
		}

		internal unsafe static string AvStrError(int errorCode)
		{
			byte* value = stackalloc byte[500];
			int num = ffmpeg.av_strerror(errorCode, new IntPtr(value), 500uL);
			if (num < 0)
			{
				return "No description available.";
			}
			string text = Marshal.PtrToStringAnsi(new IntPtr(value), 500).Trim(new char[1]).Trim();
			Debug.WriteLineIf(Debugger.IsAttached, text);
			return text;
		}

		internal static void SetLogLevel(LogLevel level)
		{
			ffmpeg.av_log_set_level((int)level);
		}

		internal static LogLevel GetLogLevel()
		{
			return (LogLevel)ffmpeg.av_log_get_level();
		}

		internal static void SetLogCallback(LogCallback callback)
		{
			ffmpeg.av_log_set_callback(Marshal.GetFunctionPointerForDelegate(callback));
		}

		internal unsafe static LogCallback GetDefaultLogCallback()
		{
			return delegate(void* ptr, int level, byte* fmt, IntPtr vl)
			{
				ffmpeg.av_log_default_callback(ptr, level, Marshal.PtrToStringAnsi(new IntPtr(fmt)), (sbyte*)(void*)vl);
			};
		}

		internal unsafe static string FormatLine(void* avcl, int level, string fmt, IntPtr vl, ref int printPrefix)
		{
			string empty = string.Empty;
			byte* ptr = stackalloc byte[1024];
			fixed (int* print_prefix = &printPrefix)
			{
				int num = ffmpeg.av_log_format_line2(avcl, level, fmt, (sbyte*)(void*)vl, (IntPtr)ptr, 1024, print_prefix);
				if (num < 0)
				{
					Debug.WriteLine("av_log_format_line2 failed with " + num.ToString("x8"));
					return empty;
				}
				empty = Marshal.PtrToStringAnsi((IntPtr)ptr);
				if (empty != null && num > 0)
				{
					empty = empty.Substring(0, num);
				}
				return empty;
			}
		}
	}
	public class FfmpegConfigurationSection : ConfigurationSection
	{
		[ConfigurationProperty("httpProxy", DefaultValue = "", IsRequired = false)]
		public string HttpProxy
		{
			get
			{
				return (string)((ConfigurationElement)this)["httpProxy"];
			}
			set
			{
				((ConfigurationElement)this)["httpProxy"] = value;
			}
		}

		[ConfigurationProperty("proxyWhitelist", DefaultValue = "*", IsRequired = false)]
		public string ProxyWhitelist
		{
			get
			{
				return (string)((ConfigurationElement)this)["proxyWhitelist"];
			}
			set
			{
				((ConfigurationElement)this)["proxyWhitelist"] = value;
			}
		}

		[ConfigurationProperty("loglevel", DefaultValue = null, IsRequired = false)]
		public LogLevel? LogLevel
		{
			get
			{
				object obj = ((ConfigurationElement)this)["loglevel"];
				if (obj is LogLevel && Enum.IsDefined(typeof(LogLevel), obj))
				{
					return (LogLevel?)obj;
				}
				return null;
			}
			set
			{
				((ConfigurationElement)this)["loglevel"] = value;
			}
		}
	}
	public class FfmpegDecoder : IWaveSource, IReadableAudioSource<byte>, IAudioSource, IDisposable
	{
		private readonly object _lockObject = new object();

		private readonly Uri _uri;

		private FfmpegStream _ffmpegStream;

		private AvFormatContext _formatContext;

		private bool _disposeStream = false;

		private byte[] _overflowBuffer = new byte[0];

		private int _overflowCount;

		private int _overflowOffset;

		private long _position;

		private Stream _stream;

		public Dictionary<string, string> Metadata
		{
			get
			{
				if (_formatContext == null)
				{
					return new Dictionary<string, string>();
				}
				return _formatContext.Metadata;
			}
		}

		public bool CanSeek
		{
			get
			{
				if (_formatContext == null)
				{
					return false;
				}
				return _formatContext.CanSeek;
			}
		}

		public WaveFormat WaveFormat { get; private set; }

		public long Position
		{
			get
			{
				return _position;
			}
			set
			{
				SeekPosition(value);
			}
		}

		public long Length
		{
			get
			{
				if (_formatContext == null || _formatContext.SelectedStream == null)
				{
					return 0L;
				}
				return Extensions.GetRawElements((IAudioSource)(object)this, TimeSpan.FromSeconds(_formatContext.LengthInSeconds));
			}
		}

		public FfmpegDecoder(string url)
		{
			_uri = new Uri(url);
			try
			{
				_formatContext = new AvFormatContext(url);
				Initialize();
			}
			catch (FfmpegException ex)
			{
				if (ex.ErrorCode == -22 && "avformat_open_input".Equals(ex.Function, StringComparison.OrdinalIgnoreCase))
				{
					if (!TryInitializeWithFileAsStream(url))
					{
						throw;
					}
					return;
				}
				throw;
			}
		}

		public FfmpegDecoder(Stream stream)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			InitializeWithStream(stream, disposeStream: false);
		}

		public int Read(byte[] buffer, int offset, int count)
		{
			int num = 0;
			count -= count % WaveFormat.BlockAlign;
			int overflows = GetOverflows(buffer, ref offset, count);
			num += overflows;
			while (num < count)
			{
				int num2;
				long rawElements;
				lock (_lockObject)
				{
					using AvFrame avFrame = new AvFrame(_formatContext);
					num2 = avFrame.ReadNextFrame(out var seconds, ref _overflowBuffer);
					rawElements = Extensions.GetRawElements((IAudioSource)(object)this, TimeSpan.FromSeconds(seconds));
				}
				if (num2 <= 0)
				{
					if (!(_uri != null) || _uri.IsFile)
					{
						break;
					}
					Thread.Sleep(10);
				}
				int num3 = Math.Min(count - num, num2);
				Array.Copy(_overflowBuffer, 0, buffer, offset, num3);
				num += num3;
				offset += num3;
				_overflowCount = ((num2 > num3) ? (num2 - num3) : 0);
				_overflowOffset = ((num2 > num3) ? num3 : 0);
				_position = rawElements + num - overflows;
			}
			if (overflows == num)
			{
				_position += num;
			}
			return num;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			GC.SuppressFinalize(this);
			if (disposing)
			{
				if (_disposeStream && _stream != null)
				{
					_stream.Dispose();
					_stream = null;
				}
				if (_formatContext != null)
				{
					_formatContext.Dispose();
					_formatContext = null;
				}
				if (_ffmpegStream != null)
				{
					_ffmpegStream.Dispose();
					_ffmpegStream = null;
				}
			}
		}

		private void Initialize()
		{
			WaveFormat = _formatContext.SelectedStream.GetSuggestedWaveFormat();
		}

		private void InitializeWithStream(Stream stream, bool disposeStream)
		{
			_stream = stream;
			_disposeStream = disposeStream;
			_ffmpegStream = new FfmpegStream(stream, allowWrite: false);
			_formatContext = new AvFormatContext(_ffmpegStream);
			Initialize();
		}

		private bool TryInitializeWithFileAsStream(string filename)
		{
			if (!File.Exists(filename))
			{
				return false;
			}
			Stream stream = null;
			try
			{
				stream = File.OpenRead(filename);
				InitializeWithStream(stream, disposeStream: true);
				return true;
			}
			catch (Exception)
			{
				stream?.Dispose();
				return false;
			}
		}

		~FfmpegDecoder()
		{
			Dispose(disposing: false);
		}

		private void SeekPosition(long position)
		{
			double seconds = (double)Extensions.GetMilliseconds((IAudioSource)(object)this, position) / 1000.0;
			lock (_lockObject)
			{
				_formatContext.SeekFile(seconds);
				_position = position;
				_overflowCount = 0;
				_overflowOffset = 0;
			}
		}

		private int GetOverflows(byte[] buffer, ref int offset, int count)
		{
			if (_overflowCount != 0 && _overflowBuffer != null && count > 0)
			{
				int num = Math.Min(count, _overflowCount);
				Array.Copy(_overflowBuffer, _overflowOffset, buffer, offset, num);
				_overflowCount -= num;
				_overflowOffset += num;
				offset += num;
				return num;
			}
			return 0;
		}
	}
	public class FfmpegException : Exception
	{
		public int ErrorCode { get; private set; }

		public string Function { get; private set; }

		public static void Try(int errorCode, string function)
		{
			if (errorCode < 0)
			{
				throw new FfmpegException(errorCode, function);
			}
		}

		public FfmpegException(int errorCode, string function)
			: base($"{function} returned 0x{errorCode:x8}: {FfmpegCalls.AvStrError(errorCode)}")
		{
			ErrorCode = errorCode;
			Function = function;
		}

		public FfmpegException(string message, string function)
			: base($"{message} failed: {function}")
		{
			Function = function;
		}

		public FfmpegException(string message)
			: base(message)
		{
		}
	}
	public class FfmpegLogReceivedEventArgs : EventArgs
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate IntPtr ItemNameFunc(IntPtr avClass);

		public string Message { get; private set; }

		public LogLevel Level { get; private set; }

		public string ClassName { get; private set; }

		public string ItemName { get; private set; }

		public string ParentLogContextClassName { get; set; }

		public string ParentLogContextItemName { get; set; }

		internal unsafe FfmpegLogReceivedEventArgs(AVClass? avClass, AVClass? parentLogContext, LogLevel level, string line, void* ptr, void* ptr1)
		{
			Message = line;
			Level = level;
			if (avClass.HasValue)
			{
				AVClass value = avClass.Value;
				ClassName = Marshal.PtrToStringAnsi((IntPtr)value.class_name);
				if (value.item_name != IntPtr.Zero)
				{
					ItemNameFunc itemNameFunc = (ItemNameFunc)Marshal.GetDelegateForFunctionPointer(value.item_name, typeof(ItemNameFunc));
					IntPtr intPtr = itemNameFunc((IntPtr)ptr);
					if (intPtr != IntPtr.Zero)
					{
						ItemName = Marshal.PtrToStringAnsi(intPtr);
					}
				}
			}
			if (!parentLogContext.HasValue)
			{
				return;
			}
			AVClass value2 = parentLogContext.Value;
			ParentLogContextClassName = Marshal.PtrToStringAnsi((IntPtr)value2.class_name);
			if (value2.item_name != IntPtr.Zero)
			{
				ItemNameFunc itemNameFunc = (ItemNameFunc)Marshal.GetDelegateForFunctionPointer(value2.item_name, typeof(ItemNameFunc));
				IntPtr intPtr = itemNameFunc((IntPtr)ptr1);
				if (intPtr != IntPtr.Zero)
				{
					ParentLogContextItemName = Marshal.PtrToStringAnsi(intPtr);
				}
			}
		}
	}
	internal sealed class FfmpegStream : IDisposable
	{
		private readonly Stream _stream;

		public AvioContext AvioContext { get; private set; }

		public FfmpegStream(Stream stream)
			: this(stream, allowWrite: true)
		{
		}

		public FfmpegStream(Stream stream, bool allowWrite)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (!stream.CanRead)
			{
				throw new ArgumentException("Stream is not readable.", "stream");
			}
			_stream = stream;
			AvioContext = new AvioContext(ReadDataCallback, stream.CanSeek ? new FfmpegCalls.AvioSeek(SeekCallback) : null, (stream.CanWrite && allowWrite) ? new FfmpegCalls.AvioWriteData(WriteDataCallback) : null);
		}

		private long SeekCallback(IntPtr opaque, long offset, FfmpegCalls.SeekFlags whence)
		{
			if ((whence & FfmpegCalls.SeekFlags.SeekSize) == FfmpegCalls.SeekFlags.SeekSize)
			{
				return _stream.Length;
			}
			SeekOrigin origin;
			if ((whence & FfmpegCalls.SeekFlags.SeekSet) == 0)
			{
				origin = SeekOrigin.Begin;
			}
			else if ((whence & FfmpegCalls.SeekFlags.SeekCur) == FfmpegCalls.SeekFlags.SeekCur)
			{
				origin = SeekOrigin.Current;
			}
			else
			{
				if ((whence & FfmpegCalls.SeekFlags.SeekEnd) != FfmpegCalls.SeekFlags.SeekEnd)
				{
					return -1L;
				}
				origin = SeekOrigin.End;
			}
			try
			{
				return _stream.Seek(offset, origin);
			}
			catch (Exception)
			{
				return -1L;
			}
		}

		private int WriteDataCallback(IntPtr opaque, IntPtr buffer, int bufferSize)
		{
			byte[] array = new byte[bufferSize];
			Marshal.Copy(buffer, array, 0, bufferSize);
			_stream.Write(array, 0, bufferSize);
			return bufferSize;
		}

		private int ReadDataCallback(IntPtr opaque, IntPtr buffer, int bufferSize)
		{
			byte[] array = new byte[bufferSize];
			int num = 0;
			while (num < bufferSize)
			{
				int num2 = _stream.Read(array, num, bufferSize - num);
				num += num2;
				if (num2 == 0)
				{
					break;
				}
			}
			num = Math.Min(num, bufferSize);
			Marshal.Copy(array, 0, buffer, Math.Min(num, bufferSize));
			Console.WriteLine("Read: " + num);
			return num;
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			if (AvioContext != null)
			{
				AvioContext.Dispose();
				AvioContext = null;
			}
		}

		~FfmpegStream()
		{
			Dispose();
		}
	}
	public static class FfmpegUtils
	{
		private static readonly FfmpegCalls.LogCallback LogCallback;

		private static readonly FfmpegCalls.LogCallback DefaultLogCallback;

		private static readonly object LockObj;

		public static LogLevel LogLevel
		{
			get
			{
				return FfmpegCalls.GetLogLevel();
			}
			set
			{
				if (value < LogLevel.Quit || value > LogLevel.Debug || (int)value % 8 != 0)
				{
					throw new InvalidEnumArgumentException("value", (int)value, typeof(LogLevel));
				}
				FfmpegCalls.SetLogLevel(value);
			}
		}

		public static bool LogToDefaultLogger { get; set; }

		public static event EventHandler<FfmpegLogReceivedEventArgs> FfmpegLogReceived;

		public static event EventHandler<ResolveFfmpegAssemblyLocationEventArgs> ResolveFfmpegAssemblyLocation;

		unsafe static FfmpegUtils()
		{
			LockObj = new object();
			LogCallback = OnLogMessage;
			DefaultLogCallback = FfmpegCalls.GetDefaultLogCallback();
			FfmpegCalls.SetLogCallback(LogCallback);
		}

		public static IEnumerable<Format> GetOutputFormats()
		{
			AVOutputFormat[] outputFormats = FfmpegCalls.GetOutputFormats();
			return outputFormats.Select((AVOutputFormat format) => new Format(format));
		}

		public static IEnumerable<Format> GetInputFormats()
		{
			AVInputFormat[] inputFormats = FfmpegCalls.GetInputFormats();
			return inputFormats.Select((AVInputFormat format) => new Format(format));
		}

		private unsafe static void OnLogMessage(void* ptr, int level, byte* fmt, IntPtr vl)
		{
			lock (LockObj)
			{
				if (level >= 0)
				{
					level &= 0xFF;
				}
				if (level > (int)LogLevel)
				{
					return;
				}
				if (LogToDefaultLogger)
				{
					DefaultLogCallback(ptr, level, fmt, vl);
				}
				EventHandler<FfmpegLogReceivedEventArgs> ffmpegLogReceived = FfmpegUtils.FfmpegLogReceived;
				if (ffmpegLogReceived == null)
				{
					return;
				}
				AVClass? avClass = null;
				AVClass? parentLogContext = null;
				AVClass** ptr2 = default(AVClass**);
				if (ptr != null)
				{
					avClass = *(*(AVClass**)ptr);
					if (avClass.Value.parent_log_context_offset != 0)
					{
						ptr2 = *(AVClass***)((byte*)ptr + avClass.Value.parent_log_context_offset);
						if (ptr2 != null && *ptr2 != null)
						{
							parentLogContext = *(*ptr2);
						}
					}
				}
				int printPrefix = 1;
				string line = FfmpegCalls.FormatLine(ptr, level, Marshal.PtrToStringAnsi((IntPtr)fmt), vl, ref printPrefix);
				ffmpegLogReceived(null, new FfmpegLogReceivedEventArgs(avClass, parentLogContext, (LogLevel)level, line, ptr, ptr2));
			}
		}

		internal static DirectoryInfo FindFfmpegDirectory(PlatformID platform)
		{
			EventHandler<ResolveFfmpegAssemblyLocationEventArgs> resolveFfmpegAssemblyLocation = FfmpegUtils.ResolveFfmpegAssemblyLocation;
			ResolveFfmpegAssemblyLocationEventArgs resolveFfmpegAssemblyLocationEventArgs = new ResolveFfmpegAssemblyLocationEventArgs(platform);
			resolveFfmpegAssemblyLocation?.Invoke(null, resolveFfmpegAssemblyLocationEventArgs);
			return resolveFfmpegAssemblyLocationEventArgs.FfmpegDirectory;
		}
	}
	public class Format
	{
		public string Name { get; private set; }

		public string LongName { get; private set; }

		public ReadOnlyCollection<AvCodecId> Codecs { get; private set; }

		public ReadOnlyCollection<string> FileExtensions { get; private set; }

		internal unsafe Format(AVOutputFormat format)
		{
			LongName = Marshal.PtrToStringAnsi((IntPtr)format.long_name);
			Name = Marshal.PtrToStringAnsi((IntPtr)format.name);
			Codecs = FfmpegCalls.GetCodecOfCodecTag(format.codec_tag).AsReadOnly();
			string text = Marshal.PtrToStringAnsi((IntPtr)format.extensions);
			FileExtensions = ((!string.IsNullOrEmpty(text)) ? text.Split(new char[1] { ',' }).ToList().AsReadOnly() : Enumerable.Empty<string>().ToList().AsReadOnly());
		}

		internal unsafe Format(AVInputFormat format)
		{
			LongName = Marshal.PtrToStringAnsi((IntPtr)format.long_name);
			Name = Marshal.PtrToStringAnsi((IntPtr)format.name);
			Codecs = FfmpegCalls.GetCodecOfCodecTag(format.codec_tag).AsReadOnly();
			string text = Marshal.PtrToStringAnsi((IntPtr)format.extensions);
			FileExtensions = ((!string.IsNullOrEmpty(text)) ? text.Split(new char[1] { ',' }).ToList().AsReadOnly() : Enumerable.Empty<string>().ToList().AsReadOnly());
		}
	}
	public enum LogLevel
	{
		Quit = -8,
		LogPanic = 0,
		Fatal = 8,
		Error = 16,
		Warning = 24,
		Info = 32,
		Verbose = 40,
		Debug = 48
	}
	public class ResolveFfmpegAssemblyLocationEventArgs : EventArgs
	{
		public PlatformID Platform { get; private set; }

		public DirectoryInfo FfmpegDirectory { get; set; }

		internal ResolveFfmpegAssemblyLocationEventArgs(PlatformID platformId)
		{
			Platform = platformId;
		}
	}
}
namespace CSCore.Ffmpeg.Interops
{
	internal class ConstCharPtrMarshaler : ICustomMarshaler
	{
		private static readonly ConstCharPtrMarshaler Instance = new ConstCharPtrMarshaler();

		public object MarshalNativeToManaged(IntPtr pNativeData)
		{
			return Marshal.PtrToStringAnsi(pNativeData);
		}

		public IntPtr MarshalManagedToNative(object managedObj)
		{
			return IntPtr.Zero;
		}

		public void CleanUpNativeData(IntPtr pNativeData)
		{
		}

		public void CleanUpManagedData(object managedObj)
		{
		}

		public int GetNativeDataSize()
		{
			return IntPtr.Size;
		}

		public static ICustomMarshaler GetInstance(string cookie)
		{
			return Instance;
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVBuffer
	{
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVBufferPool
	{
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVBPrint
	{
	}
	internal struct AVDictionary
	{
		internal int count;

		internal unsafe AVDictionaryEntry* elems;

		public AVDictionaryEntry[] Elements => GetElements();

		private unsafe AVDictionaryEntry[] GetElements()
		{
			AVDictionaryEntry* ptr = elems;
			AVDictionaryEntry[] array = new AVDictionaryEntry[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = ptr[i];
			}
			return array;
		}
	}
	internal struct AVCodecDescriptor
	{
		internal AvCodecId id;

		internal AVMediaType type;

		internal unsafe sbyte* name;

		internal unsafe sbyte* long_name;

		internal int props;

		internal unsafe sbyte** mime_types;

		internal unsafe AVProfile* profiles;
	}
	internal struct AVProfile
	{
		internal int profile;

		internal unsafe sbyte* name;
	}
	internal struct RcOverride
	{
		internal int start_frame;

		internal int end_frame;

		internal int qscale;

		internal float quality_factor;
	}
	internal struct AVPanScan
	{
		internal int id;

		internal int width;

		internal int height;

		internal unsafe fixed short position0[2];

		internal unsafe fixed short position1[2];

		internal unsafe fixed short position2[2];
	}
	internal struct AVCPBProperties
	{
		internal int max_bitrate;

		internal int min_bitrate;

		internal int avg_bitrate;

		internal int buffer_size;

		internal ulong vbv_delay;
	}
	internal struct AVPacketSideData
	{
		internal unsafe sbyte* data;

		internal int size;

		internal AVPacketSideDataType type;
	}
	internal struct AVPacket
	{
		internal unsafe AVBufferRef* buf;

		internal long pts;

		internal long dts;

		internal unsafe sbyte* data;

		internal int size;

		internal int stream_index;

		internal int flags;

		internal unsafe AVPacketSideData* side_data;

		internal int side_data_elems;

		internal long duration;

		internal long pos;

		internal long convergence_duration;
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVCodecInternal
	{
	}
	internal struct AVCodecContext
	{
		internal unsafe AVClass* av_class;

		internal int log_level_offset;

		internal AVMediaType codec_type;

		internal unsafe AVCodec* codec;

		internal unsafe fixed sbyte codec_name[32];

		internal AvCodecId codec_id;

		internal uint codec_tag;

		internal uint stream_codec_tag;

		internal unsafe void* priv_data;

		internal unsafe AVCodecInternal* @internal;

		internal unsafe void* opaque;

		internal long bit_rate;

		internal int bit_rate_tolerance;

		internal int global_quality;

		internal int compression_level;

		internal int flags;

		internal int flags2;

		internal unsafe sbyte* extradata;

		internal int extradata_size;

		internal AVRational time_base;

		internal int ticks_per_frame;

		internal int delay;

		internal int width;

		internal int height;

		internal int coded_width;

		internal int coded_height;

		internal int gop_size;

		internal AVPixelFormat pix_fmt;

		internal int me_method;

		internal IntPtr draw_horiz_band;

		internal IntPtr get_format;

		internal int max_b_frames;

		internal float b_quant_factor;

		internal int rc_strategy;

		internal int b_frame_strategy;

		internal float b_quant_offset;

		internal int has_b_frames;

		internal int mpeg_quant;

		internal float i_quant_factor;

		internal float i_quant_offset;

		internal float lumi_masking;

		internal float temporal_cplx_masking;

		internal float spatial_cplx_masking;

		internal float p_masking;

		internal float dark_masking;

		internal int slice_count;

		internal int prediction_method;

		internal unsafe int* slice_offset;

		internal AVRational sample_aspect_ratio;

		internal int me_cmp;

		internal int me_sub_cmp;

		internal int mb_cmp;

		internal int ildct_cmp;

		internal int dia_size;

		internal int last_predictor_count;

		internal int pre_me;

		internal int me_pre_cmp;

		internal int pre_dia_size;

		internal int me_subpel_quality;

		internal int dtg_active_format;

		internal int me_range;

		internal int intra_quant_bias;

		internal int inter_quant_bias;

		internal int slice_flags;

		internal int xvmc_acceleration;

		internal int mb_decision;

		internal unsafe ushort* intra_matrix;

		internal unsafe ushort* inter_matrix;

		internal int scenechange_threshold;

		internal int noise_reduction;

		internal int me_threshold;

		internal int mb_threshold;

		internal int intra_dc_precision;

		internal int skip_top;

		internal int skip_bottom;

		internal float border_masking;

		internal int mb_lmin;

		internal int mb_lmax;

		internal int me_penalty_compensation;

		internal int bidir_refine;

		internal int brd_scale;

		internal int keyint_min;

		internal int refs;

		internal int chromaoffset;

		internal int scenechange_factor;

		internal int mv0_threshold;

		internal int b_sensitivity;

		internal AVColorPrimaries color_primaries;

		internal AVColorTransferCharacteristic color_trc;

		internal AVColorSpace colorspace;

		internal AVColorRange color_range;

		internal AVChromaLocation chroma_sample_location;

		internal int slices;

		internal AVFieldOrder field_order;

		internal int sample_rate;

		internal int channels;

		internal AVSampleFormat sample_fmt;

		internal int frame_size;

		internal int frame_number;

		internal int block_align;

		internal int cutoff;

		internal ulong channel_layout;

		internal ulong request_channel_layout;

		internal AVAudioServiceType audio_service_type;

		internal AVSampleFormat request_sample_fmt;

		internal IntPtr get_buffer2;

		internal int refcounted_frames;

		internal float qcompress;

		internal float qblur;

		internal int qmin;

		internal int qmax;

		internal int max_qdiff;

		internal float rc_qsquish;

		internal float rc_qmod_amp;

		internal int rc_qmod_freq;

		internal int rc_buffer_size;

		internal int rc_override_count;

		internal unsafe RcOverride* rc_override;

		internal unsafe sbyte* rc_eq;

		internal long rc_max_rate;

		internal long rc_min_rate;

		internal float rc_buffer_aggressivity;

		internal float rc_initial_cplx;

		internal float rc_max_available_vbv_use;

		internal float rc_min_vbv_overflow_use;

		internal int rc_initial_buffer_occupancy;

		internal int coder_type;

		internal int context_model;

		internal int lmin;

		internal int lmax;

		internal int frame_skip_threshold;

		internal int frame_skip_factor;

		internal int frame_skip_exp;

		internal int frame_skip_cmp;

		internal int trellis;

		internal int min_prediction_order;

		internal int max_prediction_order;

		internal long timecode_frame_start;

		internal IntPtr rtp_callback;

		internal int rtp_payload_size;

		internal int mv_bits;

		internal int header_bits;

		internal int i_tex_bits;

		internal int p_tex_bits;

		internal int i_count;

		internal int p_count;

		internal int skip_count;

		internal int misc_bits;

		internal int frame_bits;

		internal unsafe sbyte* stats_out;

		internal unsafe sbyte* stats_in;

		internal int workaround_bugs;

		internal int strict_std_compliance;

		internal int error_concealment;

		internal int debug;

		internal int debug_mv;

		internal int err_recognition;

		internal long reordered_opaque;

		internal unsafe AVHWAccel* hwaccel;

		internal unsafe void* hwaccel_context;

		internal unsafe fixed ulong error[8];

		internal int dct_algo;

		internal int idct_algo;

		internal int bits_per_coded_sample;

		internal int bits_per_raw_sample;

		internal int lowres;

		internal unsafe AVFrame* coded_frame;

		internal int thread_count;

		internal int thread_type;

		internal int active_thread_type;

		internal int thread_safe_callbacks;

		internal IntPtr execute;

		internal IntPtr execute2;

		internal int nsse_weight;

		internal int profile;

		internal int level;

		internal AVDiscard skip_loop_filter;

		internal AVDiscard skip_idct;

		internal AVDiscard skip_frame;

		internal unsafe sbyte* subtitle_header;

		internal int subtitle_header_size;

		internal int error_rate;

		internal ulong vbv_delay;

		internal int side_data_only_packets;

		internal int initial_padding;

		internal AVRational framerate;

		internal AVPixelFormat sw_pix_fmt;

		internal AVRational pkt_timebase;

		internal unsafe AVCodecDescriptor* codec_descriptor;

		internal long pts_correction_num_faulty_pts;

		internal long pts_correction_num_faulty_dts;

		internal long pts_correction_last_pts;

		internal long pts_correction_last_dts;

		internal unsafe sbyte* sub_charenc;

		internal int sub_charenc_mode;

		internal int skip_alpha;

		internal int seek_preroll;

		internal unsafe ushort* chroma_intra_matrix;

		internal unsafe sbyte* dump_separator;

		internal unsafe sbyte* codec_whitelist;

		internal uint properties;

		internal unsafe AVPacketSideData* coded_side_data;

		internal int nb_coded_side_data;

		internal unsafe AVBufferRef* hw_frames_ctx;

		internal int sub_text_format;

		internal int trailing_padding;
	}
	internal struct AVHWAccel
	{
		internal unsafe sbyte* name;

		internal AVMediaType type;

		internal AvCodecId id;

		internal AVPixelFormat pix_fmt;

		internal int capabilities;

		internal unsafe AVHWAccel* next;

		internal IntPtr alloc_frame;

		internal IntPtr start_frame;

		internal IntPtr decode_slice;

		internal IntPtr end_frame;

		internal int frame_priv_data_size;

		internal IntPtr decode_mb;

		internal IntPtr init;

		internal IntPtr uninit;

		internal int priv_data_size;
	}
	internal struct AVCodec
	{
		internal unsafe sbyte* name;

		internal unsafe sbyte* long_name;

		internal AVMediaType type;

		internal AvCodecId id;

		internal int capabilities;

		internal unsafe AVRational* supported_framerates;

		internal unsafe AVPixelFormat* pix_fmts;

		internal unsafe int* supported_samplerates;

		internal unsafe AVSampleFormat* sample_fmts;

		internal unsafe ulong* channel_layouts;

		internal sbyte max_lowres;

		internal unsafe AVClass* priv_class;

		internal unsafe AVProfile* profiles;

		internal int priv_data_size;

		internal unsafe AVCodec* next;

		internal IntPtr init_thread_copy;

		internal IntPtr update_thread_context;

		internal unsafe AVCodecDefault* defaults;

		internal IntPtr init_static_data;

		internal IntPtr init;

		internal IntPtr encode_sub;

		internal IntPtr encode2;

		internal IntPtr decode;

		internal IntPtr close;

		internal IntPtr send_frame;

		internal IntPtr send_packet;

		internal IntPtr receive_frame;

		internal IntPtr receive_packet;

		internal IntPtr flush;

		internal int caps_internal;
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVCodecDefault
	{
	}
	internal struct AVSubtitle
	{
		internal ushort format;

		internal uint start_display_time;

		internal uint end_display_time;

		internal uint num_rects;

		internal unsafe AVSubtitleRect** rects;

		internal long pts;
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct MpegEncContext
	{
	}
	internal struct AVPicture
	{
		internal unsafe sbyte* data0;

		internal unsafe sbyte* data1;

		internal unsafe sbyte* data2;

		internal unsafe sbyte* data3;

		internal unsafe sbyte* data4;

		internal unsafe sbyte* data5;

		internal unsafe sbyte* data6;

		internal unsafe sbyte* data7;

		internal unsafe fixed int linesize[8];
	}
	internal struct AVSubtitleRect
	{
		internal int x;

		internal int y;

		internal int w;

		internal int h;

		internal int nb_colors;

		internal AVPicture pict;

		internal unsafe sbyte* data0;

		internal unsafe sbyte* data1;

		internal unsafe sbyte* data2;

		internal unsafe sbyte* data3;

		internal unsafe fixed int linesize[4];

		internal AVSubtitleType type;

		internal unsafe sbyte* text;

		internal unsafe sbyte* ass;

		internal int flags;
	}
	internal struct AVCodecParameters
	{
		internal AVMediaType codec_type;

		internal AvCodecId codec_id;

		internal uint codec_tag;

		internal unsafe sbyte* extradata;

		internal int extradata_size;

		internal int format;

		internal long bit_rate;

		internal int bits_per_coded_sample;

		internal int bits_per_raw_sample;

		internal int profile;

		internal int level;

		internal int width;

		internal int height;

		internal AVRational sample_aspect_ratio;

		internal AVFieldOrder field_order;

		internal AVColorRange color_range;

		internal AVColorPrimaries color_primaries;

		internal AVColorTransferCharacteristic color_trc;

		internal AVColorSpace color_space;

		internal AVChromaLocation chroma_location;

		internal int video_delay;

		internal ulong channel_layout;

		internal int channels;

		internal int sample_rate;

		internal int block_align;

		internal int frame_size;

		internal int initial_padding;

		internal int trailing_padding;

		internal int seek_preroll;
	}
	internal struct AVCodecParserContext
	{
		internal unsafe void* priv_data;

		internal unsafe AVCodecParser* parser;

		internal long frame_offset;

		internal long cur_offset;

		internal long next_frame_offset;

		internal int pict_type;

		internal int repeat_pict;

		internal long pts;

		internal long dts;

		internal long last_pts;

		internal long last_dts;

		internal int fetch_timestamp;

		internal int cur_frame_start_index;

		internal unsafe fixed long cur_frame_offset[4];

		internal unsafe fixed long cur_frame_pts[4];

		internal unsafe fixed long cur_frame_dts[4];

		internal int flags;

		internal long offset;

		internal unsafe fixed long cur_frame_end[4];

		internal int key_frame;

		internal long convergence_duration;

		internal int dts_sync_point;

		internal int dts_ref_dts_delta;

		internal int pts_dts_delta;

		internal unsafe fixed long cur_frame_pos[4];

		internal long pos;

		internal long last_pos;

		internal int duration;

		internal AVFieldOrder field_order;

		internal AVPictureStructure picture_structure;

		internal int output_picture_number;

		internal int width;

		internal int height;

		internal int coded_width;

		internal int coded_height;

		internal int format;
	}
	internal struct AVCodecParser
	{
		internal unsafe fixed int codec_ids[5];

		internal int priv_data_size;

		internal IntPtr parser_init;

		internal IntPtr parser_parse;

		internal IntPtr parser_close;

		internal IntPtr split;

		internal unsafe AVCodecParser* next;
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct ReSampleContext
	{
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVResampleContext
	{
	}
	internal struct AVBitStreamFilterContext
	{
		internal unsafe void* priv_data;

		internal unsafe AVBitStreamFilter* filter;

		internal unsafe AVCodecParserContext* parser;

		internal unsafe AVBitStreamFilterContext* next;

		internal unsafe sbyte* args;
	}
	internal struct AVBitStreamFilter
	{
		internal unsafe sbyte* name;

		internal unsafe AvCodecId* codec_ids;

		internal unsafe AVClass* priv_class;

		internal int priv_data_size;

		internal IntPtr init;

		internal IntPtr filter;

		internal IntPtr close;
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVBSFInternal
	{
	}
	internal struct AVBSFContext
	{
		internal unsafe AVClass* av_class;

		internal unsafe AVBitStreamFilter* filter;

		internal unsafe AVBSFInternal* @internal;

		internal unsafe void* priv_data;

		internal unsafe AVCodecParameters* par_in;

		internal unsafe AVCodecParameters* par_out;

		internal AVRational time_base_in;

		internal AVRational time_base_out;
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct AVBSFList
	{
	}
	internal enum Motion_Est_ID
	{
		ME_ZERO = 1,
		ME_FULL = 2,
		ME_LOG = 3,
		ME_PHODS = 4,
		ME_EPZS = 5,
		ME_X1 = 6,
		ME_HEX = 7,
		ME_UMH = 8,
		ME_TESA = 9,
		ME_ITER = 50
	}
	internal enum AVDiscard
	{
		AVDISCARD_NONE = -16,
		AVDISCARD_DEFAULT = 0,
		AVDISCARD_NONREF = 8,
		AVDISCARD_BIDIR = 16,
		AVDISCARD_NONINTRA = 24,
		AVDISCARD_NONKEY = 32,
		AVDISCARD_ALL = 48
	}
	internal enum AVAudioServiceType
	{
		AV_AUDIO_SERVICE_TYPE_MAIN,
		AV_AUDIO_SERVICE_TYPE_EFFECTS,
		AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED,
		AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED,
		AV_AUDIO_SERVICE_TYPE_DIALOGUE,
		AV_AUDIO_SERVICE_TYPE_COMMENTARY,
		AV_AUDIO_SERVICE_TYPE_EMERGENCY,
		AV_AUDIO_SERVICE_TYPE_VOICE_OVER,
		AV_AUDIO_SERVICE_TYPE_KARAOKE,
		AV_AUDIO_SERVICE_TYPE_NB
	}
	internal enum AVPacketSideDataType
	{
		AV_PKT_DATA_PALETTE = 0,
		AV_PKT_DATA_NEW_EXTRADATA = 1,
		AV_PKT_DATA_PARAM_CHANGE = 2,
		AV_PKT_DATA_H263_MB_INFO = 3,
		AV_PKT_DATA_REPLAYGAIN = 4,
		AV_PKT_DATA_DISPLAYMATRIX = 5,
		AV_PKT_DATA_STEREO3D = 6,
		AV_PKT_DATA_AUDIO_SERVICE_TYPE = 7,
		AV_PKT_DATA_QUALITY_STATS = 8,
		AV_PKT_DATA_FALLBACK_TRACK = 9,
		AV_PKT_DATA_CPB_PROPERTIES = 10,
		AV_PKT_DATA_SKIP_SAMPLES = 70,
		AV_PKT_DATA_JP_DUALMONO = 71,
		AV_PKT_DATA_STRINGS_METADATA = 72,
		AV_PKT_DATA_SUBTITLE_POSITION = 73,
		AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL = 74,
		AV_PKT_DATA_WEBVTT_IDENTIFIER = 75,
		AV_PKT_DATA_WEBVTT_SETTINGS = 76,
		AV_PKT_DATA_METADATA_UPDATE = 77,
		AV_PKT_DATA_MPEGTS_STREAM_ID = 78,
		AV_PKT_DATA_MASTERING_DISPLAY_METADATA = 79
	}
	internal enum AVSideDataParamChangeFlags
	{
		AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 1,
		AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 2,
		AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 4,
		AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 8
	}
	internal enum AVFieldOrder
	{
		AV_FIELD_UNKNOWN,
		AV_FIELD_PROGRESSIVE,
		AV_FIELD_TT,
		AV_FIELD_BB,
		AV_FIELD_TB,
		AV_FIELD_BT
	}
	internal enum AVSubtitleType
	{
		SUBTITLE_NONE,
		SUBTITLE_BITMAP,
		SUBTITLE_TEXT,
		SUBTITLE_ASS
	}
	internal enum AVPictureStructure
	{
		AV_PICTURE_STRUCTURE_UNKNOWN,
		AV_PICTURE_STRUCTURE_TOP_FIELD,
		AV_PICTURE_STRUCTURE_BOTTOM_FIELD,
		AV_PICTURE_STRUCTURE_FRAME
	}
	internal enum AVLockOp
	{
		AV_LOCK_CREATE,
		AV_LOCK_OBTAIN,
		AV_LOCK_RELEASE,
		AV_LOCK_DESTROY
	}
	internal static class ffmpeg
	{
		internal const int LIBAVCODEC_VERSION_MAJOR = 57;

		internal const int LIBAVCODEC_VERSION_MINOR = 64;

		internal const int LIBAVCODEC_VERSION_MICRO = 100;

		internal const bool FF_API_VIMA_DECODER = true;

		internal const bool FF_API_AUDIO_CONVERT = true;

		internal const bool FF_API_AVCODEC_RESAMPLE = true;

		internal const bool FF_API_GETCHROMA = true;

		internal const bool FF_API_MISSING_SAMPLE = true;

		internal const bool FF_API_LOWRES = true;

		internal const bool FF_API_CAP_VDPAU = true;

		internal const bool FF_API_BUFS_VDPAU = true;

		internal const bool FF_API_VOXWARE = true;

		internal const bool FF_API_SET_DIMENSIONS = true;

		internal const bool FF_API_DEBUG_MV = true;

		internal const bool FF_API_AC_VLC = true;

		internal const bool FF_API_OLD_MSMPEG4 = true;

		internal const bool FF_API_ASPECT_EXTENDED = true;

		internal const bool FF_API_ARCH_ALPHA = true;

		internal const bool FF_API_ERROR_RATE = true;

		internal const bool FF_API_QSCALE_TYPE = true;

		internal const bool FF_API_MB_TYPE = true;

		internal const bool FF_API_MAX_BFRAMES = true;

		internal const bool FF_API_NEG_LINESIZES = true;

		internal const bool FF_API_EMU_EDGE = true;

		internal const bool FF_API_ARCH_SH4 = true;

		internal const bool FF_API_ARCH_SPARC = true;

		internal const bool FF_API_UNUSED_MEMBERS = true;

		internal const bool FF_API_IDCT_XVIDMMX = true;

		internal const bool FF_API_INPUT_PRESERVED = true;

		internal const bool FF_API_NORMALIZE_AQP = true;

		internal const bool FF_API_GMC = true;

		internal const bool FF_API_MV0 = true;

		internal const bool FF_API_CODEC_NAME = true;

		internal const bool FF_API_AFD = true;

		internal const bool FF_API_VISMV = true;

		internal const bool FF_API_AUDIOENC_DELAY = true;

		internal const bool FF_API_VAAPI_CONTEXT = true;

		internal const bool FF_API_AVCTX_TIMEBASE = true;

		internal const bool FF_API_MPV_OPT = true;

		internal const bool FF_API_STREAM_CODEC_TAG = true;

		internal const bool FF_API_QUANT_BIAS = true;

		internal const bool FF_API_RC_STRATEGY = true;

		internal const bool FF_API_CODED_FRAME = true;

		internal const bool FF_API_MOTION_EST = true;

		internal const bool FF_API_WITHOUT_PREFIX = true;

		internal const bool FF_API_SIDEDATA_ONLY_PKT = true;

		internal const bool FF_API_VDPAU_PROFILE = true;

		internal const bool FF_API_CONVERGENCE_DURATION = true;

		internal const bool FF_API_AVPICTURE = true;

		internal const bool FF_API_AVPACKET_OLD_API = true;

		internal const bool FF_API_RTP_CALLBACK = true;

		internal const bool FF_API_VBV_DELAY = true;

		internal const bool FF_API_CODER_TYPE = true;

		internal const bool FF_API_STAT_BITS = true;

		internal const bool FF_API_PRIVATE_OPT = true;

		internal const bool FF_API_ASS_TIMING = true;

		internal const bool FF_API_OLD_BSF = true;

		internal const bool FF_API_COPY_CONTEXT = true;

		internal const bool FF_API_GET_CONTEXT_DEFAULTS = true;

		internal const bool FF_API_NVENC_OLD_NAME = true;

		internal const int AV_CODEC_PROP_INTRA_ONLY = 1;

		internal const int AV_CODEC_PROP_LOSSY = 2;

		internal const int AV_CODEC_PROP_LOSSLESS = 4;

		internal const int AV_CODEC_PROP_REORDER = 8;

		internal const int AV_CODEC_PROP_BITMAP_SUB = 65536;

		internal const int AV_CODEC_PROP_TEXT_SUB = 131072;

		internal const int AV_INPUT_BUFFER_PADDING_SIZE = 32;

		internal const int AV_INPUT_BUFFER_MIN_SIZE = 16384;

		internal const int FF_INPUT_BUFFER_PADDING_SIZE = 32;

		internal const int FF_MIN_BUFFER_SIZE = 16384;

		internal const int FF_MAX_B_FRAMES = 16;

		internal const int AV_CODEC_FLAG_UNALIGNED = 1;

		internal const int AV_CODEC_FLAG_QSCALE = 2;

		internal const int AV_CODEC_FLAG_4MV = 4;

		internal const int AV_CODEC_FLAG_OUTPUT_CORRUPT = 8;

		internal const int AV_CODEC_FLAG_QPEL = 16;

		internal const int AV_CODEC_FLAG_PASS1 = 512;

		internal const int AV_CODEC_FLAG_PASS2 = 1024;

		internal const int AV_CODEC_FLAG_LOOP_FILTER = 2048;

		internal const int AV_CODEC_FLAG_GRAY = 8192;

		internal const int AV_CODEC_FLAG_PSNR = 32768;

		internal const int AV_CODEC_FLAG_TRUNCATED = 65536;

		internal const int AV_CODEC_FLAG_INTERLACED_DCT = 262144;

		internal const int AV_CODEC_FLAG_LOW_DELAY = 524288;

		internal const int AV_CODEC_FLAG_GLOBAL_HEADER = 4194304;

		internal const int AV_CODEC_FLAG_BITEXACT = 8388608;

		internal const int AV_CODEC_FLAG_AC_PRED = 16777216;

		internal const int AV_CODEC_FLAG_INTERLACED_ME = 536870912;

		internal const uint AV_CODEC_FLAG_CLOSED_GOP = 2147483648u;

		internal const int AV_CODEC_FLAG2_FAST = 1;

		internal const int AV_CODEC_FLAG2_NO_OUTPUT = 4;

		internal const int AV_CODEC_FLAG2_LOCAL_HEADER = 8;

		internal const int AV_CODEC_FLAG2_DROP_FRAME_TIMECODE = 8192;

		internal const int AV_CODEC_FLAG2_CHUNKS = 32768;

		internal const int AV_CODEC_FLAG2_IGNORE_CROP = 65536;

		internal const int AV_CODEC_FLAG2_SHOW_ALL = 4194304;

		internal const int AV_CODEC_FLAG2_EXPORT_MVS = 268435456;

		internal const int AV_CODEC_FLAG2_SKIP_MANUAL = 536870912;

		internal const int AV_CODEC_FLAG2_RO_FLUSH_NOOP = 1073741824;

		internal const int AV_CODEC_CAP_DRAW_HORIZ_BAND = 1;

		internal const int AV_CODEC_CAP_DR1 = 2;

		internal const int AV_CODEC_CAP_TRUNCATED = 8;

		internal const int AV_CODEC_CAP_DELAY = 32;

		internal const int AV_CODEC_CAP_SMALL_LAST_FRAME = 64;

		internal const int AV_CODEC_CAP_HWACCEL_VDPAU = 128;

		internal const int AV_CODEC_CAP_SUBFRAMES = 256;

		internal const int AV_CODEC_CAP_EXPERIMENTAL = 512;

		internal const int AV_CODEC_CAP_CHANNEL_CONF = 1024;

		internal const int AV_CODEC_CAP_FRAME_THREADS = 4096;

		internal const int AV_CODEC_CAP_SLICE_THREADS = 8192;

		internal const int AV_CODEC_CAP_PARAM_CHANGE = 16384;

		internal const int AV_CODEC_CAP_AUTO_THREADS = 32768;

		internal const int AV_CODEC_CAP_VARIABLE_FRAME_SIZE = 65536;

		internal const int AV_CODEC_CAP_AVOID_PROBING = 131072;

		internal const int AV_CODEC_CAP_INTRA_ONLY = 1073741824;

		internal const uint AV_CODEC_CAP_LOSSLESS = 2147483648u;

		internal const int CODEC_FLAG_UNALIGNED = 1;

		internal const int CODEC_FLAG_QSCALE = 2;

		internal const int CODEC_FLAG_4MV = 4;

		internal const int CODEC_FLAG_OUTPUT_CORRUPT = 8;

		internal const int CODEC_FLAG_QPEL = 16;

		internal const int CODEC_FLAG_GMC = 32;

		internal const int CODEC_FLAG_MV0 = 64;

		internal const int CODEC_FLAG_INPUT_PRESERVED = 256;

		internal const int CODEC_FLAG_PASS1 = 512;

		internal const int CODEC_FLAG_PASS2 = 1024;

		internal const int CODEC_FLAG_GRAY = 8192;

		internal const int CODEC_FLAG_EMU_EDGE = 16384;

		internal const int CODEC_FLAG_PSNR = 32768;

		internal const int CODEC_FLAG_TRUNCATED = 65536;

		internal const int CODEC_FLAG_NORMALIZE_AQP = 131072;

		internal const int CODEC_FLAG_INTERLACED_DCT = 262144;

		internal const int CODEC_FLAG_LOW_DELAY = 524288;

		internal const int CODEC_FLAG_GLOBAL_HEADER = 4194304;

		internal const int CODEC_FLAG_BITEXACT = 8388608;

		internal const int CODEC_FLAG_AC_PRED = 16777216;

		internal const int CODEC_FLAG_LOOP_FILTER = 2048;

		internal const int CODEC_FLAG_INTERLACED_ME = 536870912;

		internal const uint CODEC_FLAG_CLOSED_GOP = 2147483648u;

		internal const int CODEC_FLAG2_FAST = 1;

		internal const int CODEC_FLAG2_NO_OUTPUT = 4;

		internal const int CODEC_FLAG2_LOCAL_HEADER = 8;

		internal const int CODEC_FLAG2_DROP_FRAME_TIMECODE = 8192;

		internal const int CODEC_FLAG2_IGNORE_CROP = 65536;

		internal const int CODEC_FLAG2_CHUNKS = 32768;

		internal const int CODEC_FLAG2_SHOW_ALL = 4194304;

		internal const int CODEC_FLAG2_EXPORT_MVS = 268435456;

		internal const int CODEC_FLAG2_SKIP_MANUAL = 536870912;

		internal const int CODEC_CAP_DRAW_HORIZ_BAND = 1;

		internal const int CODEC_CAP_DR1 = 2;

		internal const int CODEC_CAP_TRUNCATED = 8;

		internal const int CODEC_CAP_HWACCEL = 16;

		internal const int CODEC_CAP_DELAY = 32;

		internal const int CODEC_CAP_SMALL_LAST_FRAME = 64;

		internal const int CODEC_CAP_HWACCEL_VDPAU = 128;

		internal const int CODEC_CAP_SUBFRAMES = 256;

		internal const int CODEC_CAP_EXPERIMENTAL = 512;

		internal const int CODEC_CAP_CHANNEL_CONF = 1024;

		internal const int CODEC_CAP_NEG_LINESIZES = 2048;

		internal const int CODEC_CAP_FRAME_THREADS = 4096;

		internal const int CODEC_CAP_SLICE_THREADS = 8192;

		internal const int CODEC_CAP_PARAM_CHANGE = 16384;

		internal const int CODEC_CAP_AUTO_THREADS = 32768;

		internal const int CODEC_CAP_VARIABLE_FRAME_SIZE = 65536;

		internal const int CODEC_CAP_INTRA_ONLY = 1073741824;

		internal const uint CODEC_CAP_LOSSLESS = 2147483648u;

		internal const int HWACCEL_CODEC_CAP_EXPERIMENTAL = 512;

		internal const int MB_TYPE_INTRA4x4 = 1;

		internal const int MB_TYPE_INTRA16x16 = 2;

		internal const int MB_TYPE_INTRA_PCM = 4;

		internal const int MB_TYPE_16x16 = 8;

		internal const int MB_TYPE_16x8 = 16;

		internal const int MB_TYPE_8x16 = 32;

		internal const int MB_TYPE_8x8 = 64;

		internal const int MB_TYPE_INTERLACED = 128;

		internal const int MB_TYPE_DIRECT2 = 256;

		internal const int MB_TYPE_ACPRED = 512;

		internal const int MB_TYPE_GMC = 1024;

		internal const int MB_TYPE_SKIP = 2048;

		internal const int MB_TYPE_P0L0 = 4096;

		internal const int MB_TYPE_P1L0 = 8192;

		internal const int MB_TYPE_P0L1 = 16384;

		internal const int MB_TYPE_P1L1 = 32768;

		internal const int MB_TYPE_L0 = 12288;

		internal const int MB_TYPE_L1 = 49152;

		internal const int MB_TYPE_L0L1 = 61440;

		internal const int MB_TYPE_QUANT = 65536;

		internal const int MB_TYPE_CBP = 131072;

		internal const int FF_QSCALE_TYPE_MPEG1 = 0;

		internal const int FF_QSCALE_TYPE_MPEG2 = 1;

		internal const int FF_QSCALE_TYPE_H264 = 2;

		internal const int FF_QSCALE_TYPE_VP56 = 3;

		internal const int AV_GET_BUFFER_FLAG_REF = 1;

		internal const int AV_PKT_FLAG_KEY = 1;

		internal const int AV_PKT_FLAG_CORRUPT = 2;

		internal const int AV_PKT_FLAG_DISCARD = 4;

		internal const int FF_COMPRESSION_DEFAULT = -1;

		internal const int FF_ASPECT_EXTENDED = 15;

		internal const int FF_RC_STRATEGY_XVID = 1;

		internal const int FF_PRED_LEFT = 0;

		internal const int FF_PRED_PLANE = 1;

		internal const int FF_PRED_MEDIAN = 2;

		internal const int FF_CMP_SAD = 0;

		internal const int FF_CMP_SSE = 1;

		internal const int FF_CMP_SATD = 2;

		internal const int FF_CMP_DCT = 3;

		internal const int FF_CMP_PSNR = 4;

		internal const int FF_CMP_BIT = 5;

		internal const int FF_CMP_RD = 6;

		internal const int FF_CMP_ZERO = 7;

		internal const int FF_CMP_VSAD = 8;

		internal const int FF_CMP_VSSE = 9;

		internal const int FF_CMP_NSSE = 10;

		internal const int FF_CMP_W53 = 11;

		internal const int FF_CMP_W97 = 12;

		internal const int FF_CMP_DCTMAX = 13;

		internal const int FF_CMP_DCT264 = 14;

		internal const int FF_CMP_MEDIAN_SAD = 15;

		internal const int FF_CMP_CHROMA = 256;

		internal const int FF_DTG_AFD_SAME = 8;

		internal const int FF_DTG_AFD_4_3 = 9;

		internal const int FF_DTG_AFD_16_9 = 10;

		internal const int FF_DTG_AFD_14_9 = 11;

		internal const int FF_DTG_AFD_4_3_SP_14_9 = 13;

		internal const int FF_DTG_AFD_16_9_SP_14_9 = 14;

		internal const int FF_DTG_AFD_SP_4_3 = 15;

		internal const int FF_DEFAULT_QUANT_BIAS = 999999;

		internal const int SLICE_FLAG_CODED_ORDER = 1;

		internal const int SLICE_FLAG_ALLOW_FIELD = 2;

		internal const int SLICE_FLAG_ALLOW_PLANE = 4;

		internal const int FF_MB_DECISION_SIMPLE = 0;

		internal const int FF_MB_DECISION_BITS = 1;

		internal const int FF_MB_DECISION_RD = 2;

		internal const int FF_CODER_TYPE_VLC = 0;

		internal const int FF_CODER_TYPE_AC = 1;

		internal const int FF_CODER_TYPE_RAW = 2;

		internal const int FF_CODER_TYPE_RLE = 3;

		internal const int FF_CODER_TYPE_DEFLATE = 4;

		internal const int FF_BUG_AUTODETECT = 1;

		internal const int FF_BUG_OLD_MSMPEG4 = 2;

		internal const int FF_BUG_XVID_ILACE = 4;

		internal const int FF_BUG_UMP4 = 8;

		internal const int FF_BUG_NO_PADDING = 16;

		internal const int FF_BUG_AMV = 32;

		internal const int FF_BUG_AC_VLC = 0;

		internal const int FF_BUG_QPEL_CHROMA = 64;

		internal const int FF_BUG_STD_QPEL = 128;

		internal const int FF_BUG_QPEL_CHROMA2 = 256;

		internal const int FF_BUG_DIRECT_BLOCKSIZE = 512;

		internal const int FF_BUG_EDGE = 1024;

		internal const int FF_BUG_HPEL_CHROMA = 2048;

		internal const int FF_BUG_DC_CLIP = 4096;

		internal const int FF_BUG_MS = 8192;

		internal const int FF_BUG_TRUNCATED = 16384;

		internal const int FF_COMPLIANCE_VERY_STRICT = 2;

		internal const int FF_COMPLIANCE_STRICT = 1;

		internal const int FF_COMPLIANCE_NORMAL = 0;

		internal const int FF_COMPLIANCE_UNOFFICIAL = -1;

		internal const int FF_COMPLIANCE_EXPERIMENTAL = -2;

		internal const int FF_EC_GUESS_MVS = 1;

		internal const int FF_EC_DEBLOCK = 2;

		internal const int FF_EC_FAVOR_INTER = 256;

		internal const int FF_DEBUG_PICT_INFO = 1;

		internal const int FF_DEBUG_RC = 2;

		internal const int FF_DEBUG_BITSTREAM = 4;

		internal const int FF_DEBUG_MB_TYPE = 8;

		internal const int FF_DEBUG_QP = 16;

		internal const int FF_DEBUG_MV = 32;

		internal const int FF_DEBUG_DCT_COEFF = 64;

		internal const int FF_DEBUG_SKIP = 128;

		internal const int FF_DEBUG_STARTCODE = 256;

		internal const int FF_DEBUG_PTS = 512;

		internal const int FF_DEBUG_ER = 1024;

		internal const int FF_DEBUG_MMCO = 2048;

		internal const int FF_DEBUG_BUGS = 4096;

		internal const int FF_DEBUG_VIS_QP = 8192;

		internal const int FF_DEBUG_VIS_MB_TYPE = 16384;

		internal const int FF_DEBUG_BUFFERS = 32768;

		internal const int FF_DEBUG_THREADS = 65536;

		internal const int FF_DEBUG_GREEN_MD = 8388608;

		internal const int FF_DEBUG_NOMC = 16777216;

		internal const int FF_DEBUG_VIS_MV_P_FOR = 1;

		internal const int FF_DEBUG_VIS_MV_B_FOR = 2;

		internal const int FF_DEBUG_VIS_MV_B_BACK = 4;

		internal const int AV_EF_CRCCHECK = 1;

		internal const int AV_EF_BITSTREAM = 2;

		internal const int AV_EF_BUFFER = 4;

		internal const int AV_EF_EXPLODE = 8;

		internal const int AV_EF_IGNORE_ERR = 32768;

		internal const int AV_EF_CAREFUL = 65536;

		internal const int AV_EF_COMPLIANT = 131072;

		internal const int AV_EF_AGGRESSIVE = 262144;

		internal const int FF_DCT_AUTO = 0;

		internal const int FF_DCT_FASTINT = 1;

		internal const int FF_DCT_INT = 2;

		internal const int FF_DCT_MMX = 3;

		internal const int FF_DCT_ALTIVEC = 5;

		internal const int FF_DCT_FAAN = 6;

		internal const int FF_IDCT_AUTO = 0;

		internal const int FF_IDCT_INT = 1;

		internal const int FF_IDCT_SIMPLE = 2;

		internal const int FF_IDCT_SIMPLEMMX = 3;

		internal const int FF_IDCT_ARM = 7;

		internal const int FF_IDCT_ALTIVEC = 8;

		internal const int FF_IDCT_SH4 = 9;

		internal const int FF_IDCT_SIMPLEARM = 10;

		internal const int FF_IDCT_IPP = 13;

		internal const int FF_IDCT_XVID = 14;

		internal const int FF_IDCT_XVIDMMX = 14;

		internal const int FF_IDCT_SIMPLEARMV5TE = 16;

		internal const int FF_IDCT_SIMPLEARMV6 = 17;

		internal const int FF_IDCT_SIMPLEVIS = 18;

		internal const int FF_IDCT_FAAN = 20;

		internal const int FF_IDCT_SIMPLENEON = 22;

		internal const int FF_IDCT_SIMPLEALPHA = 23;

		internal const int FF_IDCT_SIMPLEAUTO = 128;

		internal const int FF_THREAD_FRAME = 1;

		internal const int FF_THREAD_SLICE = 2;

		internal const int FF_PROFILE_UNKNOWN = -99;

		internal const int FF_PROFILE_RESERVED = -100;

		internal const int FF_PROFILE_AAC_MAIN = 0;

		internal const int FF_PROFILE_AAC_LOW = 1;

		internal const int FF_PROFILE_AAC_SSR = 2;

		internal const int FF_PROFILE_AAC_LTP = 3;

		internal const int FF_PROFILE_AAC_HE = 4;

		internal const int FF_PROFILE_AAC_HE_V2 = 28;

		internal const int FF_PROFILE_AAC_LD = 22;

		internal const int FF_PROFILE_AAC_ELD = 38;

		internal const int FF_PROFILE_MPEG2_AAC_LOW = 128;

		internal const int FF_PROFILE_MPEG2_AAC_HE = 131;

		internal const int FF_PROFILE_DNXHD = 0;

		internal const int FF_PROFILE_DNXHR_LB = 1;

		internal const int FF_PROFILE_DNXHR_SQ = 2;

		internal const int FF_PROFILE_DNXHR_HQ = 3;

		internal const int FF_PROFILE_DNXHR_HQX = 4;

		internal const int FF_PROFILE_DNXHR_444 = 5;

		internal const int FF_PROFILE_DTS = 20;

		internal const int FF_PROFILE_DTS_ES = 30;

		internal const int FF_PROFILE_DTS_96_24 = 40;

		internal const int FF_PROFILE_DTS_HD_HRA = 50;

		internal const int FF_PROFILE_DTS_HD_MA = 60;

		internal const int FF_PROFILE_DTS_EXPRESS = 70;

		internal const int FF_PROFILE_MPEG2_422 = 0;

		internal const int FF_PROFILE_MPEG2_HIGH = 1;

		internal const int FF_PROFILE_MPEG2_SS = 2;

		internal const int FF_PROFILE_MPEG2_SNR_SCALABLE = 3;

		internal const int FF_PROFILE_MPEG2_MAIN = 4;

		internal const int FF_PROFILE_MPEG2_SIMPLE = 5;

		internal const int FF_PROFILE_H264_CONSTRAINED = 512;

		internal const int FF_PROFILE_H264_INTRA = 2048;

		internal const int FF_PROFILE_H264_BASELINE = 66;

		internal const int FF_PROFILE_H264_CONSTRAINED_BASELINE = 578;

		internal const int FF_PROFILE_H264_MAIN = 77;

		internal const int FF_PROFILE_H264_EXTENDED = 88;

		internal const int FF_PROFILE_H264_HIGH = 100;

		internal const int FF_PROFILE_H264_HIGH_10 = 110;

		internal const int FF_PROFILE_H264_HIGH_10_INTRA = 2158;

		internal const int FF_PROFILE_H264_MULTIVIEW_HIGH = 118;

		internal const int FF_PROFILE_H264_HIGH_422 = 122;

		internal const int FF_PROFILE_H264_HIGH_422_INTRA = 2170;

		internal const int FF_PROFILE_H264_STEREO_HIGH = 128;

		internal const int FF_PROFILE_H264_HIGH_444 = 144;

		internal const int FF_PROFILE_H264_HIGH_444_PREDICTIVE = 244;

		internal const int FF_PROFILE_H264_HIGH_444_INTRA = 2292;

		internal const int FF_PROFILE_H264_CAVLC_444 = 44;

		internal const int FF_PROFILE_VC1_SIMPLE = 0;

		internal const int FF_PROFILE_VC1_MAIN = 1;

		internal const int FF_PROFILE_VC1_COMPLEX = 2;

		internal const int FF_PROFILE_VC1_ADVANCED = 3;

		internal const int FF_PROFILE_MPEG4_SIMPLE = 0;

		internal const int FF_PROFILE_MPEG4_SIMPLE_SCALABLE = 1;

		internal const int FF_PROFILE_MPEG4_CORE = 2;

		internal const int FF_PROFILE_MPEG4_MAIN = 3;

		internal const int FF_PROFILE_MPEG4_N_BIT = 4;

		internal const int FF_PROFILE_MPEG4_SCALABLE_TEXTURE = 5;

		internal const int FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION = 6;

		internal const int FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE = 7;

		internal const int FF_PROFILE_MPEG4_HYBRID = 8;

		internal const int FF_PROFILE_MPEG4_ADVANCED_REAL_TIME = 9;

		internal const int FF_PROFILE_MPEG4_CORE_SCALABLE = 10;

		internal const int FF_PROFILE_MPEG4_ADVANCED_CODING = 11;

		internal const int FF_PROFILE_MPEG4_ADVANCED_CORE = 12;

		internal const int FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE = 13;

		internal const int FF_PROFILE_MPEG4_SIMPLE_STUDIO = 14;

		internal const int FF_PROFILE_MPEG4_ADVANCED_SIMPLE = 15;

		internal const int FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 = 1;

		internal const int FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 = 2;

		internal const int FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION = 32768;

		internal const int FF_PROFILE_JPEG2000_DCINEMA_2K = 3;

		internal const int FF_PROFILE_JPEG2000_DCINEMA_4K = 4;

		internal const int FF_PROFILE_VP9_0 = 0;

		internal const int FF_PROFILE_VP9_1 = 1;

		internal const int FF_PROFILE_VP9_2 = 2;

		internal const int FF_PROFILE_VP9_3 = 3;

		internal const int FF_PROFILE_HEVC_MAIN = 1;

		internal const int FF_PROFILE_HEVC_MAIN_10 = 2;

		internal const int FF_PROFILE_HEVC_MAIN_STILL_PICTURE = 3;

		internal const int FF_PROFILE_HEVC_REXT = 4;

		internal const int FF_LEVEL_UNKNOWN = -99;

		internal const int FF_SUB_CHARENC_MODE_DO_NOTHING = -1;

		internal const int FF_SUB_CHARENC_MODE_AUTOMATIC = 0;

		internal const int FF_SUB_CHARENC_MODE_PRE_DECODER = 1;

		internal const int FF_CODEC_PROPERTY_LOSSLESS = 1;

		internal const int FF_CODEC_PROPERTY_CLOSED_CAPTIONS = 2;

		internal const int FF_SUB_TEXT_FMT_ASS = 0;

		internal const int FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS = 1;

		internal const int AV_HWACCEL_FLAG_IGNORE_LEVEL = 1;

		internal const int AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH = 2;

		internal const int AV_SUBTITLE_FLAG_FORCED = 1;

		internal const int AV_PARSER_PTS_NB = 4;

		internal const int PARSER_FLAG_COMPLETE_FRAMES = 1;

		internal const int PARSER_FLAG_ONCE = 2;

		internal const int PARSER_FLAG_FETCHED_OFFSET = 4;

		internal const int PARSER_FLAG_USE_CODEC_TS = 4096;

		private const string libavcodec = "avcodec-57";

		internal const int LIBAVFORMAT_VERSION_MAJOR = 57;

		internal const int LIBAVFORMAT_VERSION_MINOR = 56;

		internal const int LIBAVFORMAT_VERSION_MICRO = 100;

		internal const bool FF_API_LAVF_BITEXACT = true;

		internal const bool FF_API_LAVF_FRAC = true;

		internal const bool FF_API_LAVF_CODEC_TB = true;

		internal const bool FF_API_URL_FEOF = true;

		internal const bool FF_API_LAVF_FMT_RAWPICTURE = true;

		internal const bool FF_API_COMPUTE_PKT_FIELDS2 = true;

		internal const bool FF_API_OLD_OPEN_CALLBACKS = true;

		internal const bool FF_API_LAVF_AVCTX = true;

		internal const bool FF_API_NOCONST_GET_SIDE_DATA = true;

		internal const bool FF_API_HTTP_USER_AGENT = true;

		internal const int FF_API_R_FRAME_RATE = 1;

		internal const int AVIO_SEEKABLE_NORMAL = 1;

		internal const int AVSEEK_SIZE = 65536;

		internal const int AVSEEK_FORCE = 131072;

		internal const int AVIO_FLAG_READ = 1;

		internal const int AVIO_FLAG_WRITE = 2;

		internal const int AVIO_FLAG_READ_WRITE = 3;

		internal const int AVIO_FLAG_NONBLOCK = 8;

		internal const int AVIO_FLAG_DIRECT = 32768;

		internal const int AVPROBE_SCORE_RETRY = 25;

		internal const int AVPROBE_SCORE_STREAM_RETRY = 24;

		internal const int AVPROBE_SCORE_EXTENSION = 50;

		internal const int AVPROBE_SCORE_MIME = 75;

		internal const int AVPROBE_SCORE_MAX = 100;

		internal const int AVPROBE_PADDING_SIZE = 32;

		internal const int AVFMT_NOFILE = 1;

		internal const int AVFMT_NEEDNUMBER = 2;

		internal const int AVFMT_SHOW_IDS = 8;

		internal const int AVFMT_RAWPICTURE = 32;

		internal const int AVFMT_GLOBALHEADER = 64;

		internal const int AVFMT_NOTIMESTAMPS = 128;

		internal const int AVFMT_GENERIC_INDEX = 256;

		internal const int AVFMT_TS_DISCONT = 512;

		internal const int AVFMT_VARIABLE_FPS = 1024;

		internal const int AVFMT_NODIMENSIONS = 2048;

		internal const int AVFMT_NOSTREAMS = 4096;

		internal const int AVFMT_NOBINSEARCH = 8192;

		internal const int AVFMT_NOGENSEARCH = 16384;

		internal const int AVFMT_NO_BYTE_SEEK = 32768;

		internal const int AVFMT_ALLOW_FLUSH = 65536;

		internal const int AVFMT_TS_NONSTRICT = 131072;

		internal const int AVFMT_TS_NEGATIVE = 262144;

		internal const int AVFMT_SEEK_TO_PTS = 67108864;

		internal const int AVINDEX_KEYFRAME = 1;

		internal const int AVINDEX_DISCARD_FRAME = 2;

		internal const int AV_DISPOSITION_DEFAULT = 1;

		internal const int AV_DISPOSITION_DUB = 2;

		internal const int AV_DISPOSITION_ORIGINAL = 4;

		internal const int AV_DISPOSITION_COMMENT = 8;

		internal const int AV_DISPOSITION_LYRICS = 16;

		internal const int AV_DISPOSITION_KARAOKE = 32;

		internal const int AV_DISPOSITION_FORCED = 64;

		internal const int AV_DISPOSITION_HEARING_IMPAIRED = 128;

		internal const int AV_DISPOSITION_VISUAL_IMPAIRED = 256;

		internal const int AV_DISPOSITION_CLEAN_EFFECTS = 512;

		internal const int AV_DISPOSITION_ATTACHED_PIC = 1024;

		internal const int AV_DISPOSITION_TIMED_THUMBNAILS = 2048;

		internal const int AV_DISPOSITION_CAPTIONS = 65536;

		internal const int AV_DISPOSITION_DESCRIPTIONS = 131072;

		internal const int AV_DISPOSITION_METADATA = 262144;

		internal const int AV_PTS_WRAP_IGNORE = 0;

		internal const int AV_PTS_WRAP_ADD_OFFSET = 1;

		internal const int AV_PTS_WRAP_SUB_OFFSET = -1;

		internal const int AVSTREAM_EVENT_FLAG_METADATA_UPDATED = 1;

		internal const int MAX_STD_TIMEBASES = 399;

		internal const int MAX_REORDER_DELAY = 16;

		internal const int AV_PROGRAM_RUNNING = 1;

		internal const int AVFMTCTX_NOHEADER = 1;

		internal const int AVFMT_FLAG_GENPTS = 1;

		internal const int AVFMT_FLAG_IGNIDX = 2;

		internal const int AVFMT_FLAG_NONBLOCK = 4;

		internal const int AVFMT_FLAG_IGNDTS = 8;

		internal const int AVFMT_FLAG_NOFILLIN = 16;

		internal const int AVFMT_FLAG_NOPARSE = 32;

		internal const int AVFMT_FLAG_NOBUFFER = 64;

		internal const int AVFMT_FLAG_CUSTOM_IO = 128;

		internal const int AVFMT_FLAG_DISCARD_CORRUPT = 256;

		internal const int AVFMT_FLAG_FLUSH_PACKETS = 512;

		internal const int AVFMT_FLAG_BITEXACT = 1024;

		internal const int AVFMT_FLAG_MP4A_LATM = 32768;

		internal const int AVFMT_FLAG_SORT_DTS = 65536;

		internal const int AVFMT_FLAG_PRIV_OPT = 131072;

		internal const int AVFMT_FLAG_KEEP_SIDE_DATA = 262144;

		internal const int AVFMT_FLAG_FAST_SEEK = 524288;

		internal const int AVFMT_FLAG_SHORTEST = 1048576;

		internal const int AVFMT_FLAG_AUTO_BSF = 2097152;

		internal const int FF_FDEBUG_TS = 1;

		internal const int AVFMT_EVENT_FLAG_METADATA_UPDATED = 1;

		internal const int AVFMT_AVOID_NEG_TS_AUTO = -1;

		internal const int AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE = 1;

		internal const int AVFMT_AVOID_NEG_TS_MAKE_ZERO = 2;

		internal const int AVSEEK_FLAG_BACKWARD = 1;

		internal const int AVSEEK_FLAG_BYTE = 2;

		internal const int AVSEEK_FLAG_ANY = 4;

		internal const int AVSEEK_FLAG_FRAME = 8;

		internal const int AVSTREAM_INIT_IN_WRITE_HEADER = 0;

		internal const int AVSTREAM_INIT_IN_INIT_OUTPUT = 1;

		internal const int AV_FRAME_FILENAME_FLAGS_MULTIPLE = 1;

		private const string libavformat = "avformat-57";

		internal const int __STDC_CONSTANT_MACROS = 1;

		internal const int AVCODEC_D3D11VA_H = 1;

		internal const int AVCODEC_DXVA2_H = 1;

		internal const int AVCODEC_QSV_H = 1;

		internal const int AVCODEC_VDA_H = 1;

		internal const int AVCODEC_VDPAU_H = 1;

		internal const int AVCODEC_VIDEOTOOLBOX_H = 1;

		internal const int AVCODEC_XVMC_H = 1;

		internal const int FF_LAMBDA_SHIFT = 7;

		internal const int FF_LAMBDA_SCALE = 128;

		internal const int FF_QP2LAMBDA = 118;

		internal const int FF_LAMBDA_MAX = 32767;

		internal const int FF_QUALITY_SCALE = 128;

		internal const ulong AV_NOPTS_VALUE = 9223372036854775808uL;

		internal const int AV_TIME_BASE = 1000000;

		internal const int LIBAVUTIL_VERSION_MAJOR = 55;

		internal const int LIBAVUTIL_VERSION_MINOR = 34;

		internal const int LIBAVUTIL_VERSION_MICRO = 100;

		internal const bool FF_API_VDPAU = true;

		internal const bool FF_API_XVMC = true;

		internal const bool FF_API_OPT_TYPE_METADATA = true;

		internal const bool FF_API_DLOG = true;

		internal const bool FF_API_VAAPI = true;

		internal const bool FF_API_FRAME_QP = true;

		internal const bool FF_API_PLUS1_MINUS1 = true;

		internal const bool FF_API_ERROR_FRAME = true;

		internal const bool FF_API_CRC_BIG_TABLE = true;

		internal const bool FF_API_PKT_PTS = true;

		internal const int AV_HAVE_BIGENDIAN = 0;

		internal const int AV_HAVE_FAST_UNALIGNED = 1;

		internal const int AV_ERROR_MAX_STRING_SIZE = 64;

		internal const double M_E = Math.E;

		internal const double M_LN2 = 0.6931471805599453;

		internal const double M_LN10 = 2.302585092994046;

		internal const double M_LOG2_10 = 3.321928094887362;

		internal const double M_PHI = 1.618033988749895;

		internal const double M_PI = Math.PI;

		internal const double M_PI_2 = Math.PI / 2.0;

		internal const double M_SQRT1_2 = 0.7071067811865476;

		internal const double M_SQRT2 = 1.4142135623730951;

		internal const int AV_LOG_QUIET = -8;

		internal const int AV_LOG_PANIC = 0;

		internal const int AV_LOG_FATAL = 8;

		internal const int AV_LOG_ERROR = 16;

		internal const int AV_LOG_WARNING = 24;

		internal const int AV_LOG_INFO = 32;

		internal const int AV_LOG_VERBOSE = 40;

		internal const int AV_LOG_DEBUG = 48;

		internal const int AV_LOG_TRACE = 56;

		internal const int AV_LOG_MAX_OFFSET = 64;

		internal const int AV_LOG_SKIP_REPEATED = 1;

		internal const int AV_LOG_PRINT_LEVEL = 2;

		internal const int AVPALETTE_SIZE = 1024;

		internal const int AVPALETTE_COUNT = 256;

		internal const int AV_CH_FRONT_LEFT = 1;

		internal const int AV_CH_FRONT_RIGHT = 2;

		internal const int AV_CH_FRONT_CENTER = 4;

		internal const int AV_CH_LOW_FREQUENCY = 8;

		internal const int AV_CH_BACK_LEFT = 16;

		internal const int AV_CH_BACK_RIGHT = 32;

		internal const int AV_CH_FRONT_LEFT_OF_CENTER = 64;

		internal const int AV_CH_FRONT_RIGHT_OF_CENTER = 128;

		internal const int AV_CH_BACK_CENTER = 256;

		internal const int AV_CH_SIDE_LEFT = 512;

		internal const int AV_CH_SIDE_RIGHT = 1024;

		internal const int AV_CH_TOP_CENTER = 2048;

		internal const int AV_CH_TOP_FRONT_LEFT = 4096;

		internal const int AV_CH_TOP_FRONT_CENTER = 8192;

		internal const int AV_CH_TOP_FRONT_RIGHT = 16384;

		internal const int AV_CH_TOP_BACK_LEFT = 32768;

		internal const int AV_CH_TOP_BACK_CENTER = 65536;

		internal const int AV_CH_TOP_BACK_RIGHT = 131072;

		internal const int AV_CH_STEREO_LEFT = 536870912;

		internal const int AV_CH_STEREO_RIGHT = 1073741824;

		internal const ulong AV_CH_WIDE_LEFT = 2147483648uL;

		internal const ulong AV_CH_WIDE_RIGHT = 4294967296uL;

		internal const ulong AV_CH_SURROUND_DIRECT_LEFT = 8589934592uL;

		internal const ulong AV_CH_SURROUND_DIRECT_RIGHT = 17179869184uL;

		internal const ulong AV_CH_LOW_FREQUENCY_2 = 34359738368uL;

		internal const ulong AV_CH_LAYOUT_NATIVE = 9223372036854775808uL;

		internal const int AV_CH_LAYOUT_MONO = 4;

		internal const int AV_CH_LAYOUT_STEREO = 3;

		internal const int AV_CH_LAYOUT_2POINT1 = 11;

		internal const int AV_CH_LAYOUT_2_1 = 259;

		internal const int AV_CH_LAYOUT_SURROUND = 7;

		internal const int AV_CH_LAYOUT_3POINT1 = 15;

		internal const int AV_CH_LAYOUT_4POINT0 = 263;

		internal const int AV_CH_LAYOUT_4POINT1 = 271;

		internal const int AV_CH_LAYOUT_2_2 = 1539;

		internal const int AV_CH_LAYOUT_QUAD = 51;

		internal const int AV_CH_LAYOUT_5POINT0 = 1543;

		internal const int AV_CH_LAYOUT_5POINT1 = 1551;

		internal const int AV_CH_LAYOUT_5POINT0_BACK = 55;

		internal const int AV_CH_LAYOUT_5POINT1_BACK = 63;

		internal const int AV_CH_LAYOUT_6POINT0 = 1799;

		internal const int AV_CH_LAYOUT_6POINT0_FRONT = 1731;

		internal const int AV_CH_LAYOUT_HEXAGONAL = 311;

		internal const int AV_CH_LAYOUT_6POINT1 = 1807;

		internal const int AV_CH_LAYOUT_6POINT1_BACK = 319;

		internal const int AV_CH_LAYOUT_6POINT1_FRONT = 1739;

		internal const int AV_CH_LAYOUT_7POINT0 = 1591;

		internal const int AV_CH_LAYOUT_7POINT0_FRONT = 1735;

		internal const int AV_CH_LAYOUT_7POINT1 = 1599;

		internal const int AV_CH_LAYOUT_7POINT1_WIDE = 1743;

		internal const int AV_CH_LAYOUT_7POINT1_WIDE_BACK = 255;

		internal const int AV_CH_LAYOUT_OCTAGONAL = 1847;

		internal const ulong AV_CH_LAYOUT_HEXADECAGONAL = 6442710839uL;

		internal const int AV_CH_LAYOUT_STEREO_DOWNMIX = 1610612736;

		internal const uint AV_CPU_FLAG_FORCE = 2147483648u;

		internal const int AV_CPU_FLAG_MMX = 1;

		internal const int AV_CPU_FLAG_MMXEXT = 2;

		internal const int AV_CPU_FLAG_MMX2 = 2;

		internal const int AV_CPU_FLAG_3DNOW = 4;

		internal const int AV_CPU_FLAG_SSE = 8;

		internal const int AV_CPU_FLAG_SSE2 = 16;

		internal const int AV_CPU_FLAG_SSE2SLOW = 1073741824;

		internal const int AV_CPU_FLAG_3DNOWEXT = 32;

		internal const int AV_CPU_FLAG_SSE3 = 64;

		internal const int AV_CPU_FLAG_SSE3SLOW = 536870912;

		internal const int AV_CPU_FLAG_SSSE3 = 128;

		internal const int AV_CPU_FLAG_ATOM = 268435456;

		internal const int AV_CPU_FLAG_SSE4 = 256;

		internal const int AV_CPU_FLAG_SSE42 = 512;

		internal const int AV_CPU_FLAG_AESNI = 524288;

		internal const int AV_CPU_FLAG_AVX = 16384;

		internal const int AV_CPU_FLAG_AVXSLOW = 134217728;

		internal const int AV_CPU_FLAG_XOP = 1024;

		internal const int AV_CPU_FLAG_FMA4 = 2048;

		internal const int AV_CPU_FLAG_CMOV = 4096;

		internal const int AV_CPU_FLAG_AVX2 = 32768;

		internal const int AV_CPU_FLAG_FMA3 = 65536;

		internal const int AV_CPU_FLAG_BMI1 = 131072;

		internal const int AV_CPU_FLAG_BMI2 = 262144;

		internal const int AV_CPU_FLAG_ALTIVEC = 1;

		internal const int AV_CPU_FLAG_VSX = 2;

		internal const int AV_CPU_FLAG_POWER8 = 4;

		internal const int AV_CPU_FLAG_ARMV5TE = 1;

		internal const int AV_CPU_FLAG_ARMV6 = 2;

		internal const int AV_CPU_FLAG_ARMV6T2 = 4;

		internal const int AV_CPU_FLAG_VFP = 8;

		internal const int AV_CPU_FLAG_VFPV3 = 16;

		internal const int AV_CPU_FLAG_NEON = 32;

		internal const int AV_CPU_FLAG_ARMV8 = 64;

		internal const int AV_CPU_FLAG_VFP_VM = 128;

		internal const int AV_CPU_FLAG_SETEND = 65536;

		internal const int AV_BUFFER_FLAG_READONLY = 1;

		internal const int AV_DICT_MATCH_CASE = 1;

		internal const int AV_DICT_IGNORE_SUFFIX = 2;

		internal const int AV_DICT_DONT_STRDUP_KEY = 4;

		internal const int AV_DICT_DONT_STRDUP_VAL = 8;

		internal const int AV_DICT_DONT_OVERWRITE = 16;

		internal const int AV_DICT_APPEND = 32;

		internal const int AV_DICT_MULTIKEY = 64;

		internal const int AV_NUM_DATA_POINTERS = 8;

		internal const int AV_FRAME_FLAG_CORRUPT = 1;

		internal const int AV_FRAME_FLAG_DISCARD = 4;

		internal const int FF_DECODE_ERROR_INVALID_BITSTREAM = 1;

		internal const int FF_DECODE_ERROR_MISSING_REFERENCE = 2;

		internal const int AV_OPT_FLAG_ENCODING_PARAM = 1;

		internal const int AV_OPT_FLAG_DECODING_PARAM = 2;

		internal const int AV_OPT_FLAG_METADATA = 4;

		internal const int AV_OPT_FLAG_AUDIO_PARAM = 8;

		internal const int AV_OPT_FLAG_VIDEO_PARAM = 16;

		internal const int AV_OPT_FLAG_SUBTITLE_PARAM = 32;

		internal const int AV_OPT_FLAG_EXPORT = 64;

		internal const int AV_OPT_FLAG_READONLY = 128;

		internal const int AV_OPT_FLAG_FILTERING_PARAM = 65536;

		internal const int AV_OPT_SEARCH_CHILDREN = 1;

		internal const int AV_OPT_SEARCH_FAKE_OBJ = 2;

		internal const int AV_OPT_ALLOW_NULL = 4;

		internal const int AV_OPT_MULTI_COMPONENT_RANGE = 4096;

		internal const int AV_OPT_SERIALIZE_SKIP_DEFAULTS = 1;

		internal const int AV_OPT_SERIALIZE_OPT_FLAGS_EXACT = 2;

		internal const int AV_PIX_FMT_FLAG_BE = 1;

		internal const int AV_PIX_FMT_FLAG_PAL = 2;

		internal const int AV_PIX_FMT_FLAG_BITSTREAM = 4;

		internal const int AV_PIX_FMT_FLAG_HWACCEL = 8;

		internal const int AV_PIX_FMT_FLAG_PLANAR = 16;

		internal const int AV_PIX_FMT_FLAG_RGB = 32;

		internal const int AV_PIX_FMT_FLAG_PSEUDOPAL = 64;

		internal const int AV_PIX_FMT_FLAG_ALPHA = 128;

		internal const int FF_LOSS_RESOLUTION = 1;

		internal const int FF_LOSS_DEPTH = 2;

		internal const int FF_LOSS_COLORSPACE = 4;

		internal const int FF_LOSS_ALPHA = 8;

		internal const int FF_LOSS_COLORQUANT = 16;

		internal const int FF_LOSS_CHROMA = 32;

		private const string libavutil = "avutil-55";

		internal const int LIBSWRESAMPLE_VERSION_MAJOR = 2;

		internal const int LIBSWRESAMPLE_VERSION_MINOR = 3;

		internal const int LIBSWRESAMPLE_VERSION_MICRO = 100;

		internal const int SWR_FLAG_RESAMPLE = 1;

		private const string libswresample = "swresample-2";

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern AVRational av_codec_get_pkt_timebase(AVCodecContext* avctx);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern void av_codec_set_pkt_timebase(AVCodecContext* avctx, AVRational val);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern AVCodecDescriptor* av_codec_get_codec_descriptor(AVCodecContext* avctx);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern void av_codec_set_codec_descriptor(AVCodecContext* avctx, AVCodecDescriptor* desc);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern uint av_codec_get_codec_properties(AVCodecContext* avctx);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern int av_codec_get_lowres(AVCodecContext* avctx);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern void av_codec_set_lowres(AVCodecContext* avctx, int val);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern int av_codec_get_seek_preroll(AVCodecContext* avctx);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern void av_codec_set_seek_preroll(AVCodecContext* avctx, int val);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern ushort* av_codec_get_chroma_intra_matrix(AVCodecContext* avctx);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern void av_codec_set_chroma_intra_matrix(AVCodecContext* avctx, ushort* val);

		[DllImport("avcodec-57", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal unsafe static extern int av_codec_

plugins/CSCore/CSCore.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Configuration;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using CSCore.Codecs.AAC;
using CSCore.Codecs.AIFF;
using CSCore.Codecs.DDP;
using CSCore.Codecs.FLAC;
using CSCore.Codecs.FLAC.Metadata;
using CSCore.Codecs.MP1;
using CSCore.Codecs.MP2;
using CSCore.Codecs.MP3;
using CSCore.Codecs.WAV;
using CSCore.Codecs.WMA;
using CSCore.CoreAudioAPI;
using CSCore.DMO;
using CSCore.DMO.Effects;
using CSCore.DSP;
using CSCore.DirectSound;
using CSCore.MediaFoundation;
using CSCore.SoundIn;
using CSCore.SoundOut;
using CSCore.SoundOut.MMInterop;
using CSCore.Streams;
using CSCore.Streams.SampleConverter;
using CSCore.Tags.ID3;
using CSCore.Tags.ID3.Frames;
using CSCore.Utils;
using CSCore.Utils.Buffer;
using CSCore.Win32;

[assembly: CompilationRelaxations(8)]
[assembly: AssemblyTitle("CSCore")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription(".NET Sound Library")]
[assembly: Guid("7939b0f4-fed9-4dcf-bb59-a17505864c55")]
[assembly: AssemblyFileVersion("1.2.1.2")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CLSCompliant(true)]
[assembly: ComVisible(false)]
[assembly: InternalsVisibleTo("CSCore.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100237314800493cdf9aabec35955e8928e3d5416ad1d223e8914e0e025ff9095b21bbb696235b9d3886b0edec26107ca0af49c3170fc08d117e8e9265ab371b157f2c2b27843d97c1d312850d10d1272c1d46d18f02ac56f46676cbe7946049b1b344db7154d35788fee27b3d581bd7d43e41813b10fd360a3fbfab9199d9e86a4")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CSCore")]
[assembly: AssemblyCopyright("Florian R.")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.2")]
[module: UnverifiableCode]
namespace CSCore
{
	public static class AudioSubTypes
	{
		public static readonly Guid Unknown = new Guid(0, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Pcm = new Guid(1, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Adpcm = new Guid(2, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid IeeeFloat = new Guid(3, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Vselp = new Guid(4, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid IbmCvsd = new Guid(5, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid ALaw = new Guid(6, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MuLaw = new Guid(7, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Dts = new Guid(8, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Drm = new Guid(9, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WmaVoice9 = new Guid(10, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid OkiAdpcm = new Guid(16, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DviAdpcm = new Guid(17, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid ImaAdpcm = new Guid(17, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MediaspaceAdpcm = new Guid(18, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid SierraAdpcm = new Guid(19, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid G723Adpcm = new Guid(20, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DigiStd = new Guid(21, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DigiFix = new Guid(22, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DialogicOkiAdpcm = new Guid(23, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MediaVisionAdpcm = new Guid(24, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid CUCodec = new Guid(25, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid YamahaAdpcm = new Guid(32, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid SonarC = new Guid(33, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DspGroupTrueSpeech = new Guid(34, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid EchoSpeechCorporation1 = new Guid(35, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid AudioFileAf36 = new Guid(36, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Aptx = new Guid(37, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid AudioFileAf10 = new Guid(38, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Prosody1612 = new Guid(39, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Lrc = new Guid(40, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DolbyAc2 = new Guid(48, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Gsm610 = new Guid(49, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MsnAudio = new Guid(50, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid AntexAdpcme = new Guid(51, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid ControlResVqlpc = new Guid(52, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DigiReal = new Guid(53, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid DigiAdpcm = new Guid(54, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid ControlResCr10 = new Guid(55, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_NMS_VBXADPCM = new Guid(56, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_CS_IMAADPCM = new Guid(57, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ECHOSC3 = new Guid(58, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ROCKWELL_ADPCM = new Guid(59, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ROCKWELL_DIGITALK = new Guid(60, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_XEBEC = new Guid(61, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_G721_ADPCM = new Guid(64, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_G728_CELP = new Guid(65, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_MSG723 = new Guid(66, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Mpeg = new Guid(80, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_RT24 = new Guid(82, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_PAC = new Guid(83, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MpegLayer3 = new Guid(85, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_LUCENT_G723 = new Guid(89, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_CIRRUS = new Guid(96, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ESPCM = new Guid(97, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE = new Guid(98, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_CANOPUS_ATRAC = new Guid(99, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_G726_ADPCM = new Guid(100, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_G722_ADPCM = new Guid(101, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_DSAT_DISPLAY = new Guid(103, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = new Guid(105, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_AC8 = new Guid(112, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_AC10 = new Guid(113, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_AC16 = new Guid(114, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_AC20 = new Guid(115, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_RT24 = new Guid(116, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_RT29 = new Guid(117, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_RT29HW = new Guid(118, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_VR12 = new Guid(119, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_VR18 = new Guid(120, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_TQ40 = new Guid(121, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SOFTSOUND = new Guid(128, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VOXWARE_TQ60 = new Guid(129, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_MSRT24 = new Guid(130, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_G729A = new Guid(131, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_MVI_MVI2 = new Guid(132, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_DF_G726 = new Guid(133, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_DF_GSM610 = new Guid(134, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ISIAUDIO = new Guid(136, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ONLIVE = new Guid(137, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SBC24 = new Guid(145, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_DOLBY_AC3_SPDIF = new Guid(146, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_MEDIASONIC_G723 = new Guid(147, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_PROSODY_8KBPS = new Guid(148, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ZYXEL_ADPCM = new Guid(151, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_PHILIPS_LPCBB = new Guid(152, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_PACKED = new Guid(153, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_MALDEN_PHONYTALK = new Guid(160, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Gsm = new Guid(161, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid G729 = new Guid(162, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid G723 = new Guid(163, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Acelp = new Guid(164, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid RawAac = new Guid(255, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_RHETOREX_ADPCM = new Guid(256, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_IRAT = new Guid(257, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VIVO_G723 = new Guid(273, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VIVO_SIREN = new Guid(274, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_DIGITAL_G723 = new Guid(291, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SANYO_LD_ADPCM = new Guid(293, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SIPROLAB_ACEPLNET = new Guid(304, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SIPROLAB_ACELP4800 = new Guid(305, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SIPROLAB_ACELP8V3 = new Guid(306, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SIPROLAB_G729 = new Guid(307, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SIPROLAB_G729A = new Guid(308, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SIPROLAB_KELVIN = new Guid(309, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_G726ADPCM = new Guid(320, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_QUALCOMM_PUREVOICE = new Guid(336, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_QUALCOMM_HALFRATE = new Guid(337, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_TUBGSM = new Guid(341, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_MSAUDIO1 = new Guid(352, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WindowsMediaAudio = new Guid(353, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WindowsMediaAudioProfessional = new Guid(354, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WindowsMediaAudioLosseless = new Guid(355, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WindowsMediaAudioSpdif = new Guid(356, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_UNISYS_NAP_ADPCM = new Guid(368, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_UNISYS_NAP_ULAW = new Guid(369, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_UNISYS_NAP_ALAW = new Guid(370, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_UNISYS_NAP_16K = new Guid(371, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_CREATIVE_ADPCM = new Guid(512, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_CREATIVE_FASTSPEECH8 = new Guid(514, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_CREATIVE_FASTSPEECH10 = new Guid(515, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_UHER_ADPCM = new Guid(528, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_QUARTERDECK = new Guid(544, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ILINK_VC = new Guid(560, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_RAW_SPORT = new Guid(576, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_ESST_AC3 = new Guid(577, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_IPI_HSX = new Guid(592, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_IPI_RPELP = new Guid(593, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_CS2 = new Guid(608, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SONY_SCX = new Guid(624, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_FM_TOWNS_SND = new Guid(768, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_BTV_DIGITAL = new Guid(1024, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_QDESIGN_MUSIC = new Guid(1104, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_VME_VMPCM = new Guid(1664, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_TPC = new Guid(1665, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_OLIGSM = new Guid(4096, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_OLIADPCM = new Guid(4097, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_OLICELP = new Guid(4098, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_OLISBC = new Guid(4099, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_OLIOPR = new Guid(4100, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_LH_CODEC = new Guid(4352, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_NORRIS = new Guid(5120, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = new Guid(5376, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MPEG_ADTS_AAC = new Guid(5632, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MPEG_RAW_AAC = new Guid(5633, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MPEG_LOAS = new Guid(5634, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid NOKIA_MPEG_ADTS_AAC = new Guid(5640, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid NOKIA_MPEG_RAW_AAC = new Guid(5641, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid VODAFONE_MPEG_ADTS_AAC = new Guid(5642, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid VODAFONE_MPEG_RAW_AAC = new Guid(5643, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MPEG_HEAAC = new Guid(5648, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_DVM = new Guid(8192, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Vorbis1 = new Guid(26447, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Vorbis2 = new Guid(26448, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Vorbis3 = new Guid(26449, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Vorbis1P = new Guid(26479, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Vorbis2P = new Guid(26480, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Vorbis3P = new Guid(26481, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_RAW_AAC1 = new Guid(255, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_WMAVOICE9 = new Guid(10, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid Extensible = new Guid(65534, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_DEVELOPMENT = new Guid(65535, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid WAVE_FORMAT_FLAC = new Guid(61868, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);

		public static readonly Guid MediaTypeAudio = new Guid("73647561-0000-0010-8000-00AA00389B71");

		public static AudioEncoding EncodingFromSubType(Guid audioSubType)
		{
			byte[] value = audioSubType.ToByteArray();
			int num = BitConverter.ToInt32(value, 0);
			if (Enum.IsDefined(typeof(AudioEncoding), (short)num))
			{
				return (AudioEncoding)num;
			}
			throw new ArgumentException("Invalid audioSubType.", "audioSubType");
		}

		public static Guid SubTypeFromEncoding(AudioEncoding audioEncoding)
		{
			if (Enum.IsDefined(typeof(AudioEncoding), (short)audioEncoding))
			{
				return new Guid((int)audioEncoding, 0, 16, 128, 0, 0, 170, 0, 56, 155, 113);
			}
			throw new ArgumentException("Invalid encoding.", "audioEncoding");
		}
	}
	public enum AudioEncoding : short
	{
		Unknown = 0,
		Pcm = 1,
		Adpcm = 2,
		IeeeFloat = 3,
		Vselp = 4,
		IbmCvsd = 5,
		ALaw = 6,
		MuLaw = 7,
		Dts = 8,
		Drm = 9,
		WmaVoice9 = 10,
		OkiAdpcm = 16,
		DviAdpcm = 17,
		ImaAdpcm = 17,
		MediaspaceAdpcm = 18,
		SierraAdpcm = 19,
		G723Adpcm = 20,
		DigiStd = 21,
		DigiFix = 22,
		DialogicOkiAdpcm = 23,
		MediaVisionAdpcm = 24,
		CUCodec = 25,
		YamahaAdpcm = 32,
		SonarC = 33,
		DspGroupTrueSpeech = 34,
		EchoSpeechCorporation1 = 35,
		AudioFileAf36 = 36,
		Aptx = 37,
		AudioFileAf10 = 38,
		Prosody1612 = 39,
		Lrc = 40,
		DolbyAc2 = 48,
		Gsm610 = 49,
		MsnAudio = 50,
		AntexAdpcme = 51,
		ControlResVqlpc = 52,
		DigiReal = 53,
		DigiAdpcm = 54,
		ControlResCr10 = 55,
		WAVE_FORMAT_NMS_VBXADPCM = 56,
		WAVE_FORMAT_CS_IMAADPCM = 57,
		WAVE_FORMAT_ECHOSC3 = 58,
		WAVE_FORMAT_ROCKWELL_ADPCM = 59,
		WAVE_FORMAT_ROCKWELL_DIGITALK = 60,
		WAVE_FORMAT_XEBEC = 61,
		WAVE_FORMAT_G721_ADPCM = 64,
		WAVE_FORMAT_G728_CELP = 65,
		WAVE_FORMAT_MSG723 = 66,
		Mpeg = 80,
		WAVE_FORMAT_RT24 = 82,
		WAVE_FORMAT_PAC = 83,
		MpegLayer3 = 85,
		WAVE_FORMAT_LUCENT_G723 = 89,
		WAVE_FORMAT_CIRRUS = 96,
		WAVE_FORMAT_ESPCM = 97,
		WAVE_FORMAT_VOXWARE = 98,
		WAVE_FORMAT_CANOPUS_ATRAC = 99,
		WAVE_FORMAT_G726_ADPCM = 100,
		WAVE_FORMAT_G722_ADPCM = 101,
		WAVE_FORMAT_DSAT_DISPLAY = 103,
		WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = 105,
		WAVE_FORMAT_VOXWARE_AC8 = 112,
		WAVE_FORMAT_VOXWARE_AC10 = 113,
		WAVE_FORMAT_VOXWARE_AC16 = 114,
		WAVE_FORMAT_VOXWARE_AC20 = 115,
		WAVE_FORMAT_VOXWARE_RT24 = 116,
		WAVE_FORMAT_VOXWARE_RT29 = 117,
		WAVE_FORMAT_VOXWARE_RT29HW = 118,
		WAVE_FORMAT_VOXWARE_VR12 = 119,
		WAVE_FORMAT_VOXWARE_VR18 = 120,
		WAVE_FORMAT_VOXWARE_TQ40 = 121,
		WAVE_FORMAT_SOFTSOUND = 128,
		WAVE_FORMAT_VOXWARE_TQ60 = 129,
		WAVE_FORMAT_MSRT24 = 130,
		WAVE_FORMAT_G729A = 131,
		WAVE_FORMAT_MVI_MVI2 = 132,
		WAVE_FORMAT_DF_G726 = 133,
		WAVE_FORMAT_DF_GSM610 = 134,
		WAVE_FORMAT_ISIAUDIO = 136,
		WAVE_FORMAT_ONLIVE = 137,
		WAVE_FORMAT_SBC24 = 145,
		WAVE_FORMAT_DOLBY_AC3_SPDIF = 146,
		WAVE_FORMAT_MEDIASONIC_G723 = 147,
		WAVE_FORMAT_PROSODY_8KBPS = 148,
		WAVE_FORMAT_ZYXEL_ADPCM = 151,
		WAVE_FORMAT_PHILIPS_LPCBB = 152,
		WAVE_FORMAT_PACKED = 153,
		WAVE_FORMAT_MALDEN_PHONYTALK = 160,
		Gsm = 161,
		G729 = 162,
		G723 = 163,
		Acelp = 164,
		RawAac = 255,
		WAVE_FORMAT_RHETOREX_ADPCM = 256,
		WAVE_FORMAT_IRAT = 257,
		WAVE_FORMAT_VIVO_G723 = 273,
		WAVE_FORMAT_VIVO_SIREN = 274,
		WAVE_FORMAT_DIGITAL_G723 = 291,
		WAVE_FORMAT_SANYO_LD_ADPCM = 293,
		WAVE_FORMAT_SIPROLAB_ACEPLNET = 304,
		WAVE_FORMAT_SIPROLAB_ACELP4800 = 305,
		WAVE_FORMAT_SIPROLAB_ACELP8V3 = 306,
		WAVE_FORMAT_SIPROLAB_G729 = 307,
		WAVE_FORMAT_SIPROLAB_G729A = 308,
		WAVE_FORMAT_SIPROLAB_KELVIN = 309,
		WAVE_FORMAT_G726ADPCM = 320,
		WAVE_FORMAT_QUALCOMM_PUREVOICE = 336,
		WAVE_FORMAT_QUALCOMM_HALFRATE = 337,
		WAVE_FORMAT_TUBGSM = 341,
		WAVE_FORMAT_MSAUDIO1 = 352,
		WindowsMediaAudio = 353,
		WindowsMediaAudioProfessional = 354,
		WindowsMediaAudioLosseless = 355,
		WindowsMediaAudioSpdif = 356,
		WAVE_FORMAT_UNISYS_NAP_ADPCM = 368,
		WAVE_FORMAT_UNISYS_NAP_ULAW = 369,
		WAVE_FORMAT_UNISYS_NAP_ALAW = 370,
		WAVE_FORMAT_UNISYS_NAP_16K = 371,
		WAVE_FORMAT_CREATIVE_ADPCM = 512,
		WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 514,
		WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 515,
		WAVE_FORMAT_UHER_ADPCM = 528,
		WAVE_FORMAT_QUARTERDECK = 544,
		WAVE_FORMAT_ILINK_VC = 560,
		WAVE_FORMAT_RAW_SPORT = 576,
		WAVE_FORMAT_ESST_AC3 = 577,
		WAVE_FORMAT_IPI_HSX = 592,
		WAVE_FORMAT_IPI_RPELP = 593,
		WAVE_FORMAT_CS2 = 608,
		WAVE_FORMAT_SONY_SCX = 624,
		WAVE_FORMAT_FM_TOWNS_SND = 768,
		WAVE_FORMAT_BTV_DIGITAL = 1024,
		WAVE_FORMAT_QDESIGN_MUSIC = 1104,
		WAVE_FORMAT_VME_VMPCM = 1664,
		WAVE_FORMAT_TPC = 1665,
		WAVE_FORMAT_OLIGSM = 4096,
		WAVE_FORMAT_OLIADPCM = 4097,
		WAVE_FORMAT_OLICELP = 4098,
		WAVE_FORMAT_OLISBC = 4099,
		WAVE_FORMAT_OLIOPR = 4100,
		WAVE_FORMAT_LH_CODEC = 4352,
		WAVE_FORMAT_NORRIS = 5120,
		WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = 5376,
		MPEG_ADTS_AAC = 5632,
		MPEG_RAW_AAC = 5633,
		MPEG_LOAS = 5634,
		NOKIA_MPEG_ADTS_AAC = 5640,
		NOKIA_MPEG_RAW_AAC = 5641,
		VODAFONE_MPEG_ADTS_AAC = 5642,
		VODAFONE_MPEG_RAW_AAC = 5643,
		MPEG_HEAAC = 5648,
		WAVE_FORMAT_DVM = 8192,
		Vorbis1 = 26447,
		Vorbis2 = 26448,
		Vorbis3 = 26449,
		Vorbis1P = 26479,
		Vorbis2P = 26480,
		Vorbis3P = 26481,
		WAVE_FORMAT_RAW_AAC1 = 255,
		WAVE_FORMAT_WMAVOICE9 = 10,
		Extensible = -2,
		WAVE_FORMAT_DEVELOPMENT = -1,
		WAVE_FORMAT_FLAC = -3668
	}
	[Flags]
	public enum ChannelMask
	{
		SpeakerFrontLeft = 1,
		SpeakerFrontRight = 2,
		SpeakerFrontCenter = 4,
		SpeakerLowFrequency = 8,
		SpeakerBackLeft = 0x10,
		SpeakerBackRight = 0x20,
		SpeakerFrontLeftOfCenter = 0x40,
		SpeakerFrontRightOfCenter = 0x80,
		SpeakerBackCenter = 0x100,
		SpeakerSideLeft = 0x200,
		SpeakerSideRight = 0x400,
		SpeakerTopCenter = 0x800,
		SpeakerTopFrontLeft = 0x1000,
		SpeakerTopFrontCenter = 0x2000,
		SpeakerTopFrontRight = 0x4000,
		SpeakerTopBackLeft = 0x8000,
		SpeakerTopBackCenter = 0x10000,
		SpeakerTopBackRight = 0x20000
	}
	public static class ChannelMasks
	{
		public const ChannelMask MonoMask = ChannelMask.SpeakerFrontCenter;

		public const ChannelMask StereoMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight;

		public const ChannelMask FiveDotOneWithRearMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight;

		public const ChannelMask FiveDotOneWithSideMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight;

		public const ChannelMask SevenDotOneMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight;
	}
	public static class FluentExtensions
	{
		public static TResult AppendSource<TInput, TResult>(this TInput input, Func<TInput, TResult> func) where TInput : IAudioSource
		{
			return func(input);
		}

		public static TResult AppendSource<TInput, TResult>(this TInput input, Func<TInput, TResult> func, out TResult outputSource) where TInput : IAudioSource
		{
			outputSource = func(input);
			return outputSource;
		}

		public static IWaveSource ChangeSampleRate(this IWaveSource input, int destinationSampleRate)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (destinationSampleRate <= 0)
			{
				throw new ArgumentOutOfRangeException("destinationSampleRate");
			}
			if (input.WaveFormat.SampleRate == destinationSampleRate)
			{
				return input;
			}
			return new DmoResampler(input, destinationSampleRate);
		}

		public static ISampleSource ChangeSampleRate(this ISampleSource input, int destinationSampleRate)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (destinationSampleRate <= 0)
			{
				throw new ArgumentOutOfRangeException("destinationSampleRate");
			}
			if (input.WaveFormat.SampleRate == destinationSampleRate)
			{
				return input;
			}
			return new DmoResampler(input.ToWaveSource(), destinationSampleRate).ToSampleSource();
		}

		public static IWaveSource ToStereo(this IWaveSource input)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (input.WaveFormat.Channels == 2)
			{
				return input;
			}
			if (input.WaveFormat.Channels == 1)
			{
				return new MonoToStereoSource(input.ToSampleSource()).ToWaveSource(input.WaveFormat.BitsPerSample);
			}
			if (input.WaveFormat is WaveFormatExtensible waveFormatExtensible)
			{
				ChannelMask channelMask = waveFormatExtensible.ChannelMask;
				ChannelMatrix matrix = ChannelMatrix.GetMatrix(channelMask, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight);
				return new DmoChannelResampler(input, matrix);
			}
			WaveFormat waveFormat = (WaveFormat)input.WaveFormat.Clone();
			waveFormat.Channels = 2;
			return new DmoResampler(input, waveFormat);
		}

		public static ISampleSource ToStereo(this ISampleSource input)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (input.WaveFormat.Channels == 2)
			{
				return input;
			}
			if (input.WaveFormat.Channels == 1)
			{
				return new MonoToStereoSource(input);
			}
			return input.ToWaveSource().ToStereo().ToSampleSource();
		}

		public static IWaveSource ToMono(this IWaveSource input)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (input.WaveFormat.Channels == 1)
			{
				return input;
			}
			if (input.WaveFormat.Channels == 2)
			{
				return new StereoToMonoSource(input.ToSampleSource()).ToWaveSource(input.WaveFormat.BitsPerSample);
			}
			if (input.WaveFormat is WaveFormatExtensible waveFormatExtensible)
			{
				ChannelMask channelMask = waveFormatExtensible.ChannelMask;
				ChannelMatrix matrix = ChannelMatrix.GetMatrix(channelMask, ChannelMask.SpeakerFrontCenter);
				return new DmoChannelResampler(input, matrix);
			}
			WaveFormat waveFormat = (WaveFormat)input.WaveFormat.Clone();
			waveFormat.Channels = 1;
			return new DmoResampler(input, waveFormat);
		}

		public static ISampleSource ToMono(this ISampleSource input)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (input.WaveFormat.Channels == 1)
			{
				return input;
			}
			if (input.WaveFormat.Channels == 2)
			{
				return new StereoToMonoSource(input);
			}
			return input.ToWaveSource().ToMono().ToSampleSource();
		}

		public static IWaveSource Loop(this IWaveSource input)
		{
			return new LoopStream(input)
			{
				EnableLoop = true
			};
		}

		public static IWaveSource ToWaveSource(this ISampleSource sampleSource, int bits)
		{
			if (sampleSource == null)
			{
				throw new ArgumentNullException("sampleSource");
			}
			return bits switch
			{
				8 => new SampleToPcm8(sampleSource), 
				16 => new SampleToPcm16(sampleSource), 
				24 => new SampleToPcm24(sampleSource), 
				32 => new SampleToIeeeFloat32(sampleSource), 
				_ => throw new ArgumentOutOfRangeException("bits", "Must be 8, 16, 24 or 32 bits."), 
			};
		}

		public static IWaveSource ToWaveSource(this ISampleSource sampleSource)
		{
			if (sampleSource == null)
			{
				throw new ArgumentNullException("sampleSource");
			}
			return new SampleToIeeeFloat32(sampleSource);
		}

		public static ISampleSource ToSampleSource(this IWaveSource waveSource)
		{
			if (waveSource == null)
			{
				throw new ArgumentNullException("waveSource");
			}
			return WaveToSampleBase.CreateConverter(waveSource);
		}

		public static SynchronizedWaveSource<TAudioSource, T> Synchronized<TAudioSource, T>(this TAudioSource audioSource) where TAudioSource : class, IReadableAudioSource<T>
		{
			if (audioSource == null)
			{
				throw new ArgumentNullException("audioSource");
			}
			return new SynchronizedWaveSource<TAudioSource, T>(audioSource);
		}
	}
	public interface IAudioSource : IDisposable
	{
		bool CanSeek { get; }

		WaveFormat WaveFormat { get; }

		long Position { get; set; }

		long Length { get; }
	}
	public interface IWaveSource : IReadableAudioSource<byte>, IAudioSource, IDisposable
	{
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormat : ICloneable, IEquatable<WaveFormat>
	{
		private AudioEncoding _encoding;

		private short _channels;

		private int _sampleRate;

		private int _bytesPerSecond;

		private short _blockAlign;

		private short _bitsPerSample;

		private short _extraSize;

		public virtual int Channels
		{
			get
			{
				return _channels;
			}
			protected internal set
			{
				_channels = (short)value;
				UpdateProperties();
			}
		}

		public virtual int SampleRate
		{
			get
			{
				return _sampleRate;
			}
			protected internal set
			{
				_sampleRate = value;
				UpdateProperties();
			}
		}

		public virtual int BytesPerSecond
		{
			get
			{
				return _bytesPerSecond;
			}
			protected internal set
			{
				_bytesPerSecond = value;
			}
		}

		public virtual int BlockAlign
		{
			get
			{
				return _blockAlign;
			}
			protected internal set
			{
				_blockAlign = (short)value;
			}
		}

		public virtual int BitsPerSample
		{
			get
			{
				return _bitsPerSample;
			}
			protected internal set
			{
				_bitsPerSample = (short)value;
				UpdateProperties();
			}
		}

		public virtual int ExtraSize
		{
			get
			{
				return _extraSize;
			}
			protected internal set
			{
				_extraSize = (short)value;
			}
		}

		public virtual int BytesPerSample => BitsPerSample / 8;

		public virtual int BytesPerBlock => BytesPerSample * Channels;

		public virtual AudioEncoding WaveFormatTag
		{
			get
			{
				return _encoding;
			}
			protected internal set
			{
				_encoding = value;
			}
		}

		public WaveFormat()
			: this(44100, 16, 2)
		{
		}

		public WaveFormat(int sampleRate, int bits, int channels)
			: this(sampleRate, bits, channels, AudioEncoding.Pcm)
		{
		}

		public WaveFormat(int sampleRate, int bits, int channels, AudioEncoding encoding)
			: this(sampleRate, bits, channels, encoding, 0)
		{
		}

		public WaveFormat(int sampleRate, int bits, int channels, AudioEncoding encoding, int extraSize)
		{
			if (sampleRate < 1)
			{
				throw new ArgumentOutOfRangeException("sampleRate");
			}
			if (bits < 0)
			{
				throw new ArgumentOutOfRangeException("bits");
			}
			if (channels < 1)
			{
				throw new ArgumentOutOfRangeException("channels", "Number of channels has to be bigger than 0.");
			}
			_sampleRate = sampleRate;
			_bitsPerSample = (short)bits;
			_channels = (short)channels;
			_encoding = encoding;
			_extraSize = (short)extraSize;
			UpdateProperties();
		}

		public long MillisecondsToBytes(double milliseconds)
		{
			long num = (long)((double)BytesPerSecond / 1000.0 * milliseconds);
			return num - num % BlockAlign;
		}

		public double BytesToMilliseconds(long bytes)
		{
			bytes -= bytes % BlockAlign;
			return (double)bytes / (double)BytesPerSecond * 1000.0;
		}

		public virtual bool Equals(WaveFormat other)
		{
			if (Channels == other.Channels && SampleRate == other.SampleRate && BytesPerSecond == other.BytesPerSecond && BlockAlign == other.BlockAlign && BitsPerSample == other.BitsPerSample && ExtraSize == other.ExtraSize)
			{
				return WaveFormatTag == other.WaveFormatTag;
			}
			return false;
		}

		public override string ToString()
		{
			return GetInformation().ToString();
		}

		public virtual object Clone()
		{
			return MemberwiseClone();
		}

		internal virtual void SetWaveFormatTagInternal(AudioEncoding waveFormatTag)
		{
			WaveFormatTag = waveFormatTag;
		}

		internal virtual void SetBitsPerSampleAndFormatProperties(int bitsPerSample)
		{
			BitsPerSample = bitsPerSample;
			UpdateProperties();
		}

		protected internal virtual void UpdateProperties()
		{
			BlockAlign = BitsPerSample / 8 * Channels;
			BytesPerSecond = BlockAlign * SampleRate;
		}

		[DebuggerStepThrough]
		private StringBuilder GetInformation()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("ChannelsAvailable: " + Channels);
			stringBuilder.Append("|SampleRate: " + SampleRate);
			stringBuilder.Append("|Bps: " + BytesPerSecond);
			stringBuilder.Append("|BlockAlign: " + BlockAlign);
			stringBuilder.Append("|BitsPerSample: " + BitsPerSample);
			stringBuilder.Append("|Encoding: " + _encoding);
			return stringBuilder;
		}
	}
}
namespace CSCore.DSP
{
	public class DmoResampler : WaveAggregatorBase
	{
		internal MediaBuffer InputBuffer;

		internal object LockObj = new object();

		internal DmoOutputDataBuffer OutputBuffer;

		internal WaveFormat Outputformat;

		private readonly bool _ignoreBaseStreamPosition;

		internal decimal Ratio;

		internal WMResampler Resampler;

		private bool _disposed;

		private int _quality = 30;

		private byte[] _readBuffer;

		private long _position;

		public override WaveFormat WaveFormat => Outputformat;

		public override long Position
		{
			get
			{
				if (_ignoreBaseStreamPosition)
				{
					return _position;
				}
				return InputToOutput(base.Position);
			}
			set
			{
				base.Position = OutputToInput(value);
				if (_ignoreBaseStreamPosition)
				{
					_position = InputToOutput(base.Position);
				}
			}
		}

		public override long Length => InputToOutput(base.Length);

		public int Quality
		{
			get
			{
				return _quality;
			}
			set
			{
				if (value < 1 || value > 60)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_quality = value;
				using (Resampler.MediaObject.Lock())
				{
					Resampler.ResamplerProps.SetHalfFilterLength(value);
				}
			}
		}

		private static WaveFormat GetWaveFormatWithChangedSampleRate(IWaveSource source, int destSampleRate)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			WaveFormat waveFormat = (WaveFormat)source.WaveFormat.Clone();
			waveFormat.SampleRate = destSampleRate;
			return waveFormat;
		}

		public DmoResampler(IWaveSource source, int destinationSampleRate)
			: this(source, GetWaveFormatWithChangedSampleRate(source, destinationSampleRate))
		{
		}

		public DmoResampler(IWaveSource source, WaveFormat outputFormat)
			: this(source, outputFormat, ignoreBaseStreamPosition: true)
		{
		}

		public DmoResampler(IWaveSource source, WaveFormat outputFormat, bool ignoreBaseStreamPosition)
			: base(source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (outputFormat == null)
			{
				throw new ArgumentNullException("outputFormat");
			}
			Initialize(source.WaveFormat, outputFormat);
			Outputformat = outputFormat;
			_ignoreBaseStreamPosition = ignoreBaseStreamPosition;
		}

		internal void Initialize(WaveFormat inputformat, WaveFormat outputformat)
		{
			Ratio = (decimal)outputformat.BytesPerSecond / (decimal)inputformat.BytesPerSecond;
			lock (LockObj)
			{
				Resampler = new WMResampler();
				MediaObject mediaObject = Resampler.MediaObject;
				if (!mediaObject.SupportsInputFormat(0, inputformat))
				{
					throw new NotSupportedException("Inputformat not supported.");
				}
				mediaObject.SetInputType(0, inputformat);
				if (!mediaObject.SupportsOutputFormat(0, outputformat))
				{
					throw new NotSupportedException("Outputformat not supported.");
				}
				mediaObject.SetOutputType(0, outputformat);
				InputBuffer = new MediaBuffer(inputformat.BytesPerSecond / 2);
				OutputBuffer = new DmoOutputDataBuffer(outputformat.BytesPerSecond / 2);
			}
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			lock (LockObj)
			{
				int num = 0;
				while (num < count)
				{
					MediaObject mediaObject = Resampler.MediaObject;
					if (mediaObject.IsReadyForInput(0))
					{
						int num2 = (int)OutputToInput(count - num);
						_readBuffer = _readBuffer.CheckBuffer(num2);
						int num3 = base.Read(_readBuffer, 0, num2);
						if (num3 <= 0 || _disposed)
						{
							break;
						}
						if (InputBuffer.MaxLength < num3)
						{
							InputBuffer.Dispose();
							InputBuffer = new MediaBuffer(num3);
						}
						InputBuffer.Write(_readBuffer, 0, num3);
						mediaObject.ProcessInput(0, InputBuffer);
						OutputBuffer.Reset();
						MediaBuffer mediaBuffer = (MediaBuffer)OutputBuffer.Buffer;
						if (mediaBuffer.MaxLength < count)
						{
							mediaBuffer.Dispose();
							OutputBuffer.Buffer = new MediaBuffer(count);
						}
						OutputBuffer.Buffer.SetLength(0);
						mediaObject.ProcessOutput(ProcessOutputFlags.None, new DmoOutputDataBuffer[1] { OutputBuffer }, 1);
						if (OutputBuffer.Length > 0)
						{
							OutputBuffer.Read(buffer, offset + num);
							num += OutputBuffer.Length;
						}
					}
				}
				if (_ignoreBaseStreamPosition)
				{
					_position += num;
				}
				return num;
			}
		}

		internal long InputToOutput(long position)
		{
			long num = (long)((decimal)position * Ratio);
			return num - num % Outputformat.BlockAlign;
		}

		internal long OutputToInput(long position)
		{
			long num = (long)((decimal)position / Ratio);
			return num - num % BaseSource.WaveFormat.BlockAlign;
		}

		public void DisposeResamplerOnly()
		{
			bool disposeBaseSource = base.DisposeBaseSource;
			base.DisposeBaseSource = false;
			Dispose();
			base.DisposeBaseSource = disposeBaseSource;
		}

		protected override void Dispose(bool disposing)
		{
			if (!disposing)
			{
				base.DisposeBaseSource = false;
			}
			base.Dispose(disposing);
			DisposeAndReset(ref Resampler);
			OutputBuffer.Dispose();
			DisposeAndReset(ref InputBuffer);
			_readBuffer = null;
			_disposed = true;
		}

		private void DisposeAndReset<T>(ref T obj) where T : class, IDisposable
		{
			if (obj != null)
			{
				try
				{
					obj.Dispose();
				}
				catch (ObjectDisposedException)
				{
				}
				obj = null;
			}
		}
	}
}
namespace CSCore
{
	public interface ISampleSource : IReadableAudioSource<float>, IAudioSource, IDisposable
	{
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormatExtensible : WaveFormat
	{
		internal const int WaveFormatExtensibleExtraSize = 22;

		private short _samplesUnion;

		private ChannelMask _channelMask;

		private Guid _subFormat;

		public int ValidBitsPerSample
		{
			get
			{
				return _samplesUnion;
			}
			protected internal set
			{
				_samplesUnion = (short)value;
			}
		}

		public int SamplesPerBlock
		{
			get
			{
				return _samplesUnion;
			}
			protected internal set
			{
				_samplesUnion = (short)value;
			}
		}

		public ChannelMask ChannelMask
		{
			get
			{
				return _channelMask;
			}
			protected internal set
			{
				_channelMask = value;
			}
		}

		public Guid SubFormat
		{
			get
			{
				return _subFormat;
			}
			protected internal set
			{
				_subFormat = value;
			}
		}

		public static Guid SubTypeFromWaveFormat(WaveFormat waveFormat)
		{
			if (waveFormat == null)
			{
				throw new ArgumentNullException("waveFormat");
			}
			if (waveFormat is WaveFormatExtensible)
			{
				return ((WaveFormatExtensible)waveFormat).SubFormat;
			}
			return AudioSubTypes.SubTypeFromEncoding(waveFormat.WaveFormatTag);
		}

		internal WaveFormatExtensible()
		{
		}

		public WaveFormatExtensible(int sampleRate, int bits, int channels, Guid subFormat)
			: base(sampleRate, bits, channels, AudioEncoding.Extensible, 22)
		{
			_samplesUnion = (short)bits;
			_subFormat = SubTypeFromWaveFormat(this);
			int num = 0;
			for (int i = 0; i < channels; i++)
			{
				num |= 1 << i;
			}
			_channelMask = (ChannelMask)num;
			_subFormat = subFormat;
		}

		public WaveFormatExtensible(int sampleRate, int bits, int channels, Guid subFormat, ChannelMask channelMask)
			: this(sampleRate, bits, channels, subFormat)
		{
			Array values = Enum.GetValues(typeof(ChannelMask));
			int num = 0;
			for (int i = 0; i < values.Length; i++)
			{
				if ((channelMask & (ChannelMask)values.GetValue(i)) == (ChannelMask)values.GetValue(i))
				{
					num++;
				}
			}
			if (channels != num)
			{
				throw new ArgumentException("Channels has to equal the set flags in the channelmask.");
			}
			_channelMask = channelMask;
		}

		public WaveFormat ToWaveFormat()
		{
			return new WaveFormat(SampleRate, BitsPerSample, Channels, AudioSubTypes.EncodingFromSubType(SubFormat));
		}

		public override object Clone()
		{
			return MemberwiseClone();
		}

		internal override void SetWaveFormatTagInternal(AudioEncoding waveFormatTag)
		{
			SubFormat = AudioSubTypes.SubTypeFromEncoding(waveFormatTag);
		}

		[DebuggerStepThrough]
		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder(base.ToString());
			stringBuilder.Append("|SubFormat: " + SubFormat);
			stringBuilder.Append("|ChannelMask: " + ChannelMask);
			return stringBuilder.ToString();
		}
	}
}
namespace CSCore.DSP
{
	public class ChannelMatrix
	{
		private static class Factory
		{
			private class FactoryEntry
			{
				public ChannelMask Input { get; set; }

				public ChannelMask Output { get; set; }

				public ChannelMatrix Matrix { get; set; }

				public FactoryEntry(ChannelMask input, ChannelMask output, ChannelMatrix matrix)
				{
					Input = input;
					Output = output;
					Matrix = matrix;
				}
			}

			private static readonly FactoryEntry[] FactoryEntries = new FactoryEntry[18]
			{
				new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, MonoToStereoMatrix),
				new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, MonoToFiveDotOneSurroundWithRear),
				new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, MonoToFiveDotOneSurroundWithSide),
				new FactoryEntry(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, MonoToSevenDotOneSurround),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontCenter, StereoToMonoMatrix),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, StereoToFiveDotOneSurroundWithRear),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, StereoToFiveDotOneSurroundWithSide),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, StereoToSevenDotOneSurround),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontCenter, FiveDotOneSurroundWithRearToMono),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, FiveDotOneSurroundWithRearToStereo),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, FiveDotOneSurroundWithRearToSevenDotOne),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontCenter, FiveDotOneSurroundWithSideToMono),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, FiveDotOneSurroundWithSideToStereo),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, FiveDotOneSurroundWithSideToSevenDotOne),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontCenter, SevenDotOneSurroundToMono),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, SevenDotOneSurroundToStereo),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, SevenDotOneSurroundToFiveDotOneSurroundWithRear),
				new FactoryEntry(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, SevenDotOneSurroundToFiveDotOneSurroundWithSide)
			};

			public static ChannelMatrix GetMatrix(ChannelMask from, ChannelMask to)
			{
				if (from == to)
				{
					throw new ArgumentException("from must not equal to.");
				}
				FactoryEntry factoryEntry = FactoryEntries.FirstOrDefault((FactoryEntry x) => x.Input == from && x.Output == to);
				if (factoryEntry == null)
				{
					throw new KeyNotFoundException("Could not find a channel matrix for specified channelmasks.");
				}
				return factoryEntry.Matrix;
			}
		}

		public static readonly ChannelMatrix StereoToFiveDotOneSurroundWithRear;

		public static readonly ChannelMatrix FiveDotOneSurroundWithRearToStereo;

		public static readonly ChannelMatrix StereoToFiveDotOneSurroundWithSide;

		public static readonly ChannelMatrix FiveDotOneSurroundWithSideToStereo;

		public static readonly ChannelMatrix StereoToSevenDotOneSurround;

		public static readonly ChannelMatrix SevenDotOneSurroundToStereo;

		public static readonly ChannelMatrix MonoToFiveDotOneSurroundWithRear;

		public static readonly ChannelMatrix FiveDotOneSurroundWithRearToMono;

		public static readonly ChannelMatrix MonoToFiveDotOneSurroundWithSide;

		public static readonly ChannelMatrix FiveDotOneSurroundWithSideToMono;

		public static readonly ChannelMatrix MonoToSevenDotOneSurround;

		public static readonly ChannelMatrix SevenDotOneSurroundToMono;

		public static readonly ChannelMatrix StereoToMonoMatrix;

		public static readonly ChannelMatrix MonoToStereoMatrix;

		public static readonly ChannelMatrix FiveDotOneSurroundWithRearToSevenDotOne;

		public static readonly ChannelMatrix SevenDotOneSurroundToFiveDotOneSurroundWithRear;

		public static readonly ChannelMatrix FiveDotOneSurroundWithSideToSevenDotOne;

		public static readonly ChannelMatrix SevenDotOneSurroundToFiveDotOneSurroundWithSide;

		private readonly ChannelMask _inputMask;

		private readonly ChannelMatrixElement[,] _matrix;

		private readonly ChannelMask _outputMask;

		public ChannelMask InputMask => _inputMask;

		public ChannelMask OutputMask => _outputMask;

		public int Height => _matrix.GetLength(0);

		public int Width => _matrix.GetLength(1);

		public int InputChannelCount => Height;

		public int OutputChannelCount => Width;

		public ChannelMatrixElement this[int input, int output]
		{
			get
			{
				return _matrix[input, output];
			}
			set
			{
				_matrix[input, output] = value;
			}
		}

		public static ChannelMatrix GetMatrix(ChannelMask from, ChannelMask to)
		{
			return Factory.GetMatrix(from, to);
		}

		public static ChannelMatrix GetMatrix(WaveFormat from, WaveFormat to)
		{
			if (from == null)
			{
				throw new ArgumentNullException("from");
			}
			if (to == null)
			{
				throw new ArgumentNullException("to");
			}
			if (TryExtractChannelMask(from, out var channelMask) && TryExtractChannelMask(to, out var channelMask2))
			{
				return GetMatrix(channelMask, channelMask2);
			}
			return null;
		}

		private static bool TryExtractChannelMask(WaveFormat waveFormat, out ChannelMask channelMask)
		{
			channelMask = (ChannelMask)0;
			if (waveFormat is WaveFormatExtensible waveFormatExtensible)
			{
				channelMask = waveFormatExtensible.ChannelMask;
			}
			else if (waveFormat.Channels == 1)
			{
				channelMask = ChannelMask.SpeakerFrontCenter;
			}
			else
			{
				if (waveFormat.Channels != 2)
				{
					return false;
				}
				channelMask = ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight;
			}
			return true;
		}

		internal WaveFormat BuildOutputWaveFormat(IAudioSource audioSource)
		{
			if (audioSource == null)
			{
				throw new ArgumentNullException("source");
			}
			return new WaveFormatExtensible(audioSource.WaveFormat.SampleRate, audioSource.WaveFormat.BitsPerSample, OutputChannelCount, WaveFormatExtensible.SubTypeFromWaveFormat(audioSource.WaveFormat), OutputMask);
		}

		static ChannelMatrix()
		{
			StereoToFiveDotOneSurroundWithRear = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
			StereoToFiveDotOneSurroundWithRear.SetMatrix(new float[2, 6]
			{
				{ 0.314f, 0f, 0.222f, 0.031f, 0.268f, 0.164f },
				{ 0f, 0.314f, 0.222f, 0.031f, 0.164f, 0.268f }
			});
			FiveDotOneSurroundWithRearToStereo = StereoToFiveDotOneSurroundWithRear.Flip();
			StereoToFiveDotOneSurroundWithSide = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
			StereoToFiveDotOneSurroundWithSide.SetMatrix(new float[2, 6]
			{
				{ 0.32f, 0f, 0.226f, 0.032f, 0.292f, 0.13f },
				{ 0f, 0.32f, 0.226f, 0.032f, 0.13f, 0.292f }
			});
			FiveDotOneSurroundWithSideToStereo = StereoToFiveDotOneSurroundWithSide.Flip();
			StereoToSevenDotOneSurround = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
			StereoToSevenDotOneSurround.SetMatrix(new float[2, 8]
			{
				{ 0.222f, 0f, 0.157f, 0.022f, 0.189f, 0.116f, 0.203f, 0.09f },
				{ 0f, 0.222f, 0.157f, 0.022f, 0.116f, 0.189f, 0.09f, 0.203f }
			});
			SevenDotOneSurroundToStereo = StereoToSevenDotOneSurround.Flip();
			MonoToFiveDotOneSurroundWithRear = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight);
			MonoToFiveDotOneSurroundWithRear.SetMatrix(new float[1, 6] { { 0.192f, 0.192f, 0.192f, 0.038f, 0.192f, 0.192f } });
			FiveDotOneSurroundWithRearToMono = MonoToFiveDotOneSurroundWithRear.Flip();
			MonoToFiveDotOneSurroundWithSide = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
			MonoToFiveDotOneSurroundWithSide.SetMatrix(new float[1, 6] { { 0.192f, 0.192f, 0.192f, 0.038f, 0.192f, 0.192f } });
			FiveDotOneSurroundWithSideToMono = MonoToFiveDotOneSurroundWithSide.Flip();
			MonoToSevenDotOneSurround = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
			MonoToSevenDotOneSurround.SetMatrix(new float[1, 8] { { 0.139f, 0.139f, 0.139f, 0.028f, 0.139f, 0.139f, 0.139f, 0.139f } });
			SevenDotOneSurroundToMono = MonoToSevenDotOneSurround.Flip();
			FiveDotOneSurroundWithRearToSevenDotOne = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
			FiveDotOneSurroundWithRearToSevenDotOne.SetMatrix(new float[6, 8]
			{
				{ 0.518f, 0f, 0f, 0f, 0f, 0f, 0.189f, 0f },
				{ 0f, 0.518f, 0f, 0f, 0f, 0f, 0f, 0.189f },
				{ 0f, 0f, 0.518f, 0f, 0f, 0f, 0f, 0f },
				{ 0f, 0f, 0f, 0.518f, 0f, 0f, 0f, 0f },
				{ 0f, 0f, 0f, 0f, 0.518f, 0f, 0.482f, 0f },
				{ 0f, 0f, 0f, 0f, 0f, 0.518f, 0f, 0.482f }
			});
			SevenDotOneSurroundToFiveDotOneSurroundWithRear = FiveDotOneSurroundWithRearToSevenDotOne.Flip();
			FiveDotOneSurroundWithSideToSevenDotOne = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight | ChannelMask.SpeakerFrontCenter | ChannelMask.SpeakerLowFrequency | ChannelMask.SpeakerBackLeft | ChannelMask.SpeakerBackRight | ChannelMask.SpeakerSideLeft | ChannelMask.SpeakerSideRight);
			FiveDotOneSurroundWithSideToSevenDotOne.SetMatrix(new float[6, 8]
			{
				{ 0.447f, 0f, 0f, 0f, 0f, 0f, 0f, 0f },
				{ 0f, 0.447f, 0f, 0f, 0f, 0f, 0f, 0f },
				{ 0f, 0f, 0.447f, 0f, 0f, 0f, 0f, 0f },
				{ 0f, 0f, 0f, 0.447f, 0f, 0f, 0f, 0f },
				{ 0f, 0f, 0f, 0f, 0.429f, 0.124f, 0.447f, 0f },
				{ 0f, 0f, 0f, 0f, 0.124f, 0.429f, 0f, 0.447f }
			});
			SevenDotOneSurroundToFiveDotOneSurroundWithSide = FiveDotOneSurroundWithSideToSevenDotOne.Flip();
			StereoToMonoMatrix = new ChannelMatrix(ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight, ChannelMask.SpeakerFrontCenter);
			StereoToMonoMatrix.SetMatrix(new float[2, 1]
			{
				{ 0.5f },
				{ 0.5f }
			});
			MonoToStereoMatrix = new ChannelMatrix(ChannelMask.SpeakerFrontCenter, ChannelMask.SpeakerFrontLeft | ChannelMask.SpeakerFrontRight);
			MonoToStereoMatrix.SetMatrix(new float[1, 2] { { 1f, 1f } });
		}

		public ChannelMatrix(ChannelMask inputMask, ChannelMask outputMask)
		{
			_inputMask = inputMask;
			_outputMask = outputMask;
			if (inputMask <= (ChannelMask)0)
			{
				throw new ArgumentException("Invalid inputMask");
			}
			if (outputMask <= (ChannelMask)0)
			{
				throw new ArgumentException("Invalid outputMask");
			}
			_matrix = new ChannelMatrixElement[GetValuesOfChannelMask(inputMask).Length, GetValuesOfChannelMask(outputMask).Length];
			for (int i = 0; i < Width; i++)
			{
				for (int j = 0; j < Height; j++)
				{
					_matrix[j, i] = new ChannelMatrixElement(GetValuesOfChannelMask(inputMask)[j], GetValuesOfChannelMask(outputMask)[i]);
				}
			}
		}

		public void SetMatrix(float[,] matrix)
		{
			if (matrix == null)
			{
				throw new ArgumentException("matrix");
			}
			if (matrix.GetLength(1) != Width)
			{
				throw new ArgumentException("Matrix has to have a width of " + Width);
			}
			if (matrix.GetLength(0) != Height)
			{
				throw new ArgumentException("Matrix has to have a height of " + Height);
			}
			for (int i = 0; i < Width; i++)
			{
				for (int j = 0; j < Height; j++)
				{
					this[j, i].Value = matrix[j, i];
				}
			}
		}

		public float[] GetOneDimensionalMatrix()
		{
			List<float> list = new List<float>();
			for (int i = 0; i < Width; i++)
			{
				for (int j = 0; j < Height; j++)
				{
					list.Add(this[j, i].Value);
				}
			}
			return list.ToArray();
		}

		public ChannelMatrix Flip()
		{
			ChannelMatrix channelMatrix = new ChannelMatrix(OutputMask, InputMask);
			for (int i = 0; i < OutputChannelCount; i++)
			{
				for (int j = 0; j < InputChannelCount; j++)
				{
					ChannelMatrixElement channelMatrixElement = this[j, i];
					channelMatrix[i, j] = new ChannelMatrixElement(channelMatrixElement.OutputChannel, channelMatrixElement.InputChannel)
					{
						Value = channelMatrixElement.Value
					};
				}
			}
			return channelMatrix;
		}

		private static ChannelMask[] GetValuesOfChannelMask(ChannelMask channelMask)
		{
			Array values = Enum.GetValues(typeof(ChannelMask));
			List<ChannelMask> list = new List<ChannelMask>();
			for (int i = 0; i < values.Length; i++)
			{
				if ((channelMask & (ChannelMask)values.GetValue(i)) == (ChannelMask)values.GetValue(i))
				{
					list.Add((ChannelMask)values.GetValue(i));
				}
			}
			return list.ToArray();
		}
	}
}
namespace CSCore.Streams
{
	public sealed class MonoToStereoSource : SampleAggregatorBase
	{
		private float[] _buffer;

		private readonly WaveFormat _waveFormat;

		public override long Position
		{
			get
			{
				return base.Position * 2;
			}
			set
			{
				value -= value % WaveFormat.BlockAlign;
				base.Position = value / 2;
			}
		}

		public override long Length => base.Length * 2;

		public override WaveFormat WaveFormat => _waveFormat;

		public MonoToStereoSource(ISampleSource source)
			: base(source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (source.WaveFormat.Channels != 1)
			{
				throw new ArgumentException("The WaveFormat of the source has be a mono format (one channel).", "source");
			}
			_waveFormat = new WaveFormat(source.WaveFormat.SampleRate, 32, 2, AudioEncoding.IeeeFloat);
		}

		public override int Read(float[] buffer, int offset, int count)
		{
			int num = count / 2;
			_buffer = _buffer.CheckBuffer(num);
			int num2 = offset;
			int num3 = base.Read(_buffer, 0, num);
			for (int i = 0; i < num3; i++)
			{
				buffer[num2++] = _buffer[i];
				buffer[num2++] = _buffer[i];
			}
			return num3 * 2;
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			_buffer = null;
		}
	}
}
namespace CSCore.DSP
{
	public class DmoChannelResampler : DmoResampler
	{
		private readonly ChannelMatrix _channelMatrix;

		public ChannelMatrix ChannelMatrix => _channelMatrix;

		public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix)
			: this(source, channelMatrix, source.WaveFormat.SampleRate)
		{
		}

		public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix, WaveFormat outputFormat)
			: base(source, outputFormat)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (channelMatrix == null)
			{
				throw new ArgumentNullException("channelMatrix");
			}
			if (outputFormat == null)
			{
				throw new ArgumentNullException("outputFormat");
			}
			if (source.WaveFormat.Channels != channelMatrix.InputChannelCount)
			{
				throw new ArgumentException("The number of channels of the source has to be equal to the number of input channels specified by the channelMatrix.");
			}
			WaveFormatExtensible inputformat = new WaveFormatExtensible(source.WaveFormat.SampleRate, source.WaveFormat.BitsPerSample, source.WaveFormat.Channels, WaveFormatExtensible.SubTypeFromWaveFormat(source.WaveFormat), channelMatrix.InputMask);
			Outputformat = new WaveFormatExtensible(outputFormat.SampleRate, outputFormat.BitsPerSample, outputFormat.Channels, WaveFormatExtensible.SubTypeFromWaveFormat(outputFormat), channelMatrix.OutputMask);
			Initialize(inputformat, Outputformat);
			_channelMatrix = channelMatrix;
			CommitChannelMatrixChanges();
		}

		public DmoChannelResampler(IWaveSource source, ChannelMatrix channelMatrix, int destinationSampleRate)
			: this(source, channelMatrix, GetOutputWaveFormat(source, destinationSampleRate, channelMatrix))
		{
		}

		private static WaveFormat GetOutputWaveFormat(IWaveSource source, int sampleRate, ChannelMatrix channelMatrix)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (channelMatrix == null)
			{
				throw new ArgumentNullException("channelMatrix");
			}
			WaveFormat waveFormat = channelMatrix.BuildOutputWaveFormat(source);
			waveFormat.SampleRate = sampleRate;
			return waveFormat;
		}

		public void CommitChannelMatrixChanges()
		{
			using (Resampler.MediaObject.Lock())
			{
				Resampler.MediaObject.SetOutputType(0, Resampler.MediaObject.GetOutputCurrentType(0), SetTypeFlags.None);
				Resampler.ResamplerProps.SetUserChannelMtx(_channelMatrix.GetOneDimensionalMatrix());
			}
		}
	}
}
namespace CSCore.Streams
{
	public class StereoToMonoSource : SampleAggregatorBase
	{
		private readonly WaveFormat _waveFormat;

		private float[] _buffer;

		public override long Position
		{
			get
			{
				return BaseSource.Position / 2;
			}
			set
			{
				value -= value % WaveFormat.BlockAlign;
				BaseSource.Position = value * 2;
			}
		}

		public override long Length => BaseSource.Length / 2;

		public override WaveFormat WaveFormat => _waveFormat;

		public StereoToMonoSource(ISampleSource source)
			: base(source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (source.WaveFormat.Channels != 2)
			{
				throw new ArgumentException("The WaveFormat of the source has be a stereo format (two channels).", "source");
			}
			_waveFormat = new WaveFormat(source.WaveFormat.SampleRate, 32, 1, AudioEncoding.IeeeFloat);
		}

		public unsafe override int Read(float[] buffer, int offset, int count)
		{
			_buffer = _buffer.CheckBuffer(count * 2);
			int num = BaseSource.Read(_buffer, 0, count * 2);
			fixed (float* ptr = buffer)
			{
				float* ptr2 = ptr + offset;
				for (int i = 0; i < num - 1; i += 2)
				{
					*(ptr2++) = (_buffer[i] + _buffer[i + 1]) / 2f;
				}
			}
			return num / 2;
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			_buffer = null;
		}
	}
	public class LoopStream : WaveAggregatorBase
	{
		private bool _enableLoop = true;

		private bool _raisedStreamFinishedEvent;

		public bool EnableLoop
		{
			get
			{
				return _enableLoop;
			}
			set
			{
				_enableLoop = value;
			}
		}

		public event EventHandler StreamFinished;

		public LoopStream(IWaveSource source)
			: base(source)
		{
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			int i;
			int num;
			for (i = base.Read(buffer, offset, count); i < count; i += num)
			{
				num = base.Read(buffer, offset + i, count - i);
				if (num == 0)
				{
					EventHandler streamFinished = this.StreamFinished;
					if (streamFinished != null && !_raisedStreamFinishedEvent)
					{
						streamFinished(this, EventArgs.Empty);
						_raisedStreamFinishedEvent = true;
					}
					if (!EnableLoop)
					{
						break;
					}
					Position = 0L;
				}
				else
				{
					_raisedStreamFinishedEvent = false;
				}
			}
			return i;
		}
	}
}
namespace CSCore.Streams.SampleConverter
{
	public class SampleToPcm8 : SampleToWaveBase
	{
		public SampleToPcm8(ISampleSource source)
			: base(source, 8, AudioEncoding.Pcm)
		{
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			Buffer = Buffer.CheckBuffer(count);
			int num = Source.Read(Buffer, 0, count);
			for (int i = offset; i < num; i++)
			{
				byte b = (byte)((Buffer[i] + 1f) * 128f);
				buffer[i] = b;
			}
			return num;
		}
	}
	public class SampleToPcm16 : SampleToWaveBase
	{
		public SampleToPcm16(ISampleSource source)
			: base(source, 16, AudioEncoding.Pcm)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			Buffer = Buffer.CheckBuffer(count / 2);
			int num = Source.Read(Buffer, 0, count / 2);
			int num2 = offset;
			for (int i = 0; i < num; i++)
			{
				short value = (short)(Buffer[i] * 32767f);
				byte[] bytes = BitConverter.GetBytes(value);
				buffer[num2++] = bytes[0];
				buffer[num2++] = bytes[1];
			}
			return num * 2;
		}
	}
	public class SampleToPcm24 : SampleToWaveBase
	{
		public SampleToPcm24(ISampleSource source)
			: base(source, 24, AudioEncoding.Pcm)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
		}

		public unsafe override int Read(byte[] buffer, int offset, int count)
		{
			int num = count / 3;
			Buffer = Buffer.CheckBuffer(num);
			int num2 = Source.Read(Buffer, 0, num);
			int num3 = offset;
			for (int i = 0; i < num2; i++)
			{
				uint num4 = (uint)(Buffer[i] * 8388608f);
				byte* ptr = (byte*)(&num4);
				buffer[num3++] = *ptr;
				buffer[num3++] = ptr[1];
				buffer[num3++] = ptr[2];
			}
			return num2 * 3;
		}
	}
	public class SampleToIeeeFloat32 : SampleToWaveBase
	{
		public SampleToIeeeFloat32(ISampleSource source)
			: base(source, 32, AudioEncoding.IeeeFloat)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			Buffer = Buffer.CheckBuffer(count / 4);
			int num = Source.Read(Buffer, offset / 4, count / 4);
			System.Buffer.BlockCopy(Buffer, 0, buffer, offset, num * 4);
			return num * 4;
		}
	}
	public abstract class WaveToSampleBase : ISampleSource, IReadableAudioSource<float>, IAudioSource, IDisposable
	{
		private readonly WaveFormat _waveFormat;

		protected internal IWaveSource Source;

		protected internal byte[] Buffer;

		public WaveFormat WaveFormat => _waveFormat;

		public long Position
		{
			get
			{
				if (!CanSeek)
				{
					return 0L;
				}
				return Source.Position / Source.WaveFormat.BytesPerSample;
			}
			set
			{
				if (CanSeek)
				{
					value -= value % WaveFormat.BlockAlign;
					Source.Position = value * Source.WaveFormat.BytesPerSample;
					return;
				}
				throw new InvalidOperationException();
			}
		}

		public long Length
		{
			get
			{
				if (!CanSeek || Source.Length == 0L)
				{
					return 0L;
				}
				return Source.Length / Source.WaveFormat.BytesPerSample;
			}
		}

		public bool CanSeek => Source.CanSeek;

		protected WaveToSampleBase(IWaveSource source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			Source = source;
			_waveFormat = (WaveFormat)source.WaveFormat.Clone();
			_waveFormat.BitsPerSample = 32;
			_waveFormat.SetWaveFormatTagInternal(AudioEncoding.IeeeFloat);
		}

		public abstract int Read(float[] buffer, int offset, int count);

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (Source != null)
			{
				Source.Dispose();
				Source = null;
			}
		}

		~WaveToSampleBase()
		{
			Dispose(disposing: false);
		}

		public static ISampleSource CreateConverter(IWaveSource source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			int bitsPerSample = source.WaveFormat.BitsPerSample;
			if (source.WaveFormat.IsPCM())
			{
				return bitsPerSample switch
				{
					8 => new Pcm8BitToSample(source), 
					16 => new Pcm16BitToSample(source), 
					24 => new Pcm24BitToSample(source), 
					32 => new Pcm32BitToSample(source), 
					_ => throw new NotSupportedException("Waveformat is not supported. Invalid BitsPerSample value."), 
				};
			}
			if (source.WaveFormat.IsIeeeFloat() && bitsPerSample == 32)
			{
				return new IeeeFloatToSample(source);
			}
			throw new NotSupportedException("Waveformat is not supported. Invalid WaveformatTag.");
		}
	}
}
namespace CSCore.Streams
{
	public class SynchronizedWaveSource<TBaseSource, T> : IAggregator<T, TBaseSource>, IReadableAudioSource<T>, IAudioSource, IDisposable where TBaseSource : class, IReadableAudioSource<T>
	{
		private readonly object _lockObj = new object();

		private TBaseSource _baseSource;

		private bool _disposed;

		public WaveFormat WaveFormat
		{
			get
			{
				lock (_lockObj)
				{
					return BaseSource.WaveFormat;
				}
			}
		}

		public long Position
		{
			get
			{
				lock (_lockObj)
				{
					return BaseSource.Position;
				}
			}
			set
			{
				lock (_lockObj)
				{
					value -= value % WaveFormat.BlockAlign;
					BaseSource.Position = value;
				}
			}
		}

		public long Length
		{
			get
			{
				lock (_lockObj)
				{
					return BaseSource.Length;
				}
			}
		}

		public bool CanSeek
		{
			get
			{
				lock (_lockObj)
				{
					return BaseSource.CanSeek;
				}
			}
		}

		public TBaseSource BaseSource
		{
			get
			{
				lock (_lockObj)
				{
					return _baseSource;
				}
			}
			set
			{
				lock (_lockObj)
				{
					if (value == null)
					{
						throw new ArgumentNullException("value");
					}
					_baseSource = value;
				}
			}
		}

		public SynchronizedWaveSource(TBaseSource baseWaveSource)
		{
			BaseSource = baseWaveSource;
		}

		public int Read(T[] buffer, int offset, int count)
		{
			lock (_lockObj)
			{
				return BaseSource.Read(buffer, offset, count);
			}
		}

		public static explicit operator TBaseSource(SynchronizedWaveSource<TBaseSource, T> synchronizedWaveSource)
		{
			if (synchronizedWaveSource == null)
			{
				throw new ArgumentNullException("synchronizedWaveSource");
			}
			return synchronizedWaveSource.BaseSource;
		}

		protected void Dispose(bool disposing)
		{
			lock (_lockObj)
			{
				if (BaseSource != null)
				{
					BaseSource.Dispose();
				}
				_baseSource = null;
			}
		}

		public void Dispose()
		{
			lock (_lockObj)
			{
				if (!_disposed)
				{
					_disposed = true;
					Dispose(disposing: true);
					GC.SuppressFinalize(this);
				}
			}
		}

		~SynchronizedWaveSource()
		{
			lock (_lockObj)
			{
				Dispose(disposing: false);
			}
		}
	}
}
namespace CSCore
{
	public interface IReadableAudioSource<in T> : IAudioSource, IDisposable
	{
		int Read(T[] buffer, int offset, int count);
	}
	public interface IWriteable
	{
		void Write(byte[] buffer, int offset, int count);
	}
	public enum MmResult
	{
		NoError = 0,
		Error = 1,
		BadDevice = 2,
		NotEnabled = 3,
		Allocated = 4,
		InvalidHandle = 5,
		NoDriver = 6,
		NoMemory = 7,
		NotSupported = 8,
		BadErrorNumber = 9,
		InvalidFlag = 10,
		InvalidParameter = 11,
		HandleBusy = 12,
		InvalidAlias = 13,
		BadDatabase = 14,
		KeyNotFound = 15,
		ReadError = 16,
		WriteError = 17,
		DeleteError = 18,
		ValueNotFound = 19,
		NoDriverCallback = 20,
		MoreData = 21,
		BadFormat = 32,
		StillPlaying = 33,
		Unprepared = 34,
		Synchronous = 35
	}
	public class StoppedEventArgs : EventArgs
	{
		private readonly Exception _exception;

		public virtual bool HasError => _exception != null;

		public virtual Exception Exception => _exception;

		public StoppedEventArgs()
			: this(null)
		{
		}

		public StoppedEventArgs(Exception exception)
		{
			_exception = exception;
		}
	}
	public abstract class TimeConverter
	{
		internal class _WaveSourceTimeConverter : TimeConverter
		{
			public override long ToRawElements(WaveFormat waveFormat, TimeSpan timeSpan)
			{
				return waveFormat.MillisecondsToBytes(timeSpan.TotalMilliseconds);
			}

			public override TimeSpan ToTimeSpan(WaveFormat waveFormat, long rawElements)
			{
				return TimeSpan.FromMilliseconds(waveFormat.BytesToMilliseconds(rawElements));
			}
		}

		internal class _SampleSourceTimeConverter : TimeConverter
		{
			public override long ToRawElements(WaveFormat waveFormat, TimeSpan timeSpan)
			{
				return waveFormat.MillisecondsToBytes(timeSpan.TotalMilliseconds) / waveFormat.BytesPerSample;
			}

			public override TimeSpan ToTimeSpan(WaveFormat waveFormat, long rawElements)
			{
				return TimeSpan.FromMilliseconds(waveFormat.BytesToMilliseconds(rawElements * waveFormat.BytesPerSample));
			}
		}

		public static readonly TimeConverter SampleSourceTimeConverter = new _SampleSourceTimeConverter();

		public static readonly TimeConverter WaveSourceTimeConverter = new _WaveSourceTimeConverter();

		public abstract long ToRawElements(WaveFormat waveFormat, TimeSpan timeSpan);

		public abstract TimeSpan ToTimeSpan(WaveFormat waveFormat, long rawElements);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class TimeConverterAttribute : Attribute
	{
		public Type TimeConverterType { get; private set; }

		public object[] Args { get; set; }

		public bool ForceNewInstance { get; set; }

		public TimeConverterAttribute(Type timeConverterType)
		{
			if ((object)timeConverterType == null)
			{
				throw new ArgumentNullException("timeConverterType");
			}
			if (!typeof(TimeConverter).IsAssignableFrom(timeConverterType))
			{
				throw new ArgumentException("Specified type is no time converter.", "timeConverterType");
			}
			TimeConverterType = timeConverterType;
		}
	}
	public sealed class TimeConverterFactory
	{
		private class CacheItem
		{
			public TimeConverter TimeConverter { get; set; }

			public TimeConverterAttribute TimeConverterAttribute { get; set; }

			public bool CreateNewInstance { get; set; }

			public TimeConverter GetTimeConverter()
			{
				if (CreateNewInstance)
				{
					return (TimeConverter)Activator.CreateInstance(TimeConverterAttribute.TimeConverterType, TimeConverterAttribute.Args);
				}
				return TimeConverter;
			}
		}

		private static readonly TimeConverterFactory _instance = new TimeConverterFactory();

		private readonly Dictionary<Type, TimeConverter> _timeConverters;

		private readonly Dictionary<Type, CacheItem> _cache;

		public static TimeConverterFactory Instance => _instance;

		private TimeConverterFactory()
		{
			_timeConverters = new Dictionary<Type, TimeConverter>();
			_cache = new Dictionary<Type, CacheItem>();
			RegisterTimeConverterForSourceType<IWaveSource>(TimeConverter.WaveSourceTimeConverter);
			RegisterTimeConverterForSourceType<ISampleSource>(TimeConverter.SampleSourceTimeConverter);
		}

		public void RegisterTimeConverterForSourceType<TSource>(TimeConverter timeConverter) where TSource : IAudioSource
		{
			if (timeConverter == null)
			{
				throw new ArgumentNullException("timeConverter");
			}
			Type typeFromHandle = typeof(TSource);
			if (_timeConverters.ContainsKey(typeFromHandle))
			{
				throw new ArgumentException("A timeconverter for the same source type got already registered.");
			}
			_timeConverters.Add(typeFromHandle, timeConverter);
		}

		public void UnregisterTimeConverter<TSource>() where TSource : IAudioSource
		{
			Type typeFromHandle = typeof(TSource);
			if (!_timeConverters.ContainsKey(typeFromHandle))
			{
				throw new ArgumentException("There is no timeconverter registered for the specified source type.");
			}
			_timeConverters.Remove(typeFromHandle);
		}

		public TimeConverter GetTimeConverterForSource<TSource>(TSource source) where TSource : class, IAudioSource
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return GetTimeConverterForSourceType(source.GetType());
		}

		public TimeConverter GetTimeConverterForSource<TSource>() where TSource : IAudioSource
		{
			return GetTimeConverterForSourceType(typeof(TSource));
		}

		public TimeConverter GetTimeConverterForSourceType(Type sourceType)
		{
			if ((object)sourceType == null)
			{
				throw new ArgumentNullException("sourceType");
			}
			if (!typeof(IAudioSource).IsAssignableFrom(sourceType))
			{
				throw new ArgumentException("Specified type is no AudioSource.", "sourceType");
			}
			if (_cache.ContainsKey(sourceType))
			{
				return _cache[sourceType].GetTimeConverter();
			}
			TimeConverterAttribute timeConverterAttribute = sourceType.GetCustomAttributes(typeof(TimeConverterAttribute), inherit: false).FirstOrDefault() as TimeConverterAttribute;
			TimeConverter timeConverter = null;
			try
			{
				if (timeConverterAttribute == null)
				{
					Type[] array = (from x in GetTypes(sourceType)
						where _timeConverters.ContainsKey(x)
						select x).ToArray();
					if (array.Length == 1)
					{
						timeConverter = _timeConverters[array.First()];
						return timeConverter;
					}
					if (array.Length == 0)
					{
						throw new ArgumentException("No registered time converter for the specified source type was found.");
					}
					throw new ArgumentException("Multiple possible time converters, for the specified source type, were found. Specify which time converter to use, through the TimeConverterAttribute.");
				}
				Type timeConverterType = timeConverterAttribute.TimeConverterType;
				timeConverter = (TimeConverter)Activator.CreateInstance(timeConverterType, timeConverterAttribute.Args);
				return timeConverter;
			}
			finally
			{
				if (timeConverter != null)
				{
					CacheItem value = ((timeConverterAttribute != null) ? new CacheItem
					{
						CreateNewInstance = timeConverterAttribute.ForceNewInstance,
						TimeConverterAttribute = timeConverterAttribute,
						TimeConverter = (timeConverterAttribute.ForceNewInstance ? null : timeConverter)
					} : new CacheItem
					{
						CreateNewInstance = false,
						TimeConverter = timeConverter
					});
					_cache[sourceType] = value;
				}
			}
		}

		public void ClearCache()
		{
			_cache.Clear();
		}

		private IEnumerable<Type> GetTypes(Type type)
		{
			if ((object)type.BaseType != typeof(object))
			{
				return Enumerable.Repeat(type.BaseType, 1).Concat<Type>(type.GetInterfaces()).Concat(GetTypes(type.BaseType))
					.Distinct();
			}
			return type.GetInterfaces();
		}
	}
	public interface ISampleAggregator : ISampleSource, IReadableAudioSource<float>, IAudioSource, IDisposable, IAggregator<float, ISampleSource>
	{
	}
	public interface IAggregator<in T, out TAggregator> : IReadableAudioSource<T>, IAudioSource, IDisposable where TAggregator : IReadableAudioSource<T>
	{
		TAggregator BaseSource { get; }
	}
	public interface IWaveAggregator : IWaveSource, IReadableAudioSource<byte>, IAudioSource, IDisposable, IAggregator<byte, IWaveSource>
	{
	}
	[Serializable]
	public class MmException : Exception
	{
		public MmResult Result { get; private set; }

		[Obsolete("Use the Function property instead.")]
		public string Target { get; private set; }

		public string Function => Target;

		public static void Try(MmResult result, string function)
		{
			if (result != 0)
			{
				throw new MmException(result, function);
			}
		}

		public MmException(MmResult result, string function)
		{
			Result = result;
			Target = function;
		}

		public MmException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			if (info == null)
			{
				throw new ArgumentNullException("info");
			}
			Target = info.GetString("Target");
			Result = (MmResult)info.GetInt32("Result");
		}

		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			base.GetObjectData(info, context);
			info.AddValue("Target", Target);
			info.AddValue("Result", (int)Result);
		}
	}
	public class SampleAggregatorBase : ISampleAggregator, ISampleSource, IReadableAudioSource<float>, IAudioSource, IDisposable, IAggregator<float, ISampleSource>
	{
		private bool _disposed;

		private ISampleSource _baseSource;

		public virtual WaveFormat WaveFormat => BaseSource.WaveFormat;

		public virtual long Position
		{
			get
			{
				if (!CanSeek)
				{
					return 0L;
				}
				return BaseSource.Position;
			}
			set
			{
				if (CanSeek)
				{
					value -= value % WaveFormat.BlockAlign;
					BaseSource.Position = value;
					return;
				}
				throw new InvalidOperationException("Underlying BaseSource is not readable.");
			}
		}

		public virtual long Length
		{
			get
			{
				if (!CanSeek)
				{
					return 0L;
				}
				return BaseSource.Length;
			}
		}

		public bool CanSeek => BaseSource.CanSeek;

		public virtual ISampleSource BaseSource
		{
			get
			{
				return _baseSource;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				_baseSource = value;
			}
		}

		public bool DisposeBaseSource { get; set; }

		public SampleAggregatorBase(ISampleSource source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			_baseSource = source;
			DisposeBaseSource = true;
		}

		public virtual int Read(float[] buffer, int offset, int count)
		{
			if (offset % WaveFormat.Channels != 0)
			{
				offset -= offset % WaveFormat.Channels;
			}
			if (count % WaveFormat.Channels != 0)
			{
				count -= count % WaveFormat.Channels;
			}
			return BaseSource.Read(buffer, offset, count);
		}

		public void Dispose()
		{
			if (!_disposed)
			{
				_disposed = true;
				Dispose(disposing: true);
				GC.SuppressFinalize(this);
			}
		}

		protected virtual void Dispose(bool disposing)
		{
			if (DisposeBaseSource && BaseSource != null)
			{
				BaseSource.Dispose();
				_baseSource = null;
			}
		}

		~SampleAggregatorBase()
		{
			Dispose(disposing: false);
		}
	}
	public static class Extensions
	{
		public static TimeSpan GetLength(this IAudioSource source)
		{
			return source.GetTime(source.Length);
		}

		public static TimeSpan GetPosition(this IAudioSource source)
		{
			return source.GetTime(source.Position);
		}

		public static void SetPosition(this IAudioSource source, TimeSpan position)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (position.TotalMilliseconds < 0.0)
			{
				throw new ArgumentOutOfRangeException("position");
			}
			long rawElements = source.GetRawElements(position);
			source.Position = rawElements;
		}

		public static TimeSpan GetTime(this IAudioSource source, long elementCount)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (elementCount < 0)
			{
				throw new ArgumentNullException("elementCount");
			}
			return TimeConverterFactory.Instance.GetTimeConverterForSource(source).ToTimeSpan(source.WaveFormat, elementCount);
		}

		public static long GetMilliseconds(this IAudioSource source, long elementCount)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (elementCount < 0)
			{
				throw new ArgumentOutOfRangeException("elementCount");
			}
			return (long)source.GetTime(elementCount).TotalMilliseconds;
		}

		public static long GetRawElements(this IAudioSource source, TimeSpan timespan)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return TimeConverterFactory.Instance.GetTimeConverterForSource(source).ToRawElements(source.WaveFormat, timespan);
		}

		public static long GetRawElements(this IAudioSource source, long milliseconds)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (milliseconds < 0)
			{
				throw new ArgumentOutOfRangeException("milliseconds");
			}
			return source.GetRawElements(TimeSpan.FromMilliseconds(milliseconds));
		}

		public static void WriteToFile(this IWaveSource source, string filename)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			using FileStream stream = File.OpenWrite(filename);
			source.WriteToWaveStream(stream);
		}

		public static void WriteToWaveStream(this IWaveSource source, Stream stream)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (!stream.CanWrite)
			{
				throw new ArgumentException("Stream is not writeable.", "stream");
			}
			using WaveWriter waveWriter = new WaveWriter(stream, source.WaveFormat);
			byte[] array = new byte[source.WaveFormat.BytesPerSecond];
			int count;
			while ((count = source.Read(array, 0, array.Length)) > 0)
			{
				waveWriter.Write(array, 0, count);
			}
		}

		public static void WriteToStream(this IWaveSource waveSource, Stream stream)
		{
			if (waveSource == null)
			{
				throw new ArgumentNullException("waveSource");
			}
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (!stream.CanWrite)
			{
				throw new ArgumentException("Stream is not writeable.", "stream");
			}
			byte[] array = new byte[waveSource.WaveFormat.BytesPerSecond];
			int count;
			while ((count = waveSource.Read(array, 0, array.Length)) > 0)
			{
				stream.Write(array, 0, count);
			}
		}

		public static T[] CheckBuffer<T>(this T[] inst, long size, bool exactSize = false)
		{
			if (inst == null || (!exactSize && inst.Length < size) || (exactSize && inst.Length != size))
			{
				return new T[size];
			}
			return inst;
		}

		internal static byte[] ReadBytes(this IWaveSource waveSource, int count)
		{
			if (waveSource == null)
			{
				throw new ArgumentNullException("waveSource");
			}
			count -= count % waveSource.WaveFormat.BlockAlign;
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException("count");
			}
			byte[] array = new byte[count];
			int num = waveSource.Read(array, 0, array.Length);
			if (num < count)
			{
				Array.Resize(ref array, num);
			}
			return array;
		}

		internal static bool IsClosed(this Stream stream)
		{
			if (!stream.CanRead)
			{
				return !stream.CanWrite;
			}
			return false;
		}

		internal static bool IsEndOfStream(this Stream stream)
		{
			return stream.Position == stream.Length;
		}

		internal static int LowWord(this int number)
		{
			return number & 0xFFFF;
		}

		internal static int LowWord(this int number, int newValue)
		{
			return (int)((number & 0xFFFF0000u) + (newValue & 0xFFFF));
		}

		internal static int HighWord(this int number)
		{
			return (int)(number & 0xFFFF0000u);
		}

		internal static int HighWord(this int number, int newValue)
		{
			return (number & 0xFFFF) + (newValue << 16);
		}

		internal static uint LowWord(this uint number)
		{
			return number & 0xFFFFu;
		}

		internal static uint LowWord(this uint number, int newValue)
		{
			return (uint)((uint)((int)number & -65536) + (newValue & 0xFFFF));
		}

		internal static uint HighWord(this uint number)
		{
			return number & 0xFFFF0000u;
		}

		internal static uint HighWord(this uint number, int newValue)
		{
			return (uint)((number & 0xFFFF) + (newValue << 16));
		}

		internal static Guid GetGuid(this object obj)
		{
			return obj.GetType().GUID;
		}

		internal static void WaitForExit(this Thread thread)
		{
			if (thread != null)
			{
				if (thread == Thread.CurrentThread)
				{
					throw new InvalidOperationException("Deadlock detected.");
				}
				thread.Join();
			}
		}

		internal static bool WaitForExit(this Thread thread, int timeout)
		{
			if (thread == null)
			{
				return true;
			}
			if (thread == Thread.CurrentThread)
			{
				throw new InvalidOperationException("Deadlock detected.");
			}
			return thread.Join(timeout);
		}

		internal static bool IsPCM(this WaveFormat waveFormat)
		{
			if (waveFormat == null)
			{
				throw new ArgumentNullException("waveFormat");
			}
			if (waveFormat is WaveFormatExtensible)
			{
				return ((WaveFormatExtensible)waveFormat).SubFormat == AudioSubTypes.Pcm;
			}
			return waveFormat.WaveFormatTag == AudioEncoding.Pcm;
		}

		internal static bool IsIeeeFloat(this WaveFormat waveFormat)
		{
			if (waveFormat == null)
			{
				throw new ArgumentNullException("waveFormat");
			}
			if (waveFormat is WaveFormatExtensible)
			{
				return ((WaveFormatExtensible)waveFormat).SubFormat == AudioSubTypes.IeeeFloat;
			}
			return waveFormat.WaveFormatTag == AudioEncoding.IeeeFloat;
		}

		internal static AudioEncoding GetWaveFormatTag(this WaveFormat waveFormat)
		{
			if (waveFormat is WaveFormatExtensible)
			{
				return AudioSubTypes.EncodingFromSubType(((WaveFormatExtensible)waveFormat).SubFormat);
			}
			return waveFormat.WaveFormatTag;
		}

		public static bool WaitForStopped(this ISoundOut soundOut, int millisecondsTimeout)
		{
			if (soundOut == null)
			{
				throw new ArgumentNullException("soundOut");
			}
			if (millisecondsTimeout < -1)
			{
				throw new ArgumentOutOfRangeException("millisecondsTimeout");
			}
			if (soundOut.PlaybackState == PlaybackState.Stopped)
			{
				return true;
			}
			AutoResetEvent waitHandle = new AutoResetEvent(initialState: false);
			try
			{
				EventHandler<PlaybackStoppedEventArgs> value = delegate
				{
					waitHandle.Set();
				};
				soundOut.Stopped += value;
				bool result = waitHandle.WaitOne(millisecondsTimeout);
				soundOut.Stopped -= value;
				return result;
			}
			finally
			{
				if (waitHandle != null)
				{
					((IDisposable)waitHandle).Dispose();
				}
			}
		}

		public static void WaitForStopped(this ISoundOut soundOut)
		{
			soundOut.WaitForStopped(-1);
		}

		internal static void SetValueForValueType<T>(this FieldInfo field, ref T item, object value) where T : struct
		{
			field.SetValueDirect(__makeref(item), value);
		}
	}
}
namespace CSCore.SoundOut
{
	public class PlaybackStoppedEventArgs : StoppedEventArgs
	{
		public PlaybackStoppedEventArgs()
			: this(null)
		{
		}

		public PlaybackStoppedEventArgs(Exception exception)
			: base(exception)
		{
		}
	}
}
namespace CSCore.Codecs.WAV
{
	public class WaveWriter : IDisposable, IWriteable
	{
		private readonly WaveFormat _waveFormat;

		private readonly long _waveStartPosition;

		private int _dataLength;

		private bool _isDisposed;

		private Stream _stream;

		private BinaryWriter _writer;

		private bool _isDisposing;

		private readonly bool _closeStream;

		public bool IsDisposed => _isDisposed;

		public bool IsDisposing => _isDisposing;

		public WaveWriter(string fileName, WaveFormat waveFormat)
			: this(File.OpenWrite(fileName), waveFormat)
		{
			_closeStream = true;
		}

		public WaveWriter(Stream stream, WaveFormat waveFormat)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (!stream.CanWrite)
			{
				throw new ArgumentException("Stream not writeable.", "stream");
			}
			if (!stream.CanSeek)
			{
				throw new ArgumentException("Stream not seekable.", "stream");
			}
			_isDisposing = false;
			_isDisposed = false;
			_stream = stream;
			_waveStartPosition = stream.Position;
			_writer = new BinaryWriter(stream);
			for (int i = 0; i < 44; i++)
			{
				_writer.Write((byte)0);
			}
			_waveFormat = waveFormat;
			WriteHeader();
			_closeStream = false;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		[Obsolete("Use the Extensions.WriteToWaveStream extension instead.")]
		public static void WriteToFile(string filename, IWaveSource source, bool deleteFileIfAlreadyExists, int maxlength = -1)
		{
			if (deleteFileIfAlreadyExists && File.Exists(filename))
			{
				File.Delete(filename);
			}
			int num = 0;
			byte[] array = new byte[source.WaveFormat.BytesPerSecond];
			using WaveWriter waveWriter = new WaveWriter(filename, source.WaveFormat);
			int num2;
			while ((num2 = source.Read(array, 0, array.Length)) > 0)
			{
				waveWriter.Write(array, 0, num2);
				num += num2;
				if (maxlength != -1 && num > maxlength)
				{
					break;
				}
			}
		}

		public void WriteSample(float sample)
		{
			CheckObjectDisposed();
			if (sample < -1f || sample > 1f)
			{
				sample = Math.Max(-1f, Math.Min(1f, sample));
			}
			if (_waveFormat.IsPCM())
			{
				switch (_waveFormat.BitsPerSample)
				{
				case 8:
					Write((byte)(255f * sample));
					break;
				case 16:
					Write((short)(32767f * sample));
					break;
				case 24:
				{
					byte[] bytes = BitConverter.GetBytes((int)(8388607f * sample));
					Write(new byte[3]
					{
						bytes[0],
						bytes[1],
						bytes[2]
					}, 0, 3);
					break;
				}
				case 32:
					Write((int)(2.1474836E+09f * sample));
					break;
				default:
					throw new InvalidOperationException("Invalid Waveformat", new InvalidOperationException("Invalid BitsPerSample while using PCM encoding."));
				}
			}
			else if (_waveFormat.IsIeeeFloat())
			{
				Write(sample);
			}
			else
			{
				if (_waveFormat.WaveFormatTag != AudioEncoding.Extensible || _waveFormat.BitsPerSample != 32)
				{
					throw new InvalidOperationException("Invalid Waveformat: Waveformat has to be PCM[8, 16, 24, 32] or IeeeFloat[32]");
				}
				Write(65535 * (int)sample);
			}
		}

		public void WriteSamples(float[] samples, int offset, int count)
		{
			CheckObjectDisposed();
			for (int i = offset; i < offset + count; i++)
			{
				WriteSample(samples[i]);
			}
		}

		public void Write(byte[] buffer, int offset, int count)
		{
			CheckObjectDisposed();
			_stream.Write(buffer, offset, count);
			_dataLength += count;
		}

		public void Write(byte value)
		{
			CheckObjectDisposed();
			_writer.Write(value);
			_dataLength++;
		}

		public void Write(short value)
		{
			CheckObjectDisposed();
			_writer.Write(value);
			_dataLength += 2;
		}

		public void Write(int value)
		{
			CheckObjectDisposed();
			_writer.Write(value);
			_dataLength += 4;
		}

		public void Write(float value)
		{
			CheckObjectDisposed();
			_writer.Write(value);
			_dataLength += 4;
		}

		private void WriteHeader()
		{
			_writer.Flush();
			long position = _stream.Position;
			_stream.Position = _waveStartPosition;
			WriteRiffHeader();
			WriteFmtChunk();
			WriteDataChunk();
			_writer.Flush();
			_stream.Position = position;
		}

		private void WriteRiffHeader()
		{
			_writer.Write(Encoding.UTF8.GetBytes("RIFF"));
			_writer.Write((int)(_stream.Length - 8));
			_writer.Write(Encoding.UTF8.GetBytes("WAVE"));
		}

		private void WriteFmtChunk()
		{
			AudioEncoding audioEncoding = _waveFormat.WaveFormatTag;
			if (audioEncoding == AudioEncoding.Extensible && _waveFormat is WaveFormatExtensible)
			{
				audioEncoding = AudioSubTypes.EncodingFromSubType((_waveFormat as WaveFormatExtensible).SubFormat);
			}
			_writer.Write(Encoding.UTF8.GetBytes("fmt "));
			_writer.Write(16);
			_writer.Write((short)audioEncoding);
			_writer.Write((short)_waveFormat.Channels);
			_writer.Write(_waveFormat.SampleRate);
			_writer.Write(_waveFormat.BytesPerSecond);
			_writer.Write((short)_waveFormat.BlockAlign);
			_writer.Write((short)_waveFormat.BitsPerSample);
		}

		private void WriteDataChunk()
		{
			_writer.Write(Encoding.UTF8.GetBytes("data"));
			_writer.Write(_dataLength);
		}

		private void CheckObjectDisposed()
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException("WaveWriter");
			}
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_isDisposed || !disposing)
			{
				return;
			}
			try
			{
				_isDisposing = true;
				WriteHeader();
			}
			catch (Exception)
			{
			}
			finally
			{
				if (_closeStream)
				{
					if (_writer != null)
					{
						_writer.Close();
						_writer = null;
					}
					if (_stream != null)
					{
						_stream.Dispose();
						_stream = null;
					}
				}
				_isDisposing = false;
			}
			_isDisposed = true;
		}

		~WaveWriter()
		{
			Dispose(disposing: false);
		}
	}
}
namespace CSCore.SoundOut
{
	public interface ISoundOut : IDisposable
	{
		float Volume { get; set; }

		IWaveSource WaveSource { get; }

		PlaybackState PlaybackState { get; }

		event EventHandler<PlaybackStoppedEventArgs> Stopped;

		void Play();

		void Pause();

		void Resume();

		void Stop();

		void Initialize(IWaveSource source);
	}
	public enum PlaybackState
	{
		Stopped,
		Playing,
		Paused
	}
}
namespace CSCore
{
	public abstract class WaveAggregatorBase : IWaveAggregator, IWaveSource, IReadableAudioSource<byte>, IAudioSource, IDisposable, IAggregator<byte, IWaveSource>
	{
		private IWaveSource _baseSource;

		private bool _disposed;

		public bool DisposeBaseSource { get; set; }

		public virtual IWaveSource BaseSource
		{
			get
			{
				return _baseSource;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "BaseSource must not be null.");
				}
				_baseSource = value;
			}
		}

		public virtual WaveFormat WaveFormat => BaseSource.WaveFormat;

		public virtual long Position
		{
			get
			{
				if (!CanSeek)
				{
					return 0L;
				}
				return BaseSource.Position;
			}
			set
			{
				if (CanSeek)
				{
					value -= value % WaveFormat.BlockAlign;
					BaseSource.Position = value;
					return;
				}
				throw new InvalidOperationException();
			}
		}

		public virtual long Length
		{
			get
			{
				if (!CanSeek)
				{
					return 0L;
				}
				return BaseSource.Length;
			}
		}

		public virtual bool CanSeek => BaseSource.CanSeek;

		protected WaveAggregat