/// <summary> /// Renders the video image. This method is called on a Dispatcher timer. /// It is responsible for rendering the decoded video image continuously. /// It also avoids rendering the same image again. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void RenderVideoImage(object sender, EventArgs e) { MediaFramesExtractedDone.Wait(Constants.FrameExtractorWaitMs); var renderTime = RealtimeClock.PositionSeconds; try { var videoFrame = VideoFramesCache.GetFrame(renderTime, false); if (videoFrame == null || videoFrame == LastRenderedVideoFrame) { return; } if (videoFrame.PictureBufferPtr != IntPtr.Zero) { VideoRenderer.Lock(); Helper.NativeMethods.RtlMoveMemory(VideoRenderer.BackBuffer, videoFrame.PictureBufferPtr, videoFrame.PictureBufferLength); VideoRenderer.AddDirtyRect(new Int32Rect(0, 0, VideoRenderer.PixelWidth, VideoRenderer.PixelHeight)); VideoRenderer.Unlock(); LastRenderedVideoFrame = videoFrame; } } finally { this.Position = renderTime; } }