血糖高吃什么最好| kj是什么意思| 孕妇吸氧对胎儿有什么好处| 想改名字需要什么手续| 酒后头疼吃什么| 99年属什么生肖| 白细胞计数偏高是什么意思| sey什么意思| 什么木做菜板最好| 龟头感染用什么药| 尿路感染吃什么药最见效| 什么水果糖分低| 心肌炎吃什么食物最好| 唐僧被封为什么佛| 补肾吃什么好| blm是什么意思| 肾火旺有什么症状| 什么炒肉好吃| 什么是健康管理| 什么的鸟窝| 外聘是什么意思| 啫喱是什么| 澳大利亚说什么语| 什么都有| 荔枝肉是什么菜系| 浙江属于什么方向| 河虾最爱吃什么食物| 什么是好人| 汆是什么意思| dm医学上是什么意思| 小孩腹泻吃什么药好得快| 11月出生是什么星座| 松露是什么| 感冒咳嗽一直不好是什么原因| 4月8号是什么星座| 男士生育检查挂什么科| 男扮女装叫什么| 口腔溃疡挂什么科| 蓝字五行属什么| 身上皮肤痒是什么原因| 什么粉可以代替木薯粉| 小儿咳嗽吃什么药好| 精囊炎吃什么药| 北京古代叫什么| 什么样的毛刺是良性的| 乳头经常痒是什么原因| 什么生肖怕老婆| 偷窥是什么意思| 肌张力高有什么表现| 自律性是什么意思| 2028年属什么生肖| 高考移民是什么意思| 嘴巴发甜是什么原因| 痛风发作期吃什么药| 梦见被蛇缠身是什么意思| 贴秋膘是什么意思啊| 海豹油有什么作用| 胳肢窝痒是什么原因| 阴历3月是什么星座| ccd是什么意思| 肝火旺盛吃什么药好| 茶叶属于什么类目| 高血糖什么原因引起| 目字旁与什么有关| 送老师什么礼物| ea7是什么品牌| mirage轮胎什么牌子| 脸上过敏是什么症状| 挚爱和至爱有什么区别| 免单是什么意思| 眼睛有点模糊是什么原因| 间歇性跛行见于什么病| 什么的冬天| 懒羊羊的什么| 马叉虫是什么意思| 不以规矩下一句是什么| 拖拖拉拉什么意思| 阁五行属什么| 梦魇是什么意思| 甲亢和甲减有什么区别| 什么是直辖市| 黑豆熟地水功效是什么| 肌层回声均匀是什么意思| kb什么意思| sandals是什么意思| nyc是什么牌子| 宫颈lsil是什么意思| 夏天受凉感冒吃什么药| 酸奶什么时候喝好| 韭菜什么时候种最合适| 看鼻子挂什么科| 资生堂适合什么年龄段| 哺乳期发烧吃什么药不影响哺乳| 4月18日什么星座| 一什么而什么的成语| 甲亢是一种什么病严重吗| 叩是什么意思| 水垢是什么| 美尼尔眩晕症吃什么药| 司法鉴定是干什么的| 健康证有什么用| 萤火虫为什么发光| 什么食物利尿| 天经地义的意思是什么| 妊娠高血压对胎儿有什么影响| 5月16是什么星座| 胰腺疼痛吃什么药| 最大的哺乳动物是什么| lpa是什么意思| 睁眼睡觉是什么原因| 黄皮什么时候上市| 红玫瑰的花语是什么| 认真是什么意思| 心功能二级是什么意思| 黑白蛇是什么蛇| 正月初七什么星座| 胃消化不良吃什么药| 面瘫什么意思| simon是什么意思| 甲功异常有什么症状| 什么是福报| 荷花的寓意是什么| 索是什么意思| 清真不吃什么肉| 你为什么不说话歌词| 近亲结婚有什么危害| 见红的血是什么颜色| 吃夏枯草有什么副作用| 润字五行属什么| 生姜水泡脚有什么好处| 空气湿度是什么意思| 身上长扁平疣是什么原因| 1946年属什么生肖属相| 晕车吃什么好| 双子座的幸运色是什么| 献血有什么要求| 式可以加什么偏旁| 淘宝交易关闭是什么意思| 我一言难尽忍不住伤心是什么歌| 23岁属什么| 孩子流黄鼻涕吃什么药效果好| 掌纹多而乱代表什么| bhp是什么单位| tomboy是什么意思| 麻鸡是什么鸡| 左手小指疼痛预兆什么| 烧腊是什么| 什么教无类| 偏执是什么意思| 防晒衣什么颜色最防晒| 胃穿孔有什么症状| 样板间是什么意思| 暗房是什么意思| 什么是光| 痞是什么意思| 眼袋重是什么原因| 生理期是什么意思| 绿色心情是什么意思| 男人交公粮什么意思| 尿频是什么原因导致的| 据悉是什么意思| 阴平阳秘是什么意思| 印度为什么没把墨脱占领| 品牌logo是什么意思| 恶露是什么| 突然心跳加快是什么原因| 肚子里有积水是什么病| 鸡肠炎用什么药效果好| 霉菌性阴炎是什么原因引起的女| 孕期长痘痘是什么原因| 宫颈糜烂用什么药好得快| 银925是什么意思| 枪是什么生肖| 驻外大使是什么级别| 李商隐是什么朝代的| 咳嗽吃什么食物好得最快最有效| 痔疮不能吃什么东西| 北豆腐是什么| 过期食品属于什么垃圾| 看客是什么意思| 湿气重什么原因| 棉涤是什么面料| 人中龙凤下一句是什么| 具象是什么意思| 阴虚内热是什么意思| airwalk是什么牌子| 芝士是什么| 穷的生肖指什么生肖| 唐朝灭亡后是什么朝代| 大便干硬是什么原因| 老鸨是什么| 卷饼里面配什么菜好吃| 微信拉黑和删除有什么区别| 陈皮泡水喝有什么好处| 甲状腺功能亢进是什么意思| 消字号是什么意思| 熬夜对身体有什么危害| 音序是什么| 老年人手抖是什么原因| 权志龙为什么这么火| 经期头疼吃什么药效果最好| 清肺热用什么泡水喝比较好| 婴儿拉肚子是什么原因造成的| c3是什么驾驶证| 身披枷锁是什么生肖| 肌炎有什么症状| 一月19日是什么星座| 嘴咸是什么原因| 什么叫意识| 柠檬片泡水喝有什么功效和作用| 游乐场都有什么项目| 碳酸氢钠是什么添加剂| 不是什么而是什么造句| 腊月初四是什么星座| 梦见下大雨是什么预兆| 阴道炎用什么药效果最好| 高考推迟月经吃什么药| 扁桃体发炎可以吃什么水果| 散光400度是什么概念| 血虚吃什么食物可以补| 爱马仕是什么品牌| 幽会是什么意思| 公鸡的尾巴有什么作用| 刘邦字什么| 火丹是什么原因造成的| 十二指肠溃疡吃什么中成药| 心肌炎有什么症状| 银屑病为什么会自愈| 2023年五行属什么| 心脏早搏有什么症状| 学区房什么意思| 蚕蛹过敏什么办法最快| 手术后吃什么好| 自我救赎是什么意思| 睡前吃什么有助于睡眠| 音调是由什么决定的| 辛辣是什么意思| 湿温病是什么症状| 身体痒是什么原因| 信徒是什么意思| 静脉采血检查什么| upi是什么意思| 胃痛是什么原因| 什么是嗳气有何症状| 助听器什么牌子最好| 手发胀是什么原因造成的| 逝去是什么意思| 豆柏是什么| 对口高考班是什么意思| 嘴唇神经跳动是什么原因| 心率快是什么原因| 睡眠不好总做梦是什么原因| 蛇的五行属什么| 手指僵硬暗示什么疾病| 什么是静脉血栓| 频繁做噩梦是什么原因| 二月开什么花| 感冒头晕是什么原因| 国师是什么职位| 正常大便是什么颜色| 视频是什么意思| 睡觉中途总醒什么原因| zero什么意思| 皮肤变黑是什么原因| 百度

