FFmpeg
qrencode.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file QR encoder source and filter.
21  *
22  * A QR code (quick-response code) is a type of two-dimensional matrix
23  * barcode, invented in 1994, by Japanese company Denso Wave for
24  * labelling automobile parts.
25  *
26  * This source uses the libqrencode library to generate QR code:
27  * https://fukuchi.org/works/qrencode/
28  */
29 
30 //#define DEBUG
31 
32 #include "config_components.h"
33 
34 #include "libavutil/internal.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/mem.h"
37 #include "libavutil/opt.h"
38 #include "libavutil/lfg.h"
39 #include "libavutil/random_seed.h"
40 
41 #include "avfilter.h"
42 #include "drawutils.h"
43 #include "filters.h"
44 #include "formats.h"
45 #include "textutils.h"
46 #include "video.h"
47 #include "libswscale/swscale.h"
48 
49 #include <qrencode.h>
50 
51 enum var_name {
67 };
68 
69 static const char *const var_names[] = {
70  "dar",
71  "duration",
72  "hsub", "vsub",
73  "main_h", "H", ///< height of the input video
74  "main_w", "W", ///< width of the input video
75  "n", ///< number of frame
76  "pict_type",
77  "qr_w", "w", ///< width of the QR code
78  "rendered_padded_qr_w", "Q", ///< width of the rendered QR code
79  "rendered_qr_w", "q", ///< width of the rendered QR code
80  "sar",
81  "t", ///< timestamp expressed in seconds
82  "x",
83  "y",
84  NULL
85 };
86 
87 #define V(name_) qr->var_values[VAR_##name_]
88 
89 enum Expansion {
92 };
93 
94 typedef struct QREncodeContext {
95  const AVClass *class;
96 
97  char is_source;
98  char *x_expr;
99  char *y_expr;
101 
105 
108 
109  unsigned char *text;
110  char *textfile;
111  uint64_t pts;
112 
113  int level;
115 
116  uint8_t foreground_color[4];
117  uint8_t background_color[4];
118 
120  FFDrawColor draw_foreground_color; ///< foreground color
121  FFDrawColor draw_background_color; ///< background color
122 
123  /* these are only used when nothing must be encoded */
125  FFDrawColor draw0_background_color; ///< background color
126 
127  uint8_t *qrcode_data[4];
129  uint8_t *qrcode_mask_data[4];
131 
132  /* only used for filter to contain scaled image to blend on top of input */
133  uint8_t *rendered_qrcode_data[4];
135 
138 
140 
141  int expansion; ///< expansion mode to use for the text
142  FFExpandTextContext expand_text; ///< expand text in case expansion is enabled
143  AVBPrint expanded_text; ///< used to contain the expanded text
144 
146  AVLFG lfg; ///< random generator
149 
150 #define OFFSET(x) offsetof(QREncodeContext, x)
151 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
152 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
153 
154 #define COMMON_OPTIONS \
155  { "qrcode_width", "set rendered QR code width expression", OFFSET(rendered_qrcode_width_expr), AV_OPT_TYPE_STRING, {.str = "64"}, 0, INT_MAX, FLAGS }, \
156  { "q", "set rendered QR code width expression", OFFSET(rendered_qrcode_width_expr), AV_OPT_TYPE_STRING, {.str = "64"}, 0, INT_MAX, FLAGS }, \
157  { "padded_qrcode_width", "set rendered padded QR code width expression", OFFSET(rendered_padded_qrcode_width_expr), AV_OPT_TYPE_STRING, {.str = "q"}, 0, INT_MAX, FLAGS }, \
158  { "Q", "set rendered padded QR code width expression", OFFSET(rendered_padded_qrcode_width_expr), AV_OPT_TYPE_STRING, {.str = "q"}, 0, INT_MAX, FLAGS }, \
159  { "case_sensitive", "generate code which is case sensitive", OFFSET(case_sensitive), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS }, \
160  { "cs", "generate code which is case sensitive", OFFSET(case_sensitive), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS }, \
161  \
162  { "level", "error correction level, lowest is L", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = AVCOL_SPC_UNSPECIFIED }, 0, QR_ECLEVEL_H, .flags = FLAGS, .unit = "level"}, \
163  { "l", "error correction level, lowest is L", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = AVCOL_SPC_UNSPECIFIED }, 0, QR_ECLEVEL_H, .flags = FLAGS, .unit = "level"}, \
164  { "L", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_L }, 0, 0, FLAGS, .unit = "level" }, \
165  { "M", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_M }, 0, 0, FLAGS, .unit = "level" }, \
166  { "Q", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_Q }, 0, 0, FLAGS, .unit = "level" }, \
167  { "H", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_H }, 0, 0, FLAGS, .unit = "level" }, \
168  \
169  {"expansion", "set the expansion mode", OFFSET(expansion), AV_OPT_TYPE_INT, {.i64=EXPANSION_NORMAL}, 0, 2, FLAGS, .unit = "expansion"}, \
170  {"none", "set no expansion", OFFSET(expansion), AV_OPT_TYPE_CONST, {.i64 = EXPANSION_NONE}, 0, 0, FLAGS, .unit = "expansion"}, \
171  {"normal", "set normal expansion", OFFSET(expansion), AV_OPT_TYPE_CONST, {.i64 = EXPANSION_NORMAL}, 0, 0, FLAGS, .unit = "expansion"}, \
172  \
173  { "foreground_color", "set QR foreground color", OFFSET(foreground_color), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGS }, \
174  { "fc", "set QR foreground color", OFFSET(foreground_color), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGS }, \
175  { "background_color", "set QR background color", OFFSET(background_color), AV_OPT_TYPE_COLOR, {.str = "white"}, 0, 0, FLAGS }, \
176  { "bc", "set QR background color", OFFSET(background_color), AV_OPT_TYPE_COLOR, {.str = "white"}, 0, 0, FLAGS }, \
177  \
178  {"text", "set text to encode", OFFSET(text), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS}, \
179  {"textfile", "set text file to encode", OFFSET(textfile), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS}, \
180 
181 static const char *const fun2_names[] = {
182  "rand"
183 };
184 
185 static double drand(void *opaque, double min, double max)
186 {
187  return min + (max-min) / UINT_MAX * av_lfg_get(opaque);
188 }
189 
190 static const ff_eval_func2 fun2[] = {
191  drand,
192  NULL
193 };
194 
195 static int func_pts(void *ctx, AVBPrint *bp, const char *function_name,
196  unsigned argc, char **argv)
197 {
198  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
199  const char *fmt;
200  const char *strftime_fmt = NULL;
201  const char *delta = NULL;
202  double t = qr->var_values[VAR_t];
203 
204  // argv: pts, FMT, [DELTA, strftime_fmt]
205 
206  fmt = argc >= 1 ? argv[0] : "flt";
207  if (argc >= 2) {
208  delta = argv[1];
209  }
210  if (argc >= 3) {
211  strftime_fmt = argv[2];
212  }
213 
214  return ff_print_pts(ctx, bp, t, delta, fmt, strftime_fmt);
215 }
216 
217 static int func_frame_num(void *ctx, AVBPrint *bp, const char *function_name,
218  unsigned argc, char **argv)
219 {
220  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
221 
222  av_bprintf(bp, "%d", (int)V(n));
223  return 0;
224 }
225 
226 static int func_strftime(void *ctx, AVBPrint *bp, const char *function_name,
227  unsigned argc, char **argv)
228 {
229  const char *strftime_fmt = argc ? argv[0] : NULL;
230 
231  return ff_print_time(ctx, bp, strftime_fmt, !strcmp(function_name, "localtime"));
232 }
233 
234 static int func_frame_metadata(void *ctx, AVBPrint *bp, const char *function_name,
235  unsigned argc, char **argv)
236 {
237  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
238  AVDictionaryEntry *e = av_dict_get(qr->metadata, argv[0], NULL, 0);
239 
240  if (e && e->value)
241  av_bprintf(bp, "%s", e->value);
242  else if (argc >= 2)
243  av_bprintf(bp, "%s", argv[1]);
244 
245  return 0;
246 }
247 
248 static int func_eval_expr(void *ctx, AVBPrint *bp, const char *function_name,
249  unsigned argc, char **argv)
250 {
251  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
252 
253  return ff_print_eval_expr(ctx, bp, argv[0],
254  fun2_names, fun2,
255  var_names, qr->var_values, &qr->lfg);
256 }
257 
258 static int func_eval_expr_formatted(void *ctx, AVBPrint *bp, const char *function_name,
259  unsigned argc, char **argv)
260 {
261  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
262  int ret;
263  int positions = -1;
264 
265  /*
266  * argv[0] expression to be converted to `int`
267  * argv[1] format: 'x', 'X', 'd' or 'u'
268  * argv[2] positions printed (optional)
269  */
270 
271  if (argc == 3) {
272  ret = sscanf(argv[2], "%u", &positions);
273  if (ret != 1) {
274  av_log(ctx, AV_LOG_ERROR, "expr_int_format(): Invalid number of positions"
275  " to print: '%s'\n", argv[2]);
276  return AVERROR(EINVAL);
277  }
278  }
279 
280  return ff_print_formatted_eval_expr(ctx, bp, argv[0],
281  fun2_names, fun2,
282  var_names, qr->var_values,
283  &qr->lfg,
284  argv[1][0], positions);
285 }
286 
288  { "expr", 1, 1, func_eval_expr },
289  { "e", 1, 1, func_eval_expr },
290  { "expr_formatted", 2, 3, func_eval_expr_formatted },
291  { "ef", 2, 3, func_eval_expr_formatted },
292  { "metadata", 1, 2, func_frame_metadata },
293  { "frame_num", 0, 0, func_frame_num },
294  { "n", 0, 0, func_frame_num },
295  { "gmtime", 0, 1, func_strftime },
296  { "localtime", 0, 1, func_strftime },
297  { "pts", 0, 3, func_pts }
298 };
299 
301 {
302  QREncodeContext *qr = ctx->priv;
303  int ret;
304 
306 
307  qr->qrcode_width = -1;
309 
310  if (qr->textfile) {
311  if (qr->text) {
313  "Both text and text file provided. Please provide only one\n");
314  return AVERROR(EINVAL);
315  }
316  if ((ret = ff_load_textfile(ctx, (const char *)qr->textfile, &(qr->text), NULL)) < 0)
317  return ret;
318  }
319 
321  .log_ctx = ctx,
322  .functions = expand_text_functions,
323  .functions_nb = FF_ARRAY_ELEMS(expand_text_functions)
324  };
325 
327 
328  return 0;
329 }
330 
332 {
333  QREncodeContext *qr = ctx->priv;
334 
335  av_expr_free(qr->x_pexpr);
336  av_expr_free(qr->y_pexpr);
337 
339 
340  av_freep(&qr->qrcode_data[0]);
342  av_freep(&qr->qrcode_mask_data[0]);
343 }
344 
345 #ifdef DEBUG
346 static void show_qrcode(AVFilterContext *ctx, const QRcode *qrcode)
347 {
348  int i, j;
349  char *line = av_malloc(qrcode->width + 1);
350  const char *p = qrcode->data;
351 
352  if (!line)
353  return;
354  for (i = 0; i < qrcode->width; i++) {
355  for (j = 0; j < qrcode->width; j++)
356  line[j] = (*p++)&1 ? '@' : ' ';
357  line[j] = 0;
358  av_log(ctx, AV_LOG_DEBUG, "%3d: %s\n", i, line);
359  }
360  av_free(line);
361 }
362 #endif
363 
365 {
366  QREncodeContext *qr = ctx->priv;
367  struct SwsContext *sws = NULL;
368  QRcode *qrcode = NULL;
369  int i, j;
370  char qrcode_width_changed;
371  int ret;
372  int offset;
373  uint8_t *srcp;
374  uint8_t *dstp0, *dstp;
375 
377 
378  switch (qr->expansion) {
379  case EXPANSION_NONE:
380  av_bprintf(&qr->expanded_text, "%s", qr->text);
381  break;
382  case EXPANSION_NORMAL:
383  if ((ret = ff_expand_text(&qr->expand_text, qr->text, &qr->expanded_text)) < 0)
384  return ret;
385  break;
386  }
387 
388  if (!qr->expanded_text.str || qr->expanded_text.str[0] == 0) {
389  if (qr->is_source) {
391  frame->data, frame->linesize,
393  }
394 
395  return 0;
396  }
397 
398  av_log(ctx, AV_LOG_DEBUG, "Encoding string '%s'\n", qr->expanded_text.str);
399  qrcode = QRcode_encodeString(qr->expanded_text.str, 1, qr->level, QR_MODE_8,
400  qr->case_sensitive);
401  if (!qrcode) {
402  ret = AVERROR(errno);
404  "Failed to encode string with error \'%s\'\n", av_err2str(ret));
405  goto end;
406  }
407 
409  "Encoded QR with width:%d version:%d\n", qrcode->width, qrcode->version);
410 #ifdef DEBUG
411  show_qrcode(ctx, (const QRcode *)qrcode);
412 #endif
413 
414  qrcode_width_changed = qr->qrcode_width != qrcode->width;
415  qr->qrcode_width = qrcode->width;
416 
417  // realloc mask if needed
418  if (qrcode_width_changed) {
419  av_freep(&qr->qrcode_mask_data[0]);
421  qrcode->width, qrcode->width,
422  AV_PIX_FMT_GRAY8, 16);
423  if (ret < 0) {
425  "Failed to allocate image for QR code with width %d\n", qrcode->width);
426  goto end;
427  }
428  }
429 
430  /* fill mask */
431  dstp0 = qr->qrcode_mask_data[0];
432  srcp = qrcode->data;
433 
434  for (i = 0; i < qrcode->width; i++) {
435  dstp = dstp0;
436  for (j = 0; j < qrcode->width; j++)
437  *dstp++ = (*srcp++ & 1) ? 255 : 0;
438  dstp0 += qr->qrcode_mask_linesize[0];
439  }
440 
441  if (qr->is_source) {
442  if (qrcode_width_changed) {
443  /* realloc padded image */
444 
445  // compute virtual non-rendered padded size
446  // Q/q = W/w
447  qr->padded_qrcode_width =
448  ((double)qr->rendered_padded_qrcode_width / qr->rendered_qrcode_width) * qrcode->width;
449 
450  av_freep(&qr->qrcode_data[0]);
453  AV_PIX_FMT_ARGB, 16);
454  if (ret < 0) {
456  "Failed to allocate image for QR code with width %d\n",
457  qr->padded_qrcode_width);
458  goto end;
459  }
460  }
461 
462  /* fill padding */
464  qr->qrcode_data, qr->qrcode_linesize,
466 
467  /* blend mask */
468  offset = (qr->padded_qrcode_width - qr->qrcode_width) / 2;
470  qr->qrcode_data, qr->qrcode_linesize,
472  qr->qrcode_mask_data[0], qr->qrcode_mask_linesize[0], qrcode->width, qrcode->width,
473  3, 0, offset, offset);
474 
475  /* scale padded QR over the frame */
476  sws = sws_alloc_context();
477  if (!sws) {
478  ret = AVERROR(ENOMEM);
479  goto end;
480  }
481 
482  av_opt_set_int(sws, "srcw", qr->padded_qrcode_width, 0);
483  av_opt_set_int(sws, "srch", qr->padded_qrcode_width, 0);
484  av_opt_set_int(sws, "src_format", AV_PIX_FMT_ARGB, 0);
485  av_opt_set_int(sws, "dstw", qr->rendered_padded_qrcode_width, 0);
486  av_opt_set_int(sws, "dsth", qr->rendered_padded_qrcode_width, 0);
487  av_opt_set_int(sws, "dst_format", frame->format, 0);
488  av_opt_set_int(sws, "sws_flags", SWS_POINT, 0);
489 
490  if ((ret = sws_init_context(sws, NULL, NULL)) < 0)
491  goto end;
492 
493  sws_scale(sws,
494  (const uint8_t *const *)&qr->qrcode_data, qr->qrcode_linesize,
495  0, qr->padded_qrcode_width,
496  frame->data, frame->linesize);
497  } else {
498 #define EVAL_EXPR(name_) \
499  av_expr_eval(qr->name_##_pexpr, qr->var_values, &qr->lfg);
500 
501  V(qr_w) = V(w) = qrcode->width;
502 
503  V(rendered_qr_w) = V(q) = EVAL_EXPR(rendered_qrcode_width);
504  V(rendered_padded_qr_w) = V(Q) = EVAL_EXPR(rendered_padded_qrcode_width);
505  /* It is necessary if q is expressed from Q */
506  V(rendered_qr_w) = V(q) = EVAL_EXPR(rendered_qrcode_width);
507 
508  V(x) = EVAL_EXPR(x);
509  V(y) = EVAL_EXPR(y);
510  /* It is necessary if x is expressed from y */
511  V(x) = EVAL_EXPR(x);
512 
514  "Rendering QR code with values n:%d w:%d q:%d Q:%d x:%d y:%d t:%f\n",
515  (int)V(n), (int)V(w), (int)V(q), (int)V(Q), (int)V(x), (int)V(y), V(t));
516 
517  /* blend rectangle over the target */
519  frame->data, frame->linesize, frame->width, frame->height,
520  V(x), V(y), V(Q), V(Q));
521 
522  if (V(q) != qr->rendered_qrcode_width) {
524  qr->rendered_qrcode_width = V(q);
525 
528  AV_PIX_FMT_GRAY8, 16);
529  if (ret < 0) {
531  "Failed to allocate image for rendered QR code with width %d\n",
533  goto end;
534  }
535  }
536 
537  /* scale mask */
538  sws = sws_alloc_context();
539  if (!sws) {
540  ret = AVERROR(ENOMEM);
541  goto end;
542  }
543 
544  av_opt_set_int(sws, "srcw", qr->qrcode_width, 0);
545  av_opt_set_int(sws, "srch", qr->qrcode_width, 0);
546  av_opt_set_int(sws, "src_format", AV_PIX_FMT_GRAY8, 0);
547  av_opt_set_int(sws, "dstw", qr->rendered_qrcode_width, 0);
548  av_opt_set_int(sws, "dsth", qr->rendered_qrcode_width, 0);
549  av_opt_set_int(sws, "dst_format", AV_PIX_FMT_GRAY8, 0);
550  av_opt_set_int(sws, "sws_flags", SWS_POINT, 0);
551 
552  if ((ret = sws_init_context(sws, NULL, NULL)) < 0)
553  goto end;
554 
555  sws_scale(sws,
556  (const uint8_t *const *)&qr->qrcode_mask_data, qr->qrcode_mask_linesize,
557  0, qr->qrcode_width,
559 
560  /* blend mask over the input frame */
561  offset = (V(Q) - V(q)) / 2;
563  frame->data, frame->linesize, frame->width, frame->height,
566  3, 0, V(x) + offset, V(y) + offset);
567  }
568 
569 end:
570  sws_freeContext(sws);
571  QRcode_free(qrcode);
572 
573  return ret;
574 }
575 
576 #if CONFIG_QRENCODESRC_FILTER
577 
578 static const AVOption qrencodesrc_options[] = {
580  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
581  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
582  { NULL }
583 };
584 
585 AVFILTER_DEFINE_CLASS(qrencodesrc);
586 
588 {
589  FilterLink *l = ff_filter_link(outlink);
590  AVFilterContext *ctx = outlink->src;
591  QREncodeContext *qr = ctx->priv;
592  int ret;
593 
594  qr->is_source = 1;
595  V(x) = V(y) = 0;
596 
597 #define PARSE_AND_EVAL_EXPR(var_name_, expr_name_) \
598  ret = av_expr_parse_and_eval(&qr->var_values[VAR_##var_name_], \
599  qr->expr_name_##_expr, \
600  var_names, qr->var_values, \
601  NULL, NULL, \
602  fun2_names, fun2, \
603  &qr->lfg, 0, ctx); \
604  if (ret < 0) { \
605  av_log(ctx, AV_LOG_ERROR, \
606  "Could not evaluate expression '%s'\n", \
607  qr->expr_name_##_expr); \
608  return ret; \
609  }
610 
611  /* undefined for the source */
612  V(main_w) = V(W) = NAN;
613  V(main_h) = V(H) = NAN;
614  V(x) = V(y) = V(t) = V(n) = NAN;
615  V(dar) = V(sar) = 1.0;
616 
617  PARSE_AND_EVAL_EXPR(rendered_qr_w, rendered_qrcode_width);
618  V(q) = V(rendered_qr_w);
619  PARSE_AND_EVAL_EXPR(rendered_padded_qr_w, rendered_padded_qrcode_width);
620  V(Q) = V(rendered_padded_qr_w);
621  PARSE_AND_EVAL_EXPR(rendered_qr_w, rendered_qrcode_width);
622  V(q) = V(rendered_qr_w);
623 
624  qr->rendered_qrcode_width = V(rendered_qr_w);
625  qr->rendered_padded_qrcode_width = V(rendered_padded_qr_w);
626 
628  "q:%d Q:%d case_sensitive:%d level:%d\n",
630  qr->case_sensitive, qr->level);
631 
634  "Resulting padded QR code width (%d) is lesser than the QR code width (%d)\n",
636  return AVERROR(EINVAL);
637  }
638 
640  ff_draw_color(&qr->draw, &qr->draw_foreground_color, (const uint8_t *)&qr->foreground_color);
641  ff_draw_color(&qr->draw, &qr->draw_background_color, (const uint8_t *)&qr->background_color);
642 
643  ff_draw_init2(&qr->draw0, outlink->format, outlink->colorspace, outlink->color_range, FF_DRAW_PROCESS_ALPHA);
644  ff_draw_color(&qr->draw0, &qr->draw0_background_color, (const uint8_t *)&qr->background_color);
645 
646  outlink->w = qr->rendered_padded_qrcode_width;
647  outlink->h = qr->rendered_padded_qrcode_width;
648  outlink->time_base = av_inv_q(qr->frame_rate);
649  l->frame_rate = qr->frame_rate;
650 
651  return 0;
652 }
653 
654 static int request_frame(AVFilterLink *outlink)
655 {
656  AVFilterContext *ctx = (AVFilterContext *)outlink->src;
657  QREncodeContext *qr = ctx->priv;
658  AVFrame *frame =
659  ff_get_video_buffer(outlink, qr->rendered_padded_qrcode_width, qr->rendered_padded_qrcode_width);
660  int ret;
661 
662  if (!frame)
663  return AVERROR(ENOMEM);
664  frame->sample_aspect_ratio = (AVRational) {1, 1};
665  V(n) = frame->pts = qr->pts++;
666  V(t) = qr->pts * av_q2d(outlink->time_base);
667 
668  if ((ret = draw_qrcode(ctx, frame)) < 0)
669  return ret;
670 
671  return ff_filter_frame(outlink, frame);
672 }
673 
675  AVFilterFormatsConfig **cfg_in,
676  AVFilterFormatsConfig **cfg_out)
677 {
678  enum AVPixelFormat pix_fmt;
680  AVFilterFormats *fmts = NULL;
681  int ret;
682 
683  // this is needed to support both the no-draw and draw cases
684  // for the no-draw case we use FFDrawContext to write on the input picture ref
686  if (ff_draw_init(&draw, pix_fmt, 0) >= 0 &&
688  (ret = ff_add_format(&fmts, pix_fmt)) < 0)
689  return ret;
690 
691  return ff_set_common_formats2(ctx, cfg_in, cfg_out, fmts);
692 }
693 
695  {
696  .name = "default",
697  .type = AVMEDIA_TYPE_VIDEO,
698  .request_frame = request_frame,
699  .config_props = qrencodesrc_config_props,
700  }
701 };
702 
704  .name = "qrencodesrc",
705  .description = NULL_IF_CONFIG_SMALL("Generate a QR code."),
706  .priv_size = sizeof(QREncodeContext),
707  .priv_class = &qrencodesrc_class,
708  .init = init,
709  .uninit = uninit,
710  .inputs = NULL,
713 };
714 
715 #endif // CONFIG_QRENCODESRC_FILTER
716 
717 #if CONFIG_QRENCODE_FILTER
718 
719 static const AVOption qrencode_options[] = {
721  {"x", "set x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},
722  {"y", "set y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},
723  { NULL }
724 };
725 
726 AVFILTER_DEFINE_CLASS(qrencode);
727 
729 {
730  AVFilterContext *ctx = inlink->dst;
731  QREncodeContext *qr = ctx->priv;
732  char *expr;
733  int ret;
734 
735  qr->is_source = 0;
736 
737  ff_draw_init2(&qr->draw, inlink->format, inlink->colorspace, inlink->color_range,
739 
740  V(W) = V(main_w) = inlink->w;
741  V(H) = V(main_h) = inlink->h;
742  V(sar) = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
743  V(dar) = (double)inlink->w / inlink->h * V(sar);
744  V(hsub) = 1 << qr->draw.hsub_max;
745  V(vsub) = 1 << qr->draw.vsub_max;
746  V(t) = NAN;
747  V(x) = V(y) = NAN;
748 
749  qr->x_pexpr = qr->y_pexpr = NULL;
750  qr->x_pexpr = qr->y_pexpr = NULL;
751 
752 #define PARSE_EXPR(name_) \
753  ret = av_expr_parse(&qr->name_##_pexpr, expr = qr->name_##_expr, var_names, \
754  NULL, NULL, fun2_names, fun2, 0, ctx); \
755  if (ret < 0) { \
756  av_log(ctx, AV_LOG_ERROR, \
757  "Could not to parse expression '%s' for '%s'\n", \
758  expr, #name_); \
759  return AVERROR(EINVAL); \
760  }
761 
762  PARSE_EXPR(x);
763  PARSE_EXPR(y);
764  PARSE_EXPR(rendered_qrcode_width);
765  PARSE_EXPR(rendered_padded_qrcode_width);
766 
767  ff_draw_init2(&qr->draw, inlink->format, inlink->colorspace, inlink->color_range,
769  ff_draw_color(&qr->draw, &qr->draw_foreground_color, (const uint8_t *)&qr->foreground_color);
770  ff_draw_color(&qr->draw, &qr->draw_background_color, (const uint8_t *)&qr->background_color);
771 
772  qr->rendered_qrcode_width = -1;
773 
774  return 0;
775 }
776 
778  AVFilterFormatsConfig **cfg_in,
779  AVFilterFormatsConfig **cfg_out)
780 {
781  return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_draw_supported_pixel_formats(0));
782 }
783 
785 {
787  AVFilterContext *ctx = inlink->dst;
788  AVFilterLink *outlink = ctx->outputs[0];
789  QREncodeContext *qr = ctx->priv;
790  int ret;
791 
792  V(n) = inl->frame_count_out;
793  V(t) = frame->pts == AV_NOPTS_VALUE ?
794  NAN : frame->pts * av_q2d(inlink->time_base);
795  V(pict_type) = frame->pict_type;
796  V(duration) = frame->duration * av_q2d(inlink->time_base);
797 
798  qr->metadata = frame->metadata;
799 
800  if ((ret = draw_qrcode(ctx, frame)) < 0)
801  return ret;
802 
803  return ff_filter_frame(outlink, frame);
804 }
805 
807  {
808  .name = "default",
809  .type = AVMEDIA_TYPE_VIDEO,
811  .filter_frame = filter_frame,
812  .config_props = qrencode_config_input,
813  },
814 };
815 
817  .name = "qrencode",
818  .description = NULL_IF_CONFIG_SMALL("Draw a QR code on top of video frames."),
819  .priv_size = sizeof(QREncodeContext),
820  .priv_class = &qrencode_class,
821  .init = init,
822  .uninit = uninit,
827 };
828 
829 #endif // CONFIG_QRENCODE_FILTER
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:116
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
QREncodeContext::foreground_color
uint8_t foreground_color[4]
Definition: qrencode.c:116
FFDrawColor
Definition: drawutils.h:51
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
W
@ W
Definition: vf_addroi.c:27
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
var_name
var_name
Definition: noise.c:47
func_eval_expr_formatted
static int func_eval_expr_formatted(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:258
VAR_VARS_NB
@ VAR_VARS_NB
Definition: qrencode.c:66
sws_isSupportedOutput
#define sws_isSupportedOutput(x)
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1062
qrencode_config_input
static int qrencode_config_input(AVFilterLink *inlink)
Definition: qrencode.c:728
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3170
AV_OPT_TYPE_VIDEO_RATE
@ AV_OPT_TYPE_VIDEO_RATE
Underlying C type is AVRational.
Definition: opt.h:315
VAR_x
@ VAR_x
Definition: qrencode.c:64
ff_set_common_formats2
int ff_set_common_formats2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, AVFilterFormats *formats)
Definition: formats.c:1007
qrencodesrc_outputs
static const AVFilterPad qrencodesrc_outputs[]
Definition: qrencode.c:694
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
sws_freeContext
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2446
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
FFDrawContext::hsub_max
uint8_t hsub_max
Definition: drawutils.h:43
QREncodeContext::qrcode_data
uint8_t * qrcode_data[4]
Definition: qrencode.c:127
w
uint8_t w
Definition: llviddspenc.c:38
QREncodeContext
Definition: qrencode.c:94
QREncodeContext::draw_background_color
FFDrawColor draw_background_color
background color
Definition: qrencode.c:121
QREncodeContext::rendered_padded_qrcode_width_pexpr
AVExpr * rendered_padded_qrcode_width_pexpr
Definition: qrencode.c:104
QREncodeContext::background_color
uint8_t background_color[4]
Definition: qrencode.c:117
AVOption
AVOption.
Definition: opt.h:429
QREncodeContext::draw_foreground_color
FFDrawColor draw_foreground_color
foreground color
Definition: qrencode.c:120
QREncodeContext::var_values
double var_values[VAR_VARS_NB]
Definition: qrencode.c:145
VAR_hsub
@ VAR_hsub
Definition: qrencode.c:54
FLAGS
#define FLAGS
Definition: cmdutils.c:595
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
VAR_sar
@ VAR_sar
Definition: qrencode.c:62
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVDictionary
Definition: dict.c:34
func_pts
static int func_pts(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:195
VAR_n
@ VAR_n
Definition: qrencode.c:57
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
video.h
EXPANSION_NORMAL
@ EXPANSION_NORMAL
Definition: qrencode.c:91
QREncodeContext::padded_qrcode_width
int padded_qrcode_width
Definition: qrencode.c:137
VAR_duration
@ VAR_duration
Definition: qrencode.c:53
drand
static double drand(void *opaque, double min, double max)
Definition: qrencode.c:185
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
av_get_random_seed
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:167
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
draw_qrcode
static int draw_qrcode(AVFilterContext *ctx, AVFrame *frame)
Definition: qrencode.c:364
FFDrawContext::vsub_max
uint8_t vsub_max
Definition: drawutils.h:44
QREncodeContext::rendered_qrcode_data
uint8_t * rendered_qrcode_data[4]
Definition: qrencode.c:133
expand_text_functions
static const FFExpandTextFunction expand_text_functions[]
Definition: qrencode.c:287
QREncodeContext::draw
FFDrawContext draw
Definition: qrencode.c:119
positions
const static uint16_t positions[][14][3]
Definition: vf_vectorscope.c:817
QREncodeContext::is_source
char is_source
Definition: qrencode.c:97
QREncodeContext::draw0
FFDrawContext draw0
Definition: qrencode.c:124
PARSE_EXPR
#define PARSE_EXPR(e, s)
QREncodeContext::rendered_qrcode_linesize
int rendered_qrcode_linesize[4]
Definition: qrencode.c:134
sws_init_context
av_warn_unused_result int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:2081
FFExpandTextContext::log_ctx
void * log_ctx
log context to pass to the function, used for logging and for accessing the context for the function
Definition: textutils.h:71
ff_expand_text
int ff_expand_text(FFExpandTextContext *expand_text, const char *text, AVBPrint *bp)
Expand text template.
Definition: textutils.c:123
ff_blend_mask
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, int l2depth, unsigned endianness, int x0, int y0)
Blend an alpha mask with an uniform color.
Definition: drawutils.c:549
FFExpandTextFunction
Function used to expand a template sequence in the format %{FUNCTION_NAME[:PARAMS]},...
Definition: textutils.h:36
SWS_POINT
#define SWS_POINT
Definition: swscale.h:154
QREncodeContext::draw0_background_color
FFDrawColor draw0_background_color
background color
Definition: qrencode.c:125
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:358
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
QREncodeContext::frame_rate
AVRational frame_rate
Definition: qrencode.c:139
QREncodeContext::case_sensitive
char case_sensitive
Definition: qrencode.c:114
VAR_q
@ VAR_q
Definition: qrencode.c:61
SwsContext
struct SwsContext SwsContext
Definition: swscale.h:45
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
ff_load_textfile
int ff_load_textfile(void *log_ctx, const char *textfile, unsigned char **text, size_t *text_size)
Definition: textutils.c:353
QREncodeContext::lfg
AVLFG lfg
random generator
Definition: qrencode.c:146
ff_video_default_filterpad
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
duration
int64_t duration
Definition: movenc.c:65
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
QREncodeContext::qrcode_width
int qrcode_width
Definition: qrencode.c:136
VAR_w
@ VAR_w
Definition: qrencode.c:59
COMMON_OPTIONS
#define COMMON_OPTIONS
Definition: libvpxenc.c:1900
QREncodeContext::pts
uint64_t pts
Definition: qrencode.c:111
ff_vsrc_qrencodesrc
const AVFilter ff_vsrc_qrencodesrc
Definition: qrencode.c:703
av_lfg_get
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:53
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: qrencode.c:654
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
lfg.h
FF_DRAW_PROCESS_ALPHA
#define FF_DRAW_PROCESS_ALPHA
Process alpha pixel component.
Definition: drawutils.h:63
QREncodeContext::x_expr
char * x_expr
Definition: qrencode.c:98
filters.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AVExpr
Definition: eval.c:158
func_frame_num
static int func_frame_num(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:217
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Definition: drawutils.c:166
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
NAN
#define NAN
Definition: mathematics.h:115
VAR_qr_w
@ VAR_qr_w
Definition: qrencode.c:59
QREncodeContext::expansion
int expansion
expansion mode to use for the text
Definition: qrencode.c:141
VAR_y
@ VAR_y
Definition: qrencode.c:65
VAR_W
@ VAR_W
Definition: qrencode.c:56
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
QREncodeContext::rendered_padded_qrcode_width_expr
char * rendered_padded_qrcode_width_expr
Definition: qrencode.c:103
ff_print_formatted_eval_expr
int ff_print_formatted_eval_expr(void *log_ctx, AVBPrint *bp, const char *expr, const char *const *fun_names, const ff_eval_func2 *fun_values, const char *const *var_names, const double *var_values, void *eval_ctx, const char format, int positions)
Definition: textutils.c:303
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
V
#define V
Definition: avdct.c:31
ff_add_format
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:504
QREncodeContext::rendered_padded_qrcode_width
int rendered_padded_qrcode_width
Definition: qrencode.c:107
textutils.h
QREncodeContext::rendered_qrcode_width_expr
char * rendered_qrcode_width_expr
Definition: qrencode.c:102
avfilter_vf_qrencode_inputs
static const AVFilterPad avfilter_vf_qrencode_inputs[]
Definition: qrencode.c:806
double
double
Definition: af_crystalizer.c:132
VAR_rendered_qr_w
@ VAR_rendered_qr_w
Definition: qrencode.c:61
init
static av_cold int init(AVFilterContext *ctx)
Definition: qrencode.c:300
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: qrencode.c:331
VAR_Q
@ VAR_Q
Definition: qrencode.c:60
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:111
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:872
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
VAR_t
@ VAR_t
Definition: qrencode.c:63
qrencodesrc_config_props
static int qrencodesrc_config_props(AVFilterLink *outlink)
Definition: qrencode.c:587
av_image_alloc
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align)
Allocate an image with size w and h and pixel format pix_fmt, and fill pointers and linesizes accordi...
Definition: imgutils.c:218
AVFILTERPAD_FLAG_NEEDS_WRITABLE
#define AVFILTERPAD_FLAG_NEEDS_WRITABLE
The filter expects writable frames from its input link, duplicating data buffers if needed.
Definition: filters.h:57
TFLAGS
#define TFLAGS
Definition: af_afade.c:64
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
QREncodeContext::rendered_qrcode_width
int rendered_qrcode_width
Definition: qrencode.c:106
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext.
Definition: utils.c:1227
ff_blend_rectangle
void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, int x0, int y0, int w, int h)
Blend a rectangle with an uniform color.
Definition: drawutils.c:368
QREncodeContext::qrcode_mask_linesize
int qrcode_mask_linesize[4]
Definition: qrencode.c:130
ff_print_eval_expr
int ff_print_eval_expr(void *log_ctx, AVBPrint *bp, const char *expr, const char *const *fun_names, const ff_eval_func2 *fun_values, const char *const *var_names, const double *var_values, void *eval_ctx)
Definition: textutils.c:281
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
ff_draw_init2
int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, enum AVColorRange range, unsigned flags)
Init a draw context.
Definition: drawutils.c:95
VAR_pict_type
@ VAR_pict_type
Definition: qrencode.c:58
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
EXPANSION_NONE
@ EXPANSION_NONE
Definition: qrencode.c:90
ff_fill_rectangle
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:246
fun2_names
static const char *const fun2_names[]
Definition: qrencode.c:181
QREncodeContext::qrcode_mask_data
uint8_t * qrcode_mask_data[4]
Definition: qrencode.c:129
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(qrencodesrc)
H
#define H
Definition: pixlet.c:39
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: qrencode.c:784
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
line
Definition: graph2dot.c:48
qrencode_options
static const AVOption qrencode_options[]
Definition: qrencode.c:719
draw
static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: avf_showcwt.c:440
VAR_H
@ VAR_H
Definition: qrencode.c:55
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#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:182
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
ff_print_pts
int ff_print_pts(void *log_ctx, AVBPrint *bp, double pts, const char *delta, const char *fmt, const char *strftime_fmt)
Definition: textutils.c:149
VAR_main_w
@ VAR_main_w
Definition: qrencode.c:56
QREncodeContext::level
int level
Definition: qrencode.c:113
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
internal.h
ff_draw_supported_pixel_formats
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:662
delta
float delta
Definition: vorbis_enc_data.h:430
VAR_dar
@ VAR_dar
Definition: qrencode.c:52
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
VAR_main_h
@ VAR_main_h
Definition: qrencode.c:55
VAR_vsub
@ VAR_vsub
Definition: qrencode.c:54
FFDrawContext
Definition: drawutils.h:36
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:171
AVFilter
Filter definition.
Definition: avfilter.h:201
ret
ret
Definition: filter_design.txt:187
var_names
static const char *const var_names[]
Definition: qrencode.c:69
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
ff_vf_qrencode
const AVFilter ff_vf_qrencode
Definition: qrencode.c:816
QREncodeContext::textfile
char * textfile
Definition: qrencode.c:110
QREncodeContext::metadata
AVDictionary * metadata
Definition: qrencode.c:147
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
OFFSET
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option keep it simple and lowercase description are in without and describe what they for example set the foo of the bar offset is the offset of the field in your see the OFFSET() macro
random_seed.h
qrencodesrc_options
static const AVOption qrencodesrc_options[]
Definition: qrencode.c:578
qrencodesrc_query_formats
static int qrencodesrc_query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: qrencode.c:674
sws_scale
int attribute_align_arg sws_scale(SwsContext *sws, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
Definition: swscale.c:1246
avfilter.h
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:232
FFExpandTextContext
in a text template, followed by any character, always expands to the second character.
Definition: textutils.h:66
QREncodeContext::expand_text
FFExpandTextContext expand_text
expand text in case expansion is enabled
Definition: qrencode.c:142
show_qrcode
static void show_qrcode(AVFilterContext *ctx, const QRcode *qrcode)
Definition: qrencode.c:346
fun2
static const ff_eval_func2 fun2[]
Definition: qrencode.c:190
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
func_frame_metadata
static int func_frame_metadata(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:234
mem.h
func_eval_expr
static int func_eval_expr(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:248
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
QREncodeContext::qrcode_linesize
int qrcode_linesize[4]
Definition: qrencode.c:128
QREncodeContext::x_pexpr
AVExpr * x_pexpr
Definition: qrencode.c:100
func_strftime
static int func_strftime(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:226
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
QREncodeContext::y_pexpr
AVExpr * y_pexpr
Definition: qrencode.c:100
Q
#define Q(x)
Definition: filter_template.c:423
imgutils.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VAR_rendered_padded_qr_w
@ VAR_rendered_padded_qr_w
Definition: qrencode.c:60
QREncodeContext::expanded_text
AVBPrint expanded_text
used to contain the expanded text
Definition: qrencode.c:143
AVDictionaryEntry::value
char * value
Definition: dict.h:91
AV_OPT_TYPE_STRING
@ 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:276
drawutils.h
qrencode_query_formats
static int qrencode_query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: qrencode.c:777
ff_print_time
int ff_print_time(void *log_ctx, AVBPrint *bp, const char *strftime_fmt, char localtime)
Definition: textutils.c:202
swscale.h
QREncodeContext::rendered_qrcode_width_pexpr
AVExpr * rendered_qrcode_width_pexpr
Definition: qrencode.c:104
QREncodeContext::y_expr
char * y_expr
Definition: qrencode.c:99
Expansion
Expansion
Definition: qrencode.c:89
min
float min
Definition: vorbis_enc_data.h:429
QREncodeContext::text
unsigned char * text
Definition: qrencode.c:109