我们从ijk中seek的处理流程来看ffmpeg的这个问题
int ffp_seek_to_l(FFPlayer *ffp, long msec)
{
assert(ffp);
VideoState *is = ffp->is;
int64_t start_time = 0;
int64_t seek_pos = milliseconds_to_fftime(msec);
int64_t duration = milliseconds_to_fftime(ffp_get_duration_l(ffp));
if (!is)
return EIJK_NULL_IS_PTR;
//add by hxk
if(ffp->loopStart != 0 && ffp->loopEnd != INT_MAX){
//use setLooping
setLooping,
} else {
//not use setLooping
resetLoopStartAndEnd(ffp);
}
//add end
if (duration > 0 && seek_pos >= duration && ffp->enable_accurate_seek) {
toggle_pause(ffp, 1);
ffp_notify_msg1(ffp, FFP_MSG_COMPLETED);
return 0;
}
start_time = is->ic->start_time;
if (start_time > 0 && start_time != AV_NOPTS_VALUE)
seek_pos += start_time;
// FIXME: 9 seek by bytes
// FIXME: 9 seek out of range
// FIXME: 9 seekable
av_log(ffp, AV_LOG_DEBUG, "stream_seek %"PRId64"(%d) + %"PRId64", \n", seek_pos, (int)msec, start_time);
stream_seek(is, seek_pos, 0, 0);
return 0;
}
看一下stream_Seek/ff_ffplay.c函数,可以看到ijk中没有处理seek_flags
/* seek in the stream */
static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
{
if (!is->seek_req) {
is->seek_pos = pos;
is->seek_rel = rel;
is->seek_flags &= ~AVSEEK_FLAG_BYTE;
if (seek_by_bytes)
is->seek_flags |= AVSEEK_FLAG_BYTE;
is->seek_req = 1;
SDL_CondSignal(is->continue_read_thread);
}
}
在read_thread/ff_ffplay.c中会获取这个flag来使用 avformat_seek_file函数跳转位置。
ffp_toggle_buffering(ffp, 1);//hxk:Open the buffer and start playing.
ffp_notify_msg3(ffp, FFP_MSG_BUFFERING_UPDATE, 0, 0);
/**跳转到逼近ts时间点,并且在seek_min和seek_max范围之内,这里的flag是0*/
ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR,
"%s: error while seeking\n", is->ic->filename);
} else {
那么ffmpeg中flag可以设置哪些呢?
flag值:
#deflagfine 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
AVSEEK_FLAG_BACKWARD//是seek到请求的timestamp之前最近的关键帧
AVSEEK_FLAG_BYTE // 是基于字节位置的查找
AVSEEK_FLAG_ANY //是可以seek到任意帧,注意不一定是关键帧,因此使用时可能会导致花屏
AVSEEK_FLAG_FRAME//是基于帧数量快进
上面的几个flag目前我都没使用过。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)