Main interface for using Media Foundation with NAudio
        private IMFSample ReadFromSource()
        {
            // we always read a full second
            int bytesRead = sourceProvider.Read(sourceBuffer, 0, sourceBuffer.Length);

            if (bytesRead == 0)
            {
                return(null);
            }

            var    mediaBuffer = MediaFoundationApi.CreateMemoryBuffer(bytesRead);
            IntPtr pBuffer;
            int    maxLength, currentLength;

            mediaBuffer.Lock(out pBuffer, out maxLength, out currentLength);
            Marshal.Copy(sourceBuffer, 0, pBuffer, bytesRead);
            mediaBuffer.Unlock();
            mediaBuffer.SetCurrentLength(bytesRead);

            var sample = MediaFoundationApi.CreateSample();

            sample.AddBuffer(mediaBuffer);
            // we'll set the time, I don't think it is needed for Resampler, but other MFTs might need it
            sample.SetSampleTime(inputPosition);
            long duration = BytesToNsPosition(bytesRead, sourceProvider.WaveFormat);

            sample.SetSampleDuration(duration);
            inputPosition += duration;
            Marshal.ReleaseComObject(mediaBuffer);
            return(sample);
        }
Esempio n. 2
0
        // Token: 0x06000A59 RID: 2649 RVA: 0x0001E1A8 File Offset: 0x0001C3A8
        private IMFSample ReadFromSource()
        {
            int num = this.sourceProvider.Read(this.sourceBuffer, 0, this.sourceBuffer.Length);

            if (num == 0)
            {
                return(null);
            }
            IMFMediaBuffer imfmediaBuffer = MediaFoundationApi.CreateMemoryBuffer(num);
            IntPtr         destination;
            int            num2;
            int            num3;

            imfmediaBuffer.Lock(out destination, out num2, out num3);
            Marshal.Copy(this.sourceBuffer, 0, destination, num);
            imfmediaBuffer.Unlock();
            imfmediaBuffer.SetCurrentLength(num);
            IMFSample imfsample = MediaFoundationApi.CreateSample();

            imfsample.AddBuffer(imfmediaBuffer);
            imfsample.SetSampleTime(this.inputPosition);
            long num4 = MediaFoundationTransform.BytesToNsPosition(num, this.sourceProvider.WaveFormat);

            imfsample.SetSampleDuration(num4);
            this.inputPosition += num4;
            Marshal.ReleaseComObject(imfmediaBuffer);
            return(imfsample);
        }
Esempio n. 3
0
 /// <summary>
 /// Constructs a new MediaFounationSimplePlayer.
 /// </summary>
 /// <param name="url">The file to play.</param>
 /// <param name="m_selectFlags">Specify how the player selects streams.</param>
 public MediaFounationSimplePlayer(string url, StreamSelectFlags selectFlags = StreamSelectFlags.SelectByDefault)
 {
     if (!File.Exists(url))
     {
         throw new FileNotFoundException("This file doesn't exist.");
     }
     MediaFoundationApi.Startup();
     m_selectflag = selectFlags;
     URL          = url;
     Load();
 }
