mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
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 "video.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
static const char *var_names[] = {
|
||||
"in_w" , "iw", ///< width 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;
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
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;
|
||||
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++) {
|
||||
int32_t v;
|
||||
int x1, y1;
|
||||
@ -373,6 +449,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
|
||||
x += c;
|
||||
y -= s;
|
||||
}
|
||||
}
|
||||
xprime += s;
|
||||
yprime += c;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user