血尿是什么原因引起的男性| gd什么意思| 黄精什么时候种植| 琪字五行属什么| 鸡眼用什么药| 附件炎是什么原因引起的| 生小孩需要准备什么| 高筋面粉和低筋面粉有什么区别| 小兔子吃什么食物| 5.22是什么星座| 白酒是什么酿造的| 胸前长痘痘是什么原因| 有偿什么意思| 做梦大便是什么意思| 肾炎是什么病| 白皮书是什么意思| 吃什么补大脑记忆力| 促销员是做什么的| 坠积效应是什么意思| 转头头晕是什么原因| 胸部疼痛挂什么科| 梦见拖地是什么意思| 什么是先天之本| 什么是党的性质和宗旨的体现| 生命科学专业学什么| 朱顶红什么时候开花| 痔疮有什么特征| 为什么硬起来有点疼| 高风亮节是什么意思| 生殖器疱疹用什么药最好| 头经常晕是什么原因| 祸不单行是什么意思| 什么意思啊| 为什么会得霉菌感染| 肚子拉稀像水一样是什么情况| 狗吃什么蔬菜好| 早泄吃什么药| 扬州瘦马什么意思| 来姨妈喝什么比较好| 为什么会得近视眼| 药流后吃什么消炎药比较好| 下肢动脉闭塞吃什么药| 小沈阳属什么生肖| 什么虫咬了起水泡| 我还能做什么| 什么自若| 壁虎是什么类动物| 开山鼻祖是什么意思| 左眼跳代表什么| 吃什么降血压效果最好| 蓟类植物是什么| 为什么人| 感冒有痰吃什么药| 寒号鸟是什么动物| 老头疼是什么原因导致的| 鼓上蚤是什么意思| 女人长期喝西洋参有什么好处| 便秘是什么意思| 基围虾不能和什么一起吃| 怕冷的女人是什么原因| 寿者相什么意思| 支原体感染是什么病| 赵云的马叫什么| 男士内裤买什么牌子好| 经典什么意思| 亲嘴什么感觉| 发烧拉肚子是什么原因| 晚上口渴是什么原因引起的| r表示什么| 迪士尼狗狗叫什么名字| BS是什么意思啊| 轻生什么意思| 黎明是什么时间| 眼开大财主是什么生肖| 碳酸钙d3颗粒什么时候吃最好| 巴旦木是什么树的果实| 怀女孩有什么征兆| 驻村是什么意思| ngs什么意思| ig是什么意思| 梦见土豆是什么意思| 什么地说话| 生殖细胞是什么| 益气固表是什么意思| 正太是什么| 牛建读什么| 与狼共舞什么意思| 梦见一条小蛇是什么意思| 食字五行属什么| 月经老是提前是什么原因| 七月14号是什么星座| 铎读什么| 眼皮红肿是什么原因| 龟头炎用什么药| 祎字五行属什么| 今年为什么有两个6月| 晚上胃疼是什么原因| 雷诺综合征是什么病| 疟疾是什么| 什么样的人容易高原反应| 什么是一线城市| 六度万行 是什么意思| 卵巢增大是什么原因引起的| 乙肝145阳性是什么意思| 柴鸡是什么鸡| 喉部有异物感是什么病| r医学是什么意思| 褶是什么意思| 偷鸡不成蚀把米是什么意思| 撒野是什么意思| 多管闲事是什么意思| 布加综合征是什么病| 拐枣泡酒有什么功效| 果酱样大便见于什么病| 洗假牙用什么洗最好| 谢娜人气为什么那么高| 52年属什么生肖| 经常肚子痛什么原因| 为什么小孩子经常流鼻血| 泽泻是什么| 网店卖什么好| 失眠是什么原因导致的| 无咎是什么意思| 女人梦到蝎子什么征兆| 高血压吃什么盐| 婚检都查什么| 碳素笔是什么笔| 牙根出血是什么原因| 什么是黄道吉日| 呕吐拉肚子吃什么药| 爬山有什么好处| plg是什么意思| 海绵体修复吃什么药| 人生有什么意义| 喝什么茶可以降血糖| 升米恩斗米仇是什么意思| 安宫牛黄丸什么时候吃最好| 良民是什么意思| 蛋白糖是什么糖| 贫血孕妇吃什么补血最快| 蚕吃什么| 遗精是什么症状| 唯有女子与小人难养也什么意思| insun是什么牌子| 排尿困难是什么原因男性| 颈部淋巴结肿大吃什么药| 膝盖疼吃什么药好| 拉屎发黑是什么原因| 玉佛寺求什么最灵验| 茶壶嘴为什么不能对着人| 鼻咽炎吃什么药| 髻是什么意思| 吃什么升白细胞比较快| 什么样的女人最旺夫| 4月19号是什么星座| cock什么意思| 理数是什么意思| 正骨是什么意思| 梦见好多老鼠是什么意思| other是什么品牌| mk是什么牌子| 四大才子是什么生肖| 燚是什么意思| 大创是什么| 脚起皮干裂是什么原因| 穷字代表什么生肖| 指奸是什么意思| 迈之灵治什么病| 乙肝不能吃什么东西| 什么是虚拟币| 恰如其分是什么意思| 头疼吃什么药最有效| 气血不足吃什么中成药最好| 黄晓明的老婆叫什么名字| 退步是什么意思| 碳酸钠俗称什么| 鬼斧神工是什么意思| york是什么牌子| 明了是什么意思| 命薄是什么意思| 手麻木什么原因| 腱鞘炎在什么位置| 陈光标做什么生意| 木日念什么| 五花八门什么意思| 什么是词性| 女人更年期什么症状| 9月3号是什么星座| 梦见驴是什么意思| 多汗症看什么科| 棉花糖是什么做的| 胃火旺怎么调理吃什么药最好| 青字五行属什么| 夏天吹空调感冒了吃什么药| 蔗糖脂肪酸酯是什么| 黄瓜含有什么营养成分| 数字17代表什么意思| 副科级是什么级别| 蹦蹦跳跳是什么生肖| 什么是原发性高血压和继发性高血压| 什么是马上风| 春天都有什么花开| 长脸适合什么发型男| 国药准字是什么意思| 痒是什么原因引起的| 维生素d缺乏吃什么药| 来月经有什么症状| 8月8是什么星座| 什么是虫草| 往届毕业生是什么意思| 什么的北风| 技校算什么学历| 频繁做梦是什么原因| 大腿根疼是什么原因| 10月1日什么星座| 为什么越睡越困| 男的有霉菌是什么症状| 肝多发小囊肿什么意思| 血液生化检查能看出什么病| 什么颜色显皮肤白| 阳性是什么病| 什么是逻辑思维| 什么花香| 什么是卵泡期| 翡翠是什么颜色| 左旋肉碱是什么东西| 灵芝孢子粉有什么用| 桃花依旧笑春风什么意思| 怀孕为什么会流血| 口红用什么能洗掉| 牛肉饺子馅配什么蔬菜好吃| 室上速是什么病| 女人做梦哭醒预示什么| 胸部正侧位片检查什么| 阴道流黄色分泌物是什么原因| 肺活量不足是什么症状| 嘴角烂是什么原因| 胡萝卜不能和什么一起吃| 尬是什么意思| 月下老人什么意思| 殆什么意思| 昭觉寺求什么最灵验| 寻麻疹不能吃什么| 什么时候上环是最佳时期| 独在异乡为异客异是什么意思| 来月经喝酒有什么影响| 四大发明有什么| 梦见好多蚊子是什么意思| 肾结石吃什么水果好| 女金片的功效与作用是什么| 处女座前面是什么星座| 桃子不能和什么水果一起吃| 风热感冒吃什么药好| 钝是什么意思| 如是我闻是什么意思| 工装裤搭配什么上衣| 突然肚子疼是什么原因| 女人依赖男人说明什么| 窘迫什么意思| 草字头下面一个高字读什么| 帽子戏法是什么意思| 散瞳后需要注意什么| 摇花手是什么意思| 焦作有什么大学| 百度

