//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); } } }
/// <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; } } }
/// <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 = ×tamp) { 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); } }
/// <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 = ×tamp) { 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; } }
/// <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); } }
//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; } } }
/// <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"); }
/// <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])); }
/// <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]); }
/// <summary> /// Delivers a sample to the sink writer. /// </summary> public void WriteSample(int streamIndex, MFSample sample) { MediaFoundationException.Try(WriteSampleNative(streamIndex, sample), c, "WriteSample"); }