summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-04-02 20:14:00 +0000
committerjstebbins <[email protected]>2011-04-02 20:14:00 +0000
commitde2144f7054a3a106164a5356a9ee989674160b1 (patch)
treef5c787b75ec04caf79b530050b4c995103e55422
parentc5493132981f650d13c03181d53da5e3fd205bcd (diff)
Flush ffmpeg codec buffers after every seek.
According to several e-mails I've read on ffmpeg-devel, avcodec_flush_buffers should be called after any seek. It appears this is even more critical to do when using frame based multi-threading. I don't see any immediate difference in functionality by adding this, but it may prevent surprises in the future. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3896 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/stream.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/libhb/stream.c b/libhb/stream.c
index 5b4d248d0..ccc10f746 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -1421,6 +1421,20 @@ int hb_stream_read( hb_stream_t * src_stream, hb_buffer_t * b )
return hb_ts_stream_decode( src_stream, b );
}
+void ffmpeg_flush_stream_buffers( hb_stream_t *stream )
+{
+ int i;
+ AVFormatContext *ic = stream->ffmpeg_ic;
+
+ for ( i = 0; i < ic->nb_streams; i++ )
+ {
+ if ( ic->streams[i]->codec && ic->streams[i]->codec->codec )
+ {
+ avcodec_flush_buffers( ic->streams[i]->codec );
+ }
+ }
+}
+
int64_t ffmpeg_initial_timestamp( hb_stream_t * stream )
{
AVStream *s = stream->ffmpeg_ic->streams[stream->ffmpeg_video_id];
@@ -1462,6 +1476,7 @@ int hb_stream_seek_chapter( hb_stream_t * stream, int chapter_num )
if ( chapter_num > 1 && pos > 0 )
{
av_seek_frame( stream->ffmpeg_ic, -1, pos, 0);
+ ffmpeg_flush_stream_buffers( stream );
}
return 1;
}
@@ -3598,10 +3613,12 @@ static int ffmpeg_seek( hb_stream_t *stream, float frac )
}
av_seek_frame( ic, -1, pos, 0 );
stream->need_keyframe = 1;
+ ffmpeg_flush_stream_buffers( stream );
}
else
{
av_seek_frame( ic, -1, 0LL, AVSEEK_FLAG_BACKWARD );
+ ffmpeg_flush_stream_buffers( stream );
}
return 1;
}
@@ -3611,10 +3628,13 @@ static int ffmpeg_seek_ts( hb_stream_t *stream, int64_t ts )
{
AVFormatContext *ic = stream->ffmpeg_ic;
int64_t pos;
+ int ret;
pos = ts * AV_TIME_BASE / 90000 + ffmpeg_initial_timestamp( stream );
stream->need_keyframe = 1;
// Seek to the nearest timestamp before that requested where
// there is an I-frame
- return av_seek_frame( ic, -1, pos, AVSEEK_FLAG_BACKWARD );
+ ret = av_seek_frame( ic, -1, pos, AVSEEK_FLAG_BACKWARD );
+ ffmpeg_flush_stream_buffers( stream );
+ return ret;
}