Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Releases
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
ffmpeg
Commits
5508e04c
Commit
5508e04c
authored
Jan 30, 2023
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_colorlevels: add support for gbrpf32 format
parent
2d202985
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
28 deletions
+90
-28
vf_colorlevels.c
libavfilter/vf_colorlevels.c
+90
-28
No files found.
libavfilter/vf_colorlevels.c
View file @
5508e04c
...
...
@@ -97,11 +97,13 @@ typedef struct ThreadData {
int
h
;
float
fimin
[
4
];
float
fomin
[
4
];
int
imin
[
4
];
int
omin
[
4
];
}
ThreadData
;
#define DO_COMMON(type,
clip, preserve, planar)
\
#define DO_COMMON(type,
ptype, clip, preserve, planar)
\
const ThreadData *td = arg; \
const int linesize = s->linesize; \
const int step = s->step; \
...
...
@@ -118,14 +120,14 @@ typedef struct ThreadData {
type *dst_g = (type *)(td->dstrow[G]) + src_linesize * slice_start; \
type *dst_b = (type *)(td->dstrow[B]) + src_linesize * slice_start; \
type *dst_a = (type *)(td->dstrow[A]) + src_linesize * slice_start; \
const
int imin_r = td->imin[R];
\
const
int imin_g = td->imin[G];
\
const
int imin_b = td->imin[B];
\
const
int imin_a = td->imin[A];
\
const
int omin_r = td->omin[R];
\
const
int omin_g = td->omin[G];
\
const
int omin_b = td->omin[B];
\
const
int omin_a = td->omin[A];
\
const
ptype imin_r = s->depth == 32 ? td->fimin[R] : td->imin[R];
\
const
ptype imin_g = s->depth == 32 ? td->fimin[G] : td->imin[G];
\
const
ptype imin_b = s->depth == 32 ? td->fimin[B] : td->imin[B];
\
const
ptype imin_a = s->depth == 32 ? td->fimin[A] : td->imin[A];
\
const
ptype omin_r = s->depth == 32 ? td->fomin[R] : td->omin[R];
\
const
ptype omin_g = s->depth == 32 ? td->fomin[G] : td->omin[G];
\
const
ptype omin_b = s->depth == 32 ? td->fomin[B] : td->omin[B];
\
const
ptype omin_a = s->depth == 32 ? td->fomin[A] : td->omin[A];
\
const float coeff_r = td->coeff[R]; \
const float coeff_g = td->coeff[G]; \
const float coeff_b = td->coeff[B]; \
...
...
@@ -133,12 +135,12 @@ typedef struct ThreadData {
\
for (int y = slice_start; y < slice_end; y++) { \
for (int x = 0; x < linesize; x += step) { \
int ir, ig, ib, or, og, ob;
\
ptype ir, ig, ib, or, og, ob;
\
ir = src_r[x]; \
ig = src_g[x]; \
ib = src_b[x]; \
if (preserve) { \
float ratio, icolor, ocolor, max = s->
max;
\
float ratio, icolor, ocolor, max = s->
depth==32 ? 1.f : s->max;
\
\
or = (ir - imin_r) * coeff_r + omin_r; \
og = (ig - imin_g) * coeff_g + omin_g; \
...
...
@@ -180,39 +182,40 @@ typedef struct ThreadData {
#define CLIP8(x, depth) av_clip_uint8(x)
#define CLIP16(x, depth) av_clip_uint16(x)
#define NOCLIP(x, depth) (x)
static
int
colorlevels_slice_8
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
uint8_t
,
CLIP8
,
0
,
0
)
DO_COMMON
(
uint8_t
,
int
,
CLIP8
,
0
,
0
)
return
0
;
}
static
int
colorlevels_slice_16
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
\
DO_COMMON
(
uint16_t
,
CLIP16
,
0
,
0
)
DO_COMMON
(
uint16_t
,
int
,
CLIP16
,
0
,
0
)
return
0
;
}
static
int
colorlevels_preserve_slice_8
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
uint8_t
,
CLIP8
,
1
,
0
)
DO_COMMON
(
uint8_t
,
int
,
CLIP8
,
1
,
0
)
return
0
;
}
static
int
colorlevels_preserve_slice_16
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
uint16_t
,
CLIP16
,
1
,
0
)
DO_COMMON
(
uint16_t
,
int
,
CLIP16
,
1
,
0
)
return
0
;
}
static
int
colorlevels_slice_8_planar
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
uint8_t
,
CLIP8
,
0
,
1
)
DO_COMMON
(
uint8_t
,
int
,
CLIP8
,
0
,
1
)
return
0
;
}
...
...
@@ -220,7 +223,7 @@ static int colorlevels_slice_9_planar(AVFilterContext *ctx, void *arg, int jobnr
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
9
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
0
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
0
,
1
)
return
0
;
}
...
...
@@ -228,7 +231,7 @@ static int colorlevels_slice_10_planar(AVFilterContext *ctx, void *arg, int jobn
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
10
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
0
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
0
,
1
)
return
0
;
}
...
...
@@ -236,7 +239,7 @@ static int colorlevels_slice_12_planar(AVFilterContext *ctx, void *arg, int jobn
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
12
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
0
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
0
,
1
)
return
0
;
}
...
...
@@ -244,21 +247,28 @@ static int colorlevels_slice_14_planar(AVFilterContext *ctx, void *arg, int jobn
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
14
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
0
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
0
,
1
)
return
0
;
}
static
int
colorlevels_slice_16_planar
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
uint16_t
,
CLIP16
,
0
,
1
)
DO_COMMON
(
uint16_t
,
int
,
CLIP16
,
0
,
1
)
return
0
;
}
static
int
colorlevels_slice_32_planar
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
float
,
float
,
NOCLIP
,
0
,
1
)
return
0
;
}
static
int
colorlevels_preserve_slice_8_planar
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
uint8_t
,
CLIP8
,
1
,
1
)
DO_COMMON
(
uint8_t
,
int
,
CLIP8
,
1
,
1
)
return
0
;
}
...
...
@@ -266,7 +276,7 @@ static int colorlevels_preserve_slice_9_planar(AVFilterContext *ctx, void *arg,
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
9
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
1
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
1
,
1
)
return
0
;
}
...
...
@@ -274,7 +284,7 @@ static int colorlevels_preserve_slice_10_planar(AVFilterContext *ctx, void *arg,
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
10
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
1
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
1
,
1
)
return
0
;
}
...
...
@@ -282,7 +292,7 @@ static int colorlevels_preserve_slice_12_planar(AVFilterContext *ctx, void *arg,
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
12
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
1
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
1
,
1
)
return
0
;
}
...
...
@@ -290,14 +300,21 @@ static int colorlevels_preserve_slice_14_planar(AVFilterContext *ctx, void *arg,
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
const
int
depth
=
14
;
DO_COMMON
(
uint16_t
,
av_clip_uintp2
,
1
,
1
)
DO_COMMON
(
uint16_t
,
int
,
av_clip_uintp2
,
1
,
1
)
return
0
;
}
static
int
colorlevels_preserve_slice_16_planar
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
uint16_t
,
CLIP16
,
1
,
1
)
DO_COMMON
(
uint16_t
,
int
,
CLIP16
,
1
,
1
)
return
0
;
}
static
int
colorlevels_preserve_slice_32_planar
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
ColorLevelsContext
*
s
=
ctx
->
priv
;
DO_COMMON
(
float
,
float
,
NOCLIP
,
1
,
1
)
return
0
;
}
...
...
@@ -349,6 +366,10 @@ static int config_input(AVFilterLink *inlink)
s
->
colorlevels_slice
[
0
]
=
colorlevels_slice_16_planar
;
s
->
colorlevels_slice
[
1
]
=
colorlevels_preserve_slice_16_planar
;
break
;
case
32
:
s
->
colorlevels_slice
[
0
]
=
colorlevels_slice_32_planar
;
s
->
colorlevels_slice
[
1
]
=
colorlevels_preserve_slice_32_planar
;
break
;
}
}
...
...
@@ -479,6 +500,46 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
td
.
omin
[
i
]
=
omin
;
}
break
;
case
4
:
for
(
int
i
=
0
;
i
<
s
->
nb_comp
;
i
++
)
{
Range
*
r
=
&
s
->
range
[
i
];
const
uint8_t
offset
=
s
->
rgba_map
[
i
];
const
uint8_t
*
srcrow
=
in
->
data
[
0
];
float
imin
=
r
->
in_min
;
float
imax
=
r
->
in_max
;
float
omin
=
r
->
out_min
;
float
omax
=
r
->
out_max
;
float
coeff
;
if
(
imin
<
0
.
f
)
{
imin
=
1
.
f
;
for
(
int
y
=
0
;
y
<
inlink
->
h
;
y
++
)
{
const
float
*
src
=
(
const
float
*
)
srcrow
;
for
(
int
x
=
0
;
x
<
s
->
linesize
;
x
+=
step
)
imin
=
fminf
(
imin
,
src
[
x
+
offset
]);
srcrow
+=
in
->
linesize
[
0
];
}
}
if
(
imax
<
0
.
f
)
{
srcrow
=
in
->
data
[
0
];
imax
=
0
.
f
;
for
(
int
y
=
0
;
y
<
inlink
->
h
;
y
++
)
{
const
float
*
src
=
(
const
float
*
)
srcrow
;
for
(
int
x
=
0
;
x
<
s
->
linesize
;
x
+=
step
)
imax
=
fmaxf
(
imax
,
src
[
x
+
offset
]);
srcrow
+=
in
->
linesize
[
0
];
}
}
coeff
=
(
omax
-
omin
)
/
(
double
)(
imax
-
imin
);
td
.
coeff
[
i
]
=
coeff
;
td
.
fimin
[
i
]
=
imin
;
td
.
fomin
[
i
]
=
omin
;
}
break
;
}
ff_filter_execute
(
ctx
,
s
->
colorlevels_slice
[
s
->
preserve_color
>
0
],
&
td
,
NULL
,
...
...
@@ -524,7 +585,8 @@ const AVFilter ff_vf_colorlevels = {
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_GBRP16
,
AV_PIX_FMT_GBRAP16
,
AV_PIX_FMT_GBRPF32
,
AV_PIX_FMT_GBRAPF32
),
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
|
AVFILTER_FLAG_SLICE_THREADS
,
.
process_command
=
ff_filter_process_command
,
};
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