FFmpeg
Loading...
Searching...
No Matches
vf_chromakey.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 Timo Rothenpieler <timo@rothenpieler.org>
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 "libavutil/opt.h"
23#include "libavutil/pixdesc.h"
24#include "avfilter.h"
25#include "filters.h"
26
27typedef struct ChromakeyContext {
28 const AVClass *class;
29
30 uint8_t chromakey_rgba[4];
31 uint16_t chromakey_uv[2];
32
34 float blend;
35
36 int is_yuv;
37 int depth;
38 int mid;
39 int max;
40
43
45 int jobnr, int nb_jobs);
47
48static uint8_t do_chromakey_pixel(ChromakeyContext *ctx, uint8_t u[9], uint8_t v[9])
49{
50 double diff = 0.0;
51 int du, dv, i;
52
53 for (i = 0; i < 9; ++i) {
54 du = (int)u[i] - ctx->chromakey_uv[0];
55 dv = (int)v[i] - ctx->chromakey_uv[1];
56
57 diff += sqrt((du * du + dv * dv) / (255.0 * 255.0 * 2));
58 }
59
60 diff /= 9.0;
61
62 if (ctx->blend > 0.0001) {
63 return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * 255.0;
64 } else {
65 return (diff > ctx->similarity) ? 255 : 0;
66 }
67}
68
69static uint16_t do_chromakey_pixel16(ChromakeyContext *ctx, uint16_t u[9], uint16_t v[9])
70{
71 double max = ctx->max;
72 double diff = 0.0;
73 int du, dv, i;
74
75 for (i = 0; i < 9; ++i) {
76 du = (int)u[i] - ctx->chromakey_uv[0];
77 dv = (int)v[i] - ctx->chromakey_uv[1];
78
79 diff += sqrt((du * du + dv * dv) / (max * max * 2));
80 }
81
82 diff /= 9.0;
83
84 if (ctx->blend > 0.0001) {
85 return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * max;
86 } else {
87 return (diff > ctx->similarity) ? max : 0;
88 }
89}
90
91static av_always_inline void get_pixel_uv(AVFrame *frame, int hsub_log2, int vsub_log2, int x, int y, uint8_t *u, uint8_t *v)
92{
93 if (x < 0 || x >= frame->width || y < 0 || y >= frame->height)
94 return;
95
96 x >>= hsub_log2;
97 y >>= vsub_log2;
98
99 *u = frame->data[1][frame->linesize[1] * y + x];
100 *v = frame->data[2][frame->linesize[2] * y + x];
101}
102
103static av_always_inline void get_pixel16_uv(AVFrame *frame, int hsub_log2, int vsub_log2, int x, int y, uint16_t *u, uint16_t *v)
104{
105 if (x < 0 || x >= frame->width || y < 0 || y >= frame->height)
106 return;
107
108 x >>= hsub_log2;
109 y >>= vsub_log2;
110
111 *u = AV_RN16(&frame->data[1][frame->linesize[1] * y + 2 * x]);
112 *v = AV_RN16(&frame->data[2][frame->linesize[2] * y + 2 * x]);
113}
114
115static int do_chromakey_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
116{
117 AVFrame *frame = arg;
118
119 const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs);
120 const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs);
121
122 ChromakeyContext *ctx = avctx->priv;
123
124 int x, y, xo, yo;
125 uint8_t u[9], v[9];
126
127 memset(u, ctx->chromakey_uv[0], sizeof(u));
128 memset(v, ctx->chromakey_uv[1], sizeof(v));
129
130 for (y = slice_start; y < slice_end; ++y) {
131 for (x = 0; x < frame->width; ++x) {
132 for (yo = 0; yo < 3; ++yo) {
133 for (xo = 0; xo < 3; ++xo) {
134 get_pixel_uv(frame, ctx->hsub_log2, ctx->vsub_log2, x + xo - 1, y + yo - 1, &u[yo * 3 + xo], &v[yo * 3 + xo]);
135 }
136 }
137
138 frame->data[3][frame->linesize[3] * y + x] = do_chromakey_pixel(ctx, u, v);
139 }
140 }
141
142 return 0;
143}
144
145static int do_chromakey16_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
146{
147 AVFrame *frame = arg;
148
149 const int slice_start = ff_slice_pos(frame->height, jobnr, nb_jobs);
150 const int slice_end = ff_slice_pos(frame->height, jobnr + 1, nb_jobs);
151
152 ChromakeyContext *ctx = avctx->priv;
153
154 int x, y, xo, yo;
155 uint16_t u[9], v[9];
156
157 for (int i = 0; i < 9; i++) {
158 u[i] = ctx->chromakey_uv[0];
159 v[i] = ctx->chromakey_uv[1];
160 }
161
162 for (y = slice_start; y < slice_end; ++y) {
163 for (x = 0; x < frame->width; ++x) {
164 uint16_t *dst = (uint16_t *)(frame->data[3] + frame->linesize[3] * y);
165
166 for (yo = 0; yo < 3; ++yo) {
167 for (xo = 0; xo < 3; ++xo) {
168 get_pixel16_uv(frame, ctx->hsub_log2, ctx->vsub_log2, x + xo - 1, y + yo - 1, &u[yo * 3 + xo], &v[yo * 3 + xo]);
169 }
170 }
171
172 dst[x] = do_chromakey_pixel16(ctx, u, v);
173 }
174 }
175
176 return 0;
177}
178
179static int do_chromahold_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
180{
181 ChromakeyContext *ctx = avctx->priv;
182 AVFrame *frame = arg;
183 const int slice_start = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr, nb_jobs);
184 const int slice_end = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr + 1, nb_jobs);
185
186 int x, y, alpha;
187
188 for (y = slice_start; y < slice_end; ++y) {
189 for (x = 0; x < frame->width >> ctx->hsub_log2; ++x) {
190 int u = frame->data[1][frame->linesize[1] * y + x];
191 int v = frame->data[2][frame->linesize[2] * y + x];
192 double diff;
193 int du, dv;
194
195 du = u - ctx->chromakey_uv[0];
196 dv = v - ctx->chromakey_uv[1];
197
198 diff = sqrt((du * du + dv * dv) / (255.0 * 255.0 * 2.0));
199
200 alpha = diff > ctx->similarity;
201 if (ctx->blend > 0.0001) {
202 double f = 1. - av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0);
203
204 frame->data[1][frame->linesize[1] * y + x] = 128 + (u - 128) * f;
205 frame->data[2][frame->linesize[2] * y + x] = 128 + (v - 128) * f;
206 } else if (alpha) {
207 frame->data[1][frame->linesize[1] * y + x] = 128;
208 frame->data[2][frame->linesize[2] * y + x] = 128;
209 }
210 }
211 }
212
213 return 0;
214}
215
216static int do_chromahold16_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
217{
218 ChromakeyContext *ctx = avctx->priv;
219 AVFrame *frame = arg;
220 const int slice_start = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr, nb_jobs);
221 const int slice_end = ff_slice_pos(frame->height >> ctx->vsub_log2, jobnr + 1, nb_jobs);
222 const int mid = ctx->mid;
223 double max = ctx->max;
224
225 int x, y, alpha;
226
227 for (y = slice_start; y < slice_end; ++y) {
228 for (x = 0; x < frame->width >> ctx->hsub_log2; ++x) {
229 int u = AV_RN16(&frame->data[1][frame->linesize[1] * y + 2 * x]);
230 int v = AV_RN16(&frame->data[2][frame->linesize[2] * y + 2 * x]);
231 double diff;
232 int du, dv;
233
234 du = u - ctx->chromakey_uv[0];
235 dv = v - ctx->chromakey_uv[1];
236
237 diff = sqrt((du * du + dv * dv) / (max * max * 2.0));
238
239 alpha = diff > ctx->similarity;
240 if (ctx->blend > 0.0001) {
241 double f = 1. - av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0);
242
243 AV_WN16(&frame->data[1][frame->linesize[1] * y + 2 * x], mid + (u - mid) * f);
244 AV_WN16(&frame->data[2][frame->linesize[2] * y + 2 * x], mid + (v - mid) * f);
245 } else if (alpha) {
246 AV_WN16(&frame->data[1][frame->linesize[1] * y + 2 * x], mid);
247 AV_WN16(&frame->data[2][frame->linesize[2] * y + 2 * x], mid);
248 }
249 }
250 }
251
252 return 0;
253}
254
256{
257 AVFilterContext *avctx = link->dst;
258 ChromakeyContext *ctx = avctx->priv;
259 int res;
260
261 if (res = ff_filter_execute(avctx, ctx->do_slice, frame, NULL,
262 FFMIN(frame->height, ff_filter_get_nb_threads(avctx))))
263 return res;
264
265 if (!strcmp(avctx->filter->name, "chromakey"))
266 frame->alpha_mode = avctx->outputs[0]->alpha_mode;
267 return ff_filter_frame(avctx->outputs[0], frame);
268}
269
270#define FIXNUM(x) lrint((x) * (1 << 10))
271#define RGB_TO_U(rgb) (((- FIXNUM(0.16874) * rgb[0] - FIXNUM(0.33126) * rgb[1] + FIXNUM(0.50000) * rgb[2] + (1 << 9) - 1) >> 10) + 128)
272#define RGB_TO_V(rgb) ((( FIXNUM(0.50000) * rgb[0] - FIXNUM(0.41869) * rgb[1] - FIXNUM(0.08131) * rgb[2] + (1 << 9) - 1) >> 10) + 128)
273
275{
277 AVFilterContext *avctx = outlink->src;
278 ChromakeyContext *ctx = avctx->priv;
279 int factor;
280
281 ctx->depth = desc->comp[0].depth;
282 ctx->mid = 1 << (ctx->depth - 1);
283 ctx->max = (1 << ctx->depth) - 1;
284
285 factor = 1 << (ctx->depth - 8);
286
287 if (ctx->is_yuv) {
288 ctx->chromakey_uv[0] = ctx->chromakey_rgba[1] * factor;
289 ctx->chromakey_uv[1] = ctx->chromakey_rgba[2] * factor;
290 } else {
291 ctx->chromakey_uv[0] = RGB_TO_U(ctx->chromakey_rgba) * factor;
292 ctx->chromakey_uv[1] = RGB_TO_V(ctx->chromakey_rgba) * factor;
293 }
294
295 if (!strcmp(avctx->filter->name, "chromakey")) {
297 ctx->do_slice = ctx->depth <= 8 ? do_chromakey_slice : do_chromakey16_slice;
298 } else {
299 ctx->do_slice = ctx->depth <= 8 ? do_chromahold_slice: do_chromahold16_slice;
300 }
301
302 return 0;
303}
304
306{
307 AVFilterContext *avctx = inlink->dst;
308 ChromakeyContext *ctx = avctx->priv;
310
311 ctx->hsub_log2 = desc->log2_chroma_w;
312 ctx->vsub_log2 = desc->log2_chroma_h;
313
314 return 0;
315}
316
317static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
318 char *res, int res_len, int flags)
319{
320 int ret;
321
322 ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
323 if (ret < 0)
324 return ret;
325
326 return config_output(ctx->outputs[0]);
327}
328
329static const AVFilterPad inputs[] = {
330 {
331 .name = "default",
332 .type = AVMEDIA_TYPE_VIDEO,
334 .filter_frame = filter_frame,
335 .config_props = config_input,
336 },
337};
338
339static const AVFilterPad outputs[] = {
340 {
341 .name = "default",
342 .type = AVMEDIA_TYPE_VIDEO,
343 .config_props = config_output,
344 },
345};
346
347#define OFFSET(x) offsetof(ChromakeyContext, x)
348#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
349
350static const AVOption chromakey_options[] = {
351 { "color", "set the chromakey key color", OFFSET(chromakey_rgba), AV_OPT_TYPE_COLOR, { .str = "black" }, 0, 0, FLAGS },
352 { "similarity", "set the chromakey similarity value", OFFSET(similarity), AV_OPT_TYPE_FLOAT, { .dbl = 0.01 }, 0.00001, 1.0, FLAGS },
353 { "blend", "set the chromakey key blend value", OFFSET(blend), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, 0.0, 1.0, FLAGS },
354 { "yuv", "color parameter is in yuv instead of rgb", OFFSET(is_yuv), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
355 { NULL }
356};
357
368
370
372 .p.name = "chromakey",
373 .p.description = NULL_IF_CONFIG_SMALL("Turns a certain color into transparency. Operates on YUV colors."),
374 .p.priv_class = &chromakey_class,
376 .priv_size = sizeof(ChromakeyContext),
380 .process_command = process_command,
381};
382
383static const AVOption chromahold_options[] = {
384 { "color", "set the chromahold key color", OFFSET(chromakey_rgba), AV_OPT_TYPE_COLOR, { .str = "black" }, 0, 0, FLAGS },
385 { "similarity", "set the chromahold similarity value", OFFSET(similarity), AV_OPT_TYPE_FLOAT, { .dbl = 0.01 }, 0.00001, 1.0, FLAGS },
386 { "blend", "set the chromahold blend value", OFFSET(blend), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, 0.0, 1.0, FLAGS },
387 { "yuv", "color parameter is in yuv instead of rgb", OFFSET(is_yuv), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
388 { NULL }
389};
390
409
411
413 .p.name = "chromahold",
414 .p.description = NULL_IF_CONFIG_SMALL("Turns a certain color range into gray."),
415 .p.priv_class = &chromahold_class,
417 .priv_size = sizeof(ChromakeyContext),
421 .process_command = process_command,
422};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static const AVFilterPad inputs[]
Definition af_aap.c:299
static const AVFilterPad outputs[]
Definition af_aap.c:310
static int config_input(AVFilterLink *inlink)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
const FFFilter ff_vf_chromakey
const FFFilter ff_vf_chromahold
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition avfilter.c:906
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition avfilter.c:1696
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition avfilter.c:846
Main libavfilter public API header.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define FLAGS
Definition cmdutils.c:598
#define av_clipd
Definition common.h:148
#define NULL
Definition coverity.c:32
#define max(a, b)
static AVFrame * frame
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition opt.h:270
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ AV_OPT_TYPE_COLOR
Underlying C type is uint8_t[4].
Definition opt.h:322
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition avfilter.h:196
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition avfilter.h:166
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
static const int16_t alpha[]
Definition ilbcdata.h:55
#define AV_WN16(p, v)
#define AV_RN16(p)
static int config_output(AVBitStreamFilterLink *outlink)
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
const char * arg
Definition jacosubdec.c:65
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition filters.h:763
#define AVFILTERPAD_FLAG_NEEDS_WRITABLE
The filter expects writable frames from its input link, duplicating data buffers if needed.
Definition filters.h:59
#define FILTER_PIXFMTS_ARRAY(array)
Definition filters.h:244
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
static const int factor[16]
Definition vf_pp7.c:98
#define av_always_inline
Definition attributes.h:72
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
const char * desc
Definition libsvtav1.c:83
#define FFMIN(a, b)
Definition macros.h:49
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
Definition mpeg12dec.c:1697
AVOptions.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_YUV420P16
Definition pixfmt.h:556
#define AV_PIX_FMT_YUV444P12
Definition pixfmt.h:552
#define AV_PIX_FMT_YUV444P9
Definition pixfmt.h:544
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
#define AV_PIX_FMT_YUV422P9
Definition pixfmt.h:543
#define AV_PIX_FMT_YUVA444P10
Definition pixfmt.h:598
#define AV_PIX_FMT_YUVA420P16
Definition pixfmt.h:601
#define AV_PIX_FMT_YUV420P12
Definition pixfmt.h:549
#define AV_PIX_FMT_YUVA420P10
Definition pixfmt.h:596
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition pixfmt.h:819
#define AV_PIX_FMT_YUVA422P9
Definition pixfmt.h:594
#define AV_PIX_FMT_YUV422P12
Definition pixfmt.h:550
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
#define AV_PIX_FMT_YUV420P9
Definition pixfmt.h:542
#define AV_PIX_FMT_YUVA420P9
Definition pixfmt.h:593
#define AV_PIX_FMT_YUVA422P10
Definition pixfmt.h:597
#define AV_PIX_FMT_YUV420P14
Definition pixfmt.h:553
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition pixfmt.h:108
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition pixfmt.h:174
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition pixfmt.h:173
#define AV_PIX_FMT_YUVA422P12
Definition pixfmt.h:599
#define AV_PIX_FMT_YUV422P14
Definition pixfmt.h:554
#define AV_PIX_FMT_YUV422P16
Definition pixfmt.h:557
#define AV_PIX_FMT_YUVA444P16
Definition pixfmt.h:603
#define AV_PIX_FMT_YUVA422P16
Definition pixfmt.h:602
#define AV_PIX_FMT_YUV444P14
Definition pixfmt.h:555
#define AV_PIX_FMT_YUVA444P9
Definition pixfmt.h:595
#define AV_PIX_FMT_YUVA444P12
Definition pixfmt.h:600
#define AV_PIX_FMT_YUV444P16
Definition pixfmt.h:558
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
const AVFilter * filter
the AVFilter of which this is an instance
Definition avfilter.h:276
void * priv
private data for use by the filter
Definition avfilter.h:288
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:285
A filter pad used for either input or output.
Definition filters.h:40
const char * name
Filter name.
Definition avfilter.h:219
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
uint16_t chromakey_uv[2]
int(* do_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
uint8_t chromakey_rgba[4]
static AVFormatContext * ctx
Definition movenc.c:49
static const AVOption chromahold_options[]
static av_always_inline void get_pixel_uv(AVFrame *frame, int hsub_log2, int vsub_log2, int x, int y, uint8_t *u, uint8_t *v)
static uint8_t do_chromakey_pixel(ChromakeyContext *ctx, uint8_t u[9], uint8_t v[9])
static const AVOption chromakey_options[]
static int do_chromahold_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
#define RGB_TO_V(rgb)
static av_cold int config_output(AVFilterLink *outlink)
static enum AVPixelFormat chromakey_fmts[]
static av_cold int config_input(AVFilterLink *inlink)
static enum AVPixelFormat hold_pixel_fmts[]
static int filter_frame(AVFilterLink *link, AVFrame *frame)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
#define RGB_TO_U(rgb)
static int do_chromahold16_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
#define OFFSET(x)
static uint16_t do_chromakey_pixel16(ChromakeyContext *ctx, uint16_t u[9], uint16_t v[9])
static int do_chromakey16_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
static int do_chromakey_slice(AVFilterContext *avctx, void *arg, int jobnr, int nb_jobs)
static av_always_inline void get_pixel16_uv(AVFrame *frame, int hsub_log2, int vsub_log2, int x, int y, uint16_t *u, uint16_t *v)
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition dec.c:844