FFmpeg
phase_template.c
Go to the documentation of this file.
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 static enum PhaseMode fn(analyze_plane)(void *ctx, enum PhaseMode mode, AVFrame *old, AVFrame *new)
56 {
57  double bdiff, tdiff, pdiff;
58 
59  if (mode == AUTO) {
60  mode = new->interlaced_frame ? new->top_field_first ?
62  } else if (mode == AUTO_ANALYZE) {
63  mode = new->interlaced_frame ? new->top_field_first ?
65  }
66 
67  if (mode <= BOTTOM_FIRST) {
68  bdiff = pdiff = tdiff = 65536.0;
69  } else {
70  const double factor = 1. / (25. * (1 << (DEPTH - 8)) * (1 << (DEPTH - 8)));
71  const int ns = new->linesize[0] / sizeof(pixel);
72  const int os = old->linesize[0] / sizeof(pixel);
73  const pixel *nptr = (pixel *)new->data[0];
74  const pixel *optr = (pixel *)old->data[0];
75  const int h = new->height;
76  const int w = new->width;
77  accumulator bdif, tdif, pdif;
78  double scale;
79 
80  int top = 0, t;
81  const pixel *rend, *end = nptr + (h - 2) * ns;
82 
83  bdiff = pdiff = tdiff = 0.0;
84 
85  nptr += ns;
86  optr += os;
87  while (nptr < end) {
88  pdif = tdif = bdif = 0;
89 
90  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;
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  case FULL_ANALYZE:
131  if (top) {
132  for (rend = nptr + w; nptr < rend; nptr++, optr++) {
133  pdif += DIFF(nptr, ns, nptr, ns);
134  tdif += DIFF(nptr, ns, optr, os);
135  bdif += DIFF(optr, os, nptr, ns);
136  }
137  } else {
138  for (rend = nptr + w; nptr < rend; nptr++, optr++) {
139  pdif += DIFF(nptr, ns, nptr, ns);
140  bdif += DIFF(nptr, ns, optr, os);
141  tdif += DIFF(optr, os, nptr, ns);
142  }
143  }
144  break;
145  default:
146  av_assert0(0);
147  }
148 
149  pdiff += (double)pdif;
150  tdiff += (double)tdif;
151  bdiff += (double)bdif;
152  nptr += ns - w;
153  optr += os - w;
154  top ^= 1;
155  }
156 
157  scale = 1.0 / (w * (h - 3)) * factor;
158  pdiff *= scale;
159  tdiff *= scale;
160  bdiff *= scale;
161 
162  if (mode == TOP_FIRST_ANALYZE) {
163  bdiff = 65536.0;
164  } else if (mode == BOTTOM_FIRST_ANALYZE) {
165  tdiff = 65536.0;
166  } else if (mode == ANALYZE) {
167  pdiff = 65536.0;
168  }
169 
170  if (bdiff < pdiff && bdiff < tdiff) {
171  mode = BOTTOM_FIRST;
172  } else if (tdiff < pdiff && tdiff < bdiff) {
173  mode = TOP_FIRST;
174  } else {
175  mode = PROGRESSIVE;
176  }
177  }
178 
179  av_log(ctx, AV_LOG_DEBUG, "mode=%c tdiff=%f bdiff=%f pdiff=%f\n",
180  mode == BOTTOM_FIRST ? 'b' : mode == TOP_FIRST ? 't' : 'p',
181  tdiff, bdiff, pdiff);
182  return mode;
183 }
BOTTOM_FIRST
@ BOTTOM_FIRST
Definition: vf_phase.c:33
PROGRESSIVE
@ PROGRESSIVE
in the bitstream is reported as 00b
Definition: vc1.h:149
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
w
uint8_t w
Definition: llviddspenc.c:38
video.h
formats.h
DIFF
#define DIFF(a, as, b, bs)
Definition: phase_template.c:49
ANALYZE
@ ANALYZE
Definition: vf_phase.c:36
avassert.h
AUTO
@ AUTO
Definition: vf_phase.c:38
TOP_FIRST
@ TOP_FIRST
Definition: vf_phase.c:32
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
ctx
AVFormatContext * ctx
Definition: movenc.c:48
TOP_FIRST_ANALYZE
@ TOP_FIRST_ANALYZE
Definition: vf_phase.c:34
pixel
uint8_t pixel
Definition: tiny_ssim.c:42
analyze_plane
static enum PhaseMode fn() analyze_plane(void *ctx, enum PhaseMode mode, AVFrame *old, AVFrame *new)
Definition: phase_template.c:55
accumulator
#define accumulator
Definition: phase_template.c:34
FULL_ANALYZE
@ FULL_ANALYZE
Definition: vf_phase.c:37
ns
#define ns(max_value, name, subs,...)
Definition: cbs_av1.c:686
internal.h
pixel
#define pixel
Definition: phase_template.c:33
PhaseMode
PhaseMode
Definition: vf_phase.c:30
fn
#define fn(a)
Definition: phase_template.c:39
DEPTH
#define DEPTH
Definition: v210enc.c:40
AUTO_ANALYZE
@ AUTO_ANALYZE
Definition: vf_phase.c:39
mode
mode
Definition: ebur128.h:83
avfilter.h
factor
static const int factor[16]
Definition: vf_pp7.c:75
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
h
h
Definition: vp9dsp_template.c:2038
BOTTOM_FIRST_ANALYZE
@ BOTTOM_FIRST_ANALYZE
Definition: vf_phase.c:35