diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-04-19 00:29:57 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-04-19 01:22:06 +0200 |
commit | a47cc877a072bf6dc0d2c6ff2e138d685b162470 (patch) | |
tree | 012277422cbec567675e6490a175700f828dd12d /libavfilter | |
parent | 3a1feb01da6149170a442111ce6419fff22fffba (diff) | |
download | ffmpeg-a47cc877a072bf6dc0d2c6ff2e138d685b162470.tar.gz |
avfilter/vf_rotate: increase fixed point precision
This ensures int_sins output doesnt have "random" lsbs
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter')
-rw-r--r-- | libavfilter/vf_rotate.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c index e242ee2dfa..2f55bfc1cc 100644 --- a/libavfilter/vf_rotate.c +++ b/libavfilter/vf_rotate.c @@ -252,11 +252,12 @@ static int config_props(AVFilterLink *outlink) } #define FIXP (1<<16) -#define INT_PI 205887 //(M_PI * FIXP) +#define FIXP2 (1<<20) +#define INT_PI 3294199 //(M_PI * FIXP2) /** * Compute the sin of a using integer values. - * Input and output values are scaled by FIXP. + * Input is scaled by FIXP2 and output values are scaled by FIXP. */ static int64_t int_sin(int64_t a) { @@ -268,13 +269,13 @@ static int64_t int_sin(int64_t a) if (a >= INT_PI*3/2) a -= 2*INT_PI; // -PI/2 .. 3PI/2 if (a >= INT_PI/2 ) a = INT_PI - a; // -PI/2 .. PI/2 - /* compute sin using Taylor series approximated to the third term */ - a2 = (a*a)/FIXP; - for (i = 2; i < 7; i += 2) { + /* compute sin using Taylor series approximated to the fifth term */ + a2 = (a*a)/(FIXP2); + for (i = 2; i < 11; i += 2) { res += a; - a = -a*a2 / (FIXP*i*(i+1)); + a = -a*a2 / (FIXP2*i*(i+1)); } - return res; + return (res + 8)>>4; } /** @@ -402,7 +403,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_log(ctx, AV_LOG_DEBUG, "n:%f time:%f angle:%f/PI\n", rot->var_values[VAR_N], rot->var_values[VAR_T], rot->angle/M_PI); - angle_int = res * FIXP; + angle_int = res * FIXP * 16; s = int_sin(angle_int); c = int_sin(angle_int + INT_PI/2); |