[Bf-blender-cvs] [ec173298a05] temp-VSE-fixes: VSE: Fix video strip duration calculation

Sebastian Parborg noreply at git.blender.org
Fri Aug 13 16:49:27 CEST 2021


Commit: ec173298a05496d64c9d74c442a8fbb846c6b9bd
Author: Sebastian Parborg
Date:   Mon Jul 12 16:00:43 2021 +0200
Branches: temp-VSE-fixes
https://developer.blender.org/rBec173298a05496d64c9d74c442a8fbb846c6b9bd

VSE: Fix video strip duration calculation

The video duration was not read correctly from the video file.

It would use the global duration of the file which does in some cases
not line up with the actual duration of the video stream.
Now we take the video stream duration and start time into account when
calculating the strip duration.

Reviewed By: Richard Antalik

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

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

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 47514308ae4..c08df2889de 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -616,10 +616,50 @@ static int startffmpeg(struct anim *anim)
       }
     }
   }
-  /* Fall back to the container. */
+  /* Fall back to manually estimating the video stream duration.
+   * This is because the video stream duration can be shorter than the pFormatCtx->duration.
+   */
   if (anim->duration_in_frames == 0) {
-    anim->duration_in_frames = (int)(pFormatCtx->duration * av_q2d(frame_rate) / AV_TIME_BASE +
-                                     0.5f);
+    double pts_time_base = av_q2d(video_stream->time_base);
+    double stream_dur;
+
+    if (video_stream->duration != AV_NOPTS_VALUE) {
+      stream_dur = video_stream->duration * pts_time_base;
+    }
+    else {
+      double video_start = 0;
+      double audio_start = 0;
+
+      if (video_stream->start_time != AV_NOPTS_VALUE) {
+        video_start = video_stream->start_time * pts_time_base;
+      }
+
+      /* Find audio stream to guess the duration of the video.
+       * Sometimes the audio AND the video stream have a start offset.
+       * The difference between these is the offset we want to use to
+       * calculate the video duration.
+       */
+      for (i = 0; i < pFormatCtx->nb_streams; i++) {
+        if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+          AVStream *audio_stream = pFormatCtx->streams[i];
+          if (audio_stream->start_time != AV_NOPTS_VALUE) {
+            audio_start = audio_stream->start_time * av_q2d(audio_stream->time_base);
+          }
+          break;
+        }
+      }
+
+      if (video_start > audio_start) {
+        stream_dur = (double)pFormatCtx->duration / AV_TIME_BASE - (video_start - audio_start);
+      }
+      else {
+        /* The video stream starts before or at the same time as the audio stream!
+         * We have to assume that the video stream is as long as the full pFormatCtx->duration.
+         */
+        stream_dur = (double)pFormatCtx->duration / AV_TIME_BASE;
+      }
+    }
+    anim->duration_in_frames = (int)(stream_dur * av_q2d(frame_rate) + 0.5f);
   }
 
   frs_num = frame_rate.num;



More information about the Bf-blender-cvs mailing list