搜索
您的当前位置:首页正文

av_rescale_q()

来源:爱go旅游网

当我们发送h264时是没有pts和dts的,所以我们要加上,中间会用到av_rescale_q()


一下是根据网络和源码的理解:

<span style="font-size:24px;"><strong>av_rescale_q()</strong></span>

说明:av_rescale_q用于计算Packet的PTS。av_rescale_q的返回值是一个很大的整数,
且每次计算的结果间隔很大。
不同于avcodec_encode_video改变AVCodecContext *avctx的pts(小整数,且间隔小)。
av_rescale_q(a,b,c)是用来把时间戳从一个时基调整到另外一个时基时候用的函数。
它基本的动作是计算a*b/c,但是这个函数还是必需的,因为直接计算会有溢出的情况发生。
AV_TIME_BASE_Q是AV_TIME_BASE作为分母后的版本。
它们是很不相同的:AV_TIME_BASE * time_in_seconds = avcodec_timestamp
而AV_TIME_BASE_Q * avcodec_timestamp = time_in_seconds
(注意AV_TIME_BASE_Q实际上是一个AVRational对象,
所以你必需使用avcodec中特定的q函数来处理它)。

/**
 * rational number numerator/denominator
 */
typedef struct AVRational{
    int num; ///< numerator 分子
    int den; ///< denominator 分母
} AVRational;


int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
{
    return av_rescale_q_rnd(a, bq, cq, AV_ROUND_NEAR_INF);
}

int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq,
                         enum AVRounding rnd)
{
    int64_t b = bq.num * (int64_t)cq.den;
    int64_t c = cq.num * (int64_t)bq.den;
    return av_rescale_rnd(a, b, c, rnd);
}

int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
{
/*它的作用是计算 "a * b / c" 的值并分五种方式来取整.
  将以 "时钟基c" 表示的 数值a 转换成以 "时钟基b" 来表示。
  eg:将以"1MHz时钟基" 表示的 "PTS/DTS值a" 转换成以 "90kHz时钟基" 表示*/
    int64_t r = 0;
    av_assert2(c > 0);
    av_assert2(b >=0);
    av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4);

    if (c <= 0 || b < 0 || !((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4))
        return INT64_MIN;

    if (rnd & AV_ROUND_PASS_MINMAX) {
        if (a == INT64_MIN || a == INT64_MAX)
            return a;
        rnd -= AV_ROUND_PASS_MINMAX;
    }

    if (a < 0 && a != INT64_MIN)
        return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd >> 1) & 1));

    if (rnd == AV_ROUND_NEAR_INF)
        r = c / 2;
    else if (rnd & 1)
        r = c - 1;

    if (b <= INT_MAX && c <= INT_MAX) {
        if (a <= INT_MAX)
            return (a * b + r) / c;
        else
            return a / c * b + (a % c * b + r) / c;
    } else {
#if 1
        uint64_t a0  = a & 0xFFFFFFFF;
        uint64_t a1  = a >> 32;
        uint64_t b0  = b & 0xFFFFFFFF;
        uint64_t b1  = b >> 32;
        uint64_t t1  = a0 * b1 + a1 * b0;
        uint64_t t1a = t1 << 32;
        int i;

        a0  = a0 * b0 + t1a;
        a1  = a1 * b1 + (t1 >> 32) + (a0 < t1a);
        a0 += r;
        a1 += a0 < r;

        for (i = 63; i >= 0; i--) {
            a1 += a1 + ((a0 >> i) & 1);
            t1 += t1;
            if (c <= a1) {
                a1 -= c;
                t1++;
            }
        }
        return t1;
    }
#else
        AVInteger ai;
        ai = av_mul_i(av_int2i(a), av_int2i(b));
        ai = av_add_i(ai, av_int2i(r));

        return av_i2int(av_div_i(ai, av_int2i(c)));
    }
#endif
}


因篇幅问题不能全部显示,请点此查看更多更全内容

Top