[FFmpeg-devel] [WIP] rotate filter(s)
Michael Niedermayer
michaelni
Tue Oct 5 14:36:19 CEST 2010
On Mon, Oct 04, 2010 at 10:27:29PM +0200, Stefano Sabatini wrote:
> On date Sunday 2010-10-03 21:35:00 +0200, Michael Niedermayer encoded:
> > On Sun, Oct 03, 2010 at 07:35:49PM +0200, Stefano Sabatini wrote:
> > > Hi,
> > >
> > > in attachment a first stub at the rotate filter. I don't know if it is
> > > a good idea to keep the float variant, while the rotate_ss may be
> > > useful (and the rotation angle could be made parametric).
> > >
> > > The integer-only rotating code is taken from tests/rotozoom.c, I don't
> > > know if we have a corresponding version in the libs.
> > >
> > > fill_line_with_color() and draw_rectangle() are duplicated from
> > > vf_pad.c, so maybe we should make them public (or at least ff_ them),
> > > drawutils.[ch] may be a good place where to put them.
> > >
> > > Note that ffplay/SDL doesn't work with odd width/height sizes, so you
> > > may need to rescale to an even wxh size (this could be done with a
> > > parametric scale as discussed some months ago).
> > >
> > > What this rotate filter still lacks, apart a resolution to the
> > > refactoring problems mentioned above, is a YUV planar version of the
> > > rotating function, and possibly the extension to other RGB variants,
> > > which should be pretty easy to add. Everyone feel free to continue to
> > > work on this and post an updated patch.
> >
> > looks like you implemented nearest neighbor sampling in int and float
> > thats not what rotozoom does, also see vf_perspective.c
>
> Implemented bilinear interpolation as in rotozoom.c, merged the three
> variants into a single one and made the expression for angle
> parametric.
>
> Still missing: more packed and planar formats for the non-float path,
> a more efficient way for filling the background.
>
> Should I remove the float path?
if its slower then yes.
[...]
> +/**
> + * @file
> + * rotation filter
> + *
> + * @todo handle planar pixel and more packed formats in the non-float path
> +*/
> +
> +#include "libavutil/eval.h"
> +#include "libavutil/intreadwrite.h"
> +#include "libavutil/pixdesc.h"
> +#include "avfilter.h"
> +#include "drawutils.h"
> +#include "parseutils.h"
> +
> +static const char *var_names[] = {
> + "E",
> + "PHI",
> + "PI",
> + "w", ///< width of the input video
> + "h", ///< height of the input video
> + "n", ///< number of frame
> + "t", ///< timestamp expressed in seconds
> + NULL
> +};
> +
> +enum var_name {
> + VAR_E,
> + VAR_PHI,
> + VAR_PI,
> + VAR_W,
> + VAR_H,
> + VAR_N,
> + VAR_T,
> + VAR_VARS_NB
> +};
> +
> +#define FIXP (1<<16)
> +#define INT_PI 205887 //(M_PI * FIXP)
> +
> +/**
> + * Compute the power of a a^p using integer values.
> + * Input and output values are scaled by FIXP.
> + */
> +static int64_t int_pow(int64_t a, int p)
> +{
> + int64_t v = FIXP;
> +
> + for (; p; p--) {
> + v *= a;
> + v /= FIXP;
> + }
> +
> + return v;
> +}
> +
> +/**
> + * Compute the sin of a using integer values.
> + * Input and output values are scaled by FIXP.
> + */
> +static int64_t int_sin(int64_t a)
> +{
> + if (a < 0) a = INT_PI-a; // 0..inf
> + a %= 2 * INT_PI; // 0..2PI
> +
> + 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
> +
> + return a - int_pow(a, 3)/6 + int_pow(a, 5)/120 - int_pow(a, 7)/5040;
a2= a*a/X
for(i=2; a; i+=2){
r+= a;
a= -a*a2/(X*i*(i+1));
}
and test it against sin() please
and with the 16bit fixp most things fit in 32bit
> +}
> +
> +/**
> + * Interpolate the color in src at position x and y using bilinear
> + * interpolation.
> + *
> + * @param dst_color put here the destination color
> + */
> +static uint8_t *ipol(uint8_t *dst_color,
> + const uint8_t *src, const int src_linesize, int x, int y,
> + int max_x, int max_y)
> +{
> + int int_x = x>>16;
> + int int_y = y>>16;
> + int frac_x = x&0xFFFF;
> + int frac_y = y&0xFFFF;
> + int i;
> +
> + for (i = 0; i < 3; i++) {
> + int s00 = src[3 * int_x + i + src_linesize * int_y];
> + int s01 = src[3 * FFMIN(int_x+1,max_x) + i + src_linesize * int_y];
> + int s10 = src[3 * int_x + i + src_linesize * FFMIN(int_y+1, max_y)];
> + int s11 = src[3 * FFMIN(int_x+1,max_x) + i + src_linesize * FFMIN(int_y+1, max_y)];
> + int s0 = (((1<<16) - frac_x)*s00 + frac_x*s01)>>8;
> + int s1 = (((1<<16) - frac_x)*s10 + frac_x*s11)>>8;
> +
> + dst_color[i] = (((1<<16) - frac_y)*s0 + frac_y*s1)>>24;
> + }
the >>8 can be avoided by adjusting perecission sanely
the FFMIN doesnt belong in the loop
> +
> + return dst_color;
> +}
> +
> +typedef struct {
> + const AVClass *class;
> + int angle;
> + char *angle_expr; ///< expression for the angle
> + AVExpr *angle_pexpr; ///< parsed expression for the angle
> + uint8_t bgcolor[4]; ///< color expressed either in YUVA or RGBA colorspace for the padding area
> + char *bgcolor_str;
> + int hsub, vsub;
> + int use_float;
> + int use_bilinear;
> + int keep_same_size;
> + uint8_t *line[4];
> + int line_step[4];
> + float transx, transy; ///< how much to translate (in pixels)
> + float sinx, cosx;
> + int output_h, output_w;
> + double var_values[VAR_VARS_NB];
> +} RotContext;
> +
> +#define OFFSET(x) offsetof(RotContext, x)
> +
> +static const AVOption rot_options[]= {
> + {"angle", "set angle expression", OFFSET(angle_expr), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX },
> + {"bgcolor", "set background color", OFFSET(bgcolor_str), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX },
> + {"float", "use float path", OFFSET(use_float), FF_OPT_TYPE_INT, 0, 0, 1 },
> + {"ss", "keep same size", OFFSET(keep_same_size), FF_OPT_TYPE_INT, 0, 0, 1 },
> + {"bilinear", "use bilinear interpolation", OFFSET(use_bilinear), FF_OPT_TYPE_INT, 1, 0, 1 },
> + {NULL},
> +};
bilinear should be default
and this filter looks kinda big for what it does
if i compare it to lets say vf_perspective that does more
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
It is dangerous to be right in matters on which the established authorities
are wrong. -- Voltaire
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101005/435eecd3/attachment.pgp>
More information about the ffmpeg-devel
mailing list