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); }
// 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); }
/// <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(); }
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); }
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); }
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; }
/// <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); }
/// <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); }
/// <summary> /// Creates and wraps a new IMFMediaType object /// </summary> public MediaType() { mediaType = MediaFoundationApi.CreateMediaType(); }
/// <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(); }
/// <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); }