FFmpeg
edge_template.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Thilo Borgmann <thilo.borgmann _at_ mail.de>
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 Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  * Redistribution and use in source and binary forms, with or without modification,
20  * are permitted provided that the following conditions are met:
21  */
22 
23 #include "libavutil/avassert.h"
24 #include "avfilter.h"
25 #include "video.h"
26 
27 #undef pixel
28 #if DEPTH == 8
29 #define pixel uint8_t
30 #else
31 #define pixel uint16_t
32 #endif
33 
34 #undef fn
35 #undef fn2
36 #undef fn3
37 #define fn3(a,b) ff_##a##_##b
38 #define fn2(a,b) fn3(a,b)
39 #define fn(a) fn2(a, DEPTH)
40 
41 void fn(sobel)(int w, int h,
42  uint16_t *dst, int dst_linesize,
43  int8_t *dir, int dir_linesize,
44  const uint8_t *src, int src_linesize, int src_stride)
45 {
46  pixel *srcp = (pixel *)src;
47 
48  src_stride /= sizeof(pixel);
49  src_linesize /= sizeof(pixel);
50  dst_linesize /= sizeof(pixel);
51 
52  for (int j = 1; j < h - 1; j++) {
53  dst += dst_linesize;
54  dir += dir_linesize;
55  srcp += src_linesize;
56  for (int i = 1; i < w - 1; i++) {
57  const int gx =
58  -1*srcp[-src_linesize + (i-1)*src_stride] + 1*srcp[-src_linesize + (i+1)*src_stride]
59  -2*srcp[ (i-1)*src_stride] + 2*srcp[ (i+1)*src_stride]
60  -1*srcp[ src_linesize + (i-1)*src_stride] + 1*srcp[ src_linesize + (i+1)*src_stride];
61  const int gy =
62  -1*srcp[-src_linesize + (i-1)*src_stride] + 1*srcp[ src_linesize + (i-1)*src_stride]
63  -2*srcp[-src_linesize + (i )*src_stride] + 2*srcp[ src_linesize + (i )*src_stride]
64  -1*srcp[-src_linesize + (i+1)*src_stride] + 1*srcp[ src_linesize + (i+1)*src_stride];
65 
66  dst[i] = FFABS(gx) + FFABS(gy);
67  dir[i] = get_rounded_direction(gx, gy);
68  }
69  }
70 }
71 
72 void fn(gaussian_blur)(int w, int h,
73  uint8_t *dst, int dst_linesize,
74  const uint8_t *src, int src_linesize, int src_stride)
75 {
76  int j;
77  pixel *srcp = (pixel *)src;
78  pixel *dstp = (pixel *)dst;
79 
80  src_stride /= sizeof(pixel);
81  src_linesize /= sizeof(pixel);
82  dst_linesize /= sizeof(pixel);
83 
84  for (j = 0; j < FFMIN(h, 2); j++) {
85  memcpy(dstp, srcp, w*sizeof(pixel));
86  dstp += dst_linesize;
87  srcp += src_linesize;
88  }
89 
90  for (; j < h - 2; j++) {
91  int i;
92  for (i = 0; i < FFMIN(w, 2); i++)
93  dstp[i] = srcp[i*src_stride];
94  for (; i < w - 2; i++) {
95  /* Gaussian mask of size 5x5 with sigma = 1.4 */
96  dstp[i] = ((srcp[-2*src_linesize + (i-2)*src_stride] + srcp[2*src_linesize + (i-2)*src_stride]) * 2
97  + (srcp[-2*src_linesize + (i-1)*src_stride] + srcp[2*src_linesize + (i-1)*src_stride]) * 4
98  + (srcp[-2*src_linesize + (i )*src_stride] + srcp[2*src_linesize + (i )*src_stride]) * 5
99  + (srcp[-2*src_linesize + (i+1)*src_stride] + srcp[2*src_linesize + (i+1)*src_stride]) * 4
100  + (srcp[-2*src_linesize + (i+2)*src_stride] + srcp[2*src_linesize + (i+2)*src_stride]) * 2
101 
102  + (srcp[ -src_linesize + (i-2)*src_stride] + srcp[ src_linesize + (i-2)*src_stride]) * 4
103  + (srcp[ -src_linesize + (i-1)*src_stride] + srcp[ src_linesize + (i-1)*src_stride]) * 9
104  + (srcp[ -src_linesize + (i )*src_stride] + srcp[ src_linesize + (i )*src_stride]) * 12
105  + (srcp[ -src_linesize + (i+1)*src_stride] + srcp[ src_linesize + (i+1)*src_stride]) * 9
106  + (srcp[ -src_linesize + (i+2)*src_stride] + srcp[ src_linesize + (i+2)*src_stride]) * 4
107 
108  + srcp[(i-2)*src_stride] * 5
109  + srcp[(i-1)*src_stride] * 12
110  + srcp[(i )*src_stride] * 15
111  + srcp[(i+1)*src_stride] * 12
112  + srcp[(i+2)*src_stride] * 5) / 159;
113  }
114  for (; i < w; i++)
115  dstp[i] = srcp[i*src_stride];
116 
117  dstp += dst_linesize;
118  srcp += src_linesize;
119  }
120  for (; j < h; j++) {
121  memcpy(dstp, srcp, w*sizeof(pixel));
122  dstp += dst_linesize;
123  srcp += src_linesize;
124  }
125 }
gaussian_blur
void fn() gaussian_blur(int w, int h, uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int src_stride)
Definition: edge_template.c:72
w
uint8_t w
Definition: llviddspenc.c:38
fn
#define fn(a)
Definition: edge_template.c:39
video.h
get_rounded_direction
static int get_rounded_direction(int gx, int gy)
Definition: edge_common.c:22
avassert.h
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
pixel
uint8_t pixel
Definition: tiny_ssim.c:41
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
pixel
#define pixel
Definition: edge_template.c:31
avfilter.h
sobel
void fn() sobel(int w, int h, uint16_t *dst, int dst_linesize, int8_t *dir, int dir_linesize, const uint8_t *src, int src_linesize, int src_stride)
Definition: edge_template.c:41
h
h
Definition: vp9dsp_template.c:2070
src
#define src
Definition: vp8dsp.c:248