ffmpeg # AVRational

2018-07-23  本文已影响272人  FlyingPenguin

用ffmpeg经常用到以下的数据结构:

/**
 * Rational number (pair of numerator and denominator).
 */
typedef struct AVRational{
    int num; ///< Numerator
    int den; ///< Denominator
} AVRational;

Rational是啥意思? 其实这里表示的Rational number。

Rational number

In mathematics, a rational number is any number that can be expressed as the quotient or fraction p/q of two integers, a numerator p and a non-zero denominator q.[1]
Since q may be equal to 1, every integer is a rational number.

rational number就是可以表示成p/q两个整数相除的数。其实就是传说中的有理数
numberator: 分子
denominator: 分母

可见AVRational中num是numberator的简称,den是denominator的简称

AVRational time_base

typedef struct AVCodecContext {
    ...

    /**
     * This is the fundamental unit of time (in seconds) in terms
     * of which frame timestamps are represented. For fixed-fps content,
     * timebase should be 1/framerate and timestamp increments should be
     * identically 1.
     * This often, but not always is the inverse of the frame rate or field rate
     * for video. 1/time_base is not the average frame rate if the frame rate is not
     * constant.
     *
     * Like containers, elementary streams also can store timestamps, 1/time_base
     * is the unit in which these timestamps are specified.
     * As example of such codec time base see ISO/IEC 14496-2:2001(E)
     * vop_time_increment_resolution and fixed_vop_rate
     * (fixed_vop_rate == 0 implies that it is different from the framerate)
     *
     * - encoding: MUST be set by user.
     * - decoding: the use of this field for decoding is deprecated.
     *             Use framerate instead.
     */
    AVRational time_base;

    ...
}
帧率为25时

一个需要注意的地方,我们在这里使用了 int64 来存储 PTS,这是因为 PTS 是一个整型值。比如,如果一个视频流的帧率是 24,那么 PTS 为 42 则表示这一帧应该是第 42 帧如果我们 1/24 秒播一帧的话。我们可以用这个值除以帧率来得到以秒为单位的时间。视频流的 time_base 值则是 1/framerate,所以当我们获得 PTS 后,我们要乘上 time_base。

PTS的时间单位为AVRational,所以计算实际的时间时,经常遇到如下代码:

if (frame->pts != AV_NOPTS_VALUE)
            dpts = av_q2d(is->video_st->time_base) * frame->pts;

av_q2d是啥?

av_q2d
/**
 * Convert an AVRational to a `double`.
 * @param a AVRational to convert
 * @return `a` in floating-point form
 * @see av_d2q()
 */
static inline double av_q2d(AVRational a){
    return a.num / (double) a.den;
}

AVRational frame_rate

有时帧率也用AVRational来表示。

static void do_video_out(OutputFile *of,
                         OutputStream *ost,
                         AVFrame *next_picture,
                         double sync_ipts)
{
    ...
    AVRational frame_rate;
  
    ...

    frame_rate = av_buffersink_get_frame_rate(filter);
    if (frame_rate.num > 0 && frame_rate.den > 0)
        duration = 1/(av_q2d(frame_rate) * av_q2d(enc->time_base));

    ....
}

References:

https://en.wikipedia.org/wiki/Rational_number
http://www.samirchen.com/ffmpeg-tutorial-5/

上一篇下一篇

猜你喜欢

热点阅读