//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);
                }
            }
        }
示例#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);
                }
            }
        }
        /// <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;
                }
            }
        }
示例#4
0
        /// <summary>
        /// Reads the next sample from the media source.
        /// </summary>
        /// <returns>HRESULT</returns>
        public unsafe int ReadSampleNative(int streamIndex, int controlFlags, out int actualStreamIndex, out MFSourceReaderFlag streamFlags, out long timestamp, out MFSample sample)
        {
            IntPtr psample = IntPtr.Zero;

            fixed(void *ptr0 = &actualStreamIndex, ptr1 = &streamFlags, ptr2 = &timestamp)
            {
                int result = InteropCalls.CalliMethodPtr(_basePtr, streamIndex, controlFlags, ptr0, ptr1, ptr2, &psample, ((void **)(*(void **)_basePtr))[9]);

                sample = psample == IntPtr.Zero ? null : new MFSample(psample);
                return(result);
            }
        }
示例#5
0
 /// <summary>
 /// Reads the next sample from the media source.
 /// </summary>
 /// <returns>HRESULT</returns>
 public unsafe int ReadSampleNative(int streamIndex, int controlFlags, out int actualStreamIndex, out MFSourceReaderFlag streamFlags, out long timestamp, out MFSample sample)
 {
     IntPtr psample = IntPtr.Zero;
     fixed (void* ptr0 = &actualStreamIndex, ptr1 = &streamFlags, ptr2 = &timestamp)
     {
         int result = InteropCalls.CalliMethodPtr(_basePtr, streamIndex, controlFlags, ptr0, ptr1, ptr2, &psample, ((void**)(*(void**)_basePtr))[9]);
         sample = psample == IntPtr.Zero ? null : new MFSample(psample);
         return result;
     }
 }
示例#6
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);
            }
        }
示例#7
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;
                }
            }
        }
示例#8
0
 /// <summary>
 /// Delivers a sample to the sink writer.
 /// </summary>
 /// <param name="streamIndex">The zero-based index of the stream for this sample.</param>
 /// <param name="sample">The sample to write.</param>
 /// <remarks>You must call <see cref="BeginWriting"/> before calling this method.</remarks>
 public void WriteSample(int streamIndex, MFSample sample)
 {
     MediaFoundationException.Try(WriteSampleNative(streamIndex, sample), InterfaceName, "WriteSample");
 }
示例#9
0
        /// <summary>
        /// Delivers a sample to the sink writer.
        /// <seealso cref="WriteSample"/>
        /// </summary>
        /// <param name="streamIndex">The zero-based index of the stream for this sample.</param>
        /// <param name="sample">The sample to write.</param>
        /// <returns>HRESULT</returns>
        /// <remarks>You must call <see cref="BeginWriting"/> before calling this method.</remarks>
        public unsafe int WriteSampleNative(int streamIndex, MFSample sample)
        {
            void *ps = (void *)(sample == null ? IntPtr.Zero : sample.BasePtr);

            return(InteropCalls.CalliMethodPtr(UnsafeBasePtr, streamIndex, ps, ((void **)(*(void **)UnsafeBasePtr))[6]));
        }
示例#10
0
 /// <summary>
 /// Delivers a sample to the sink writer.
 /// </summary>
 /// <returns>HRESULT</returns>
 public unsafe int WriteSampleNative(int streamIndex, MFSample sample)
 {
     void* ps = (void*)(sample == null ? IntPtr.Zero : sample.BasePtr);
     return InteropCalls.CalliMethodPtr(_basePtr, streamIndex, ps, ((void**)(*(void**)_basePtr))[6]);
 }
示例#11
0
 /// <summary>
 /// Delivers a sample to the sink writer.
 /// </summary>
 public void WriteSample(int streamIndex, MFSample sample)
 {
     MediaFoundationException.Try(WriteSampleNative(streamIndex, sample), c, "WriteSample");
 }