/// <summary>
/// Loads IWaveProvider.
/// </summary>
/// <param name="waveProvider">The waveProvider to be loaded.</param>
public void Init(IWaveProvider waveProvider)
{
MediaFoundationApi.Startup();
m_sourcewave = waveProvider;
int readcount;
MemoryStream msByteStrem = new MemoryStream();
byte[] _data;
do
{
readcount = 0;
_data = new byte[32767];
readcount = waveProvider.Read(_data, 0, _data.Length);
if (readcount < 0)
{
continue;
}
msByteStrem.Write(_data, 0, readcount);
} while (readcount >= _data.Length | readcount < 0);//Creates a IMFByteStream and fills it with the data in waveProvider.
ComStream csByteStream = new ComStream(msByteStrem);
IMFByteStream mfByteStream = MediaFoundationApi.CreateByteStream(csByteStream);
MediaFoundationInterop.MFCreateSourceResolver(out IMFSourceResolver resolver);
IMFAttributes streamattributes = mfByteStream as IMFAttributes;
mfByteStream.GetLength(out long _length);
resolver.CreateObjectFromByteStream(mfByteStream, null, SourceResolverFlags.MF_RESOLUTION_MEDIASOURCE
| SourceResolverFlags.MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE, null, out _, out object _source);//Turns the stream to IMFMediaSource
IMFMediaSource source = _source as IMFMediaSource;
source.CreatePresentationDescriptor(out IMFPresentationDescriptor descriptor);
MediaFoundationInterop.MFCreateTopology(out IMFTopology topo);
descriptor.GetStreamDescriptorCount(out uint sdcount);
for (uint i = 0; i < sdcount; i++)//For each stream in the source,creates renderer and adds to the topology.
{
descriptor.GetStreamDescriptorByIndex(i, out bool IsSelected, out IMFStreamDescriptor sd);
if (!IsSelected)
{
if (SelectAllStream)
{
descriptor.SelectStream(i);
}
else
{
continue;
}
}
sd.GetMediaTypeHandler(out IMFMediaTypeHandler typeHandler);
typeHandler.GetMajorType(out Guid streamtype);
IMFActivate renderer;
if (streamtype == MediaTypes.MFMediaType_Audio)
{
MediaFoundationInterop.MFCreateAudioRendererActivate(out renderer);//Creates renderer for audio streams
}
else
{
continue;
}
//Creats and equips the topology nodes of the certain stream
MediaFoundationInterop.MFCreateTopologyNode(MF_TOPOLOGY_TYPE.MF_TOPOLOGY_SOURCESTREAM_NODE, out IMFTopologyNode sourcenode);
sourcenode.SetUnknown(MediaFoundationAttributes.MF_TOPONODE_SOURCE, source);
sourcenode.SetUnknown(MediaFoundationAttributes.MF_TOPONODE_PRESENTATION_DESCRIPTOR, descriptor);
sourcenode.SetUnknown(MediaFoundationAttributes.MF_TOPONODE_STREAM_DESCRIPTOR, sd);
topo.AddNode(sourcenode);
MediaFoundationInterop.MFCreateTopologyNode(MF_TOPOLOGY_TYPE.MF_TOPOLOGY_OUTPUT_NODE, out IMFTopologyNode outputnode);
outputnode.SetObject(renderer);
topo.AddNode(outputnode);
sourcenode.ConnectOutput(0, outputnode, 0);
}
MediaFoundationInterop.MFCreateMediaSession(IntPtr.Zero, out m_Session);
m_Session.SetTopology(0, topo);
m_eventthread = new Thread(ProcessEvent);
m_eventthread.Start();
}