Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
de30863f
Commit
de30863f
authored
Jun 24, 2016
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_rotate: add >8 bit depth support
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
1ad44715
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
123 additions
and
62 deletions
+123
-62
vf_rotate.c
libavfilter/vf_rotate.c
+109
-62
filter-pixfmts-rotate
tests/ref/fate/filter-pixfmts-rotate
+14
-0
No files found.
libavfilter/vf_rotate.c
View file @
de30863f
...
...
@@ -60,7 +60,7 @@ enum var_name {
VAR_VARS_NB
};
typedef
struct
{
typedef
struct
RotContext
{
const
AVClass
*
class
;
double
angle
;
char
*
angle_expr_str
;
///< expression for the angle
...
...
@@ -77,6 +77,9 @@ typedef struct {
double
var_values
[
VAR_VARS_NB
];
FFDrawContext
draw
;
FFDrawColor
color
;
uint8_t
*
(
*
interpolate_bilinear
)(
uint8_t
*
dst_color
,
const
uint8_t
*
src
,
int
src_linesize
,
int
src_linestep
,
int
x
,
int
y
,
int
max_x
,
int
max_y
);
}
RotContext
;
typedef
struct
ThreadData
{
...
...
@@ -142,6 +145,14 @@ static int query_formats(AVFilterContext *ctx)
AV_PIX_FMT_YUV444P
,
AV_PIX_FMT_YUVJ444P
,
AV_PIX_FMT_YUV420P
,
AV_PIX_FMT_YUVJ420P
,
AV_PIX_FMT_YUVA444P
,
AV_PIX_FMT_YUVA420P
,
AV_PIX_FMT_YUV420P10LE
,
AV_PIX_FMT_YUVA420P10LE
,
AV_PIX_FMT_YUV444P10LE
,
AV_PIX_FMT_YUVA444P10LE
,
AV_PIX_FMT_YUV420P12LE
,
AV_PIX_FMT_YUV444P12LE
,
AV_PIX_FMT_YUV444P16LE
,
AV_PIX_FMT_YUVA444P16LE
,
AV_PIX_FMT_YUV420P16LE
,
AV_PIX_FMT_YUVA420P16LE
,
AV_PIX_FMT_YUV444P9LE
,
AV_PIX_FMT_YUVA444P9LE
,
AV_PIX_FMT_YUV420P9LE
,
AV_PIX_FMT_YUVA420P9LE
,
AV_PIX_FMT_NONE
};
...
...
@@ -187,6 +198,93 @@ static const char * const func1_names[] = {
NULL
};
#define FIXP (1<<16)
#define FIXP2 (1<<20)
#define INT_PI 3294199 //(M_PI * FIXP2)
/**
* Compute the sin of a using integer values.
* Input is scaled by FIXP2 and output values are scaled by FIXP.
*/
static
int64_t
int_sin
(
int64_t
a
)
{
int64_t
a2
,
res
=
0
;
int
i
;
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
/* 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
/
(
FIXP2
*
i
*
(
i
+
1
));
}
return
(
res
+
8
)
>>
4
;
}
/**
* Interpolate the color in src at position x and y using bilinear
* interpolation.
*/
static
uint8_t
*
interpolate_bilinear8
(
uint8_t
*
dst_color
,
const
uint8_t
*
src
,
int
src_linesize
,
int
src_linestep
,
int
x
,
int
y
,
int
max_x
,
int
max_y
)
{
int
int_x
=
av_clip
(
x
>>
16
,
0
,
max_x
);
int
int_y
=
av_clip
(
y
>>
16
,
0
,
max_y
);
int
frac_x
=
x
&
0xFFFF
;
int
frac_y
=
y
&
0xFFFF
;
int
i
;
int
int_x1
=
FFMIN
(
int_x
+
1
,
max_x
);
int
int_y1
=
FFMIN
(
int_y
+
1
,
max_y
);
for
(
i
=
0
;
i
<
src_linestep
;
i
++
)
{
int
s00
=
src
[
src_linestep
*
int_x
+
i
+
src_linesize
*
int_y
];
int
s01
=
src
[
src_linestep
*
int_x1
+
i
+
src_linesize
*
int_y
];
int
s10
=
src
[
src_linestep
*
int_x
+
i
+
src_linesize
*
int_y1
];
int
s11
=
src
[
src_linestep
*
int_x1
+
i
+
src_linesize
*
int_y1
];
int
s0
=
(((
1
<<
16
)
-
frac_x
)
*
s00
+
frac_x
*
s01
);
int
s1
=
(((
1
<<
16
)
-
frac_x
)
*
s10
+
frac_x
*
s11
);
dst_color
[
i
]
=
((
int64_t
)((
1
<<
16
)
-
frac_y
)
*
s0
+
(
int64_t
)
frac_y
*
s1
)
>>
32
;
}
return
dst_color
;
}
/**
* Interpolate the color in src at position x and y using bilinear
* interpolation.
*/
static
uint8_t
*
interpolate_bilinear16
(
uint8_t
*
dst_color
,
const
uint8_t
*
src
,
int
src_linesize
,
int
src_linestep
,
int
x
,
int
y
,
int
max_x
,
int
max_y
)
{
int
int_x
=
av_clip
(
x
>>
16
,
0
,
max_x
);
int
int_y
=
av_clip
(
y
>>
16
,
0
,
max_y
);
int
frac_x
=
x
&
0xFFFF
;
int
frac_y
=
y
&
0xFFFF
;
int
i
;
int
int_x1
=
FFMIN
(
int_x
+
1
,
max_x
);
int
int_y1
=
FFMIN
(
int_y
+
1
,
max_y
);
for
(
i
=
0
;
i
<
src_linestep
;
i
+=
2
)
{
int
s00
=
AV_RL16
(
&
src
[
src_linestep
*
int_x
+
i
+
src_linesize
*
int_y
]);
int
s01
=
AV_RL16
(
&
src
[
src_linestep
*
int_x1
+
i
+
src_linesize
*
int_y
]);
int
s10
=
AV_RL16
(
&
src
[
src_linestep
*
int_x
+
i
+
src_linesize
*
int_y1
]);
int
s11
=
AV_RL16
(
&
src
[
src_linestep
*
int_x1
+
i
+
src_linesize
*
int_y1
]);
int
s0
=
(((
1
<<
16
)
-
frac_x
)
*
s00
+
frac_x
*
s01
);
int
s1
=
(((
1
<<
16
)
-
frac_x
)
*
s10
+
frac_x
*
s11
);
AV_WL16
(
&
dst_color
[
i
],
((
int64_t
)((
1
<<
16
)
-
frac_y
)
*
s0
+
(
int64_t
)
frac_y
*
s1
)
>>
32
);
}
return
dst_color
;
}
static
int
config_props
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
...
...
@@ -203,6 +301,11 @@ static int config_props(AVFilterLink *outlink)
rot
->
hsub
=
pixdesc
->
log2_chroma_w
;
rot
->
vsub
=
pixdesc
->
log2_chroma_h
;
if
(
pixdesc
->
comp
[
0
].
depth
==
8
)
rot
->
interpolate_bilinear
=
interpolate_bilinear8
;
else
rot
->
interpolate_bilinear
=
interpolate_bilinear16
;
rot
->
var_values
[
VAR_IN_W
]
=
rot
->
var_values
[
VAR_IW
]
=
inlink
->
w
;
rot
->
var_values
[
VAR_IN_H
]
=
rot
->
var_values
[
VAR_IH
]
=
inlink
->
h
;
rot
->
var_values
[
VAR_HSUB
]
=
1
<<
rot
->
hsub
;
...
...
@@ -255,63 +358,6 @@ static int config_props(AVFilterLink *outlink)
return
0
;
}
#define FIXP (1<<16)
#define FIXP2 (1<<20)
#define INT_PI 3294199 //(M_PI * FIXP2)
/**
* Compute the sin of a using integer values.
* Input is scaled by FIXP2 and output values are scaled by FIXP.
*/
static
int64_t
int_sin
(
int64_t
a
)
{
int64_t
a2
,
res
=
0
;
int
i
;
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
/* 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
/
(
FIXP2
*
i
*
(
i
+
1
));
}
return
(
res
+
8
)
>>
4
;
}
/**
* Interpolate the color in src at position x and y using bilinear
* interpolation.
*/
static
uint8_t
*
interpolate_bilinear
(
uint8_t
*
dst_color
,
const
uint8_t
*
src
,
int
src_linesize
,
int
src_linestep
,
int
x
,
int
y
,
int
max_x
,
int
max_y
)
{
int
int_x
=
av_clip
(
x
>>
16
,
0
,
max_x
);
int
int_y
=
av_clip
(
y
>>
16
,
0
,
max_y
);
int
frac_x
=
x
&
0xFFFF
;
int
frac_y
=
y
&
0xFFFF
;
int
i
;
int
int_x1
=
FFMIN
(
int_x
+
1
,
max_x
);
int
int_y1
=
FFMIN
(
int_y
+
1
,
max_y
);
for
(
i
=
0
;
i
<
src_linestep
;
i
++
)
{
int
s00
=
src
[
src_linestep
*
int_x
+
i
+
src_linesize
*
int_y
];
int
s01
=
src
[
src_linestep
*
int_x1
+
i
+
src_linesize
*
int_y
];
int
s10
=
src
[
src_linestep
*
int_x
+
i
+
src_linesize
*
int_y1
];
int
s11
=
src
[
src_linestep
*
int_x1
+
i
+
src_linesize
*
int_y1
];
int
s0
=
(((
1
<<
16
)
-
frac_x
)
*
s00
+
frac_x
*
s01
);
int
s1
=
(((
1
<<
16
)
-
frac_x
)
*
s10
+
frac_x
*
s11
);
dst_color
[
i
]
=
((
int64_t
)((
1
<<
16
)
-
frac_y
)
*
s0
+
(
int64_t
)
frac_y
*
s1
)
>>
32
;
}
return
dst_color
;
}
static
av_always_inline
void
copy_elem
(
uint8_t
*
pout
,
const
uint8_t
*
pin
,
int
elem_size
)
{
int
v
;
...
...
@@ -421,9 +467,9 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
uint8_t
inp_inv
[
4
];
/* interpolated input value */
pout
=
out
->
data
[
plane
]
+
j
*
out
->
linesize
[
plane
]
+
i
*
rot
->
draw
.
pixelstep
[
plane
];
if
(
rot
->
use_bilinear
)
{
pin
=
interpolate_bilinear
(
inp_inv
,
in
->
data
[
plane
],
in
->
linesize
[
plane
],
rot
->
draw
.
pixelstep
[
plane
],
x
,
y
,
inw
-
1
,
inh
-
1
);
pin
=
rot
->
interpolate_bilinear
(
inp_inv
,
in
->
data
[
plane
],
in
->
linesize
[
plane
],
rot
->
draw
.
pixelstep
[
plane
],
x
,
y
,
inw
-
1
,
inh
-
1
);
}
else
{
int
x2
=
av_clip
(
x1
,
0
,
inw
-
1
);
int
y2
=
av_clip
(
y1
,
0
,
inh
-
1
);
...
...
@@ -434,7 +480,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
*
pout
=
*
pin
;
break
;
case
2
:
*
((
uint16_t
*
)
pout
)
=
*
((
uint16_t
*
)
pin
);
v
=
AV_RL16
(
pin
);
AV_WL16
(
pout
,
v
);
break
;
case
3
:
v
=
AV_RB24
(
pin
);
...
...
tests/ref/fate/filter-pixfmts-rotate
View file @
de30863f
...
...
@@ -13,8 +13,22 @@ rgb24 f4438057d046e6d98ade4e45294b21be
rgba b6e1b441c365e03b5ffdf9b7b68d9a0c
yuv410p 5d4d992a7728431aa4e0700f87fb7fd8
yuv420p a014c7eb7a8385d1dd092b7a583f1bff
yuv420p10le 15c83294ef560d57f25d16ae6e0fc70c
yuv420p12le c19a477a07fcf88e37ab37b416d064c0
yuv420p16le dae8da9edd4255051e3e546ae7ed9bd3
yuv420p9le 83a6d32c91c15a3bc334bb9abf920654
yuv444p 8f90fb3a757878c545a8bfe5d19a9bab
yuv444p10le 6d736fa464ff2de2b07e0a56af8444b7
yuv444p12le 08a81b2ea9c7c8b447e40ef8f4a46a4a
yuv444p16le 781c22317c02b3dd4225709000bdb847
yuv444p9le caef947b8aff5b52285385c6ae9b2439
yuva420p b227672e56215e184e702c02a771d7f3
yuva420p10le 01e94ee605714396e69b013c11dda348
yuva420p16le b1930ab28ffe031c78ca28d3406311c8
yuva420p9le 0e9c9803aaaddc9f38e419de587793c2
yuva444p 459fad5abfd16db9bb6a52761dc74cc1
yuva444p10le 92f820d3481b7ebcb48b98a73e7b4c90
yuva444p16le 2ed56ea50fafda4d226c9b133755dad8
yuva444p9le 4eeb5988df0740fea720da1e31bbb829
yuvj420p 8f3d8f1b4577d11082d5ab8a901e048d
yuvj444p b161e6d5a941e2a4bb7bc56ef8af623f
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment