/// <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
            });
        }
예제 #2
0
        /// <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);
                }
            }
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        /// <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));
        }
예제 #6
0
        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());
        }
예제 #7
0
        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);
                }
            }
        }
예제 #8
0
        /// <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();
                }
            }
        }
예제 #10
0
 static MediaFoundationDecoder()
 {
     MediaFoundationCore.Startup(); //make sure that the MediaFoundation is started up.
 }
예제 #11
0
 /// <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))
 {
 }
예제 #12
0
 /// <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();
 }
예제 #14
0
 private MFSourceReader Initialize(IMFByteStream stream)
 {
     MediaFoundationCore.Startup();
     return(Initialize(MediaFoundationCore.CreateSourceReaderFromByteStream(stream, IntPtr.Zero)));
 }
예제 #15
0
 public static MFMediaType CreateEmpty()
 {
     MediaFoundationCore.Startup();
     return(MediaFoundationCore.CreateMediaType());
 }
예제 #16
0
 private MFSourceReader Initialize(MFByteStream byteStream)
 {
     return(Initialize(MediaFoundationCore.CreateSourceReaderFromByteStream(byteStream.BasePtr, IntPtr.Zero)));
 }
예제 #17
0
 /// <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))
 {
 }
예제 #18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MFSample"/> class.
 /// </summary>
 /// <remarks>Calls the MFCreateSample function.</remarks>
 public MFSample()
     : this(MediaFoundationCore.CreateEmptySample())
 {
 }
예제 #19
0
 /// <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))
 {
 }
예제 #20
0
 public static MFMediaType FromWaveFormat(WaveFormat waveFormat)
 {
     MediaFoundationCore.Startup();
     return(MediaFoundationCore.MediaTypeFromWaveFormat(waveFormat));
 }
예제 #21
0
 /// <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))
 {
 }