国际社会点赞中国经济数据


Directory: ../../../ffmpeg/
File: src/libavfilter/vf_hue.c
Date: 2025-08-04 00:43:16
Exec Total Coverage
Lines: 149 201 74.1%
Functions: 11 13 84.6%
Branches: 71 126 56.3%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2003 Michael Niedermayer
3 * Copyright (c) 2012 Jeremy Tran
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 /**
23 * @file
24 * Apply a hue/saturation filter to the input video
25 * Ported from MPlayer libmpcodecs/vf_hue.c.
26 */
27
28 #include <float.h>
29 #include "libavutil/eval.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/opt.h"
33 #include "libavutil/pixdesc.h"
34
35 #include "avfilter.h"
36 #include "filters.h"
37 #include "video.h"
38
39 #define SAT_MIN_VAL -10
40 #define SAT_MAX_VAL 10
41
42 static const char *const var_names[] = {
43 "n", // frame count
44 "pts", // presentation timestamp expressed in AV_TIME_BASE units
45 "r", // frame rate
46 "t", // timestamp expressed in seconds
47 "tb", // timebase
48 NULL
49 };
50
51 enum var_name {
52 VAR_N,
53 VAR_PTS,
54 VAR_R,
55 VAR_T,
56 VAR_TB,
57 VAR_NB
58 };
59
60 typedef struct HueContext {
61 const AVClass *class;
62 float hue_deg; /* hue expressed in degrees */
63 float hue; /* hue expressed in radians */
64 char *hue_deg_expr;
65 char *hue_expr;
66 AVExpr *hue_deg_pexpr;
67 AVExpr *hue_pexpr;
68 float saturation;
69 char *saturation_expr;
70 AVExpr *saturation_pexpr;
71 float brightness;
72 char *brightness_expr;
73 AVExpr *brightness_pexpr;
74 int hsub;
75 int vsub;
76 int is_first;
77 int32_t hue_sin;
78 int32_t hue_cos;
79 double var_values[VAR_NB];
80 uint8_t lut_l[256];
81 uint8_t lut_u[256][256];
82 uint8_t lut_v[256][256];
83 uint16_t lut_l16[65536];
84 uint16_t lut_u10[1024][1024];
85 uint16_t lut_v10[1024][1024];
86 } HueContext;
87
88 #define OFFSET(x) offsetof(HueContext, x)
89 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
90 static const AVOption hue_options[] = {
91 { "h", "set the hue angle degrees expression", OFFSET(hue_deg_expr), AV_OPT_TYPE_STRING,
92 { .str = NULL }, .flags = FLAGS },
93 { "s", "set the saturation expression", OFFSET(saturation_expr), AV_OPT_TYPE_STRING,
94 { .str = "1" }, .flags = FLAGS },
95 { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING,
96 { .str = NULL }, .flags = FLAGS },
97 { "b", "set the brightness expression", OFFSET(brightness_expr), AV_OPT_TYPE_STRING,
98 { .str = "0" }, .flags = FLAGS },
99 { NULL }
100 };
101
102 AVFILTER_DEFINE_CLASS(hue);
103
104 92 static inline void compute_sin_and_cos(HueContext *hue)
105 {
106 /*
107 * Scale the value to the norm of the resulting (U,V) vector, that is
108 * the saturation.
109 * This will be useful in the apply_lut function.
110 */
111 92 hue->hue_sin = lrint(sin(hue->hue) * (1 << 16) * hue->saturation);
112 92 hue->hue_cos = lrint(cos(hue->hue) * (1 << 16) * hue->saturation);
113 92 }
114
115 23 static inline void create_luma_lut(HueContext *h)
116 {
117 23 const float b = h->brightness;
118 int i;
119
120
2/2
✓ Branch 0 taken 5888 times.
✓ Branch 1 taken 23 times.
5911 for (i = 0; i < 256; i++) {
121 5888 h->lut_l[i] = av_clip_uint8(i + b * 25.5);
122 }
123
2/2
✓ Branch 0 taken 1507328 times.
✓ Branch 1 taken 23 times.
1507351 for (i = 0; i < 65536; i++) {
124 1507328 h->lut_l16[i] = av_clip_uintp2(i + b * 102.4, 10);
125 }
126 23 }
127
128 64 static inline void create_chrominance_lut(HueContext *h, const int32_t c,
129 const int32_t s)
130 {
131 int32_t i, j, u, v, new_u, new_v;
132
133 /*
134 * If we consider U and V as the components of a 2D vector then its angle
135 * is the hue and the norm is the saturation
136 */
137
2/2
✓ Branch 0 taken 16384 times.
✓ Branch 1 taken 64 times.
16448 for (i = 0; i < 256; i++) {
138
2/2
✓ Branch 0 taken 4194304 times.
✓ Branch 1 taken 16384 times.
4210688 for (j = 0; j < 256; j++) {
139 /* Normalize the components from range [16;240] to [-112;112] */
140 4194304 u = i - 128;
141 4194304 v = j - 128;
142 /*
143 * Apply the rotation of the vector : (c * u) - (s * v)
144 * (s * u) + (c * v)
145 * De-normalize the components (without forgetting to scale 128
146 * by << 16)
147 * Finally scale back the result by >> 16
148 */
149 4194304 new_u = ((c * u) - (s * v) + (1 << 15) + (128 << 16)) >> 16;
150 4194304 new_v = ((s * u) + (c * v) + (1 << 15) + (128 << 16)) >> 16;
151
152 /* Prevent a potential overflow */
153 4194304 h->lut_u[i][j] = av_clip_uint8(new_u);
154 4194304 h->lut_v[i][j] = av_clip_uint8(new_v);
155 }
156 }
157
2/2
✓ Branch 0 taken 65536 times.
✓ Branch 1 taken 64 times.
65600 for (i = 0; i < 1024; i++) {
158
2/2
✓ Branch 0 taken 67108864 times.
✓ Branch 1 taken 65536 times.
67174400 for (j = 0; j < 1024; j++) {
159 67108864 u = i - 512;
160 67108864 v = j - 512;
161 /*
162 * Apply the rotation of the vector : (c * u) - (s * v)
163 * (s * u) + (c * v)
164 * De-normalize the components (without forgetting to scale 512
165 * by << 16)
166 * Finally scale back the result by >> 16
167 */
168 67108864 new_u = ((c * u) - (s * v) + (1 << 15) + (512 << 16)) >> 16;
169 67108864 new_v = ((s * u) + (c * v) + (1 << 15) + (512 << 16)) >> 16;
170
171 /* Prevent a potential overflow */
172 67108864 h->lut_u10[i][j] = av_clip_uintp2(new_u, 10);
173 67108864 h->lut_v10[i][j] = av_clip_uintp2(new_v, 10);
174 }
175 }
176 64 }
177
178 20 static int set_expr(AVExpr **pexpr_ptr, char **expr_ptr,
179 const char *expr, const char *option, void *log_ctx)
180 {
181 int ret;
182 AVExpr *new_pexpr;
183 char *new_expr;
184
185 20 new_expr = av_strdup(expr);
186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (!new_expr)
187 return AVERROR(ENOMEM);
188 20 ret = av_expr_parse(&new_pexpr, expr, var_names,
189 NULL, NULL, NULL, NULL, 0, log_ctx);
190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (ret < 0) {
191 av_log(log_ctx, AV_LOG_ERROR,
192 "Error when evaluating the expression '%s' for %s\n",
193 expr, option);
194 av_free(new_expr);
195 return ret;
196 }
197
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (*pexpr_ptr)
199 av_expr_free(*pexpr_ptr);
200 20 *pexpr_ptr = new_pexpr;
201 20 av_freep(expr_ptr);
202 20 *expr_ptr = new_expr;
203
204 20 return 0;
205 }
206
207 8 static av_cold int init(AVFilterContext *ctx)
208 {
209 8 HueContext *hue = ctx->priv;
210 int ret;
211
212
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if (hue->hue_expr && hue->hue_deg_expr) {
213 av_log(ctx, AV_LOG_ERROR,
214 "H and h options are incompatible and cannot be specified "
215 "at the same time\n");
216 return AVERROR(EINVAL);
217 }
218
219 #define SET_EXPR(expr, option) \
220 if (hue->expr##_expr) do { \
221 ret = set_expr(&hue->expr##_pexpr, &hue->expr##_expr, \
222 hue->expr##_expr, option, ctx); \
223 if (ret < 0) \
224 return ret; \
225 } while (0)
226
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 SET_EXPR(brightness, "b");
227
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 SET_EXPR(saturation, "s");
228
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
8 SET_EXPR(hue_deg, "h");
229
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 SET_EXPR(hue, "H");
230 #undef SET_EXPR
231
232 8 av_log(ctx, AV_LOG_VERBOSE,
233 "H_expr:%s h_deg_expr:%s s_expr:%s b_expr:%s\n",
234 hue->hue_expr, hue->hue_deg_expr, hue->saturation_expr, hue->brightness_expr);
235 8 compute_sin_and_cos(hue);
236 8 hue->is_first = 1;
237
238 8 return 0;
239 }
240
241 8 static av_cold void uninit(AVFilterContext *ctx)
242 {
243 8 HueContext *hue = ctx->priv;
244
245 8 av_expr_free(hue->brightness_pexpr);
246 8 av_expr_free(hue->hue_deg_pexpr);
247 8 av_expr_free(hue->hue_pexpr);
248 8 av_expr_free(hue->saturation_pexpr);
249 8 }
250
251 static const enum AVPixelFormat pix_fmts[] = {
252 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P,
253 AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P,
254 AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,
255 AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P,
256 AV_PIX_FMT_YUVA420P,
257 AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10,
258 AV_PIX_FMT_YUV420P10,
259 AV_PIX_FMT_YUV440P10,
260 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10,
261 AV_PIX_FMT_YUVA420P10,
262 AV_PIX_FMT_NONE
263 };
264
265 4 static int config_props(AVFilterLink *inlink)
266 {
267 4 HueContext *hue = inlink->dst->priv;
268 4 FilterLink *l = ff_filter_link(inlink);
269 4 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
270
271 4 hue->hsub = desc->log2_chroma_w;
272 4 hue->vsub = desc->log2_chroma_h;
273
274 4 hue->var_values[VAR_N] = 0;
275 4 hue->var_values[VAR_TB] = av_q2d(inlink->time_base);
276
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 hue->var_values[VAR_R] = l->frame_rate.num == 0 || l->frame_rate.den == 0 ?
277
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 NAN : av_q2d(l->frame_rate);
278
279 4 return 0;
280 }
281
282 20 static void apply_luma_lut(HueContext *s,
283 uint8_t *ldst, const int dst_linesize,
284 uint8_t *lsrc, const int src_linesize,
285 int w, int h)
286 {
287 int i;
288
289
2/2
✓ Branch 0 taken 5760 times.
✓ Branch 1 taken 20 times.
5780 while (h--) {
290
2/2
✓ Branch 0 taken 2027520 times.
✓ Branch 1 taken 5760 times.
2033280 for (i = 0; i < w; i++)
291 2027520 ldst[i] = s->lut_l[lsrc[i]];
292
293 5760 lsrc += src_linesize;
294 5760 ldst += dst_linesize;
295 }
296 20 }
297
298 static void apply_luma_lut10(HueContext *s,
299 uint16_t *ldst, const int dst_linesize,
300 uint16_t *lsrc, const int src_linesize,
301 int w, int h)
302 {
303 int i;
304
305 while (h--) {
306 for (i = 0; i < w; i++)
307 ldst[i] = s->lut_l16[lsrc[i]];
308
309 lsrc += src_linesize;
310 ldst += dst_linesize;
311 }
312 }
313
314 63 static void apply_lut(HueContext *s,
315 uint8_t *udst, uint8_t *vdst, const int dst_linesize,
316 uint8_t *usrc, uint8_t *vsrc, const int src_linesize,
317 int w, int h)
318 {
319 int i;
320
321
2/2
✓ Branch 0 taken 9072 times.
✓ Branch 1 taken 63 times.
9135 while (h--) {
322
2/2
✓ Branch 0 taken 1596672 times.
✓ Branch 1 taken 9072 times.
1605744 for (i = 0; i < w; i++) {
323 1596672 const int u = usrc[i];
324 1596672 const int v = vsrc[i];
325
326 1596672 udst[i] = s->lut_u[u][v];
327 1596672 vdst[i] = s->lut_v[u][v];
328 }
329
330 9072 usrc += src_linesize;
331 9072 vsrc += src_linesize;
332 9072 udst += dst_linesize;
333 9072 vdst += dst_linesize;
334 }
335 63 }
336
337 21 static void apply_lut10(HueContext *s,
338 uint16_t *udst, uint16_t *vdst, const int dst_linesize,
339 uint16_t *usrc, uint16_t *vsrc, const int src_linesize,
340 int w, int h)
341 {
342 int i;
343
344
2/2
✓ Branch 0 taken 6048 times.
✓ Branch 1 taken 21 times.
6069 while (h--) {
345
2/2
✓ Branch 0 taken 1064448 times.
✓ Branch 1 taken 6048 times.
1070496 for (i = 0; i < w; i++) {
346 1064448 const int u = av_clip_uintp2(usrc[i], 10);
347 1064448 const int v = av_clip_uintp2(vsrc[i], 10);
348
349 1064448 udst[i] = s->lut_u10[u][v];
350 1064448 vdst[i] = s->lut_v10[u][v];
351 }
352
353 6048 usrc += src_linesize;
354 6048 vsrc += src_linesize;
355 6048 udst += dst_linesize;
356 6048 vdst += dst_linesize;
357 }
358 21 }
359
360 84 static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
361 {
362 84 FilterLink *inl = ff_filter_link(inlink);
363 84 HueContext *hue = inlink->dst->priv;
364 84 AVFilterLink *outlink = inlink->dst->outputs[0];
365 AVFrame *outpic;
366 84 const int32_t old_hue_sin = hue->hue_sin, old_hue_cos = hue->hue_cos;
367 84 const float old_brightness = hue->brightness;
368 84 int direct = 0;
369 84 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
370
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 63 times.
84 const int bps = desc->comp[0].depth > 8 ? 2 : 1;
371
372
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 if (av_frame_is_writable(inpic)) {
373 84 direct = 1;
374 84 outpic = inpic;
375 } else {
376 outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
377 if (!outpic) {
378 av_frame_free(&inpic);
379 return AVERROR(ENOMEM);
380 }
381 av_frame_copy_props(outpic, inpic);
382 }
383
384 84 hue->var_values[VAR_N] = inl->frame_count_out;
385
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 hue->var_values[VAR_T] = TS2T(inpic->pts, inlink->time_base);
386
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 hue->var_values[VAR_PTS] = TS2D(inpic->pts);
387
388
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 if (hue->saturation_expr) {
389 84 hue->saturation = av_expr_eval(hue->saturation_pexpr, hue->var_values, NULL);
390
391
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
84 if (hue->saturation < SAT_MIN_VAL || hue->saturation > SAT_MAX_VAL) {
392 hue->saturation = av_clip(hue->saturation, SAT_MIN_VAL, SAT_MAX_VAL);
393 av_log(inlink->dst, AV_LOG_WARNING,
394 "Saturation value not in range [%d,%d]: clipping value to %0.1f\n",
395 SAT_MIN_VAL, SAT_MAX_VAL, hue->saturation);
396 }
397 }
398
399
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 if (hue->brightness_expr) {
400 84 hue->brightness = av_expr_eval(hue->brightness_pexpr, hue->var_values, NULL);
401
402
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
84 if (hue->brightness < -10 || hue->brightness > 10) {
403 hue->brightness = av_clipf(hue->brightness, -10, 10);
404 av_log(inlink->dst, AV_LOG_WARNING,
405 "Brightness value not in range [%d,%d]: clipping value to %0.1f\n",
406 -10, 10, hue->brightness);
407 }
408 }
409
410
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 42 times.
84 if (hue->hue_deg_expr) {
411 42 hue->hue_deg = av_expr_eval(hue->hue_deg_pexpr, hue->var_values, NULL);
412 42 hue->hue = hue->hue_deg * M_PI / 180;
413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 } else if (hue->hue_expr) {
414 hue->hue = av_expr_eval(hue->hue_pexpr, hue->var_values, NULL);
415 hue->hue_deg = hue->hue * 180 / M_PI;
416 }
417
418 84 av_log(inlink->dst, AV_LOG_DEBUG,
419 "H:%0.1f*PI h:%0.1f s:%0.1f b:%0.f t:%0.1f n:%d\n",
420 84 hue->hue/M_PI, hue->hue_deg, hue->saturation, hue->brightness,
421 84 hue->var_values[VAR_T], (int)hue->var_values[VAR_N]);
422
423 84 compute_sin_and_cos(hue);
424
6/6
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 40 times.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 20 times.
84 if (hue->is_first || (old_hue_sin != hue->hue_sin || old_hue_cos != hue->hue_cos))
425 64 create_chrominance_lut(hue, hue->hue_cos, hue->hue_sin);
426
427
6/6
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 1 times.
84 if (hue->is_first || (old_brightness != hue->brightness && hue->brightness))
428 23 create_luma_lut(hue);
429
430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (!direct) {
431 if (!hue->brightness)
432 av_image_copy_plane(outpic->data[0], outpic->linesize[0],
433 inpic->data[0], inpic->linesize[0],
434 inlink->w * bps, inlink->h);
435 if (inpic->data[3])
436 av_image_copy_plane(outpic->data[3], outpic->linesize[3],
437 inpic->data[3], inpic->linesize[3],
438 inlink->w * bps, inlink->h);
439 }
440
441
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 63 times.
84 if (bps > 1) {
442 21 apply_lut10(hue, (uint16_t*)outpic->data[1], (uint16_t*)outpic->data[2], outpic->linesize[1]/2,
443 21 (uint16_t*) inpic->data[1], (uint16_t*) inpic->data[2], inpic->linesize[1]/2,
444 21 AV_CEIL_RSHIFT(inlink->w, hue->hsub),
445 21 AV_CEIL_RSHIFT(inlink->h, hue->vsub));
446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (hue->brightness)
447 apply_luma_lut10(hue, (uint16_t*)outpic->data[0], outpic->linesize[0]/2,
448 (uint16_t*) inpic->data[0], inpic->linesize[0]/2, inlink->w, inlink->h);
449 } else {
450 63 apply_lut(hue, outpic->data[1], outpic->data[2], outpic->linesize[1],
451 63 inpic->data[1], inpic->data[2], inpic->linesize[1],
452 63 AV_CEIL_RSHIFT(inlink->w, hue->hsub),
453 63 AV_CEIL_RSHIFT(inlink->h, hue->vsub));
454
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 43 times.
63 if (hue->brightness)
455 20 apply_luma_lut(hue, outpic->data[0], outpic->linesize[0],
456 20 inpic->data[0], inpic->linesize[0], inlink->w, inlink->h);
457 }
458
459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (!direct)
460 av_frame_free(&inpic);
461
462 84 hue->is_first = 0;
463 84 return ff_filter_frame(outlink, outpic);
464 }
465
466 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
467 char *res, int res_len, int flags)
468 {
469 HueContext *hue = ctx->priv;
470 int ret;
471
472 #define SET_EXPR(expr, option) \
473 do { \
474 ret = set_expr(&hue->expr##_pexpr, &hue->expr##_expr, \
475 args, option, ctx); \
476 if (ret < 0) \
477 return ret; \
478 } while (0)
479
480 if (!strcmp(cmd, "h")) {
481 SET_EXPR(hue_deg, "h");
482 av_freep(&hue->hue_expr);
483 } else if (!strcmp(cmd, "H")) {
484 SET_EXPR(hue, "H");
485 av_freep(&hue->hue_deg_expr);
486 } else if (!strcmp(cmd, "s")) {
487 SET_EXPR(saturation, "s");
488 } else if (!strcmp(cmd, "b")) {
489 SET_EXPR(brightness, "b");
490 } else
491 return AVERROR(ENOSYS);
492
493 return 0;
494 }
495
496 static const AVFilterPad hue_inputs[] = {
497 {
498 .name = "default",
499 .type = AVMEDIA_TYPE_VIDEO,
500 .filter_frame = filter_frame,
501 .config_props = config_props,
502 },
503 };
504
505 const FFFilter ff_vf_hue = {
506 .p.name = "hue",
507 .p.description = NULL_IF_CONFIG_SMALL("Adjust the hue and saturation of the input video."),
508 .p.priv_class = &hue_class,
509 .p.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
510 .priv_size = sizeof(HueContext),
511 .init = init,
512 .uninit = uninit,
513 .process_command = process_command,
514 FILTER_INPUTS(hue_inputs),
515 FILTER_OUTPUTS(ff_video_default_filterpad),
516 FILTER_PIXFMTS_ARRAY(pix_fmts),
517 };
518

