寫開源項目的時候需要做seek功能,使用了av_seek_frame的功能,記錄如下。先看段文檔
int av_seek_frame ( AVFormatContext * s,
int stream_index,
int64_t timestamp,
int flags
)
Seek to the keyframe at timestamp.
'timestamp' in 'stream_index'.
Parameters
s media file handle
stream_index If stream_index is (-1), a default stream is selected, and timestamp is automatically converted from AV_TIME_BASE units to the stream specific time_base.
timestamp Timestamp in AVStream.time_base units or, if no stream is specified, in AV_TIME_BASE units.
flags flags which select direction and seeking mode
#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes
#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes
#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number
Returns
>= 0 on success
解釋###
timebase指的是時間戳,對應(yīng)pts時間戳,如果index是-1,則使用AV_TIMEBASE作為timebase并由ffmpeg自動轉(zhuǎn)換成默認時間戳, 如果指定了stream那么就要使用相應(yīng)的stream的timebase來計算pts了。這里注意的是比如seek到32s不能簡單的直接32*AV_TIMEBASE來計算時間戳,因為pts不一定是從0開始的,所以要加上起始的pts。
stream_index是選擇針對哪一條媒體流來做seek
flag用來指定尋找尋找的I幀和指定點之間的位置關(guān)系,因為seek過去的時間點不一定就處在I幀的地方,解碼需要依賴于I幀,所以這時候就得選擇一個附近的I幀,flag表明要seek到當前幀的前面一個I幀還是后面一個I幀
seek到32s的例子###
int ret = av_seek_frame(inputFormatContext, -1, ((double)ms/(double)1000)*AV_TIME_BASE + (double)inputFormatContext->start_time, AVSEEK_FLAG_BACKWARD);//不指定stream進行seek
int ret = av_seek_frame(inputFormatContext, videoIndex, (double)videoTimeBase.den/(double)videoTimeBase.num * ((double)ms/(double)1000)*AV_TIME_BASE + (double)inputFormatContext->start_time/(double)AV_TIME_BASE*((double)videoTimeBase.den/(double)videoTimeBase.num)*/, AVSEEK_FLAG_BACKWARD);//指定stream進行seek