Beispiel #1
0
        /// <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();
        }
        private void Load()
        {
            MediaFoundationInterop.MFCreateSourceResolver(out IMFSourceResolver resolver);
            object unknown;

            try
            {
                resolver.CreateObjectFromURL(URL, SourceResolverFlags.MF_RESOLUTION_MEDIASOURCE | SourceResolverFlags.MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE,
                                             null, out _, out unknown);
            }
            catch
            {
                throw new ArgumentException("Unsupported type.");
            }
            MediaFoundationInterop.MFCreateMediaSession(IntPtr.Zero, out m_Session);
            MediaFoundationInterop.MFCreateTopology(out IMFTopology topo);
            IMFMediaSource source = unknown as IMFMediaSource;

            source.CreatePresentationDescriptor(out m_pDescriptor);
            m_pDescriptor.GetUINT64(MediaFoundationAttributes.MF_PD_DURATION, out long dur);
            m_Duration = dur / 10000000;
            m_pDescriptor.GetStreamDescriptorCount(out uint sdcount);
            m_streamcount = (int)sdcount;
            for (uint i = 0; i < m_streamcount; i++)
            {
                m_pDescriptor.GetStreamDescriptorByIndex(i, out bool IsSelected, out IMFStreamDescriptor sd);
                m_DefaultStreamSelect.Add(IsSelected);
                switch (StreamSelectFlag)
                {
                case StreamSelectFlags.SelectAllStream:
                    if (!IsSelected)
                    {
                        m_pDescriptor.SelectStream(i);
                    }
                    break;

                case StreamSelectFlags.SelectNone:
                    if (IsSelected)
                    {
                        m_pDescriptor.DeselectStream(i);
                    }
                    break;
                }
                sd.GetMediaTypeHandler(out IMFMediaTypeHandler typeHandler);
                typeHandler.GetMediaTypeByIndex(0, out IMFMediaType mediaType);
                mediaType.GetMajorType(out Guid streamtype);
                IMFActivate renderer;
                if (streamtype == MediaTypes.MFMediaType_Audio)
                {
                    MediaFoundationInterop.MFCreateAudioRendererActivate(out renderer);
                    mediaType.GetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND, out int rate);//SampleRate
                    mediaType.GetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS, out int channelcount);
                    int samplesize;
                    try
                    {
                        mediaType.GetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE, out samplesize);
                    }
                    catch (COMException e)
                    {
                        if ((uint)e.HResult != 0xC00D36E6)
                        {
                            throw e;
                        }
                        else
                        {
                            samplesize = 8;
                        }
                    }
                    m_format.Add(new WaveFormat(rate, samplesize, channelcount));
                }
                else
                {
                    continue;
                }
                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, m_pDescriptor);
                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);
            }
            m_Session.SetTopology(0, topo);
            m_Eventthread = new Thread(ProcessEvent);
            m_Eventthread.Start();
        }