什么的水花| 人怕出名猪怕壮是什么生肖| 湖北九头鸟是什么意思| 包皮过长会有什么影响| 酸菜鱼是什么地方的菜| 化学阉割是什么| 女性支原体感染有什么症状| 猫在风水上代表什么| 放屁多是什么病的征兆| 1983年五行属什么| 维生素b族有什么用| 肺气阴两虚吃什么中成药| 熵是什么| 2026年是什么生肖年| 巴雷特是什么| 红红的眼睛是什么生肖| 口臭药店买什么药吃| 脑梗有什么前兆| 结婚6年是什么婚| 不动明王是什么意思| 献血后吃什么补血最快| 脑梗什么症状| bone什么意思| 中国是什么人种| 肌酸激酶高是什么原因| 腥臭味是什么妇科病| 梦见桥断了是什么意思| 孕中期头疼是什么原因| 飞龙在天是什么生肖| 低血糖是什么原因| 农历十月初八是什么星座| 牛子是什么意思| diqua是什么牌子| 下连是什么意思| 武汉大学校长是什么级别| 5月11日是什么星座| 房间里放什么阳气旺| 攫住是什么意思| 尿崩症是什么意思| 安利什么意思| 什么鱼蛋白质含量高| 怡字五行属什么的| 超霸是什么意思| 陀飞轮是什么意思| 象牙有什么作用与功效| 嘴唇发紫是什么病| 气血不足看什么科室| 什么是肝癌| 灵芝孢子粉有什么功效| hpv59阳性是什么意思| 织女是什么意思| 中国的八大菜系是什么| 含羞草为什么害羞| 肝气犯胃吃什么中成药| 比卡丘什么意思| 尿道感染是什么原因| 月经提前是什么原因引起的| 撤退性出血是什么颜色| a4腰什么意思| 胃反流吃什么药好| 寒潮是什么| 电器发生火灾用什么灭火器| 玫瑰糠疹是什么病| 什么减肥产品最好| 做肝功能检查挂什么科| 凌乱是什么意思| 洁面液是干什么用的| 小孩子发烧手脚冰凉是什么原因| 霜降穿什么衣服| 类风湿是什么原因引起的| hcg阴性是什么意思| 左肋骨下面是什么器官| 上嘴唇发黑是什么原因| 水瓶后面是什么星座| 吃什么可以降胆固醇| 双亲是什么意思| ebohr手表什么牌子多少钱| 玉戴久了会有什么变化| 什么叫二婚线| 牙龈疼是什么问题| 胎位lop是什么意思| 手上长小水泡很痒是什么原因| 24节气是什么| 岁月如歌什么意思| 胖大海配什么喝治咽炎| 尿泡沫多吃什么药| 脊髓空洞是什么意思| 法务是干什么的| 中国古代四大发明是什么| 信五行属什么| 勤劳的小蜜蜂什么意思| 腿上有青筋是什么原因| 智字五行属什么| 移动电源和充电宝有什么区别| 蜘蛛的天敌是什么动物| 枕芯用什么填充物好| edc是什么| 疖肿是什么样子的图片| 老是嗜睡是什么原因| 玉历宝钞是什么书| 怕热的人是什么原因| 梦见黄金是什么意思| 血糖高去医院挂什么科| x58主板配什么cpu| 背水一战什么意思| 什么山什么水| 1993年出生属什么生肖| 人生最重要的是什么| 例假提前是什么原因| 属鸡的跟什么属相最配| 爱什么稀罕| ab型血和o型血生的孩子是什么血型| 9月3日是什么星座的| 喝什么提神| 什么馅饺子好吃| 脚趾头疼是什么原因| 二月二十是什么星座| 湿热吃什么食物好得快| 铁树开花什么样| 雪蛤是什么| 孔雀男是什么意思| 愚蠢是什么意思| 高考什么时候恢复| 安娜苏香水什么档次| 衣原体是什么| a1微球蛋白偏高说明什么意思| 财库是什么意思| 尿培养能查出什么病| 尿频尿急吃什么药比较好| zf是什么意思| 耳垂后面有痣代表什么| 脆生生是什么意思| 小姑娘月经推迟不来什么原因| 耳朵疼什么原因| 骨髓穿刺是检查什么病| 舒克是什么职业| 美纹纸是干什么用的| 伶字五行属什么| 淘米水洗脸有什么作用与功效| 92属什么| 解表化湿是什么意思| 网是什么结构的字| 双侧乳腺腺病是什么意思| a货是什么意思| 吃甲硝唑有什么副作用| 生吃大蒜有什么好处| 为什么脚底会脱皮| 糖尿病人可以吃什么水果| 胆红素高吃什么食物能降得快| 肺部有问题一般会出现什么症状| 单剂量给药是什么意思| 心脏变大是什么原因| 牙疼是什么原因引起的| 湿疹是因为什么原因引起的| 幼儿急疹为什么不能碰水| 星星为什么眨眼睛| 月经期喝什么水最好| 七十岁是什么之年| nt什么时候做| 小腿细是什么原因| 眼皮肿是什么原因| 指滑是什么意思| 头昏吃什么药| 种植牙是什么意思| 女人为什么要少吃鳝鱼| 羊脑炎什么症状怎么治| 什么是免疫组化| 又拉又吐吃什么药| 应激反应是什么意思| 脸油是什么原因导致的| 什么叫逻辑思维| 看喉咙挂什么科| 化疗后吃什么药| 马拉色菌毛囊炎用什么药治疗最好| 雷字五行属什么| 腋下臭是什么原因| 肺气泡吃什么药| 被口什么感觉| 是什么品牌| 肾小球肾炎吃什么药| 大腿肌肉疼是什么原因| 痛经什么原因| 什么样人穿棉麻好看| 中央民族大学什么档次| 为什么要做包皮手术| 为什么大拇指只有两节| 0到3个月的婴儿惊吓吃什么药| 今年阴历是什么年| 右眼一直跳是因为什么原因| 眼底出血有什么症状| abc是什么药| 经常吐口水是什么原因| 属牛的生什么属相的孩子好| 抑郁症有什么表现| 一什么头发| 读书是为了什么| 佛是什么| 香草味是什么味道| 种草是什么意思| 谝是什么意思| 邮政编码有什么用| 怀孕腿抽筋是因为什么原因引起的| 脚凉吃什么药| 血管检查是做什么检查| http是什么| 优势是什么意思| 眼睛干涩吃什么食物好| 逐年是什么意思| 什么是蛇缠腰病| 过生日送什么礼物| 柠檬和什么一起泡减肥| 怠工是什么意思| 梦见修坟墓是什么预兆| 腰酸背痛挂什么科| 殷是什么意思| 4月8日什么星座| cpb是什么意思| 查过敏原挂什么科| 安眠穴在什么位置| rococo是什么牌子| 痔疮吃什么| 大便颗粒状是什么原因造成的| 屏气是什么意思| 什么是同素异形体| 五行土克什么| 为什么打哈欠| 意字五行属什么| 秦始皇原名叫什么| 稽留热常见于什么病| 失常是什么意思| 敛肺是什么意思| 陆地上最重的动物是什么| 精液是什么颜色| 91年的羊是什么命| 多饮多尿可能是什么病| 十二月十四日是什么星座| 大便成细条状是什么病| 花中四君子是什么| 挚友是指什么的朋友| 什么叫生酮| 用甲硝唑栓有什么反应| 1981年是什么命| 脚踝疼是什么原因| 点卯是什么意思| 心电图窦性心动过缓是什么意思| 长寿花什么时候开花| 脚麻看什么科室最好| 漪字五行属什么| her是什么意思| 跻身是什么意思| 大名鼎鼎的鼎是什么意思| 什么品种的榴莲最好吃| 花生不能和什么食物一起吃| 孕初期需要注意些什么| 月经不规律是什么原因| 地接是什么意思| esim卡是什么| 看演唱会需要准备什么| 肝最怕什么| 3月17日什么星座| 印堂发黑是什么征兆| 梦见床上有蛇什么预兆| 不举是什么原因造成的| 婴儿掉头发是什么原因| 百度

