History

avfilter/vf_convolution: add column/vertical mode

Paul B Mahol committed 8 years ago

Commit aba39cc1 parent 901dc112 files · +144 −47Browse files

Showing the changes to libavfilter/vf_convolution.c (1 of 2 files). Show all

Unified · Split

libavfilter/vf_convolution.c+142−45
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 enum MatrixMode {
3333 MATRIX_SQUARE,
3434 MATRIX_ROW,
35+ MATRIX_COLUMN,
3536 MATRIX_NBMODES,
3637 };
3738
@@ -60,9 +61,10 @@ typedef struct ConvolutionContext { · 22 unmodified lines
6061
6162 void (*setup[4])(int radius, const uint8_t *c[], const uint8_t *src, int stride,
6263 int x, int width, int y, int height, int bpc);
63− void (*filter[4])(uint8_t *dst, const uint8_t *src, int width,
64+ void (*filter[4])(uint8_t *dst, int width,
6465 float rdiv, float bias, const int *const matrix,
65− const uint8_t *c[], int peak, int radius);
66+ const uint8_t *c[], int peak, int radius,
67+ int dstride, int stride);
6668 } ConvolutionContext;
6769
6870 #define OFFSET(x) offsetof(ConvolutionContext, x)
@@ -87,6 +89,7 @@ static const AVOption convolution_options[] = { · 18 unmodified lines
8789 { "3mode", "set matrix mode for 4th plane", OFFSET(mode[3]), AV_OPT_TYPE_INT, {.i64=MATRIX_SQUARE}, 0, MATRIX_NBMODES-1, FLAGS, "mode" },
8890 { "square", "square matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_SQUARE}, 0, 0, FLAGS, "mode" },
8991 { "row", "single row matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_ROW} , 0, 0, FLAGS, "mode" },
92+ { "column", "single column matrix", 0, AV_OPT_TYPE_CONST, {.i64=MATRIX_COLUMN}, 0, 0, FLAGS, "mode" },
9093 { NULL }
9194 };
9295
@@ -140,9 +143,10 @@ typedef struct ThreadData { · 47 unmodified lines
140143 AVFrame *in, *out;
141144 } ThreadData;
142145
143−static void filter16_prewitt(uint8_t *dstp, const uint8_t *src, int width,
146+static void filter16_prewitt(uint8_t *dstp, int width,
144147 float scale, float delta, const int *const matrix,
145− const uint8_t *c[], int peak, int radius)
148+ const uint8_t *c[], int peak, int radius,
149+ int dstride, int stride)
146150 {
147151 uint16_t *dst = (uint16_t *)dstp;
148152 int x;
@@ -157,9 +161,10 @@ static void filter16_prewitt(uint8_t *dstp, const uint8_t *src, int width, · 8 unmodified lines
157161 }
158162 }
159163
160−static void filter16_roberts(uint8_t *dstp, const uint8_t *src, int width,
164+static void filter16_roberts(uint8_t *dstp, int width,
161165 float scale, float delta, const int *const matrix,
162− const uint8_t *c[], int peak, int radius)
166+ const uint8_t *c[], int peak, int radius,
167+ int dstride, int stride)
163168 {
164169 uint16_t *dst = (uint16_t *)dstp;
165170 int x;
@@ -172,9 +177,10 @@ static void filter16_roberts(uint8_t *dstp, const uint8_t *src, int width, · 6 unmodified lines
172177 }
173178 }
174179
175−static void filter16_sobel(uint8_t *dstp, const uint8_t *src, int width,
180+static void filter16_sobel(uint8_t *dstp, int width,
176181 float scale, float delta, const int *const matrix,
177− const uint8_t *c[], int peak, int radius)
182+ const uint8_t *c[], int peak, int radius,
183+ int dstride, int stride)
178184 {
179185 uint16_t *dst = (uint16_t *)dstp;
180186 int x;
@@ -189,9 +195,10 @@ static void filter16_sobel(uint8_t *dstp, const uint8_t *src, int width, · 8 unmodified lines
189195 }
190196 }
191197
192−static void filter_prewitt(uint8_t *dst, const uint8_t *src, int width,
198+static void filter_prewitt(uint8_t *dst, int width,
193199 float scale, float delta, const int *const matrix,
194− const uint8_t *c[], int peak, int radius)
200+ const uint8_t *c[], int peak, int radius,
201+ int dstride, int stride)
195202 {
196203 const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
197204 const uint8_t *c3 = c[3], *c5 = c[5];
@@ -208,9 +215,10 @@ static void filter_prewitt(uint8_t *dst, const uint8_t *src, int width, · 10 unmodified lines
208215 }
209216 }
210217
211−static void filter_roberts(uint8_t *dst, const uint8_t *src, int width,
218+static void filter_roberts(uint8_t *dst, int width,
212219 float scale, float delta, const int *const matrix,
213− const uint8_t *c[], int peak, int radius)
220+ const uint8_t *c[], int peak, int radius,
221+ int dstride, int stride)
214222 {
215223 int x;
216224
@@ -222,9 +230,10 @@ static void filter_roberts(uint8_t *dst, const uint8_t *src, int width, · 5 unmodified lines
222230 }
223231 }
224232
225−static void filter_sobel(uint8_t *dst, const uint8_t *src, int width,
233+static void filter_sobel(uint8_t *dst, int width,
226234 float scale, float delta, const int *const matrix,
227− const uint8_t *c[], int peak, int radius)
235+ const uint8_t *c[], int peak, int radius,
236+ int dstride, int stride)
228237 {
229238 const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
230239 const uint8_t *c3 = c[3], *c5 = c[5];
@@ -241,9 +250,10 @@ static void filter_sobel(uint8_t *dst, const uint8_t *src, int width, · 10 unmodified lines
241250 }
242251 }
243252
244−static void filter16_3x3(uint8_t *dstp, const uint8_t *src, int width,
253+static void filter16_3x3(uint8_t *dstp, int width,
245254 float rdiv, float bias, const int *const matrix,
246− const uint8_t *c[], int peak, int radius)
255+ const uint8_t *c[], int peak, int radius,
256+ int dstride, int stride)
247257 {
248258 uint16_t *dst = (uint16_t *)dstp;
249259 int x;
@@ -263,9 +273,10 @@ static void filter16_3x3(uint8_t *dstp, const uint8_t *src, int width, · 13 unmodified lines
263273 }
264274 }
265275
266−static void filter16_5x5(uint8_t *dstp, const uint8_t *src, int width,
276+static void filter16_5x5(uint8_t *dstp, int width,
267277 float rdiv, float bias, const int *const matrix,
268− const uint8_t *c[], int peak, int radius)
278+ const uint8_t *c[], int peak, int radius,
279+ int dstride, int stride)
269280 {
270281 uint16_t *dst = (uint16_t *)dstp;
271282 int x;
@@ -281,9 +292,10 @@ static void filter16_5x5(uint8_t *dstp, const uint8_t *src, int width, · 9 unmodified lines
281292 }
282293 }
283294
284−static void filter16_7x7(uint8_t *dstp, const uint8_t *src, int width,
295+static void filter16_7x7(uint8_t *dstp, int width,
285296 float rdiv, float bias, const int *const matrix,
286− const uint8_t *c[], int peak, int radius)
297+ const uint8_t *c[], int peak, int radius,
298+ int dstride, int stride)
287299 {
288300 uint16_t *dst = (uint16_t *)dstp;
289301 int x;
@@ -299,9 +311,10 @@ static void filter16_7x7(uint8_t *dstp, const uint8_t *src, int width, · 9 unmodified lines
299311 }
300312 }
301313
302−static void filter16_row(uint8_t *dstp, const uint8_t *src, int width,
314+static void filter16_row(uint8_t *dstp, int width,
303315 float rdiv, float bias, const int *const matrix,
304− const uint8_t *c[], int peak, int radius)
316+ const uint8_t *c[], int peak, int radius,
317+ int dstride, int stride)
305318 {
306319 uint16_t *dst = (uint16_t *)dstp;
307320 int x;
@@ -317,9 +330,30 @@ static void filter16_row(uint8_t *dstp, const uint8_t *src, int width, · 9 unmodified lines
317330 }
318331 }
319332
320−static void filter_7x7(uint8_t *dst, const uint8_t *src, int width,
333+static void filter16_column(uint8_t *dstp, int height,
334+ float rdiv, float bias, const int *const matrix,
335+ const uint8_t *c[], int peak, int radius,
336+ int dstride, int stride)
337+{
338+ uint16_t *dst = (uint16_t *)dstp;
339+ int y;
340+
341+ for (y = 0; y < height; y++) {
342+ int i, sum = 0;
343+
344+ for (i = 0; i < 2 * radius + 1; i++)
345+ sum += AV_RN16A(&c[i][0 + y * stride]) * matrix[i];
346+
347+ sum = (int)(sum * rdiv + bias + 0.5f);
348+ dst[0] = av_clip(sum, 0, peak);
349+ dst += dstride / 2;
350+ }
351+}
352+
353+static void filter_7x7(uint8_t *dst, int width,
321354 float rdiv, float bias, const int *const matrix,
322− const uint8_t *c[], int peak, int radius)
355+ const uint8_t *c[], int peak, int radius,
356+ int dstride, int stride)
323357 {
324358 int x;
325359
@@ -334,9 +368,10 @@ static void filter_7x7(uint8_t *dst, const uint8_t *src, int width, · 8 unmodified lines
334368 }
335369 }
336370
337−static void filter_5x5(uint8_t *dst, const uint8_t *src, int width,
371+static void filter_5x5(uint8_t *dst, int width,
338372 float rdiv, float bias, const int *const matrix,
339− const uint8_t *c[], int peak, int radius)
373+ const uint8_t *c[], int peak, int radius,
374+ int dstride, int stride)
340375 {
341376 int x;
342377
@@ -351,9 +386,10 @@ static void filter_5x5(uint8_t *dst, const uint8_t *src, int width, · 8 unmodified lines
351386 }
352387 }
353388
354−static void filter_3x3(uint8_t *dst, const uint8_t *src, int width,
389+static void filter_3x3(uint8_t *dst, int width,
355390 float rdiv, float bias, const int *const matrix,
356− const uint8_t *c[], int peak, int radius)
391+ const uint8_t *c[], int peak, int radius,
392+ int dstride, int stride)
357393 {
358394 const uint8_t *c0 = c[0], *c1 = c[1], *c2 = c[2];
359395 const uint8_t *c3 = c[3], *c4 = c[4], *c5 = c[5];
@@ -369,9 +405,10 @@ static void filter_3x3(uint8_t *dst, const uint8_t *src, int width, · 9 unmodified lines
369405 }
370406 }
371407
372−static void filter_row(uint8_t *dst, const uint8_t *src, int width,
408+static void filter_row(uint8_t *dst, int width,
373409 float rdiv, float bias, const int *const matrix,
374− const uint8_t *c[], int peak, int radius)
410+ const uint8_t *c[], int peak, int radius,
411+ int dstride, int stride)
375412 {
376413 int x;
377414
@@ -386,6 +423,25 @@ static void filter_row(uint8_t *dst, const uint8_t *src, int width, · 8 unmodified lines
386423 }
387424 }
388425
426+static void filter_column(uint8_t *dst, int height,
427+ float rdiv, float bias, const int *const matrix,
428+ const uint8_t *c[], int peak, int radius,
429+ int dstride, int stride)
430+{
431+ int y;
432+
433+ for (y = 0; y < height; y++) {
434+ int i, sum = 0;
435+
436+ for (i = 0; i < 2 * radius + 1; i++)
437+ sum += c[i][0 + y * stride] * matrix[i];
438+
439+ sum = (int)(sum * rdiv + bias + 0.5f);
440+ dst[0] = av_clip_uint8(sum);
441+ dst += dstride;
442+ }
443+}
444+
389445 static void setup_3x3(int radius, const uint8_t *c[], const uint8_t *src, int stride,
390446 int x, int w, int y, int h, int bpc)
391447 {
@@ -448,6 +504,20 @@ static void setup_row(int radius, const uint8_t *c[], const uint8_t *src, int st · 56 unmodified lines
448504 }
449505 }
450506
507+static void setup_column(int radius, const uint8_t *c[], const uint8_t *src, int stride,
508+ int x, int w, int y, int h, int bpc)
509+{
510+ int i;
511+
512+ for (i = 0; i < radius * 2 + 1; i++) {
513+ int xoff = FFABS(x + i - radius);
514+
515+ xoff = xoff >= h ? 2 * h - 1 - xoff : xoff;
516+
517+ c[i] = src + y * bpc + xoff * stride;
518+ }
519+}
520+
451521 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
452522 {
453523 ConvolutionContext *s = ctx->priv;
@@ -457,43 +527,64 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) · 3 unmodified lines
457527 int plane;
458528
459529 for (plane = 0; plane < s->nb_planes; plane++) {
530+ const int mode = s->mode[plane];
531+ const int bpc = s->bpc;
460532 const int radius = s->size[plane] / 2;
461533 const int height = s->planeheight[plane];
462534 const int width = s->planewidth[plane];
463535 const int stride = in->linesize[plane];
464536 const int dstride = out->linesize[plane];
465− const int slice_start = (height * jobnr) / nb_jobs;
466− const int slice_end = (height * (jobnr+1)) / nb_jobs;
537+ const int sizeh = mode == MATRIX_COLUMN ? width : height;
538+ const int sizew = mode == MATRIX_COLUMN ? height : width;
539+ const int slice_start = (sizeh * jobnr) / nb_jobs;
540+ const int slice_end = (sizeh * (jobnr+1)) / nb_jobs;
467541 const float rdiv = s->rdiv[plane];
468542 const float bias = s->bias[plane];
469543 const uint8_t *src = in->data[plane];
470− uint8_t *dst = out->data[plane] + slice_start * out->linesize[plane];
544+ const int dst_pos = slice_start * (mode == MATRIX_COLUMN ? bpc : out->linesize[plane]);
545+ uint8_t *dst = out->data[plane] + dst_pos;
471546 const int *matrix = s->matrix[plane];
472− const int bpc = s->bpc;
473547 const uint8_t *c[49];
474548 int y, x;
475549
476550 if (s->copy[plane]) {
477− av_image_copy_plane(dst, dstride, src + slice_start * stride, stride,
478− width * bpc, slice_end - slice_start);
551+ if (mode == MATRIX_COLUMN)
552+ av_image_copy_plane(dst, dstride, src + slice_start * bpc, stride,
553+ (slice_end - slice_start) * bpc, height);
554+ else
555+ av_image_copy_plane(dst, dstride, src + slice_start * stride, stride,
556+ width * bpc, slice_end - slice_start);
479557 continue;
480558 }
481559
482560 for (y = slice_start; y < slice_end; y++) {
561+ const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : radius * bpc;
562+ const int yoff = mode == MATRIX_COLUMN ? radius * stride : 0;
563+
483564 for (x = 0; x < radius; x++) {
565+ const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc;
566+ const int yoff = mode == MATRIX_COLUMN ? x * stride : 0;
567+
484568 s->setup[plane](radius, c, src, stride, x, width, y, height, bpc);
485− s->filter[plane](dst + x * bpc, src, 1, rdiv,
486− bias, matrix, c, s->max, radius);
569+ s->filter[plane](dst + yoff + xoff, 1, rdiv,
570+ bias, matrix, c, s->max, radius,
571+ dstride, stride);
487572 }
488573 s->setup[plane](radius, c, src, stride, radius, width, y, height, bpc);
489− s->filter[plane](dst + radius * bpc, src, width - 2 * radius,
490− rdiv, bias, matrix, c, s->max, radius);
491− for (x = width - radius; x < width; x++) {
574+ s->filter[plane](dst + yoff + xoff, sizew - 2 * radius,
575+ rdiv, bias, matrix, c, s->max, radius,
576+ dstride, stride);
577+ for (x = sizew - radius; x < sizew; x++) {
578+ const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc;
579+ const int yoff = mode == MATRIX_COLUMN ? x * stride : 0;
580+
492581 s->setup[plane](radius, c, src, stride, x, width, y, height, bpc);
493− s->filter[plane](dst + x * bpc, src, 1, rdiv,
494− bias, matrix, c, s->max, radius);
582+ s->filter[plane](dst + yoff + xoff, 1, rdiv,
583+ bias, matrix, c, s->max, radius,
584+ dstride, stride);
495585 }
496− dst += dstride;
586+ if (mode != MATRIX_COLUMN)
587+ dst += dstride;
497588 }
498589 }
499590
@@ -524,6 +615,8 @@ static int config_input(AVFilterLink *inlink) · 24 unmodified lines
524615 for (p = 0; p < s->nb_planes; p++) {
525616 if (s->mode[p] == MATRIX_ROW)
526617 s->filter[p] = filter16_row;
618+ else if (s->mode[p] == MATRIX_COLUMN)
619+ s->filter[p] = filter16_column;
527620 else if (s->size[p] == 3)
528621 s->filter[p] = filter16_3x3;
529622 else if (s->size[p] == 5)
@@ -566,7 +659,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 36 unmodified lines
566659
567660 td.in = in;
568661 td.out = out;
569− ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(s->planeheight[1], s->nb_threads));
662+ ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN3(s->planeheight[1], s->planewidth[1], s->nb_threads));
570663
571664 av_frame_free(&in);
572665 return ff_filter_frame(outlink, out);
@@ -602,6 +695,10 @@ static av_cold int init(AVFilterContext *ctx) · 29 unmodified lines
602695 s->filter[i] = filter_row;
603696 s->setup[i] = setup_row;
604697 s->size[i] = s->matrix_length[i];
698+ } else if (s->mode[i] == MATRIX_COLUMN) {
699+ s->filter[i] = filter_column;
700+ s->setup[i] = setup_column;
701+ s->size[i] = s->matrix_length[i];
605702 } else if (s->matrix_length[i] == 9) {
606703 s->size[i] = 3;
607704 if (!memcmp(matrix, same3x3, sizeof(same3x3)))

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t