/// <summary> /// Returns a new instance of the <see cref="MediaFoundationEncoder"/> class, configured as mp3 encoder. /// </summary> /// <param name="sourceFormat">The input format, of the data to encode.</param> /// <param name="bitRate">The bitrate to use. The final bitrate can differ from the specified value.</param> /// <param name="targetStream">The stream to write to.</param> /// <remarks>For more information about supported input and output formats, see <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh162907(v=vs.85).aspx"/>.</remarks> /// <returns>A new instance of the <see cref="MediaFoundationEncoder"/> class, configured as mp3 encoder.</returns> // ReSharper disable once InconsistentNaming public static MediaFoundationEncoder CreateMP3Encoder(WaveFormat sourceFormat, Stream targetStream, int bitRate = 192000) { if (sourceFormat == null) { throw new ArgumentNullException("sourceFormat"); } if (targetStream == null) { throw new ArgumentNullException("targetStream"); } if (targetStream.CanWrite != true) { throw new ArgumentException("Stream not writeable.", "targetStream"); } MFMediaType targetMediaType = FindBestMediaType(AudioSubTypes.MpegLayer3, sourceFormat.SampleRate, sourceFormat.Channels, bitRate); MFMediaType sourceMediaType = MediaFoundationCore.MediaTypeFromWaveFormat(sourceFormat); if (targetMediaType == null) { throw new PlatformNotSupportedException("No MP3-Encoder was found."); } return(new MediaFoundationEncoder(targetStream, sourceMediaType, targetMediaType, TranscodeContainerTypes.MFTranscodeContainerType_MP3) { _disposeBaseStream = false }); }
/// <returns>Ticks, NO BYTES!</returns> private long WriteBlock(byte[] buffer, int offset, int count, int streamIndex, long positionInTicks, int sourceBytesPerSecond) { int bytesToWrite = count; using (MFMediaBuffer mfBuffer = new MFMediaBuffer(MediaFoundationCore.CreateMemoryBuffer(bytesToWrite))) { using (MFSample sample = new MFSample(MediaFoundationCore.CreateEmptySample())) { sample.AddBuffer(mfBuffer); int currentLength, maxLength; IntPtr bufferPtr = mfBuffer.Lock(out maxLength, out currentLength); long ticks = BytesToNanoSeconds(count, sourceBytesPerSecond); Marshal.Copy(buffer, offset, bufferPtr, count); mfBuffer.SetCurrentLength(count); mfBuffer.Unlock(); sample.SetSampleTime(positionInTicks); sample.SetSampleDuration(ticks); _sinkWriter.WriteSample(_streamIndex, sample); return(ticks); } } }
/// <summary> /// See http://msdn.microsoft.com/en-us/library/windows/desktop/ff819498(v=vs.85).aspx for supported input and output types. /// </summary> public static MediaFoundationEncoder CreateWMAEncoder(WaveFormat sourceFormat, Stream targetStream, int bitRate = 192000) { if (sourceFormat == null) { throw new ArgumentNullException("sourceFormat"); } if (targetStream == null) { throw new ArgumentNullException("targetStream"); } if (targetStream.CanWrite != true) { throw new ArgumentException("Stream not writeable.", "targetStream"); } var targetMediaType = FindBestMediaType(MediaFoundation.MFMediaTypes.MFAudioFormat_WMAudioV8, sourceFormat.SampleRate, sourceFormat.Channels, bitRate); var sourceMediaType = MediaFoundationCore.MediaTypeFromWaveFormat(sourceFormat); if (targetMediaType == null) { throw new PlatformNotSupportedException("No WMA-Encoder was found."); } return(new MediaFoundationEncoder(targetStream, sourceMediaType, targetMediaType, TranscodeContainerTypes.MFTranscodeContainerType_ASF)); }
private MFSourceReader Initialize(MFSourceReader reader) { MediaFoundationCore.Startup(); try { reader.SetStreamSelection(MFInterops.MF_SOURCE_READER_ALL_STREAMS, false); reader.SetStreamSelection(MFInterops.MF_SOURCE_READER_FIRST_AUDIO_STREAM, true); using (var mediaType = MFMediaType.CreateEmpty()) { mediaType.MajorType = MediaTypes.MediaTypeAudio; mediaType.SubType = MediaTypes.MEDIATYPE_Pcm; //variable?? reader.SetCurrentMediaType(MFInterops.MF_SOURCE_READER_FIRST_AUDIO_STREAM, mediaType); } using (var currentMediaType = reader.GetCurrentMediaType(MFInterops.MF_SOURCE_READER_FIRST_AUDIO_STREAM)) { if (currentMediaType.MajorType != MediaTypes.MediaTypeAudio) { throw new InvalidOperationException(String.Format("Invalid Majortype set on sourcereader: {0}.", currentMediaType.MajorType.ToString())); } AudioEncoding encoding; if (currentMediaType.SubType == MediaTypes.MEDIATYPE_Pcm) { encoding = AudioEncoding.Pcm; } else if (currentMediaType.SubType == MediaTypes.MEDIATYPE_IeeeFloat) { encoding = AudioEncoding.IeeeFloat; } else { throw new InvalidOperationException(String.Format("Invalid Subtype set on sourcereader: {0}.", currentMediaType.SubType.ToString())); } _waveFormat = new WaveFormat(currentMediaType.SampleRate, currentMediaType.BitsPerSample, currentMediaType.Channels, encoding); } reader.SetStreamSelection(MFInterops.MF_SOURCE_READER_FIRST_AUDIO_STREAM, true); if (_hasFixedLength) { _length = GetLength(reader); } return(reader); } catch (Exception) { Dispose(); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="MediaFoundationDecoder" /> class. /// </summary> /// <param name="url">Uri which points to an audio source which can be decoded.</param> public MediaFoundationDecoder(string url) { if (String.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } _hasFixedLength = true; _reader = Initialize(MediaFoundationCore.CreateSourceReaderFromUrl(url)); }
protected static MFMediaType FindBestMediaType(Guid audioSubType, int sampleRate, int channels, int bitRate) { var mediaTypes = MediaFoundationCore.GetEncoderMediaTypes(audioSubType); var n = mediaTypes.Where(x => x.SampleRate == sampleRate && x.Channels == channels); var availableMediaTypes = n.Select(x => new { mediaType = x, dif = Math.Abs(bitRate - (x.AverageBytesPerSecond * 8)) }); return(availableMediaTypes.OrderBy(x => x.dif).Select(x => x.mediaType).FirstOrDefault()); }
protected void SetTargetStream(Stream stream, MFMediaType inputMediaType, MFMediaType targetMediaType, Guid containerType) { IMFAttributes attributes = null; try { _targetStream = MediaFoundationCore.IStreamToByteStream(new ComStream(stream)); MFByteStreamCapsFlags flags = MFByteStreamCapsFlags.None; int result = _targetStream.GetCapabilities(ref flags); attributes = MediaFoundationCore.CreateEmptyAttributes(2); attributes.SetUINT32(MediaFoundationAttributes.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1); attributes.SetGUID(MediaFoundationAttributes.MF_TRANSCODE_CONTAINERTYPE, containerType); _sinkWriter = MediaFoundationCore.CreateSinkWriterFromMFByteStream(_targetStream, attributes); _streamIndex = _sinkWriter.AddStream(targetMediaType); _sinkWriter.SetInputMediaType(_streamIndex, inputMediaType, null); _inputMediaType = inputMediaType; _targetMediaType = targetMediaType; _sourceBytesPerSecond = inputMediaType.AverageBytesPerSecond; //initialize the sinkwriter _sinkWriter.BeginWriting(); } catch (Exception) { if (_sinkWriter != null) { _sinkWriter.Dispose(); _sinkWriter = null; } if (_targetStream != null) { _targetStream.Close(); Marshal.ReleaseComObject(_targetStream); _targetStream = null; } throw; } finally { if (attributes != null) { Marshal.ReleaseComObject(attributes); } } }
/// <summary> /// Initializes a new instance of the <see cref="MediaFoundationDecoder" /> class. /// </summary> /// <param name="stream">Stream which provides the audio data to decode.</param> public MediaFoundationDecoder(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanRead) { throw new ArgumentException("Stream is not readable.", "stream"); } stream = new ComStream(stream); _stream = stream; _byteStream = MediaFoundationCore.IStreamToByteStream((IStream)stream); _reader = Initialize(_byteStream); }
/// <summary> /// Sets and initializes the targetstream for the encoding process. /// </summary> /// <param name="stream">Stream which should be used as the targetstream.</param> /// <param name="inputMediaType">Mediatype of the raw input data to encode.</param> /// <param name="targetMediaType">Mediatype of the encoded data.</param> /// <param name="containerType">Container type which should be used.</param> protected void SetTargetStream(Stream stream, MFMediaType inputMediaType, MFMediaType targetMediaType, Guid containerType) { MFAttributes attributes = null; try { _targetBaseStream = new ComStream(stream); _targetStream = MediaFoundationCore.IStreamToByteStream(_targetBaseStream); attributes = new MFAttributes(2); attributes.SetUINT32(MediaFoundationAttributes.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1); attributes.SetGuid(MediaFoundationAttributes.MF_TRANSCODE_CONTAINERTYPE, containerType); _sinkWriter = new MFSinkWriter(_targetStream, attributes); _streamIndex = _sinkWriter.AddStream(targetMediaType); _sinkWriter.SetInputMediaType(_streamIndex, inputMediaType, null); _targetMediaType = targetMediaType; _sourceBytesPerSecond = inputMediaType.AverageBytesPerSecond; //initialize the sinkwriter _sinkWriter.BeginWriting(); } catch (Exception) { if (_sinkWriter != null) { _sinkWriter.Dispose(); _sinkWriter = null; } if (_targetStream != null) { _targetStream.Dispose(); _targetStream = null; } throw; } finally { if (attributes != null) { attributes.Dispose(); } } }
static MediaFoundationDecoder() { MediaFoundationCore.Startup(); //make sure that the MediaFoundation is started up. }
/// <summary> /// Initializes a new instance of the <see cref="MFMediaBuffer"/> class with the specified maximum <paramref name="size"/>. /// </summary> /// <param name="size">The size of the <see cref="MFMediaBuffer"/> in bytes. The specified <paramref name="size"/> will be the <see cref="MaxLength"/> of the constructed <see cref="MFMediaBuffer"/>.</param> /// <remarks>The caller needs to release the allocated memory by disposing the <see cref="MFMediaBuffer"/>.</remarks> public MFMediaBuffer(int size) : this(MediaFoundationCore.CreateMemoryBuffer(size)) { }
/// <summary> /// Initializes a new instance of the <see cref="MFByteStream"/> class which acts as a wrapper for the specified <paramref name="stream"/> to use it in a media foundation context. /// </summary> /// <param name="stream">The stream to wrap for media foundation usage.</param> public MFByteStream(Stream stream) : this(MediaFoundationCore.StreamToByteStreamNative(stream)) { }
static MediaFoundationEncoder() { MediaFoundationCore.Startup(); }
private MFSourceReader Initialize(IMFByteStream stream) { MediaFoundationCore.Startup(); return(Initialize(MediaFoundationCore.CreateSourceReaderFromByteStream(stream, IntPtr.Zero))); }
public static MFMediaType CreateEmpty() { MediaFoundationCore.Startup(); return(MediaFoundationCore.CreateMediaType()); }
private MFSourceReader Initialize(MFByteStream byteStream) { return(Initialize(MediaFoundationCore.CreateSourceReaderFromByteStream(byteStream.BasePtr, IntPtr.Zero))); }
/// <summary> /// Initializes a new instance of the <see cref="MFSinkWriter"/> class with a underlying <paramref name="byteStream"/>. /// </summary> /// <param name="byteStream">The underlying <see cref="MFByteStream"/> to use.</param> /// <param name="attributes">Attributes to configure the <see cref="MFSinkWriter"/>. For more information, see <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd389284(v=vs.85).aspx"/>. Use null/nothing as the default value.</param> public MFSinkWriter(MFByteStream byteStream, MFAttributes attributes = null) : this(MediaFoundationCore.CreateSinkWriterFromMFByteStreamNative(byteStream, attributes)) { }
/// <summary> /// Initializes a new instance of the <see cref="MFSample"/> class. /// </summary> /// <remarks>Calls the MFCreateSample function.</remarks> public MFSample() : this(MediaFoundationCore.CreateEmptySample()) { }
/// <summary> /// Initializes a new instance of the <see cref="MFSourceReader"/> class based on a given <paramref name="url"/>. /// </summary> /// <param name="url">The URL.</param> public MFSourceReader(string url) : this(MediaFoundationCore.CreateSourceReaderFromUrlNative(url)) { }
public static MFMediaType FromWaveFormat(WaveFormat waveFormat) { MediaFoundationCore.Startup(); return(MediaFoundationCore.MediaTypeFromWaveFormat(waveFormat)); }
/// <summary> /// Initializes a new instance of the <see cref="MFByteStream"/> class which acts as a wrapper for the specified <paramref name="stream"/> to use it in a media foundation context. /// </summary> /// <param name="stream">The stream to wrap for media foundation usage.</param> /// <param name="closeStreamOnDispose">A value indicating whether the <paramref name="stream"/> should be closed when the /// <see cref="Dispose"/> method is being called.</param> public MFByteStream(Stream stream, bool closeStreamOnDispose) : this(MediaFoundationCore.StreamToByteStreamNative(stream, closeStreamOnDispose)) { }