FFmpeg
Loading...
Searching...
No Matches
vf_drawbox.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 Affine Systems, Inc (Michael Sullivan, Bobby Impollonia)
3 * Copyright (c) 2013 Andrey Utkin <andrey.krieger.utkin gmail com>
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 * Box and grid drawing filters. Also a nice template for a filter
25 * that needs to write in the input frame.
26 */
27
28#include "config_components.h"
29
31#include "libavutil/common.h"
32#include "libavutil/opt.h"
33#include "libavutil/eval.h"
34#include "libavutil/pixdesc.h"
37#include "avfilter.h"
38#include "drawutils.h"
39#include "filters.h"
40#include "video.h"
41
42static const char *const var_names[] = {
43 "dar",
44 "hsub", "vsub",
45 "in_h", "ih", ///< height of the input video
46 "in_w", "iw", ///< width of the input video
47 "sar",
48 "x",
49 "y",
50 "h", ///< height of the rendered box
51 "w", ///< width of the rendered box
52 "t",
53 "fill",
54 NULL
55};
56
57enum { Y, U, V, A };
58enum { R, G, B };
59
74
75struct DrawBoxContext;
76
77typedef int (*PixelBelongsToRegion)(struct DrawBoxContext *s, int x, int y);
78
79typedef struct DrawBoxContext {
80 const AVClass *class;
81 int x, y, w, h;
83 char *color_str;
84 uint8_t rgba_map[4];
85 uint8_t rgba_color[4];
86 unsigned char yuv_color[4];
87 int invert_color; ///< invert luma color
88 int vsub, hsub; ///< chroma subsampling
89 char *x_expr, *y_expr; ///< expression for x and y
90 char *w_expr, *h_expr; ///< expression for width and height
91 char *t_expr; ///< expression for thickness
92 char *box_source_string; ///< string for box data source
95 int step;
97
98 void (*draw_region)(AVFrame *frame, struct DrawBoxContext *ctx, int left, int top, int right, int down,
99 PixelBelongsToRegion pixel_belongs_to_region);
101
102static const int NUM_EXPR_EVALS = 5;
103
104#define ASSIGN_THREE_CHANNELS \
105 row[0] = frame->data[0] + y * frame->linesize[0]; \
106 row[1] = frame->data[1] + (y >> ctx->vsub) * frame->linesize[1]; \
107 row[2] = frame->data[2] + (y >> ctx->vsub) * frame->linesize[2];
108
109#define ASSIGN_FOUR_CHANNELS \
110 ASSIGN_THREE_CHANNELS \
111 row[3] = frame->data[3] + y * frame->linesize[3];
112
113static void draw_region(AVFrame *frame, DrawBoxContext *ctx, int left, int top, int right, int down,
114 PixelBelongsToRegion pixel_belongs_to_region)
115{
116 unsigned char *row[4];
117 int x, y;
118 if (ctx->have_alpha && ctx->replace) {
119 for (y = top; y < down; y++) {
121 if (ctx->invert_color) {
122 for (x = left; x < right; x++)
123 if (pixel_belongs_to_region(ctx, x, y))
124 row[0][x] = 0xff - row[0][x];
125 } else {
126 for (x = left; x < right; x++) {
127 if (pixel_belongs_to_region(ctx, x, y)) {
128 row[0][x ] = ctx->yuv_color[Y];
129 row[1][x >> ctx->hsub] = ctx->yuv_color[U];
130 row[2][x >> ctx->hsub] = ctx->yuv_color[V];
131 row[3][x ] = ctx->yuv_color[A];
132 }
133 }
134 }
135 }
136 } else {
137 const double alpha = (double)ctx->yuv_color[A] / 255;
138 const int hsub = ctx->hsub;
139 const int yc = ctx->yuv_color[Y];
140 const int uc = ctx->yuv_color[U];
141 const int vc = ctx->yuv_color[V];
142
143 for (y = top; y < down; y++) {
145 if (ctx->invert_color) {
146 for (x = left; x < right; x++)
147 if (pixel_belongs_to_region(ctx, x, y))
148 row[0][x] = 0xff - row[0][x];
149 } else {
150 for (x = left; x < right; x++) {
151 if (pixel_belongs_to_region(ctx, x, y)) {
152 row[0][x ] = (1 - alpha) * row[0][x ] + alpha * yc;
153 row[1][x >> hsub] = (1 - alpha) * row[1][x >> hsub] + alpha * uc;
154 row[2][x >> hsub] = (1 - alpha) * row[2][x >> hsub] + alpha * vc;
155 }
156 }
157 }
158 }
159 }
160}
161
162#define ASSIGN_THREE_CHANNELS_PACKED \
163 row[0] = frame->data[0] + y * frame->linesize[0] + ctx->rgba_map[0]; \
164 row[1] = frame->data[0] + y * frame->linesize[0] + ctx->rgba_map[1]; \
165 row[2] = frame->data[0] + y * frame->linesize[0] + ctx->rgba_map[2];
166
167#define ASSIGN_FOUR_CHANNELS_PACKED \
168 ASSIGN_THREE_CHANNELS_PACKED \
169 row[3] = frame->data[0] + y * frame->linesize[0] + ctx->rgba_map[3];
170
171static void draw_region_rgb_packed(AVFrame *frame, DrawBoxContext *ctx, int left, int top, int right, int down,
172 PixelBelongsToRegion pixel_belongs_to_region)
173{
174 const int C = ctx->step;
175 uint8_t *row[4];
176
177 if (ctx->have_alpha && ctx->replace) {
178 for (int y = top; y < down; y++) {
180 if (ctx->invert_color) {
181 for (int x = left; x < right; x++)
182 if (pixel_belongs_to_region(ctx, x, y)) {
183 row[0][x*C] = 0xff - row[0][x*C];
184 row[1][x*C] = 0xff - row[1][x*C];
185 row[2][x*C] = 0xff - row[2][x*C];
186 }
187 } else {
188 for (int x = left; x < right; x++) {
189 if (pixel_belongs_to_region(ctx, x, y)) {
190 row[0][x*C] = ctx->rgba_color[R];
191 row[1][x*C] = ctx->rgba_color[G];
192 row[2][x*C] = ctx->rgba_color[B];
193 row[3][x*C] = ctx->rgba_color[A];
194 }
195 }
196 }
197 }
198 } else {
199 const float alpha = (float)ctx->rgba_color[A] / 255.f;
200
201 for (int y = top; y < down; y++) {
203 if (ctx->invert_color) {
204 for (int x = left; x < right; x++)
205 if (pixel_belongs_to_region(ctx, x, y)) {
206 row[0][x*C] = 0xff - row[0][x*C];
207 row[1][x*C] = 0xff - row[1][x*C];
208 row[2][x*C] = 0xff - row[2][x*C];
209 }
210 } else {
211 for (int x = left; x < right; x++) {
212 if (pixel_belongs_to_region(ctx, x, y)) {
213 row[0][x*C] = (1.f - alpha) * row[0][x*C] + alpha * ctx->rgba_color[R];
214 row[1][x*C] = (1.f - alpha) * row[1][x*C] + alpha * ctx->rgba_color[G];
215 row[2][x*C] = (1.f - alpha) * row[2][x*C] + alpha * ctx->rgba_color[B];
216 }
217 }
218 }
219 }
220 }
221}
222
224{
226 if (!strcmp(box_source_string, "side_data_detection_bboxes")) {
228 } else {
229 // will support side_data_regions_of_interest next
230 return AVERROR(EINVAL);
231 }
232}
233
235{
236 DrawBoxContext *s = ctx->priv;
237
238 if (s->box_source_string) {
239 s->box_source = box_source_string_parse(s->box_source_string);
240 if ((int)s->box_source < 0) {
241 av_log(ctx, AV_LOG_ERROR, "Error box source: %s\n",s->box_source_string);
242 return AVERROR(EINVAL);
243 }
244 }
245
246 if (!strcmp(s->color_str, "invert"))
247 s->invert_color = 1;
248 else if (av_parse_color(s->rgba_color, s->color_str, -1, ctx) < 0)
249 return AVERROR(EINVAL);
250
251 if (!s->invert_color) {
252 s->yuv_color[Y] = RGB_TO_Y_CCIR(s->rgba_color[0], s->rgba_color[1], s->rgba_color[2]);
253 s->yuv_color[U] = RGB_TO_U_CCIR(s->rgba_color[0], s->rgba_color[1], s->rgba_color[2], 0);
254 s->yuv_color[V] = RGB_TO_V_CCIR(s->rgba_color[0], s->rgba_color[1], s->rgba_color[2], 0);
255 s->yuv_color[A] = s->rgba_color[3];
256 }
257
258 return 0;
259}
260
274
275static int config_input(AVFilterLink *inlink)
276{
277 AVFilterContext *ctx = inlink->dst;
278 DrawBoxContext *s = ctx->priv;
280 double var_values[VARS_NB], res;
281 char *expr;
282 int ret;
283 int i;
284
285 ff_fill_rgba_map(s->rgba_map, inlink->format);
286
287 if (!(desc->flags & AV_PIX_FMT_FLAG_RGB))
288 s->draw_region = draw_region;
289 else
290 s->draw_region = draw_region_rgb_packed;
291
292 s->step = av_get_padded_bits_per_pixel(desc) >> 3;
293 s->hsub = desc->log2_chroma_w;
294 s->vsub = desc->log2_chroma_h;
295 s->have_alpha = desc->flags & AV_PIX_FMT_FLAG_ALPHA;
296
297 var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
298 var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
299 var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
300 var_values[VAR_DAR] = (double)inlink->w / inlink->h * var_values[VAR_SAR];
301 var_values[VAR_HSUB] = s->hsub;
302 var_values[VAR_VSUB] = s->vsub;
303 var_values[VAR_X] = NAN;
304 var_values[VAR_Y] = NAN;
305 var_values[VAR_H] = NAN;
306 var_values[VAR_W] = NAN;
307 var_values[VAR_T] = NAN;
308
309 for (i = 0; i <= NUM_EXPR_EVALS; i++) {
310 /* evaluate expressions, fail on last iteration */
311 var_values[VAR_MAX] = inlink->w;
312 if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),
313 var_names, var_values,
314 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
315 goto fail;
316 var_values[VAR_X] = res;
317
318 var_values[VAR_MAX] = inlink->h;
319 if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
320 var_names, var_values,
321 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
322 goto fail;
323 var_values[VAR_Y] = res;
324
325 var_values[VAR_MAX] = inlink->w - trunc(var_values[VAR_X]);
326 if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
327 var_names, var_values,
328 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
329 goto fail;
330 var_values[VAR_W] = res;
331
332 var_values[VAR_MAX] = inlink->h - trunc(var_values[VAR_Y]);
333 if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
334 var_names, var_values,
335 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
336 goto fail;
337 var_values[VAR_H] = res;
338
339 var_values[VAR_MAX] = INT_MAX;
340 if ((ret = av_expr_parse_and_eval(&res, (expr = s->t_expr),
341 var_names, var_values,
342 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
343 goto fail;
344 var_values[VAR_T] = res;
345 }
346
347 if (!(fabs(var_values[VAR_X]) <= INT_MAX / 4 && fabs(var_values[VAR_Y]) <= INT_MAX / 4 &&
348 fabs(var_values[VAR_W]) <= INT_MAX / 4 && fabs(var_values[VAR_H]) <= INT_MAX / 4 &&
349 fabs(var_values[VAR_T]) <= INT_MAX)) {
350 av_log(ctx, AV_LOG_ERROR, "Position, size or thickness out of range.\n");
351 return AVERROR(EINVAL);
352 }
353 s->x = var_values[VAR_X];
354 s->y = var_values[VAR_Y];
355 s->w = var_values[VAR_W];
356 s->h = var_values[VAR_H];
357 s->thickness = var_values[VAR_T];
358
359 /* if w or h are zero, use the input w/h */
360 s->w = (s->w > 0) ? s->w : inlink->w;
361 s->h = (s->h > 0) ? s->h : inlink->h;
362
363 /* sanity check width and height */
364 if (s->w < 0 || s->h < 0) {
365 av_log(ctx, AV_LOG_ERROR, "Size values less than 0 are not acceptable.\n");
366 return AVERROR(EINVAL);
367 }
368
369 av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d w:%d h:%d color:0x%02X%02X%02X%02X\n",
370 s->x, s->y, s->w, s->h,
371 s->yuv_color[Y], s->yuv_color[U], s->yuv_color[V], s->yuv_color[A]);
372
373 return 0;
374
375fail:
377 "Error when evaluating the expression '%s'.\n",
378 expr);
379 return ret;
380}
381
383{
384 return (y - s->y < s->thickness) || (s->y + s->h - 1 - y < s->thickness) ||
385 (x - s->x < s->thickness) || (s->x + s->w - 1 - x < s->thickness);
386}
387
389{
390 AVFilterContext *ctx = inlink->dst;
391 DrawBoxContext *s = ctx->priv;
393 const AVDetectionBBox *bbox;
394 AVFrameSideData *sd;
395 int loop = 1;
396
397 if (s->box_source == AV_FRAME_DATA_DETECTION_BBOXES) {
399 if (sd) {
401 loop = header->nb_bboxes;
402 } else {
403 av_log(ctx, AV_LOG_WARNING, "No detection bboxes.\n");
404 return ff_filter_frame(inlink->dst->outputs[0], frame);
405 }
406 }
407
408 for (int i = 0; i < loop; i++) {
409 if (header) {
411 s->y = bbox->y;
412 s->x = bbox->x;
413 s->h = bbox->h;
414 s->w = bbox->w;
415 }
416
417 s->draw_region(frame, s, FFMAX(s->x, 0), FFMAX(s->y, 0), FFMIN(s->x + s->w, frame->width),
418 FFMIN(s->y + s->h, frame->height), pixel_belongs_to_box);
419 }
420
421 return ff_filter_frame(inlink->dst->outputs[0], frame);
422}
423
424static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
425{
426 AVFilterLink *inlink = ctx->inputs[0];
427 DrawBoxContext *s = ctx->priv;
428 int old_x = s->x;
429 int old_y = s->y;
430 int old_w = s->w;
431 int old_h = s->h;
432 int old_t = s->thickness;
433 int old_r = s->replace;
434 int ret;
435
436 ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
437 if (ret < 0)
438 return ret;
439
440 ret = init(ctx);
441 if (ret < 0)
442 goto end;
443 ret = config_input(inlink);
444end:
445 if (ret < 0) {
446 s->x = old_x;
447 s->y = old_y;
448 s->w = old_w;
449 s->h = old_h;
450 s->thickness = old_t;
451 s->replace = old_r;
452 }
453
454 return ret;
455}
456
457#define OFFSET(x) offsetof(DrawBoxContext, x)
458#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
459
460#if CONFIG_DRAWBOX_FILTER
461
462static const AVOption drawbox_options[] = {
463 { "x", "set horizontal position of the left box edge", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
464 { "y", "set vertical position of the top box edge", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
465 { "width", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
466 { "w", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
467 { "height", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
468 { "h", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
469 { "color", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS },
470 { "c", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS },
471 { "thickness", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, 0, 0, FLAGS },
472 { "t", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, 0, 0, FLAGS },
473 { "replace", "replace color & alpha", OFFSET(replace), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, FLAGS },
474 { "box_source","use data from bounding box in side data", OFFSET(box_source_string), AV_OPT_TYPE_STRING, { .str=NULL }, 0, 1, FLAGS },
475 { NULL }
476};
477
478AVFILTER_DEFINE_CLASS(drawbox);
479
480static const AVFilterPad drawbox_inputs[] = {
481 {
482 .name = "default",
483 .type = AVMEDIA_TYPE_VIDEO,
485 .config_props = config_input,
486 .filter_frame = filter_frame,
487 },
488};
489
490const FFFilter ff_vf_drawbox = {
491 .p.name = "drawbox",
492 .p.description = NULL_IF_CONFIG_SMALL("Draw a colored box on the input video."),
493 .p.priv_class = &drawbox_class,
495 .priv_size = sizeof(DrawBoxContext),
496 .init = init,
497 FILTER_INPUTS(drawbox_inputs),
500 .process_command = process_command,
501 .flags_internal = FF_FILTER_FLAG_DYNAMIC_FRAME_SIZE,
502};
503#endif /* CONFIG_DRAWBOX_FILTER */
504
505#if CONFIG_DRAWGRID_FILTER
506static av_pure av_always_inline int pixel_belongs_to_grid(DrawBoxContext *drawgrid, int x, int y)
507{
508 // x is horizontal (width) coord,
509 // y is vertical (height) coord
510 int x_modulo;
511 int y_modulo;
512
513 // Abstract from the offset
514 x -= drawgrid->x;
515 y -= drawgrid->y;
516
517 x_modulo = x % drawgrid->w;
518 y_modulo = y % drawgrid->h;
519
520 // If x or y got negative, fix values to preserve logics
521 if (x_modulo < 0)
522 x_modulo += drawgrid->w;
523 if (y_modulo < 0)
524 y_modulo += drawgrid->h;
525
526 return x_modulo < drawgrid->thickness // Belongs to vertical line
527 || y_modulo < drawgrid->thickness; // Belongs to horizontal line
528}
529
530static int drawgrid_filter_frame(AVFilterLink *inlink, AVFrame *frame)
531{
532 DrawBoxContext *drawgrid = inlink->dst->priv;
533
534 drawgrid->draw_region(frame, drawgrid, 0, 0, frame->width, frame->height, pixel_belongs_to_grid);
535
536 return ff_filter_frame(inlink->dst->outputs[0], frame);
537}
538
539static const AVOption drawgrid_options[] = {
540 { "x", "set horizontal offset", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
541 { "y", "set vertical offset", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
542 { "width", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
543 { "w", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
544 { "height", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
545 { "h", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS },
546 { "color", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS },
547 { "c", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS },
548 { "thickness", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, 0, 0, FLAGS },
549 { "t", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, 0, 0, FLAGS },
550 { "replace", "replace color & alpha", OFFSET(replace), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, FLAGS },
551 { NULL }
552};
553
554AVFILTER_DEFINE_CLASS(drawgrid);
555
556static const AVFilterPad drawgrid_inputs[] = {
557 {
558 .name = "default",
559 .type = AVMEDIA_TYPE_VIDEO,
561 .config_props = config_input,
562 .filter_frame = drawgrid_filter_frame,
563 },
564};
565
566const FFFilter ff_vf_drawgrid = {
567 .p.name = "drawgrid",
568 .p.description = NULL_IF_CONFIG_SMALL("Draw a colored grid on the input video."),
569 .p.priv_class = &drawgrid_class,
571 .priv_size = sizeof(DrawBoxContext),
572 .init = init,
573 FILTER_INPUTS(drawgrid_inputs),
576 .process_command = process_command,
577 .flags_internal = FF_FILTER_FLAG_DYNAMIC_FRAME_SIZE,
578};
579
580#endif /* CONFIG_DRAWGRID_FILTER */
@ VAR_T
Definition aeval.c:53
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_drawbox
const FFFilter ff_vf_drawgrid
static AVFormatContext * ctx
#define U(x)
Definition vpx_arith.h:37
#define A(x)
Definition vpx_arith.h:28
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define V
Definition avdct.c:32
@ VAR_H
Definition avfilter.c:574
@ VAR_W
Definition avfilter.c:573
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1079
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:917
Main libavfilter public API header.
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
@ VAR_VSUB
Definition boxblur.c:42
@ VARS_NB
Definition boxblur.c:43
@ VAR_HSUB
Definition boxblur.c:41
#define Y
Definition boxblur.h:37
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:596
common internal and external API header
#define NULL
Definition coverity.c:32
static __device__ float fabs(float a)
static __device__ float trunc(float a)
static AVFrame * frame
static av_always_inline AVDetectionBBox * av_get_detection_bbox(const AVDetectionBBoxHeader *header, unsigned int idx)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition drawutils.c:80
misc drawing utilities
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:613
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition eval.c:839
simple arithmetic expression evaluator
@ VAR_MAX
Definition f_drawgraph.c:91
@ VAR_IW
Definition f_select.c:147
@ VAR_IH
Definition f_select.c:146
int ret
Definition ffplay.c:391
static int loop
Definition ffplay.c:367
#define fail
Definition test.h:479
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#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:202
#define AVERROR(e)
Definition error.h:45
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:662
AVFrameSideDataType
Definition frame.h:49
@ AV_FRAME_DATA_DETECTION_BBOXES
Bounding boxes for object detection and classification, as described by AVDetectionBBoxHeader.
Definition frame.h:194
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define B
Definition huffyuv.h:42
#define R
Definition huffyuv.h:44
#define G
Definition huffyuv.h:43
static const int16_t alpha[]
Definition ilbcdata.h:55
#define C
#define FILTER_INPUTS(array)
Definition filters.h:279
#define FILTER_OUTPUTS(array)
Definition filters.h:280
#define FF_FILTER_FLAG_DYNAMIC_FRAME_SIZE
The filter handles input frames whose size differs from the one its input link was configured with.
Definition filters.h:214
#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:259
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:493
@ VAR_X
Definition vf_blend.c:55
@ VAR_Y
Definition vf_blend.c:55
#define av_always_inline
Definition attributes.h:72
#define av_cold
Definition attributes.h:117
#define av_pure
Definition attributes.h:105
Various defines for YUV<->RGB conversion.
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
Definition colorspace.h:102
#define RGB_TO_Y_CCIR(r, g, b)
Definition colorspace.h:98
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
Definition colorspace.h:106
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
const char * desc
Definition libsvtav1.c:83
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define NAN
var_name
Definition noise.c:46
static const char *const var_names[]
Definition noise.c:30
AVOptions.
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx)
Put the RGBA values that correspond to color_string in rgba_color.
Definition parseutils.c:359
misc parsing utilities
int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel for the pixel format described by pixdesc, including any padding ...
Definition pixdesc.c:3449
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition pixdesc.h:147
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition pixdesc.h:136
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ 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_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition pixfmt.h:106
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition pixfmt.h:265
@ 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_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition pixfmt.h:99
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition pixfmt.h:102
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition pixfmt.h:101
@ 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_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition pixfmt.h:107
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition pixfmt.h:79
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition pixfmt.h:264
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition pixfmt.h:80
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition pixfmt.h:100
@ 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_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition pixfmt.h:86
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition pixfmt.h:263
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition pixfmt.h:173
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition pixfmt.h:262
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition pixfmt.h:87
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition pixfmt.h:85
@ VAR_SAR
Definition scale_eval.c:49
@ VAR_IN_W
Definition scale_eval.c:44
@ VAR_IN_H
Definition scale_eval.c:45
@ VAR_DAR
Definition scale_eval.c:50
static const uint8_t header[24]
Definition sdr2.c:68
Describe the class of an AVClass context structure.
Definition log.h:76
int x
Distance in pixels from the left/top edge of the frame, together with width and height,...
An instance of a filter.
Definition avfilter.h:279
void * priv
private data for use by the filter
Definition avfilter.h:294
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:291
A filter pad used for either input or output.
Definition filters.h:40
Structure to hold side data for an AVFrame.
Definition frame.h:334
uint8_t * data
Definition frame.h:336
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
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
int num
Numerator.
Definition rational.h:59
char * y_expr
expression for x and y
Definition vf_drawbox.c:89
void(* draw_region)(AVFrame *frame, struct DrawBoxContext *ctx, int left, int top, int right, int down, PixelBelongsToRegion pixel_belongs_to_region)
Definition vf_drawbox.c:98
char * h_expr
expression for width and height
Definition vf_drawbox.c:90
uint8_t rgba_map[4]
Definition vf_drawbox.c:84
int invert_color
invert luma color
Definition vf_drawbox.c:87
char * color_str
Definition vf_drawbox.c:83
char * t_expr
expression for thickness
Definition vf_drawbox.c:91
int hsub
chroma subsampling
Definition vf_drawbox.c:88
unsigned char yuv_color[4]
Definition vf_drawbox.c:86
uint8_t rgba_color[4]
Definition vf_drawbox.c:85
char * box_source_string
string for box data source
Definition vf_drawbox.c:92
enum AVFrameSideDataType box_source
Definition vf_drawbox.c:96
#define av_log(a,...)
int(* PixelBelongsToRegion)(struct DrawBoxContext *s, int x, int y)
Definition vf_drawbox.c:77
static const int NUM_EXPR_EVALS
Definition vf_drawbox.c:102
static int config_input(AVFilterLink *inlink)
Definition vf_drawbox.c:275
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition vf_drawbox.c:388
#define ASSIGN_FOUR_CHANNELS
Definition vf_drawbox.c:109
#define ASSIGN_FOUR_CHANNELS_PACKED
Definition vf_drawbox.c:167
static av_pure av_always_inline int pixel_belongs_to_box(DrawBoxContext *s, int x, int y)
Definition vf_drawbox.c:382
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition vf_drawbox.c:424
#define OFFSET(x)
Definition vf_drawbox.c:457
#define ASSIGN_THREE_CHANNELS_PACKED
Definition vf_drawbox.c:162
static void draw_region_rgb_packed(AVFrame *frame, DrawBoxContext *ctx, int left, int top, int right, int down, PixelBelongsToRegion pixel_belongs_to_region)
Definition vf_drawbox.c:171
static void draw_region(AVFrame *frame, DrawBoxContext *ctx, int left, int top, int right, int down, PixelBelongsToRegion pixel_belongs_to_region)
Definition vf_drawbox.c:113
#define ASSIGN_THREE_CHANNELS
Definition vf_drawbox.c:104
static enum AVFrameSideDataType box_source_string_parse(const char *box_source_string)
Definition vf_drawbox.c:223
static void hsub(htype *dst, const htype *src, int bins)
Definition vf_median.c:74
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition video.c:37