av_seek_frame

写开源项目的时候需要做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指的是时间戳,对应pts时间戳,如果index是-1,则使用AV_TIMEBASE作为timebase并由ffmpeg自动转换成默认时间戳, 如果指定了stream那么就要使用相应的stream的timebase来计算pts了。这里注意的是比如seek到32s不能简单的直接32*AV_TIMEBASE来计算时间戳,因为pts不一定是从0开始的,所以要加上起始的pts。

stream_index是选择针对哪一条媒体流来做seek

flag用来指定寻找寻找的I帧和指定点之间的位置关系,因为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

你可能感兴趣的:(av_seek_frame)