X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Frational.c;h=21d2bb72c37370e1d148d3048c11d420e121728e;hb=42a6a3841868b2150b7a13f35458bd9d2ffeb3e6;hp=594a6f81e6c0d5205b9e88a8bec5110043c9ad92;hpb=e8a460672f7e9aec129a7cfa01345857b1565a15;p=ffmpeg diff --git a/libavutil/rational.c b/libavutil/rational.c index 594a6f81e6c..21d2bb72c37 100644 --- a/libavutil/rational.c +++ b/libavutil/rational.c @@ -148,6 +148,40 @@ int av_find_nearest_q_idx(AVRational q, const AVRational* q_list) return nearest_q_idx; } +uint32_t av_q2intfloat(AVRational q) { + int64_t n; + int shift; + int sign = 0; + + if (q.den < 0) { + q.den *= -1; + q.num *= -1; + } + if (q.num < 0) { + q.num *= -1; + sign = 1; + } + + if (!q.num && !q.den) return 0xFFC00000; + if (!q.num) return 0; + if (!q.den) return 0x7F800000 | (q.num & 0x80000000); + + shift = 23 + av_log2(q.den) - av_log2(q.num); + if (shift >= 0) n = av_rescale(q.num, 1LL<= (1<<24); + shift += n < (1<<23); + + if (shift >= 0) n = av_rescale(q.num, 1LL<= (1<<23)); + + return sign<<31 | (150-shift)<<23 | (n - (1<<23)); +} + #ifdef TEST int main(void) { @@ -202,6 +236,20 @@ int main(void) } } } + + for (a.den = 1; a.den < 0x100000000U/3; a.den*=3) { + for (a.num = -1; a.num < (1<<27); a.num += 1 + a.num/100) { + float f = av_int2float(av_q2intfloat(a)); + float f2 = av_q2d(a); + if (fabs(f - f2) > fabs(f)/5000000) { + av_log(NULL, AV_LOG_ERROR, "%d/%d %f %f\n", a.num, + a.den, f, f2); + return 1; + } + + } + } + return 0; } #endif