[Bf-blender-cvs] [10528a5cd4e] blender-v2.83-release: Fix Frame Dropping not dropping the correct amount of frames

Sebastian Parborg noreply at git.blender.org
Tue May 19 12:23:45 CEST 2020


Commit: 10528a5cd4eacad7d67e0939f0e0941d8c499876
Author: Sebastian Parborg
Date:   Tue May 12 13:19:20 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rB10528a5cd4eacad7d67e0939f0e0941d8c499876

Fix Frame Dropping not dropping the correct amount of frames

Previously the playback mode "Frame Dropping" would not drop the correct
number of frames which would lead to slow playback.

For example, the playback target is 60fps.  However we can only muster
around 32 fps.

The delta frames from the last step is in this case ~1.98 or so.

With the previous code, we would floor this.  That would lead us to step
forward one frame each time, effectively playing back the animation at
half the speed as we will try to render every frame.

To fix this we simply save the remaining fraction from the previous
frame and use it to compute the current frame step.

Reviewed By: Sybren

Differential Revision: http://developer.blender.org/D7694

===================================================================

M	source/blender/editors/include/ED_screen_types.h
M	source/blender/editors/screen/screen_ops.c

===================================================================

diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index 06c2c3039f5..51f3eea74fa 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -34,11 +34,11 @@ extern "C" {
 typedef struct ScreenAnimData {
   ARegion *region; /* do not read from this, only for comparing if region exists */
   short redraws;
-  short flag;           /* flags for playback */
-  int sfra;             /* frame that playback was started from */
-  int nextfra;          /* next frame to go to (when ANIMPLAY_FLAG_USE_NEXT_FRAME is set) */
-  double last_duration; /* used for frame dropping */
-  bool from_anim_edit;  /* playback was invoked from animation editor */
+  short flag;                 /* flags for playback */
+  int sfra;                   /* frame that playback was started from */
+  int nextfra;                /* next frame to go to (when ANIMPLAY_FLAG_USE_NEXT_FRAME is set) */
+  double lagging_frame_count; /* used for frame dropping */
+  bool from_anim_edit;        /* playback was invoked from animation editor */
 } ScreenAnimData;
 
 /* for animplayer */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 57367abca1a..90813c9351c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -4443,10 +4443,29 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
     }
     else {
       if (sync) {
-        /* note: this is very simplistic,
-         * its has problem that it may skip too many frames.
-         * however at least this gives a less jittery playback */
-        const int step = max_ii(1, floor((wt->duration - sad->last_duration) * FPS));
+        /* Try to keep the playback in realtime by dropping frames. */
+
+        /* How much time (in frames) has passed since the last frame was drawn? */
+        double delta_frames = wt->delta * FPS;
+
+        /* Add the remaining fraction from the last time step. */
+        delta_frames += sad->lagging_frame_count;
+
+        if (delta_frames < 1.0) {
+          /* We can render faster than the scene frame rate. However skipping or delaying frames
+           * here seems to in practice lead to jittery playback so just step forward a minimum of
+           * one frame. (Even though this can lead to too fast playback, the jitteryness is more
+           * annoying)
+           */
+          delta_frames = 1.0f;
+          sad->lagging_frame_count = 0;
+        }
+        else {
+          /* Extract the delta frame fractions that will be skipped when converting to int. */
+          sad->lagging_frame_count = delta_frames - (int)delta_frames;
+        }
+
+        const int step = delta_frames;
 
         /* skip frames */
         if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
@@ -4467,8 +4486,6 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
       }
     }
 
-    sad->last_duration = wt->duration;
-
     /* reset 'jumped' flag before checking if we need to jump... */
     sad->flag &= ~ANIMPLAY_FLAG_JUMPED;



More information about the Bf-blender-cvs mailing list