1 /*
2 * Copyright (c) 2002 A'rpi
3 * This file is part of FFmpeg.
4 *
5 * FFmpeg is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * FFmpeg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 /**
21 * @file
22 * border detection filter
23 * Ported from MPlayer libmpcodecs/vf_cropdetect.c.
24 */
25
29
34
46
62 };
63
65 {
66 int total = 0;
68 const uint16_t *src16 = (
const uint16_t *)
src;
69
70 switch (bpp) {
71 case 1:
77 }
81 }
82 break;
83 case 2:
90 }
92 total += src16[0];
94 }
95 break;
96 case 3:
97 case 4:
105 }
109 }
110 div *= 3;
111 break;
112 }
113 total /= div;
114
116 return total;
117 }
118
120 {
122
123 s->frame_nb = -1 *
s->skip;
124
126 s->limit,
s->round,
s->skip,
s->reset_count);
127
128 return 0;
129 }
130
132 {
136
138
140 s->limit *= (1 <<
desc->comp[0].depth) - 1;
141
146
147 return 0;
148 }
149
150 #define SET_META(key, value) \
151 av_dict_set_int(metadata, key, value, 0)
152
154 {
157 int bpp =
s->max_pixsteps[0];
158 int w,
h, x, y, shrink_by;
160 int outliers, last_y;
162
163 // ignore first s->skip frames
164 if (++
s->frame_nb > 0) {
165 metadata = &
frame->metadata;
166
167 // Reset the crop area every reset_count frames, if reset_count is > 0
168 if (
s->reset_count > 0 &&
s->frame_nb >
s->reset_count) {
170 s->y1 =
frame->height - 1;
174 }
175
176 #define FIND(DST, FROM, NOEND, INC, STEP0, STEP1, LEN) \
177 outliers = 0;\
178 for (last_y = y = FROM; NOEND; y = y INC) {\
179 if (checkline(ctx, frame->data[0] + STEP0 * y, STEP1, LEN, bpp) > limit) {\
180 if (++outliers > s->max_outliers) { \
181 DST = last_y;\
182 break;\
183 }\
184 } else\
185 last_y = y INC;\
186 }
187
192
193
194 // round x and y (up), important for yuv colorspaces
195 // make sure they stay rounded!
198
201
202 // w and h must be divisible by 2 as well because of yuv
203 // colorspace problems.
208
209 shrink_by =
w %
s->round;
211 x += (shrink_by/2 + 1) & ~1;
212
213 shrink_by =
h %
s->round;
215 y += (shrink_by/2 + 1) & ~1;
216
225
227 "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n",
228 s->x1,
s->x2,
s->y1,
s->y2,
w,
h, x, y,
frame->pts,
231 }
232
234 }
235
236 #define OFFSET(x) offsetof(CropDetectContext, x)
237 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
238
242 {
"reset",
"Recalculate the crop area after this many frames",
OFFSET(reset_count),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
FLAGS },
244 {
"reset_count",
"Recalculate the crop area after this many frames",
OFFSET(reset_count),
AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX,
FLAGS },
247 };
248
250
252 {
257 },
258 };
259
261 {
264 },
265 };
266
268 .
name =
"cropdetect",
271 .priv_class = &cropdetect_class,
277 };