FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavfilter
libmpcodecs
vf_tinterlace.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2003 Michael Zucchi <notzed@ximian.com>
3
*
4
* This file is part of MPlayer.
5
*
6
* MPlayer 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
* MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
*/
20
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#include "config.h"
26
#include "
mp_msg.h
"
27
28
#include "
img_format.h
"
29
#include "
mp_image.h
"
30
#include "
vf.h
"
31
32
#include "
libvo/fastmemcpy.h
"
33
34
struct
vf_priv_s
{
35
int
mode
;
36
int
frame
;
37
mp_image_t
*
dmpi
;
38
};
39
40
static
int
put_image
(
struct
vf_instance *vf,
mp_image_t
*mpi,
double
pts)
41
{
42
int
ret = 0;
43
mp_image_t
*dmpi;
44
45
switch
(vf->priv->mode) {
46
case
0:
47
dmpi = vf->
priv
->dmpi;
48
if
(dmpi ==
NULL
) {
49
dmpi =
ff_vf_get_image
(vf->next, mpi->
imgfmt
,
50
MP_IMGTYPE_STATIC
,
MP_IMGFLAG_ACCEPT_STRIDE
|
51
MP_IMGFLAG_PRESERVE
,
52
mpi->
width
, mpi->
height
*2);
53
54
vf->priv->dmpi = dmpi;
55
56
memcpy_pic
(dmpi->
planes
[0], mpi->
planes
[0], mpi->
w
, mpi->
h
,
57
dmpi->
stride
[0]*2, mpi->
stride
[0]);
58
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
59
memcpy_pic
(dmpi->
planes
[1], mpi->
planes
[1],
60
mpi->
chroma_width
, mpi->
chroma_height
,
61
dmpi->
stride
[1]*2, mpi->
stride
[1]);
62
memcpy_pic
(dmpi->
planes
[2], mpi->
planes
[2],
63
mpi->
chroma_width
, mpi->
chroma_height
,
64
dmpi->
stride
[2]*2, mpi->
stride
[2]);
65
}
66
}
else
{
67
vf->priv->dmpi =
NULL
;
68
69
memcpy_pic
(dmpi->
planes
[0]+dmpi->
stride
[0], mpi->
planes
[0], mpi->
w
, mpi->
h
,
70
dmpi->
stride
[0]*2, mpi->
stride
[0]);
71
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
72
memcpy_pic
(dmpi->
planes
[1]+dmpi->
stride
[1], mpi->
planes
[1],
73
mpi->
chroma_width
, mpi->
chroma_height
,
74
dmpi->
stride
[1]*2, mpi->
stride
[1]);
75
memcpy_pic
(dmpi->
planes
[2]+dmpi->
stride
[2], mpi->
planes
[2],
76
mpi->
chroma_width
, mpi->
chroma_height
,
77
dmpi->
stride
[2]*2, mpi->
stride
[2]);
78
}
79
ret =
ff_vf_next_put_image
(vf, dmpi,
MP_NOPTS_VALUE
);
80
}
81
break
;
82
case
1:
83
if
(vf->priv->frame & 1)
84
ret =
ff_vf_next_put_image
(vf, mpi,
MP_NOPTS_VALUE
);
85
break
;
86
case
2:
87
if
((vf->priv->frame & 1) == 0)
88
ret =
ff_vf_next_put_image
(vf, mpi,
MP_NOPTS_VALUE
);
89
break
;
90
case
3:
91
dmpi =
ff_vf_get_image
(vf->next, mpi->
imgfmt
,
92
MP_IMGTYPE_TEMP
,
MP_IMGFLAG_ACCEPT_STRIDE
,
93
mpi->
width
, mpi->
height
*2);
94
/* fixme, just clear alternate lines */
95
ff_vf_mpi_clear
(dmpi, 0, 0, dmpi->
w
, dmpi->
h
);
96
if
((vf->priv->frame & 1) == 0) {
97
memcpy_pic
(dmpi->
planes
[0], mpi->
planes
[0], mpi->
w
, mpi->
h
,
98
dmpi->
stride
[0]*2, mpi->
stride
[0]);
99
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
100
memcpy_pic
(dmpi->
planes
[1], mpi->
planes
[1],
101
mpi->
chroma_width
, mpi->
chroma_height
,
102
dmpi->
stride
[1]*2, mpi->
stride
[1]);
103
memcpy_pic
(dmpi->
planes
[2], mpi->
planes
[2],
104
mpi->
chroma_width
, mpi->
chroma_height
,
105
dmpi->
stride
[2]*2, mpi->
stride
[2]);
106
}
107
}
else
{
108
memcpy_pic
(dmpi->
planes
[0]+dmpi->
stride
[0], mpi->
planes
[0], mpi->
w
, mpi->
h
,
109
dmpi->
stride
[0]*2, mpi->
stride
[0]);
110
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
111
memcpy_pic
(dmpi->
planes
[1]+dmpi->
stride
[1], mpi->
planes
[1],
112
mpi->
chroma_width
, mpi->
chroma_height
,
113
dmpi->
stride
[1]*2, mpi->
stride
[1]);
114
memcpy_pic
(dmpi->
planes
[2]+dmpi->
stride
[2], mpi->
planes
[2],
115
mpi->
chroma_width
, mpi->
chroma_height
,
116
dmpi->
stride
[2]*2, mpi->
stride
[2]);
117
}
118
}
119
ret =
ff_vf_next_put_image
(vf, dmpi,
MP_NOPTS_VALUE
);
120
break
;
121
case
4:
122
// Interleave even lines (only) from Frame 'i' with odd
123
// lines (only) from Frame 'i+1', halving the Frame
124
// rate and preserving image height.
125
126
dmpi = vf->
priv
->dmpi;
127
128
// @@ Need help: Should I set dmpi->fields to indicate
129
// that the (new) frame will be interlaced!? E.g. ...
130
// dmpi->fields |= MP_IMGFIELD_INTERLACED;
131
// dmpi->fields |= MP_IMGFIELD_TOP_FIRST;
132
// etc.
133
134
if
(dmpi ==
NULL
) {
135
dmpi =
ff_vf_get_image
(vf->next, mpi->
imgfmt
,
136
MP_IMGTYPE_STATIC
,
MP_IMGFLAG_ACCEPT_STRIDE
|
137
MP_IMGFLAG_PRESERVE
,
138
mpi->
width
, mpi->
height
);
139
140
vf->priv->dmpi = dmpi;
141
142
my_memcpy_pic
(dmpi->
planes
[0], mpi->
planes
[0], mpi->
w
, mpi->
h
/2,
143
dmpi->
stride
[0]*2, mpi->
stride
[0]*2);
144
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
145
my_memcpy_pic
(dmpi->
planes
[1], mpi->
planes
[1],
146
mpi->
chroma_width
, mpi->
chroma_height
/2,
147
dmpi->
stride
[1]*2, mpi->
stride
[1]*2);
148
my_memcpy_pic
(dmpi->
planes
[2], mpi->
planes
[2],
149
mpi->
chroma_width
, mpi->
chroma_height
/2,
150
dmpi->
stride
[2]*2, mpi->
stride
[2]*2);
151
}
152
}
else
{
153
vf->priv->dmpi =
NULL
;
154
155
my_memcpy_pic
(dmpi->
planes
[0]+dmpi->
stride
[0],
156
mpi->
planes
[0]+mpi->
stride
[0],
157
mpi->
w
, mpi->
h
/2,
158
dmpi->
stride
[0]*2, mpi->
stride
[0]*2);
159
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
160
my_memcpy_pic
(dmpi->
planes
[1]+dmpi->
stride
[1],
161
mpi->
planes
[1]+mpi->
stride
[1],
162
mpi->
chroma_width
, mpi->
chroma_height
/2,
163
dmpi->
stride
[1]*2, mpi->
stride
[1]*2);
164
my_memcpy_pic
(dmpi->
planes
[2]+dmpi->
stride
[2],
165
mpi->
planes
[2]+mpi->
stride
[2],
166
mpi->
chroma_width
, mpi->
chroma_height
/2,
167
dmpi->
stride
[2]*2, mpi->
stride
[2]*2);
168
}
169
ret =
ff_vf_next_put_image
(vf, dmpi,
MP_NOPTS_VALUE
);
170
}
171
break
;
172
}
173
174
vf->priv->frame++;
175
176
return
ret;
177
}
178
179
static
int
query_format
(
struct
vf_instance *vf,
unsigned
int
fmt
)
180
{
181
/* FIXME - figure out which other formats work */
182
switch
(fmt) {
183
case
IMGFMT_YV12
:
184
case
IMGFMT_IYUV
:
185
case
IMGFMT_I420
:
186
return
ff_vf_next_query_format
(vf, fmt);
187
}
188
return
0;
189
}
190
191
static
int
config
(
struct
vf_instance *vf,
192
int
width
,
int
height
,
int
d_width,
int
d_height,
193
unsigned
int
flags
,
unsigned
int
outfmt)
194
{
195
switch
(vf->priv->mode) {
196
case
0:
197
case
3:
198
return
ff_vf_next_config
(vf,width,height*2,d_width,d_height*2,flags,outfmt);
199
case
1:
/* odd frames */
200
case
2:
/* even frames */
201
case
4:
/* alternate frame (height-preserving) interlacing */
202
return
ff_vf_next_config
(vf,width,height,d_width,d_height,flags,outfmt);
203
}
204
return
0;
205
}
206
207
static
void
uninit
(
struct
vf_instance *vf)
208
{
209
free(vf->priv);
210
}
211
212
static
int
vf_open
(
vf_instance_t
*vf,
char
*args)
213
{
214
struct
vf_priv_s
*p;
215
vf->
config
=
config
;
216
vf->
put_image
=
put_image
;
217
vf->
query_format
=
query_format
;
218
vf->
uninit
=
uninit
;
219
vf->
default_reqs
=
VFCAP_ACCEPT_STRIDE
;
220
vf->
priv
= p = calloc(1,
sizeof
(
struct
vf_priv_s
));
221
p->
mode
= 0;
222
if
(args)
223
sscanf(args,
"%d"
, &p->
mode
);
224
p->
frame
= 0;
225
return
1;
226
}
227
228
const
vf_info_t
ff_vf_info_tinterlace
= {
229
"temporal field interlacing"
,
230
"tinterlace"
,
231
"Michael Zucchi"
,
232
""
,
233
vf_open
,
234
NULL
235
};
Generated on Sat May 25 2013 04:01:15 for FFmpeg by
1.8.2