Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
d6e50e07
Commit
d6e50e07
authored
Sep 24, 2018
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_curves: add planar rgb support
parent
bb660800
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
146 additions
and
58 deletions
+146
-58
vf_curves.c
libavfilter/vf_curves.c
+141
-53
filter-curves
tests/ref/fate/filter-curves
+5
-5
No files found.
libavfilter/vf_curves.c
View file @
d6e50e07
...
@@ -70,6 +70,9 @@ typedef struct CurvesContext {
...
@@ -70,6 +70,9 @@ typedef struct CurvesContext {
int
step
;
int
step
;
char
*
plot_filename
;
char
*
plot_filename
;
int
is_16bit
;
int
is_16bit
;
int
depth
;
int
(
*
filter_slice
)(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
);
}
CurvesContext
;
}
CurvesContext
;
typedef
struct
ThreadData
{
typedef
struct
ThreadData
{
...
@@ -209,7 +212,7 @@ static int get_nb_points(const struct keypoint *d)
...
@@ -209,7 +212,7 @@ static int get_nb_points(const struct keypoint *d)
* @see http://people.math.sfu.ca/~stockie/teaching/macm316/notes/splines.pdf
* @see http://people.math.sfu.ca/~stockie/teaching/macm316/notes/splines.pdf
*/
*/
#define CLIP(v) (nbits == 8 ? av_clip_uint8(v) : av_clip_uint
16(v
))
#define CLIP(v) (nbits == 8 ? av_clip_uint8(v) : av_clip_uint
p2_c(v, nbits
))
static
inline
int
interpolate
(
void
*
log_ctx
,
uint16_t
*
y
,
static
inline
int
interpolate
(
void
*
log_ctx
,
uint16_t
*
y
,
const
struct
keypoint
*
points
,
int
nbits
)
const
struct
keypoint
*
points
,
int
nbits
)
...
@@ -341,6 +344,10 @@ static int interpolate##nbits(void *log_ctx, uint16_t *y, \
...
@@ -341,6 +344,10 @@ static int interpolate##nbits(void *log_ctx, uint16_t *y, \
}
}
DECLARE_INTERPOLATE_FUNC
(
8
)
DECLARE_INTERPOLATE_FUNC
(
8
)
DECLARE_INTERPOLATE_FUNC
(
9
)
DECLARE_INTERPOLATE_FUNC
(
10
)
DECLARE_INTERPOLATE_FUNC
(
12
)
DECLARE_INTERPOLATE_FUNC
(
14
)
DECLARE_INTERPOLATE_FUNC
(
16
)
DECLARE_INTERPOLATE_FUNC
(
16
)
static
int
parse_psfile
(
AVFilterContext
*
ctx
,
const
char
*
fname
)
static
int
parse_psfile
(
AVFilterContext
*
ctx
,
const
char
*
fname
)
...
@@ -512,6 +519,12 @@ static int query_formats(AVFilterContext *ctx)
...
@@ -512,6 +519,12 @@ static int query_formats(AVFilterContext *ctx)
AV_PIX_FMT_RGB0
,
AV_PIX_FMT_BGR0
,
AV_PIX_FMT_RGB0
,
AV_PIX_FMT_BGR0
,
AV_PIX_FMT_RGB48
,
AV_PIX_FMT_BGR48
,
AV_PIX_FMT_RGB48
,
AV_PIX_FMT_BGR48
,
AV_PIX_FMT_RGBA64
,
AV_PIX_FMT_BGRA64
,
AV_PIX_FMT_RGBA64
,
AV_PIX_FMT_BGRA64
,
AV_PIX_FMT_GBRP
,
AV_PIX_FMT_GBRAP
,
AV_PIX_FMT_GBRP9
,
AV_PIX_FMT_GBRP10
,
AV_PIX_FMT_GBRAP10
,
AV_PIX_FMT_GBRP12
,
AV_PIX_FMT_GBRAP12
,
AV_PIX_FMT_GBRP14
,
AV_PIX_FMT_GBRP16
,
AV_PIX_FMT_GBRAP16
,
AV_PIX_FMT_NONE
AV_PIX_FMT_NONE
};
};
AVFilterFormats
*
fmts_list
=
ff_make_format_list
(
pix_fmts
);
AVFilterFormats
*
fmts_list
=
ff_make_format_list
(
pix_fmts
);
...
@@ -520,6 +533,120 @@ static int query_formats(AVFilterContext *ctx)
...
@@ -520,6 +533,120 @@ static int query_formats(AVFilterContext *ctx)
return
ff_set_common_formats
(
ctx
,
fmts_list
);
return
ff_set_common_formats
(
ctx
,
fmts_list
);
}
}
static
int
filter_slice_packed
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
int
x
,
y
;
const
CurvesContext
*
curves
=
ctx
->
priv
;
const
ThreadData
*
td
=
arg
;
const
AVFrame
*
in
=
td
->
in
;
const
AVFrame
*
out
=
td
->
out
;
const
int
direct
=
out
==
in
;
const
int
step
=
curves
->
step
;
const
uint8_t
r
=
curves
->
rgba_map
[
R
];
const
uint8_t
g
=
curves
->
rgba_map
[
G
];
const
uint8_t
b
=
curves
->
rgba_map
[
B
];
const
uint8_t
a
=
curves
->
rgba_map
[
A
];
const
int
slice_start
=
(
in
->
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
in
->
height
*
(
jobnr
+
1
))
/
nb_jobs
;
if
(
curves
->
is_16bit
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint16_t
*
dstp
=
(
uint16_t
*
)(
out
->
data
[
0
]
+
y
*
out
->
linesize
[
0
]);
const
uint16_t
*
srcp
=
(
const
uint16_t
*
)(
in
->
data
[
0
]
+
y
*
in
->
linesize
[
0
]);
for
(
x
=
0
;
x
<
in
->
width
*
step
;
x
+=
step
)
{
dstp
[
x
+
r
]
=
curves
->
graph
[
R
][
srcp
[
x
+
r
]];
dstp
[
x
+
g
]
=
curves
->
graph
[
G
][
srcp
[
x
+
g
]];
dstp
[
x
+
b
]
=
curves
->
graph
[
B
][
srcp
[
x
+
b
]];
if
(
!
direct
&&
step
==
4
)
dstp
[
x
+
a
]
=
srcp
[
x
+
a
];
}
}
}
else
{
uint8_t
*
dst
=
out
->
data
[
0
]
+
slice_start
*
out
->
linesize
[
0
];
const
uint8_t
*
src
=
in
->
data
[
0
]
+
slice_start
*
in
->
linesize
[
0
];
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
x
=
0
;
x
<
in
->
width
*
step
;
x
+=
step
)
{
dst
[
x
+
r
]
=
curves
->
graph
[
R
][
src
[
x
+
r
]];
dst
[
x
+
g
]
=
curves
->
graph
[
G
][
src
[
x
+
g
]];
dst
[
x
+
b
]
=
curves
->
graph
[
B
][
src
[
x
+
b
]];
if
(
!
direct
&&
step
==
4
)
dst
[
x
+
a
]
=
src
[
x
+
a
];
}
dst
+=
out
->
linesize
[
0
];
src
+=
in
->
linesize
[
0
];
}
}
return
0
;
}
static
int
filter_slice_planar
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
int
x
,
y
;
const
CurvesContext
*
curves
=
ctx
->
priv
;
const
ThreadData
*
td
=
arg
;
const
AVFrame
*
in
=
td
->
in
;
const
AVFrame
*
out
=
td
->
out
;
const
int
direct
=
out
==
in
;
const
int
step
=
curves
->
step
;
const
uint8_t
r
=
curves
->
rgba_map
[
R
];
const
uint8_t
g
=
curves
->
rgba_map
[
G
];
const
uint8_t
b
=
curves
->
rgba_map
[
B
];
const
uint8_t
a
=
curves
->
rgba_map
[
A
];
const
int
slice_start
=
(
in
->
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
in
->
height
*
(
jobnr
+
1
))
/
nb_jobs
;
if
(
curves
->
is_16bit
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint16_t
*
dstrp
=
(
uint16_t
*
)(
out
->
data
[
r
]
+
y
*
out
->
linesize
[
r
]);
uint16_t
*
dstgp
=
(
uint16_t
*
)(
out
->
data
[
g
]
+
y
*
out
->
linesize
[
g
]);
uint16_t
*
dstbp
=
(
uint16_t
*
)(
out
->
data
[
b
]
+
y
*
out
->
linesize
[
b
]);
uint16_t
*
dstap
=
(
uint16_t
*
)(
out
->
data
[
a
]
+
y
*
out
->
linesize
[
a
]);
const
uint16_t
*
srcrp
=
(
const
uint16_t
*
)(
in
->
data
[
r
]
+
y
*
in
->
linesize
[
r
]);
const
uint16_t
*
srcgp
=
(
const
uint16_t
*
)(
in
->
data
[
g
]
+
y
*
in
->
linesize
[
g
]);
const
uint16_t
*
srcbp
=
(
const
uint16_t
*
)(
in
->
data
[
b
]
+
y
*
in
->
linesize
[
b
]);
const
uint16_t
*
srcap
=
(
const
uint16_t
*
)(
in
->
data
[
a
]
+
y
*
in
->
linesize
[
a
]);
for
(
x
=
0
;
x
<
in
->
width
;
x
++
)
{
dstrp
[
x
]
=
curves
->
graph
[
R
][
srcrp
[
x
]];
dstgp
[
x
]
=
curves
->
graph
[
G
][
srcgp
[
x
]];
dstbp
[
x
]
=
curves
->
graph
[
B
][
srcbp
[
x
]];
if
(
!
direct
&&
step
==
4
)
dstap
[
x
]
=
srcap
[
x
];
}
}
}
else
{
uint8_t
*
dstr
=
out
->
data
[
r
]
+
slice_start
*
out
->
linesize
[
r
];
uint8_t
*
dstg
=
out
->
data
[
g
]
+
slice_start
*
out
->
linesize
[
g
];
uint8_t
*
dstb
=
out
->
data
[
b
]
+
slice_start
*
out
->
linesize
[
b
];
uint8_t
*
dsta
=
out
->
data
[
a
]
+
slice_start
*
out
->
linesize
[
a
];
const
uint8_t
*
srcr
=
in
->
data
[
r
]
+
slice_start
*
in
->
linesize
[
r
];
const
uint8_t
*
srcg
=
in
->
data
[
g
]
+
slice_start
*
in
->
linesize
[
g
];
const
uint8_t
*
srcb
=
in
->
data
[
b
]
+
slice_start
*
in
->
linesize
[
b
];
const
uint8_t
*
srca
=
in
->
data
[
a
]
+
slice_start
*
in
->
linesize
[
a
];
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
x
=
0
;
x
<
in
->
width
;
x
++
)
{
dstr
[
x
]
=
curves
->
graph
[
R
][
srcr
[
x
]];
dstg
[
x
]
=
curves
->
graph
[
G
][
srcg
[
x
]];
dstb
[
x
]
=
curves
->
graph
[
B
][
srcb
[
x
]];
if
(
!
direct
&&
step
==
4
)
dsta
[
x
]
=
srca
[
x
];
}
dstr
+=
out
->
linesize
[
r
];
dstg
+=
out
->
linesize
[
g
];
dstb
+=
out
->
linesize
[
b
];
dsta
+=
out
->
linesize
[
a
];
srcr
+=
in
->
linesize
[
r
];
srcg
+=
in
->
linesize
[
g
];
srcb
+=
in
->
linesize
[
b
];
srca
+=
in
->
linesize
[
a
];
}
}
return
0
;
}
static
int
config_input
(
AVFilterLink
*
inlink
)
static
int
config_input
(
AVFilterLink
*
inlink
)
{
{
int
i
,
j
,
ret
;
int
i
,
j
,
ret
;
...
@@ -531,8 +658,10 @@ static int config_input(AVFilterLink *inlink)
...
@@ -531,8 +658,10 @@ static int config_input(AVFilterLink *inlink)
ff_fill_rgba_map
(
curves
->
rgba_map
,
inlink
->
format
);
ff_fill_rgba_map
(
curves
->
rgba_map
,
inlink
->
format
);
curves
->
is_16bit
=
desc
->
comp
[
0
].
depth
>
8
;
curves
->
is_16bit
=
desc
->
comp
[
0
].
depth
>
8
;
curves
->
lut_size
=
curves
->
is_16bit
?
1
<<
16
:
1
<<
8
;
curves
->
depth
=
desc
->
comp
[
0
].
depth
;
curves
->
lut_size
=
1
<<
curves
->
depth
;
curves
->
step
=
av_get_padded_bits_per_pixel
(
desc
)
>>
(
3
+
curves
->
is_16bit
);
curves
->
step
=
av_get_padded_bits_per_pixel
(
desc
)
>>
(
3
+
curves
->
is_16bit
);
curves
->
filter_slice
=
desc
->
flags
&
AV_PIX_FMT_FLAG_PLANAR
?
filter_slice_planar
:
filter_slice_packed
;
for
(
i
=
0
;
i
<
NB_COMP
+
1
;
i
++
)
{
for
(
i
=
0
;
i
<
NB_COMP
+
1
;
i
++
)
{
curves
->
graph
[
i
]
=
av_mallocz_array
(
curves
->
lut_size
,
sizeof
(
*
curves
->
graph
[
0
]));
curves
->
graph
[
i
]
=
av_mallocz_array
(
curves
->
lut_size
,
sizeof
(
*
curves
->
graph
[
0
]));
...
@@ -541,8 +670,14 @@ static int config_input(AVFilterLink *inlink)
...
@@ -541,8 +670,14 @@ static int config_input(AVFilterLink *inlink)
ret
=
parse_points_str
(
ctx
,
comp_points
+
i
,
curves
->
comp_points_str
[
i
],
curves
->
lut_size
);
ret
=
parse_points_str
(
ctx
,
comp_points
+
i
,
curves
->
comp_points_str
[
i
],
curves
->
lut_size
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
if
(
curves
->
is_16bit
)
ret
=
interpolate16
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
switch
(
curves
->
depth
)
{
else
ret
=
interpolate8
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
case
8
:
ret
=
interpolate8
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
break
;
case
9
:
ret
=
interpolate9
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
break
;
case
10
:
ret
=
interpolate10
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
break
;
case
12
:
ret
=
interpolate12
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
break
;
case
14
:
ret
=
interpolate14
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
break
;
case
16
:
ret
=
interpolate16
(
ctx
,
curves
->
graph
[
i
],
comp_points
[
i
]);
break
;
}
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
}
}
...
@@ -579,57 +714,10 @@ static int config_input(AVFilterLink *inlink)
...
@@ -579,57 +714,10 @@ static int config_input(AVFilterLink *inlink)
return
0
;
return
0
;
}
}
static
int
filter_slice
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
int
x
,
y
;
const
CurvesContext
*
curves
=
ctx
->
priv
;
const
ThreadData
*
td
=
arg
;
const
AVFrame
*
in
=
td
->
in
;
const
AVFrame
*
out
=
td
->
out
;
const
int
direct
=
out
==
in
;
const
int
step
=
curves
->
step
;
const
uint8_t
r
=
curves
->
rgba_map
[
R
];
const
uint8_t
g
=
curves
->
rgba_map
[
G
];
const
uint8_t
b
=
curves
->
rgba_map
[
B
];
const
uint8_t
a
=
curves
->
rgba_map
[
A
];
const
int
slice_start
=
(
in
->
height
*
jobnr
)
/
nb_jobs
;
const
int
slice_end
=
(
in
->
height
*
(
jobnr
+
1
))
/
nb_jobs
;
if
(
curves
->
is_16bit
)
{
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
uint16_t
*
dstp
=
(
uint16_t
*
)(
out
->
data
[
0
]
+
y
*
out
->
linesize
[
0
]);
const
uint16_t
*
srcp
=
(
const
uint16_t
*
)(
in
->
data
[
0
]
+
y
*
in
->
linesize
[
0
]);
for
(
x
=
0
;
x
<
in
->
width
*
step
;
x
+=
step
)
{
dstp
[
x
+
r
]
=
curves
->
graph
[
R
][
srcp
[
x
+
r
]];
dstp
[
x
+
g
]
=
curves
->
graph
[
G
][
srcp
[
x
+
g
]];
dstp
[
x
+
b
]
=
curves
->
graph
[
B
][
srcp
[
x
+
b
]];
if
(
!
direct
&&
step
==
4
)
dstp
[
x
+
a
]
=
srcp
[
x
+
a
];
}
}
}
else
{
uint8_t
*
dst
=
out
->
data
[
0
]
+
slice_start
*
out
->
linesize
[
0
];
const
uint8_t
*
src
=
in
->
data
[
0
]
+
slice_start
*
in
->
linesize
[
0
];
for
(
y
=
slice_start
;
y
<
slice_end
;
y
++
)
{
for
(
x
=
0
;
x
<
in
->
width
*
step
;
x
+=
step
)
{
dst
[
x
+
r
]
=
curves
->
graph
[
R
][
src
[
x
+
r
]];
dst
[
x
+
g
]
=
curves
->
graph
[
G
][
src
[
x
+
g
]];
dst
[
x
+
b
]
=
curves
->
graph
[
B
][
src
[
x
+
b
]];
if
(
!
direct
&&
step
==
4
)
dst
[
x
+
a
]
=
src
[
x
+
a
];
}
dst
+=
out
->
linesize
[
0
];
src
+=
in
->
linesize
[
0
];
}
}
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterContext
*
ctx
=
inlink
->
dst
;
CurvesContext
*
curves
=
ctx
->
priv
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
AVFrame
*
out
;
AVFrame
*
out
;
ThreadData
td
;
ThreadData
td
;
...
@@ -647,7 +735,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
...
@@ -647,7 +735,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
td
.
in
=
in
;
td
.
in
=
in
;
td
.
out
=
out
;
td
.
out
=
out
;
ctx
->
internal
->
execute
(
ctx
,
filter_slice
,
&
td
,
NULL
,
FFMIN
(
outlink
->
h
,
ff_filter_get_nb_threads
(
ctx
)));
ctx
->
internal
->
execute
(
ctx
,
curves
->
filter_slice
,
&
td
,
NULL
,
FFMIN
(
outlink
->
h
,
ff_filter_get_nb_threads
(
ctx
)));
if
(
out
!=
in
)
if
(
out
!=
in
)
av_frame_free
(
&
in
);
av_frame_free
(
&
in
);
...
...
tests/ref/fate/filter-curves
View file @
d6e50e07
...
@@ -3,8 +3,8 @@
...
@@ -3,8 +3,8 @@
#codec_id 0: rawvideo
#codec_id 0: rawvideo
#dimensions 0: 640x480
#dimensions 0: 640x480
#sar 0: 0/1
#sar 0: 0/1
0, 0, 0, 1, 921600, 0x
cf42
6780
0, 0, 0, 1, 921600, 0x
3ed3
6780
0, 1, 1, 1, 921600, 0x7
642
892d
0, 1, 1, 1, 921600, 0x7
dbd
892d
0, 2, 2, 1, 921600, 0x
13c1
ab7e
0, 2, 2, 1, 921600, 0x
0894
ab7e
0, 3, 3, 1, 921600, 0x
3eca
04bf
0, 3, 3, 1, 921600, 0x
4710
04bf
0, 4, 4, 1, 921600, 0x
6153
9162
0, 4, 4, 1, 921600, 0x
79c7
9162
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