/// <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);
                }
            }
        }
Beispiel #4
0
        /// <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();
            }
        }