您的位置:首页 > 其它

FFmpeg av_seek_frame()参数以及使用

2015-01-20 11:02 429 查看
以下是FFmpeg中经常会使用到的av_seek_frame()需要注意的地方。
/**
* Seek to the keyframe at timestamp.
* 'timestamp' in 'stream_index'.
*
* @param s media file handle                                      //容器内容
* @param stream_index If stream_index is (-1), a default          //<span style="color: rgb(68, 68, 68); font-family: Tahoma, Helvetica, SimSun, sans-serif; font-size: 14px; line-height: 21px;">流索引</span>
* stream is selected, and timestamp is automatically converted
* from AV_TIME_BASE units to the stream specific time_base.
* @param timestamp Timestamp in AVStream.time_base units          //seek的时间(微妙级)
*        or, if no stream is specified, in AV_TIME_BASE units.
* @param flags flags which select direction and seeking mode      //seek的flag
* @return >= 0 on success
*/
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
int flags);
参数4flag的意义
假设视频从1s到1.8s依次如下:
1.0    1.1   1.2   1.3   1.4   1.5   1.6   1.7   1.8 ...
I      P     B     B     B     I     P     B     B  ...
若flag值为:#define AVSEEK_FLAG_BACKWARD 1  则seek的位置为距离最近之前的关键帧。 比如我要seek到1.1s(或者1.2s,1.3s,1.4s),则实际seek到的位置是1.0s。要seek到1.7s,1.8s,则实际会seek到1.5s的关键帧位置。
若flag值为:#define AVSEEK_FLAG_ANY 2       则seek的位置为距离最近之后的关键帧。比如我要seek到1.1s(或者1.2s,1.3s,1.4s),则实际seek到的位置为1.5s的位置。
</pre><pre name="code" class="cpp">//清除buffer和相关状态
avcodec_flush_buffers(pFormatCtx->streams[videoStream]->codec);
</pre><pre name="code" class="cpp"><span style="font-family: Arial; font-size: 14px; line-height: 26px;"><span style="font-family: Arial; font-size: 14px; line-height: 26px;"></span></span><pre name="code" class="cpp">	av_seek_frame(pFormatCtx,
-1,
(int64_t)seekTime*(1000),
AVSEEK_FLAG_BACKWARD) ;//AVSEEK_FLAG_ANY AVSEEK_FLAG_BACKWARD
//清除buffer和相关状态
avcodec_flush_buffers(pFormatCtx->streams[videoStream]->codec);
FFMPEG_LOGI(TAG, "time = %d seek_step = %d",seekTime,m_seek_step);

//读取Frame,开始解码
int frameFinished = 0 ;
while(av_read_frame(pFormatCtx, &packet) >= 0)
{

if(packet.stream_index == videoStream)
{

avcodec_decode_video2(pCodecCtx,
pFrame,
&frameFinished,
&packet) ;
if(frameFinished)
{
//if(pFrame->key_frame == 1) //的判断,则提取的是关键帧
sws_scale(pSwsCtx,
pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize) ;
double timesatamp = (pFrame->pkt_pts)*av_q2d(pFormatCtx->streams[videoStream]->time_base) ;
if((timesatamp*1000) >= seekTime)
{
data = (int *)pFrameRGB->data[0] ;
return data ;
}
}
else
{
FFMPEG_LOGI(TAG, "Drop Frame") ;
}
}
//av_free_packet(&packet) ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: