FFmpeg
1.2.12
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavfilter
libmpcodecs
vf_phase.c
Go to the documentation of this file.
1
/*
2
* This file is part of MPlayer.
3
*
4
* MPlayer is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
8
*
9
* MPlayer is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License along
15
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
16
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
*/
18
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <string.h>
22
#include <limits.h>
23
24
#include "
config.h
"
25
#include "
mp_msg.h
"
26
27
#include "
img_format.h
"
28
#include "
mp_image.h
"
29
#include "
vf.h
"
30
31
#include "
libvo/fastmemcpy.h
"
32
33
enum
mode
{
PROGRESSIVE
,
TOP_FIRST
,
BOTTOM_FIRST
,
34
TOP_FIRST_ANALYZE
,
BOTTOM_FIRST_ANALYZE
,
35
ANALYZE
,
FULL_ANALYZE
,
AUTO
,
AUTO_ANALYZE
};
36
37
#define fixed_mode(p) ((p)<=BOTTOM_FIRST)
38
39
struct
vf_priv_s
40
{
41
enum
mode
mode
;
42
int
verbose
;
43
unsigned
char
*
buf
[3];
44
};
45
46
/*
47
* Copy fields from either current or buffered previous frame to the
48
* output and store the current frame unmodified to the buffer.
49
*/
50
51
static
void
do_plane
(
unsigned
char
*
to
,
unsigned
char
*
from
,
52
int
w,
int
h,
int
ts,
int
fs,
53
unsigned
char
**bufp,
enum
mode
mode
)
54
{
55
unsigned
char
*buf, *
end
;
56
int
top;
57
58
if
(!*bufp)
59
{
60
mode=
PROGRESSIVE
;
61
if
(!(*bufp=malloc(h*w)))
return
;
62
}
63
64
for
(end=to+h*ts, buf=*bufp, top=1; to<
end
; from+=fs, to+=ts, buf+=w, top^=1)
65
{
66
fast_memcpy
(to, mode==(top?
BOTTOM_FIRST
:
TOP_FIRST
)?buf:from, w);
67
fast_memcpy
(buf, from, w);
68
}
69
}
70
71
/*
72
* This macro interpolates the value of both fields at a point halfway
73
* between lines and takes the squared difference. In field resolution
74
* the point is a quarter pixel below a line in one field and a quarter
75
* pixel above a line in other.
76
*
77
* (the result is actually multiplied by 25)
78
*/
79
80
#define diff(a, as, b, bs) (t=((*a-b[bs])<<2)+a[as<<1]-b[-bs], t*t)
81
82
/*
83
* Find which field combination has the smallest average squared difference
84
* between the fields.
85
*/
86
87
static
enum
mode
analyze_plane
(
unsigned
char
*old,
unsigned
char
*
new
,
88
int
w,
int
h,
int
os,
int
ns,
enum
mode
mode
,
89
int
verbose,
int
fields)
90
{
91
double
bdiff, pdiff, tdiff,
scale
;
92
int
bdif, tdif, pdif;
93
int
top,
t
;
94
unsigned
char
*
end
, *rend;
95
96
if
(mode==
AUTO
)
97
mode=fields&
MP_IMGFIELD_ORDERED
?fields&
MP_IMGFIELD_TOP_FIRST
?
98
TOP_FIRST
:
BOTTOM_FIRST
:
PROGRESSIVE
;
99
else
if
(mode==
AUTO_ANALYZE
)
100
mode=fields&
MP_IMGFIELD_ORDERED
?fields&
MP_IMGFIELD_TOP_FIRST
?
101
TOP_FIRST_ANALYZE
:
BOTTOM_FIRST_ANALYZE
:
FULL_ANALYZE
;
102
103
if
(
fixed_mode
(mode))
104
bdiff=pdiff=tdiff=65536.0;
105
else
106
{
107
bdiff=pdiff=tdiff=0.0;
108
109
for
(end=
new
+(h-2)*ns,
new
+=ns, old+=os, top=0;
110
new
<
end
;
new
+=ns-w, old+=os-w, top^=1)
111
{
112
pdif=tdif=bdif=0;
113
114
switch
(mode)
115
{
116
case
TOP_FIRST_ANALYZE
:
117
if
(top)
118
for
(rend=
new
+w;
new
<rend;
new
++, old++)
119
pdif+=
diff
(
new
, ns,
new
, ns),
120
tdif+=
diff
(
new
, ns, old, os);
121
else
122
for
(rend=
new
+w;
new
<rend;
new
++, old++)
123
pdif+=
diff
(
new
, ns,
new
, ns),
124
tdif+=
diff
(old, os,
new
, ns);
125
break
;
126
127
case
BOTTOM_FIRST_ANALYZE
:
128
if
(top)
129
for
(rend=
new
+w;
new
<rend;
new
++, old++)
130
pdif+=
diff
(
new
, ns,
new
, ns),
131
bdif+=
diff
(old, os,
new
, ns);
132
else
133
for
(rend=
new
+w;
new
<rend;
new
++, old++)
134
pdif+=
diff
(
new
, ns,
new
, ns),
135
bdif+=
diff
(
new
, ns, old, os);
136
break
;
137
138
case
ANALYZE
:
139
if
(top)
140
for
(rend=
new
+w;
new
<rend;
new
++, old++)
141
tdif+=
diff
(
new
, ns, old, os),
142
bdif+=
diff
(old, os,
new
, ns);
143
else
144
for
(rend=
new
+w;
new
<rend;
new
++, old++)
145
bdif+=
diff
(
new
, ns, old, os),
146
tdif+=
diff
(old, os,
new
, ns);
147
break
;
148
149
default
:
/* FULL_ANALYZE */
150
if
(top)
151
for
(rend=
new
+w;
new
<rend;
new
++, old++)
152
pdif+=
diff
(
new
, ns,
new
, ns),
153
tdif+=
diff
(
new
, ns, old, os),
154
bdif+=
diff
(old, os,
new
, ns);
155
else
156
for
(rend=
new
+w;
new
<rend;
new
++, old++)
157
pdif+=
diff
(
new
, ns,
new
, ns),
158
bdif+=
diff
(
new
, ns, old, os),
159
tdif+=
diff
(old, os,
new
, ns);
160
}
161
162
pdiff+=(double)pdif;
163
tdiff+=(double)tdif;
164
bdiff+=(double)bdif;
165
}
166
167
scale=1.0/(w*(h-3))/25.0;
168
pdiff*=
scale
;
169
tdiff*=
scale
;
170
bdiff*=
scale
;
171
172
if
(mode==
TOP_FIRST_ANALYZE
)
173
bdiff=65536.0;
174
else
if
(mode==
BOTTOM_FIRST_ANALYZE
)
175
tdiff=65536.0;
176
else
if
(mode==
ANALYZE
)
177
pdiff=65536.0;
178
179
if
(bdiff<pdiff && bdiff<tdiff)
180
mode=
BOTTOM_FIRST
;
181
else
if
(tdiff<pdiff && tdiff<bdiff)
182
mode=
TOP_FIRST
;
183
else
184
mode=
PROGRESSIVE
;
185
}
186
187
if
(
ff_mp_msg_test
(
MSGT_VFILTER
,
MSGL_V
) )
188
{
189
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
"%c"
, mode==
BOTTOM_FIRST
?
'b'
:mode==
TOP_FIRST
?
't'
:
'p'
);
190
if
(tdiff==65536.0)
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
" N/A "
);
else
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
" %8.2f"
, tdiff);
191
if
(bdiff==65536.0)
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
" N/A "
);
else
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
" %8.2f"
, bdiff);
192
if
(pdiff==65536.0)
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
" N/A "
);
else
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
" %8.2f"
, pdiff);
193
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_INFO
,
" \n"
);
194
}
195
196
return
mode
;
197
}
198
199
static
int
put_image
(
struct
vf_instance
*vf,
mp_image_t
*mpi,
double
pts)
200
{
201
mp_image_t
*dmpi;
202
int
w;
203
enum
mode
mode
;
204
205
if
(!(dmpi=
ff_vf_get_image
(vf->
next
, mpi->
imgfmt
,
206
MP_IMGTYPE_TEMP
,
MP_IMGFLAG_ACCEPT_STRIDE
,
207
mpi->
w
, mpi->
h
)))
208
return
0;
209
210
w=dmpi->
w
;
211
if
(!(dmpi->
flags
&
MP_IMGFLAG_PLANAR
))
212
w*=dmpi->
bpp
/8;
213
214
mode=vf->
priv
->
mode
;
215
216
if
(!vf->
priv
->
buf
[0])
217
mode=
PROGRESSIVE
;
218
else
219
mode=
analyze_plane
(vf->
priv
->
buf
[0], mpi->
planes
[0],
220
w, dmpi->
h
, w, mpi->
stride
[0], mode,
221
vf->
priv
->
verbose
, mpi->
fields
);
222
223
do_plane
(dmpi->
planes
[0], mpi->
planes
[0],
224
w, dmpi->
h
,
225
dmpi->
stride
[0], mpi->
stride
[0],
226
&vf->
priv
->
buf
[0], mode);
227
228
if
(dmpi->
flags
&
MP_IMGFLAG_PLANAR
)
229
{
230
do_plane
(dmpi->
planes
[1], mpi->
planes
[1],
231
dmpi->
chroma_width
, dmpi->
chroma_height
,
232
dmpi->
stride
[1], mpi->
stride
[1],
233
&vf->
priv
->
buf
[1], mode);
234
do_plane
(dmpi->
planes
[2], mpi->
planes
[2],
235
dmpi->
chroma_width
, dmpi->
chroma_height
,
236
dmpi->
stride
[2], mpi->
stride
[2],
237
&vf->
priv
->
buf
[2], mode);
238
}
239
240
return
ff_vf_next_put_image
(vf, dmpi,
MP_NOPTS_VALUE
);
241
}
242
243
static
void
uninit
(
struct
vf_instance
*vf)
244
{
245
if
(!vf->
priv
)
246
return
;
247
free(vf->
priv
->
buf
[0]);
248
free(vf->
priv
->
buf
[1]);
249
free(vf->
priv
->
buf
[2]);
250
free(vf->
priv
);
251
}
252
253
static
int
vf_open
(
vf_instance_t
*vf,
char
*args)
254
{
255
vf->
put_image
=
put_image
;
256
vf->
uninit
=
uninit
;
257
vf->
default_reqs
=
VFCAP_ACCEPT_STRIDE
;
258
259
if
(!(vf->
priv
= calloc(1,
sizeof
(
struct
vf_priv_s
))))
260
{
261
uninit
(vf);
262
return
0;
263
}
264
265
vf->
priv
->
mode
=
AUTO_ANALYZE
;
266
vf->
priv
->
verbose
=0;
267
268
while
(args && *args)
269
{
270
switch
(*args)
271
{
272
case
't'
: vf->
priv
->
mode
=
TOP_FIRST
;
break
;
273
case
'a'
: vf->
priv
->
mode
=
AUTO
;
break
;
274
case
'b'
: vf->
priv
->
mode
=
BOTTOM_FIRST
;
break
;
275
case
'u'
: vf->
priv
->
mode
=
ANALYZE
;
break
;
276
case
'T'
: vf->
priv
->
mode
=
TOP_FIRST_ANALYZE
;
break
;
277
case
'A'
: vf->
priv
->
mode
=
AUTO_ANALYZE
;
break
;
278
case
'B'
: vf->
priv
->
mode
=
BOTTOM_FIRST_ANALYZE
;
break
;
279
case
'U'
: vf->
priv
->
mode
=
FULL_ANALYZE
;
break
;
280
case
'p'
: vf->
priv
->
mode
=
PROGRESSIVE
;
break
;
281
case
'v'
: vf->
priv
->
verbose
=1;
break
;
282
case
':'
:
break
;
283
284
default
:
285
uninit
(vf);
286
return
0;
/* bad args */
287
}
288
289
if
( (args=strchr(args,
':'
)) ) args++;
290
}
291
292
return
1;
293
}
294
295
const
vf_info_t
ff_vf_info_phase
=
296
{
297
"phase shift fields"
,
298
"phase"
,
299
"Ville Saari"
,
300
""
,
301
vf_open
,
302
NULL
303
};
Generated on Thu Feb 12 2015 17:57:00 for FFmpeg by
1.8.1.2