《斗破苍穹》电视剧片场照曝光 林允版萧薰儿青春靓丽


Directory: ../../../ffmpeg/
File: src/libavfilter/vf_mix.c
Date: 2025-08-04 00:43:16
Exec Total Coverage
Lines: 0 208 0.0%
Functions: 0 10 0.0%
Branches: 0 178 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2017 Paul B Mahol
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config_components.h"
22
23 #include "libavutil/avstring.h"
24 #include "libavutil/imgutils.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
28
29 #include "avfilter.h"
30 #include "filters.h"
31 #include "formats.h"
32 #include "framesync.h"
33 #include "video.h"
34
35 typedef struct MixContext {
36 const AVClass *class;
37 const AVPixFmtDescriptor *desc;
38 char *weights_str;
39 int nb_inputs;
40 int nb_threads;
41 int duration;
42 float *weights;
43 float scale;
44 float wfactor;
45
46 int fast;
47 int tmix;
48 int nb_frames;
49 int nb_unique_frames;
50
51 int depth;
52 int max;
53 int planes;
54 int nb_planes;
55 int linesizes[4];
56 int height[4];
57
58 uint8_t *sum[4];
59
60 uint8_t **data;
61 int *linesize;
62
63 AVFrame **frames;
64 FFFrameSync fs;
65 } MixContext;
66
67 static int query_formats(const AVFilterContext *ctx,
68 AVFilterFormatsConfig **cfg_in,
69 AVFilterFormatsConfig **cfg_out)
70 {
71 unsigned reject_flags = AV_PIX_FMT_FLAG_BITSTREAM |
72 AV_PIX_FMT_FLAG_HWACCEL |
73 AV_PIX_FMT_FLAG_PAL;
74 unsigned accept_flags = 0;
75
76 if (!HAVE_BIGENDIAN)
77 reject_flags |= AV_PIX_FMT_FLAG_BE;
78 else
79 accept_flags |= AV_PIX_FMT_FLAG_BE;
80
81 return ff_set_common_formats2(ctx, cfg_in, cfg_out,
82 ff_formats_pixdesc_filter(accept_flags, reject_flags));
83 }
84
85 static int parse_weights(AVFilterContext *ctx)
86 {
87 MixContext *s = ctx->priv;
88 char *p, *arg, *saveptr = NULL;
89 int i, last = 0;
90
91 s->fast = 1;
92 s->wfactor = 0.f;
93 p = s->weights_str;
94 for (i = 0; i < s->nb_inputs; i++) {
95 if (!(arg = av_strtok(p, " |", &saveptr)))
96 break;
97
98 p = NULL;
99 if (av_sscanf(arg, "%f", &s->weights[i]) != 1) {
100 av_log(ctx, AV_LOG_ERROR, "Invalid syntax for weights[%d].\n", i);
101 return AVERROR(EINVAL);
102 }
103 s->wfactor += s->weights[i];
104 if (i > 0)
105 s->fast &= s->weights[i] == s->weights[0];
106 last = i;
107 }
108
109 for (; i < s->nb_inputs; i++) {
110 s->weights[i] = s->weights[last];
111 s->wfactor += s->weights[i];
112 }
113 if (s->scale == 0) {
114 s->wfactor = 1 / s->wfactor;
115 } else {
116 if (s->scale != 1.f / s->wfactor)
117 s->fast = 0;
118 s->wfactor = s->scale;
119 }
120
121 return 0;
122 }
123
124 static av_cold int init(AVFilterContext *ctx)
125 {
126 MixContext *s = ctx->priv;
127 int ret;
128
129 s->tmix = !strcmp(ctx->filter->name, "tmix");
130
131 s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames));
132 if (!s->frames)
133 return AVERROR(ENOMEM);
134
135 s->weights = av_calloc(s->nb_inputs, sizeof(*s->weights));
136 if (!s->weights)
137 return AVERROR(ENOMEM);
138
139 if (!s->tmix) {
140 for (int i = 0; i < s->nb_inputs; i++) {
141 AVFilterPad pad = { 0 };
142
143 pad.type = AVMEDIA_TYPE_VIDEO;
144 pad.name = av_asprintf("input%d", i);
145 if (!pad.name)
146 return AVERROR(ENOMEM);
147
148 if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
149 return ret;
150 }
151 }
152
153 return parse_weights(ctx);
154 }
155
156 typedef struct ThreadData {
157 AVFrame **in, *out;
158 } ThreadData;
159
160 #define FAST_TMIX_SLICE(type, stype, round) \
161 for (int p = 0; p < s->nb_planes; p++) { \
162 const int slice_start = (s->height[p] * jobnr) / nb_jobs; \
163 const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \
164 const int width = s->linesizes[p] / sizeof(type); \
165 stype *sum = (stype *)(s->sum[p] + slice_start * s->linesizes[p] * 2); \
166 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
167 const ptrdiff_t sum_linesize = (s->linesizes[p] * 2) / sizeof(stype); \
168 const ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \
169 const int idx = FFMAX(0, nb_inputs - nb_unique); \
170 const ptrdiff_t src_linesize[2] = { in[idx]->linesize[p], \
171 in[nb_inputs-1]->linesize[p] }; \
172 const type *src[2]; \
173 \
174 if (!((1 << p) & s->planes)) { \
175 av_image_copy_plane((uint8_t *)dst, out->linesize[p], \
176 in[0]->data[p] + slice_start * in[0]->linesize[p], \
177 in[0]->linesize[p], \
178 s->linesizes[p], slice_end - slice_start); \
179 continue; \
180 } \
181 \
182 src[0] = (const type *)(in[idx]->data[p] + slice_start*src_linesize[0]); \
183 src[1] = (const type *)(in[nb_inputs-1]->data[p] + slice_start * src_linesize[1]); \
184 \
185 for (int y = slice_start; y < slice_end; y++) { \
186 for (int x = 0; x < width; x++) { \
187 sum[x] += src[1][x] * (1 + (nb_inputs - 1) * (idx == (nb_inputs - 1))); \
188 dst[x] = (sum[x] + (round)) / nb_inputs; \
189 sum[x] -= src[0][x]; \
190 } \
191 \
192 dst += dst_linesize; \
193 sum += sum_linesize; \
194 src[0] += src_linesize[0] / sizeof(type); \
195 src[1] += src_linesize[1] / sizeof(type); \
196 } \
197 }
198
199 #define MIX_SLICE(type, fun, clip) \
200 for (int p = 0; p < s->nb_planes; p++) { \
201 const int slice_start = (s->height[p] * jobnr) / nb_jobs; \
202 const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \
203 const int width = s->linesizes[p] / sizeof(type); \
204 type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
205 const ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \
206 \
207 if (!((1 << p) & s->planes)) { \
208 av_image_copy_plane((uint8_t *)dst, out->linesize[p], \
209 in[0]->data[p] + slice_start * in[0]->linesize[p], \
210 in[0]->linesize[p], \
211 s->linesizes[p], slice_end - slice_start); \
212 continue; \
213 } \
214 \
215 for (int i = 0; i < nb_inputs; i++) \
216 linesize[i] = in[i]->linesize[p]; \
217 \
218 for (int i = 0; i < nb_inputs; i++) \
219 srcf[i] = in[i]->data[p] + slice_start * linesize[i]; \
220 \
221 for (int y = slice_start; y < slice_end; y++) { \
222 for (int x = 0; x < width; x++) { \
223 float val = 0.f; \
224 \
225 for (int i = 0; i < nb_inputs; i++) { \
226 float src = *(type *)(srcf[i] + x * sizeof(type)); \
227 \
228 val += src * weights[i]; \
229 } \
230 \
231 dst[x] = clip(fun(val * wfactor), 0, max); \
232 } \
233 \
234 dst += dst_linesize; \
235 for (int i = 0; i < nb_inputs; i++) \
236 srcf[i] += linesize[i]; \
237 } \
238 }
239
240 #define CLIP8(x, min, max) av_clip_uint8(x)
241 #define CLIP16(x, min, max) av_clip(x, min, max)
242 #define CLIPF(x, min, max) (x)
243 #define NOP(x) (x)
244
245 static int mix_frames(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
246 {
247 MixContext *s = ctx->priv;
248 ThreadData *td = arg;
249 AVFrame **in = td->in;
250 AVFrame *out = td->out;
251 const float *weights = s->weights;
252 uint8_t **srcf = s->data + jobnr * s->nb_inputs;
253 int *linesize = s->linesize + jobnr * s->nb_inputs;
254 const int nb_unique = s->nb_unique_frames;
255 const int nb_inputs = s->nb_inputs;
256 const float wfactor = s->wfactor;
257 const int max = s->max;
258
259 if (s->tmix && s->fast) {
260 if (s->depth <= 8) {
261 FAST_TMIX_SLICE(uint8_t, uint16_t, nb_inputs >> 1)
262 } else if (s->depth <= 16) {
263 FAST_TMIX_SLICE(uint16_t, uint32_t, nb_inputs >> 1)
264 } else {
265 FAST_TMIX_SLICE(float, float, 0.f)
266 }
267
268 return 0;
269 }
270
271 if (s->depth <= 8) {
272 MIX_SLICE(uint8_t, lrintf, CLIP8)
273 } else if (s->depth <= 16) {
274 MIX_SLICE(uint16_t, lrintf, CLIP16)
275 } else {
276 MIX_SLICE(float, NOP, CLIPF)
277 }
278
279 return 0;
280 }
281
282 static int process_frame(FFFrameSync *fs)
283 {
284 AVFilterContext *ctx = fs->parent;
285 AVFilterLink *outlink = ctx->outputs[0];
286 MixContext *s = fs->opaque;
287 AVFrame **in = s->frames;
288 AVFrame *out;
289 ThreadData td;
290 int i, ret;
291
292 for (i = 0; i < s->nb_inputs; i++) {
293 if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0)
294 return ret;
295 }
296
297 if (ctx->is_disabled) {
298 out = av_frame_clone(s->frames[0]);
299 if (!out)
300 return AVERROR(ENOMEM);
301 out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);
302 return ff_filter_frame(outlink, out);
303 }
304
305 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
306 if (!out)
307 return AVERROR(ENOMEM);
308 out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);
309
310 td.in = in;
311 td.out = out;
312 ff_filter_execute(ctx, mix_frames, &td, NULL,
313 FFMIN(s->height[1], s->nb_threads));
314
315 return ff_filter_frame(outlink, out);
316 }
317
318 static int config_output(AVFilterLink *outlink)
319 {
320 AVFilterContext *ctx = outlink->src;
321 MixContext *s = ctx->priv;
322 FilterLink *il = ff_filter_link(ctx->inputs[0]);
323 FilterLink *ol = ff_filter_link(outlink);
324 AVRational sar = ctx->inputs[0]->sample_aspect_ratio;
325 AVFilterLink *inlink = ctx->inputs[0];
326 int height = ctx->inputs[0]->h;
327 int width = ctx->inputs[0]->w;
328 FFFrameSyncIn *in;
329 int i, ret;
330
331 if (!s->tmix) {
332 for (i = 1; i < s->nb_inputs; i++) {
333 if (ctx->inputs[i]->h != height || ctx->inputs[i]->w != width) {
334 av_log(ctx, AV_LOG_ERROR, "Input %d size (%dx%d) does not match input %d size (%dx%d).\n", i, ctx->inputs[i]->w, ctx->inputs[i]->h, 0, width, height);
335 return AVERROR(EINVAL);
336 }
337 }
338 }
339
340 s->nb_threads = ff_filter_get_nb_threads(ctx);
341 s->desc = av_pix_fmt_desc_get(outlink->format);
342 if (!s->desc)
343 return AVERROR_BUG;
344 s->nb_planes = av_pix_fmt_count_planes(outlink->format);
345 s->depth = s->desc->comp[0].depth;
346 s->max = (1 << s->depth) - 1;
347
348 if ((ret = av_image_fill_linesizes(s->linesizes, inlink->format, inlink->w)) < 0)
349 return ret;
350
351 s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
352 s->height[0] = s->height[3] = inlink->h;
353
354 s->data = av_calloc(s->nb_threads * s->nb_inputs, sizeof(*s->data));
355 if (!s->data)
356 return AVERROR(ENOMEM);
357
358 s->linesize = av_calloc(s->nb_threads * s->nb_inputs, sizeof(*s->linesize));
359 if (!s->linesize)
360 return AVERROR(ENOMEM);
361
362 if (s->tmix) {
363 for (int p = 0; p < s->nb_planes; p++) {
364 s->sum[p] = av_calloc(s->linesizes[p], s->height[p] * sizeof(*s->sum) * 2);
365 if (!s->sum[p])
366 return AVERROR(ENOMEM);
367 }
368 return 0;
369 }
370
371 outlink->w = width;
372 outlink->h = height;
373 ol->frame_rate = il->frame_rate;
374 outlink->sample_aspect_ratio = sar;
375
376 if ((ret = ff_framesync_init(&s->fs, ctx, s->nb_inputs)) < 0)
377 return ret;
378
379 in = s->fs.in;
380 s->fs.opaque = s;
381 s->fs.on_event = process_frame;
382
383 for (i = 0; i < s->nb_inputs; i++) {
384 AVFilterLink *inlink = ctx->inputs[i];
385
386 in[i].time_base = inlink->time_base;
387 in[i].sync = 1;
388 in[i].before = EXT_STOP;
389 in[i].after = (s->duration == 1 || (s->duration == 2 && i == 0)) ? EXT_STOP : EXT_INFINITY;
390 }
391
392 ret = ff_framesync_configure(&s->fs);
393 outlink->time_base = s->fs.time_base;
394
395 return ret;
396 }
397
398 static av_cold void uninit(AVFilterContext *ctx)
399 {
400 MixContext *s = ctx->priv;
401 int i;
402
403 ff_framesync_uninit(&s->fs);
404 av_freep(&s->weights);
405 av_freep(&s->data);
406 av_freep(&s->linesize);
407
408 if (s->tmix) {
409 for (i = 0; i < 4; i++)
410 av_freep(&s->sum[i]);
411 for (i = 0; i < s->nb_frames && s->frames; i++)
412 av_frame_free(&s->frames[i]);
413 }
414 av_freep(&s->frames);
415 }
416
417 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
418 char *res, int res_len, int flags)
419 {
420 int ret;
421
422 ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
423 if (ret < 0)
424 return ret;
425
426 return parse_weights(ctx);
427 }
428
429 static int activate(AVFilterContext *ctx)
430 {
431 MixContext *s = ctx->priv;
432 return ff_framesync_activate(&s->fs);
433 }
434
435 #define OFFSET(x) offsetof(MixContext, x)
436 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
437 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM
438
439 static const AVOption mix_options[] = {
440 { "inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=2}, 2, INT16_MAX, .flags = FLAGS },
441 { "weights", "set weight for each input", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, .flags = TFLAGS },
442 { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = TFLAGS },
443 { "planes", "set what planes to filter", OFFSET(planes), AV_OPT_TYPE_FLAGS, {.i64=15}, 0, 15, .flags = TFLAGS },
444 { "duration", "how to determine end of stream", OFFSET(duration), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, .flags = FLAGS, .unit = "duration" },
445 { "longest", "Duration of longest input", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "duration" },
446 { "shortest", "Duration of shortest input", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "duration" },
447 { "first", "Duration of first input", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, .unit = "duration" },
448 { NULL },
449 };
450
451 static const AVFilterPad outputs[] = {
452 {
453 .name = "default",
454 .type = AVMEDIA_TYPE_VIDEO,
455 .config_props = config_output,
456 },
457 };
458
459 #if CONFIG_MIX_FILTER
460 AVFILTER_DEFINE_CLASS(mix);
461
462 const FFFilter ff_vf_mix = {
463 .p.name = "mix",
464 .p.description = NULL_IF_CONFIG_SMALL("Mix video inputs."),
465 .p.priv_class = &mix_class,
466 .p.flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_SLICE_THREADS |
467 AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
468 .priv_size = sizeof(MixContext),
469 FILTER_OUTPUTS(outputs),
470 FILTER_QUERY_FUNC2(query_formats),
471 .init = init,
472 .uninit = uninit,
473 .activate = activate,
474 .process_command = process_command,
475 };
476
477 #endif /* CONFIG_MIX_FILTER */
478
479 #if CONFIG_TMIX_FILTER
480 static int tmix_filter_frame(AVFilterLink *inlink, AVFrame *in)
481 {
482 AVFilterContext *ctx = inlink->dst;
483 AVFilterLink *outlink = ctx->outputs[0];
484 MixContext *s = ctx->priv;
485 ThreadData td;
486 AVFrame *out;
487
488 if (s->nb_inputs == 1)
489 return ff_filter_frame(outlink, in);
490
491 if (s->nb_frames < s->nb_inputs) {
492 s->frames[s->nb_frames] = in;
493 s->nb_frames++;
494 s->nb_unique_frames++;
495 while (s->nb_frames < s->nb_inputs) {
496 s->frames[s->nb_frames] = av_frame_clone(s->frames[s->nb_frames - 1]);
497 if (!s->frames[s->nb_frames])
498 return AVERROR(ENOMEM);
499 s->nb_frames++;
500 }
501 } else {
502 s->nb_unique_frames = FFMIN(s->nb_unique_frames + 1, s->nb_inputs);
503 av_frame_free(&s->frames[0]);
504 memmove(&s->frames[0], &s->frames[1], sizeof(*s->frames) * (s->nb_inputs - 1));
505 s->frames[s->nb_inputs - 1] = in;
506 }
507
508 if (ctx->is_disabled) {
509 out = av_frame_clone(s->frames[0]);
510 if (!out)
511 return AVERROR(ENOMEM);
512 return ff_filter_frame(outlink, out);
513 }
514
515 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
516 if (!out)
517 return AVERROR(ENOMEM);
518 out->pts = s->frames[s->nb_frames - 1]->pts;
519
520 td.out = out;
521 td.in = s->frames;
522 ff_filter_execute(ctx, mix_frames, &td, NULL,
523 FFMIN(s->height[1], s->nb_threads));
524
525 return ff_filter_frame(outlink, out);
526 }
527
528 static const AVOption tmix_options[] = {
529 { "frames", "set number of successive frames to mix", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=3}, 1, 1024, .flags = FLAGS },
530 { "weights", "set weight for each frame", OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1 1"}, 0, 0, .flags = TFLAGS },
531 { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT16_MAX, .flags = TFLAGS },
532 { "planes", "set what planes to filter", OFFSET(planes), AV_OPT_TYPE_FLAGS, {.i64=15}, 0, 15, .flags = TFLAGS },
533 { NULL },
534 };
535
536 static const AVFilterPad inputs[] = {
537 {
538 .name = "default",
539 .type = AVMEDIA_TYPE_VIDEO,
540 .filter_frame = tmix_filter_frame,
541 },
542 };
543
544 AVFILTER_DEFINE_CLASS(tmix);
545
546 const FFFilter ff_vf_tmix = {
547 .p.name = "tmix",
548 .p.description = NULL_IF_CONFIG_SMALL("Mix successive video frames."),
549 .p.priv_class = &tmix_class,
550 .p.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
551 .priv_size = sizeof(MixContext),
552 FILTER_OUTPUTS(outputs),
553 FILTER_INPUTS(inputs),
554 FILTER_QUERY_FUNC2(query_formats),
555 .init = init,
556 .uninit = uninit,
557 .process_command = process_command,
558 };
559
560 #endif /* CONFIG_TMIX_FILTER */
561

丝瓜有什么好处 eso是什么意思 春天有什么 竟无语凝噎什么意思 婴儿口水多是什么原因
嘴里发甜是什么原因 肿瘤标志物是什么 小老头是什么意思 十一月底是什么星座 肾功能不全是什么意思
蒲公英泡水喝有什么好处 有里面没有两横是什么字 农历五月二十是什么星座 治疗心率过快用什么药效果好 基数是什么意思
吃荆芥有什么好处 单硬脂酸甘油酯是什么 双肺结节是什么意思 化疗期间吃什么升白细胞快 大佐相当于中国的什么军衔
天山童姥练的什么武功hcv9jop2ns1r.cn 什么水果清热解毒去火hcv9jop6ns8r.cn 小孩子不吃饭是什么原因引起的hcv7jop5ns1r.cn 什么样人不能吃海参hcv8jop5ns4r.cn 自制力是什么意思hcv9jop3ns4r.cn
金牛座和什么星座不合hkuteam.com 肺气肿吃什么食物好adwl56.com 胃酸过多吃什么食物好hcv8jop9ns1r.cn 什么叫伴手礼zhiyanzhang.com 左肺钙化灶是什么意思hcv8jop4ns8r.cn
反流性食管炎吃什么药好hcv7jop4ns7r.cn 简单明了是什么意思hcv8jop9ns9r.cn coat是什么意思中文hcv8jop2ns1r.cn 长征是什么意思bysq.com 宝宝头大是什么原因hcv9jop7ns4r.cn
腮腺炎用什么药hcv7jop6ns4r.cn 软化耳屎的药水叫什么hcv7jop4ns7r.cn 物理压榨油是什么意思hcv7jop4ns5r.cn 属猪和什么属相相冲bfb118.com 吃什么水果对胃好cl108k.com
百度