拉红尿是什么原因


Directory: ../../../ffmpeg/
File: src/libavfilter/vf_bilateral.c
Date: 2025-08-04 00:43:16
Exec Total Coverage
Lines: 0 130 0.0%
Functions: 0 14 0.0%
Branches: 0 94 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2017 Ming Yang
3 * Copyright (c) 2019 Paul B Mahol
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #include "libavutil/imgutils.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
28 #include "avfilter.h"
29 #include "filters.h"
30 #include "video.h"
31
32 typedef struct BilateralContext {
33 const AVClass *class;
34
35 float sigmaS;
36 float sigmaR;
37 int planes;
38
39 int nb_threads;
40 int nb_planes;
41 int depth;
42 int planewidth[4];
43 int planeheight[4];
44
45 float alpha;
46 float range_table[65536];
47
48 float *img_out_f[4];
49 float *img_temp[4];
50 float *map_factor_a[4];
51 float *map_factor_b[4];
52 float *slice_factor_a[4];
53 float *slice_factor_b[4];
54 float *line_factor_a[4];
55 float *line_factor_b[4];
56 } BilateralContext;
57
58 #define OFFSET(x) offsetof(BilateralContext, x)
59 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
60
61 static const AVOption bilateral_options[] = {
62 { "sigmaS", "set spatial sigma", OFFSET(sigmaS), AV_OPT_TYPE_FLOAT, {.dbl=0.1}, 0.0, 512, FLAGS },
63 { "sigmaR", "set range sigma", OFFSET(sigmaR), AV_OPT_TYPE_FLOAT, {.dbl=0.1}, 0.0, 1, FLAGS },
64 { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=1}, 0, 0xF, FLAGS },
65 { NULL }
66 };
67
68 AVFILTER_DEFINE_CLASS(bilateral);
69
70 static const enum AVPixelFormat pix_fmts[] = {
71 AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P,
72 AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P,
73 AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P,
74 AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
75 AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
76 AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
77 AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
78 AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12,
79 AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14,
80 AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
81 AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
82 AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
83 AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16,
84 AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
85 AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
86 AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16,
87 AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16,
88 AV_PIX_FMT_NONE
89 };
90
91 static int config_params(AVFilterContext *ctx)
92 {
93 BilateralContext *s = ctx->priv;
94 float inv_sigma_range;
95
96 inv_sigma_range = 1.0f / (s->sigmaR * ((1 << s->depth) - 1));
97 s->alpha = expf(-sqrtf(2.f) / s->sigmaS);
98
99 //compute a lookup table
100 for (int i = 0; i < (1 << s->depth); i++)
101 s->range_table[i] = s->alpha * expf(-i * inv_sigma_range);
102
103 return 0;
104 }
105
106 typedef struct ThreadData {
107 AVFrame *in, *out;
108 } ThreadData;
109
110 static int config_input(AVFilterLink *inlink)
111 {
112 AVFilterContext *ctx = inlink->dst;
113 BilateralContext *s = ctx->priv;
114 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
115
116 s->depth = desc->comp[0].depth;
117 config_params(ctx);
118
119 s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
120 s->planewidth[0] = s->planewidth[3] = inlink->w;
121 s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
122 s->planeheight[0] = s->planeheight[3] = inlink->h;
123
124 s->nb_planes = av_pix_fmt_count_planes(inlink->format);
125 s->nb_threads = ff_filter_get_nb_threads(ctx);
126
127 for (int p = 0; p < s->nb_planes; p++) {
128 const int w = s->planewidth[p];
129 const int h = s->planeheight[p];
130
131 s->img_out_f[p] = av_calloc(w * h, sizeof(float));
132 s->img_temp[p] = av_calloc(w * h, sizeof(float));
133 s->map_factor_a[p] = av_calloc(w * h, sizeof(float));
134 s->map_factor_b[p] = av_calloc(w * h, sizeof(float));
135 s->slice_factor_a[p] = av_calloc(w, sizeof(float));
136 s->slice_factor_b[p] = av_calloc(w, sizeof(float));
137 s->line_factor_a[p] = av_calloc(w, sizeof(float));
138 s->line_factor_b[p] = av_calloc(w, sizeof(float));
139
140 if (!s->img_out_f[p] ||
141 !s->img_temp[p] ||
142 !s->map_factor_a[p] ||
143 !s->map_factor_b[p] ||
144 !s->slice_factor_a[p] ||
145 !s->slice_factor_a[p] ||
146 !s->line_factor_a[p] ||
147 !s->line_factor_a[p])
148 return AVERROR(ENOMEM);
149 }
150
151 return 0;
152 }
153
154 #define BILATERAL_H(type, name) \
155 static void bilateralh_##name(BilateralContext *s, AVFrame *out, AVFrame *in, \
156 int jobnr, int nb_jobs, int plane) \
157 { \
158 const int width = s->planewidth[plane]; \
159 const int height = s->planeheight[plane]; \
160 const int slice_start = (height * jobnr) / nb_jobs; \
161 const int slice_end = (height * (jobnr+1)) / nb_jobs; \
162 const int src_linesize = in->linesize[plane] / sizeof(type); \
163 const type *src = (const type *)in->data[plane]; \
164 float *img_temp = s->img_temp[plane]; \
165 float *map_factor_a = s->map_factor_a[plane]; \
166 const float *const range_table = s->range_table; \
167 const float alpha = s->alpha; \
168 float ypr, ycr, fp, fc; \
169 const float inv_alpha_ = 1.f - alpha; \
170 \
171 for (int y = slice_start; y < slice_end; y++) { \
172 float *temp_factor_x, *temp_x = &img_temp[y * width]; \
173 const type *in_x = &src[y * src_linesize]; \
174 const type *texture_x = &src[y * src_linesize]; \
175 type tpr; \
176 \
177 *temp_x++ = ypr = *in_x++; \
178 tpr = *texture_x++; \
179 \
180 temp_factor_x = &map_factor_a[y * width]; \
181 *temp_factor_x++ = fp = 1; \
182 \
183 for (int x = 1; x < width; x++) { \
184 float alpha_; \
185 int range_dist; \
186 type tcr = *texture_x++; \
187 type dr = abs(tcr - tpr); \
188 \
189 range_dist = dr; \
190 alpha_ = range_table[range_dist]; \
191 *temp_x++ = ycr = inv_alpha_*(*in_x++) + alpha_*ypr; \
192 tpr = tcr; \
193 ypr = ycr; \
194 *temp_factor_x++ = fc = inv_alpha_ + alpha_ * fp; \
195 fp = fc; \
196 } \
197 --temp_x; *temp_x = ((*temp_x) + (*--in_x)); \
198 tpr = *--texture_x; \
199 ypr = *in_x; \
200 \
201 --temp_factor_x; *temp_factor_x = ((*temp_factor_x) + 1); \
202 fp = 1; \
203 \
204 for (int x = width - 2; x >= 0; x--) { \
205 type tcr = *--texture_x; \
206 type dr = abs(tcr - tpr); \
207 int range_dist = dr; \
208 float alpha_ = range_table[range_dist]; \
209 \
210 ycr = inv_alpha_ * (*--in_x) + alpha_ * ypr; \
211 --temp_x; *temp_x = ((*temp_x) + ycr); \
212 tpr = tcr; \
213 ypr = ycr; \
214 \
215 fc = inv_alpha_ + alpha_*fp; \
216 --temp_factor_x; \
217 *temp_factor_x = ((*temp_factor_x) + fc); \
218 fp = fc; \
219 } \
220 } \
221 }
222
223 BILATERAL_H(uint8_t, byte)
224 BILATERAL_H(uint16_t, word)
225
226 #define BILATERAL_V(type, name) \
227 static void bilateralv_##name(BilateralContext *s, AVFrame *out, AVFrame *in, \
228 int jobnr, int nb_jobs, int plane) \
229 { \
230 const int width = s->planewidth[plane]; \
231 const int height = s->planeheight[plane]; \
232 const int slice_start = (width * jobnr) / nb_jobs; \
233 const int slice_end = (width * (jobnr+1)) / nb_jobs; \
234 const int src_linesize = in->linesize[plane] / sizeof(type); \
235 const type *src = (const type *)in->data[plane] + slice_start; \
236 float *img_out_f = s->img_out_f[plane] + slice_start; \
237 float *img_temp = s->img_temp[plane] + slice_start; \
238 float *map_factor_a = s->map_factor_a[plane] + slice_start; \
239 float *map_factor_b = s->map_factor_b[plane] + slice_start; \
240 float *slice_factor_a = s->slice_factor_a[plane] + slice_start; \
241 float *slice_factor_b = s->slice_factor_b[plane] + slice_start; \
242 float *line_factor_a = s->line_factor_a[plane] + slice_start; \
243 float *line_factor_b = s->line_factor_b[plane] + slice_start; \
244 const float *const range_table = s->range_table; \
245 const float alpha = s->alpha; \
246 float *ycy, *ypy, *xcy; \
247 const float inv_alpha_ = 1.f - alpha; \
248 float *ycf, *ypf, *xcf, *in_factor; \
249 const type *tcy, *tpy; \
250 int h1; \
251 \
252 memcpy(img_out_f, img_temp, sizeof(float) * (slice_end - slice_start)); \
253 \
254 in_factor = map_factor_a; \
255 memcpy(map_factor_b, in_factor, sizeof(float) * (slice_end - slice_start)); \
256 for (int y = 1; y < height; y++) { \
257 tpy = &src[(y - 1) * src_linesize]; \
258 tcy = &src[y * src_linesize]; \
259 xcy = &img_temp[y * width]; \
260 ypy = &img_out_f[(y - 1) * width]; \
261 ycy = &img_out_f[y * width]; \
262 \
263 xcf = &in_factor[y * width]; \
264 ypf = &map_factor_b[(y - 1) * width]; \
265 ycf = &map_factor_b[y * width]; \
266 for (int x = 0; x < slice_end - slice_start; x++) { \
267 type dr = abs((*tcy++) - (*tpy++)); \
268 int range_dist = dr; \
269 float alpha_ = range_table[range_dist]; \
270 \
271 *ycy++ = inv_alpha_*(*xcy++) + alpha_*(*ypy++); \
272 *ycf++ = inv_alpha_*(*xcf++) + alpha_*(*ypf++); \
273 } \
274 } \
275 h1 = height - 1; \
276 ycf = line_factor_a; \
277 ypf = line_factor_b; \
278 memcpy(ypf, &in_factor[h1 * width], sizeof(float) * (slice_end - slice_start)); \
279 for (int x = 0, k = 0; x < slice_end - slice_start; x++) \
280 map_factor_b[h1 * width + x] = (map_factor_b[h1 * width + x] + ypf[k++]); \
281 \
282 ycy = slice_factor_a; \
283 ypy = slice_factor_b; \
284 memcpy(ypy, &img_temp[h1 * width], sizeof(float) * (slice_end - slice_start)); \
285 for (int x = 0, k = 0; x < slice_end - slice_start; x++) { \
286 int idx = h1 * width + x; \
287 img_out_f[idx] = (img_out_f[idx] + ypy[k++]) / map_factor_b[h1 * width + x]; \
288 } \
289 \
290 for (int y = h1 - 1; y >= 0; y--) { \
291 float *ycf_, *ypf_, *factor_; \
292 float *ycy_, *ypy_, *out_; \
293 \
294 tpy = &src[(y + 1) * src_linesize]; \
295 tcy = &src[y * src_linesize]; \
296 xcy = &img_temp[y * width]; \
297 ycy_ = ycy; \
298 ypy_ = ypy; \
299 out_ = &img_out_f[y * width]; \
300 \
301 xcf = &in_factor[y * width]; \
302 ycf_ = ycf; \
303 ypf_ = ypf; \
304 factor_ = &map_factor_b[y * width]; \
305 for (int x = 0; x < slice_end - slice_start; x++) { \
306 type dr = abs((*tcy++) - (*tpy++)); \
307 int range_dist = dr; \
308 float alpha_ = range_table[range_dist]; \
309 float ycc, fcc = inv_alpha_*(*xcf++) + alpha_*(*ypf_++); \
310 \
311 *ycf_++ = fcc; \
312 *factor_ = (*factor_ + fcc); \
313 \
314 ycc = inv_alpha_*(*xcy++) + alpha_*(*ypy_++); \
315 *ycy_++ = ycc; \
316 *out_ = (*out_ + ycc) / (*factor_); \
317 out_++; \
318 factor_++; \
319 } \
320 \
321 ypy = ycy; \
322 ypf = ycf; \
323 } \
324 }
325
326 BILATERAL_V(uint8_t, byte)
327 BILATERAL_V(uint16_t, word)
328
329 #define BILATERAL_O(type, name) \
330 static void bilateralo_##name(BilateralContext *s, AVFrame *out, AVFrame *in, \
331 int jobnr, int nb_jobs, int plane) \
332 { \
333 const int width = s->planewidth[plane]; \
334 const int height = s->planeheight[plane]; \
335 const int slice_start = (height * jobnr) / nb_jobs; \
336 const int slice_end = (height * (jobnr+1)) / nb_jobs; \
337 const int dst_linesize = out->linesize[plane] / sizeof(type); \
338 \
339 for (int i = slice_start; i < slice_end; i++) { \
340 type *dst = (type *)out->data[plane] + i * dst_linesize; \
341 const float *const img_out_f = s->img_out_f[plane] + i * width; \
342 for (int j = 0; j < width; j++) \
343 dst[j] = lrintf(img_out_f[j]); \
344 } \
345 }
346
347 BILATERAL_O(uint8_t, byte)
348 BILATERAL_O(uint16_t, word)
349
350 static int bilateralh_planes(AVFilterContext *ctx, void *arg,
351 int jobnr, int nb_jobs)
352 {
353 BilateralContext *s = ctx->priv;
354 ThreadData *td = arg;
355 AVFrame *out = td->out;
356 AVFrame *in = td->in;
357
358 for (int plane = 0; plane < s->nb_planes; plane++) {
359 if (!(s->planes & (1 << plane)))
360 continue;
361
362 if (s->depth <= 8)
363 bilateralh_byte(s, out, in, jobnr, nb_jobs, plane);
364 else
365 bilateralh_word(s, out, in, jobnr, nb_jobs, plane);
366 }
367
368 return 0;
369 }
370
371 static int bilateralv_planes(AVFilterContext *ctx, void *arg,
372 int jobnr, int nb_jobs)
373 {
374 BilateralContext *s = ctx->priv;
375 ThreadData *td = arg;
376 AVFrame *out = td->out;
377 AVFrame *in = td->in;
378
379 for (int plane = 0; plane < s->nb_planes; plane++) {
380 if (!(s->planes & (1 << plane)))
381 continue;
382
383 if (s->depth <= 8)
384 bilateralv_byte(s, out, in, jobnr, nb_jobs, plane);
385 else
386 bilateralv_word(s, out, in, jobnr, nb_jobs, plane);
387 }
388
389 return 0;
390 }
391
392 static int bilateralo_planes(AVFilterContext *ctx, void *arg,
393 int jobnr, int nb_jobs)
394 {
395 BilateralContext *s = ctx->priv;
396 ThreadData *td = arg;
397 AVFrame *out = td->out;
398 AVFrame *in = td->in;
399
400 for (int plane = 0; plane < s->nb_planes; plane++) {
401 if (!(s->planes & (1 << plane))) {
402 if (out != in) {
403 const int height = s->planeheight[plane];
404 const int slice_start = (height * jobnr) / nb_jobs;
405 const int slice_end = (height * (jobnr+1)) / nb_jobs;
406 const int width = s->planewidth[plane];
407 const int linesize = in->linesize[plane];
408 const int dst_linesize = out->linesize[plane];
409 const uint8_t *src = in->data[plane];
410 uint8_t *dst = out->data[plane];
411
412 av_image_copy_plane(dst + slice_start * dst_linesize,
413 dst_linesize,
414 src + slice_start * linesize,
415 linesize,
416 width * ((s->depth + 7) / 8),
417 slice_end - slice_start);
418 }
419 continue;
420 }
421
422 if (s->depth <= 8)
423 bilateralo_byte(s, out, in, jobnr, nb_jobs, plane);
424 else
425 bilateralo_word(s, out, in, jobnr, nb_jobs, plane);
426 }
427
428 return 0;
429 }
430
431 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
432 {
433 AVFilterContext *ctx = inlink->dst;
434 BilateralContext *s = ctx->priv;
435 AVFilterLink *outlink = ctx->outputs[0];
436 ThreadData td;
437 AVFrame *out;
438
439 if (av_frame_is_writable(in)) {
440 out = in;
441 } else {
442 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
443 if (!out) {
444 av_frame_free(&in);
445 return AVERROR(ENOMEM);
446 }
447 av_frame_copy_props(out, in);
448 }
449
450 td.in = in;
451 td.out = out;
452 ff_filter_execute(ctx, bilateralh_planes, &td, NULL, s->nb_threads);
453 ff_filter_execute(ctx, bilateralv_planes, &td, NULL, s->nb_threads);
454 ff_filter_execute(ctx, bilateralo_planes, &td, NULL, s->nb_threads);
455
456 if (out != in)
457 av_frame_free(&in);
458 return ff_filter_frame(outlink, out);
459 }
460
461 static av_cold void uninit(AVFilterContext *ctx)
462 {
463 BilateralContext *s = ctx->priv;
464
465 for (int p = 0; p < s->nb_planes; p++) {
466 av_freep(&s->img_out_f[p]);
467 av_freep(&s->img_temp[p]);
468 av_freep(&s->map_factor_a[p]);
469 av_freep(&s->map_factor_b[p]);
470 av_freep(&s->slice_factor_a[p]);
471 av_freep(&s->slice_factor_b[p]);
472 av_freep(&s->line_factor_a[p]);
473 av_freep(&s->line_factor_b[p]);
474 }
475 }
476
477 static int process_command(AVFilterContext *ctx,
478 const char *cmd,
479 const char *arg,
480 char *res,
481 int res_len,
482 int flags)
483 {
484 int ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags);
485
486 if (ret < 0)
487 return ret;
488
489 return config_params(ctx);
490 }
491
492 static const AVFilterPad bilateral_inputs[] = {
493 {
494 .name = "default",
495 .type = AVMEDIA_TYPE_VIDEO,
496 .config_props = config_input,
497 .filter_frame = filter_frame,
498 },
499 };
500
501 const FFFilter ff_vf_bilateral = {
502 .p.name = "bilateral",
503 .p.description = NULL_IF_CONFIG_SMALL("Apply Bilateral filter."),
504 .p.priv_class = &bilateral_class,
505 .p.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
506 AVFILTER_FLAG_SLICE_THREADS,
507 .priv_size = sizeof(BilateralContext),
508 .uninit = uninit,
509 FILTER_INPUTS(bilateral_inputs),
510 FILTER_OUTPUTS(ff_video_default_filterpad),
511 FILTER_PIXFMTS_ARRAY(pix_fmts),
512 .process_command = process_command,
513 };
514

