Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavfilter
vf_fade.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2010 Brandon Mintern
3
* Copyright (c) 2007 Bobby Bingham
4
*
5
* This file is part of Libav.
6
*
7
* Libav is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* Libav is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
28
#include "
libavutil/pixdesc.h
"
29
#include "
avfilter.h
"
30
31
typedef
struct
{
32
int
factor,
fade_per_frame
;
33
unsigned
int
frame_index,
start_frame
,
stop_frame
;
34
int
hsub,
vsub
, bpp;
35
}
FadeContext
;
36
37
static
av_cold
int
init
(
AVFilterContext
*ctx,
const
char
*args,
void
*opaque)
38
{
39
FadeContext
*fade = ctx->
priv
;
40
unsigned
int
nb_frames;
41
char
in_out[4];
42
43
if
(!args ||
44
sscanf(args,
" %3[^:]:%u:%u"
, in_out, &fade->
start_frame
, &nb_frames) != 3) {
45
av_log
(ctx,
AV_LOG_ERROR
,
46
"Expected 3 arguments '(in|out):#:#':'%s'\n"
, args);
47
return
AVERROR
(EINVAL);
48
}
49
50
nb_frames = nb_frames ? nb_frames : 1;
51
fade->
fade_per_frame
= (1 << 16) / nb_frames;
52
if
(!strcmp(in_out,
"in"
))
53
fade->
factor
= 0;
54
else
if (!strcmp(in_out,
"out"
)) {
55
fade->
fade_per_frame
= -fade->
fade_per_frame
;
56
fade->
factor
= (1 << 16);
57
}
else
{
58
av_log
(ctx,
AV_LOG_ERROR
,
59
"first argument must be 'in' or 'out':'%s'\n"
, in_out);
60
return
AVERROR
(EINVAL);
61
}
62
fade->
stop_frame
= fade->
start_frame
+ nb_frames;
63
64
av_log
(ctx,
AV_LOG_INFO
,
65
"type:%s start_frame:%d nb_frames:%d\n"
,
66
in_out, fade->
start_frame
, nb_frames);
67
return
0;
68
}
69
70
static
int
query_formats
(
AVFilterContext
*ctx)
71
{
72
static
const
enum
PixelFormat
pix_fmts[] = {
73
PIX_FMT_YUV444P
,
PIX_FMT_YUV422P
,
PIX_FMT_YUV420P
,
74
PIX_FMT_YUV411P
,
PIX_FMT_YUV410P
,
75
PIX_FMT_YUVJ444P
,
PIX_FMT_YUVJ422P
,
PIX_FMT_YUVJ420P
,
76
PIX_FMT_YUV440P
,
PIX_FMT_YUVJ440P
,
77
PIX_FMT_RGB24
,
PIX_FMT_BGR24
,
78
PIX_FMT_NONE
79
};
80
81
avfilter_set_common_formats
(ctx,
avfilter_make_format_list
(pix_fmts));
82
return
0;
83
}
84
85
static
int
config_props
(
AVFilterLink
*inlink)
86
{
87
FadeContext
*fade = inlink->
dst
->
priv
;
88
const
AVPixFmtDescriptor
*pixdesc = &
av_pix_fmt_descriptors
[inlink->
format
];
89
90
fade->
hsub
= pixdesc->
log2_chroma_w
;
91
fade->
vsub
= pixdesc->
log2_chroma_h
;
92
93
fade->
bpp
=
av_get_bits_per_pixel
(pixdesc) >> 3;
94
return
0;
95
}
96
97
static
void
draw_slice
(
AVFilterLink
*inlink,
int
y,
int
h,
int
slice_dir)
98
{
99
FadeContext
*fade = inlink->
dst
->
priv
;
100
AVFilterBufferRef
*outpic = inlink->
cur_buf
;
101
uint8_t *p;
102
int
i, j, plane;
103
104
if
(fade->
factor
< UINT16_MAX) {
105
/* luma or rgb plane */
106
for
(i = 0; i < h; i++) {
107
p = outpic->
data
[0] + (y+i) * outpic->
linesize
[0];
108
for
(j = 0; j < inlink->
w
* fade->
bpp
; j++) {
109
/* fade->factor is using 16 lower-order bits for decimal
110
* places. 32768 = 1 << 15, it is an integer representation
111
* of 0.5 and is for rounding. */
112
*p = (*p * fade->
factor
+ 32768) >> 16;
113
p++;
114
}
115
}
116
117
if
(outpic->
data
[1] && outpic->
data
[2]) {
118
/* chroma planes */
119
for
(plane = 1; plane < 3; plane++) {
120
for
(i = 0; i < h; i++) {
121
p = outpic->
data
[plane] + ((y+i) >> fade->
vsub
) * outpic->
linesize
[plane];
122
for
(j = 0; j < inlink->
w
>> fade->
hsub
; j++) {
123
/* 8421367 = ((128 << 1) + 1) << 15. It is an integer
124
* representation of 128.5. The .5 is for rounding
125
* purposes. */
126
*p = ((*p - 128) * fade->
factor
+ 8421367) >> 16;
127
p++;
128
}
129
}
130
}
131
}
132
}
133
134
avfilter_draw_slice
(inlink->
dst
->
outputs
[0], y, h, slice_dir);
135
}
136
137
static
void
end_frame
(
AVFilterLink
*inlink)
138
{
139
FadeContext
*fade = inlink->
dst
->
priv
;
140
141
avfilter_end_frame
(inlink->
dst
->
outputs
[0]);
142
143
if
(fade->
frame_index
>= fade->
start_frame
&&
144
fade->
frame_index
<= fade->
stop_frame
)
145
fade->
factor
+= fade->
fade_per_frame
;
146
fade->
factor
= av_clip_uint16(fade->
factor
);
147
fade->
frame_index
++;
148
}
149
150
AVFilter
avfilter_vf_fade
= {
151
.
name
=
"fade"
,
152
.description =
NULL_IF_CONFIG_SMALL
(
"Fade in/out input video"
),
153
.init =
init
,
154
.priv_size =
sizeof
(
FadeContext
),
155
.
query_formats
=
query_formats
,
156
157
.inputs = (
AVFilterPad
[]) {{ .name =
"default"
,
158
.type =
AVMEDIA_TYPE_VIDEO
,
159
.config_props =
config_props
,
160
.get_video_buffer =
avfilter_null_get_video_buffer
,
161
.start_frame =
avfilter_null_start_frame
,
162
.draw_slice =
draw_slice
,
163
.end_frame =
end_frame
,
164
.min_perms =
AV_PERM_READ
|
AV_PERM_WRITE
,
165
.rej_perms =
AV_PERM_PRESERVE
, },
166
{ .name =
NULL
}},
167
.outputs = (
AVFilterPad
[]) {{ .name =
"default"
,
168
.type =
AVMEDIA_TYPE_VIDEO
, },
169
{ .name =
NULL
}},
170
};