X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Fmathematics.c;h=252794e46005246b08f27c734e0eaa210333e57b;hb=d96d0252fd535db5183492b804341cba93468b15;hp=c9b24afeacde78bbeec76e17264221d158cfe920;hpb=cdfe45ad371b7a8e6135b6c063b6b2a93152cb3a;p=ffmpeg diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index c9b24afeacd..252794e4600 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -1,20 +1,20 @@ /* - * Copyright (c) 2005 Michael Niedermayer + * Copyright (c) 2005-2012 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -27,6 +27,8 @@ #include #include "mathematics.h" +#include "libavutil/common.h" +#include "avassert.h" #include "version.h" int64_t av_gcd(int64_t a, int64_t b) @@ -40,10 +42,19 @@ int64_t av_gcd(int64_t a, int64_t b) int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) { 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 || rnd == 4 || rnd > 5) + 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)); @@ -114,6 +125,8 @@ int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b) { int64_t a = tb_a.num * (int64_t)tb_b.den; int64_t b = tb_b.num * (int64_t)tb_a.den; + if ((FFABS(ts_a)|a|FFABS(ts_b)|b) <= INT_MAX) + return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b); if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) return -1; if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a) @@ -128,3 +141,48 @@ int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod) c -= mod; return c; } + +int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb){ + int64_t a, b, this; + + av_assert0(in_ts != AV_NOPTS_VALUE); + av_assert0(duration >= 0); + + if (*last == AV_NOPTS_VALUE || !duration || in_tb.num*(int64_t)out_tb.den <= out_tb.num*(int64_t)in_tb.den) { +simple_round: + *last = av_rescale_q(in_ts, in_tb, fs_tb) + duration; + return av_rescale_q(in_ts, in_tb, out_tb); + } + + a = av_rescale_q_rnd(2*in_ts-1, in_tb, fs_tb, AV_ROUND_DOWN) >>1; + b = (av_rescale_q_rnd(2*in_ts+1, in_tb, fs_tb, AV_ROUND_UP )+1)>>1; + if (*last < 2*a - b || *last > 2*b - a) + goto simple_round; + + this = av_clip64(*last, a, b); + *last = this + duration; + + return av_rescale_q(this, fs_tb, out_tb); +} + +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc) +{ + int64_t m, d; + + if (inc != 1) + inc_tb = av_mul_q(inc_tb, (AVRational) {inc, 1}); + + m = inc_tb.num * (int64_t)ts_tb.den; + d = inc_tb.den * (int64_t)ts_tb.num; + + if (m % d == 0) + return ts + m / d; + if (m < d) + return ts; + + { + int64_t old = av_rescale_q(ts, ts_tb, inc_tb); + int64_t old_ts = av_rescale_q(old, inc_tb, ts_tb); + return av_rescale_q(old + 1, inc_tb, ts_tb) + (ts - old_ts); + } +}