回乡偶书的偶书是什么意思| 一望无际是什么意思| 鱼和熊掌不可兼得什么意思| 西瓜什么样的好吃| 特别是什么意思| 为什么医生爱开喜炎平| 什么叫慢性萎缩性胃炎| 春季感冒吃什么药| soso什么意思| 便血挂什么科室| 消瘦是什么意思| 菊花像什么| 食欲不振是什么原因| 属猪的跟什么属相最配| 鬼子来了为什么被禁| 八婆什么意思| 睡午觉有什么好处| azul是什么颜色| 8.1是什么星座| 肌层回声均匀是什么意思| 血糖高是什么原因引起的| 肠炎吃什么药最好| 无名指和小指发麻是什么原因| 红斑狼疮是什么| 鹰嘴桃什么时候成熟| 知己什么意思| 小孩血压低是什么原因| 打喷嚏代表什么| 一个斤一个页念什么| 青豆是什么豆| 什么叫ins风格| 升是什么意思| 拉分是什么意思| 真菌涂片检查是查什么| 早餐吃什么最健康| 做b超可以检查出什么| 孩子发烧肚子疼是什么原因| 尿素肌酐高是什么原因| 维生素b是补什么的| 木加一笔变成什么字| 彩超能检查什么| 对峙什么意思| 回民不吃什么| 大面积杀跳蚤用什么药| 尿胆原是什么| 子宫肌腺症是什么病| 百香果的籽有什么功效| 恶心想吐胃不舒服是什么原因| 海绵是什么材料做的| 什么命要承受丧子之痛| 安宫牛黄丸有什么作用| 出现幻觉幻听是什么心理疾病| 小狗感冒吃什么药| 医院可以点痣吗挂什么科| 肌无力是什么症状| 情绪是什么意思| 传宗接代是什么意思| 勃起困难是什么原因造成的| 梦见拉麦子是什么预兆| 国代是什么意思| 女人不排卵是什么原因造成的| 绿豆和什么相克中毒| 男性全身皮肤瘙痒是什么原因| 次元是什么意思| 堪称什么意思| cba什么意思| 散片是什么意思| 带状疱疹后遗神经痛挂什么科| 走马观花是什么生肖| 足内翻是什么样子的| 七里香是什么| 包皮痒用什么药| 为什么感觉| 五脏主什么| 什么军官可以随身配枪| 佛跳墙是什么东西| 丧偶是什么意思| 下午三点到五点是什么时辰| 拉肚子是什么原因导致的| AC是胎儿的什么意思| 衬衫配什么裤子好看| 女人为什么比男人长寿| 舌苔白厚是什么原因| cns医学上是什么意思| 吃藕粉对身体有什么好处| 合菜是什么| 肾结石能吃什么水果| 雍正为什么不杀十阿哥| 豇豆不能和什么一起吃| alpha什么意思| shy是什么意思| 2025年是什么命| 黄姜长什么样图片| mdz0.2是什么药| 为什么老是口腔溃疡| 结核感染是什么意思| 在五行中属什么| 木棉花的花语是什么| 心花怒放是什么生肖| 太虚是什么意思| 羊蛋是什么| b超检查前要注意什么| 台卡是什么| 一花一世界下一句是什么| 威胁是什么意思| 纳采是什么意思| 赵云字什么| 紫茉莉什么时候开花| 高什么远什么| 什么是前鼻音和后鼻音| 无声无息是什么意思| 什么是速写| 斐然是什么意思| 咳嗽可以吃什么水果| 缺爱是什么意思| 血气是什么意思| 红萝卜不能和什么一起吃| 榴莲为什么苦| 一鸣惊人指什么动物| 彩蛋是什么意思| 干眼症是什么原因引起的| 限行是什么意思| 巨细胞病毒是什么| 阴唇为什么一个大一个小| 荡秋千有什么好处| 月经期间吃什么补血| 看心脏病挂什么科| rush是什么意思| 喝生鸡蛋有什么好处| 精力旺盛是什么意思| 官鬼是什么意思| 什么人不能吃韭菜| 血糖偏高吃什么食物好| 肠结核是什么病| k2是什么| 额头长痘是什么原因| 正师级是什么军衔| ggdb是什么牌子| 被香灰烫了预示着什么| 投射效应是什么意思| 花洒不出水什么原因| 腿上有白点是什么原因| 90年属什么生肖| 弄璋之喜是什么意思| 令是什么生肖| 鼻窦炎长什么样图片| 腥是什么意思| 乙肝核心抗体偏高是什么意思| 什么克风| 额头炎是什么症状| bj是什么意思| 糖尿病人不能吃什么水果| 狗的尾巴有什么作用| 额头爱出汗是什么原因| 蟾蜍是什么| 前程无量是什么意思| 脑管瘤的症状是什么| 什么叫外阴白斑| 情有独钟什么意思| 狗屎运是什么意思| 隔应是什么意思| 虱子长什么样| 低压太低是什么原因| 脚水肿是什么原因引起的| 女人为什么会患得患失| 吃什么消炎药可以喝酒| 脾气虚吃什么药| 四大皆空是什么意思| 九月什么星座| 世界大同是什么意思| instagram是什么软件| 手背发黄是什么原因| 十二月二号是什么星座| 副军长是什么军衔| 什么的什么好吃| 读书有什么好处| 宫颈萎缩意味着什么| 扪是什么意思| 大拇指指甲凹陷是什么原因| 火腿是什么肉| 不知不觉是什么意思| 吃丹参有什么好处| 孩子呼吸道感染吃什么药效果最好| 伏羲和女娲是什么关系| 阿尔兹海默症是什么病| 颈椎病用什么药最好| 移车打什么电话| 发烧白细胞高是什么原因| 胃病吃什么药最好| 高五行属什么| 金项链断了有什么预兆| 赵国是现在的什么地方| 银杏是什么| 烧心胃酸吃什么药| 下午五点到七点是什么时辰| 阴蒂痒是什么原因| 运动员为什么吃香蕉| 肩膀骨头响是什么原因| 为什么叫天津卫| 经常拉屎是什么原因| 为什么会长疣| 胰岛素是什么器官分泌的| 糖尿病2型是什么意思| 荆轲姓什么| p波代表什么| 睡前喝蜂蜜水有什么好处| 数字7的风水含义是什么| 谷氨酸高是什么原因| 真好是什么意思| 嘴角烂是什么原因| 眼压高是什么原因造成的| 教师节贺卡上写什么| 婴儿什么时候可以吃盐| 尿素氮肌酐比值偏高是什么原因| chb是什么意思| 检查头部挂什么科| 病毒性扁桃体炎吃什么药| 梦见自己牙齿掉了是什么意思| 防晒衣什么品牌好| 血小板是什么| 红枣桂圆泡水喝有什么好处和坏处| 冥寿是什么意思| 吃羊肉不能和什么一起吃| 依依不舍的依依是什么意思| 花甲炒什么配菜好吃| 偶尔失眠是什么原因| tiamo是什么意思| 瘢痕子宫什么意思| 曹操属什么生肖| 蛋清加蜂蜜敷脸有什么好处| 毛孔粗大是什么原因引起的| 小便粉红色是什么原因| 积食吃什么食物帮助消化| 维生素d低是什么原因| 头发长不长是什么原因怎么办| 白细胞偏高说明什么| 卵巢检查做什么项目| 肋骨外翻有什么危害| 勃艮第红是什么颜色| 潜阳是什么意思| 狗狗感冒了是什么症状| 睾丸扭转有什么症状| 日柱灾煞是什么意思| 胎儿脉络丛囊肿是什么原因引起的| cdc是什么| 花团锦簇什么意思| 子时是什么时候| 手肿脚肿是什么原因引起的| 扁桃体发炎了吃什么药| 5月20号是什么星座| gjb2基因杂合突变是什么意思| 火命人适合什么颜色| 防血栓是什么意思| 水烟是什么| 嘴唇紫色是什么原因| 反目成仇是什么意思| 二型血糖高吃什么药好| 温饱是什么意思| 山对什么| 糖五行属什么| 白介素是什么| 孕妇可以吃什么感冒药| hpv疫苗是什么疫苗| 1989年属什么生肖| 百度

构建“东城文艺大格局” 激发基层文联新活力