Esempio n. 4
0
        public static IMFMediaType CreateMediaTypeFromWaveFormat(WaveFormat waveFormat)
        {
            IMFMediaType imfmediaType = MediaFoundationApi.CreateMediaType();

            try
            {
                MediaFoundationInterop.MFInitMediaTypeFromWaveFormatEx(imfmediaType, waveFormat, Marshal.SizeOf(waveFormat));
            }
            catch (Exception)
            {
                Marshal.ReleaseComObject(imfmediaType);
                throw;
            }
            return(imfmediaType);
        }
        /// <summary>
        /// Attempts to read from the transform
        /// Some useful info here:
        /// http://msdn.microsoft.com/en-gb/library/windows/desktop/aa965264%28v=vs.85%29.aspx#process_data
        /// </summary>
        /// <returns></returns>
        private int ReadFromTransform()
        {
            var outputDataBuffer = new MFT_OUTPUT_DATA_BUFFER[1];
            // we have to create our own for
            var sample  = MediaFoundationApi.CreateSample();
            var pBuffer = MediaFoundationApi.CreateMemoryBuffer(outputBuffer.Length);

            sample.AddBuffer(pBuffer);
            sample.SetSampleTime(outputPosition); // hopefully this is not needed
            outputDataBuffer[0].pSample = sample;

            _MFT_PROCESS_OUTPUT_STATUS status;
            var hr = transform.ProcessOutput(_MFT_PROCESS_OUTPUT_FLAGS.None,
                                             1, outputDataBuffer, out status);

            if (hr == MediaFoundationErrors.MF_E_TRANSFORM_NEED_MORE_INPUT)
            {
                Marshal.ReleaseComObject(pBuffer);
                Marshal.ReleaseComObject(sample);
                // nothing to read
                return(0);
            }
            else if (hr != 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            IMFMediaBuffer outputMediaBuffer;

            outputDataBuffer[0].pSample.ConvertToContiguousBuffer(out outputMediaBuffer);
            IntPtr pOutputBuffer;
            int    outputBufferLength;
            int    maxSize;

            outputMediaBuffer.Lock(out pOutputBuffer, out maxSize, out outputBufferLength);
            outputBuffer = BufferHelpers.Ensure(outputBuffer, outputBufferLength);
            Marshal.Copy(pOutputBuffer, outputBuffer, 0, outputBufferLength);
            outputBufferOffset = 0;
            outputBufferCount  = outputBufferLength;
            outputMediaBuffer.Unlock();
            outputPosition += BytesToNsPosition(outputBufferCount, WaveFormat); // hopefully not needed
            Marshal.ReleaseComObject(pBuffer);
            sample.RemoveAllBuffers();                                          // needed to fix memory leak in some cases
            Marshal.ReleaseComObject(sample);
            Marshal.ReleaseComObject(outputMediaBuffer);
            return(outputBufferLength);
        }
Esempio n. 6
0
        public MediaFoundationCapturer(IMFActivate devsource)
        {
            MediaFoundationApi.Startup();
            WaveFormat format = new WaveFormat();

            try
            {
                devsource.ActivateObject(typeof(IMFMediaSource).GUID, out object _source);
                source = _source as IMFMediaSource;
            }
            catch (COMException)
            {
                throw new ArgumentException("Can't create media source with the devsource.");
            }
            SetFormat(format);
            recordthread = new Thread(DoRecord);
        }
Esempio n. 7
0
        private void SetFormat(WaveFormat format)
        {
            source.CreatePresentationDescriptor(out IMFPresentationDescriptor descriptor);
            descriptor.GetStreamDescriptorCount(out uint sdcount);
            bool hasaudio = false;

            for (uint i = 0; i < sdcount; i++)
            {
                descriptor.GetStreamDescriptorByIndex(i, out _, out IMFStreamDescriptor sd);
                descriptor.SelectStream(i);
                sd.GetMediaTypeHandler(out IMFMediaTypeHandler typeHandler);
                typeHandler.GetMediaTypeByIndex(0, out IMFMediaType mediaType);
                mediaType.GetMajorType(out Guid streamtype);
                if (streamtype == MediaTypes.MFMediaType_Audio)
                {
                    try
                    {
                        mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND, format.SampleRate);//SampleRate
                        mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS, format.Channels);
                        mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE, format.BitsPerSample);
                        mediaType.SetGUID(MediaFoundationAttributes.MF_MT_SUBTYPE, AudioSubtypes.MFAudioFormat_PCM);
                    }
                    catch (COMException)
                    {
                        throw new InvalidOperationException("Can't configure the source with specific format.");
                    }
                    hasaudio = true;
                }
                else
                {
                    continue;
                }
            }
            if (!hasaudio)
            {
                throw new ArgumentException("The device doesn't have audio stream.");
            }
            this.format = format;
            IMFAttributes readerattr = MediaFoundationApi.CreateAttributes(2);

            readerattr.SetUnknown(MediaFoundationAttributes.MF_SOURCE_READER_ASYNC_CALLBACK, callback);
            MediaFoundationInterop.MFCreateSourceReaderFromMediaSource(source, readerattr, out IMFSourceReader _sourceReader);
            sourceReader = _sourceReader as IMFSourceReader2;
        }
