1 /*
2 * Copyright (c) 2004 Ville Saari
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 General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 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
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
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
24
25 #undef pixel
26 #undef accumulator
27 #if DEPTH == 8
28 #define pixel uint8_t
29 #define accumulator int
30 #else
31 #define pixel uint16_t
32 #define accumulator int64_t
33 #endif
34
35 #define fn3(a,b) a##_##b
36 #define fn2(a,b) fn3(a,b)
37 #define fn(a) fn2(a, DEPTH)
38
39 /*
40 * This macro interpolates the value of both fields at a point halfway
41 * between lines and takes the squared difference. In field resolution
42 * the point is a quarter pixel below a line in one field and a quarter
43 * pixel above a line in other.
44 *
45 * (The result is actually multiplied by 25)
46 */
47 #define DIFF(a, as, b, bs) ((t) = ((*(a) - (b)[bs]) * 4) + (a)[(as) * 2] - (b)[-(bs)], (t) * (t))
48
49 /*
50 * Find which field combination has the smallest average squared difference
51 * between the fields.
52 */
54 {
55 double bdiff, tdiff, pdiff;
56
63 }
64
66 bdiff = pdiff = tdiff = 65536.0;
67 } else {
69 const int ns =
new->linesize[0] /
sizeof(
pixel);
70 const int os = old->linesize[0] /
sizeof(
pixel);
73 const int h =
new->height;
74 const int w =
new->width;
77
78 int top = 0, t;
79 const pixel *rend, *end = nptr + (
h - 2) *
ns;
80
81 bdiff = pdiff = tdiff = 0.0;
82
84 optr += os;
85 while (nptr < end) {
86 pdif = tdif = bdif = 0;
87
90 if (top) {
91 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
93 tdif +=
DIFF(nptr,
ns, optr, os);
94 }
95 } else {
96 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
98 tdif +=
DIFF(optr, os, nptr,
ns);
99 }
100 }
101 break;
103 if (top) {
104 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
106 bdif +=
DIFF(optr, os, nptr,
ns);
107 }
108 } else {
109 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
111 bdif +=
DIFF(nptr,
ns, optr, os);
112 }
113 }
114 break;
116 if (top) {
117 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
118 tdif +=
DIFF(nptr,
ns, optr, os);
119 bdif +=
DIFF(optr, os, nptr,
ns);
120 }
121 } else {
122 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
123 bdif +=
DIFF(nptr,
ns, optr, os);
124 tdif +=
DIFF(optr, os, nptr,
ns);
125 }
126 }
127 break;
129 if (top) {
130 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
132 tdif +=
DIFF(nptr,
ns, optr, os);
133 bdif +=
DIFF(optr, os, nptr,
ns);
134 }
135 } else {
136 for (rend = nptr +
w; nptr < rend; nptr++, optr++) {
138 bdif +=
DIFF(nptr,
ns, optr, os);
139 tdif +=
DIFF(optr, os, nptr,
ns);
140 }
141 }
142 break;
143 default:
145 }
146
152 top ^= 1;
153 }
154
159
161 bdiff = 65536.0;
163 tdiff = 65536.0;
165 pdiff = 65536.0;
166 }
167
168 if (bdiff < pdiff && bdiff < tdiff) {
170 } else if (tdiff < pdiff && tdiff < bdiff) {
172 } else {
174 }
175 }
176
179 tdiff, bdiff, pdiff);
181 }