avformat_seek_file :用于在媒体文件中进行时间定位(seek)操作
- 原型如下
/**
* Seek to timestamp ts.
* Seeking will be done so that the point from which all active streams
* can be presented successfully will be closest to ts and within min/max_ts.
* Active streams are all streams that have AVStream.discard < AVDISCARD_ALL.
*
* If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and
* are the file position (this may not be supported by all demuxers).
* If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames
* in the stream with stream_index (this may not be supported by all demuxers).
* Otherwise all timestamps are in units of the stream selected by stream_index
* or if stream_index is -1, in AV_TIME_BASE units.
* If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as
* keyframes (this may not be supported by all demuxers).
* If flags contain AVSEEK_FLAG_BACKWARD, it is ignored.
*
* @param s media file handle
* @param stream_index index of the stream which is used as time base reference
* @param min_ts smallest acceptable timestamp
* @param ts target timestamp
* @param max_ts largest acceptable timestamp
* @param flags flags
* @return >=0 on success, error code otherwise
*
* @note This is part of the new seek API which is still under construction.
* Thus do not use this yet. It may change at any time, do not expect
* ABI compatibility yet!
*/
int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
- 参数解释
s
: 指向AVFormatContext
结构体的指针,表示媒体文件的上下文信息。stream_index
: 需要进行定位的流的索引。可以通过av_find_best_stream
等函数获取。min_ts
: 允许的最小时间戳(timestamp),以AV_TIME_BASE
为单位。如果没有合适的时间戳,会选择最接近的时间戳。target_ts
: 目标时间戳,以AV_TIME_BASE
为单位。函数将尝试定位到与目标时间戳最接近的位置。max_ts
: 允许的最大时间戳,以AV_TIME_BASE
为单位。如果没有合适的时间戳,会选择最接近的时间戳。flags
: 控制定位行为的标志位。- flags 解释
AVSEEK_FLAG_BACKWARD
:向后定位(从目标时间戳向前搜索)。AVSEEK_FLAG_ANY
:允许任意帧的定位,而不仅仅是关键帧。AVSEEK_FLAG_FRAME
:定位到目标时间戳所在的最接近的关键帧。
- flags 解释
调用范例
#include <stdio.h>
#include <libavformat/avformat.h>
int main() {
// step-1
av_register_all();
AVFormatContext *formatContext = NULL;
// step-2
int ret = avformat_open_input(&formatContext, "input.mp4", NULL, NULL);
if (ret < 0) {
printf("Error opening input file\n");
return ret;
}
// step-3
ret = avformat_find_stream_info(formatContext, NULL);
if (ret < 0) {
printf("Error finding stream information\n");
avformat_close_input(&formatContext);
return ret;
}
// step-4
int streamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (streamIndex < 0) {
printf("Error finding video stream\n");
avformat_close_input(&formatContext);
return streamIndex;
}
// step-5
AVStream *stream = formatContext->streams[streamIndex];
int64_t targetTimestamp = 5000000; // Target timestamp in microseconds
int64_t minTimestamp = INT64_MIN;
int64_t maxTimestamp = INT64_MAX;
int flags = AVSEEK_FLAG_BACKWARD;
// step-6
ret = avformat_seek_file(formatContext, streamIndex, minTimestamp, targetTimestamp, maxTimestamp, flags);
if (ret < 0) {
printf("Error seeking to target timestamp\n");
avformat_close_input(&formatContext);
return ret;
}
// Perform necessary operations after seeking (e.g., decoding frames)
avformat_close_input(&formatContext);
return 0;
}