avfilter/vf_rotate: make int*90° rotates suck less speedwise
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
c9aab1ee7f
commit
d340dabb76
@ -36,6 +36,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
static const char *var_names[] = {
|
static const char *var_names[] = {
|
||||||
"in_w" , "iw", ///< width of the input video
|
"in_w" , "iw", ///< width of the input video
|
||||||
"in_h" , "ih", ///< height of the input video
|
"in_h" , "ih", ///< height of the input video
|
||||||
@ -308,6 +310,62 @@ static uint8_t *interpolate_bilinear(uint8_t *dst_color,
|
|||||||
return dst_color;
|
return dst_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static av_always_inline void copy_elem(uint8_t *pout, const uint8_t *pin, int elem_size)
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
switch (elem_size) {
|
||||||
|
case 1:
|
||||||
|
*pout = *pin;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*((uint16_t *)pout) = *((uint16_t *)pin);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
v = AV_RB24(pin);
|
||||||
|
AV_WB24(pout, v);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*((uint32_t *)pout) = *((uint32_t *)pin);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
memcpy(pout, pin, elem_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_always_inline void simple_rotate_internal(uint8_t *dst, const uint8_t *src, int src_linesize, int angle, int elem_size, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
switch(angle) {
|
||||||
|
case 0:
|
||||||
|
memcpy(dst, src, elem_size * len);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
for (i = 0; i<len; i++)
|
||||||
|
copy_elem(dst + i*elem_size, src + (len-i-1)*src_linesize, elem_size);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
for (i = 0; i<len; i++)
|
||||||
|
copy_elem(dst + i*elem_size, src + (len-i-1)*elem_size, elem_size);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
for (i = 0; i<len; i++)
|
||||||
|
copy_elem(dst + i*elem_size, src + i*src_linesize, elem_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_always_inline void simple_rotate(uint8_t *dst, const uint8_t *src, int src_linesize, int angle, int elem_size, int len)
|
||||||
|
{
|
||||||
|
switch(elem_size) {
|
||||||
|
case 1 : simple_rotate_internal(dst, src, src_linesize, angle, 1, len); break;
|
||||||
|
case 2 : simple_rotate_internal(dst, src, src_linesize, angle, 2, len); break;
|
||||||
|
case 3 : simple_rotate_internal(dst, src, src_linesize, angle, 3, len); break;
|
||||||
|
case 4 : simple_rotate_internal(dst, src, src_linesize, angle, 4, len); break;
|
||||||
|
default: simple_rotate_internal(dst, src, src_linesize, angle, elem_size, len); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
|
#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
|
||||||
|
|
||||||
static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
|
static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
|
||||||
@ -331,6 +389,24 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
|
|||||||
x = xprime + xi + FIXP*(inw-1)/2;
|
x = xprime + xi + FIXP*(inw-1)/2;
|
||||||
y = yprime + yi + FIXP*(inh-1)/2;
|
y = yprime + yi + FIXP*(inh-1)/2;
|
||||||
|
|
||||||
|
if (fabs(rot->angle - 0) < FLT_EPSILON && outw == inw && outh == inh) {
|
||||||
|
simple_rotate(out->data[plane] + j * out->linesize[plane],
|
||||||
|
in->data[plane] + j * in->linesize[plane],
|
||||||
|
in->linesize[plane], 0, rot->draw.pixelstep[plane], outw);
|
||||||
|
} else if (fabs(rot->angle - M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) {
|
||||||
|
simple_rotate(out->data[plane] + j * out->linesize[plane],
|
||||||
|
in->data[plane] + j * rot->draw.pixelstep[plane],
|
||||||
|
in->linesize[plane], 1, rot->draw.pixelstep[plane], outw);
|
||||||
|
} else if (fabs(rot->angle - M_PI) < FLT_EPSILON && outw == inw && outh == inh) {
|
||||||
|
simple_rotate(out->data[plane] + j * out->linesize[plane],
|
||||||
|
in->data[plane] + (outh-j-1) * in->linesize[plane],
|
||||||
|
in->linesize[plane], 2, rot->draw.pixelstep[plane], outw);
|
||||||
|
} else if (fabs(rot->angle - 3*M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) {
|
||||||
|
simple_rotate(out->data[plane] + j * out->linesize[plane],
|
||||||
|
in->data[plane] + (outh-j-1) * rot->draw.pixelstep[plane],
|
||||||
|
in->linesize[plane], 3, rot->draw.pixelstep[plane], outw);
|
||||||
|
} else {
|
||||||
|
|
||||||
for (i = 0; i < outw; i++) {
|
for (i = 0; i < outw; i++) {
|
||||||
int32_t v;
|
int32_t v;
|
||||||
int x1, y1;
|
int x1, y1;
|
||||||
@ -373,6 +449,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
|
|||||||
x += c;
|
x += c;
|
||||||
y -= s;
|
y -= s;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
xprime += s;
|
xprime += s;
|
||||||
yprime += c;
|
yprime += c;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user