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
06db1bef
Commit
06db1bef
authored
Feb 08, 2020
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avfilter/vf_fade: add >8 bit support for black and alpha fade
parent
48b102c5
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
138 additions
and
31 deletions
+138
-31
vf_fade.c
libavfilter/vf_fade.c
+138
-31
No files found.
libavfilter/vf_fade.c
View file @
06db1bef
...
@@ -54,7 +54,7 @@ typedef struct FadeContext {
...
@@ -54,7 +54,7 @@ typedef struct FadeContext {
int
type
;
int
type
;
int
factor
,
fade_per_frame
;
int
factor
,
fade_per_frame
;
int
start_frame
,
nb_frames
;
int
start_frame
,
nb_frames
;
int
hsub
,
vsub
,
bpp
;
int
hsub
,
vsub
,
bpp
,
depth
;
unsigned
int
black_level
,
black_level_scaled
;
unsigned
int
black_level
,
black_level_scaled
;
uint8_t
is_rgb
;
uint8_t
is_rgb
;
uint8_t
is_packed_rgb
;
uint8_t
is_packed_rgb
;
...
@@ -65,6 +65,9 @@ typedef struct FadeContext {
...
@@ -65,6 +65,9 @@ typedef struct FadeContext {
enum
{
VF_FADE_WAITING
=
0
,
VF_FADE_FADING
,
VF_FADE_DONE
}
fade_state
;
enum
{
VF_FADE_WAITING
=
0
,
VF_FADE_FADING
,
VF_FADE_DONE
}
fade_state
;
uint8_t
color_rgba
[
4
];
///< fade color
uint8_t
color_rgba
[
4
];
///< fade color
int
black_fade
;
///< if color_rgba is black
int
black_fade
;
///< if color_rgba is black
int
(
*
filter_slice_luma
)(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
);
int
(
*
filter_slice_chroma
)(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
);
int
(
*
filter_slice_alpha
)(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
);
}
FadeContext
;
}
FadeContext
;
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
...
@@ -110,6 +113,15 @@ static int query_formats(AVFilterContext *ctx)
...
@@ -110,6 +113,15 @@ static int query_formats(AVFilterContext *ctx)
AV_PIX_FMT_ARGB
,
AV_PIX_FMT_ABGR
,
AV_PIX_FMT_ARGB
,
AV_PIX_FMT_ABGR
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_BGRA
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_BGRA
,
AV_PIX_FMT_GBRP
,
AV_PIX_FMT_GBRAP
,
AV_PIX_FMT_GBRP
,
AV_PIX_FMT_GBRAP
,
AV_PIX_FMT_YUV420P9
,
AV_PIX_FMT_YUV422P9
,
AV_PIX_FMT_YUV444P9
,
AV_PIX_FMT_YUV420P10
,
AV_PIX_FMT_YUV422P10
,
AV_PIX_FMT_YUV444P10
,
AV_PIX_FMT_YUV420P12
,
AV_PIX_FMT_YUV422P12
,
AV_PIX_FMT_YUV444P12
,
AV_PIX_FMT_YUV440P12
,
AV_PIX_FMT_YUV420P14
,
AV_PIX_FMT_YUV422P14
,
AV_PIX_FMT_YUV444P14
,
AV_PIX_FMT_YUV420P16
,
AV_PIX_FMT_YUV422P16
,
AV_PIX_FMT_YUV444P16
,
AV_PIX_FMT_YUVA420P9
,
AV_PIX_FMT_YUVA422P9
,
AV_PIX_FMT_YUVA444P9
,
AV_PIX_FMT_YUVA420P10
,
AV_PIX_FMT_YUVA422P10
,
AV_PIX_FMT_YUVA444P10
,
AV_PIX_FMT_YUVA422P12
,
AV_PIX_FMT_YUVA444P12
,
AV_PIX_FMT_YUVA420P16
,
AV_PIX_FMT_YUVA422P16
,
AV_PIX_FMT_YUVA444P16
,
AV_PIX_FMT_NONE
AV_PIX_FMT_NONE
};
};
static
const
enum
AVPixelFormat
pix_fmts_rgb
[]
=
{
static
const
enum
AVPixelFormat
pix_fmts_rgb
[]
=
{
...
@@ -121,6 +133,10 @@ static int query_formats(AVFilterContext *ctx)
...
@@ -121,6 +133,10 @@ static int query_formats(AVFilterContext *ctx)
};
};
static
const
enum
AVPixelFormat
pix_fmts_alpha
[]
=
{
static
const
enum
AVPixelFormat
pix_fmts_alpha
[]
=
{
AV_PIX_FMT_YUVA420P
,
AV_PIX_FMT_YUVA422P
,
AV_PIX_FMT_YUVA444P
,
AV_PIX_FMT_YUVA420P
,
AV_PIX_FMT_YUVA422P
,
AV_PIX_FMT_YUVA444P
,
AV_PIX_FMT_YUVA420P9
,
AV_PIX_FMT_YUVA422P9
,
AV_PIX_FMT_YUVA444P9
,
AV_PIX_FMT_YUVA420P10
,
AV_PIX_FMT_YUVA422P10
,
AV_PIX_FMT_YUVA444P10
,
AV_PIX_FMT_YUVA422P12
,
AV_PIX_FMT_YUVA444P12
,
AV_PIX_FMT_YUVA420P16
,
AV_PIX_FMT_YUVA422P16
,
AV_PIX_FMT_YUVA444P16
,
AV_PIX_FMT_ARGB
,
AV_PIX_FMT_ABGR
,
AV_PIX_FMT_ARGB
,
AV_PIX_FMT_ABGR
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_BGRA
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_BGRA
,
AV_PIX_FMT_GBRAP
,
AV_PIX_FMT_GBRAP
,
...
@@ -154,36 +170,18 @@ const static enum AVPixelFormat studio_level_pix_fmts[] = {
...
@@ -154,36 +170,18 @@ const static enum AVPixelFormat studio_level_pix_fmts[] = {
AV_PIX_FMT_YUV444P
,
AV_PIX_FMT_YUV422P
,
AV_PIX_FMT_YUV420P
,
AV_PIX_FMT_YUV444P
,
AV_PIX_FMT_YUV422P
,
AV_PIX_FMT_YUV420P
,
AV_PIX_FMT_YUV411P
,
AV_PIX_FMT_YUV410P
,
AV_PIX_FMT_YUV411P
,
AV_PIX_FMT_YUV410P
,
AV_PIX_FMT_YUV440P
,
AV_PIX_FMT_YUV440P
,
AV_PIX_FMT_YUV420P9
,
AV_PIX_FMT_YUV422P9
,
AV_PIX_FMT_YUV444P9
,
AV_PIX_FMT_YUV420P10
,
AV_PIX_FMT_YUV422P10
,
AV_PIX_FMT_YUV444P10
,
AV_PIX_FMT_YUV420P12
,
AV_PIX_FMT_YUV422P12
,
AV_PIX_FMT_YUV444P12
,
AV_PIX_FMT_YUV440P12
,
AV_PIX_FMT_YUV420P14
,
AV_PIX_FMT_YUV422P14
,
AV_PIX_FMT_YUV444P14
,
AV_PIX_FMT_YUV420P16
,
AV_PIX_FMT_YUV422P16
,
AV_PIX_FMT_YUV444P16
,
AV_PIX_FMT_YUVA420P9
,
AV_PIX_FMT_YUVA422P9
,
AV_PIX_FMT_YUVA444P9
,
AV_PIX_FMT_YUVA420P10
,
AV_PIX_FMT_YUVA422P10
,
AV_PIX_FMT_YUVA444P10
,
AV_PIX_FMT_YUVA422P12
,
AV_PIX_FMT_YUVA444P12
,
AV_PIX_FMT_YUVA420P16
,
AV_PIX_FMT_YUVA422P16
,
AV_PIX_FMT_YUVA444P16
,
AV_PIX_FMT_NONE
AV_PIX_FMT_NONE
};
};
static
int
config_props
(
AVFilterLink
*
inlink
)
{
FadeContext
*
s
=
inlink
->
dst
->
priv
;
const
AVPixFmtDescriptor
*
pixdesc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
s
->
hsub
=
pixdesc
->
log2_chroma_w
;
s
->
vsub
=
pixdesc
->
log2_chroma_h
;
ff_fill_rgba_map
(
s
->
rgba_map
,
inlink
->
format
);
s
->
bpp
=
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_PLANAR
?
1
:
av_get_bits_per_pixel
(
pixdesc
)
>>
3
;
s
->
alpha
&=
!!
(
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_ALPHA
);
s
->
is_planar
=
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_PLANAR
;
s
->
is_rgb
=
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_RGB
;
s
->
is_packed_rgb
=
!
s
->
is_planar
&&
s
->
is_rgb
;
/* use CCIR601/709 black level for studio-level pixel non-alpha components */
s
->
black_level
=
ff_fmt_is_in
(
inlink
->
format
,
studio_level_pix_fmts
)
&&
!
s
->
alpha
?
16
:
0
;
/* 32768 = 1 << 15, it is an integer representation
* of 0.5 and is for rounding. */
s
->
black_level_scaled
=
(
s
->
black_level
<<
16
)
+
32768
;
return
0
;
}
static
av_always_inline
void
filter_rgb
(
FadeContext
*
s
,
const
AVFrame
*
frame
,
static
av_always_inline
void
filter_rgb
(
FadeContext
*
s
,
const
AVFrame
*
frame
,
int
slice_start
,
int
slice_end
,
int
slice_start
,
int
slice_end
,
int
do_alpha
,
int
step
)
int
do_alpha
,
int
step
)
...
@@ -277,6 +275,31 @@ static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr,
...
@@ -277,6 +275,31 @@ static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr,
return
0
;
return
0
;
}
}
static
int
filter_slice_luma16
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
FadeContext
*
s
=
ctx
->
priv
;
AVFrame
*
frame
=
arg
;
int
slice_start
=
(
frame
->
height
*
jobnr
)
/
nb_jobs
;
int
slice_end
=
(
frame
->
height
*
(
jobnr
+
1
))
/
nb_jobs
;
int
i
,
j
;
for
(
int
k
=
0
;
k
<
1
+
2
*
(
s
->
is_planar
&&
s
->
is_rgb
);
k
++
)
{
for
(
i
=
slice_start
;
i
<
slice_end
;
i
++
)
{
uint16_t
*
p
=
(
uint16_t
*
)(
frame
->
data
[
k
]
+
i
*
frame
->
linesize
[
k
]);
for
(
j
=
0
;
j
<
frame
->
width
*
s
->
bpp
;
j
++
)
{
/* s->factor is using 16 lower-order bits for decimal
* places. 32768 = 1 << 15, it is an integer representation
* of 0.5 and is for rounding. */
*
p
=
((
*
p
-
s
->
black_level
)
*
s
->
factor
+
s
->
black_level_scaled
)
>>
16
;
p
++
;
}
}
}
return
0
;
}
static
int
filter_slice_chroma
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
static
int
filter_slice_chroma
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
int
nb_jobs
)
{
{
...
@@ -304,6 +327,32 @@ static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr,
...
@@ -304,6 +327,32 @@ static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr,
return
0
;
return
0
;
}
}
static
int
filter_slice_chroma16
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
FadeContext
*
s
=
ctx
->
priv
;
AVFrame
*
frame
=
arg
;
int
i
,
j
,
plane
;
const
int
width
=
AV_CEIL_RSHIFT
(
frame
->
width
,
s
->
hsub
);
const
int
height
=
AV_CEIL_RSHIFT
(
frame
->
height
,
s
->
vsub
);
const
int
mid
=
1
<<
(
s
->
depth
-
1
);
const
int
add
=
((
mid
<<
1
)
+
1
)
<<
15
;
int
slice_start
=
(
height
*
jobnr
)
/
nb_jobs
;
int
slice_end
=
FFMIN
(((
height
*
(
jobnr
+
1
))
/
nb_jobs
),
frame
->
height
);
for
(
plane
=
1
;
plane
<
3
;
plane
++
)
{
for
(
i
=
slice_start
;
i
<
slice_end
;
i
++
)
{
uint16_t
*
p
=
(
uint16_t
*
)(
frame
->
data
[
plane
]
+
i
*
frame
->
linesize
[
plane
]);
for
(
j
=
0
;
j
<
width
;
j
++
)
{
*
p
=
((
*
p
-
mid
)
*
s
->
factor
+
add
)
>>
16
;
p
++
;
}
}
}
return
0
;
}
static
int
filter_slice_alpha
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
static
int
filter_slice_alpha
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
int
nb_jobs
)
{
{
...
@@ -329,6 +378,64 @@ static int filter_slice_alpha(AVFilterContext *ctx, void *arg, int jobnr,
...
@@ -329,6 +378,64 @@ static int filter_slice_alpha(AVFilterContext *ctx, void *arg, int jobnr,
return
0
;
return
0
;
}
}
static
int
filter_slice_alpha16
(
AVFilterContext
*
ctx
,
void
*
arg
,
int
jobnr
,
int
nb_jobs
)
{
FadeContext
*
s
=
ctx
->
priv
;
AVFrame
*
frame
=
arg
;
int
plane
=
s
->
is_packed_rgb
?
0
:
A
;
int
slice_start
=
(
frame
->
height
*
jobnr
)
/
nb_jobs
;
int
slice_end
=
(
frame
->
height
*
(
jobnr
+
1
))
/
nb_jobs
;
int
i
,
j
;
for
(
i
=
slice_start
;
i
<
slice_end
;
i
++
)
{
uint16_t
*
p
=
(
uint16_t
*
)(
frame
->
data
[
plane
]
+
i
*
frame
->
linesize
[
plane
])
+
s
->
is_packed_rgb
*
s
->
rgba_map
[
A
];
int
step
=
s
->
is_packed_rgb
?
4
:
1
;
for
(
j
=
0
;
j
<
frame
->
width
;
j
++
)
{
/* s->factor is using 16 lower-order bits for decimal
* places. 32768 = 1 << 15, it is an integer representation
* of 0.5 and is for rounding. */
*
p
=
((
*
p
-
s
->
black_level
)
*
s
->
factor
+
s
->
black_level_scaled
)
>>
16
;
p
+=
step
;
}
}
return
0
;
}
static
int
config_props
(
AVFilterLink
*
inlink
)
{
FadeContext
*
s
=
inlink
->
dst
->
priv
;
const
AVPixFmtDescriptor
*
pixdesc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
s
->
hsub
=
pixdesc
->
log2_chroma_w
;
s
->
vsub
=
pixdesc
->
log2_chroma_h
;
ff_fill_rgba_map
(
s
->
rgba_map
,
inlink
->
format
);
s
->
depth
=
pixdesc
->
comp
[
0
].
depth
;
s
->
bpp
=
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_PLANAR
?
1
:
av_get_bits_per_pixel
(
pixdesc
)
>>
3
;
s
->
alpha
&=
!!
(
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_ALPHA
);
s
->
is_planar
=
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_PLANAR
;
s
->
is_rgb
=
pixdesc
->
flags
&
AV_PIX_FMT_FLAG_RGB
;
s
->
is_packed_rgb
=
!
s
->
is_planar
&&
s
->
is_rgb
;
/* use CCIR601/709 black level for studio-level pixel non-alpha components */
s
->
black_level
=
ff_fmt_is_in
(
inlink
->
format
,
studio_level_pix_fmts
)
&&
!
s
->
alpha
?
16
*
(
1
<<
(
s
->
depth
-
8
))
:
0
;
/* 32768 = 1 << 15, it is an integer representation
* of 0.5 and is for rounding. */
s
->
black_level_scaled
=
(
s
->
black_level
<<
16
)
+
32768
;
s
->
filter_slice_luma
=
s
->
depth
<=
8
?
filter_slice_luma
:
filter_slice_luma16
;
s
->
filter_slice_chroma
=
s
->
depth
<=
8
?
filter_slice_chroma
:
filter_slice_chroma16
;
s
->
filter_slice_alpha
=
s
->
depth
<=
8
?
filter_slice_alpha
:
filter_slice_alpha16
;
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
frame
)
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
frame
)
{
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
AVFilterContext
*
ctx
=
inlink
->
dst
;
...
@@ -385,19 +492,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
...
@@ -385,19 +492,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
if
(
s
->
factor
<
UINT16_MAX
)
{
if
(
s
->
factor
<
UINT16_MAX
)
{
if
(
s
->
alpha
)
{
if
(
s
->
alpha
)
{
ctx
->
internal
->
execute
(
ctx
,
filter_slice_alpha
,
frame
,
NULL
,
ctx
->
internal
->
execute
(
ctx
,
s
->
filter_slice_alpha
,
frame
,
NULL
,
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
}
else
if
(
s
->
is_rgb
&&
!
s
->
black_fade
)
{
}
else
if
(
s
->
is_rgb
&&
!
s
->
black_fade
)
{
ctx
->
internal
->
execute
(
ctx
,
filter_slice_rgb
,
frame
,
NULL
,
ctx
->
internal
->
execute
(
ctx
,
filter_slice_rgb
,
frame
,
NULL
,
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
}
else
{
}
else
{
/* luma, or rgb plane in case of black */
/* luma, or rgb plane in case of black */
ctx
->
internal
->
execute
(
ctx
,
filter_slice_luma
,
frame
,
NULL
,
ctx
->
internal
->
execute
(
ctx
,
s
->
filter_slice_luma
,
frame
,
NULL
,
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
if
(
frame
->
data
[
1
]
&&
frame
->
data
[
2
]
&&
!
s
->
is_rgb
)
{
if
(
frame
->
data
[
1
]
&&
frame
->
data
[
2
]
&&
!
s
->
is_rgb
)
{
/* chroma planes */
/* chroma planes */
ctx
->
internal
->
execute
(
ctx
,
filter_slice_chroma
,
frame
,
NULL
,
ctx
->
internal
->
execute
(
ctx
,
s
->
filter_slice_chroma
,
frame
,
NULL
,
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
FFMIN
(
frame
->
height
,
ff_filter_get_nb_threads
(
ctx
)));
}
}
}
}
...
...
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