/// <summary> /// Initializes a new instance of the <see cref="AsyncRealtimeVideoReader"/> class. /// </summary> /// <param name="captureDevice">The capture device.</param> /// <param name="immediateStart">True to start video reading immediately.</param> public AsyncRealtimeVideoReader(CaptureDeviceInfo captureDevice, bool immediateStart = true) : base(captureDevice) { // Start immediately if requested m_currentBufferLock = new object(); m_currentBuffer = null; m_currentBufferTimestamp = DateTime.MinValue; if (immediateStart) { this.Start(); } }
/// <summary> /// Initializes a new instance of the <see cref="AsyncRealtimeVideoReader"/> class. /// </summary> /// <param name="videoSource">The source of the video file.</param> /// <param name="immediateStart">True to start video reading immediately.</param> public AsyncRealtimeVideoReader(ResourceLink videoSource, bool immediateStart = true) : base(videoSource) { // Start immediately if requested m_currentBufferLock = new object(); m_currentBuffer = null; m_currentBufferTimestamp = DateTime.MinValue; if (immediateStart) { this.Start(); } }
/// <summary> /// Performs asynchronous video reading. /// </summary> /// <param name="cancelToken">The cancel token.</param> private async Task PerformVideoReadingAsync(CancellationToken cancelToken) { // Ensure that we are working on the ThreadPool // => Thread.CurrentThread.IsThreadPoolThread not possible on WinRT platform await Task.Delay(100).ConfigureAwait(false); bool doContinue = true; bool endReached = false; while (doContinue && (!cancelToken.IsCancellationRequested) && (!this.IsDisposed)) { bool currentBufferChanged = false; // Read next frame SeeingSharpMediaBuffer mediaBuffer = this.ReadFrameInternal(); if (mediaBuffer != null) { lock (m_currentBufferLock) { GraphicsHelper.SafeDispose(ref m_currentBuffer); m_currentBuffer = mediaBuffer; m_currentBufferTimestamp = DateTime.UtcNow; m_processedFrameCount++; currentBufferChanged = true; endReached = false; } } // Fire VideoReachedEnd event if (base.EndReached && (!endReached)) { endReached = true; try { VideoReachedEnd.Raise(this, EventArgs.Empty); } catch { // TODO: Raise an alert or something here } } // Wait some time because we could no read the last frame if (!currentBufferChanged) { await Task.Delay(200); } } }
/// <summary> /// Reads the next frame and puts it into the provided buffer. /// </summary> /// <param name="targetBuffer">The target buffer to write to.</param> public bool ReadFrame(MemoryMappedTexture32bpp targetBuffer) { this.EnsureNotNullOrDisposed("this"); targetBuffer.EnsureNotNull(nameof(targetBuffer)); if ((targetBuffer.Width != base.FrameSize.Width) || (targetBuffer.Height != base.FrameSize.Height)) { throw new SeeingSharpGraphicsException("Size of the given buffer does not match the video size!"); } // Read the frame SeeingSharpMediaBuffer mediaSharpManaged = base.ReadFrameInternal(); if (mediaSharpManaged == null) { return(false); } // Process the frame try { MF.MediaBuffer mediaBuffer = mediaSharpManaged.GetBuffer(); int cbMaxLength; int cbCurrentLenght; IntPtr mediaBufferPointer = mediaBuffer.Lock(out cbMaxLength, out cbCurrentLenght); // Performance optimization using CopyMemory method // see http://www.rolandk.de/wp/2015/05/wie-schnell-man-speicher-falsch-kopieren-kann/ CommonTools.CopyMemory( mediaBufferPointer, targetBuffer.Pointer, (ulong)(base.FrameSize.Width * base.FrameSize.Height * 4)); return(true); } finally { mediaSharpManaged.Dispose(); } }