南屏晚钟什么意思 准妈妈是什么意思 半夜胎动频繁是什么原因 欧盟是什么 知了喜欢吃什么
领导谈话自己该说什么 前列腺有什么作用 queen是什么意思 免去职务是什么意思 午五行属什么
喝黑豆浆有什么好处 尿多是什么原因引起的 家庭养什么狗最干净 金命适合什么颜色 什么地溜达
火烈鸟吃什么 女人的秘密是什么 乙肝五项245阳性是什么意思 海扶治疗是什么 流浓黄鼻涕是什么原因
海虾不能和什么一起吃qingzhougame.com 晕倒是什么原因引起的hcv9jop0ns0r.cn 肌钙蛋白低说明什么hcv8jop7ns5r.cn 短阵房速是什么意思hcv8jop8ns1r.cn 一段奶粉和二段奶粉有什么区别hcv9jop5ns2r.cn
什么牌子的裤子质量好hcv8jop6ns4r.cn 三花五罗都是什么鱼dajiketang.com 蚕长什么样hcv8jop9ns2r.cn 小孩手指脱皮是什么原因hcv9jop3ns7r.cn 毓婷是什么hcv9jop4ns3r.cn
男戴观音女戴佛有什么讲究hcv8jop8ns3r.cn 马桶对着卫生间门有什么不好huizhijixie.com 困水是什么意思wuhaiwuya.com 手指上的斗和簸箕代表什么意思hcv8jop5ns6r.cn 苦荞茶有什么作用hcv9jop4ns7r.cn
子宫长什么样hcv8jop0ns1r.cn N1是什么hcv9jop0ns9r.cn 向日葵什么时候播种0735v.com mj什么意思hcv8jop9ns0r.cn 萧何字什么hcv8jop9ns5r.cn
百度