unosquare / ffmediaelement

FFME: The Advanced WPF MediaElement (based on FFmpeg)
https://unosquare.github.io/ffmediaelement/
Other
1.18k stars 244 forks source link

Incorrect Display of Frames in Manual Video Advancement using .Position #443

Closed VideoSystems closed 4 years ago

VideoSystems commented 5 years ago

Incorrect Display of Frames in Manual Video Advancement using .Position

*We have a 200 FPS video loaded into the player, and either by using a slider to advance the player.Position property, or using a DispatcherTimer that advances the position of the player, if the video is advanced too quickly we get jerky playback. I created a video to visually illustrate the problem.

Video showing issue: http://www.jcvideo.com/AdvanceVideoIssue01.mp4 You can download 200 FPS video to attempt with here: http://www.jcvideo.com/200FPS.mp4 *

Issue Categories

Version Information

Steps to Reproduce

  1. Load 200 FPS video into the player.
  2. Manually advance the position of the player through code using a timer or using slider.
  3. Video when advanced slowly is smooth in advancement from frame to frame. If advanced too quickly, the video becomes jerky as it displays incorrect frames.

Expected Results

Sample Code

XAML

### C# public void PlayVideo(string filePath, Unosquare.FFME.MediaElement player) { if (filePath != "") { player.Source = new Uri(filePath); player.Stretch = Stretch.UniformToFill; } } private void playerScrubber_DragDelta(object sender, RadDragDeltaEventArgs e) { player.Position = TimeSpan.FromSeconds(scrubber.Value); } private void Player_MediaReady(object sender, EventArgs e) { DispatcherTimer playerPositionTimer = new DispatcherTimer(); playerPositionTimer.Tick += AdvancePlayer; playerPositionTimer.Interval = new TimeSpan(0, 0, 0, 0, 200); playerPositionTimer.Start(); } private async void AdvancePlayer(object sender, EventArgs e) { TimeSpan actualPosition = (TimeSpan)player.ActualPosition; await player.Seek(actualPosition.Add(TimeSpan.FromMilliseconds(20))); //Advances slowly and smoothly //await player.Seek(actualPosition.Add(TimeSpan.FromMilliseconds(50))); //Advances choppy }
mariodivece commented 5 years ago

Try setting MediaOptions.IsFluidSeekingDisabled = true Related Issue: #379

Please share your results!

VideoSystems commented 5 years ago

Ok, my apologies for the delay in getting back with results.

While setting IsFluidSeekingDisabled to true did make an improvement, it did not solve the issue entirely.

I found by trying to introduce an animation over the video using the BufferingStarted and BufferingEnded methods of the player, that every time there was a delay or skip in playback, that the buffering animation fired even though the video was local on the machine. I found a property called "VideoBlockCache" and set that to a higher number (1000). While the RAM increased, the video scrubs perfectly smooth and as quickly as I drag the scrubber! This was definitely the solution needed for smooth scrubbing of videos.

Do you have any further documentation on the VideoBlockCache setting?

mariodivece commented 4 years ago

Thanks for sharing the results! The VideoBlockCache is simply the number of video blocks to keep in memory. Let me see if I can explain what this does.

So the block cache settings are referring to how many frames to decode, transform for rendering and keep in memory ready for rendering. The engine will point to the middle block of the cache when rendering. As time passes and a new block gets decoded, the oldest block gets discarded from the cache to make room for the latest decoded block.

I hope I made some sense.