diff options
author | jstebbins <[email protected]> | 2011-04-02 20:14:00 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2011-04-02 20:14:00 +0000 |
commit | de2144f7054a3a106164a5356a9ee989674160b1 (patch) | |
tree | f5c787b75ec04caf79b530050b4c995103e55422 | |
parent | c5493132981f650d13c03181d53da5e3fd205bcd (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.c | 22 |
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; } |