ffmpeg时间单位解释和av_seek_frame方法

时间:2012-09-02 09:50:37

标签: ffmpeg video-processing

time_base在ffmpeg中的含义是什么?文档(here)表示它是“每秒帧数”。 我在一个真实的例子中看到:

AVFormatContext->streams[video_index]->time_base == 1/30000

但视频AVCodecContext->time_base == 1001/60000

这让我很困惑,我不明白。

第二个问题是 av_seek_frame 方法。 如果通过时间戳寻找(最后一个参数是AVSEEK_FLAG_BACKWARD或0), 搜索是从 av_seek_frame 读取的当前位置开始的? 还是从文件的开头?或者从最后 av_seek_frame 电话后解码的起始位置?

3 个答案:

答案 0 :(得分:8)

  

但是视频的AVCodecContext-> time_base == 1001/60000

     

这让我很困惑,我不明白。

time_base的类型为AVRational,它是由分子和分母组成的有理数,而不是使用小数点。我认为他们不只是使用double的原因是这样你就不会失去任何精确度。

AVRational在来源中被定义为:

typedef struct AVRational{
    int num; ///< numerator
    int den; ///< denominator
} AVRational;

time_base也是每秒帧数的倒数,不等于它。因此,如果你有30 fps,这意味着时基是1/30,而不是30。

答案 1 :(得分:2)

我测试了satuon评论链接中的所有字段和许多视频文件,看起来好像可以计算出正确的帧率:

double framerate = av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate);

...其中pFormatCtx是您的AVFormatContext,videoStream是您的视频流的索引,使用以下代码找到:

int videoStream = -1;
for (uint i=0; i < pFormatCtx->nb_streams; i++) {
    if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && videoStream < 0) {
        videoStream = i;
    }
}

使用ffmpeg 1.1。

答案 2 :(得分:2)

不要使用r_frame_rate,因为它是libavformats猜测,而不是精确。 (见http://ffmpeg.org/pipermail/ffmpeg-devel/2005-May/003079.html

AVCodecContext.time_base提供精确的fps。如果ticks_per_frame为2,则使用1/2缩小time_base的大小。例如,如果AVCodecContext.time_base(1,60)和ticks_per_frame为1,则fps为60.如果ticks_per_frame为2,则fps为30。

如果AVCodecContext-&gt; time_base为(1001,60000),则fps为60.

AVCodecContext的time_base与fps相关。

AVStream的time_base仅用于AVStream中方法的时间单位,例如获取一帧的时间或.start变量。

AVPacket还有另一个time_base。但是从ffmpeg-devel来看,他们更喜欢让AVPacket.time_base与AVStream相同。