Пример #1
0
 internal LockDisposable(MFMediaBuffer mediaBuffer, IntPtr buffer, int maxLength, int currentLength)
 {
     _mediaBuffer  = mediaBuffer;
     Buffer        = buffer;
     MaxLength     = maxLength;
     CurrentLength = currentLength;
 }
Пример #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);
                }
            }
        }
        //This method returns ticks, not bytes!
        private long WriteBlock(byte[] buffer, int offset, int count, int streamIndex, long positionInTicks,
                                int sourceBytesPerSecond)
        {
            using (var mfBuffer = new MFMediaBuffer(count))
            {
                using (var sample = new MFSample())
                {
                    sample.AddBuffer(mfBuffer);

                    using (var @lock = mfBuffer.Lock())
                    {
                        Marshal.Copy(buffer, offset, @lock.Buffer, count);
                        mfBuffer.SetCurrentLength(count);
                    }

                    long ticks = BytesToNanoSeconds(count, sourceBytesPerSecond);

                    sample.SetSampleTime(positionInTicks);
                    sample.SetSampleDuration(ticks);
                    _sinkWriter.WriteSample(streamIndex, sample);

                    return(ticks);
                }
            }
        }
Пример #4
0
 public unsafe int ConvertToContinousBufferNative(out MFMediaBuffer buffer)
 {
     IntPtr ptr = IntPtr.Zero;
     int result = InteropCalls.CalliMethodPtr(_basePtr, &ptr, ((void**)(*(void**)_basePtr))[41]);
     buffer = ptr == IntPtr.Zero ? null : new MFMediaBuffer(ptr);
     return result;
 }
Пример #5
0
 public unsafe int GetBufferByIndexNative(int index, out MFMediaBuffer buffer)
 {
     IntPtr ptr = IntPtr.Zero;
     int result = InteropCalls.CalliMethodPtr(_basePtr, index, &ptr, ((void**)(*(void**)_basePtr))[40]);
     buffer = ptr == IntPtr.Zero ? null : new MFMediaBuffer(ptr);
     return result;
 }
Пример #6
0
        public int Read(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (buffer.Length < count)
            {
                throw new ArgumentException("Length is too small.", "buffer");
            }

            lock (_lockObj)
            {
                int read = 0;

                if (_reader == null || _disposed)
                {
                    return(read);
                }

                if (_decoderBufferCount > 0)
                {
                    read += CopyDecoderBuffer(buffer, offset + read, count - read);
                }

                while (read < count)
                {
                    MFSourceReaderFlag flags;
                    long timestamp;
                    int  actualStreamIndex;
                    using (var sample = _reader.ReadSample(MFInterops.MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, out actualStreamIndex, out flags, out timestamp))
                    {
                        if (flags != MFSourceReaderFlag.None)
                        {
                            break;
                        }

                        using (MFMediaBuffer mediaBuffer = sample.ConvertToContinousBuffer())
                        {
                            int    maxlength, currentlength;
                            IntPtr pdata = mediaBuffer.Lock(out maxlength, out currentlength);
                            _decoderBuffer = _decoderBuffer.CheckBuffer(currentlength);
                            Marshal.Copy(pdata, _decoderBuffer, 0, currentlength);
                            _decoderBufferCount  = currentlength;
                            _decoderBufferOffset = 0;

                            int tmp = CopyDecoderBuffer(buffer, offset + read, count - read);
                            read += tmp;

                            mediaBuffer.Unlock();
                        }
                    }
                }

                _position += read;

                return(read);
            }
        }
Пример #7
0
        /// <summary>
        /// Converts a sample with multiple buffers into a sample with a single buffer.
        /// </summary>
        /// <param name="buffer">Receives a <see cref="MFMediaBuffer"/> instance. The caller must release the instance.</param>
        /// <returns>HRESULT</returns>
        public unsafe int ConvertToContiguousBufferNative(out MFMediaBuffer buffer)
        {
            IntPtr ptr    = IntPtr.Zero;
            int    result = InteropCalls.CalliMethodPtr(UnsafeBasePtr, &ptr, ((void **)(*(void **)UnsafeBasePtr))[41]);

            buffer = ptr == IntPtr.Zero ? null : new MFMediaBuffer(ptr);
            return(result);
        }
Пример #8
0
        /// <summary>
        /// Gets a buffer from the sample, by index.
        /// </summary>
        /// <param name="index">Index of the buffer. To find the number of buffers in the sample, call <see cref="GetBufferCount"/>. Buffers are indexed from zero. </param>
        /// <param name="buffer">Receives the <see cref="MFMediaBuffer"/> instance. The caller must release the object. </param>
        /// <returns>HRESULT</returns>
        /// <remarks>
        /// Note: In most cases, it is safer to use the <see cref="ConvertToContiguousBuffer"/> method.
        /// If the sample contains more than one buffer, the <see cref="ConvertToContiguousBuffer"/> method replaces them with a single buffer, copies the original data into that buffer, and returns the new buffer to the caller.
        /// The copy operation occurs at most once. On subsequent calls, no data is copied.
        /// </remarks>
        public unsafe int GetBufferByIndexNative(int index, out MFMediaBuffer buffer)
        {
            IntPtr ptr    = IntPtr.Zero;
            int    result = InteropCalls.CalliMethodPtr(UnsafeBasePtr, index, &ptr, ((void **)(*(void **)UnsafeBasePtr))[40]);

            buffer = ptr == IntPtr.Zero ? null : new MFMediaBuffer(ptr);
            return(result);
        }
Пример #9
0
 public void AddBuffer(MFMediaBuffer buffer)
 {
     MediaFoundationException.Try(AddBufferNative(buffer), c, "AddBuffer");
 }
Пример #10
0
 /// <summary>
 /// Adds a buffer to the end of the list of buffers in the sample. 
 /// </summary>
 /// <param name="buffer">The <see cref="MFMediaBuffer"/> to add.</param>
 /// <returns>HRESULT</returns>
 public unsafe int AddBufferNative(MFMediaBuffer buffer)
 {
     return InteropCalls.CalliMethodPtr(UnsafeBasePtr, (void*)((buffer == null) ? IntPtr.Zero : buffer.BasePtr), ((void**)(*(void**)UnsafeBasePtr))[42]);
 }
Пример #11
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;
                }
            }
        }
Пример #12
0
 internal LockDisposable(MFMediaBuffer mediaBuffer, IntPtr buffer, int maxLength, int currentLength)
 {
     _mediaBuffer = mediaBuffer;
     Buffer = buffer;
     MaxLength = maxLength;
     CurrentLength = currentLength;
 }
Пример #13
0
 public unsafe int CopyToBufferNative(MFMediaBuffer buffer)
 {
     return InteropCalls.CalliMethodPtr(_basePtr, (void*)((buffer == null) ? IntPtr.Zero : buffer.BasePtr), ((void**)(*(void**)_basePtr))[46]);
 }
Пример #14
0
 /// <summary>
 /// Copies the sample data to a buffer. This method concatenates the valid data from all of the buffers of the sample, in order.
 /// </summary>
 /// <param name="buffer">The <see cref="MFMediaBuffer"/> object of the destination buffer.
 /// The buffer must be large enough to hold the valid data in the sample.
 /// To get the size of the data in the sample, call <see cref="GetTotalLength"/>.</param>
 public void CopyToBuffer(MFMediaBuffer buffer)
 {
     MediaFoundationException.Try(CopyToBufferNative(buffer), InterfaceName, "CopyToBuffer");
 }
Пример #15
0
 /// <summary>
 /// Copies the sample data to a buffer. This method concatenates the valid data from all of the buffers of the sample, in order.
 /// </summary>
 /// <param name="buffer">The <see cref="MFMediaBuffer"/> object of the destination buffer.
 /// The buffer must be large enough to hold the valid data in the sample.
 /// To get the size of the data in the sample, call <see cref="GetTotalLength"/>.</param>
 /// <returns>HRESULT</returns>
 public unsafe int CopyToBufferNative(MFMediaBuffer buffer)
 {
     return(InteropCalls.CalliMethodPtr(UnsafeBasePtr, (void *)((buffer == null) ? IntPtr.Zero : buffer.BasePtr), ((void **)(*(void **)UnsafeBasePtr))[46]));
 }
Пример #16
0
 /// <summary>
 /// Adds a buffer to the end of the list of buffers in the sample.
 /// </summary>
 /// <param name="buffer">The <see cref="MFMediaBuffer"/> to add.</param>
 public void AddBuffer(MFMediaBuffer buffer)
 {
     MediaFoundationException.Try(AddBufferNative(buffer), InterfaceName, "AddBuffer");
 }
