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_separatefields.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2013 Paul B Mahol
3
*
4
* This file is part of FFmpeg.
5
*
6
* FFmpeg is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (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 GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with FFmpeg; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
#include "
libavutil/pixdesc.h
"
22
#include "
avfilter.h
"
23
#include "
internal.h
"
24
25
typedef
struct
{
26
int
nb_planes
;
27
AVFrame
*
second
;
28
}
SeparateFieldsContext
;
29
30
static
int
config_props_output
(
AVFilterLink
*outlink)
31
{
32
AVFilterContext
*ctx = outlink->
src
;
33
SeparateFieldsContext
*sf = ctx->
priv
;
34
AVFilterLink
*inlink = ctx->
inputs
[0];
35
36
sf->
nb_planes
=
av_pix_fmt_count_planes
(inlink->
format
);
37
38
if
(inlink->
h
& 1) {
39
av_log
(ctx,
AV_LOG_ERROR
,
"height must be even\n"
);
40
return
AVERROR_INVALIDDATA
;
41
}
42
43
outlink->
time_base
.
num
= inlink->
time_base
.
num
;
44
outlink->
time_base
.
den
= inlink->
time_base
.
den
* 2;
45
outlink->
frame_rate
.
num
= inlink->
frame_rate
.
num
* 2;
46
outlink->
frame_rate
.
den
= inlink->
frame_rate
.
den
;
47
outlink->
w
= inlink->
w
;
48
outlink->
h
= inlink->
h
/ 2;
49
50
return
0;
51
}
52
53
static
void
extract_field
(
AVFrame
*
frame
,
int
nb_planes,
int
type)
54
{
55
int
i;
56
57
for
(i = 0; i < nb_planes; i++) {
58
if
(type)
59
frame->
data
[i] = frame->
data
[i] + frame->
linesize
[i];
60
frame->
linesize
[i] *= 2;
61
}
62
}
63
64
static
int
filter_frame
(
AVFilterLink
*inlink,
AVFrame
*inpicref)
65
{
66
AVFilterContext
*ctx = inlink->
dst
;
67
SeparateFieldsContext
*sf = ctx->
priv
;
68
AVFilterLink
*outlink = ctx->
outputs
[0];
69
int
ret
;
70
71
inpicref->
height
= outlink->
h
;
72
inpicref->
interlaced_frame
= 0;
73
74
if
(!sf->
second
) {
75
goto
clone;
76
}
else
{
77
AVFrame
*second = sf->
second
;
78
79
extract_field
(second, sf->
nb_planes
, second->
top_field_first
);
80
81
if
(second->
pts
!=
AV_NOPTS_VALUE
&&
82
inpicref->
pts
!=
AV_NOPTS_VALUE
)
83
second->
pts
+= inpicref->
pts
;
84
else
85
second->
pts
=
AV_NOPTS_VALUE
;
86
87
ret =
ff_filter_frame
(outlink, second);
88
if
(ret < 0)
89
return
ret
;
90
clone:
91
sf->
second
=
av_frame_clone
(inpicref);
92
if
(!sf->
second
)
93
return
AVERROR
(ENOMEM);
94
}
95
96
extract_field
(inpicref, sf->
nb_planes
, !inpicref->
top_field_first
);
97
98
if
(inpicref->
pts
!=
AV_NOPTS_VALUE
)
99
inpicref->
pts
*= 2;
100
101
return
ff_filter_frame
(outlink, inpicref);
102
}
103
104
static
int
request_frame
(
AVFilterLink
*outlink)
105
{
106
AVFilterContext
*ctx = outlink->
src
;
107
SeparateFieldsContext
*sf = ctx->
priv
;
108
int
ret
;
109
110
ret =
ff_request_frame
(ctx->
inputs
[0]);
111
if
(ret ==
AVERROR_EOF
&& sf->
second
) {
112
sf->
second
->
pts
*= 2;
113
extract_field
(sf->
second
, sf->
nb_planes
, sf->
second
->
top_field_first
);
114
ret =
ff_filter_frame
(outlink, sf->
second
);
115
sf->
second
= 0;
116
}
117
118
return
ret
;
119
}
120
121
static
const
AVFilterPad
separatefields_inputs
[] = {
122
{
123
.
name
=
"default"
,
124
.type =
AVMEDIA_TYPE_VIDEO
,
125
.filter_frame =
filter_frame
,
126
},
127
{ NULL }
128
};
129
130
static
const
AVFilterPad
separatefields_outputs
[] = {
131
{
132
.
name
=
"default"
,
133
.type =
AVMEDIA_TYPE_VIDEO
,
134
.config_props =
config_props_output
,
135
.request_frame =
request_frame
,
136
},
137
{ NULL }
138
};
139
140
AVFilter
avfilter_vf_separatefields
= {
141
.
name
=
"separatefields"
,
142
.description =
NULL_IF_CONFIG_SMALL
(
"Split input video frames into fields."
),
143
.priv_size =
sizeof
(
SeparateFieldsContext
),
144
.
inputs
= separatefields_inputs,
145
.
outputs
= separatefields_outputs,
146
};
Generated on Sat Jan 25 2014 19:52:01 for FFmpeg by
1.8.2