GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/phase_template.c Lines: 51 88 58.0 %
Date: 2020-09-25 23:16:12 Branches: 0 0 - %

Line Branch Exec Source
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
21
#include "libavutil/avassert.h"
22
#include "avfilter.h"
23
#include "formats.h"
24
#include "internal.h"
25
#include "video.h"
26
27
#undef pixel
28
#undef accumulator
29
#if DEPTH == 8
30
#define pixel uint8_t
31
#define accumulator int
32
#else
33
#define pixel uint16_t
34
#define accumulator int64_t
35
#endif
36
37
#define fn3(a,b)   a##_##b
38
#define fn2(a,b)   fn3(a,b)
39
#define fn(a)      fn2(a, DEPTH)
40
41
/*
42
 * This macro interpolates the value of both fields at a point halfway
43
 * between lines and takes the squared difference. In field resolution
44
 * the point is a quarter pixel below a line in one field and a quarter
45
 * pixel above a line in other.
46
 *
47
 * (The result is actually multiplied by 25)
48
 */
49
#define DIFF(a, as, b, bs) ((t) = ((*(a) - (b)[bs]) << 2) + (a)[(as) << 1] - (b)[-(bs)], (t) * (t))
50
51
/*
52
 * Find which field combination has the smallest average squared difference
53
 * between the fields.
54
 */
55
49
static enum PhaseMode fn(analyze_plane)(void *ctx, enum PhaseMode mode, AVFrame *old, AVFrame *new)
56
{
57
    double bdiff, tdiff, pdiff;
58
59
49
    if (mode == AUTO) {
60
        mode = new->interlaced_frame ? new->top_field_first ?
61
               TOP_FIRST : BOTTOM_FIRST : PROGRESSIVE;
62
49
    } else if (mode == AUTO_ANALYZE) {
63
49
        mode = new->interlaced_frame ? new->top_field_first ?
64
49
               TOP_FIRST_ANALYZE : BOTTOM_FIRST_ANALYZE : FULL_ANALYZE;
65
    }
66
67
49
    if (mode <= BOTTOM_FIRST) {
68
        bdiff = pdiff = tdiff = 65536.0;
69
    } else {
70
49
        const double factor = 1. / (25. * (1 << (DEPTH - 8)) * (1 << (DEPTH - 8)));
71
49
        const int ns = new->linesize[0] / sizeof(pixel);
72
49
        const int os = old->linesize[0] / sizeof(pixel);
73
49
        const pixel *nptr = (pixel *)new->data[0];
74
49
        const pixel *optr = (pixel *)old->data[0];
75
49
        const int h = new->height;
76
49
        const int w = new->width;
77
        accumulator bdif, tdif, pdif;
78
        double scale;
79
80
49
        int top = 0, t;
81
49
        const pixel *rend, *end = nptr + (h - 2) * ns;
82
83
49
        bdiff = pdiff = tdiff = 0.0;
84
85
49
        nptr += ns;
86
49
        optr += os;
87
14014
        while (nptr < end) {
88
13965
            pdif = tdif = bdif = 0;
89
90
13965
            switch (mode) {
91
            case TOP_FIRST_ANALYZE:
92
                if (top) {
93
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
94
                        pdif += DIFF(nptr, ns, nptr, ns);
95
                        tdif += DIFF(nptr, ns, optr, os);
96
                    }
97
                } else {
98
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
99
                        pdif += DIFF(nptr, ns, nptr, ns);
100
                        tdif += DIFF(optr, os, nptr, ns);
101
                    }
102
                }
103
                break;
104
            case BOTTOM_FIRST_ANALYZE:
105
                if (top) {
106
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
107
                        pdif += DIFF(nptr, ns, nptr, ns);
108
                        bdif += DIFF(optr, os, nptr, ns);
109
                    }
110
                } else {
111
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
112
                        pdif += DIFF(nptr, ns, nptr, ns);
113
                        bdif += DIFF(nptr, ns, optr, os);
114
                    }
115
                }
116
                break;
117
            case ANALYZE:
118
                if (top) {
119
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
120
                        tdif += DIFF(nptr, ns, optr, os);
121
                        bdif += DIFF(optr, os, nptr, ns);
122
                    }
123
                } else {
124
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
125
                        bdif += DIFF(nptr, ns, optr, os);
126
                        tdif += DIFF(optr, os, nptr, ns);
127
                    }
128
                }
129
                break;
130
13965
            case FULL_ANALYZE:
131
13965
                if (top) {
132
2456174
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
133
2449216
                        pdif += DIFF(nptr, ns, nptr, ns);
134
2449216
                        tdif += DIFF(nptr, ns, optr, os);
135
2449216
                        bdif += DIFF(optr, os, nptr, ns);
136
                    }
137
                } else {
138
2473471
                    for (rend = nptr + w; nptr < rend; nptr++, optr++) {
139
2466464
                        pdif += DIFF(nptr, ns, nptr, ns);
140
2466464
                        bdif += DIFF(nptr, ns, optr, os);
141
2466464
                        tdif += DIFF(optr, os, nptr, ns);
142
                    }
143
                }
144
13965
                break;
145
            default:
146
                av_assert0(0);
147
            }
148
149
13965
            pdiff += (double)pdif;
150
13965
            tdiff += (double)tdif;
151
13965
            bdiff += (double)bdif;
152
13965
            nptr += ns - w;
153
13965
            optr += os - w;
154
13965
            top ^= 1;
155
        }
156
157
49
        scale = 1.0 / (w * (h - 3)) * factor;
158
49
        pdiff *= scale;
159
49
        tdiff *= scale;
160
49
        bdiff *= scale;
161
162
49
        if (mode == TOP_FIRST_ANALYZE) {
163
            bdiff = 65536.0;
164
49
        } else if (mode == BOTTOM_FIRST_ANALYZE) {
165
            tdiff = 65536.0;
166
49
        } else if (mode == ANALYZE) {
167
            pdiff = 65536.0;
168
        }
169
170
49
        if (bdiff < pdiff && bdiff < tdiff) {
171
            mode = BOTTOM_FIRST;
172
49
        } else if (tdiff < pdiff && tdiff < bdiff) {
173
            mode = TOP_FIRST;
174
        } else {
175
49
            mode = PROGRESSIVE;
176
        }
177
    }
178
179
98
    av_log(ctx, AV_LOG_DEBUG, "mode=%c tdiff=%f bdiff=%f pdiff=%f\n",
180
49
           mode == BOTTOM_FIRST ? 'b' : mode == TOP_FIRST ? 't' : 'p',
181
           tdiff, bdiff, pdiff);
182
49
    return mode;
183
}