Example #1
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);
            }
        }
Example #2
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);
            }
        }