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
a2a06029
Commit
a2a06029
authored
Jan 25, 2021
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_lenscorrection: allow to change colors of unmapped pixels
parent
3cc2e15b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
33 additions
and
3 deletions
+33
-3
filters.texi
doc/filters.texi
+4
-0
vf_lenscorrection.c
libavfilter/vf_lenscorrection.c
+29
-3
No files found.
doc/filters.texi
View file @
a2a06029
...
...
@@ -13455,6 +13455,10 @@ Coefficient of the double quadratic correction term. This value has a range [-1,
@item i
Set interpolation type. Can be @code{nearest} or @code{bilinear}.
Default is @code{nearest}.
@item fc
Specify the color of the unmapped pixels. For the syntax of this option,
check the @ref{color syntax,,"Color" section in the ffmpeg-utils
manual,ffmpeg-utils}. Default color is @code{black@@0}.
@end table
The formula that generates the correction is:
...
...
libavfilter/vf_lenscorrection.c
View file @
a2a06029
...
...
@@ -26,11 +26,13 @@
#include <stdlib.h>
#include <math.h>
#include "libavutil/colorspace.h"
#include "libavutil/opt.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "drawutils.h"
#include "internal.h"
#include "video.h"
...
...
@@ -43,6 +45,8 @@ typedef struct LenscorrectionCtx {
int
nb_planes
;
double
cx
,
cy
,
k1
,
k2
;
int
interpolation
;
uint8_t
fill_rgba
[
4
];
int
fill_color
[
4
];
int32_t
*
correction
[
4
];
...
...
@@ -59,6 +63,7 @@ static const AVOption lenscorrection_options[] = {
{
"i"
,
"set interpolation type"
,
OFFSET
(
interpolation
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
64
,
.
flags
=
FLAGS
,
"i"
},
{
"nearest"
,
"nearest neighbour"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
0
},
0
,
0
,
.
flags
=
FLAGS
,
"i"
},
{
"bilinear"
,
"bilinear"
,
0
,
AV_OPT_TYPE_CONST
,
{.
i64
=
1
},
0
,
0
,
.
flags
=
FLAGS
,
"i"
},
{
"fc"
,
"set the color of the unmapped pixels"
,
OFFSET
(
fill_rgba
),
AV_OPT_TYPE_COLOR
,
{.
str
=
"black@0"
},
.
flags
=
FLAGS
},
{
NULL
}
};
...
...
@@ -69,6 +74,7 @@ typedef struct ThreadData {
int
w
,
h
;
int
depth
;
int
plane
;
int
fill_color
;
int
xcenter
,
ycenter
;
int32_t
*
correction
;
}
ThreadData
;
...
...
@@ -81,6 +87,7 @@ static int filter##name##_slice(AVFilterContext *ctx, void *arg, int job, \
AVFrame *in = td->in; \
AVFrame *out = td->out; \
\
const int fill_color = td->fill_color; \
const int w = td->w, h = td->h; \
const int xcenter = td->xcenter; \
const int ycenter = td->ycenter; \
...
...
@@ -100,7 +107,7 @@ static int filter##name##_slice(AVFilterContext *ctx, void *arg, int job, \
const int x = xcenter + ((radius_mult * off_x + (1<<23))>>24); \
const int y = ycenter + ((radius_mult * off_y + (1<<23))>>24); \
const char isvalid = x >= 0 && x < w && y >= 0 && y < h; \
*out++ = isvalid ? indata[y * inlinesize + x] :
0;
\
*out++ = isvalid ? indata[y * inlinesize + x] :
fill_color;
\
} \
} \
return 0; \
...
...
@@ -118,6 +125,7 @@ static int filter##name##_slice_bilinear(AVFilterContext *ctx, void *arg, \
AVFrame *in = td->in; \
AVFrame *out = td->out; \
\
const int fill_color = td->fill_color; \
const int depth = td->depth; \
const uint64_t max = (1 << 24) - 1; \
const uint64_t add = (1 << 23); \
...
...
@@ -161,7 +169,7 @@ static int filter##name##_slice_bilinear(AVFilterContext *ctx, void *arg, \
\
out[j] = av_clip_uintp2_c((sum + (1ULL << 47)) >> 48, depth); \
} else { \
out[j] =
0;
\
out[j] =
fill_color;
\
} \
} \
} \
...
...
@@ -222,8 +230,13 @@ static int config_props(AVFilterLink *outlink)
LenscorrectionCtx
*
rect
=
ctx
->
priv
;
AVFilterLink
*
inlink
=
ctx
->
inputs
[
0
];
const
AVPixFmtDescriptor
*
pixdesc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
int
is_rgb
=
!!
(
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_RGB
);
uint8_t
rgba_map
[
4
];
int
factor
;
ff_fill_rgba_map
(
rgba_map
,
inlink
->
format
);
rect
->
depth
=
pixdesc
->
comp
[
0
].
depth
;
factor
=
1
<<
(
rect
->
depth
-
8
);
rect
->
hsub
=
pixdesc
->
log2_chroma_w
;
rect
->
vsub
=
pixdesc
->
log2_chroma_h
;
outlink
->
w
=
rect
->
width
=
inlink
->
w
;
...
...
@@ -232,7 +245,19 @@ static int config_props(AVFilterLink *outlink)
rect
->
filter_slice
=
rect
->
depth
<=
8
?
filter8_slice
:
filter16_slice
;
if
(
rect
->
interpolation
)
rect
->
filter_slice
=
rect
->
depth
<=
8
?
filter8_slice_bilinear
:
filter16_slice_bilinear
;
return
0
;
if
(
is_rgb
)
{
rect
->
fill_color
[
rgba_map
[
0
]]
=
rect
->
fill_rgba
[
0
]
*
factor
;
rect
->
fill_color
[
rgba_map
[
1
]]
=
rect
->
fill_rgba
[
1
]
*
factor
;
rect
->
fill_color
[
rgba_map
[
2
]]
=
rect
->
fill_rgba
[
2
]
*
factor
;
rect
->
fill_color
[
rgba_map
[
3
]]
=
rect
->
fill_rgba
[
3
]
*
factor
;
}
else
{
rect
->
fill_color
[
0
]
=
RGB_TO_Y_BT709
(
rect
->
fill_rgba
[
0
],
rect
->
fill_rgba
[
1
],
rect
->
fill_rgba
[
2
])
*
factor
;
rect
->
fill_color
[
1
]
=
RGB_TO_U_BT709
(
rect
->
fill_rgba
[
0
],
rect
->
fill_rgba
[
1
],
rect
->
fill_rgba
[
2
],
0
)
*
factor
;
rect
->
fill_color
[
2
]
=
RGB_TO_V_BT709
(
rect
->
fill_rgba
[
0
],
rect
->
fill_rgba
[
1
],
rect
->
fill_rgba
[
2
],
0
)
*
factor
;
rect
->
fill_color
[
3
]
=
rect
->
fill_rgba
[
3
]
*
factor
;
}
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
...
...
@@ -268,6 +293,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
.
ycenter
=
ycenter
,
.
plane
=
plane
,
.
depth
=
rect
->
depth
,
.
fill_color
=
rect
->
fill_color
[
plane
],
};
if
(
!
rect
->
correction
[
plane
])
{
...
...
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