Directory: ../../../ffmpeg/
File: src/libavfilter/vf_waveform.c
Date: 2025-08-04 00:43:16
Exec Total Coverage
Lines: 298 1659 18.0%
Functions: 13 110 11.8%
Branches: 168 1715 9.8%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2012-2016 Paul B Mahol
3 * Copyright (c) 2013 Marton Balint
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/pixdesc.h"
25 #include "libavutil/xga_font_data.h"
26 #include "avfilter.h"
27 #include "filters.h"
28 #include "formats.h"
29 #include "video.h"
30
31 typedef struct ThreadData {
32 AVFrame *in;
33 AVFrame *out;
34 int component;
35 int offset_y;
36 int offset_x;
37 } ThreadData;
38
39 enum FitMode {
40 FM_NONE,
41 FM_SIZE,
42 NB_FITMODES
43 };
44
45 enum FilterType {
46 LOWPASS,
47 FLAT,
48 AFLAT,
49 CHROMA,
50 COLOR,
51 ACOLOR,
52 XFLAT,
53 YFLAT,
54 NB_FILTERS
55 };
56
57 enum DisplayType {
58 OVERLAY,
59 STACK,
60 PARADE,
61 NB_DISPLAYS
62 };
63
64 enum ScaleType {
65 DIGITAL,
66 MILLIVOLTS,
67 IRE,
68 NB_SCALES
69 };
70
71 enum GraticuleType {
72 GRAT_NONE,
73 GRAT_GREEN,
74 GRAT_ORANGE,
75 GRAT_INVERT,
76 NB_GRATICULES
77 };
78
79 typedef struct GraticuleLine {
80 const char *name;
81 uint16_t pos;
82 } GraticuleLine;
83
84 typedef struct GraticuleLines {
85 struct GraticuleLine line[4];
86 } GraticuleLines;
87
88 typedef struct WaveformContext {
89 const AVClass *class;
90 int mode;
91 int acomp;
92 int dcomp;
93 int ncomp;
94 int pcomp;
95 uint8_t bg_color[4];
96 float fintensity;
97 int intensity;
98 int mirror;
99 int display;
100 int envelope;
101 int graticule;
102 float opacity;
103 float bgopacity;
104 int estart[4];
105 int eend[4];
106 int *emax[4][4];
107 int *emin[4][4];
108 int *peak;
109 int filter;
110 int flags;
111 int bits;
112 int max;
113 int size;
114 int scale;
115 uint8_t grat_yuva_color[4];
116 int shift_w[4], shift_h[4];
117 GraticuleLines *glines;
118 int nb_glines;
119 int rgb;
120 float ftint[2];
121 int tint[2];
122 int fitmode;
123 int input;
124
125 int (*waveform_slice)(AVFilterContext *ctx, void *arg,
126 int jobnr, int nb_jobs);
127 void (*graticulef)(struct WaveformContext *s, AVFrame *out);
128 void (*blend_line)(uint8_t *dst, int size, int linesize, float o1, float o2,
129 int v, int step);
130 void (*draw_text)(AVFrame *out, int x, int y, int mult,
131 float o1, float o2, const char *txt,
132 const uint8_t color[4]);
133 const AVPixFmtDescriptor *desc;
134 const AVPixFmtDescriptor *odesc;
135 } WaveformContext;
136
137 #define OFFSET(x) offsetof(WaveformContext, x)
138 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
139 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
140
141 static const AVOption waveform_options[] = {
142 { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, .unit = "mode" },
143 { "m", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, .unit = "mode" },
144 { "row", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "mode" },
145 { "column", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "mode" },
146 { "intensity", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 1, TFLAGS },
147 { "i", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 1, TFLAGS },
148 { "mirror", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
149 { "r", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
150 { "display", "set display mode", OFFSET(display), AV_OPT_TYPE_INT, {.i64=STACK}, 0, NB_DISPLAYS-1, FLAGS, .unit = "display" },
151 { "d", "set display mode", OFFSET(display), AV_OPT_TYPE_INT, {.i64=STACK}, 0, NB_DISPLAYS-1, FLAGS, .unit = "display" },
152 { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY}, 0, 0, FLAGS, .unit = "display" },
153 { "stack", NULL, 0, AV_OPT_TYPE_CONST, {.i64=STACK}, 0, 0, FLAGS, .unit = "display" },
154 { "parade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PARADE}, 0, 0, FLAGS, .unit = "display" },
155 { "components", "set components to display", OFFSET(pcomp), AV_OPT_TYPE_INT, {.i64=1}, 1, 15, FLAGS },
156 { "c", "set components to display", OFFSET(pcomp), AV_OPT_TYPE_INT, {.i64=1}, 1, 15, FLAGS },
157 { "envelope", "set envelope to display", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, TFLAGS, .unit = "envelope" },
158 { "e", "set envelope to display", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, TFLAGS, .unit = "envelope" },
159 { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, TFLAGS, .unit = "envelope" },
160 { "instant", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, TFLAGS, .unit = "envelope" },
161 { "peak", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, TFLAGS, .unit = "envelope" },
162 { "peak+instant", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, TFLAGS, .unit = "envelope" },
163 { "filter", "set filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FILTERS-1, FLAGS, .unit = "filter" },
164 { "f", "set filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FILTERS-1, FLAGS, .unit = "filter" },
165 { "lowpass", NULL, 0, AV_OPT_TYPE_CONST, {.i64=LOWPASS}, 0, 0, FLAGS, .unit = "filter" },
166 { "flat" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=FLAT}, 0, 0, FLAGS, .unit = "filter" },
167 { "aflat" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=AFLAT}, 0, 0, FLAGS, .unit = "filter" },
168 { "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=CHROMA}, 0, 0, FLAGS, .unit = "filter" },
169 { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=COLOR}, 0, 0, FLAGS, .unit = "filter" },
170 { "acolor", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ACOLOR}, 0, 0, FLAGS, .unit = "filter" },
171 { "xflat", NULL, 0, AV_OPT_TYPE_CONST, {.i64=XFLAT}, 0, 0, FLAGS, .unit = "filter" },
172 { "yflat", NULL, 0, AV_OPT_TYPE_CONST, {.i64=YFLAT}, 0, 0, FLAGS, .unit = "filter" },
173 { "graticule", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_GRATICULES-1, FLAGS, .unit = "graticule" },
174 { "g", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_GRATICULES-1, FLAGS, .unit = "graticule" },
175 { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_NONE}, 0, 0, FLAGS, .unit = "graticule" },
176 { "green", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_GREEN}, 0, 0, FLAGS, .unit = "graticule" },
177 { "orange", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_ORANGE}, 0, 0, FLAGS, .unit = "graticule" },
178 { "invert", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_INVERT}, 0, 0, FLAGS, .unit = "graticule" },
179 { "opacity", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, TFLAGS },
180 { "o", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, TFLAGS },
181 { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=1}, 0, 3, TFLAGS, .unit = "flags" },
182 { "fl", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=1}, 0, 3, TFLAGS, .unit = "flags" },
183 { "numbers", "draw numbers", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, TFLAGS, .unit = "flags" },
184 { "dots", "draw dots instead of lines", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, TFLAGS, .unit = "flags" },
185 { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_SCALES-1, FLAGS, .unit = "scale" },
186 { "s", "set scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_SCALES-1, FLAGS, .unit = "scale" },
187 { "digital", NULL, 0, AV_OPT_TYPE_CONST, {.i64=DIGITAL}, 0, 0, FLAGS, .unit = "scale" },
188 { "millivolts", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MILLIVOLTS}, 0, 0, FLAGS, .unit = "scale" },
189 { "ire", NULL, 0, AV_OPT_TYPE_CONST, {.i64=IRE}, 0, 0, FLAGS, .unit = "scale" },
190 { "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, TFLAGS },
191 { "b", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, TFLAGS },
192 { "tint0", "set 1st tint", OFFSET(ftint[0]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
193 { "t0", "set 1st tint", OFFSET(ftint[0]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
194 { "tint1", "set 2nd tint", OFFSET(ftint[1]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
195 { "t1", "set 2nd tint", OFFSET(ftint[1]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
196 { "fitmode", "set fit mode", OFFSET(fitmode), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FITMODES-1, FLAGS, .unit = "fitmode" },
197 { "fm", "set fit mode", OFFSET(fitmode), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FITMODES-1, FLAGS, .unit = "fitmode" },
198 { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_NONE}, 0, 0, FLAGS, .unit = "fitmode" },
199 { "size", NULL, 0, AV_OPT_TYPE_CONST, {.i64=FM_SIZE}, 0, 0, FLAGS, .unit = "fitmode" },
200 { "input", "set input formats selection", OFFSET(input), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, .unit = "input" },
201 { "all", "try to select from all available formats", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "input" },
202 { "first", "pick first available format", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "input" },
203 { NULL }
204 };
205
206 AVFILTER_DEFINE_CLASS(waveform);
207
208 static const enum AVPixelFormat in_lowpass_pix_fmts[] = {
209 AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
210 AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12,
211 AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
212 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P,
213 AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
214 AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P,
215 AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
216 AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
217 AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12,
218 AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9,
219 AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9,
220 AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10,
221 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10,
222 AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV440P12,
223 AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA422P12,
224 AV_PIX_FMT_NONE
225 };
226
227 static const enum AVPixelFormat in_color_pix_fmts[] = {
228 AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
229 AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12,
230 AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
231 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P,
232 AV_PIX_FMT_YUV411P,
233 AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P,
234 AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
235 AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
236 AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9,
237 AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9,
238 AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10,
239 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10,
240 AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV440P12,
241 AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA422P12,
242 AV_PIX_FMT_NONE
243 };
244
245 static const enum AVPixelFormat in_flat_pix_fmts[] = {
246 AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
247 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P,
248 AV_PIX_FMT_YUV411P,
249 AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P,
250 AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
251 AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
252 AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9,
253 AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9,
254 AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10,
255 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10,
256 AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV440P12,
257 AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA422P12,
258 AV_PIX_FMT_NONE
259 };
260
261 static const enum AVPixelFormat out_rgb8_lowpass_pix_fmts[] = {
262 AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
263 AV_PIX_FMT_NONE
264 };
265
266 static const enum AVPixelFormat out_rgb9_lowpass_pix_fmts[] = {
267 AV_PIX_FMT_GBRP9,
268 AV_PIX_FMT_NONE
269 };
270
271 static const enum AVPixelFormat out_rgb10_lowpass_pix_fmts[] = {
272 AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
273 AV_PIX_FMT_NONE
274 };
275
276 static const enum AVPixelFormat out_rgb12_lowpass_pix_fmts[] = {
277 AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
278 AV_PIX_FMT_NONE
279 };
280
281 static const enum AVPixelFormat out_yuv8_lowpass_pix_fmts[] = {
282 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVA444P,
283 AV_PIX_FMT_NONE
284 };
285
286 static const enum AVPixelFormat out_yuv9_lowpass_pix_fmts[] = {
287 AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUVA444P9,
288 AV_PIX_FMT_NONE
289 };
290
291 static const enum AVPixelFormat out_yuv10_lowpass_pix_fmts[] = {
292 AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10,
293 AV_PIX_FMT_NONE
294 };
295
296 static const enum AVPixelFormat out_yuv12_lowpass_pix_fmts[] = {
297 AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUVA444P12,
298 AV_PIX_FMT_NONE
299 };
300
301 static const enum AVPixelFormat out_gray8_lowpass_pix_fmts[] = {
302 AV_PIX_FMT_GRAY8,
303 AV_PIX_FMT_NONE
304 };
305
306 static const enum AVPixelFormat out_gray9_lowpass_pix_fmts[] = {
307 AV_PIX_FMT_GRAY9,
308 AV_PIX_FMT_NONE
309 };
310
311 static const enum AVPixelFormat out_gray10_lowpass_pix_fmts[] = {
312 AV_PIX_FMT_GRAY10,
313 AV_PIX_FMT_NONE
314 };
315
316 static const enum AVPixelFormat out_gray12_lowpass_pix_fmts[] = {
317 AV_PIX_FMT_GRAY12,
318 AV_PIX_FMT_NONE
319 };
320
321 8 static int query_formats(AVFilterContext *ctx)
322 {
323 8 WaveformContext *s = ctx->priv;
324 const enum AVPixelFormat *out_pix_fmts;
325 const enum AVPixelFormat *in_pix_fmts;
326 const AVPixFmtDescriptor *desc, *desc2;
327 AVFilterFormats *avff, *avff2;
328 int depth, depth2, rgb, i, ret, ncomp, ncomp2;
329
330
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (!ctx->inputs[0]->incfg.formats ||
331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 !ctx->inputs[0]->incfg.formats->nb_formats) {
332 4 return AVERROR(EAGAIN);
333 }
334
335
1/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 switch (s->filter) {
336 4 case LOWPASS: in_pix_fmts = in_lowpass_pix_fmts; break;
337 case CHROMA:
338 case XFLAT:
339 case YFLAT:
340 case AFLAT:
341 case FLAT: in_pix_fmts = in_flat_pix_fmts; break;
342 case ACOLOR:
343 case COLOR: in_pix_fmts = in_color_pix_fmts; break;
344 default: return AVERROR_BUG;
345 }
346
347
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!ctx->inputs[0]->outcfg.formats) {
348
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0)
349 return ret;
350 }
351
352 4 avff = ctx->inputs[0]->incfg.formats;
353 4 avff2 = ctx->inputs[0]->outcfg.formats;
354 4 desc = av_pix_fmt_desc_get(avff->formats[0]);
355 4 desc2 = av_pix_fmt_desc_get(avff2->formats[0]);
356 4 ncomp = desc->nb_components;
357 4 ncomp2 = desc2->nb_components;
358 4 rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
359 4 depth = desc->comp[0].depth;
360 4 depth2 = desc2->comp[0].depth;
361
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (ncomp != ncomp2 || depth != depth2)
362 return AVERROR(EAGAIN);
363
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 for (i = 1; i < avff->nb_formats && !s->input; i++) {
364 desc = av_pix_fmt_desc_get(avff->formats[i]);
365 if (rgb != (desc->flags & AV_PIX_FMT_FLAG_RGB) ||
366 depth != desc->comp[0].depth)
367 return AVERROR(EAGAIN);
368 }
369
370
2/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if (s->filter == LOWPASS && ncomp == 1 && depth == 8)
371 out_pix_fmts = out_gray8_lowpass_pix_fmts;
372
2/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 else if (s->filter == LOWPASS && ncomp == 1 && depth == 9)
373 out_pix_fmts = out_gray9_lowpass_pix_fmts;
374
2/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 else if (s->filter == LOWPASS && ncomp == 1 && depth == 10)
375 out_pix_fmts = out_gray10_lowpass_pix_fmts;
376
2/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 else if (s->filter == LOWPASS && ncomp == 1 && depth == 12)
377 out_pix_fmts = out_gray12_lowpass_pix_fmts;
378
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 else if (rgb && depth == 8 && ncomp > 2)
379 out_pix_fmts = out_rgb8_lowpass_pix_fmts;
380
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 else if (rgb && depth == 9 && ncomp > 2)
381 out_pix_fmts = out_rgb9_lowpass_pix_fmts;
382
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 else if (rgb && depth == 10 && ncomp > 2)
383 out_pix_fmts = out_rgb10_lowpass_pix_fmts;
384
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 else if (rgb && depth == 12 && ncomp > 2)
385 out_pix_fmts = out_rgb12_lowpass_pix_fmts;
386
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 else if (depth == 8 && ncomp > 2)
387 4 out_pix_fmts = out_yuv8_lowpass_pix_fmts;
388 else if (depth == 9 && ncomp > 2)
389 out_pix_fmts = out_yuv9_lowpass_pix_fmts;
390 else if (depth == 10 && ncomp > 2)
391 out_pix_fmts = out_yuv10_lowpass_pix_fmts;
392 else if (depth == 12 && ncomp > 2)
393 out_pix_fmts = out_yuv12_lowpass_pix_fmts;
394 else
395 return AVERROR(EAGAIN);
396
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0)
397 return ret;
398
399 4 return 0;
400 }
401
402 static void envelope_instant16(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
403 {
404 const int dst_linesize = out->linesize[component] / 2;
405 const int bg = s->bg_color[component] * (s->max / 256);
406 const int limit = s->max - 1;
407 const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
408 const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
409 const int start = s->estart[plane];
410 const int end = s->eend[plane];
411 uint16_t *dst;
412 int x, y;
413
414 if (s->mode) {
415 for (x = offset; x < offset + dst_w; x++) {
416 for (y = start; y < end; y++) {
417 dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
418 if (dst[0] != bg) {
419 dst[0] = limit;
420 break;
421 }
422 }
423 for (y = end - 1; y >= start; y--) {
424 dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
425 if (dst[0] != bg) {
426 dst[0] = limit;
427 break;
428 }
429 }
430 }
431 } else {
432 for (y = offset; y < offset + dst_h; y++) {
433 dst = (uint16_t *)out->data[component] + y * dst_linesize;
434 for (x = start; x < end; x++) {
435 if (dst[x] != bg) {
436 dst[x] = limit;
437 break;
438 }
439 }
440 for (x = end - 1; x >= start; x--) {
441 if (dst[x] != bg) {
442 dst[x] = limit;
443 break;
444 }
445 }
446 }
447 }
448 }
449
450 50 static void envelope_instant(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
451 {
452 50 const int dst_linesize = out->linesize[component];
453 50 const uint8_t bg = s->bg_color[component];
454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
455
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
456 50 const int start = s->estart[plane];
457 50 const int end = s->eend[plane];
458 uint8_t *dst;
459 int x, y;
460
461
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 if (s->mode) {
462
2/2
✓ Branch 0 taken 17600 times.
✓ Branch 1 taken 50 times.
17650 for (x = offset; x < offset + dst_w; x++) {
463
1/2
✓ Branch 0 taken 375540 times.
✗ Branch 1 not taken.
375540 for (y = start; y < end; y++) {
464 375540 dst = out->data[component] + y * dst_linesize + x;
465
2/2
✓ Branch 0 taken 17600 times.
✓ Branch 1 taken 357940 times.
375540 if (dst[0] != bg) {
466 17600 dst[0] = 255;
467 17600 break;
468 }
469 }
470
1/2
✓ Branch 0 taken 385656 times.
✗ Branch 1 not taken.
385656 for (y = end - 1; y >= start; y--) {
471 385656 dst = out->data[component] + y * dst_linesize + x;
472
2/2
✓ Branch 0 taken 17600 times.
✓ Branch 1 taken 368056 times.
385656 if (dst[0] != bg) {
473 17600 dst[0] = 255;
474 17600 break;
475 }
476 }
477 }
478 } else {
479 for (y = offset; y < offset + dst_h; y++) {
480 dst = out->data[component] + y * dst_linesize;
481 for (x = start; x < end; x++) {
482 if (dst[x] != bg) {
483 dst[x] = 255;
484 break;
485 }
486 }
487 for (x = end - 1; x >= start; x--) {
488 if (dst[x] != bg) {
489 dst[x] = 255;
490 break;
491 }
492 }
493 }
494 }
495 50 }
496
497 static void envelope_peak16(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
498 {
499 const int dst_linesize = out->linesize[component] / 2;
500 const int bg = s->bg_color[component] * (s->max / 256);
501 const int limit = s->max - 1;
502 const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
503 const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
504 const int start = s->estart[plane];
505 const int end = s->eend[plane];
506 int *emax = s->emax[plane][component];
507 int *emin = s->emin[plane][component];
508 uint16_t *dst;
509 int x, y;
510
511 if (s->mode) {
512 for (x = offset; x < offset + dst_w; x++) {
513 for (y = start; y < end && y < emin[x - offset]; y++) {
514 dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
515 if (dst[0] != bg) {
516 emin[x - offset] = y;
517 break;
518 }
519 }
520 for (y = end - 1; y >= start && y >= emax[x - offset]; y--) {
521 dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
522 if (dst[0] != bg) {
523 emax[x - offset] = y;
524 break;
525 }
526 }
527 }
528
529 if (s->envelope == 3)
530 envelope_instant16(s, out, plane, component, offset);
531
532 for (x = offset; x < offset + dst_w; x++) {
533 dst = (uint16_t *)out->data[component] + emin[x - offset] * dst_linesize + x;
534 dst[0] = limit;
535 dst = (uint16_t *)out->data[component] + emax[x - offset] * dst_linesize + x;
536 dst[0] = limit;
537 }
538 } else {
539 for (y = offset; y < offset + dst_h; y++) {
540 dst = (uint16_t *)out->data[component] + y * dst_linesize;
541 for (x = start; x < end && x < emin[y - offset]; x++) {
542 if (dst[x] != bg) {
543 emin[y - offset] = x;
544 break;
545 }
546 }
547 for (x = end - 1; x >= start && x >= emax[y - offset]; x--) {
548 if (dst[x] != bg) {
549 emax[y - offset] = x;
550 break;
551 }
552 }
553 }
554
555 if (s->envelope == 3)
556 envelope_instant16(s, out, plane, component, offset);
557
558 for (y = offset; y < offset + dst_h; y++) {
559 dst = (uint16_t *)out->data[component] + y * dst_linesize + emin[y - offset];
560 dst[0] = limit;
561 dst = (uint16_t *)out->data[component] + y * dst_linesize + emax[y - offset];
562 dst[0] = limit;
563 }
564 }
565 }
566
567 50 static void envelope_peak(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
568 {
569 50 const int dst_linesize = out->linesize[component];
570 50 const int bg = s->bg_color[component];
571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
573 50 const int start = s->estart[plane];
574 50 const int end = s->eend[plane];
575 50 int *emax = s->emax[plane][component];
576 50 int *emin = s->emin[plane][component];
577 uint8_t *dst;
578 int x, y;
579
580
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 if (s->mode) {
581
2/2
✓ Branch 0 taken 17600 times.
✓ Branch 1 taken 50 times.
17650 for (x = offset; x < offset + dst_w; x++) {
582
3/4
✓ Branch 0 taken 152559 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 136288 times.
✓ Branch 3 taken 16271 times.
152559 for (y = start; y < end && y < emin[x - offset]; y++) {
583 136288 dst = out->data[component] + y * dst_linesize + x;
584
2/2
✓ Branch 0 taken 1329 times.
✓ Branch 1 taken 134959 times.
136288 if (dst[0] != bg) {
585 1329 emin[x - offset] = y;
586 1329 break;
587 }
588 }
589
3/4
✓ Branch 0 taken 159188 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144269 times.
✓ Branch 3 taken 14919 times.
159188 for (y = end - 1; y >= start && y >= emax[x - offset]; y--) {
590 144269 dst = out->data[component] + y * dst_linesize + x;
591
2/2
✓ Branch 0 taken 2681 times.
✓ Branch 1 taken 141588 times.
144269 if (dst[0] != bg) {
592 2681 emax[x - offset] = y;
593 2681 break;
594 }
595 }
596 }
597
598
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 if (s->envelope == 3)
599 50 envelope_instant(s, out, plane, component, offset);
600
601
2/2
✓ Branch 0 taken 17600 times.
✓ Branch 1 taken 50 times.
17650 for (x = offset; x < offset + dst_w; x++) {
602 17600 dst = out->data[component] + emin[x - offset] * dst_linesize + x;
603 17600 dst[0] = 255;
604 17600 dst = out->data[component] + emax[x - offset] * dst_linesize + x;
605 17600 dst[0] = 255;
606 }
607 } else {
608 for (y = offset; y < offset + dst_h; y++) {
609 dst = out->data[component] + y * dst_linesize;
610 for (x = start; x < end && x < emin[y - offset]; x++) {
611 if (dst[x] != bg) {
612 emin[y - offset] = x;
613 break;
614 }
615 }
616 for (x = end - 1; x >= start && x >= emax[y - offset]; x--) {
617 if (dst[x] != bg) {
618 emax[y - offset] = x;
619 break;
620 }
621 }
622 }
623
624 if (s->envelope == 3)
625 envelope_instant(s, out, plane, component, offset);
626
627 for (y = offset; y < offset + dst_h; y++) {
628 dst = out->data[component] + y * dst_linesize + emin[y - offset];
629 dst[0] = 255;
630 dst = out->data[component] + y * dst_linesize + emax[y - offset];
631 dst[0] = 255;
632 }
633 }
634 50 }
635
636 static void envelope16(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
637 {
638 if (s->envelope == 0) {
639 return;
640 } else if (s->envelope == 1) {
641 envelope_instant16(s, out, plane, component, offset);
642 } else {
643 envelope_peak16(s, out, plane, component, offset);
644 }
645 }
646
647 250 static void envelope(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
648 {
649
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 50 times.
250 if (s->envelope == 0) {
650 200 return;
651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 } else if (s->envelope == 1) {
652 envelope_instant(s, out, plane, component, offset);
653 } else {
654 50 envelope_peak(s, out, plane, component, offset);
655 }
656 }
657
658 static void update16(uint16_t *target, int max, int intensity, int limit)
659 {
660 if (*target <= max)
661 *target += intensity;
662 else
663 *target = limit;
664 }
665
666 20275200 static void update(uint8_t *target, int max, int intensity)
667 {
668
1/2
✓ Branch 0 taken 20275200 times.
✗ Branch 1 not taken.
20275200 if (*target <= max)
669 20275200 *target += intensity;
670 else
671 *target = 255;
672 20275200 }
673
674 static void update_cr(uint8_t *target, int unused, int intensity)
675 {
676 if (*target - intensity > 0)
677 *target -= intensity;
678 else
679 *target = 0;
680 }
681
682 static void update16_cr(uint16_t *target, int unused, int intensity, int limit)
683 {
684 if (*target - intensity > 0)
685 *target -= intensity;
686 else
687 *target = 0;
688 }
689
690 static av_always_inline void lowpass16(WaveformContext *s,
691 AVFrame *in, AVFrame *out,
692 int component, int intensity,
693 int offset_y, int offset_x,
694 int column, int mirror,
695 int jobnr, int nb_jobs)
696 {
697 const int plane = s->desc->comp[component].plane;
698 const int dplane = (s->rgb || s->display == OVERLAY) ? plane : 0;
699 const int shift_w = s->shift_w[component];
700 const int shift_h = s->shift_h[component];
701 const int src_linesize = in->linesize[plane] / 2;
702 const int dst_linesize = out->linesize[dplane] / 2;
703 const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
704 const int limit = s->max - 1;
705 const int max = limit - intensity;
706 const int src_h = AV_CEIL_RSHIFT(in->height, shift_h);
707 const int src_w = AV_CEIL_RSHIFT(in->width, shift_w);
708 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
709 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
710 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
711 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
712 const int step = column ? 1 << shift_w : 1 << shift_h;
713 const uint16_t *src_data = (const uint16_t *)in->data[plane] + sliceh_start * src_linesize;
714 uint16_t *dst_data = (uint16_t *)out->data[dplane] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
715 uint16_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
716 uint16_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
717 const uint16_t *p;
718 int y;
719
720 if (!column && mirror)
721 dst_data += s->size;
722
723 for (y = sliceh_start; y < sliceh_end; y++) {
724 const uint16_t *src_data_end = src_data + slicew_end;
725 uint16_t *dst = dst_line + slicew_start * step;
726
727 for (p = src_data + slicew_start; p < src_data_end; p++) {
728 uint16_t *target;
729 int i = 0, v = FFMIN(*p, limit);
730
731 if (column) {
732 do {
733 target = dst++ + dst_signed_linesize * v;
734 update16(target, max, intensity, limit);
735 } while (++i < step);
736 } else {
737 uint16_t *row = dst_data;
738 do {
739 if (mirror)
740 target = row - v - 1;
741 else
742 target = row + v;
743 update16(target, max, intensity, limit);
744 row += dst_linesize;
745 } while (++i < step);
746 }
747 }
748 src_data += src_linesize;
749 dst_data += dst_linesize * step;
750 }
751
752 if (s->display != OVERLAY && column && !s->rgb && out->data[1] && out->data[2]) {
753 const int mult = s->max / 256;
754 const int bg = s->bg_color[0] * mult;
755 const int t0 = s->tint[0];
756 const int t1 = s->tint[1];
757 uint16_t *dst0, *dst1;
758 const uint16_t *src;
759 int x;
760
761 src = (const uint16_t *)(out->data[0]) + offset_y * dst_linesize + offset_x;
762 dst0 = (uint16_t *)(out->data[1]) + offset_y * dst_linesize + offset_x;
763 dst1 = (uint16_t *)(out->data[2]) + offset_y * dst_linesize + offset_x;
764 for (y = 0; y < s->max; y++) {
765 for (x = slicew_start * step; x < slicew_end * step; x++) {
766 if (src[x] != bg) {
767 dst0[x] = t0;
768 dst1[x] = t1;
769 }
770 }
771
772 src += dst_linesize;
773 dst0 += dst_linesize;
774 dst1 += dst_linesize;
775 }
776 } else if (s->display != OVERLAY && !s->rgb && out->data[1] && out->data[2]) {
777 const int mult = s->max / 256;
778 const int bg = s->bg_color[0] * mult;
779 const int t0 = s->tint[0];
780 const int t1 = s->tint[1];
781 uint16_t *dst0, *dst1;
782 const uint16_t *src;
783 int x;
784
785 src = (const uint16_t *)out->data[0] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
786 dst0 = (uint16_t *)(out->data[1]) + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
787 dst1 = (uint16_t *)(out->data[2]) + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
788 for (y = sliceh_start * step; y < sliceh_end * step; y++) {
789 for (x = 0; x < s->max; x++) {
790 if (src[x] != bg) {
791 dst0[x] = t0;
792 dst1[x] = t1;
793 }
794 }
795
796 src += dst_linesize;
797 dst0 += dst_linesize;
798 dst1 += dst_linesize;
799 }
800 }
801 }
802
803 #define LOWPASS16_FUNC(name, column, mirror) \
804 static int lowpass16_##name(AVFilterContext *ctx, \
805 void *arg, int jobnr, \
806 int nb_jobs) \
807 { \
808 WaveformContext *s = ctx->priv; \
809 ThreadData *td = arg; \
810 AVFrame *in = td->in; \
811 AVFrame *out = td->out; \
812 int component = td->component; \
813 int offset_y = td->offset_y; \
814 int offset_x = td->offset_x; \
815 \
816 lowpass16(s, in, out, component, s->intensity, \
817 offset_y, offset_x, column, mirror, \
818 jobnr, nb_jobs); \
819 \
820 return 0; \
821 }
822
823 LOWPASS16_FUNC(column_mirror, 1, 1)
824 LOWPASS16_FUNC(column, 1, 0)
825 LOWPASS16_FUNC(row_mirror, 0, 1)
826 LOWPASS16_FUNC(row, 0, 0)
827
828 2250 static av_always_inline void lowpass(WaveformContext *s,
829 AVFrame *in, AVFrame *out,
830 int component, int intensity,
831 int offset_y, int offset_x,
832 int column, int mirror,
833 int jobnr, int nb_jobs)
834 {
835 2250 const int plane = s->desc->comp[component].plane;
836
2/4
✓ Branch 0 taken 2250 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2250 times.
2250 const int dplane = (s->rgb || s->display == OVERLAY) ? plane : 0;
837 2250 const int shift_w = s->shift_w[component];
838 2250 const int shift_h = s->shift_h[component];
839 2250 const int src_linesize = in->linesize[plane];
840 2250 const int dst_linesize = out->linesize[dplane];
841
1/2
✓ Branch 0 taken 2250 times.
✗ Branch 1 not taken.
2250 const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
842 2250 const int max = 255 - intensity;
843 2250 const int src_h = AV_CEIL_RSHIFT(in->height, shift_h);
844 2250 const int src_w = AV_CEIL_RSHIFT(in->width, shift_w);
845
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 1800 times.
2250 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
846
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 1800 times.
2250 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
847
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 450 times.
2250 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
848
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 450 times.
2250 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
849
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 450 times.
2250 const int step = column ? 1 << shift_w : 1 << shift_h;
850 2250 const uint8_t *src_data = in->data[plane] + sliceh_start * src_linesize;
851 2250 uint8_t *dst_data = out->data[dplane] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
852 2250 uint8_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
853
1/2
✓ Branch 0 taken 2250 times.
✗ Branch 1 not taken.
2250 uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
854 const uint8_t *p;
855 int y;
856
857
3/4
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 1800 times.
✓ Branch 2 taken 450 times.
✗ Branch 3 not taken.
2250 if (!column && mirror)
858 450 dst_data += s->size;
859
860
2/2
✓ Branch 0 taken 403200 times.
✓ Branch 1 taken 2250 times.
405450 for (y = sliceh_start; y < sliceh_end; y++) {
861 403200 const uint8_t *src_data_end = src_data + slicew_end;
862 403200 uint8_t *dst = dst_line + slicew_start * step;
863
864
2/2
✓ Branch 0 taken 17740800 times.
✓ Branch 1 taken 403200 times.
18144000 for (p = src_data + slicew_start; p < src_data_end; p++) {
865 uint8_t *target;
866 17740800 int i = 0;
867
868
2/2
✓ Branch 0 taken 12672000 times.
✓ Branch 1 taken 5068800 times.
17740800 if (column) {
869 do {
870 15206400 target = dst++ + dst_signed_linesize * *p;
871 15206400 update(target, max, intensity);
872
2/2
✓ Branch 0 taken 2534400 times.
✓ Branch 1 taken 12672000 times.
15206400 } while (++i < step);
873 } else {
874 5068800 uint8_t *row = dst_data;
875 do {
876
1/2
✓ Branch 0 taken 5068800 times.
✗ Branch 1 not taken.
5068800 if (mirror)
877 5068800 target = row - *p - 1;
878 else
879 target = row + *p;
880 5068800 update(target, max, intensity);
881 5068800 row += dst_linesize;
882
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5068800 times.
5068800 } while (++i < step);
883 }
884 }
885 403200 src_data += src_linesize;
886 403200 dst_data += dst_linesize * step;
887 }
888
889
6/10
✓ Branch 0 taken 2250 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1800 times.
✓ Branch 3 taken 450 times.
✓ Branch 4 taken 1800 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1800 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1800 times.
✗ Branch 9 not taken.
4050 if (s->display != OVERLAY && column && !s->rgb && out->data[1] && out->data[2]) {
890 1800 const int bg = s->bg_color[0];
891 1800 const int dst_h = 256;
892 1800 const int t0 = s->tint[0];
893 1800 const int t1 = s->tint[1];
894 uint8_t *dst0, *dst1;
895 const uint8_t *src;
896 int x;
897
898 1800 src = out->data[0] + offset_y * dst_linesize + offset_x;
899 1800 dst0 = out->data[1] + offset_y * dst_linesize + offset_x;
900 1800 dst1 = out->data[2] + offset_y * dst_linesize + offset_x;
901
2/2
✓ Branch 0 taken 460800 times.
✓ Branch 1 taken 1800 times.
462600 for (y = 0; y < dst_h; y++) {
902
2/2
✓ Branch 0 taken 18022400 times.
✓ Branch 1 taken 460800 times.
18483200 for (x = slicew_start * step; x < slicew_end * step; x++) {
903
2/2
✓ Branch 0 taken 8505880 times.
✓ Branch 1 taken 9516520 times.
18022400 if (src[x] != bg) {
904 8505880 dst0[x] = t0;
905 8505880 dst1[x] = t1;
906 }
907 }
908
909 460800 src += dst_linesize;
910 460800 dst0 += dst_linesize;
911 460800 dst1 += dst_linesize;
912 }
913
4/8
✓ Branch 0 taken 450 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 450 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 450 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 450 times.
✗ Branch 7 not taken.
450 } else if (s->display != OVERLAY && !s->rgb && out->data[1] && out->data[2]) {
914 450 const int bg = s->bg_color[0];
915 450 const int dst_w = 256;
916 450 const int t0 = s->tint[0];
917 450 const int t1 = s->tint[1];
918 uint8_t *dst0, *dst1;
919 const uint8_t *src;
920 int x;
921
922 450 src = out->data[0] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
923 450 dst0 = out->data[1] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
924 450 dst1 = out->data[2] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
925
2/2
✓ Branch 0 taken 14400 times.
✓ Branch 1 taken 450 times.
14850 for (y = sliceh_start * step; y < sliceh_end * step; y++) {
926
2/2
✓ Branch 0 taken 3686400 times.
✓ Branch 1 taken 14400 times.
3700800 for (x = 0; x < dst_w; x++) {
927
2/2
✓ Branch 0 taken 1616988 times.
✓ Branch 1 taken 2069412 times.
3686400 if (src[x] != bg) {
928 1616988 dst0[x] = t0;
929 1616988 dst1[x] = t1;
930 }
931 }
932
933 14400 src += dst_linesize;
934 14400 dst0 += dst_linesize;
935 14400 dst1 += dst_linesize;
936 }
937 }
938 2250 }
939
940 #define LOWPASS_FUNC(name, column, mirror) \
941 static int lowpass_##name(AVFilterContext *ctx, \
942 void *arg, int jobnr, \
943 int nb_jobs) \
944 { \
945 WaveformContext *s = ctx->priv; \
946 ThreadData *td = arg; \
947 AVFrame *in = td->in; \
948 AVFrame *out = td->out; \
949 int component = td->component; \
950 int offset_y = td->offset_y; \
951 int offset_x = td->offset_x; \
952 \
953 lowpass(s, in, out, component, s->intensity, \
954 offset_y, offset_x, column, mirror, \
955 jobnr, nb_jobs); \
956 \
957 return 0; \
958 }
959
960 1800 LOWPASS_FUNC(column_mirror, 1, 1)
961 LOWPASS_FUNC(column, 1, 0)
962 450 LOWPASS_FUNC(row_mirror, 0, 1)
963 LOWPASS_FUNC(row, 0, 0)
964
965 static av_always_inline void flat16(WaveformContext *s,
966 AVFrame *in, AVFrame *out,
967 int component, int intensity,
968 int offset_y, int offset_x,
969 int column, int mirror,
970 int jobnr, int nb_jobs)
971 {
972 const int plane = s->desc->comp[component].plane;
973 const int c0_linesize = in->linesize[ plane + 0 ] / 2;
974 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
975 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
976 const int c0_shift_w = s->shift_w[ component + 0 ];
977 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
978 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
979 const int c0_shift_h = s->shift_h[ component + 0 ];
980 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
981 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
982 const int d0_linesize = out->linesize[ plane + 0 ] / 2;
983 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2;
984 const int limit = s->max - 1;
985 const int max = limit - intensity;
986 const int mid = s->max / 2;
987 const int src_h = in->height;
988 const int src_w = in->width;
989 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
990 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
991 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
992 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
993 int x, y;
994
995 if (column) {
996 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
997 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
998
999 for (x = slicew_start; x < slicew_end; x++) {
1000 const uint16_t *c0_data = (uint16_t *)in->data[plane + 0];
1001 const uint16_t *c1_data = (uint16_t *)in->data[(plane + 1) % s->ncomp];
1002 const uint16_t *c2_data = (uint16_t *)in->data[(plane + 2) % s->ncomp];
1003 uint16_t *d0_data = (uint16_t *)(out->data[plane]) + offset_y * d0_linesize + offset_x;
1004 uint16_t *d1_data = (uint16_t *)(out->data[(plane + 1) % s->ncomp]) + offset_y * d1_linesize + offset_x;
1005 uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1006 uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1007 uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1008 uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1009
1010 for (y = 0; y < src_h; y++) {
1011 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + s->max;
1012 const int c1 = FFMIN(FFABS(c1_data[x >> c1_shift_w] - mid) + FFABS(c2_data[x >> c2_shift_w] - mid), limit);
1013 uint16_t *target;
1014
1015 target = d0 + x + d0_signed_linesize * c0;
1016 update16(target, max, intensity, limit);
1017 target = d1 + x + d1_signed_linesize * (c0 - c1);
1018 update16(target, max, intensity, limit);
1019 target = d1 + x + d1_signed_linesize * (c0 + c1);
1020 update16(target, max, intensity, limit);
1021
1022 if (!c0_shift_h || (y & c0_shift_h))
1023 c0_data += c0_linesize;
1024 if (!c1_shift_h || (y & c1_shift_h))
1025 c1_data += c1_linesize;
1026 if (!c2_shift_h || (y & c2_shift_h))
1027 c2_data += c2_linesize;
1028 d0_data += d0_linesize;
1029 d1_data += d1_linesize;
1030 }
1031 }
1032 } else {
1033 const uint16_t *c0_data = (uint16_t *)(in->data[plane]) + (sliceh_start >> c0_shift_h) * c0_linesize;
1034 const uint16_t *c1_data = (uint16_t *)(in->data[(plane + 1) % s->ncomp]) + (sliceh_start >> c1_shift_h) * c1_linesize;
1035 const uint16_t *c2_data = (uint16_t *)(in->data[(plane + 2) % s->ncomp]) + (sliceh_start >> c2_shift_h) * c2_linesize;
1036 uint16_t *d0_data = (uint16_t *)(out->data[plane]) + (offset_y + sliceh_start) * d0_linesize + offset_x;
1037 uint16_t *d1_data = (uint16_t *)(out->data[(plane + 1) % s->ncomp]) + (offset_y + sliceh_start) * d1_linesize + offset_x;
1038
1039 if (mirror) {
1040 d0_data += s->size - 1;
1041 d1_data += s->size - 1;
1042 }
1043
1044 for (y = sliceh_start; y < sliceh_end; y++) {
1045 for (x = 0; x < src_w; x++) {
1046 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + s->max;
1047 const int c1 = FFMIN(FFABS(c1_data[x >> c1_shift_w] - mid) + FFABS(c2_data[x >> c2_shift_w] - mid), limit);
1048 uint16_t *target;
1049
1050 if (mirror) {
1051 target = d0_data - c0;
1052 update16(target, max, intensity, limit);
1053 target = d1_data - (c0 - c1);
1054 update16(target, max, intensity, limit);
1055 target = d1_data - (c0 + c1);
1056 update16(target, max, intensity, limit);
1057 } else {
1058 target = d0_data + c0;
1059 update16(target, max, intensity, limit);
1060 target = d1_data + (c0 - c1);
1061 update16(target, max, intensity, limit);
1062 target = d1_data + (c0 + c1);
1063 update16(target, max, intensity, limit);
1064 }
1065 }
1066
1067 if (!c0_shift_h || (y & c0_shift_h))
1068 c0_data += c0_linesize;
1069 if (!c1_shift_h || (y & c1_shift_h))
1070 c1_data += c1_linesize;
1071 if (!c2_shift_h || (y & c2_shift_h))
1072 c2_data += c2_linesize;
1073 d0_data += d0_linesize;
1074 d1_data += d1_linesize;
1075 }
1076 }
1077 }
1078
1079 #define FLAT16_FUNC(name, column, mirror) \
1080 static int flat16_##name(AVFilterContext *ctx, \
1081 void *arg, int jobnr, \
1082 int nb_jobs) \
1083 { \
1084 WaveformContext *s = ctx->priv; \
1085 ThreadData *td = arg; \
1086 AVFrame *in = td->in; \
1087 AVFrame *out = td->out; \
1088 int component = td->component; \
1089 int offset_y = td->offset_y; \
1090 int offset_x = td->offset_x; \
1091 \
1092 flat16(s, in, out, component, s->intensity, \
1093 offset_y, offset_x, column, mirror, \
1094 jobnr, nb_jobs); \
1095 \
1096 return 0; \
1097 }
1098
1099 FLAT16_FUNC(column_mirror, 1, 1)
1100 FLAT16_FUNC(column, 1, 0)
1101 FLAT16_FUNC(row_mirror, 0, 1)
1102 FLAT16_FUNC(row, 0, 0)
1103
1104 static av_always_inline void flat(WaveformContext *s,
1105 AVFrame *in, AVFrame *out,
1106 int component, int intensity,
1107 int offset_y, int offset_x,
1108 int column, int mirror,
1109 int jobnr, int nb_jobs)
1110 {
1111 const int plane = s->desc->comp[component].plane;
1112 const int c0_linesize = in->linesize[ plane + 0 ];
1113 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
1114 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
1115 const int c0_shift_w = s->shift_w[ component + 0 ];
1116 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
1117 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
1118 const int c0_shift_h = s->shift_h[ component + 0 ];
1119 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
1120 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
1121 const int d0_linesize = out->linesize[ plane + 0 ];
1122 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
1123 const int max = 255 - intensity;
1124 const int src_h = in->height;
1125 const int src_w = in->width;
1126 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1127 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1128 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1129 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1130 int x, y;
1131
1132 if (column) {
1133 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1134 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1135
1136 for (x = slicew_start; x < slicew_end; x++) {
1137 const uint8_t *c0_data = in->data[plane + 0];
1138 const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
1139 const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
1140 uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x;
1141 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
1142 uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1143 uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1144 uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1145 uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1146
1147 for (y = 0; y < src_h; y++) {
1148 const int c0 = c0_data[x >> c0_shift_w] + 256;
1149 const int c1 = FFABS(c1_data[x >> c1_shift_w] - 128) + FFABS(c2_data[x >> c2_shift_w] - 128);
1150 uint8_t *target;
1151
1152 target = d0 + x + d0_signed_linesize * c0;
1153 update(target, max, intensity);
1154 target = d1 + x + d1_signed_linesize * (c0 - c1);
1155 update(target, max, intensity);
1156 target = d1 + x + d1_signed_linesize * (c0 + c1);
1157 update(target, max, intensity);
1158
1159 if (!c0_shift_h || (y & c0_shift_h))
1160 c0_data += c0_linesize;
1161 if (!c1_shift_h || (y & c1_shift_h))
1162 c1_data += c1_linesize;
1163 if (!c2_shift_h || (y & c2_shift_h))
1164 c2_data += c2_linesize;
1165 d0_data += d0_linesize;
1166 d1_data += d1_linesize;
1167 }
1168 }
1169 } else {
1170 const uint8_t *c0_data = in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize;
1171 const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1172 const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
1173 uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
1174 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
1175
1176 if (mirror) {
1177 d0_data += s->size - 1;
1178 d1_data += s->size - 1;
1179 }
1180
1181 for (y = sliceh_start; y < sliceh_end; y++) {
1182 for (x = 0; x < src_w; x++) {
1183 const int c0 = c0_data[x >> c0_shift_w] + 256;
1184 const int c1 = FFABS(c1_data[x >> c1_shift_w] - 128) + FFABS(c2_data[x >> c2_shift_w] - 128);
1185 uint8_t *target;
1186
1187 if (mirror) {
1188 target = d0_data - c0;
1189 update(target, max, intensity);
1190 target = d1_data - (c0 - c1);
1191 update(target, max, intensity);
1192 target = d1_data - (c0 + c1);
1193 update(target, max, intensity);
1194 } else {
1195 target = d0_data + c0;
1196 update(target, max, intensity);
1197 target = d1_data + (c0 - c1);
1198 update(target, max, intensity);
1199 target = d1_data + (c0 + c1);
1200 update(target, max, intensity);
1201 }
1202 }
1203
1204 if (!c0_shift_h || (y & c0_shift_h))
1205 c0_data += c0_linesize;
1206 if (!c1_shift_h || (y & c1_shift_h))
1207 c1_data += c1_linesize;
1208 if (!c2_shift_h || (y & c2_shift_h))
1209 c2_data += c2_linesize;
1210 d0_data += d0_linesize;
1211 d1_data += d1_linesize;
1212 }
1213 }
1214 }
1215
1216 #define FLAT_FUNC(name, column, mirror) \
1217 static int flat_##name(AVFilterContext *ctx, \
1218 void *arg, int jobnr, \
1219 int nb_jobs) \
1220 { \
1221 WaveformContext *s = ctx->priv; \
1222 ThreadData *td = arg; \
1223 AVFrame *in = td->in; \
1224 AVFrame *out = td->out; \
1225 int component = td->component; \
1226 int offset_y = td->offset_y; \
1227 int offset_x = td->offset_x; \
1228 \
1229 flat(s, in, out, component, s->intensity, \
1230 offset_y, offset_x, column, mirror, \
1231 jobnr, nb_jobs); \
1232 \
1233 return 0; \
1234 }
1235
1236 FLAT_FUNC(column_mirror, 1, 1)
1237 FLAT_FUNC(column, 1, 0)
1238 FLAT_FUNC(row_mirror, 0, 1)
1239 FLAT_FUNC(row, 0, 0)
1240
1241 #define AFLAT16(name, update_cb, update_cr, column, mirror) \
1242 static int name(AVFilterContext *ctx, \
1243 void *arg, int jobnr, \
1244 int nb_jobs) \
1245 { \
1246 WaveformContext *s = ctx->priv; \
1247 ThreadData *td = arg; \
1248 AVFrame *in = td->in; \
1249 AVFrame *out = td->out; \
1250 int component = td->component; \
1251 int offset_y = td->offset_y; \
1252 int offset_x = td->offset_x; \
1253 const int intensity = s->intensity; \
1254 const int plane = s->desc->comp[component].plane; \
1255 const int c0_linesize = in->linesize[ plane + 0 ] / 2; \
1256 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2; \
1257 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2; \
1258 const int c0_shift_w = s->shift_w[ component + 0 ]; \
1259 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp]; \
1260 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp]; \
1261 const int c0_shift_h = s->shift_h[ component + 0 ]; \
1262 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp]; \
1263 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp]; \
1264 const int d0_linesize = out->linesize[ plane + 0 ] / 2; \
1265 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2; \
1266 const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2; \
1267 const int limit = s->max - 1; \
1268 const int max = limit - intensity; \
1269 const int mid = s->max / 2; \
1270 const int src_h = in->height; \
1271 const int src_w = in->width; \
1272 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; \
1273 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; \
1274 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; \
1275 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; \
1276 int x, y; \
1277 \
1278 if (column) { \
1279 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1); \
1280 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1); \
1281 const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1); \
1282 \
1283 for (x = slicew_start; x < slicew_end; x++) { \
1284 const uint16_t *c0_data = (uint16_t *)in->data[plane + 0]; \
1285 const uint16_t *c1_data = (uint16_t *)in->data[(plane + 1) % s->ncomp]; \
1286 const uint16_t *c2_data = (uint16_t *)in->data[(plane + 2) % s->ncomp]; \
1287 uint16_t *d0_data = (uint16_t *)out->data[plane] + offset_y * d0_linesize + offset_x; \
1288 uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x; \
1289 uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x; \
1290 uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1); \
1291 uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data); \
1292 uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1); \
1293 uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data); \
1294 uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1); \
1295 uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data); \
1296 \
1297 for (y = 0; y < src_h; y++) { \
1298 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + mid; \
1299 const int c1 = FFMIN(c1_data[x >> c1_shift_w], limit) - mid; \
1300 const int c2 = FFMIN(c2_data[x >> c2_shift_w], limit) - mid; \
1301 uint16_t *target; \
1302 \
1303 target = d0 + x + d0_signed_linesize * c0; \
1304 update16(target, max, intensity, limit); \
1305 \
1306 target = d1 + x + d1_signed_linesize * (c0 + c1); \
1307 update_cb(target, max, intensity, limit); \
1308 \
1309 target = d2 + x + d2_signed_linesize * (c0 + c2); \
1310 update_cr(target, max, intensity, limit); \
1311 \
1312 if (!c0_shift_h || (y & c0_shift_h)) \
1313 c0_data += c0_linesize; \
1314 if (!c1_shift_h || (y & c1_shift_h)) \
1315 c1_data += c1_linesize; \
1316 if (!c2_shift_h || (y & c2_shift_h)) \
1317 c2_data += c2_linesize; \
1318 d0_data += d0_linesize; \
1319 d1_data += d1_linesize; \
1320 d2_data += d2_linesize; \
1321 } \
1322 } \
1323 } else { \
1324 const uint16_t *c0_data = (uint16_t *)in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize; \
1325 const uint16_t *c1_data = (uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize; \
1326 const uint16_t *c2_data = (uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize; \
1327 uint16_t *d0_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x; \
1328 uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x; \
1329 uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x; \
1330 \
1331 if (mirror) { \
1332 d0_data += s->size - 1; \
1333 d1_data += s->size - 1; \
1334 d2_data += s->size - 1; \
1335 } \
1336 \
1337 for (y = sliceh_start; y < sliceh_end; y++) { \
1338 for (x = 0; x < src_w; x++) { \
1339 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + mid; \
1340 const int c1 = FFMIN(c1_data[x >> c1_shift_w], limit) - mid; \
1341 const int c2 = FFMIN(c2_data[x >> c2_shift_w], limit) - mid; \
1342 uint16_t *target; \
1343 \
1344 if (mirror) { \
1345 target = d0_data - c0; \
1346 update16(target, max, intensity, limit); \
1347 target = d1_data - (c0 + c1); \
1348 update_cb(target, max, intensity, limit); \
1349 target = d2_data - (c0 + c2); \
1350 update_cr(target, max, intensity, limit); \
1351 } else { \
1352 target = d0_data + c0; \
1353 update16(target, max, intensity, limit); \
1354 target = d1_data + (c0 + c1); \
1355 update_cb(target, max, intensity, limit); \
1356 target = d2_data + (c0 + c2); \
1357 update_cr(target, max, intensity, limit); \
1358 } \
1359 } \
1360 \
1361 if (!c0_shift_h || (y & c0_shift_h)) \
1362 c0_data += c0_linesize; \
1363 if (!c1_shift_h || (y & c1_shift_h)) \
1364 c1_data += c1_linesize; \
1365 if (!c2_shift_h || (y & c2_shift_h)) \
1366 c2_data += c2_linesize; \
1367 d0_data += d0_linesize; \
1368 d1_data += d1_linesize; \
1369 d2_data += d2_linesize; \
1370 } \
1371 } \
1372 return 0; \
1373 }
1374
1375 #define AFLAT(name, update_cb, update_cr, column, mirror) \
1376 static int name(AVFilterContext *ctx, \
1377 void *arg, int jobnr, \
1378 int nb_jobs) \
1379 { \
1380 WaveformContext *s = ctx->priv; \
1381 ThreadData *td = arg; \
1382 AVFrame *in = td->in; \
1383 AVFrame *out = td->out; \
1384 int component = td->component; \
1385 int offset_y = td->offset_y; \
1386 int offset_x = td->offset_x; \
1387 const int src_h = in->height; \
1388 const int src_w = in->width; \
1389 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; \
1390 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; \
1391 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; \
1392 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; \
1393 const int intensity = s->intensity; \
1394 const int plane = s->desc->comp[component].plane; \
1395 const int c0_linesize = in->linesize[ plane + 0 ]; \
1396 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp]; \
1397 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp]; \
1398 const int c0_shift_w = s->shift_w[ component + 0 ]; \
1399 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp]; \
1400 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp]; \
1401 const int c0_shift_h = s->shift_h[ component + 0 ]; \
1402 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp]; \
1403 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp]; \
1404 const int d0_linesize = out->linesize[ plane + 0 ]; \
1405 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp]; \
1406 const int d2_linesize = out->linesize[(plane + 2) % s->ncomp]; \
1407 const int max = 255 - intensity; \
1408 int x, y; \
1409 \
1410 if (column) { \
1411 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1); \
1412 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1); \
1413 const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1); \
1414 \
1415 for (x = slicew_start; x < slicew_end; x++) { \
1416 const uint8_t *c0_data = in->data[plane + 0]; \
1417 const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp]; \
1418 const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp]; \
1419 uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x; \
1420 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x; \
1421 uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x; \
1422 uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1); \
1423 uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data); \
1424 uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1); \
1425 uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data); \
1426 uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1); \
1427 uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data); \
1428 \
1429 for (y = 0; y < src_h; y++) { \
1430 const int c0 = c0_data[x >> c0_shift_w] + 128; \
1431 const int c1 = c1_data[x >> c1_shift_w] - 128; \
1432 const int c2 = c2_data[x >> c2_shift_w] - 128; \
1433 uint8_t *target; \
1434 \
1435 target = d0 + x + d0_signed_linesize * c0; \
1436 update(target, max, intensity); \
1437 \
1438 target = d1 + x + d1_signed_linesize * (c0 + c1); \
1439 update_cb(target, max, intensity); \
1440 \
1441 target = d2 + x + d2_signed_linesize * (c0 + c2); \
1442 update_cr(target, max, intensity); \
1443 \
1444 if (!c0_shift_h || (y & c0_shift_h)) \
1445 c0_data += c0_linesize; \
1446 if (!c1_shift_h || (y & c1_shift_h)) \
1447 c1_data += c1_linesize; \
1448 if (!c2_shift_h || (y & c2_shift_h)) \
1449 c2_data += c2_linesize; \
1450 d0_data += d0_linesize; \
1451 d1_data += d1_linesize; \
1452 d2_data += d2_linesize; \
1453 } \
1454 } \
1455 } else { \
1456 const uint8_t *c0_data = in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize; \
1457 const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize; \
1458 const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize; \
1459 uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x; \
1460 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x; \
1461 uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x; \
1462 \
1463 if (mirror) { \
1464 d0_data += s->size - 1; \
1465 d1_data += s->size - 1; \
1466 d2_data += s->size - 1; \
1467 } \
1468 \
1469 for (y = sliceh_start; y < sliceh_end; y++) { \
1470 for (x = 0; x < src_w; x++) { \
1471 const int c0 = c0_data[x >> c0_shift_w] + 128; \
1472 const int c1 = c1_data[x >> c1_shift_w] - 128; \
1473 const int c2 = c2_data[x >> c2_shift_w] - 128; \
1474 uint8_t *target; \
1475 \
1476 if (mirror) { \
1477 target = d0_data - c0; \
1478 update(target, max, intensity); \
1479 target = d1_data - (c0 + c1); \
1480 update_cb(target, max, intensity); \
1481 target = d2_data - (c0 + c2); \
1482 update_cr(target, max, intensity); \
1483 } else { \
1484 target = d0_data + c0; \
1485 update(target, max, intensity); \
1486 target = d1_data + (c0 + c1); \
1487 update_cb(target, max, intensity); \
1488 target = d2_data + (c0 + c2); \
1489 update_cr(target, max, intensity); \
1490 } \
1491 } \
1492 \
1493 if (!c0_shift_h || (y & c0_shift_h)) \
1494 c0_data += c0_linesize; \
1495 if (!c1_shift_h || (y & c1_shift_h)) \
1496 c1_data += c1_linesize; \
1497 if (!c2_shift_h || (y & c2_shift_h)) \
1498 c2_data += c2_linesize; \
1499 d0_data += d0_linesize; \
1500 d1_data += d1_linesize; \
1501 d2_data += d2_linesize; \
1502 } \
1503 } \
1504 return 0; \
1505 }
1506
1507 AFLAT16(aflat16_row, update16, update16, 0, 0)
1508 AFLAT16(aflat16_row_mirror, update16, update16, 0, 1)
1509 AFLAT16(aflat16_column, update16, update16, 1, 0)
1510 AFLAT16(aflat16_column_mirror, update16, update16, 1, 1)
1511 AFLAT16(xflat16_row, update16, update16_cr, 0, 0)
1512 AFLAT16(xflat16_row_mirror, update16, update16_cr, 0, 1)
1513 AFLAT16(xflat16_column, update16, update16_cr, 1, 0)
1514 AFLAT16(xflat16_column_mirror, update16, update16_cr, 1, 1)
1515 AFLAT16(yflat16_row, update16_cr, update16_cr, 0, 0)
1516 AFLAT16(yflat16_row_mirror, update16_cr, update16_cr, 0, 1)
1517 AFLAT16(yflat16_column, update16_cr, update16_cr, 1, 0)
1518 AFLAT16(yflat16_column_mirror, update16_cr, update16_cr, 1, 1)
1519
1520 AFLAT(aflat_row, update, update, 0, 0)
1521 AFLAT(aflat_row_mirror, update, update, 0, 1)
1522 AFLAT(aflat_column, update, update, 1, 0)
1523 AFLAT(aflat_column_mirror, update, update, 1, 1)
1524 AFLAT(xflat_row, update, update_cr, 0, 0)
1525 AFLAT(xflat_row_mirror, update, update_cr, 0, 1)
1526 AFLAT(xflat_column, update, update_cr, 1, 0)
1527 AFLAT(xflat_column_mirror, update, update_cr, 1, 1)
1528 AFLAT(yflat_row, update_cr, update_cr, 0, 0)
1529 AFLAT(yflat_row_mirror, update_cr, update_cr, 0, 1)
1530 AFLAT(yflat_column, update_cr, update_cr, 1, 0)
1531 AFLAT(yflat_column_mirror, update_cr, update_cr, 1, 1)
1532
1533 static av_always_inline void chroma16(WaveformContext *s,
1534 AVFrame *in, AVFrame *out,
1535 int component, int intensity,
1536 int offset_y, int offset_x,
1537 int column, int mirror,
1538 int jobnr, int nb_jobs)
1539 {
1540 const int plane = s->desc->comp[component].plane;
1541 const int c0_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
1542 const int c1_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
1543 const int dst_linesize = out->linesize[plane] / 2;
1544 const int limit = s->max - 1;
1545 const int max = limit - intensity;
1546 const int mid = s->max / 2;
1547 const int c0_shift_w = s->shift_w[(component + 1) % s->ncomp];
1548 const int c1_shift_w = s->shift_w[(component + 2) % s->ncomp];
1549 const int c0_shift_h = s->shift_h[(component + 1) % s->ncomp];
1550 const int c1_shift_h = s->shift_h[(component + 2) % s->ncomp];
1551 const int src_h = in->height;
1552 const int src_w = in->width;
1553 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1554 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1555 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1556 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1557 int x, y;
1558
1559 if (column) {
1560 const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
1561
1562 for (x = slicew_start; x < slicew_end; x++) {
1563 const uint16_t *c0_data = (uint16_t *)in->data[(plane + 1) % s->ncomp];
1564 const uint16_t *c1_data = (uint16_t *)in->data[(plane + 2) % s->ncomp];
1565 uint16_t *dst_data = (uint16_t *)out->data[plane] + offset_y * dst_linesize + offset_x;
1566 uint16_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
1567 uint16_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
1568 uint16_t *dst = dst_line;
1569
1570 for (y = 0; y < src_h; y++) {
1571 const int sum = FFMIN(FFABS(c0_data[x >> c0_shift_w] - mid) + FFABS(c1_data[x >> c1_shift_w] - mid - 1), limit);
1572 uint16_t *target;
1573
1574 target = dst + x + dst_signed_linesize * sum;
1575 update16(target, max, intensity, limit);
1576
1577 if (!c0_shift_h || (y & c0_shift_h))
1578 c0_data += c0_linesize;
1579 if (!c1_shift_h || (y & c1_shift_h))
1580 c1_data += c1_linesize;
1581 dst_data += dst_linesize;
1582 }
1583 }
1584 } else {
1585 const uint16_t *c0_data = (uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c0_shift_h) * c0_linesize;
1586 const uint16_t *c1_data = (uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1587 uint16_t *dst_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * dst_linesize + offset_x;
1588
1589 if (mirror)
1590 dst_data += s->size - 1;
1591 for (y = sliceh_start; y < sliceh_end; y++) {
1592 for (x = 0; x < src_w; x++) {
1593 const int sum = FFMIN(FFABS(c0_data[x >> c0_shift_w] - mid) + FFABS(c1_data[x >> c1_shift_w] - mid - 1), limit);
1594 uint16_t *target;
1595
1596 if (mirror) {
1597 target = dst_data - sum;
1598 update16(target, max, intensity, limit);
1599 } else {
1600 target = dst_data + sum;
1601 update16(target, max, intensity, limit);
1602 }
1603 }
1604
1605 if (!c0_shift_h || (y & c0_shift_h))
1606 c0_data += c0_linesize;
1607 if (!c1_shift_h || (y & c1_shift_h))
1608 c1_data += c1_linesize;
1609 dst_data += dst_linesize;
1610 }
1611 }
1612 }
1613
1614 #define CHROMA16_FUNC(name, column, mirror) \
1615 static int chroma16_##name(AVFilterContext *ctx, \
1616 void *arg, int jobnr, \
1617 int nb_jobs) \
1618 { \
1619 WaveformContext *s = ctx->priv; \
1620 ThreadData *td = arg; \
1621 AVFrame *in = td->in; \
1622 AVFrame *out = td->out; \
1623 int component = td->component; \
1624 int offset_y = td->offset_y; \
1625 int offset_x = td->offset_x; \
1626 \
1627 chroma16(s, in, out, component, s->intensity,\
1628 offset_y, offset_x, column, mirror, \
1629 jobnr, nb_jobs); \
1630 \
1631 return 0; \
1632 }
1633
1634 CHROMA16_FUNC(column_mirror, 1, 1)
1635 CHROMA16_FUNC(column, 1, 0)
1636 CHROMA16_FUNC(row_mirror, 0, 1)
1637 CHROMA16_FUNC(row, 0, 0)
1638
1639 static av_always_inline void chroma(WaveformContext *s,
1640 AVFrame *in, AVFrame *out,
1641 int component, int intensity,
1642 int offset_y, int offset_x,
1643 int column, int mirror,
1644 int jobnr, int nb_jobs)
1645 {
1646 const int plane = s->desc->comp[component].plane;
1647 const int src_h = in->height;
1648 const int src_w = in->width;
1649 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1650 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1651 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1652 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1653 const int c0_linesize = in->linesize[(plane + 1) % s->ncomp];
1654 const int c1_linesize = in->linesize[(plane + 2) % s->ncomp];
1655 const int dst_linesize = out->linesize[plane];
1656 const int max = 255 - intensity;
1657 const int c0_shift_w = s->shift_w[(component + 1) % s->ncomp];
1658 const int c1_shift_w = s->shift_w[(component + 2) % s->ncomp];
1659 const int c0_shift_h = s->shift_h[(component + 1) % s->ncomp];
1660 const int c1_shift_h = s->shift_h[(component + 2) % s->ncomp];
1661 int x, y;
1662
1663 if (column) {
1664 const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
1665
1666 for (x = slicew_start; x < slicew_end; x++) {
1667 const uint8_t *c0_data = in->data[(plane + 1) % s->ncomp];
1668 const uint8_t *c1_data = in->data[(plane + 2) % s->ncomp];
1669 uint8_t *dst_data = out->data[plane] + offset_y * dst_linesize + offset_x;
1670 uint8_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
1671 uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
1672 uint8_t *dst = dst_line;
1673
1674 for (y = 0; y < src_h; y++) {
1675 const int sum = FFABS(c0_data[x >> c0_shift_w] - 128) + FFABS(c1_data[x >> c1_shift_w] - 127);
1676 uint8_t *target;
1677
1678 target = dst + x + dst_signed_linesize * sum;
1679 update(target, max, intensity);
1680
1681 if (!c0_shift_h || (y & c0_shift_h))
1682 c0_data += c0_linesize;
1683 if (!c1_shift_h || (y & c1_shift_h))
1684 c1_data += c1_linesize;
1685 dst_data += dst_linesize;
1686 }
1687 }
1688 } else {
1689 const uint8_t *c0_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c0_shift_h) * c0_linesize;
1690 const uint8_t *c1_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1691 uint8_t *dst_data = out->data[plane] + (offset_y + sliceh_start) * dst_linesize + offset_x;
1692
1693 if (mirror)
1694 dst_data += s->size - 1;
1695 for (y = sliceh_start; y < sliceh_end; y++) {
1696 for (x = 0; x < src_w; x++) {
1697 const int sum = FFABS(c0_data[x >> c0_shift_w] - 128) + FFABS(c1_data[x >> c1_shift_w] - 127);
1698 uint8_t *target;
1699
1700 if (mirror) {
1701 target = dst_data - sum;
1702 update(target, max, intensity);
1703 } else {
1704 target = dst_data + sum;
1705 update(target, max, intensity);
1706 }
1707 }
1708
1709 if (!c0_shift_h || (y & c0_shift_h))
1710 c0_data += c0_linesize;
1711 if (!c1_shift_h || (y & c1_shift_h))
1712 c1_data += c1_linesize;
1713 dst_data += dst_linesize;
1714 }
1715 }
1716 }
1717
1718 #define CHROMA_FUNC(name, column, mirror) \
1719 static int chroma_##name(AVFilterContext *ctx, \
1720 void *arg, int jobnr, \
1721 int nb_jobs) \
1722 { \
1723 WaveformContext *s = ctx->priv; \
1724 ThreadData *td = arg; \
1725 AVFrame *in = td->in; \
1726 AVFrame *out = td->out; \
1727 int component = td->component; \
1728 int offset_y = td->offset_y; \
1729 int offset_x = td->offset_x; \
1730 \
1731 chroma(s, in, out, component, s->intensity, \
1732 offset_y, offset_x, column, mirror, \
1733 jobnr, nb_jobs); \
1734 \
1735 return 0; \
1736 }
1737
1738 CHROMA_FUNC(column_mirror, 1, 1)
1739 CHROMA_FUNC(column, 1, 0)
1740 CHROMA_FUNC(row_mirror, 0, 1)
1741 CHROMA_FUNC(row, 0, 0)
1742
1743 static av_always_inline void color16(WaveformContext *s,
1744 AVFrame *in, AVFrame *out,
1745 int component, int intensity,
1746 int offset_y, int offset_x,
1747 int column, int mirror,
1748 int jobnr, int nb_jobs)
1749 {
1750 const int plane = s->desc->comp[component].plane;
1751 const int limit = s->max - 1;
1752 const int src_h = in->height;
1753 const int src_w = in->width;
1754 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1755 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1756 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1757 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1758 const int c0_linesize = in->linesize[ plane + 0 ] / 2;
1759 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
1760 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
1761 const int c0_shift_h = s->shift_h[ component + 0 ];
1762 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
1763 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
1764 const uint16_t *c0_data = (const uint16_t *)in->data[plane + 0] + (sliceh_start >> c0_shift_h) * c0_linesize;
1765 const uint16_t *c1_data = (const uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1766 const uint16_t *c2_data = (const uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
1767 const int d0_linesize = out->linesize[ plane + 0 ] / 2;
1768 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2;
1769 const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2;
1770 const int c0_shift_w = s->shift_w[ component + 0 ];
1771 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
1772 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
1773 int x, y;
1774
1775 if (column) {
1776 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1777 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1778 const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
1779 uint16_t *d0_data = (uint16_t *)out->data[plane] + offset_y * d0_linesize + offset_x;
1780 uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
1781 uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
1782 uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1783 uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1784 uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1785 uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1786 uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
1787 uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data);
1788
1789 for (y = 0; y < src_h; y++) {
1790 for (x = slicew_start; x < slicew_end; x++) {
1791 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
1792 const int c1 = c1_data[x >> c1_shift_w];
1793 const int c2 = c2_data[x >> c2_shift_w];
1794
1795 *(d0 + d0_signed_linesize * c0 + x) = c0;
1796 *(d1 + d1_signed_linesize * c0 + x) = c1;
1797 *(d2 + d2_signed_linesize * c0 + x) = c2;
1798 }
1799
1800 if (!c0_shift_h || (y & c0_shift_h))
1801 c0_data += c0_linesize;
1802 if (!c1_shift_h || (y & c1_shift_h))
1803 c1_data += c1_linesize;
1804 if (!c2_shift_h || (y & c2_shift_h))
1805 c2_data += c2_linesize;
1806 d0_data += d0_linesize;
1807 d1_data += d1_linesize;
1808 d2_data += d2_linesize;
1809 }
1810 } else {
1811 uint16_t *d0_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
1812 uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
1813 uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
1814
1815 if (mirror) {
1816 d0_data += s->size - 1;
1817 d1_data += s->size - 1;
1818 d2_data += s->size - 1;
1819 }
1820
1821 for (y = sliceh_start; y < sliceh_end; y++) {
1822 for (x = 0; x < src_w; x++) {
1823 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
1824 const int c1 = c1_data[x >> c1_shift_w];
1825 const int c2 = c2_data[x >> c2_shift_w];
1826
1827 if (mirror) {
1828 *(d0_data - c0) = c0;
1829 *(d1_data - c0) = c1;
1830 *(d2_data - c0) = c2;
1831 } else {
1832 *(d0_data + c0) = c0;
1833 *(d1_data + c0) = c1;
1834 *(d2_data + c0) = c2;
1835 }
1836 }
1837
1838 if (!c0_shift_h || (y & c0_shift_h))
1839 c0_data += c0_linesize;
1840 if (!c1_shift_h || (y & c1_shift_h))
1841 c1_data += c1_linesize;
1842 if (!c2_shift_h || (y & c2_shift_h))
1843 c2_data += c2_linesize;
1844 d0_data += d0_linesize;
1845 d1_data += d1_linesize;
1846 d2_data += d2_linesize;
1847 }
1848 }
1849 }
1850
1851 #define COLOR16_FUNC(name, column, mirror) \
1852 static int color16_##name(AVFilterContext *ctx, \
1853 void *arg, int jobnr, \
1854 int nb_jobs) \
1855 { \
1856 WaveformContext *s = ctx->priv; \
1857 ThreadData *td = arg; \
1858 AVFrame *in = td->in; \
1859 AVFrame *out = td->out; \
1860 int component = td->component; \
1861 int offset_y = td->offset_y; \
1862 int offset_x = td->offset_x; \
1863 \
1864 color16(s, in, out, component, s->intensity, \
1865 offset_y, offset_x, column, mirror, \
1866 jobnr, nb_jobs); \
1867 \
1868 return 0; \
1869 }
1870
1871 COLOR16_FUNC(column_mirror, 1, 1)
1872 COLOR16_FUNC(column, 1, 0)
1873 COLOR16_FUNC(row_mirror, 0, 1)
1874 COLOR16_FUNC(row, 0, 0)
1875
1876 static av_always_inline void color(WaveformContext *s,
1877 AVFrame *in, AVFrame *out,
1878 int component, int intensity,
1879 int offset_y, int offset_x,
1880 int column, int mirror,
1881 int jobnr, int nb_jobs)
1882 {
1883 const int plane = s->desc->comp[component].plane;
1884 const int src_h = in->height;
1885 const int src_w = in->width;
1886 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1887 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1888 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1889 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1890 const int c0_linesize = in->linesize[ plane + 0 ];
1891 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
1892 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
1893 const int c0_shift_h = s->shift_h[ component + 0 ];
1894 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
1895 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
1896 const uint8_t *c0_data = in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize;
1897 const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1898 const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
1899 const int d0_linesize = out->linesize[ plane + 0 ];
1900 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
1901 const int d2_linesize = out->linesize[(plane + 2) % s->ncomp];
1902 const int c0_shift_w = s->shift_w[ component + 0 ];
1903 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
1904 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
1905 int x, y;
1906
1907 if (column) {
1908 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1909 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1910 const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
1911 uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x;
1912 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
1913 uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
1914 uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1915 uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1916 uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1917 uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1918 uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
1919 uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data);
1920
1921 for (y = 0; y < src_h; y++) {
1922 for (x = slicew_start; x < slicew_end; x++) {
1923 const int c0 = c0_data[x >> c0_shift_w];
1924 const int c1 = c1_data[x >> c1_shift_w];
1925 const int c2 = c2_data[x >> c2_shift_w];
1926
1927 *(d0 + d0_signed_linesize * c0 + x) = c0;
1928 *(d1 + d1_signed_linesize * c0 + x) = c1;
1929 *(d2 + d2_signed_linesize * c0 + x) = c2;
1930 }
1931
1932 if (!c0_shift_h || (y & c0_shift_h))
1933 c0_data += c0_linesize;
1934 if (!c1_shift_h || (y & c1_shift_h))
1935 c1_data += c1_linesize;
1936 if (!c2_shift_h || (y & c2_shift_h))
1937 c2_data += c2_linesize;
1938 d0_data += d0_linesize;
1939 d1_data += d1_linesize;
1940 d2_data += d2_linesize;
1941 }
1942 } else {
1943 uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
1944 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
1945 uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
1946
1947 if (mirror) {
1948 d0_data += s->size - 1;
1949 d1_data += s->size - 1;
1950 d2_data += s->size - 1;
1951 }
1952
1953 for (y = sliceh_start; y < sliceh_end; y++) {
1954 for (x = 0; x < src_w; x++) {
1955 const int c0 = c0_data[x >> c0_shift_w];
1956 const int c1 = c1_data[x >> c1_shift_w];
1957 const int c2 = c2_data[x >> c2_shift_w];
1958
1959 if (mirror) {
1960 *(d0_data - c0) = c0;
1961 *(d1_data - c0) = c1;
1962 *(d2_data - c0) = c2;
1963 } else {
1964 *(d0_data + c0) = c0;
1965 *(d1_data + c0) = c1;
1966 *(d2_data + c0) = c2;
1967 }
1968 }
1969
1970 if (!c0_shift_h || (y & c0_shift_h))
1971 c0_data += c0_linesize;
1972 if (!c1_shift_h || (y & c1_shift_h))
1973 c1_data += c1_linesize;
1974 if (!c2_shift_h || (y & c2_shift_h))
1975 c2_data += c2_linesize;
1976 d0_data += d0_linesize;
1977 d1_data += d1_linesize;
1978 d2_data += d2_linesize;
1979 }
1980 }
1981 }
1982
1983 #define COLOR_FUNC(name, column, mirror) \
1984 static int color_##name(AVFilterContext *ctx, \
1985 void *arg, int jobnr, \
1986 int nb_jobs) \
1987 { \
1988 WaveformContext *s = ctx->priv; \
1989 ThreadData *td = arg; \
1990 AVFrame *in = td->in; \
1991 AVFrame *out = td->out; \
1992 int component = td->component; \
1993 int offset_y = td->offset_y; \
1994 int offset_x = td->offset_x; \
1995 \
1996 color(s, in, out, component, s->intensity, \
1997 offset_y, offset_x, column, mirror, \
1998 jobnr, nb_jobs); \
1999 \
2000 return 0; \
2001 }
2002
2003 COLOR_FUNC(column_mirror, 1, 1)
2004 COLOR_FUNC(column, 1, 0)
2005 COLOR_FUNC(row_mirror, 0, 1)
2006 COLOR_FUNC(row, 0, 0)
2007
2008 static av_always_inline void acolor16(WaveformContext *s,
2009 AVFrame *in, AVFrame *out,
2010 int component, int intensity,
2011 int offset_y, int offset_x,
2012 int column, int mirror,
2013 int jobnr, int nb_jobs)
2014 {
2015 const int plane = s->desc->comp[component].plane;
2016 const int limit = s->max - 1;
2017 const int max = limit - intensity;
2018 const int src_h = in->height;
2019 const int src_w = in->width;
2020 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
2021 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
2022 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
2023 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
2024 const int c0_shift_h = s->shift_h[ component + 0 ];
2025 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
2026 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
2027 const int c0_linesize = in->linesize[ plane + 0 ] / 2;
2028 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
2029 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
2030 const uint16_t *c0_data = (const uint16_t *)in->data[plane + 0] + (sliceh_start >> c0_shift_h) * c0_linesize;
2031 const uint16_t *c1_data = (const uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
2032 const uint16_t *c2_data = (const uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
2033 const int d0_linesize = out->linesize[ plane + 0 ] / 2;
2034 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2;
2035 const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2;
2036 const int c0_shift_w = s->shift_w[ component + 0 ];
2037 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
2038 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
2039 int x, y;
2040
2041 if (column) {
2042 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
2043 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
2044 const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
2045 uint16_t *d0_data = (uint16_t *)out->data[plane] + offset_y * d0_linesize + offset_x;
2046 uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
2047 uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
2048 uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
2049 uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data);
2050 uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
2051 uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data);
2052 uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
2053 uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data);
2054
2055 for (y = 0; y < src_h; y++) {
2056 for (x = slicew_start; x < slicew_end; x++) {
2057 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
2058 const int c1 = c1_data[x >> c1_shift_w];
2059 const int c2 = c2_data[x >> c2_shift_w];
2060
2061 update16(d0 + d0_signed_linesize * c0 + x, max, intensity, limit);
2062 *(d1 + d1_signed_linesize * c0 + x) = c1;
2063 *(d2 + d2_signed_linesize * c0 + x) = c2;
2064 }
2065
2066 if (!c0_shift_h || (y & c0_shift_h))
2067 c0_data += c0_linesize;
2068 if (!c1_shift_h || (y & c1_shift_h))
2069 c1_data += c1_linesize;
2070 if (!c2_shift_h || (y & c2_shift_h))
2071 c2_data += c2_linesize;
2072 d0_data += d0_linesize;
2073 d1_data += d1_linesize;
2074 d2_data += d2_linesize;
2075 }
2076 } else {
2077 uint16_t *d0_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
2078 uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
2079 uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
2080
2081 if (mirror) {
2082 d0_data += s->size - 1;
2083 d1_data += s->size - 1;
2084 d2_data += s->size - 1;
2085 }
2086
2087 for (y = sliceh_start; y < sliceh_end; y++) {
2088 for (x = 0; x < src_w; x++) {
2089 const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
2090 const int c1 = c1_data[x >> c1_shift_w];
2091 const int c2 = c2_data[x >> c2_shift_w];
2092
2093 if (mirror) {
2094 update16(d0_data - c0, max, intensity, limit);
2095 *(d1_data - c0) = c1;
2096 *(d2_data - c0) = c2;
2097 } else {
2098 update16(d0_data + c0, max, intensity, limit);
2099 *(d1_data + c0) = c1;
2100 *(d2_data + c0) = c2;
2101 }
2102 }
2103
2104 if (!c0_shift_h || (y & c0_shift_h))
2105 c0_data += c0_linesize;
2106 if (!c1_shift_h || (y & c1_shift_h))
2107 c1_data += c1_linesize;
2108 if (!c2_shift_h || (y & c2_shift_h))
2109 c2_data += c2_linesize;
2110 d0_data += d0_linesize;
2111 d1_data += d1_linesize;
2112 d2_data += d2_linesize;
2113 }
2114 }
2115 }
2116
2117 #define ACOLOR16_FUNC(name, column, mirror) \
2118 static int acolor16_##name(AVFilterContext *ctx, \
2119 void *arg, int jobnr, \
2120 int nb_jobs) \
2121 { \
2122 WaveformContext *s = ctx->priv; \
2123 ThreadData *td = arg; \
2124 AVFrame *in = td->in; \
2125 AVFrame *out = td->out; \
2126 int component = td->component; \
2127 int offset_y = td->offset_y; \
2128 int offset_x = td->offset_x; \
2129 \
2130 acolor16(s, in, out, component, s->intensity,\
2131 offset_y, offset_x, column, mirror, \
2132 jobnr, nb_jobs); \
2133 \
2134 return 0; \
2135 }
2136
2137 ACOLOR16_FUNC(column_mirror, 1, 1)
2138 ACOLOR16_FUNC(column, 1, 0)
2139 ACOLOR16_FUNC(row_mirror, 0, 1)
2140 ACOLOR16_FUNC(row, 0, 0)
2141
2142 static av_always_inline void acolor(WaveformContext *s,
2143 AVFrame *in, AVFrame *out,
2144 int component, int intensity,
2145 int offset_y, int offset_x,
2146 int column, int mirror,
2147 int jobnr, int nb_jobs)
2148 {
2149 const int plane = s->desc->comp[component].plane;
2150 const int src_h = in->height;
2151 const int src_w = in->width;
2152 const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
2153 const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
2154 const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
2155 const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
2156 const int c0_shift_w = s->shift_w[ component + 0 ];
2157 const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
2158 const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
2159 const int c0_shift_h = s->shift_h[ component + 0 ];
2160 const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
2161 const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
2162 const int c0_linesize = in->linesize[ plane + 0 ];
2163 const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
2164 const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
2165 const uint8_t *c0_data = in->data[plane + 0] + (sliceh_start >> c0_shift_h) * c0_linesize;
2166 const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
2167 const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
2168 const int d0_linesize = out->linesize[ plane + 0 ];
2169 const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
2170 const int d2_linesize = out->linesize[(plane + 2) % s->ncomp];
2171 const int max = 255 - intensity;
2172 int x, y;
2173
2174 if (column) {
2175 const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
2176 const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
2177 const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
2178 uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x;
2179 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
2180 uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
2181 uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
2182 uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
2183 uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
2184 uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
2185 uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
2186 uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data);
2187
2188 for (y = 0; y < src_h; y++) {
2189 for (x = slicew_start; x < slicew_end; x++) {
2190 const int c0 = c0_data[x >> c0_shift_w];
2191 const int c1 = c1_data[x >> c1_shift_w];
2192 const int c2 = c2_data[x >> c2_shift_w];
2193
2194 update(d0 + d0_signed_linesize * c0 + x, max, intensity);
2195 *(d1 + d1_signed_linesize * c0 + x) = c1;
2196 *(d2 + d2_signed_linesize * c0 + x) = c2;
2197 }
2198
2199 if (!c0_shift_h || (y & c0_shift_h))
2200 c0_data += c0_linesize;
2201 if (!c1_shift_h || (y & c1_shift_h))
2202 c1_data += c1_linesize;
2203 if (!c2_shift_h || (y & c2_shift_h))
2204 c2_data += c2_linesize;
2205 d0_data += d0_linesize;
2206 d1_data += d1_linesize;
2207 d2_data += d2_linesize;
2208 }
2209 } else {
2210 uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
2211 uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
2212 uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
2213
2214 if (mirror) {
2215 d0_data += s->size - 1;
2216 d1_data += s->size - 1;
2217 d2_data += s->size - 1;
2218 }
2219
2220 for (y = sliceh_start; y < sliceh_end; y++) {
2221 for (x = 0; x < src_w; x++) {
2222 const int c0 = c0_data[x >> c0_shift_w];
2223 const int c1 = c1_data[x >> c1_shift_w];
2224 const int c2 = c2_data[x >> c2_shift_w];
2225
2226 if (mirror) {
2227 update(d0_data - c0, max, intensity);
2228 *(d1_data - c0) = c1;
2229 *(d2_data - c0) = c2;
2230 } else {
2231 update(d0_data + c0, max, intensity);
2232 *(d1_data + c0) = c1;
2233 *(d2_data + c0) = c2;
2234 }
2235 }
2236
2237 if (!c0_shift_h || (y & c0_shift_h))
2238 c0_data += c0_linesize;
2239 if (!c1_shift_h || (y & c1_shift_h))
2240 c1_data += c1_linesize;
2241 if (!c2_shift_h || (y & c2_shift_h))
2242 c2_data += c2_linesize;
2243 d0_data += d0_linesize;
2244 d1_data += d1_linesize;
2245 d2_data += d2_linesize;
2246 }
2247 }
2248 }
2249
2250 #define ACOLOR_FUNC(name, column, mirror) \
2251 static int acolor_##name(AVFilterContext *ctx, \
2252 void *arg, int jobnr, \
2253 int nb_jobs) \
2254 { \
2255 WaveformContext *s = ctx->priv; \
2256 ThreadData *td = arg; \
2257 AVFrame *in = td->in; \
2258 AVFrame *out = td->out; \
2259 int component = td->component; \
2260 int offset_y = td->offset_y; \
2261 int offset_x = td->offset_x; \
2262 \
2263 acolor(s, in, out, component, s->intensity, \
2264 offset_y, offset_x, column, mirror, \
2265 jobnr, nb_jobs); \
2266 \
2267 return 0; \
2268 }
2269
2270 ACOLOR_FUNC(column_mirror, 1, 1)
2271 ACOLOR_FUNC(column, 1, 0)
2272 ACOLOR_FUNC(row_mirror, 0, 1)
2273 ACOLOR_FUNC(row, 0, 0)
2274
2275 static const uint8_t black_yuva_color[4] = { 0, 127, 127, 255 };
2276 static const uint8_t black_gbrp_color[4] = { 0, 0, 0, 255 };
2277
2278 static const GraticuleLines aflat_digital8[] = {
2279 { { { "16", 16+128 }, { "16", 16+128 }, { "16", 16+128 }, { "0", 0+128 } } },
2280 { { { "128", 128+128 }, { "128", 128+128 }, { "128", 128+128 }, { "128", 128+128 } } },
2281 { { { "235", 235+128 }, { "240", 240+128 }, { "240", 240+128 }, { "255", 255+128 } } },
2282 };
2283
2284 static const GraticuleLines aflat_digital9[] = {
2285 { { { "32", 32+256 }, { "32", 32+256 }, { "32", 32+256 }, { "0", 0+256 } } },
2286 { { { "256", 256+256 }, { "256", 256+256 }, { "256", 256+256 }, { "256", 256+256 } } },
2287 { { { "470", 470+256 }, { "480", 480+256 }, { "480", 480+256 }, { "511", 511+256 } } },
2288 };
2289
2290 static const GraticuleLines aflat_digital10[] = {
2291 { { { "64", 64+512 }, { "64", 64+512 }, { "64", 64+512 }, { "0", 0+512 } } },
2292 { { { "512", 512+512 }, { "512", 512+512 }, { "512", 512+512 }, { "512", 512+512 } } },
2293 { { { "940", 940+512 }, { "960", 960+512 }, { "960", 960+512 }, { "1023", 1023+512 } } },
2294 };
2295
2296 static const GraticuleLines aflat_digital12[] = {
2297 { { { "256", 256+2048 }, { "256", 256+2048 }, { "256", 256+2048 }, { "0", 0+2048 } } },
2298 { { { "2048", 2048+2048 }, { "2048", 2048+2048 }, { "2048", 2048+2048 }, { "2048", 2048+2048 } } },
2299 { { { "3760", 3760+2048 }, { "3840", 3840+2048 }, { "3840", 3840+2048 }, { "4095", 4095+2048 } } },
2300 };
2301
2302 static const GraticuleLines aflat_millivolts8[] = {
2303 { { { "0", 16+128 }, { "0", 16+128 }, { "0", 16+128 }, { "0", 0+128 } } },
2304 { { { "175", 71+128 }, { "175", 72+128 }, { "175", 72+128 }, { "175", 64+128 } } },
2305 { { { "350", 126+128 }, { "350", 128+128 }, { "350", 128+128 }, { "350", 128+128 } } },
2306 { { { "525", 180+128 }, { "525", 184+128 }, { "525", 184+128 }, { "525", 192+128 } } },
2307 { { { "700", 235+128 }, { "700", 240+128 }, { "700", 240+128 }, { "700", 255+128 } } },
2308 };
2309
2310 static const GraticuleLines aflat_millivolts9[] = {
2311 { { { "0", 32+256 }, { "0", 32+256 }, { "0", 32+256 }, { "0", 0+256 } } },
2312 { { { "175", 142+256 }, { "175", 144+256 }, { "175", 144+256 }, { "175", 128+256 } } },
2313 { { { "350", 251+256 }, { "350", 256+256 }, { "350", 256+256 }, { "350", 256+256 } } },
2314 { { { "525", 361+256 }, { "525", 368+256 }, { "525", 368+256 }, { "525", 384+256 } } },
2315 { { { "700", 470+256 }, { "700", 480+256 }, { "700", 480+256 }, { "700", 511+256 } } },
2316 };
2317
2318 static const GraticuleLines aflat_millivolts10[] = {
2319 { { { "0", 64+512 }, { "0", 64+512 }, { "0", 64+512 }, { "0", 0+512 } } },
2320 { { { "175", 283+512 }, { "175", 288+512 }, { "175", 288+512 }, { "175", 256+512 } } },
2321 { { { "350", 502+512 }, { "350", 512+512 }, { "350", 512+512 }, { "350", 512+512 } } },
2322 { { { "525", 721+512 }, { "525", 736+512 }, { "525", 736+512 }, { "525", 768+512 } } },
2323 { { { "700", 940+512 }, { "700", 960+512 }, { "700", 960+512 }, { "700", 1023+512 } } },
2324 };
2325
2326 static const GraticuleLines aflat_millivolts12[] = {
2327 { { { "0", 256+2048 }, { "0", 256+2048 }, { "0", 256+2048 }, { "0", 0+2048 } } },
2328 { { { "175", 1132+2048 }, { "175", 1152+2048 }, { "175", 1152+2048 }, { "175", 1024+2048 } } },
2329 { { { "350", 2008+2048 }, { "350", 2048+2048 }, { "350", 2048+2048 }, { "350", 2048+2048 } } },
2330 { { { "525", 2884+2048 }, { "525", 2944+2048 }, { "525", 2944+2048 }, { "525", 3072+2048 } } },
2331 { { { "700", 3760+2048 }, { "700", 3840+2048 }, { "700", 3840+2048 }, { "700", 4095+2048 } } },
2332 };
2333
2334 static const GraticuleLines aflat_ire8[] = {
2335 { { { "-25", -39+128 }, { "-25", -40+128 }, { "-25", -40+128 }, { "-25", -64+128 } } },
2336 { { { "0", 16+128 }, { "0", 16+128 }, { "0", 16+128 }, { "0", 0+128 } } },
2337 { { { "25", 71+128 }, { "25", 72+128 }, { "25", 72+128 }, { "25", 64+128 } } },
2338 { { { "50", 126+128 }, { "50", 128+128 }, { "50", 128+128 }, { "50", 128+128 } } },
2339 { { { "75", 180+128 }, { "75", 184+128 }, { "75", 184+128 }, { "75", 192+128 } } },
2340 { { { "100", 235+128 }, { "100", 240+128 }, { "100", 240+128 }, { "100", 256+128 } } },
2341 { { { "125", 290+128 }, { "125", 296+128 }, { "125", 296+128 }, { "125", 320+128 } } },
2342 };
2343
2344 static const GraticuleLines aflat_ire9[] = {
2345 { { { "-25", -78+256 }, { "-25", -80+256 }, { "-25", -80+256 }, { "-25",-128+256 } } },
2346 { { { "0", 32+256 }, { "0", 32+256 }, { "0", 32+256 }, { "0", 0+256 } } },
2347 { { { "25", 142+256 }, { "25", 144+256 }, { "25", 144+256 }, { "25", 128+256 } } },
2348 { { { "50", 251+256 }, { "50", 256+256 }, { "50", 256+256 }, { "50", 256+256 } } },
2349 { { { "75", 361+256 }, { "75", 368+256 }, { "75", 368+256 }, { "75", 384+256 } } },
2350 { { { "100", 470+256 }, { "100", 480+256 }, { "100", 480+256 }, { "100", 512+256 } } },
2351 { { { "125", 580+256 }, { "125", 592+256 }, { "125", 592+256 }, { "125", 640+256 } } },
2352 };
2353
2354 static const GraticuleLines aflat_ire10[] = {
2355 { { { "-25",-156+512 }, { "-25",-160+512 }, { "-25",-160+512 }, { "-25", -256+512 } } },
2356 { { { "0", 64+512 }, { "0", 64+512 }, { "0", 64+512 }, { "0", 0+512 } } },
2357 { { { "25", 283+512 }, { "25", 288+512 }, { "25", 288+512 }, { "25", 256+512 } } },
2358 { { { "50", 502+512 }, { "50", 512+512 }, { "50", 512+512 }, { "50", 512+512 } } },
2359 { { { "75", 721+512 }, { "75", 736+512 }, { "75", 736+512 }, { "75", 768+512 } } },
2360 { { { "100", 940+512 }, { "100", 960+512 }, { "100", 960+512 }, { "100", 1024+512 } } },
2361 { { { "125",1160+512 }, { "125",1184+512 }, { "125",1184+512 }, { "125", 1280+512 } } },
2362 };
2363
2364 static const GraticuleLines aflat_ire12[] = {
2365 { { { "-25", -624+2048 }, { "-25", -640+2048 }, { "-25", -640+2048 }, { "-25",-1024+2048 } } },
2366 { { { "0", 256+2048 }, { "0", 256+2048 }, { "0", 256+2048 }, { "0", 0+2048 } } },
2367 { { { "25", 1132+2048 }, { "25", 1152+2048 }, { "25", 1152+2048 }, { "25", 1024+2048 } } },
2368 { { { "50", 2008+2048 }, { "50", 2048+2048 }, { "50", 2048+2048 }, { "50", 2048+2048 } } },
2369 { { { "75", 2884+2048 }, { "75", 2944+2048 }, { "75", 2944+2048 }, { "75", 3072+2048 } } },
2370 { { { "100", 3760+2048 }, { "100", 3840+2048 }, { "100", 3840+2048 }, { "100", 4096+2048 } } },
2371 { { { "125", 4640+2048 }, { "125", 4736+2048 }, { "125", 4736+2048 }, { "125", 5120+2048 } } },
2372 };
2373
2374 static const GraticuleLines flat_digital8[] = {
2375 { { { "16", 16+256 }, { "16", 16+256 }, { "16", 16+256 }, { "0", 0+256 } } },
2376 { { { "128", 128+256 }, { "128", 128+256 }, { "128", 128+256 }, { "128", 128+256 } } },
2377 { { { "235", 235+256 }, { "240", 240+256 }, { "240", 240+256 }, { "255", 255+256 } } },
2378 };
2379
2380 static const GraticuleLines flat_digital9[] = {
2381 { { { "32", 32+512 }, { "32", 32+512 }, { "32", 32+512 }, { "0", 0+512 } } },
2382 { { { "256", 256+512 }, { "256", 256+512 }, { "256", 256+512 }, { "256", 256+512 } } },
2383 { { { "470", 470+512 }, { "480", 480+512 }, { "480", 480+512 }, { "511", 511+512 } } },
2384 };
2385
2386 static const GraticuleLines flat_digital10[] = {
2387 { { { "64", 64+1024 }, { "64", 64+1024 }, { "64", 64+1024 }, { "0", 0+1024 } } },
2388 { { { "512", 512+1024 }, { "512", 512+1024 }, { "512", 512+1024 }, { "512", 512+1024 } } },
2389 { { { "940", 940+1024 }, { "960", 960+1024 }, { "960", 960+1024 }, { "1023", 1023+1024 } } },
2390 };
2391
2392 static const GraticuleLines flat_digital12[] = {
2393 { { { "256", 256+4096 }, { "256", 256+4096 }, { "256", 256+4096 }, { "0", 0+4096 } } },
2394 { { { "2048", 2048+4096 }, { "2048", 2048+4096 }, { "2048", 2048+4096 }, { "2048", 2048+4096 } } },
2395 { { { "3760", 3760+4096 }, { "3840", 3840+4096 }, { "3840", 3840+4096 }, { "4095", 4095+4096 } } },
2396 };
2397
2398 static const GraticuleLines flat_millivolts8[] = {
2399 { { { "0", 16+256 }, { "0", 16+256 }, { "0", 16+256 }, { "0", 0+256 } } },
2400 { { { "175", 71+256 }, { "175", 72+256 }, { "175", 72+256 }, { "175", 64+256 } } },
2401 { { { "350", 126+256 }, { "350", 128+256 }, { "350", 128+256 }, { "350", 128+256 } } },
2402 { { { "525", 180+256 }, { "525", 184+256 }, { "525", 184+256 }, { "525", 192+256 } } },
2403 { { { "700", 235+256 }, { "700", 240+256 }, { "700", 240+256 }, { "700", 255+256 } } },
2404 };
2405
2406 static const GraticuleLines flat_millivolts9[] = {
2407 { { { "0", 32+512 }, { "0", 32+512 }, { "0", 32+512 }, { "0", 0+512 } } },
2408 { { { "175", 142+512 }, { "175", 144+512 }, { "175", 144+512 }, { "175", 128+512 } } },
2409 { { { "350", 251+512 }, { "350", 256+512 }, { "350", 256+512 }, { "350", 256+512 } } },
2410 { { { "525", 361+512 }, { "525", 368+512 }, { "525", 368+512 }, { "525", 384+512 } } },
2411 { { { "700", 470+512 }, { "700", 480+512 }, { "700", 480+512 }, { "700", 511+512 } } },
2412 };
2413
2414 static const GraticuleLines flat_millivolts10[] = {
2415 { { { "0", 64+1024 }, { "0", 64+1024 }, { "0", 64+1024 }, { "0", 0+1024 } } },
2416 { { { "175", 283+1024 }, { "175", 288+1024 }, { "175", 288+1024 }, { "175", 256+1024 } } },
2417 { { { "350", 502+1024 }, { "350", 512+1024 }, { "350", 512+1024 }, { "350", 512+1024 } } },
2418 { { { "525", 721+1024 }, { "525", 736+1024 }, { "525", 736+1024 }, { "525", 768+1024 } } },
2419 { { { "700", 940+1024 }, { "700", 960+1024 }, { "700", 960+1024 }, { "700", 1023+1024 } } },
2420 };
2421
2422 static const GraticuleLines flat_millivolts12[] = {
2423 { { { "0", 256+4096 }, { "0", 256+4096 }, { "0", 256+4096 }, { "0", 0+4096 } } },
2424 { { { "175", 1132+4096 }, { "175", 1152+4096 }, { "175", 1152+4096 }, { "175", 1024+4096 } } },
2425 { { { "350", 2008+4096 }, { "350", 2048+4096 }, { "350", 2048+4096 }, { "350", 2048+4096 } } },
2426 { { { "525", 2884+4096 }, { "525", 2944+4096 }, { "525", 2944+4096 }, { "525", 3072+4096 } } },
2427 { { { "700", 3760+4096 }, { "700", 3840+4096 }, { "700", 3840+4096 }, { "700", 4095+4096 } } },
2428 };
2429
2430 static const GraticuleLines flat_ire8[] = {
2431 { { { "-25", -39+256 }, { "-25", -40+256 }, { "-25", -40+256 }, { "-25", -64+256 } } },
2432 { { { "0", 16+256 }, { "0", 16+256 }, { "0", 16+256 }, { "0", 0+256 } } },
2433 { { { "25", 71+256 }, { "25", 72+256 }, { "25", 72+256 }, { "25", 64+256 } } },
2434 { { { "50", 126+256 }, { "50", 128+256 }, { "50", 128+256 }, { "50", 128+256 } } },
2435 { { { "75", 180+256 }, { "75", 184+256 }, { "75", 184+256 }, { "75", 192+256 } } },
2436 { { { "100", 235+256 }, { "100", 240+256 }, { "100", 240+256 }, { "100", 256+256 } } },
2437 { { { "125", 290+256 }, { "125", 296+256 }, { "125", 296+256 }, { "125", 320+256 } } },
2438 };
2439
2440 static const GraticuleLines flat_ire9[] = {
2441 { { { "-25", -78+512 }, { "-25", -80+512 }, { "-25", -80+512 }, { "-25",-128+512 } } },
2442 { { { "0", 32+512 }, { "0", 32+512 }, { "0", 32+512 }, { "0", 0+512 } } },
2443 { { { "25", 142+512 }, { "25", 144+512 }, { "25", 144+512 }, { "25", 128+512 } } },
2444 { { { "50", 251+512 }, { "50", 256+512 }, { "50", 256+512 }, { "50", 256+512 } } },
2445 { { { "75", 361+512 }, { "75", 368+512 }, { "75", 368+512 }, { "75", 384+512 } } },
2446 { { { "100", 470+512 }, { "100", 480+512 }, { "100", 480+512 }, { "100", 512+512 } } },
2447 { { { "125", 580+512 }, { "125", 592+512 }, { "125", 592+512 }, { "125", 640+512 } } },
2448 };
2449
2450 static const GraticuleLines flat_ire10[] = {
2451 { { { "-25",-156+1024 }, { "-25",-160+1024 }, { "-25",-160+1024 }, { "-25", -256+1024 } } },
2452 { { { "0", 64+1024 }, { "0", 64+1024 }, { "0", 64+1024 }, { "0", 0+1024 } } },
2453 { { { "25", 283+1024 }, { "25", 288+1024 }, { "25", 288+1024 }, { "25", 256+1024 } } },
2454 { { { "50", 502+1024 }, { "50", 512+1024 }, { "50", 512+1024 }, { "50", 512+1024 } } },
2455 { { { "75", 721+1024 }, { "75", 736+1024 }, { "75", 736+1024 }, { "75", 768+1024 } } },
2456 { { { "100", 940+1024 }, { "100", 960+1024 }, { "100", 960+1024 }, { "100", 1024+1024 } } },
2457 { { { "125",1160+1024 }, { "125",1184+1024 }, { "125",1184+1024 }, { "125", 1280+1024 } } },
2458 };
2459
2460 static const GraticuleLines flat_ire12[] = {
2461 { { { "-25", -624+4096 }, { "-25", -640+4096 }, { "-25", -640+4096 }, { "-25",-1024+4096 } } },
2462 { { { "0", 256+4096 }, { "0", 256+4096 }, { "0", 256+4096 }, { "0", 0+4096 } } },
2463 { { { "25", 1132+4096 }, { "25", 1152+4096 }, { "25", 1152+4096 }, { "25", 1024+4096 } } },
2464 { { { "50", 2008+4096 }, { "50", 2048+4096 }, { "50", 2048+4096 }, { "50", 2048+4096 } } },
2465 { { { "75", 2884+4096 }, { "75", 2944+4096 }, { "75", 2944+4096 }, { "75", 3072+4096 } } },
2466 { { { "100", 3760+4096 }, { "100", 3840+4096 }, { "100", 3840+4096 }, { "100", 4096+4096 } } },
2467 { { { "125", 4640+4096 }, { "125", 4736+4096 }, { "125", 4736+4096 }, { "125", 5120+4096 } } },
2468 };
2469
2470 static const GraticuleLines digital8[] = {
2471 { { { "16", 16 }, { "16", 16 }, { "16", 16 }, { "0", 0 } } },
2472 { { { "128", 128 }, { "128", 128 }, { "128", 128 }, { "128", 128 } } },
2473 { { { "235", 235 }, { "240", 240 }, { "240", 240 }, { "255", 255 } } },
2474 };
2475
2476 static const GraticuleLines digital9[] = {
2477 { { { "32", 32 }, { "32", 32 }, { "32", 32 }, { "0", 0 } } },
2478 { { { "256", 256 }, { "256", 256 }, { "256", 256 }, { "256", 256 } } },
2479 { { { "470", 470 }, { "480", 480 }, { "480", 480 }, { "511", 511 } } },
2480 };
2481
2482 static const GraticuleLines digital10[] = {
2483 { { { "64", 64 }, { "64", 64 }, { "64", 64 }, { "0", 0 } } },
2484 { { { "512", 512 }, { "512", 512 }, { "512", 512 }, { "512", 512 } } },
2485 { { { "940", 940 }, { "960", 960 }, { "960", 960 }, { "1023", 1023 } } },
2486 };
2487
2488 static const GraticuleLines digital12[] = {
2489 { { { "256", 256 }, { "256", 256 }, { "256", 256 }, { "0", 0 } } },
2490 { { { "2048", 2048 }, { "2048", 2048 }, { "2048", 2048 }, { "2048", 2048 } } },
2491 { { { "3760", 3760 }, { "3840", 3840 }, { "3840", 3840 }, { "4095", 4095 } } },
2492 };
2493
2494 static const GraticuleLines millivolts8[] = {
2495 { { { "0", 16 }, { "0", 16 }, { "0", 16 }, { "0", 0 } } },
2496 { { { "175", 71 }, { "175", 72 }, { "175", 72 }, { "175", 64 } } },
2497 { { { "350", 126 }, { "350", 128 }, { "350", 128 }, { "350", 128 } } },
2498 { { { "525", 180 }, { "525", 184 }, { "525", 184 }, { "525", 192 } } },
2499 { { { "700", 235 }, { "700", 240 }, { "700", 240 }, { "700", 255 } } },
2500 };
2501
2502 static const GraticuleLines millivolts9[] = {
2503 { { { "0", 32 }, { "0", 32 }, { "0", 32 }, { "0", 0 } } },
2504 { { { "175", 142 }, { "175", 144 }, { "175", 144 }, { "175", 128 } } },
2505 { { { "350", 251 }, { "350", 256 }, { "350", 256 }, { "350", 256 } } },
2506 { { { "525", 361 }, { "525", 368 }, { "525", 368 }, { "525", 384 } } },
2507 { { { "700", 470 }, { "700", 480 }, { "700", 480 }, { "700", 511 } } },
2508 };
2509
2510 static const GraticuleLines millivolts10[] = {
2511 { { { "0", 64 }, { "0", 64 }, { "0", 64 }, { "0", 0 } } },
2512 { { { "175", 283 }, { "175", 288 }, { "175", 288 }, { "175", 256 } } },
2513 { { { "350", 502 }, { "350", 512 }, { "350", 512 }, { "350", 512 } } },
2514 { { { "525", 721 }, { "525", 736 }, { "525", 736 }, { "525", 768 } } },
2515 { { { "700", 940 }, { "700", 960 }, { "700", 960 }, { "700", 1023 } } },
2516 };
2517
2518 static const GraticuleLines millivolts12[] = {
2519 { { { "0", 256 }, { "0", 256 }, { "0", 256 }, { "0", 0 } } },
2520 { { { "175", 1132 }, { "175", 1152 }, { "175", 1152 }, { "175", 1024 } } },
2521 { { { "350", 2008 }, { "350", 2048 }, { "350", 2048 }, { "350", 2048 } } },
2522 { { { "525", 2884 }, { "525", 2944 }, { "525", 2944 }, { "525", 3072 } } },
2523 { { { "700", 3760 }, { "700", 3840 }, { "700", 3840 }, { "700", 4095 } } },
2524 };
2525
2526 static const GraticuleLines ire8[] = {
2527 { { { "0", 16 }, { "0", 16 }, { "0", 16 }, { "0", 0 } } },
2528 { { { "25", 71 }, { "25", 72 }, { "25", 72 }, { "25", 64 } } },
2529 { { { "50", 126 }, { "50", 128 }, { "50", 128 }, { "50", 128 } } },
2530 { { { "75", 180 }, { "75", 184 }, { "75", 184 }, { "75", 192 } } },
2531 { { { "100", 235 }, { "100", 240 }, { "100", 240 }, { "100", 255 } } },
2532 };
2533
2534 static const GraticuleLines ire9[] = {
2535 { { { "0", 32 }, { "0", 32 }, { "0", 32 }, { "0", 0 } } },
2536 { { { "25", 142 }, { "25", 144 }, { "25", 144 }, { "25", 128 } } },
2537 { { { "50", 251 }, { "50", 256 }, { "50", 256 }, { "50", 256 } } },
2538 { { { "75", 361 }, { "75", 368 }, { "75", 368 }, { "75", 384 } } },
2539 { { { "100", 470 }, { "100", 480 }, { "100", 480 }, { "100", 511 } } },
2540 };
2541
2542 static const GraticuleLines ire10[] = {
2543 { { { "0", 64 }, { "0", 64 }, { "0", 64 }, { "0", 0 } } },
2544 { { { "25", 283 }, { "25", 288 }, { "25", 288 }, { "25", 256 } } },
2545 { { { "50", 502 }, { "50", 512 }, { "50", 512 }, { "50", 512 } } },
2546 { { { "75", 721 }, { "75", 736 }, { "75", 736 }, { "75", 768 } } },
2547 { { { "100", 940 }, { "100", 960 }, { "100", 960 }, { "100", 1023 } } },
2548 };
2549
2550 static const GraticuleLines ire12[] = {
2551 { { { "0", 256 }, { "0", 256 }, { "0", 256 }, { "0", 0 } } },
2552 { { { "25", 1132 }, { "25", 1152 }, { "25", 1152 }, { "25", 1024 } } },
2553 { { { "50", 2008 }, { "50", 2048 }, { "50", 2048 }, { "50", 2048 } } },
2554 { { { "75", 2884 }, { "75", 2944 }, { "75", 2944 }, { "75", 3072 } } },
2555 { { { "100", 3760 }, { "100", 3840 }, { "100", 3840 }, { "100", 4095 } } },
2556 };
2557
2558 static const GraticuleLines chroma_digital8[] = {
2559 { { { "50", 50 }, { "50", 50 }, { "50", 50 }, { "50", 50 } } },
2560 { { { "100", 100 }, { "100", 100 }, { "100", 100 }, { "100", 100 } } },
2561 { { { "150", 150 }, { "150", 150 }, { "150", 150 }, { "150", 150 } } },
2562 { { { "200", 200 }, { "200", 200 }, { "200", 200 }, { "200", 200 } } },
2563 { { { "255", 255 }, { "255", 255 }, { "255", 255 }, { "255", 255 } } },
2564 };
2565
2566 static const GraticuleLines chroma_digital9[] = {
2567 { { { "100", 100 }, { "100", 100 }, { "100", 100 }, { "100", 100 } } },
2568 { { { "200", 200 }, { "200", 200 }, { "200", 200 }, { "200", 200 } } },
2569 { { { "300", 300 }, { "300", 300 }, { "300", 300 }, { "300", 300 } } },
2570 { { { "400", 400 }, { "400", 400 }, { "400", 400 }, { "400", 400 } } },
2571 { { { "500", 500 }, { "500", 500 }, { "500", 500 }, { "500", 500 } } },
2572 };
2573
2574 static const GraticuleLines chroma_digital10[] = {
2575 { { { "200", 200 }, { "200", 200 }, { "200", 200 }, { "200", 200 } } },
2576 { { { "400", 400 }, { "400", 400 }, { "400", 400 }, { "400", 400 } } },
2577 { { { "600", 600 }, { "600", 600 }, { "600", 600 }, { "600", 600 } } },
2578 { { { "800", 800 }, { "800", 800 }, { "800", 800 }, { "800", 800 } } },
2579 { { {"1000",1000 }, {"1000",1000 }, {"1000",1000 }, {"1000",1000 } } },
2580 };
2581
2582 static const GraticuleLines chroma_digital12[] = {
2583 { { { "800", 800 }, { "800", 800 }, { "800", 800 }, { "800", 800 } } },
2584 { { { "1600", 1600 }, { "1600", 1600 }, { "1600", 1600 }, { "1600", 1600 } } },
2585 { { { "2400", 2400 }, { "2400", 2400 }, { "2400", 2400 }, { "2400", 2400 } } },
2586 { { { "3200", 3200 }, { "3200", 3200 }, { "3200", 3200 }, { "3200", 3200 } } },
2587 { { { "4000", 4000 }, { "4000", 4000 }, { "4000", 4000 }, { "4000", 4000 } } },
2588 };
2589
2590 static void blend_vline(uint8_t *dst, int height, int linesize, float o1, float o2, int v, int step)
2591 {
2592 int y;
2593
2594 for (y = 0; y < height; y += step) {
2595 dst[0] = v * o1 + dst[0] * o2;
2596
2597 dst += linesize * step;
2598 }
2599 }
2600
2601 static void blend_vline16(uint8_t *ddst, int height, int linesize, float o1, float o2, int v, int step)
2602 {
2603 uint16_t *dst = (uint16_t *)ddst;
2604 int y;
2605
2606 for (y = 0; y < height; y += step) {
2607 dst[0] = v * o1 + dst[0] * o2;
2608
2609 dst += (linesize / 2) * step;
2610 }
2611 }
2612
2613 static void blend_hline(uint8_t *dst, int width, int unused, float o1, float o2, int v, int step)
2614 {
2615 int x;
2616
2617 for (x = 0; x < width; x += step) {
2618 dst[x] = v * o1 + dst[x] * o2;
2619 }
2620 }
2621
2622 static void blend_hline16(uint8_t *ddst, int width, int unused, float o1, float o2, int v, int step)
2623 {
2624 uint16_t *dst = (uint16_t *)ddst;
2625 int x;
2626
2627 for (x = 0; x < width; x += step) {
2628 dst[x] = v * o1 + dst[x] * o2;
2629 }
2630 }
2631
2632 static void draw_htext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2633 {
2634 const uint8_t *font;
2635 int font_height;
2636 int i, plane;
2637
2638 font = avpriv_cga_font_get(), font_height = 8;
2639
2640 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2641 for (i = 0; txt[i]; i++) {
2642 int char_y, mask;
2643 int v = color[plane];
2644
2645 uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
2646 for (char_y = 0; char_y < font_height; char_y++) {
2647 for (mask = 0x80; mask; mask >>= 1) {
2648 if (font[txt[i] * font_height + char_y] & mask)
2649 p[0] = p[0] * o2 + v * o1;
2650 p++;
2651 }
2652 p += out->linesize[plane] - 8;
2653 }
2654 }
2655 }
2656 }
2657
2658 static void draw_htext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2659 {
2660 const uint8_t *font;
2661 int font_height;
2662 int i, plane;
2663
2664 font = avpriv_cga_font_get(), font_height = 8;
2665
2666 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2667 for (i = 0; txt[i]; i++) {
2668 int char_y, mask;
2669 int v = color[plane] * mult;
2670
2671 uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
2672 for (char_y = 0; char_y < font_height; char_y++) {
2673 for (mask = 0x80; mask; mask >>= 1) {
2674 if (font[txt[i] * font_height + char_y] & mask)
2675 p[0] = p[0] * o2 + v * o1;
2676 p++;
2677 }
2678 p += out->linesize[plane] / 2 - 8;
2679 }
2680 }
2681 }
2682 }
2683
2684 static void draw_vtext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2685 {
2686 const uint8_t *font;
2687 int font_height;
2688 int i, plane;
2689
2690 font = avpriv_cga_font_get(), font_height = 8;
2691
2692 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2693 for (i = 0; txt[i]; i++) {
2694 int char_y, mask;
2695 int v = color[plane];
2696
2697 for (char_y = font_height - 1; char_y >= 0; char_y--) {
2698 uint8_t *p = out->data[plane] + (y + i * 10) * out->linesize[plane] + x;
2699 for (mask = 0x80; mask; mask >>= 1) {
2700 if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2701 p[char_y] = p[char_y] * o2 + v * o1;
2702 p += out->linesize[plane];
2703 }
2704 }
2705 }
2706 }
2707 }
2708
2709 static void draw_vtext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2710 {
2711 const uint8_t *font;
2712 int font_height;
2713 int i, plane;
2714
2715 font = avpriv_cga_font_get(), font_height = 8;
2716
2717 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2718 for (i = 0; txt[i]; i++) {
2719 int char_y, mask;
2720 int v = color[plane] * mult;
2721
2722 for (char_y = 0; char_y < font_height; char_y++) {
2723 uint16_t *p = (uint16_t *)(out->data[plane] + (y + i * 10) * out->linesize[plane]) + x;
2724 for (mask = 0x80; mask; mask >>= 1) {
2725 if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2726 p[char_y] = p[char_y] * o2 + v * o1;
2727 p += out->linesize[plane] / 2;
2728 }
2729 }
2730 }
2731 }
2732 }
2733
2734 static void iblend_vline(uint8_t *dst, int height, int linesize, float o1, float o2, int v, int step)
2735 {
2736 int y;
2737
2738 for (y = 0; y < height; y += step) {
2739 dst[0] = (v - dst[0]) * o1 + dst[0] * o2;
2740
2741 dst += linesize * step;
2742 }
2743 }
2744
2745 static void iblend_vline16(uint8_t *ddst, int height, int linesize, float o1, float o2, int v, int step)
2746 {
2747 uint16_t *dst = (uint16_t *)ddst;
2748 int y;
2749
2750 for (y = 0; y < height; y += step) {
2751 dst[0] = (v - dst[0]) * o1 + dst[0] * o2;
2752
2753 dst += (linesize / 2) * step;
2754 }
2755 }
2756
2757 static void iblend_hline(uint8_t *dst, int width, int unused, float o1, float o2, int v, int step)
2758 {
2759 int x;
2760
2761 for (x = 0; x < width; x += step) {
2762 dst[x] = (v - dst[x]) * o1 + dst[x] * o2;
2763 }
2764 }
2765
2766 static void iblend_hline16(uint8_t *ddst, int width, int unused, float o1, float o2, int v, int step)
2767 {
2768 uint16_t *dst = (uint16_t *)ddst;
2769 int x;
2770
2771 for (x = 0; x < width; x += step) {
2772 dst[x] = (v - dst[x]) * o1 + dst[x] * o2;
2773 }
2774 }
2775
2776 static void idraw_htext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2777 {
2778 const uint8_t *font;
2779 int font_height;
2780 int i, plane;
2781
2782 font = avpriv_cga_font_get(), font_height = 8;
2783
2784 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2785 for (i = 0; txt[i]; i++) {
2786 int char_y, mask;
2787 int v = color[plane];
2788
2789 uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
2790 for (char_y = 0; char_y < font_height; char_y++) {
2791 for (mask = 0x80; mask; mask >>= 1) {
2792 if (font[txt[i] * font_height + char_y] & mask)
2793 p[0] = p[0] * o2 + (v - p[0]) * o1;
2794 p++;
2795 }
2796 p += out->linesize[plane] - 8;
2797 }
2798 }
2799 }
2800 }
2801
2802 static void idraw_htext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2803 {
2804 const uint8_t *font;
2805 int font_height;
2806 int i, plane;
2807
2808 font = avpriv_cga_font_get(), font_height = 8;
2809
2810 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2811 for (i = 0; txt[i]; i++) {
2812 int char_y, mask;
2813 int v = color[plane] * mult;
2814
2815 uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
2816 for (char_y = 0; char_y < font_height; char_y++) {
2817 for (mask = 0x80; mask; mask >>= 1) {
2818 if (font[txt[i] * font_height + char_y] & mask)
2819 p[0] = p[0] * o2 + (v - p[0]) * o1;
2820 p++;
2821 }
2822 p += out->linesize[plane] / 2 - 8;
2823 }
2824 }
2825 }
2826 }
2827
2828 static void idraw_vtext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2829 {
2830 const uint8_t *font;
2831 int font_height;
2832 int i, plane;
2833
2834 font = avpriv_cga_font_get(), font_height = 8;
2835
2836 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2837 for (i = 0; txt[i]; i++) {
2838 int char_y, mask;
2839 int v = color[plane];
2840
2841 for (char_y = font_height - 1; char_y >= 0; char_y--) {
2842 uint8_t *p = out->data[plane] + (y + i * 10) * out->linesize[plane] + x;
2843 for (mask = 0x80; mask; mask >>= 1) {
2844 if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2845 p[char_y] = p[char_y] * o2 + (v - p[char_y]) * o1;
2846 p += out->linesize[plane];
2847 }
2848 }
2849 }
2850 }
2851 }
2852
2853 static void idraw_vtext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2854 {
2855 const uint8_t *font;
2856 int font_height;
2857 int i, plane;
2858
2859 font = avpriv_cga_font_get(), font_height = 8;
2860
2861 for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2862 for (i = 0; txt[i]; i++) {
2863 int char_y, mask;
2864 int v = color[plane] * mult;
2865
2866 for (char_y = 0; char_y < font_height; char_y++) {
2867 uint16_t *p = (uint16_t *)(out->data[plane] + (y + i * 10) * out->linesize[plane]) + x;
2868 for (mask = 0x80; mask; mask >>= 1) {
2869 if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2870 p[char_y] = p[char_y] * o2 + (v - p[char_y]) * o1;
2871 p += out->linesize[plane] / 2;
2872 }
2873 }
2874 }
2875 }
2876 }
2877
2878 200 static void graticule_none(WaveformContext *s, AVFrame *out)
2879 {
2880 200 }
2881
2882 static void graticule_row(WaveformContext *s, AVFrame *out)
2883 {
2884 const int step = (s->flags & 2) + 1;
2885 const float o1 = s->opacity;
2886 const float o2 = 1. - o1;
2887 const int height = s->display == PARADE ? out->height / s->acomp : out->height;
2888 int C, k = 0, c, p, l, offset_x = 0, offset_y = 0;
2889
2890 for (c = 0; c < s->ncomp; c++) {
2891 if (!((1 << c) & s->pcomp) || (!s->display && k > 0))
2892 continue;
2893
2894 k++;
2895 C = s->rgb ? 0 : c;
2896 for (p = 0; p < s->ncomp; p++) {
2897 const int v = s->grat_yuva_color[p];
2898 for (l = 0; l < s->nb_glines; l++) {
2899 const uint16_t pos = s->glines[l].line[C].pos;
2900 int x = offset_x + (s->mirror ? s->size - 1 - pos : pos);
2901 uint8_t *dst = out->data[p] + offset_y * out->linesize[p] + x;
2902
2903 s->blend_line(dst, height, out->linesize[p], o1, o2, v, step);
2904 }
2905 }
2906
2907 for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
2908 const char *name = s->glines[l].line[C].name;
2909 const uint16_t pos = s->glines[l].line[C].pos;
2910 int x = offset_x + (s->mirror ? s->size - 1 - pos : pos) - 10;
2911
2912 if (x < 0)
2913 x = 4;
2914
2915 s->draw_text(out, x, offset_y + 2, 1, o1, o2, name, s->grat_yuva_color);
2916 }
2917
2918 offset_x += s->size * (s->display == STACK);
2919 offset_y += height * (s->display == PARADE);
2920 }
2921 }
2922
2923 static void graticule16_row(WaveformContext *s, AVFrame *out)
2924 {
2925 const int step = (s->flags & 2) + 1;
2926 const float o1 = s->opacity;
2927 const float o2 = 1. - o1;
2928 const int mult = s->max / 256;
2929 const int height = s->display == PARADE ? out->height / s->acomp : out->height;
2930 int C, k = 0, c, p, l, offset_x = 0, offset_y = 0;
2931
2932 for (c = 0; c < s->ncomp; c++) {
2933 if (!((1 << c) & s->pcomp) || (!s->display && k > 0))
2934 continue;
2935
2936 k++;
2937 C = s->rgb ? 0 : c;
2938 for (p = 0; p < s->ncomp; p++) {
2939 const int v = s->grat_yuva_color[p] * mult;
2940 for (l = 0; l < s->nb_glines ; l++) {
2941 const uint16_t pos = s->glines[l].line[C].pos;
2942 int x = offset_x + (s->mirror ? s->size - 1 - pos : pos);
2943 uint8_t *dst = (uint8_t *)(out->data[p] + offset_y * out->linesize[p]) + x * 2;
2944
2945 s->blend_line(dst, height, out->linesize[p], o1, o2, v, step);
2946 }
2947 }
2948
2949 for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
2950 const char *name = s->glines[l].line[C].name;
2951 const uint16_t pos = s->glines[l].line[C].pos;
2952 int x = offset_x + (s->mirror ? s->size - 1 - pos : pos) - 10;
2953
2954 if (x < 0)
2955 x = 4;
2956
2957 s->draw_text(out, x, offset_y + 2, mult, o1, o2, name, s->grat_yuva_color);
2958 }
2959
2960 offset_x += s->size * (s->display == STACK);
2961 offset_y += height * (s->display == PARADE);
2962 }
2963 }
2964
2965 static void graticule_column(WaveformContext *s, AVFrame *out)
2966 {
2967 const int step = (s->flags & 2) + 1;
2968 const float o1 = s->opacity;
2969 const float o2 = 1. - o1;
2970 const int width = s->display == PARADE ? out->width / s->acomp : out->width;
2971 int C, k = 0, c, p, l, offset_y = 0, offset_x = 0;
2972
2973 for (c = 0; c < s->ncomp; c++) {
2974 if ((!((1 << c) & s->pcomp) || (!s->display && k > 0)))
2975 continue;
2976
2977 k++;
2978 C = s->rgb ? 0 : c;
2979 for (p = 0; p < s->ncomp; p++) {
2980 const int v = s->grat_yuva_color[p];
2981 for (l = 0; l < s->nb_glines ; l++) {
2982 const uint16_t pos = s->glines[l].line[C].pos;
2983 int y = offset_y + (s->mirror ? s->size - 1 - pos : pos);
2984 uint8_t *dst = out->data[p] + y * out->linesize[p] + offset_x;
2985
2986 s->blend_line(dst, width, 1, o1, o2, v, step);
2987 }
2988 }
2989
2990 for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
2991 const char *name = s->glines[l].line[C].name;
2992 const uint16_t pos = s->glines[l].line[C].pos;
2993 int y = offset_y + (s->mirror ? s->size - 1 - pos : pos) - 10;
2994
2995 if (y < 0)
2996 y = 4;
2997
2998 s->draw_text(out, 2 + offset_x, y, 1, o1, o2, name, s->grat_yuva_color);
2999 }
3000
3001 offset_y += s->size * (s->display == STACK);
3002 offset_x += width * (s->display == PARADE);
3003 }
3004 }
3005
3006 static void graticule16_column(WaveformContext *s, AVFrame *out)
3007 {
3008 const int step = (s->flags & 2) + 1;
3009 const float o1 = s->opacity;
3010 const float o2 = 1. - o1;
3011 const int mult = s->max / 256;
3012 const int width = s->display == PARADE ? out->width / s->acomp : out->width;
3013 int C, k = 0, c, p, l, offset_x = 0, offset_y = 0;
3014
3015 for (c = 0; c < s->ncomp; c++) {
3016 if ((!((1 << c) & s->pcomp) || (!s->display && k > 0)))
3017 continue;
3018
3019 k++;
3020 C = s->rgb ? 0 : c;
3021 for (p = 0; p < s->ncomp; p++) {
3022 const int v = s->grat_yuva_color[p] * mult;
3023 for (l = 0; l < s->nb_glines ; l++) {
3024 const uint16_t pos = s->glines[l].line[C].pos;
3025 int y = offset_y + (s->mirror ? s->size - 1 - pos : pos);
3026 uint8_t *dst = (uint8_t *)(out->data[p] + y * out->linesize[p]) + offset_x * 2;
3027
3028 s->blend_line(dst, width, 1, o1, o2, v, step);
3029 }
3030 }
3031
3032 for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
3033 const char *name = s->glines[l].line[C].name;
3034 const uint16_t pos = s->glines[l].line[C].pos;
3035 int y = offset_y + (s->mirror ? s->size - 1 - pos: pos) - 10;
3036
3037 if (y < 0)
3038 y = 4;
3039
3040 s->draw_text(out, 2 + offset_x, y, mult, o1, o2, name, s->grat_yuva_color);
3041 }
3042
3043 offset_y += s->size * (s->display == STACK);
3044 offset_x += width * (s->display == PARADE);
3045 }
3046 }
3047
3048 4 static int config_input(AVFilterLink *inlink)
3049 {
3050 4 AVFilterContext *ctx = inlink->dst;
3051 4 WaveformContext *s = ctx->priv;
3052
3053 4 s->desc = av_pix_fmt_desc_get(inlink->format);
3054 4 s->ncomp = s->desc->nb_components;
3055 4 s->bits = s->desc->comp[0].depth;
3056 4 s->max = 1 << s->bits;
3057
3058 4 s->shift_w[0] = s->shift_w[3] = 0;
3059 4 s->shift_h[0] = s->shift_h[3] = 0;
3060 4 s->shift_w[1] = s->shift_w[2] = s->desc->log2_chroma_w;
3061 4 s->shift_h[1] = s->shift_h[2] = s->desc->log2_chroma_h;
3062
3063 4 s->graticulef = graticule_none;
3064
3065
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 switch (s->filter) {
3066 case XFLAT:
3067 case YFLAT:
3068 case AFLAT: s->size = 256 * 2; break;
3069 case FLAT: s->size = 256 * 3; break;
3070 4 default: s->size = 256; break;
3071 }
3072
3073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 switch (s->filter | ((s->bits > 8) << 4) |
3074
2/65
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
4 (s->mode << 8) | (s->mirror << 12)) {
3075 3 case 0x1100: s->waveform_slice = lowpass_column_mirror; break;
3076 1 case 0x1000: s->waveform_slice = lowpass_row_mirror; break;
3077 case 0x0100: s->waveform_slice = lowpass_column; break;
3078 case 0x0000: s->waveform_slice = lowpass_row; break;
3079 case 0x1110: s->waveform_slice = lowpass16_column_mirror; break;
3080 case 0x1010: s->waveform_slice = lowpass16_row_mirror; break;
3081 case 0x0110: s->waveform_slice = lowpass16_column; break;
3082 case 0x0010: s->waveform_slice = lowpass16_row; break;
3083 case 0x1101: s->waveform_slice = flat_column_mirror; break;
3084 case 0x1001: s->waveform_slice = flat_row_mirror; break;
3085 case 0x0101: s->waveform_slice = flat_column; break;
3086 case 0x0001: s->waveform_slice = flat_row; break;
3087 case 0x1111: s->waveform_slice = flat16_column_mirror; break;
3088 case 0x1011: s->waveform_slice = flat16_row_mirror; break;
3089 case 0x0111: s->waveform_slice = flat16_column; break;
3090 case 0x0011: s->waveform_slice = flat16_row; break;
3091 case 0x1102: s->waveform_slice = aflat_column_mirror; break;
3092 case 0x1002: s->waveform_slice = aflat_row_mirror; break;
3093 case 0x0102: s->waveform_slice = aflat_column; break;
3094 case 0x0002: s->waveform_slice = aflat_row; break;
3095 case 0x1112: s->waveform_slice = aflat16_column_mirror; break;
3096 case 0x1012: s->waveform_slice = aflat16_row_mirror; break;
3097 case 0x0112: s->waveform_slice = aflat16_column; break;
3098 case 0x0012: s->waveform_slice = aflat16_row; break;
3099 case 0x1103: s->waveform_slice = chroma_column_mirror; break;
3100 case 0x1003: s->waveform_slice = chroma_row_mirror; break;
3101 case 0x0103: s->waveform_slice = chroma_column; break;
3102 case 0x0003: s->waveform_slice = chroma_row; break;
3103 case 0x1113: s->waveform_slice = chroma16_column_mirror; break;
3104 case 0x1013: s->waveform_slice = chroma16_row_mirror; break;
3105 case 0x0113: s->waveform_slice = chroma16_column; break;
3106 case 0x0013: s->waveform_slice = chroma16_row; break;
3107 case 0x1104: s->waveform_slice = color_column_mirror; break;
3108 case 0x1004: s->waveform_slice = color_row_mirror; break;
3109 case 0x0104: s->waveform_slice = color_column; break;
3110 case 0x0004: s->waveform_slice = color_row; break;
3111 case 0x1114: s->waveform_slice = color16_column_mirror; break;
3112 case 0x1014: s->waveform_slice = color16_row_mirror; break;
3113 case 0x0114: s->waveform_slice = color16_column; break;
3114 case 0x0014: s->waveform_slice = color16_row; break;
3115 case 0x1105: s->waveform_slice = acolor_column_mirror; break;
3116 case 0x1005: s->waveform_slice = acolor_row_mirror; break;
3117 case 0x0105: s->waveform_slice = acolor_column; break;
3118 case 0x0005: s->waveform_slice = acolor_row; break;
3119 case 0x1115: s->waveform_slice = acolor16_column_mirror; break;
3120 case 0x1015: s->waveform_slice = acolor16_row_mirror; break;
3121 case 0x0115: s->waveform_slice = acolor16_column; break;
3122 case 0x0015: s->waveform_slice = acolor16_row; break;
3123 case 0x1106: s->waveform_slice = xflat_column_mirror; break;
3124 case 0x1006: s->waveform_slice = xflat_row_mirror; break;
3125 case 0x0106: s->waveform_slice = xflat_column; break;
3126 case 0x0006: s->waveform_slice = xflat_row; break;
3127 case 0x1116: s->waveform_slice = xflat16_column_mirror; break;
3128 case 0x1016: s->waveform_slice = xflat16_row_mirror; break;
3129 case 0x0116: s->waveform_slice = xflat16_column; break;
3130 case 0x0016: s->waveform_slice = xflat16_row; break;
3131 case 0x1107: s->waveform_slice = yflat_column_mirror; break;
3132 case 0x1007: s->waveform_slice = yflat_row_mirror; break;
3133 case 0x0107: s->waveform_slice = yflat_column; break;
3134 case 0x0007: s->waveform_slice = yflat_row; break;
3135 case 0x1117: s->waveform_slice = yflat16_column_mirror; break;
3136 case 0x1017: s->waveform_slice = yflat16_row_mirror; break;
3137 case 0x0117: s->waveform_slice = yflat16_column; break;
3138 case 0x0017: s->waveform_slice = yflat16_row; break;
3139 }
3140
3141 4 s->grat_yuva_color[0] = 255;
3142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 s->grat_yuva_color[1] = s->graticule == GRAT_INVERT ? 255 : 0;
3143
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 s->grat_yuva_color[2] = s->graticule == GRAT_ORANGE || s->graticule == GRAT_INVERT ? 255 : 0;
3144 4 s->grat_yuva_color[3] = 255;
3145
3146
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
4 if (s->mode == 0 && s->graticule != GRAT_INVERT) {
3147
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 s->blend_line = s->bits <= 8 ? blend_vline : blend_vline16;
3148
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 s->draw_text = s->bits <= 8 ? draw_vtext : draw_vtext16;
3149
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 } else if (s->graticule != GRAT_INVERT) {
3150
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 s->blend_line = s->bits <= 8 ? blend_hline : blend_hline16;
3151
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 s->draw_text = s->bits <= 8 ? draw_htext : draw_htext16;
3152 } else if (s->mode == 0 && s->graticule == GRAT_INVERT) {
3153 s->blend_line = s->bits <= 8 ? iblend_vline : iblend_vline16;
3154 s->draw_text = s->bits <= 8 ? idraw_vtext : idraw_vtext16;
3155 } else if (s->graticule == GRAT_INVERT) {
3156 s->blend_line = s->bits <= 8 ? iblend_hline : iblend_hline16;
3157 s->draw_text = s->bits <= 8 ? idraw_htext : idraw_htext16;
3158 }
3159
3160
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 switch (s->filter) {
3161 4 case LOWPASS:
3162 case COLOR:
3163 case ACOLOR:
3164 case CHROMA:
3165 case AFLAT:
3166 case XFLAT:
3167 case YFLAT:
3168 case FLAT:
3169
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if (s->graticule > GRAT_NONE && s->mode == 1)
3170 s->graticulef = s->bits > 8 ? graticule16_column : graticule_column;
3171
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 else if (s->graticule > GRAT_NONE && s->mode == 0)
3172 s->graticulef = s->bits > 8 ? graticule16_row : graticule_row;
3173 4 break;
3174 }
3175
3176
1/5
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 switch (s->filter) {
3177 4 case COLOR:
3178 case ACOLOR:
3179 case LOWPASS:
3180
1/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 switch (s->scale) {
3181 4 case DIGITAL:
3182
1/5
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 switch (s->bits) {
3183 4 case 8: s->glines = (GraticuleLines *)digital8; s->nb_glines = FF_ARRAY_ELEMS(digital8); break;
3184 case 9: s->glines = (GraticuleLines *)digital9; s->nb_glines = FF_ARRAY_ELEMS(digital9); break;
3185 case 10: s->glines = (GraticuleLines *)digital10; s->nb_glines = FF_ARRAY_ELEMS(digital10); break;
3186 case 12: s->glines = (GraticuleLines *)digital12; s->nb_glines = FF_ARRAY_ELEMS(digital12); break;
3187 }
3188 4 break;
3189 case MILLIVOLTS:
3190 switch (s->bits) {
3191 case 8: s->glines = (GraticuleLines *)millivolts8; s->nb_glines = FF_ARRAY_ELEMS(millivolts8); break;
3192 case 9: s->glines = (GraticuleLines *)millivolts9; s->nb_glines = FF_ARRAY_ELEMS(millivolts9); break;
3193 case 10: s->glines = (GraticuleLines *)millivolts10; s->nb_glines = FF_ARRAY_ELEMS(millivolts10); break;
3194 case 12: s->glines = (GraticuleLines *)millivolts12; s->nb_glines = FF_ARRAY_ELEMS(millivolts12); break;
3195 }
3196 break;
3197 case IRE:
3198 switch (s->bits) {
3199 case 8: s->glines = (GraticuleLines *)ire8; s->nb_glines = FF_ARRAY_ELEMS(ire8); break;
3200 case 9: s->glines = (GraticuleLines *)ire9; s->nb_glines = FF_ARRAY_ELEMS(ire9); break;
3201 case 10: s->glines = (GraticuleLines *)ire10; s->nb_glines = FF_ARRAY_ELEMS(ire10); break;
3202 case 12: s->glines = (GraticuleLines *)ire12; s->nb_glines = FF_ARRAY_ELEMS(ire12); break;
3203 }
3204 break;
3205 }
3206 4 break;
3207 case CHROMA:
3208 switch (s->scale) {
3209 case DIGITAL:
3210 switch (s->bits) {
3211 case 8: s->glines = (GraticuleLines *)chroma_digital8; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital8); break;
3212 case 9: s->glines = (GraticuleLines *)chroma_digital9; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital9); break;
3213 case 10: s->glines = (GraticuleLines *)chroma_digital10; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital10); break;
3214 case 12: s->glines = (GraticuleLines *)chroma_digital12; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital12); break;
3215 }
3216 break;
3217 case MILLIVOLTS:
3218 switch (s->bits) {
3219 case 8: s->glines = (GraticuleLines *)millivolts8; s->nb_glines = FF_ARRAY_ELEMS(millivolts8); break;
3220 case 9: s->glines = (GraticuleLines *)millivolts9; s->nb_glines = FF_ARRAY_ELEMS(millivolts9); break;
3221 case 10: s->glines = (GraticuleLines *)millivolts10; s->nb_glines = FF_ARRAY_ELEMS(millivolts10); break;
3222 case 12: s->glines = (GraticuleLines *)millivolts12; s->nb_glines = FF_ARRAY_ELEMS(millivolts12); break;
3223 }
3224 break;
3225 case IRE:
3226 switch (s->bits) {
3227 case 8: s->glines = (GraticuleLines *)ire8; s->nb_glines = FF_ARRAY_ELEMS(ire8); break;
3228 case 9: s->glines = (GraticuleLines *)ire9; s->nb_glines = FF_ARRAY_ELEMS(ire9); break;
3229 case 10: s->glines = (GraticuleLines *)ire10; s->nb_glines = FF_ARRAY_ELEMS(ire10); break;
3230 case 12: s->glines = (GraticuleLines *)ire12; s->nb_glines = FF_ARRAY_ELEMS(ire12); break;
3231 }
3232 break;
3233 }
3234 break;
3235 case XFLAT:
3236 case YFLAT:
3237 case AFLAT:
3238 switch (s->scale) {
3239 case DIGITAL:
3240 switch (s->bits) {
3241 case 8: s->glines = (GraticuleLines *)aflat_digital8; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital8); break;
3242 case 9: s->glines = (GraticuleLines *)aflat_digital9; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital9); break;
3243 case 10: s->glines = (GraticuleLines *)aflat_digital10; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital10); break;
3244 case 12: s->glines = (GraticuleLines *)aflat_digital12; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital12); break;
3245 }
3246 break;
3247 case MILLIVOLTS:
3248 switch (s->bits) {
3249 case 8: s->glines = (GraticuleLines *)aflat_millivolts8; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts8); break;
3250 case 9: s->glines = (GraticuleLines *)aflat_millivolts9; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts9); break;
3251 case 10: s->glines = (GraticuleLines *)aflat_millivolts10; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts10); break;
3252 case 12: s->glines = (GraticuleLines *)aflat_millivolts12; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts12); break;
3253 }
3254 break;
3255 case IRE:
3256 switch (s->bits) {
3257 case 8: s->glines = (GraticuleLines *)aflat_ire8; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire8); break;
3258 case 9: s->glines = (GraticuleLines *)aflat_ire9; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire9); break;
3259 case 10: s->glines = (GraticuleLines *)aflat_ire10; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire10); break;
3260 case 12: s->glines = (GraticuleLines *)aflat_ire12; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire12); break;
3261 }
3262 break;
3263 }
3264 break;
3265 case FLAT:
3266 switch (s->scale) {
3267 case DIGITAL:
3268 switch (s->bits) {
3269 case 8: s->glines = (GraticuleLines *)flat_digital8; s->nb_glines = FF_ARRAY_ELEMS(flat_digital8); break;
3270 case 9: s->glines = (GraticuleLines *)flat_digital9; s->nb_glines = FF_ARRAY_ELEMS(flat_digital9); break;
3271 case 10: s->glines = (GraticuleLines *)flat_digital10; s->nb_glines = FF_ARRAY_ELEMS(flat_digital10); break;
3272 case 12: s->glines = (GraticuleLines *)flat_digital12; s->nb_glines = FF_ARRAY_ELEMS(flat_digital12); break;
3273 }
3274 break;
3275 case MILLIVOLTS:
3276 switch (s->bits) {
3277 case 8: s->glines = (GraticuleLines *)flat_millivolts8; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts8); break;
3278 case 9: s->glines = (GraticuleLines *)flat_millivolts9; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts9); break;
3279 case 10: s->glines = (GraticuleLines *)flat_millivolts10; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts10); break;
3280 case 12: s->glines = (GraticuleLines *)flat_millivolts12; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts12); break;
3281 }
3282 break;
3283 case IRE:
3284 switch (s->bits) {
3285 case 8: s->glines = (GraticuleLines *)flat_ire8; s->nb_glines = FF_ARRAY_ELEMS(flat_ire8); break;
3286 case 9: s->glines = (GraticuleLines *)flat_ire9; s->nb_glines = FF_ARRAY_ELEMS(flat_ire9); break;
3287 case 10: s->glines = (GraticuleLines *)flat_ire10; s->nb_glines = FF_ARRAY_ELEMS(flat_ire10); break;
3288 case 12: s->glines = (GraticuleLines *)flat_ire12; s->nb_glines = FF_ARRAY_ELEMS(flat_ire12); break;
3289 }
3290 break;
3291 }
3292 break;
3293 }
3294
3295 4 s->size = s->size << (s->bits - 8);
3296
3297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 switch (inlink->format) {
3298 case AV_PIX_FMT_GBRAP:
3299 case AV_PIX_FMT_GBRP:
3300 case AV_PIX_FMT_GBRP9:
3301 case AV_PIX_FMT_GBRP10:
3302 case AV_PIX_FMT_GBRP12:
3303 s->rgb = 1;
3304 memcpy(s->bg_color, black_gbrp_color, sizeof(s->bg_color));
3305 break;
3306 4 default:
3307 4 memcpy(s->bg_color, black_yuva_color, sizeof(s->bg_color));
3308 }
3309
3310 4 return 0;
3311 }
3312
3313 4 static int config_output(AVFilterLink *outlink)
3314 {
3315 4 AVFilterContext *ctx = outlink->src;
3316 4 AVFilterLink *inlink = ctx->inputs[0];
3317 4 WaveformContext *s = ctx->priv;
3318 4 int comp = 0, i, j = 0, k, p, size;
3319
3320
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
16 for (i = 0; i < s->ncomp; i++) {
3321
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
12 if ((1 << i) & s->pcomp)
3322 5 comp++;
3323 }
3324 4 s->acomp = comp;
3325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (s->acomp == 0)
3326 return AVERROR(EINVAL);
3327
3328 4 s->odesc = av_pix_fmt_desc_get(outlink->format);
3329 4 s->dcomp = s->odesc->nb_components;
3330
3331 4 av_freep(&s->peak);
3332
3333
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (s->mode) {
3334 3 outlink->h = s->size * FFMAX(comp * (s->display == STACK), 1);
3335 3 outlink->w = inlink->w * FFMAX(comp * (s->display == PARADE), 1);
3336 3 size = inlink->w;
3337 } else {
3338 1 outlink->w = s->size * FFMAX(comp * (s->display == STACK), 1);
3339 1 outlink->h = inlink->h * FFMAX(comp * (s->display == PARADE), 1);
3340 1 size = inlink->h;
3341 }
3342
3343 4 s->peak = av_malloc_array(size, 32 * sizeof(*s->peak));
3344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!s->peak)
3345 return AVERROR(ENOMEM);
3346
3347
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
16 for (p = 0; p < s->ncomp; p++) {
3348 12 const int plane = s->desc->comp[p].plane;
3349 int offset;
3350
3351
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 5 times.
12 if (!((1 << p) & s->pcomp))
3352 7 continue;
3353
3354
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 5 times.
25 for (k = 0; k < 4; k++) {
3355 20 s->emax[plane][k] = s->peak + size * (plane * 4 + k + 0);
3356 20 s->emin[plane][k] = s->peak + size * (plane * 4 + k + 16);
3357 }
3358
3359 5 offset = j++ * s->size * (s->display == STACK);
3360 5 s->estart[plane] = offset;
3361 5 s->eend[plane] = (offset + s->size - 1);
3362
2/2
✓ Branch 0 taken 1696 times.
✓ Branch 1 taken 5 times.
1701 for (i = 0; i < size; i++) {
3363
2/2
✓ Branch 0 taken 6784 times.
✓ Branch 1 taken 1696 times.
8480 for (k = 0; k < 4; k++) {
3364 6784 s->emax[plane][k][i] = s->estart[plane];
3365 6784 s->emin[plane][k][i] = s->eend[plane];
3366 }
3367 }
3368 }
3369
3370
1/3
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
4 switch (s->fitmode) {
3371 4 case FM_NONE:
3372 4 outlink->sample_aspect_ratio = (AVRational){ 1, 1 };
3373 4 break;
3374 case FM_SIZE:
3375 if (s->mode)
3376 outlink->sample_aspect_ratio = (AVRational){ s->size * comp, inlink->h };
3377 else
3378 outlink->sample_aspect_ratio = (AVRational){ inlink->w, s->size * comp };
3379 break;
3380 }
3381
3382 4 av_reduce(&outlink->sample_aspect_ratio.num, &outlink->sample_aspect_ratio.den,
3383 4 outlink->sample_aspect_ratio.num, outlink->sample_aspect_ratio.den, INT_MAX);
3384
3385 4 return 0;
3386 }
3387
3388 200 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
3389 {
3390 200 AVFilterContext *ctx = inlink->dst;
3391 200 WaveformContext *s = ctx->priv;
3392 200 AVFilterLink *outlink = ctx->outputs[0];
3393 AVFrame *out;
3394 int i, j, k;
3395
3396 200 s->intensity = s->fintensity * (s->max - 1);
3397 200 s->bg_color[3] = s->bgopacity * (s->max - 1);
3398 200 s->tint[0] = .5f * (s->ftint[0] + 1.f) * (s->size - 1);
3399 200 s->tint[1] = .5f * (s->ftint[1] + 1.f) * (s->size - 1);
3400
3401 200 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
3402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (!out) {
3403 av_frame_free(&in);
3404 return AVERROR(ENOMEM);
3405 }
3406
3407
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 200 times.
800 for (k = 0; k < s->dcomp; k++) {
3408
1/2
✓ Branch 0 taken 600 times.
✗ Branch 1 not taken.
600 if (s->bits <= 8) {
3409
2/2
✓ Branch 0 taken 196800 times.
✓ Branch 1 taken 600 times.
197400 for (i = 0; i < outlink->h ; i++)
3410 196800 memset(out->data[s->odesc->comp[k].plane] +
3411 196800 i * out->linesize[s->odesc->comp[k].plane],
3412 196800 s->bg_color[k], outlink->w);
3413 } else {
3414 const int mult = s->max / 256;
3415 uint16_t *dst = (uint16_t *)out->data[s->odesc->comp[k].plane];
3416
3417 for (i = 0; i < outlink->h ; i++) {
3418 for (j = 0; j < outlink->w; j++)
3419 dst[j] = s->bg_color[k] * mult;
3420 dst += out->linesize[s->odesc->comp[k].plane] / 2;
3421 }
3422 }
3423 }
3424
3425
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 200 times.
800 for (k = 0, i = 0; k < s->ncomp; k++) {
3426
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 350 times.
600 if ((1 << k) & s->pcomp) {
3427 250 const int plane = s->desc->comp[k].plane;
3428 ThreadData td;
3429 int offset_y;
3430 int offset_x;
3431
3432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 250 times.
250 if (s->display == PARADE) {
3433 offset_x = s->mode ? i++ * inlink->w : 0;
3434 offset_y = s->mode ? 0 : i++ * inlink->h;
3435 } else {
3436
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 50 times.
250 offset_y = s->mode ? i++ * s->size * !!s->display : 0;
3437
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 200 times.
250 offset_x = s->mode ? 0 : i++ * s->size * !!s->display;
3438 }
3439
3440 250 td.in = in;
3441 250 td.out = out;
3442 250 td.component = k;
3443 250 td.offset_y = offset_y;
3444 250 td.offset_x = offset_x;
3445 250 ff_filter_execute(ctx, s->waveform_slice, &td, NULL,
3446 ff_filter_get_nb_threads(ctx));
3447
1/5
✓ Branch 0 taken 250 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
250 switch (s->filter) {
3448 250 case LOWPASS:
3449
1/2
✓ Branch 0 taken 250 times.
✗ Branch 1 not taken.
250 if (s->bits <= 8)
3450
4/6
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 250 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 250 times.
250 envelope(s, out, plane, s->rgb || s->display == OVERLAY ? plane : 0, s->mode ? offset_x : offset_y);
3451 else
3452 envelope16(s, out, plane, s->rgb || s->display == OVERLAY ? plane : 0, s->mode ? offset_x : offset_y);
3453 250 break;
3454 case ACOLOR:
3455 case CHROMA:
3456 case COLOR:
3457 if (s->bits <= 8)
3458 envelope(s, out, plane, plane, s->mode ? offset_x : offset_y);
3459 else
3460 envelope16(s, out, plane, plane, s->mode ? offset_x : offset_y);
3461 break;
3462 case FLAT:
3463 if (s->bits <= 8) {
3464 envelope(s, out, plane, plane, s->mode ? offset_x : offset_y);
3465 envelope(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3466 } else {
3467 envelope16(s, out, plane, plane, s->mode ? offset_x : offset_y);
3468 envelope16(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3469 }
3470 break;
3471 case AFLAT:
3472 case XFLAT:
3473 case YFLAT:
3474 if (s->bits <= 8) {
3475 envelope(s, out, plane, (plane + 0) % s->ncomp, s->mode ? offset_x : offset_y);
3476 envelope(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3477 envelope(s, out, plane, (plane + 2) % s->ncomp, s->mode ? offset_x : offset_y);
3478 } else {
3479 envelope16(s, out, plane, (plane + 0) % s->ncomp, s->mode ? offset_x : offset_y);
3480 envelope16(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3481 envelope16(s, out, plane, (plane + 2) % s->ncomp, s->mode ? offset_x : offset_y);
3482 }
3483 break;
3484 }
3485 }
3486 }
3487 200 s->graticulef(s, out);
3488
3489 200 av_frame_copy_props(out, in);
3490 200 out->color_range = AVCOL_RANGE_JPEG;
3491 200 av_frame_free(&in);
3492 200 out->sample_aspect_ratio = outlink->sample_aspect_ratio;
3493 200 return ff_filter_frame(outlink, out);
3494 }
3495
3496 8 static av_cold void uninit(AVFilterContext *ctx)
3497 {
3498 8 WaveformContext *s = ctx->priv;
3499
3500 8 av_freep(&s->peak);
3501 8 }
3502
3503 static const AVFilterPad inputs[] = {
3504 {
3505 .name = "default",
3506 .type = AVMEDIA_TYPE_VIDEO,
3507 .filter_frame = filter_frame,
3508 .config_props = config_input,
3509 },
3510 };
3511
3512 static const AVFilterPad outputs[] = {
3513 {
3514 .name = "default",
3515 .type = AVMEDIA_TYPE_VIDEO,
3516 .config_props = config_output,
3517 },
3518 };
3519
3520 const FFFilter ff_vf_waveform = {
3521 .p.name = "waveform",
3522 .p.description = NULL_IF_CONFIG_SMALL("Video waveform monitor."),
3523 .p.priv_class = &waveform_class,
3524 .p.flags = AVFILTER_FLAG_SLICE_THREADS,
3525 .priv_size = sizeof(WaveformContext),
3526 .uninit = uninit,
3527 FILTER_INPUTS(inputs),
3528 FILTER_OUTPUTS(outputs),
3529 FILTER_QUERY_FUNC(query_formats),
3530 .process_command = ff_filter_process_command,
3531 };
3532

微量元素挂什么科 血管很明显是什么原因 b27是什么检查 谁发明了什么 夭折是什么意思
东北方向五行属什么 上午右眼皮跳什么预兆 欺世盗名是什么意思 一什么蜻蜓 男孩长虎牙预示什么
发烧时不宜喝什么饮料 庹是什么意思 业力是什么 高姓和什么姓是世仇 梅花代表什么象征意义
陈醋与香醋有什么区别 尿胆原阳性是什么病 1月13日是什么星座 什么人容易得血栓 吃鸭蛋有什么好处和坏处
player是什么意思baiqunet.com 猪八戒的真名叫什么hcv8jop0ns4r.cn 前列腺吃什么药见效快hcv7jop9ns9r.cn 飞机杯什么意思hcv9jop4ns8r.cn 什么首阔步hcv9jop5ns3r.cn
什么对雨hcv8jop1ns9r.cn 台湾人说什么语言hcv8jop8ns8r.cn 割包皮挂什么科室hcv9jop7ns3r.cn 头层牛皮除牛反绒是什么意思hanqikai.com 1.15是什么星座hcv7jop9ns4r.cn
ba是什么元素hcv8jop2ns7r.cn showroom是什么意思hcv8jop5ns7r.cn 口胃读什么hcv7jop4ns6r.cn mlb是什么品牌hcv8jop4ns5r.cn 膝关节疼是什么原因xjhesheng.com
点痣挂什么科室mmeoe.com 眼镜pd是什么意思hcv7jop4ns7r.cn 龋齿什么意思hcv8jop7ns9r.cn 善太息是什么意思xinmaowt.com 法警是什么编制hcv8jop3ns4r.cn
百度