[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [32815] trunk/blender: == FFMPEG ==

Peter Schlaile peter at schlaile.de
Mon Nov 1 19:13:10 CET 2010


Revision: 32815
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32815
Author:   schlaile
Date:     2010-11-01 19:13:10 +0100 (Mon, 01 Nov 2010)

Log Message:
-----------
== FFMPEG ==

This fixes a rather subtle seeking issue with ffmpeg and Sony 
XDCAM-footage.

Problem is: MPEG2 streams within an MP4 container can contain a start 
time - at several places. There is a starttime within the video 
and audio streams and one within the container.

FFMpeg commandline tool only uses the container starttime and we used 
the stream starttime. 

The world would be a better place, if those two timestamps always match 
up, since in XDCAM-footage those two starttimes differ in 4 
frames - and the container has the right one.

We now always use the container start time as ffmpeg commandline tool 
does (in the hope, that there is a good explaination for this and this 
is the right thing(tm) to do).

I tested this also with HDV footage, which seems to work with the new 
code, too.

Additional fix: disabled seek_by_bytes again, since it will only work 
correctly, if ffmpeg guessed the HDV bitrate right (which it doesn't). 
If you have seeking issues with HDV and have an older version of ffmpeg 
installed, please upgrade, newer versions have some fixes in them.

Modified Paths:
--------------
    trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
    trunk/blender/source/blender/imbuf/intern/anim_movie.c

Modified: trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
===================================================================
--- trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp	2010-11-01 17:00:21 UTC (rev 32814)
+++ trunk/blender/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp	2010-11-01 18:13:10 UTC (rev 32815)
@@ -246,10 +246,8 @@
 {
 	if(position >= 0)
 	{
-		uint64_t st_time = m_formatCtx->streams[m_stream]->start_time;
-		double time_base = 
-			av_q2d(m_formatCtx->streams[m_stream]->time_base);
-		uint64_t seek_pos = position / time_base / m_specs.rate;
+		uint64_t st_time = m_formatCtx->start_time;
+		uint64_t seek_pos = position * AV_TIME_BASE / m_specs.rate;
 
 		if (seek_pos < 0) {
 			seek_pos = 0;
@@ -259,9 +257,14 @@
 			seek_pos += st_time;
 		}
 
+		double pts_time_base = 
+			av_q2d(m_formatCtx->streams[m_stream]->time_base);
+		uint64_t pts_st_time =
+			((st_time != AV_NOPTS_VALUE) ? st_time : 0)
+			/ pts_time_base / (uint64_t) AV_TIME_BASE;
 
 		// a value < 0 tells us that seeking failed
-		if(av_seek_frame(m_formatCtx, m_stream, seek_pos,
+		if(av_seek_frame(m_formatCtx, -1, seek_pos,
 				 AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
 		{
 			avcodec_flush_buffers(m_codecCtx);
@@ -284,7 +287,7 @@
 					{
 						// calculate real position, and read to frame!
 						m_position = (packet.pts - 
-							((st_time != AV_NOPTS_VALUE) ? st_time : 0)) * time_base * m_specs.rate;
+							pts_st_time) * pts_time_base * m_specs.rate;
 
 						if(m_position < position)
 						{
@@ -307,6 +310,7 @@
 		}
 		else
 		{
+			fprintf(stderr, "seeking failed!\n");
 			// Seeking failed, do nothing.
 		}
 	}

Modified: trunk/blender/source/blender/imbuf/intern/anim_movie.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/anim_movie.c	2010-11-01 17:00:21 UTC (rev 32814)
+++ trunk/blender/source/blender/imbuf/intern/anim_movie.c	2010-11-01 18:13:10 UTC (rev 32815)
@@ -839,7 +839,15 @@
 		}
 	}
 
+/* disable seek_by_bytes for now, since bitrates are guessed wrong!
+   also: MPEG2TS-seeking was fixed in later versions of ffmpeg, so problem
+   is somewhat fixed by now (until we add correct timecode management code...)
+*/
+#if 0
 	seek_by_bytes = !!(anim->pFormatCtx->iformat->flags & AVFMT_TS_DISCONT);
+#else
+	seek_by_bytes = FALSE;
+#endif
 
 	if (position != anim->curposition + 1) { 
 #ifdef FFMPEG_OLD_FRAME_RATE
@@ -851,12 +859,9 @@
 			av_q2d(anim->pFormatCtx->streams[anim->videoStream]
 				   ->r_frame_rate);
 #endif
-		double time_base = 
-			av_q2d(anim->pFormatCtx->streams[anim->videoStream]
-				   ->time_base);
+		double pts_time_base = av_q2d(anim->pFormatCtx->streams[anim->videoStream]->time_base);
 		long long pos;
-		long long st_time = anim->pFormatCtx
-			->streams[anim->videoStream]->start_time;
+		long long st_time = anim->pFormatCtx->start_time;
 		int ret;
 
 		if (seek_by_bytes) {
@@ -876,7 +881,7 @@
 			}
 
 			if (st_time != AV_NOPTS_VALUE) {
-				pos += st_time * AV_TIME_BASE * time_base;
+				pos += st_time;
 			}
 		}
 
@@ -891,9 +896,9 @@
 		}
 
 		pts_to_search = (long long) 
-			(((double) position) / time_base / frame_rate);
+			(((double) position) / pts_time_base / frame_rate);
 		if (st_time != AV_NOPTS_VALUE) {
-			pts_to_search += st_time;
+			pts_to_search += st_time / pts_time_base/ AV_TIME_BASE;
 		}
 
 		pos_found = 0;





More information about the Bf-blender-cvs mailing list