FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavfilter
vf_repeatfields.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2003 Tobias Diedrich
3
*
4
* This file is part of FFmpeg.
5
*
6
* FFmpeg is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* FFmpeg is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License along
17
* with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
*/
20
21
#include "
libavutil/imgutils.h
"
22
#include "
avfilter.h
"
23
#include "
internal.h
"
24
25
typedef
struct
RepeatFieldsContext
{
26
const
AVClass
*
class
;
27
int
state
;
28
int
nb_planes
;
29
int
linesize
[4];
30
int
planeheight
[4];
31
AVFrame
*
frame
;
32
}
RepeatFieldsContext
;
33
34
static
av_cold
void
uninit
(
AVFilterContext
*ctx)
35
{
36
RepeatFieldsContext
*
s
= ctx->
priv
;
37
38
av_frame_free
(&s->
frame
);
39
}
40
41
static
int
query_formats
(
AVFilterContext
*ctx)
42
{
43
static
const
enum
AVPixelFormat
pixel_fmts_eq[] = {
44
AV_PIX_FMT_GRAY8
,
45
AV_PIX_FMT_YUV410P
,
46
AV_PIX_FMT_YUV411P
,
47
AV_PIX_FMT_YUV420P
,
48
AV_PIX_FMT_YUV422P
,
49
AV_PIX_FMT_YUV444P
,
50
AV_PIX_FMT_NONE
51
};
52
53
ff_set_common_formats
(ctx,
ff_make_format_list
(pixel_fmts_eq));
54
55
return
0;
56
}
57
58
static
int
config_input
(
AVFilterLink
*inlink)
59
{
60
RepeatFieldsContext
*
s
= inlink->
dst
->
priv
;
61
const
AVPixFmtDescriptor
*desc =
av_pix_fmt_desc_get
(inlink->
format
);
62
int
ret
;
63
64
if
((ret =
av_image_fill_linesizes
(s->
linesize
, inlink->
format
, inlink->
w
)) < 0)
65
return
ret
;
66
67
s->
planeheight
[1] = s->
planeheight
[2] =
FF_CEIL_RSHIFT
(inlink->
h
, desc->
log2_chroma_h
);
68
s->
planeheight
[0] = s->
planeheight
[3] = inlink->
h
;
69
70
s->
nb_planes
=
av_pix_fmt_count_planes
(inlink->
format
);
71
72
return
0;
73
}
74
75
static
void
update_pts
(
AVFilterLink
*link,
AVFrame
*f, int64_t
pts
,
int
fields)
76
{
77
if
(
av_cmp_q
(link->
frame_rate
, (
AVRational
){30000, 1001}) == 0 &&
78
av_cmp_q
(link->time_base, (
AVRational
){1001, 60000}) <= 0
79
) {
80
f->pts =
pts
+
av_rescale_q
(fields, (
AVRational
){1001, 60000}, link->time_base);
81
}
else
82
f->pts =
AV_NOPTS_VALUE
;
83
}
84
85
static
int
filter_frame
(
AVFilterLink
*inlink,
AVFrame
*
in
) {
86
AVFilterContext
*ctx = inlink->
dst
;
87
AVFilterLink
*outlink = inlink->
dst
->
outputs
[0];
88
RepeatFieldsContext
*
s
= ctx->
priv
;
89
AVFrame
*
out
;
90
int
ret
, i;
91
int
state
= s->
state
;
92
93
if
(!s->
frame
) {
94
s->
frame
=
av_frame_clone
(in);
95
if
(!s->
frame
)
96
return
AVERROR
(ENOMEM);
97
s->
frame
->
pts
=
AV_NOPTS_VALUE
;
98
}
99
100
out = s->
frame
;
101
102
if
((state == 0 && !in->
top_field_first
) ||
103
(state == 1 && in->
top_field_first
)) {
104
av_log
(ctx,
AV_LOG_WARNING
,
"Unexpected field flags: "
105
"state=%d top_field_first=%d repeat_first_field=%d\n"
,
106
state, in->
top_field_first
, in->
repeat_pict
);
107
state ^= 1;
108
}
109
110
if
(state == 0) {
111
AVFrame
*
new
;
112
113
new
=
av_frame_clone
(in);
114
if
(!
new
)
115
return
AVERROR
(ENOMEM);
116
117
ret =
ff_filter_frame
(outlink,
new
);
118
119
if
(in->
repeat_pict
) {
120
av_frame_make_writable
(out);
121
update_pts
(outlink, out, in->
pts
, 2);
122
for
(i = 0; i < s->
nb_planes
; i++) {
123
av_image_copy_plane
(out->
data
[i], out->
linesize
[i] * 2,
124
in->
data
[i], in->
linesize
[i] * 2,
125
s->
linesize
[i], s->
planeheight
[i] / 2);
126
}
127
state = 1;
128
}
129
}
else
{
130
for
(i = 0; i < s->
nb_planes
; i++) {
131
av_frame_make_writable
(out);
132
av_image_copy_plane
(out->
data
[i] + out->
linesize
[i], out->
linesize
[i] * 2,
133
in->
data
[i] + in->
linesize
[i], in->
linesize
[i] * 2,
134
s->
linesize
[i], s->
planeheight
[i] / 2);
135
}
136
137
ret =
ff_filter_frame
(outlink,
av_frame_clone
(out));
138
139
if
(in->
repeat_pict
) {
140
AVFrame
*
new
;
141
142
new
=
av_frame_clone
(in);
143
if
(!
new
)
144
return
AVERROR
(ENOMEM);
145
146
ret =
ff_filter_frame
(outlink,
new
);
147
state = 0;
148
}
else
{
149
av_frame_make_writable
(out);
150
update_pts
(outlink, out, in->
pts
, 1);
151
for
(i = 0; i < s->
nb_planes
; i++) {
152
av_image_copy_plane
(out->
data
[i], out->
linesize
[i] * 2,
153
in->
data
[i], in->
linesize
[i] * 2,
154
s->
linesize
[i], s->
planeheight
[i] / 2);
155
}
156
}
157
}
158
159
s->
state
=
state
;
160
161
av_frame_free
(&in);
162
return
ret
;
163
}
164
165
static
const
AVFilterPad
repeatfields_inputs
[] = {
166
{
167
.
name
=
"default"
,
168
.type =
AVMEDIA_TYPE_VIDEO
,
169
.filter_frame =
filter_frame
,
170
.config_props =
config_input
,
171
},
172
{
NULL
}
173
};
174
175
static
const
AVFilterPad
repeatfields_outputs
[] = {
176
{
177
.
name
=
"default"
,
178
.type =
AVMEDIA_TYPE_VIDEO
,
179
},
180
{
NULL
}
181
};
182
183
AVFilter
ff_vf_repeatfields
= {
184
.
name
=
"repeatfields"
,
185
.description =
NULL_IF_CONFIG_SMALL
(
"Hard repeat fields based on MPEG repeat field flag."
),
186
.priv_size =
sizeof
(
RepeatFieldsContext
),
187
.
uninit
=
uninit
,
188
.
inputs
= repeatfields_inputs,
189
.
outputs
= repeatfields_outputs,
190
.
query_formats
=
query_formats
,
191
};
Generated on Sun Mar 8 2015 02:35:07 for FFmpeg by
1.8.2