/// <summary> /// Reads the next frame and returns the corresponding buffer. /// Null is returned if there was nothing to read. /// </summary> protected SeeingSharpMediaBuffer ReadFrameInternal() { if (m_endReached) { return(null); } MF.SourceReaderFlags readerFlags; int dummyStreamIndex; using (MF.Sample nextSample = m_sourceReader.ReadSample( MF.SourceReaderIndex.FirstVideoStream, MF.SourceReaderControlFlags.None, out dummyStreamIndex, out readerFlags, out m_currentPositionLong)) { // Check for end-of-stream if (readerFlags == MF.SourceReaderFlags.Endofstream) { m_endReached = true; return(null); } // No sample received if (nextSample == null) { return(null); } // Reset end-reached flag (maybe the user called SetPosition again..) m_endReached = false; // Copy pixel data into target buffer if (nextSample.BufferCount > 0) { return(new SeeingSharpMediaBuffer(nextSample.GetBufferByIndex(0))); } } return(null); }
/// <summary> /// Gets the decoded PCM samples. See remarks. /// </summary> /// <param name="startingPositionInSeconds">The starting position in seconds.</param> /// <returns>An enumerator of pointer to PCM decoded data with the same format as returned by <see cref="WaveFormat"/>.</returns> /// <remarks> /// This method is only working as a single enumerator at a time. /// The <see cref="SetSourceStream(System.IO.Stream)"/> must be set before calling <see cref="GetSamples()"/> /// </remarks> public IEnumerable <DataPointer> GetSamples(TimeSpan startingPositionInSeconds) { // A new reader is setup, so initialize it. lock (sourceReaderLock) { // If the reader was changed if (nextSourceReader != null) { if (sourceReader != null) { sourceReader.Dispose(); } sourceReader = nextSourceReader; nextSourceReader = null; } } // Make sure that any prior call CleanupAndDispose(); CheckIfDisposed(); // Set the position sourceReader.SetCurrentPosition((long)(startingPositionInSeconds.Ticks)); while (true) { int streamIndex; SourceReaderFlags flags; long time; CheckIfDisposed(); using (currentSample = sourceReader.ReadSample(SourceReaderIndex.FirstAudioStream, SourceReaderControlFlags.None, out streamIndex, out flags, out time)) { if ((flags & SourceReaderFlags.Endofstream) != 0) { break; } CheckIfDisposed(); using (currentBuffer = currentSample.ConvertToContiguousBuffer()) { int bufferMaxLength; int bufferCurrentLength; CheckIfDisposed(); var ptr = currentBuffer.Lock(out bufferMaxLength, out bufferCurrentLength); yield return(new DataPointer(ptr, bufferCurrentLength)); // Warning, because the yield could never return here, currentBuffer and currentSample should be disposed when disposing this object or when // calling it again on the GetSamples method. // In case a Dispose occurred while decoding if (currentBuffer == null) { break; } currentBuffer.Unlock(); } } } // They have been disposed, so we can just clear them currentBuffer = null; currentSample = null; }