Пример #17
0
 public void CopyToBuffer(MFMediaBuffer buffer)
 {
     MediaFoundationException.Try(CopyToBufferNative(buffer), c, "CopyToBuffer");
 }
Пример #18
0
        //This method returns ticks, not bytes!
        private long WriteBlock(byte[] buffer, int offset, int count, int streamIndex, long positionInTicks,
            int sourceBytesPerSecond)
        {
            using (var mfBuffer = new MFMediaBuffer(count))
            {
                using (var sample = new MFSample())
                {
                    sample.AddBuffer(mfBuffer);

                    using (var @lock = mfBuffer.Lock())
                    {
                        Marshal.Copy(buffer, offset, @lock.Buffer, count);
                        mfBuffer.SetCurrentLength(count);
                    }

                    long ticks = BytesToNanoSeconds(count, sourceBytesPerSecond);

                    sample.SetSampleTime(positionInTicks);
                    sample.SetSampleDuration(ticks);
                    _sinkWriter.WriteSample(streamIndex, sample);

                    return ticks;
                }
            }
        }
Пример #19
0
        /// <summary>
        ///     Reads a sequence of bytes from the <see cref="MediaFoundationDecoder" /> and advances the position within the
        ///     stream by the
        ///     number of bytes read.
        /// </summary>
        /// <param name="buffer">
        ///     An array of bytes. When this method returns, the <paramref name="buffer" /> contains the specified
        ///     byte array with the values between <paramref name="offset" /> and (<paramref name="offset" /> +
        ///     <paramref name="count" /> - 1) replaced by the bytes read from the current source.
        /// </param>
        /// <param name="offset">
        ///     The zero-based byte offset in the <paramref name="buffer" /> at which to begin storing the data
        ///     read from the current stream.
        /// </param>
        /// <param name="count">The maximum number of bytes to read from the current source.</param>
        /// <returns>The total number of bytes read into the buffer.</returns>
        public int Read(byte[] buffer, int offset, int count)
        {
            CheckForDisposed();

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (buffer.Length < count)
            {
                throw new ArgumentException("Length is too small.", "buffer");
            }

            lock (_lockObj)
            {
                int read = 0;

                if (_reader == null || _disposed)
                {
                    return(read);
                }

                if (_decoderBufferCount > 0)
                {
                    read += CopyDecoderBuffer(buffer, offset + read, count - read);
                }

                while (read < count)
                {
                    MFSourceReaderFlags flags;
                    long timestamp;
                    int  actualStreamIndex;
                    using (
                        MFSample sample = _reader.ReadSample(NativeMethods.MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0,
                                                             out actualStreamIndex, out flags, out timestamp))
                    {
                        if (flags != MFSourceReaderFlags.None)
                        {
                            break;
                        }
                        var sampleTime = sample.GetSampleTime();
                        if (_positionChanged && timestamp > 0)
                        {
                            long actualPosition = NanoSecond100UnitsToBytes(sampleTime);
                            int  bytesToSkip    = (int)(_position - actualPosition);
                            _position        = actualPosition;
                            _positionChanged = false;

                            SkipBytes(bytesToSkip);
                        }

                        using (MFMediaBuffer mediaBuffer = sample.ConvertToContiguousBuffer())
                        {
                            using (MFMediaBuffer.LockDisposable @lock = mediaBuffer.Lock())
                            {
                                _decoderBuffer = _decoderBuffer.CheckBuffer(@lock.CurrentLength);
                                Marshal.Copy(@lock.Buffer, _decoderBuffer, 0, @lock.CurrentLength);
                                _decoderBufferCount  = @lock.CurrentLength;
                                _decoderBufferOffset = 0;

                                int tmp = CopyDecoderBuffer(buffer, offset + read, count - read);
                                read += tmp;
                            }
                        }
                    }
                }

                _position += read;

                return(read);
            }
        }
Пример #20
0
 public unsafe int AddBufferNative(MFMediaBuffer buffer)
 {
     return(InteropCalls.CalliMethodPtr(_basePtr, (void *)((buffer == null) ? IntPtr.Zero : buffer.BasePtr), ((void **)(*(void **)_basePtr))[42]));
 }