Esempio n. 8
0
        /// <summary>
        /// Attempts to read from the transform
        /// Some useful info here:
        /// http://msdn.microsoft.com/en-gb/library/windows/desktop/aa965264%28v=vs.85%29.aspx#process_data
        /// </summary>
        /// <returns></returns>
        // Token: 0x06000A57 RID: 2647 RVA: 0x0001E078 File Offset: 0x0001C278
        private int ReadFromTransform()
        {
            MFT_OUTPUT_DATA_BUFFER[] array = new MFT_OUTPUT_DATA_BUFFER[1];
            IMFSample      imfsample       = MediaFoundationApi.CreateSample();
            IMFMediaBuffer imfmediaBuffer  = MediaFoundationApi.CreateMemoryBuffer(this.outputBuffer.Length);

            imfsample.AddBuffer(imfmediaBuffer);
            imfsample.SetSampleTime(this.outputPosition);
            array[0].pSample = imfsample;
            _MFT_PROCESS_OUTPUT_STATUS mft_PROCESS_OUTPUT_STATUS;
            int num = this.transform.ProcessOutput(_MFT_PROCESS_OUTPUT_FLAGS.None, 1, array, out mft_PROCESS_OUTPUT_STATUS);

            if (num == -1072861838)
            {
                Marshal.ReleaseComObject(imfmediaBuffer);
                Marshal.ReleaseComObject(imfsample);
                return(0);
            }
            if (num != 0)
            {
                Marshal.ThrowExceptionForHR(num);
            }
            IMFMediaBuffer imfmediaBuffer2;

            array[0].pSample.ConvertToContiguousBuffer(out imfmediaBuffer2);
            IntPtr source;
            int    num2;
            int    num3;

            imfmediaBuffer2.Lock(out source, out num2, out num3);
            this.outputBuffer = BufferHelpers.Ensure(this.outputBuffer, num3);
            Marshal.Copy(source, this.outputBuffer, 0, num3);
            this.outputBufferOffset = 0;
            this.outputBufferCount  = num3;
            imfmediaBuffer2.Unlock();
            this.outputPosition += MediaFoundationTransform.BytesToNsPosition(this.outputBufferCount, this.WaveFormat);
            Marshal.ReleaseComObject(imfmediaBuffer);
            Marshal.ReleaseComObject(imfsample);
            Marshal.ReleaseComObject(imfmediaBuffer2);
            return(num3);
        }
Esempio n. 9
0
 /// <summary>
 /// Creates and wraps a new IMFMediaType object based on a WaveFormat
 /// </summary>
 /// <param name="waveFormat">WaveFormat</param>
 public MediaType(WaveFormat waveFormat)
 {
     mediaType = MediaFoundationApi.CreateMediaTypeFromWaveFormat(waveFormat);
 }
Esempio n. 10
0
 /// <summary>
 /// Creates and wraps a new IMFMediaType object
 /// </summary>
 public MediaType()
 {
     mediaType = MediaFoundationApi.CreateMediaType();
 }
Esempio n. 11
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();
        }
Esempio n. 12
0
        /// <summary>
        /// Initialize the MediaFoundationProvider with specific file.
        /// </summary>
        public MediaFoundationProvider(string url)
        {
            MediaFoundationApi.Startup();
            if (!File.Exists(url))
            {
                throw new FileNotFoundException("This file doesn't exist");
            }
            MediaFoundationInterop.MFCreateSourceResolver(out IMFSourceResolver resolver);
            //Creates both IMFMediaSource and IMFByteStream.Uses the stream for 'Read' method and uses the source to collect format information.
            resolver.CreateObjectFromURL(url, SourceResolverFlags.MF_RESOLUTION_BYTESTREAM | SourceResolverFlags.MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE, null, out _, out object _stream);
            IMFByteStream byteStream = _stream as IMFByteStream;

            resolver.CreateObjectFromByteStream(byteStream, null, SourceResolverFlags.MF_RESOLUTION_MEDIASOURCE | SourceResolverFlags.MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE, null, out _, out object _source);
            Marshal.FinalReleaseComObject(resolver);
            IMFMediaSource source = _source as IMFMediaSource;

            source.CreatePresentationDescriptor(out IMFPresentationDescriptor descriptor);
            descriptor.GetStreamDescriptorCount(out uint sdcount);
            for (uint i = 0; i < sdcount; i++)
            {
                descriptor.GetStreamDescriptorByIndex(i, out _, out IMFStreamDescriptor sd);
                sd.GetMediaTypeHandler(out IMFMediaTypeHandler typeHandler);
                typeHandler.GetMediaTypeByIndex(0, out IMFMediaType mediaType);
                mediaType.GetMajorType(out Guid streamtype);
                if (streamtype == MediaTypes.MFMediaType_Audio)
                {
                    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;
                        }
                    }
                    WaveFormat = new WaveFormat(rate, samplesize, channelcount);
                }
                else
                {
                    continue;
                }
            }
            byteStream.GetLength(out streamlength);
            byteStream.SetCurrentPosition(0);
            //Moves all the bytes in IMFByteStream to MemoryStream.
            MediaFoundationInterop.MFCreateMemoryBuffer(unchecked ((int)streamlength), out IMFMediaBuffer mediabuffer);
            mediabuffer.Lock(out IntPtr pbuffer, out int length, out _);
            byteStream.Read(pbuffer, length, out _);
            byte[] buffer = new byte[length];
            Marshal.Copy(pbuffer, buffer, 0, length);
            datastream = new MemoryStream(buffer);
        }