[Bf-blender-cvs] [f2b24272dd7] master: Fix T93328: Movie seeking doesn't work.

Richard Antalik noreply at git.blender.org
Fri Jan 28 00:27:21 CET 2022


Commit: f2b24272dd7c8dd0ed13604b082247fda970e069
Author: Richard Antalik
Date:   Thu Jan 27 23:15:03 2022 +0100
Branches: master
https://developer.blender.org/rBf2b24272dd7c8dd0ed13604b082247fda970e069

Fix T93328: Movie seeking doesn't work.

Caused by integer overflow in `steps_per_frame` calculation.

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

M	source/blender/imbuf/intern/anim_movie.c

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

diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 17e82fc79c9..38dbb9bfc47 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -993,21 +993,23 @@ static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx)
   return false;
 }
 
-static int64_t ffmpeg_get_seek_pts(struct anim *anim, int64_t pts_to_search)
+static double ffmpeg_steps_per_frame_get(struct anim *anim)
 {
   AVStream *v_st = anim->pFormatCtx->streams[anim->videoStream];
-  AVRational frame_rate = v_st->r_frame_rate;
   AVRational time_base = v_st->time_base;
-  double steps_per_frame = (double)(frame_rate.den * time_base.den) /
-                           (double)(frame_rate.num * time_base.num);
+  AVRational frame_rate = av_guess_frame_rate(anim->pFormatCtx, v_st, NULL);
+  return av_q2d(av_inv_q(av_mul_q(frame_rate, time_base)));
+  ;
+}
+
+static int64_t ffmpeg_get_seek_pts(struct anim *anim, int64_t pts_to_search)
+{
   /* Step back half a frame position to make sure that we get the requested
    * frame and not the one after it. This is a workaround as ffmpeg will
    * sometimes not seek to a frame after the requested pts even if
    * AVSEEK_FLAG_BACKWARD is specified.
    */
-  int64_t pts = pts_to_search - (steps_per_frame / 2);
-
-  return pts;
+  return pts_to_search - (ffmpeg_steps_per_frame_get(anim) / 2);
 }
 
 /* This gives us an estimate of which pts our requested frame will have.
@@ -1026,13 +1028,8 @@ static int64_t ffmpeg_get_pts_to_search(struct anim *anim,
   else {
     AVStream *v_st = anim->pFormatCtx->streams[anim->videoStream];
     int64_t start_pts = v_st->start_time;
-    AVRational frame_rate = v_st->r_frame_rate;
-    AVRational time_base = v_st->time_base;
 
-    double steps_per_frame = (double)(frame_rate.den * time_base.den) /
-                             (double)(frame_rate.num * time_base.num);
-
-    pts_to_search = round(position * steps_per_frame);
+    pts_to_search = round(position * ffmpeg_steps_per_frame_get(anim));
 
     if (start_pts != AV_NOPTS_VALUE) {
       pts_to_search += start_pts;
@@ -1122,13 +1119,6 @@ static int ffmpeg_generic_seek_workaround(struct anim *anim,
                                           int64_t *requested_pts,
                                           int64_t pts_to_search)
 {
-  AVStream *v_st = anim->pFormatCtx->streams[anim->videoStream];
-  AVRational frame_rate = v_st->r_frame_rate;
-  AVRational time_base = v_st->time_base;
-
-  double steps_per_frame = (double)(frame_rate.den * time_base.den) /
-                           (double)(frame_rate.num * time_base.num);
-
   int64_t current_pts = *requested_pts;
   int64_t offset = 0;
 
@@ -1136,7 +1126,7 @@ static int ffmpeg_generic_seek_workaround(struct anim *anim,
 
   /* Step backward frame by frame until we find the key frame we are looking for. */
   while (current_pts != 0) {
-    current_pts = *requested_pts - (int64_t)round(offset * steps_per_frame);
+    current_pts = *requested_pts - (int64_t)round(offset * ffmpeg_steps_per_frame_get(anim));
     current_pts = MAX2(current_pts, 0);
 
     /* Seek to timestamp. */



More information about the Bf-blender-cvs mailing list