11五行属什么 s牌运动鞋是什么牌子 根尖周炎吃什么药 每天吃一个鸡蛋有什么好处 舟山念什么
肝硬化前期有什么症状 皮肤瘙痒是什么原因 新加坡什么工作最挣钱 腰痛吃什么药 咖啡豆是什么动物粪便
喉咙发痒咳嗽吃什么药 专升本有什么专业 翡翠和玉石有什么区别 私生子是什么意思 凌晨一点半是什么时辰
观音菩萨原名叫什么名 便秘吃什么菜有助排便 胃痞病是什么病 杏林是指什么 松香有毒吗对人体有什么危害
通告是什么意思hcv9jop5ns5r.cn 仲夏夜是什么意思hcv9jop3ns8r.cn 阴部潮湿是什么原因hcv8jop8ns2r.cn 夏天脚开裂是什么原因hcv8jop9ns2r.cn 金蝉子是什么佛hcv9jop6ns9r.cn
布鲁斯是什么意思hcv8jop5ns0r.cn 吃什么对血管好hcv8jop6ns1r.cn 阿司匹林有什么副作用hcv9jop4ns8r.cn 天下乌鸦一般黑是什么意思hcv8jop5ns1r.cn 清明为什么插柳枝hcv7jop7ns3r.cn
衣字旁的字和什么有关hcv8jop9ns2r.cn 希腊脚是什么意思youbangsi.com 河南是什么气候hcv9jop2ns0r.cn 突然心跳加快是什么原因kuyehao.com 血压下午高是什么原因hcv7jop5ns6r.cn
慢性胆囊炎是什么原因引起的hlguo.com 加特纳菌阳性是什么病hcv8jop1ns2r.cn 四个一是什么字bfb118.com 骷髅是什么意思jinxinzhichuang.com 大肠杆菌用什么药治疗效果好hcv9jop5ns1r.cn
百度