Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Runtime.InteropServices;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Windows.Storage;
- using Windows.Media;
- using Microsoft.VisualBasic;
- using System.IO;
- using System.Diagnostics;
- namespace MFSourceReaderPort
- {
- public class Reader
- {
- public static async Task TestFromWin8(Uri src_uri, Stream dst_stream)
- {
- Interop.IMFSourceReader pReader = null;
- if(src_uri.Scheme != "file")
- {
- Interop.MFCreateSourceReaderFromURL(src_uri.ToString(), IntPtr.Zero, ref pReader);
- }
- else
- {
- StorageFile src_file = await StorageFile.GetFileFromPathAsync(src_uri.LocalPath);
- using (var src_stream = await src_file.OpenAsync(FileAccessMode.Read))
- {
- Interop.IMFByteStream src_byteStream = null;
- Interop.MFCreateMFByteStreamOnStreamEx(src_stream, ref src_byteStream);
- Interop.MFCreateSourceReaderFromByteStream(src_byteStream, IntPtr.Zero, ref pReader);
- Marshal.ReleaseComObject(src_byteStream);
- }
- }
- await ConvertToWavAsync(pReader, dst_stream);
- Marshal.ReleaseComObject(pReader);
- pReader = null;
- }
- static async Task ConvertToWavAsync(Interop.IMFSourceReader pReader, Stream dest)
- {
- // We'll ask it for PCM data, 44100Hz, 2 channels, 16 bits per sample
- pReader.SetStreamSelection((int)Interop.MF_SOURCE_READER_ALL_STREAMS, false);
- pReader.SetStreamSelection(Interop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, true);
- Interop.IMFMediaType pRequestedType = null;
- Interop.MFCreateMediaType(ref pRequestedType);
- pRequestedType.SetGUID(Interop.MF_MT_MAJOR_TYPE, Interop.MFMediaType_Audio);
- pRequestedType.SetGUID(Interop.MF_MT_SUBTYPE, Interop.MFAudioFormat_PCM);
- pRequestedType.SetUINT32(Interop.MF_MT_AUDIO_NUM_CHANNELS, 2);
- pRequestedType.SetUINT32(Interop.MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
- pRequestedType.SetUINT32(Interop.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
- pReader.SetCurrentMediaType(Interop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, IntPtr.Zero, pRequestedType);
- Marshal.ReleaseComObject(pRequestedType);
- pRequestedType = null;
- // It can tell us the authoritative wave format that it picked
- Interop.IMFMediaType pAudioType = null;
- pReader.GetCurrentMediaType(Interop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, ref pAudioType);
- int cbBlockSize = 0;
- pAudioType.GetUINT32(Interop.MF_MT_AUDIO_BLOCK_ALIGNMENT, ref cbBlockSize);
- int cbBytesPerSecond = 0;
- pAudioType.GetUINT32(Interop.MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ref cbBytesPerSecond);
- IntPtr pWav = IntPtr.Zero;
- int cbFormat = 0;
- Interop.MFCreateWaveFormatExFromMFMediaType(pAudioType, ref pWav, ref cbFormat);
- byte[] wfx = new byte[cbFormat];
- Marshal.Copy(pWav, wfx, 0, cbFormat);
- pReader.SetStreamSelection(Interop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, true);
- Marshal.ReleaseComObject(pAudioType);
- pAudioType = null;
- //WAV files have pretty straightforward headers
- byte[] header = new byte[] { (byte)(Strings.AscW("R")), (byte)(Strings.AscW("I")), (byte)(Strings.AscW("F")), (byte)(Strings.AscW("F")), 0, 0, 0, 0, (byte)(Strings.AscW("W")), (byte)(Strings.AscW("A")), (byte)(Strings.AscW("V")), (byte)(Strings.AscW("E")), (byte)(Strings.AscW("f")), (byte)(Strings.AscW("m")), (byte)(Strings.AscW("t")), (byte)(Strings.AscW(" ")), (byte)(cbFormat & 255), (byte)((cbFormat >> 8) & 255), (byte)((cbFormat >> 16) & 255), (byte)((cbFormat >> 24) & 255) };
- byte[] dataHeader = new byte[] { (byte)(Strings.AscW("d")), (byte)(Strings.AscW("a")), (byte)(Strings.AscW("t")), (byte)(Strings.AscW("a")), 0, 0, 0, 0 };
- await dest.WriteAsync(header, 0, header.Length);
- await dest.WriteAsync(wfx, 0, wfx.Length);
- await dest.WriteAsync(dataHeader, 0, dataHeader.Length);
- Marshal.FreeCoTaskMem(pWav);
- int cbHeader = header.Length + cbFormat + dataHeader.Length;
- int cbAudioData = 0;
- int dwflags = 0;
- Interop.IMFSample pSample = null;
- do
- {
- pReader.ReadSample(Interop.MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, 0, ref dwflags, 0, ref pSample);
- int sample = 0;
- pSample.GetSampleFlags(ref sample);
- Interop.IMFMediaBuffer pBuffer = null;
- try
- {
- pSample.ConvertToContiguousBuffer(ref pBuffer);
- }
- catch (COMException e)
- {
- Debug.WriteLine(e.Message);
- }
- IntPtr pAudioData = IntPtr.Zero;
- int cbBuffer = 0;
- pBuffer.Lock(ref pAudioData, 0, ref cbBuffer);
- byte[] buf = new byte[cbBuffer - 1];
- Marshal.Copy(pAudioData, buf, 0, cbBuffer);
- await dest.WriteAsync(buf, 0, cbBuffer);
- cbAudioData += cbBuffer;
- pBuffer.Unlock();
- Marshal.ReleaseComObject(pBuffer);
- Marshal.ReleaseComObject(pSample);
- pBuffer = null;
- pSample = null;
- } while (dwflags != 0);
- int cbRiffFileSize = cbHeader + cbAudioData - 8;
- dest.Seek(4, SeekOrigin.Begin);
- await dest.WriteAsync(BitConverter.GetBytes(cbRiffFileSize), 0, 4);
- dest.Seek(cbHeader - 4, SeekOrigin.Begin);
- await dest.WriteAsync(BitConverter.GetBytes(cbAudioData), 0, 4);
- }
- }
- public class Interop
- {
- #region DLL Imports
- [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
- extern static public void MFStartup(int version, int dwFlags = 0);
- [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
- extern static public void MFShutdown();
- [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
- extern static public void MFCreateMediaType(ref IMFMediaType MFType);
- [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
- extern static public void MFCreateWaveFormatExFromMFMediaType(IMFMediaType MFType, ref IntPtr pWF, ref int cbSize, int flags = 0);
- [DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
- extern static public void MFCreateSourceReaderFromURL([MarshalAs(UnmanagedType.LPWStr)] string wszURL, IntPtr pAttributes, ref IMFSourceReader sourceReader);
- [DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
- extern static public void MFCreateSourceReaderFromByteStream(IMFByteStream byteStream, IntPtr pAttributes, ref IMFSourceReader sourceReader);
- [DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
- extern static public void MFCreateMFByteStreamOnStreamEx([MarshalAs(UnmanagedType.IUnknown)] object punkStream, ref IMFByteStream byteStream);
- #endregion
- #region Constants
- public const int MF_SOURCE_READER_ALL_STREAMS = unchecked((int)0xFFFFFFFE);
- public const int MF_SOURCE_READER_FIRST_AUDIO_STREAM = unchecked((int)0xFFFFFFFD);
- public const int MF_SDK_VERSION = 0x2;
- public const int MF_API_VERSION = 0x70;
- public const int MF_VERSION = (MF_SDK_VERSION << 16) | MF_API_VERSION;
- public static readonly Guid MF_MT_MAJOR_TYPE = new Guid("48eba18e-f8c9-4687-bf11-0a74c9f96a8f");
- public static readonly Guid MF_MT_SUBTYPE = new Guid("f7e34c9a-42e8-4714-b74b-cb29d72c35e5");
- public static readonly Guid MF_MT_AUDIO_BLOCK_ALIGNMENT = new Guid("322de230-9eeb-43bd-ab7a-ff412251541d");
- public static readonly Guid MF_MT_AUDIO_AVG_BYTES_PER_SECOND = new Guid("1aab75c8-cfef-451c-ab95-ac034b8e1731");
- public static readonly Guid MF_MT_AUDIO_NUM_CHANNELS = new Guid("37e48bf5-645e-4c5b-89de-ada9e29b696a");
- public static readonly Guid MF_MT_AUDIO_SAMPLES_PER_SECOND = new Guid("5faeeae7-0290-4c31-9e8a-c534f68d9dba");
- public static readonly Guid MF_MT_AUDIO_BITS_PER_SAMPLE = new Guid("f2deb57f-40fa-4764-aa33-ed4f2d1ff669");
- public static readonly Guid MFMediaType_Audio = new Guid("73647561-0000-0010-8000-00AA00389B71");
- public static readonly Guid MFAudioFormat_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71");
- #endregion
- #region COM Imports
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("70ae66f2-c809-4e4f-8915-bdcb406b7993")]
- public interface IMFSourceReader
- {
- void GetStreamSelection([In] int dwStreamIndex, [MarshalAs(UnmanagedType.Bool)] ref bool pSelected);
- void SetStreamSelection([In] int dwStreamIndex, [In, MarshalAs(UnmanagedType.Bool)] bool pSelected);
- void GetNativeMediaType([In] int dwStreamIndex, [In] int dwMediaTypeIndex, ref IntPtr ppMediaType);
- void GetCurrentMediaType([In] int dwStreamIndex, ref IMFMediaType ppMediaType);
- void SetCurrentMediaType([In] int dwStreamIndex, IntPtr pdwReserved, [In] IMFMediaType pMediaType);
- void SetCurrentPosition([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidTimeFormat, [In] object varPosition);
- void ReadSample([In] int dwStreamIndex, [In] int dwControlFlags, ref int pdwActualStreamIndex, ref int pdwStreamFlags, ref UInt64 pllTimestamp, ref IMFSample ppSample);
- void Flush([In] int dwStreamIndex);
- void GetServiceForStream([In] int dwStreamIndex, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, ref IntPtr ppvObject);
- void GetPresentationAttribute([In] int dwStreamIndex, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidAttribute, ref IntPtr pvarAttribute);
- }
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2CD2D921-C447-44A7-A13C-4ADABFC247E3")]
- public interface IMFAttributes
- {
- void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr pValue);
- void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref int pType);
- void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] ref bool pbResult);
- void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int MatchType, [MarshalAs(UnmanagedType.Bool)] ref bool pbResult);
- void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref int punValue);
- void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref long punValue);
- void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref double pfValue);
- void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref Guid pguidValue);
- void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref int pcchLength);
- void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, ref int pcchLength);
- void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] ref string ppwszValue, ref int pcchLength);
- void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref int pcbBlobSize);
- void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPArray)] ref byte pBuf, int cbBufSize, ref int pcbBlobSize);
- void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, ref IntPtr ip, ref int pcbSize);
- void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] ref object ppv);
- void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);
- void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);
- void DeleteAllItems();
- void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);
- void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);
- void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);
- void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);
- void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);
- void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte pBuf, int cbBufSize);
- void SetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);
- void LockStore();
- void UnlockStore();
- void GetCount(ref int pcItems);
- void GetItemByIndex(int unIndex, ref Guid pguidKey, IntPtr pValue);
- void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
- }
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("44AE0FA8-EA31-4109-8D2E-4CAE4997C555")]
- public interface IMFMediaType : IMFAttributes
- {
- void GetMajorType(ref Guid pguidMajorType);
- void IsCompressedFormat([MarshalAs(UnmanagedType.Bool)] ref bool pfCompressed);
- //<Runtime.InteropServices.PreserveSig> Function IsEqual(<Runtime.InteropServices.In, Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.Interface)> pIMediaType As IMFMediaType, ByRef pdwFlags As Integer) As Integer;
- [PreserveSig]
- int IsEqual([In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pIMediaType, ref int pdwFlags);
- void GetRepresentation([In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, ref IntPtr ppvRepresentation);
- void FreeRepresentation([In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, [In] IntPtr pvRepresentation);
- }
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("c40a00f2-b93a-4d80-ae8c-5a1c634f58e4")]
- public interface IMFSample : IMFAttributes
- {
- void GetSampleFlags(ref int pdwSampleFlags);
- void SetSampleFlags(int dwSampleFlags);
- void GetSampleTime(ref long phnsSampletime);
- void SetSampleTime(long hnsSampleTime);
- void GetSampleDuration(ref long phnsSampleDuration);
- void SetSampleDuration(long hnsSampleDuration);
- void GetBufferCount(ref int pdwBufferCount);
- void GetBufferByIndex(int dwIndex, ref IMFMediaBuffer ppBuffer);
- void ConvertToContiguousBuffer(ref IMFMediaBuffer ppBuffer);
- void AddBuffer(IMFMediaBuffer pBuffer);
- void RemoveBuferByindex(int dwIndex);
- void RemoveAllBuffers();
- void GetTotalLength(ref int pcbTotalLength);
- void CopyToByffer(IMFMediaBuffer pBuffer);
- }
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("045FA593-8799-42b8-BC8D-8968C6453507")]
- public interface IMFMediaBuffer
- {
- void Lock(ref IntPtr ppbBuffer, ref int pcbMaxLength, ref int pcbCurrentLength);
- void Unlock();
- void GetCurrentLength(ref int pcbCurrentLength);
- void SetCurrentLength(int cbCurrentLength);
- void GetMaxLength(ref int pcbMaxLength);
- }
- [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("ad4c1b00-4bf7-422f-9175-756693d9130d")]
- public interface IMFByteStream
- {
- //virtual HRESULT STDMETHODCALLTYPE GetCapabilities(/*[out]*/ __RPC__out DWORD *pdwCapabilities) = 0;
- void GetCapabilities(ref int pdwCapabiities);
- //virtual HRESULT STDMETHODCALLTYPE GetLength(/*[out]*/ __RPC__out QWORD *pqwLength) = 0;
- void GetLength(ref long pqwLength);
- //'virtual HRESULT STDMETHODCALLTYPE SetLength(/*[in]*/ QWORD qwLength) = 0;
- void SetLength(long qwLength);
- // 'virtual HRESULT STDMETHODCALLTYPE GetCurrentPosition(/*[out]*/ __RPC__out QWORD *pqwPosition) = 0;
- void GetCurrentPosition(ref long pqwPosition);
- // 'virtual HRESULT STDMETHODCALLTYPE SetCurrentPosition(/*[in]*/ QWORD qwPosition) = 0;
- void SetCurrentPosition(long qwPosition);
- // 'virtual HRESULT STDMETHODCALLTYPE IsEndOfStream(/*[out]*/ __RPC__out BOOL *pfEndOfStream) = 0;
- void IsEndOfStream([MarshalAs(UnmanagedType.Bool)] ref bool pfEndOfStream);
- // 'virtual HRESULT STDMETHODCALLTYPE Read(/*[size_is][out]*/ __RPC__out_ecount_full(cb) BYTE *pb, /*[in]*/ ULONG cb, /*[out]*/ __RPC__out ULONG *pcbRead) = 0;
- void Read(IntPtr pb, int cb, ref int pcbRead);
- // 'virtual /*[local]*/ HRESULT STDMETHODCALLTYPE BeginRead(/*[out]*/ _Out_writes_bytes_(cb) BYTE *pb, /*[in]*/ ULONG cb, /*[in]*/ IMFAsyncCallback *pCallback, /*[in]*/ IUnknown *punkState) = 0;
- void BeginRead(IntPtr pb, int cb, IntPtr pCallback, IntPtr punkState);
- // 'virtual /*[local]*/ HRESULT STDMETHODCALLTYPE EndRead(/*[in]*/ IMFAsyncResult *pResult, /*[out]*/ _Out_ ULONG *pcbRead) = 0;
- void EndRead(IntPtr pResult, ref int pcbRead);
- // 'virtual HRESULT STDMETHODCALLTYPE Write(/*[size_is][in]*/ __RPC__in_ecount_full(cb) const BYTE *pb, /*[in]*/ ULONG cb, /*[out]*/ __RPC__out ULONG *pcbWritten) = 0;
- void Write(IntPtr pb, int cb, ref int pcbWritten);
- // 'virtual /*[local]*/ HRESULT STDMETHODCALLTYPE BeginWrite(/*[in]*/ _In_reads_bytes_(cb) const BYTE *pb, /*[in]*/ ULONG cb, /*[in]*/ IMFAsyncCallback *pCallback, /*[in]*/ IUnknown *punkState) = 0;
- void BeginWrite(IntPtr pb, int cb, IntPtr pCallback, IntPtr punkState);
- //'virtual /*[local]*/ HRESULT STDMETHODCALLTYPE EndWrite(/*[in]*/ IMFAsyncResult *pResult, /*[out]*/ _Out_ ULONG *pcbWritten) = 0;
- void EndWrite(IntPtr pResult, ref int pcbWritten);
- //'virtual HRESULT STDMETHODCALLTYPE Seek(/*[in]*/ MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, /*[in]*/ LONGLONG llSeekOffset, /*[in]*/ DWORD dwSeekFlags, /*[out]*/ __RPC__out QWORD *pqwCurrentPosition) = 0;
- void Seek(int SeekOrigin, long llSeekOffset, int dwSeekFlags, ref long pqwCurrentPosition);
- //'virtual HRESULT STDMETHODCALLTYPE Flush( void) = 0;
- void Flush();
- //'virtual HRESULT STDMETHODCALLTYPE Close( void) = 0;
- void Close();
- }
- #endregion
- }
- }
Add Comment
Please, Sign In to add comment