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/opt.h"
37 #include "libavutil/lfg.h"
38 #include "libavutil/random_seed.h"
39 
40 #include "avfilter.h"
41 #include "drawutils.h"
42 #include "internal.h"
43 #include "formats.h"
44 #include "textutils.h"
45 #include "video.h"
46 #include "libswscale/swscale.h"
47 
48 #include <qrencode.h>
49 
50 enum var_name {
66 };
67 
68 static const char *const var_names[] = {
69  "dar",
70  "duration",
71  "hsub", "vsub",
72  "main_h", "H", ///< height of the input video
73  "main_w", "W", ///< width of the input video
74  "n", ///< number of frame
75  "pict_type",
76  "qr_w", "w", ///< width of the QR code
77  "rendered_padded_qr_w", "Q", ///< width of the rendered QR code
78  "rendered_qr_w", "q", ///< width of the rendered QR code
79  "sar",
80  "t", ///< timestamp expressed in seconds
81  "x",
82  "y",
83  NULL
84 };
85 
86 #define V(name_) qr->var_values[VAR_##name_]
87 
88 enum Expansion {
91 };
92 
93 typedef struct QREncodeContext {
94  const AVClass *class;
95 
96  char is_source;
97  char *x_expr;
98  char *y_expr;
100 
104 
107 
108  unsigned char *text;
109  char *textfile;
110  uint64_t pts;
111 
112  int level;
114 
115  uint8_t foreground_color[4];
116  uint8_t background_color[4];
117 
119  FFDrawColor draw_foreground_color; ///< foreground color
120  FFDrawColor draw_background_color; ///< background color
121 
122  /* these are only used when nothing must be encoded */
124  FFDrawColor draw0_background_color; ///< background color
125 
126  uint8_t *qrcode_data[4];
128  uint8_t *qrcode_mask_data[4];
130 
131  /* only used for filter to contain scaled image to blend on top of input */
132  uint8_t *rendered_qrcode_data[4];
134 
137 
139 
140  int expansion; ///< expansion mode to use for the text
141  FFExpandTextContext expand_text; ///< expand text in case expansion is enabled
142  AVBPrint expanded_text; ///< used to contain the expanded text
143 
145  AVLFG lfg; ///< random generator
148 
149 #define OFFSET(x) offsetof(QREncodeContext, x)
150 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
151 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
152 
153 #define COMMON_OPTIONS \
154  { "qrcode_width", "set rendered QR code width expression", OFFSET(rendered_qrcode_width_expr), AV_OPT_TYPE_STRING, {.str = "64"}, 0, INT_MAX, FLAGS }, \
155  { "q", "set rendered QR code width expression", OFFSET(rendered_qrcode_width_expr), AV_OPT_TYPE_STRING, {.str = "64"}, 0, INT_MAX, FLAGS }, \
156  { "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 }, \
157  { "Q", "set rendered padded QR code width expression", OFFSET(rendered_padded_qrcode_width_expr), AV_OPT_TYPE_STRING, {.str = "q"}, 0, INT_MAX, FLAGS }, \
158  { "case_sensitive", "generate code which is case sensitive", OFFSET(case_sensitive), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS }, \
159  { "cs", "generate code which is case sensitive", OFFSET(case_sensitive), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS }, \
160  \
161  { "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"}, \
162  { "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"}, \
163  { "L", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_L }, 0, 0, FLAGS, .unit = "level" }, \
164  { "M", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_M }, 0, 0, FLAGS, .unit = "level" }, \
165  { "Q", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_Q }, 0, 0, FLAGS, .unit = "level" }, \
166  { "H", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QR_ECLEVEL_H }, 0, 0, FLAGS, .unit = "level" }, \
167  \
168  {"expansion", "set the expansion mode", OFFSET(expansion), AV_OPT_TYPE_INT, {.i64=EXPANSION_NORMAL}, 0, 2, FLAGS, .unit = "expansion"}, \
169  {"none", "set no expansion", OFFSET(expansion), AV_OPT_TYPE_CONST, {.i64 = EXPANSION_NONE}, 0, 0, FLAGS, .unit = "expansion"}, \
170  {"normal", "set normal expansion", OFFSET(expansion), AV_OPT_TYPE_CONST, {.i64 = EXPANSION_NORMAL}, 0, 0, FLAGS, .unit = "expansion"}, \
171  \
172  { "foreground_color", "set QR foreground color", OFFSET(foreground_color), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGS }, \
173  { "fc", "set QR foreground color", OFFSET(foreground_color), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, FLAGS }, \
174  { "background_color", "set QR background color", OFFSET(background_color), AV_OPT_TYPE_COLOR, {.str = "white"}, 0, 0, FLAGS }, \
175  { "bc", "set QR background color", OFFSET(background_color), AV_OPT_TYPE_COLOR, {.str = "white"}, 0, 0, FLAGS }, \
176  \
177  {"text", "set text to encode", OFFSET(text), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS}, \
178  {"textfile", "set text file to encode", OFFSET(textfile), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS}, \
179 
180 static const char *const fun2_names[] = {
181  "rand"
182 };
183 
184 static double drand(void *opaque, double min, double max)
185 {
186  return min + (max-min) / UINT_MAX * av_lfg_get(opaque);
187 }
188 
189 static const ff_eval_func2 fun2[] = {
190  drand,
191  NULL
192 };
193 
194 static int func_pts(void *ctx, AVBPrint *bp, const char *function_name,
195  unsigned argc, char **argv)
196 {
197  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
198  const char *fmt;
199  const char *strftime_fmt = NULL;
200  const char *delta = NULL;
201  double t = qr->var_values[VAR_t];
202 
203  // argv: pts, FMT, [DELTA, strftime_fmt]
204 
205  fmt = argc >= 1 ? argv[0] : "flt";
206  if (argc >= 2) {
207  delta = argv[1];
208  }
209  if (argc >= 3) {
210  strftime_fmt = argv[2];
211  }
212 
213  return ff_print_pts(ctx, bp, t, delta, fmt, strftime_fmt);
214 }
215 
216 static int func_frame_num(void *ctx, AVBPrint *bp, const char *function_name,
217  unsigned argc, char **argv)
218 {
219  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
220 
221  av_bprintf(bp, "%d", (int)V(n));
222  return 0;
223 }
224 
225 static int func_strftime(void *ctx, AVBPrint *bp, const char *function_name,
226  unsigned argc, char **argv)
227 {
228  const char *strftime_fmt = argc ? argv[0] : NULL;
229 
230  return ff_print_time(ctx, bp, strftime_fmt, !strcmp(function_name, "localtime"));
231 }
232 
233 static int func_frame_metadata(void *ctx, AVBPrint *bp, const char *function_name,
234  unsigned argc, char **argv)
235 {
236  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
237  AVDictionaryEntry *e = av_dict_get(qr->metadata, argv[0], NULL, 0);
238 
239  if (e && e->value)
240  av_bprintf(bp, "%s", e->value);
241  else if (argc >= 2)
242  av_bprintf(bp, "%s", argv[1]);
243 
244  return 0;
245 }
246 
247 static int func_eval_expr(void *ctx, AVBPrint *bp, const char *function_name,
248  unsigned argc, char **argv)
249 {
250  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
251 
252  return ff_print_eval_expr(ctx, bp, argv[0],
253  fun2_names, fun2,
254  var_names, qr->var_values, &qr->lfg);
255 }
256 
257 static int func_eval_expr_formatted(void *ctx, AVBPrint *bp, const char *function_name,
258  unsigned argc, char **argv)
259 {
260  QREncodeContext *qr = ((AVFilterContext *)ctx)->priv;
261  int ret;
262  int positions = -1;
263 
264  /*
265  * argv[0] expression to be converted to `int`
266  * argv[1] format: 'x', 'X', 'd' or 'u'
267  * argv[2] positions printed (optional)
268  */
269 
270  if (argc == 3) {
271  ret = sscanf(argv[2], "%u", &positions);
272  if (ret != 1) {
273  av_log(ctx, AV_LOG_ERROR, "expr_int_format(): Invalid number of positions"
274  " to print: '%s'\n", argv[2]);
275  return AVERROR(EINVAL);
276  }
277  }
278 
279  return ff_print_formatted_eval_expr(ctx, bp, argv[0],
280  fun2_names, fun2,
281  var_names, qr->var_values,
282  &qr->lfg,
283  argv[1][0], positions);
284 }
285 
287  { "expr", 1, 1, func_eval_expr },
288  { "e", 1, 1, func_eval_expr },
289  { "expr_formatted", 2, 3, func_eval_expr_formatted },
290  { "ef", 2, 3, func_eval_expr_formatted },
291  { "metadata", 1, 2, func_frame_metadata },
292  { "frame_num", 0, 0, func_frame_num },
293  { "n", 0, 0, func_frame_num },
294  { "gmtime", 0, 1, func_strftime },
295  { "localtime", 0, 1, func_strftime },
296  { "pts", 0, 3, func_pts }
297 };
298 
300 {
301  QREncodeContext *qr = ctx->priv;
302  int ret;
303 
305 
306  qr->qrcode_width = -1;
308 
309  if (qr->textfile) {
310  if (qr->text) {
312  "Both text and text file provided. Please provide only one\n");
313  return AVERROR(EINVAL);
314  }
315  if ((ret = ff_load_textfile(ctx, (const char *)qr->textfile, &(qr->text), NULL)) < 0)
316  return ret;
317  }
318 
320  .log_ctx = ctx,
321  .functions = expand_text_functions,
322  .functions_nb = FF_ARRAY_ELEMS(expand_text_functions)
323  };
324 
326 
327  return 0;
328 }
329 
331 {
332  QREncodeContext *qr = ctx->priv;
333 
334  av_expr_free(qr->x_pexpr);
335  av_expr_free(qr->y_pexpr);
336 
338 
339  av_freep(&qr->qrcode_data[0]);
341  av_freep(&qr->qrcode_mask_data[0]);
342 }
343 
344 #ifdef DEBUG
345 static void show_qrcode(AVFilterContext *ctx, const QRcode *qrcode)
346 {
347  int i, j;
348  char *line = av_malloc(qrcode->width + 1);
349  const char *p = qrcode->data;
350 
351  if (!line)
352  return;
353  for (i = 0; i < qrcode->width; i++) {
354  for (j = 0; j < qrcode->width; j++)
355  line[j] = (*p++)&1 ? '@' : ' ';
356  line[j] = 0;
357  av_log(ctx, AV_LOG_DEBUG, "%3d: %s\n", i, line);
358  }
359  av_free(line);
360 }
361 #endif
362 
364 {
365  QREncodeContext *qr = ctx->priv;
366  struct SwsContext *sws = NULL;
367  QRcode *qrcode = NULL;
368  int i, j;
369  char qrcode_width_changed;
370  int ret;
371  int offset;
372  uint8_t *srcp;
373  uint8_t *dstp0, *dstp;
374 
376 
377  switch (qr->expansion) {
378  case EXPANSION_NONE:
379  av_bprintf(&qr->expanded_text, "%s", qr->text);
380  break;
381  case EXPANSION_NORMAL:
382  if ((ret = ff_expand_text(&qr->expand_text, qr->text, &qr->expanded_text)) < 0)
383  return ret;
384  break;
385  }
386 
387  if (!qr->expanded_text.str || qr->expanded_text.str[0] == 0) {
388  if (qr->is_source) {
392  }
393 
394  return 0;
395  }
396 
397  av_log(ctx, AV_LOG_DEBUG, "Encoding string '%s'\n", qr->expanded_text.str);
398  qrcode = QRcode_encodeString(qr->expanded_text.str, 1, qr->level, QR_MODE_8,
399  qr->case_sensitive);
400  if (!qrcode) {
401  ret = AVERROR(errno);
403  "Failed to encode string with error \'%s\'\n", av_err2str(ret));
404  goto end;
405  }
406 
408  "Encoded QR with width:%d version:%d\n", qrcode->width, qrcode->version);
409 #ifdef DEBUG
410  show_qrcode(ctx, (const QRcode *)qrcode);
411 #endif
412 
413  qrcode_width_changed = qr->qrcode_width != qrcode->width;
414  qr->qrcode_width = qrcode->width;
415 
416  // realloc mask if needed
417  if (qrcode_width_changed) {
418  av_freep(&qr->qrcode_mask_data[0]);
420  qrcode->width, qrcode->width,
421  AV_PIX_FMT_GRAY8, 16);
422  if (ret < 0) {
424  "Failed to allocate image for QR code with width %d\n", qrcode->width);
425  goto end;
426  }
427  }
428 
429  /* fill mask */
430  dstp0 = qr->qrcode_mask_data[0];
431  srcp = qrcode->data;
432 
433  for (i = 0; i < qrcode->width; i++) {
434  dstp = dstp0;
435  for (j = 0; j < qrcode->width; j++)
436  *dstp++ = (*srcp++ & 1) ? 255 : 0;
437  dstp0 += qr->qrcode_mask_linesize[0];
438  }
439 
440  if (qr->is_source) {
441  if (qrcode_width_changed) {
442  /* realloc padded image */
443 
444  // compute virtual non-rendered padded size
445  // Q/q = W/w
446  qr->padded_qrcode_width =
447  ((double)qr->rendered_padded_qrcode_width / qr->rendered_qrcode_width) * qrcode->width;
448 
449  av_freep(&qr->qrcode_data[0]);
452  AV_PIX_FMT_ARGB, 16);
453  if (ret < 0) {
455  "Failed to allocate image for QR code with width %d\n",
456  qr->padded_qrcode_width);
457  goto end;
458  }
459  }
460 
461  /* fill padding */
463  qr->qrcode_data, qr->qrcode_linesize,
465 
466  /* blend mask */
467  offset = (qr->padded_qrcode_width - qr->qrcode_width) / 2;
469  qr->qrcode_data, qr->qrcode_linesize,
471  qr->qrcode_mask_data[0], qr->qrcode_mask_linesize[0], qrcode->width, qrcode->width,
472  3, 0, offset, offset);
473 
474  /* scale padded QR over the frame */
475  sws = sws_alloc_context();
476  if (!sws) {
477  ret = AVERROR(ENOMEM);
478  goto end;
479  }
480 
481  av_opt_set_int(sws, "srcw", qr->padded_qrcode_width, 0);
482  av_opt_set_int(sws, "srch", qr->padded_qrcode_width, 0);
483  av_opt_set_int(sws, "src_format", AV_PIX_FMT_ARGB, 0);
484  av_opt_set_int(sws, "dstw", qr->rendered_padded_qrcode_width, 0);
485  av_opt_set_int(sws, "dsth", qr->rendered_padded_qrcode_width, 0);
486  av_opt_set_int(sws, "dst_format", frame->format, 0);
487  av_opt_set_int(sws, "sws_flags", SWS_POINT, 0);
488 
489  if ((ret = sws_init_context(sws, NULL, NULL)) < 0)
490  goto end;
491 
492  sws_scale(sws,
493  (const uint8_t *const *)&qr->qrcode_data, qr->qrcode_linesize,
494  0, qr->padded_qrcode_width,
495  frame->data, frame->linesize);
496  } else {
497 #define EVAL_EXPR(name_) \
498  av_expr_eval(qr->name_##_pexpr, qr->var_values, &qr->lfg);
499 
500  V(qr_w) = V(w) = qrcode->width;
501 
502  V(rendered_qr_w) = V(q) = EVAL_EXPR(rendered_qrcode_width);
503  V(rendered_padded_qr_w) = V(Q) = EVAL_EXPR(rendered_padded_qrcode_width);
504  /* It is necessary if q is expressed from Q */
505  V(rendered_qr_w) = V(q) = EVAL_EXPR(rendered_qrcode_width);
506 
507  V(x) = EVAL_EXPR(x);
508  V(y) = EVAL_EXPR(y);
509  /* It is necessary if x is expressed from y */
510  V(x) = EVAL_EXPR(x);
511 
513  "Rendering QR code with values n:%d w:%d q:%d Q:%d x:%d y:%d t:%f\n",
514  (int)V(n), (int)V(w), (int)V(q), (int)V(Q), (int)V(x), (int)V(y), V(t));
515 
516  /* blend rectangle over the target */
519  V(x), V(y), V(Q), V(Q));
520 
521  if (V(q) != qr->rendered_qrcode_width) {
523  qr->rendered_qrcode_width = V(q);
524 
527  AV_PIX_FMT_GRAY8, 16);
528  if (ret < 0) {
530  "Failed to allocate image for rendered QR code with width %d\n",
532  goto end;
533  }
534  }
535 
536  /* scale mask */
537  sws = sws_alloc_context();
538  if (!sws) {
539  ret = AVERROR(ENOMEM);
540  goto end;
541  }
542 
543  av_opt_set_int(sws, "srcw", qr->qrcode_width, 0);
544  av_opt_set_int(sws, "srch", qr->qrcode_width, 0);
545  av_opt_set_int(sws, "src_format", AV_PIX_FMT_GRAY8, 0);
546  av_opt_set_int(sws, "dstw", qr->rendered_qrcode_width, 0);
547  av_opt_set_int(sws, "dsth", qr->rendered_qrcode_width, 0);
548  av_opt_set_int(sws, "dst_format", AV_PIX_FMT_GRAY8, 0);
549  av_opt_set_int(sws, "sws_flags", SWS_POINT, 0);
550 
551  if ((ret = sws_init_context(sws, NULL, NULL)) < 0)
552  goto end;
553 
554  sws_scale(sws,
555  (const uint8_t *const *)&qr->qrcode_mask_data, qr->qrcode_mask_linesize,
556  0, qr->qrcode_width,
558 
559  /* blend mask over the input frame */
560  offset = (V(Q) - V(q)) / 2;
565  3, 0, V(x) + offset, V(y) + offset);
566  }
567 
568 end:
569  sws_freeContext(sws);
570  QRcode_free(qrcode);
571 
572  return ret;
573 }
574 
575 #if CONFIG_QRENCODESRC_FILTER
576 
577 static const AVOption qrencodesrc_options[] = {
579  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
580  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, FLAGS },
581  { NULL }
582 };
583 
584 AVFILTER_DEFINE_CLASS(qrencodesrc);
585 
587 {
588  AVFilterContext *ctx = outlink->src;
589  QREncodeContext *qr = ctx->priv;
590  int ret;
591 
592  qr->is_source = 1;
593  V(x) = V(y) = 0;
594 
595 #define PARSE_AND_EVAL_EXPR(var_name_, expr_name_) \
596  ret = av_expr_parse_and_eval(&qr->var_values[VAR_##var_name_], \
597  qr->expr_name_##_expr, \
598  var_names, qr->var_values, \
599  NULL, NULL, \
600  fun2_names, fun2, \
601  &qr->lfg, 0, ctx); \
602  if (ret < 0) { \
603  av_log(ctx, AV_LOG_ERROR, \
604  "Could not evaluate expression '%s'\n", \
605  qr->expr_name_##_expr); \
606  return ret; \
607  }
608 
609  /* undefined for the source */
610  V(main_w) = V(W) = NAN;
611  V(main_h) = V(H) = NAN;
612  V(x) = V(y) = V(t) = V(n) = NAN;
613  V(dar) = V(sar) = 1.0;
614 
615  PARSE_AND_EVAL_EXPR(rendered_qr_w, rendered_qrcode_width);
616  V(q) = V(rendered_qr_w);
617  PARSE_AND_EVAL_EXPR(rendered_padded_qr_w, rendered_padded_qrcode_width);
618  V(Q) = V(rendered_padded_qr_w);
619  PARSE_AND_EVAL_EXPR(rendered_qr_w, rendered_qrcode_width);
620  V(q) = V(rendered_qr_w);
621 
622  qr->rendered_qrcode_width = V(rendered_qr_w);
623  qr->rendered_padded_qrcode_width = V(rendered_padded_qr_w);
624 
626  "q:%d Q:%d case_sensitive:%d level:%d\n",
628  qr->case_sensitive, qr->level);
629 
632  "Resulting padded QR code width (%d) is lesser than the QR code width (%d)\n",
634  return AVERROR(EINVAL);
635  }
636 
638  ff_draw_color(&qr->draw, &qr->draw_foreground_color, (const uint8_t *)&qr->foreground_color);
639  ff_draw_color(&qr->draw, &qr->draw_background_color, (const uint8_t *)&qr->background_color);
640 
641  ff_draw_init2(&qr->draw0, outlink->format, outlink->colorspace, outlink->color_range, FF_DRAW_PROCESS_ALPHA);
642  ff_draw_color(&qr->draw0, &qr->draw0_background_color, (const uint8_t *)&qr->background_color);
643 
644  outlink->w = qr->rendered_padded_qrcode_width;
645  outlink->h = qr->rendered_padded_qrcode_width;
646  outlink->time_base = av_inv_q(qr->frame_rate);
647  outlink->frame_rate = qr->frame_rate;
648 
649  return 0;
650 }
651 
652 static int request_frame(AVFilterLink *outlink)
653 {
654  AVFilterContext *ctx = (AVFilterContext *)outlink->src;
655  QREncodeContext *qr = ctx->priv;
656  AVFrame *frame =
657  ff_get_video_buffer(outlink, qr->rendered_padded_qrcode_width, qr->rendered_padded_qrcode_width);
658  int ret;
659 
660  if (!frame)
661  return AVERROR(ENOMEM);
663  V(n) = frame->pts = qr->pts++;
664  V(t) = qr->pts * av_q2d(outlink->time_base);
665 
666  if ((ret = draw_qrcode(ctx, frame)) < 0)
667  return ret;
668 
669  return ff_filter_frame(outlink, frame);
670 }
671 
673 {
674  enum AVPixelFormat pix_fmt;
676  AVFilterFormats *fmts = NULL;
677  int ret;
678 
679  // this is needed to support both the no-draw and draw cases
680  // for the no-draw case we use FFDrawContext to write on the input picture ref
682  if (ff_draw_init(&draw, pix_fmt, 0) >= 0 &&
684  (ret = ff_add_format(&fmts, pix_fmt)) < 0)
685  return ret;
686 
687  return ff_set_common_formats(ctx, fmts);
688 }
689 
691  {
692  .name = "default",
693  .type = AVMEDIA_TYPE_VIDEO,
694  .request_frame = request_frame,
695  .config_props = qrencodesrc_config_props,
696  }
697 };
698 
700  .name = "qrencodesrc",
701  .description = NULL_IF_CONFIG_SMALL("Generate a QR code."),
702  .priv_size = sizeof(QREncodeContext),
703  .priv_class = &qrencodesrc_class,
704  .init = init,
705  .uninit = uninit,
706  .inputs = NULL,
709 };
710 
711 #endif // CONFIG_QRENCODESRC_FILTER
712 
713 #if CONFIG_QRENCODE_FILTER
714 
715 static const AVOption qrencode_options[] = {
717  {"x", "set x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},
718  {"y", "set y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},
719  { NULL }
720 };
721 
722 AVFILTER_DEFINE_CLASS(qrencode);
723 
725 {
726  AVFilterContext *ctx = inlink->dst;
727  QREncodeContext *qr = ctx->priv;
728  char *expr;
729  int ret;
730 
731  qr->is_source = 0;
732 
733  ff_draw_init2(&qr->draw, inlink->format, inlink->colorspace, inlink->color_range,
735 
736  V(W) = V(main_w) = inlink->w;
737  V(H) = V(main_h) = inlink->h;
738  V(sar) = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
739  V(dar) = (double)inlink->w / inlink->h * V(sar);
740  V(hsub) = 1 << qr->draw.hsub_max;
741  V(vsub) = 1 << qr->draw.vsub_max;
742  V(t) = NAN;
743  V(x) = V(y) = NAN;
744 
745  qr->x_pexpr = qr->y_pexpr = NULL;
746  qr->x_pexpr = qr->y_pexpr = NULL;
747 
748 #define PARSE_EXPR(name_) \
749  ret = av_expr_parse(&qr->name_##_pexpr, expr = qr->name_##_expr, var_names, \
750  NULL, NULL, fun2_names, fun2, 0, ctx); \
751  if (ret < 0) { \
752  av_log(ctx, AV_LOG_ERROR, \
753  "Could not to parse expression '%s' for '%s'\n", \
754  expr, #name_); \
755  return AVERROR(EINVAL); \
756  }
757 
758  PARSE_EXPR(x);
759  PARSE_EXPR(y);
760  PARSE_EXPR(rendered_qrcode_width);
761  PARSE_EXPR(rendered_padded_qrcode_width);
762 
763  ff_draw_init2(&qr->draw, inlink->format, inlink->colorspace, inlink->color_range,
765  ff_draw_color(&qr->draw, &qr->draw_foreground_color, (const uint8_t *)&qr->foreground_color);
766  ff_draw_color(&qr->draw, &qr->draw_background_color, (const uint8_t *)&qr->background_color);
767 
768  qr->rendered_qrcode_width = -1;
769 
770  return 0;
771 }
772 
774 {
776 }
777 
779 {
780  AVFilterContext *ctx = inlink->dst;
781  AVFilterLink *outlink = ctx->outputs[0];
782  QREncodeContext *qr = ctx->priv;
783  int ret;
784 
785  V(n) = inlink->frame_count_out;
786  V(t) = frame->pts == AV_NOPTS_VALUE ?
787  NAN : frame->pts * av_q2d(inlink->time_base);
788  V(pict_type) = frame->pict_type;
789  V(duration) = frame->duration * av_q2d(inlink->time_base);
790 
791  qr->metadata = frame->metadata;
792 
793  if ((ret = draw_qrcode(ctx, frame)) < 0)
794  return ret;
795 
796  return ff_filter_frame(outlink, frame);
797 }
798 
800  {
801  .name = "default",
802  .type = AVMEDIA_TYPE_VIDEO,
804  .filter_frame = filter_frame,
805  .config_props = qrencode_config_input,
806  },
807 };
808 
810  .name = "qrencode",
811  .description = NULL_IF_CONFIG_SMALL("Draw a QR code on top of video frames."),
812  .priv_size = sizeof(QREncodeContext),
813  .priv_class = &qrencode_class,
814  .init = init,
815  .uninit = uninit,
820 };
821 
822 #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:112
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
QREncodeContext::foreground_color
uint8_t foreground_color[4]
Definition: qrencode.c:115
FFDrawColor
Definition: drawutils.h:50
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_expand_text
int ff_expand_text(FFExpandTextContext *expand_text, char *text, AVBPrint *bp)
Expand text template.
Definition: textutils.c:122
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:46
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:257
VAR_VARS_NB
@ VAR_VARS_NB
Definition: qrencode.c:65
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:1018
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:750
qrencode_config_input
static int qrencode_config_input(AVFilterLink *inlink)
Definition: qrencode.c:724
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
AV_OPT_TYPE_VIDEO_RATE
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
Definition: opt.h:248
VAR_x
@ VAR_x
Definition: qrencode.c:63
qrencodesrc_outputs
static const AVFilterPad qrencodesrc_outputs[]
Definition: qrencode.c:690
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
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:344
FFDrawContext::hsub_max
uint8_t hsub_max
Definition: drawutils.h:42
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:456
AVFrame::width
int width
Definition: frame.h:416
QREncodeContext::qrcode_data
uint8_t * qrcode_data[4]
Definition: qrencode.c:126
w
uint8_t w
Definition: llviddspenc.c:38
QREncodeContext
Definition: qrencode.c:93
QREncodeContext::draw_background_color
FFDrawColor draw_background_color
background color
Definition: qrencode.c:120
QREncodeContext::rendered_padded_qrcode_width_pexpr
AVExpr * rendered_padded_qrcode_width_pexpr
Definition: qrencode.c:103
QREncodeContext::background_color
uint8_t background_color[4]
Definition: qrencode.c:116
AVOption
AVOption.
Definition: opt.h:346
QREncodeContext::draw_foreground_color
FFDrawColor draw_foreground_color
foreground color
Definition: qrencode.c:119
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:159
QREncodeContext::var_values
double var_values[VAR_VARS_NB]
Definition: qrencode.c:144
VAR_hsub
@ VAR_hsub
Definition: qrencode.c:53
FLAGS
#define FLAGS
Definition: cmdutils.c:584
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
VAR_sar
@ VAR_sar
Definition: qrencode.c:61
max
#define max(a, b)
Definition: cuda_runtime.h:33
sws_scale
int attribute_align_arg sws_scale(struct SwsContext *c, 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:1205
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:194
VAR_n
@ VAR_n
Definition: qrencode.c:56
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
video.h
EXPANSION_NORMAL
@ EXPANSION_NORMAL
Definition: qrencode.c:90
QREncodeContext::padded_qrcode_width
int padded_qrcode_width
Definition: qrencode.c:136
VAR_duration
@ VAR_duration
Definition: qrencode.c:52
drand
static double drand(void *opaque, double min, double max)
Definition: qrencode.c:184
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:365
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:73
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:363
FFDrawContext::vsub_max
uint8_t vsub_max
Definition: drawutils.h:43
QREncodeContext::rendered_qrcode_data
uint8_t * rendered_qrcode_data[4]
Definition: qrencode.c:132
QREncodeContext::draw
FFDrawContext draw
Definition: qrencode.c:118
positions
const static uint16_t positions[][14][3]
Definition: vf_vectorscope.c:817
Q
#define Q(x)
Definition: vvc_filter_template.c:433
QREncodeContext::is_source
char is_source
Definition: qrencode.c:96
QREncodeContext::draw0
FFDrawContext draw0
Definition: qrencode.c:123
PARSE_EXPR
#define PARSE_EXPR(e, s)
QREncodeContext::rendered_qrcode_linesize
int rendered_qrcode_linesize[4]
Definition: qrencode.c:133
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_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:535
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:69
QREncodeContext::draw0_background_color
FFDrawColor draw0_background_color
background color
Definition: qrencode.c:124
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:359
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
QREncodeContext::frame_rate
AVRational frame_rate
Definition: qrencode.c:138
QREncodeContext::case_sensitive
char case_sensitive
Definition: qrencode.c:113
VAR_q
@ VAR_q
Definition: qrencode.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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:352
QREncodeContext::lfg
AVLFG lfg
random generator
Definition: qrencode.c:145
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:867
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:64
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:135
VAR_w
@ VAR_w
Definition: qrencode.c:58
QREncodeContext::pts
uint64_t pts
Definition: qrencode.c:110
ff_vsrc_qrencodesrc
const AVFilter ff_vsrc_qrencodesrc
Definition: qrencode.c:699
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:652
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:62
QREncodeContext::x_expr
char * x_expr
Definition: qrencode.c:97
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVExpr
Definition: eval.c:159
func_frame_num
static int func_frame_num(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:216
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Definition: drawutils.c:152
NAN
#define NAN
Definition: mathematics.h:115
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
VAR_qr_w
@ VAR_qr_w
Definition: qrencode.c:58
frame
static AVFrame * frame
Definition: demux_decode.c:54
QREncodeContext::expansion
int expansion
expansion mode to use for the text
Definition: qrencode.c:140
VAR_y
@ VAR_y
Definition: qrencode.c:64
VAR_W
@ VAR_W
Definition: qrencode.c:55
qrencode_query_formats
static int qrencode_query_formats(AVFilterContext *ctx)
Definition: qrencode.c:773
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
QREncodeContext::rendered_padded_qrcode_width_expr
char * rendered_padded_qrcode_width_expr
Definition: qrencode.c:102
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:302
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
V
#define V
Definition: avdct.c:30
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:106
textutils.h
QREncodeContext::rendered_qrcode_width_expr
char * rendered_qrcode_width_expr
Definition: qrencode.c:101
sws_alloc_context
struct SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext.
Definition: utils.c:1180
avfilter_vf_qrencode_inputs
static const AVFilterPad avfilter_vf_qrencode_inputs[]
Definition: qrencode.c:799
double
double
Definition: af_crystalizer.c:131
VAR_rendered_qr_w
@ VAR_rendered_qr_w
Definition: qrencode.c:60
init
static av_cold int init(AVFilterContext *ctx)
Definition: qrencode.c:299
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: qrencode.c:330
VAR_Q
@ VAR_Q
Definition: qrencode.c:59
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
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:789
VAR_t
@ VAR_t
Definition: qrencode.c:62
qrencodesrc_config_props
static int qrencodesrc_config_props(AVFilterLink *outlink)
Definition: qrencode.c:586
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
TFLAGS
#define TFLAGS
Definition: af_afade.c:65
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:446
QREncodeContext::rendered_qrcode_width
int rendered_qrcode_width
Definition: qrencode.c:105
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:106
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
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:354
QREncodeContext::qrcode_mask_linesize
int qrcode_mask_linesize[4]
Definition: qrencode.c:129
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:280
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:121
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:81
VAR_pict_type
@ VAR_pict_type
Definition: qrencode.c:57
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
EXPANSION_NONE
@ EXPANSION_NONE
Definition: qrencode.c:89
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:232
fun2_names
static const char *const fun2_names[]
Definition: qrencode.c:180
QREncodeContext::qrcode_mask_data
uint8_t * qrcode_mask_data[4]
Definition: qrencode.c:128
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:431
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(qrencodesrc)
H
#define H
Definition: pixlet.c:38
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: qrencode.c:778
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
qrencodesrc_query_formats
static int qrencodesrc_query_formats(AVFilterContext *ctx)
Definition: qrencode.c:672
qrencode_options
static const AVOption qrencode_options[]
Definition: qrencode.c:715
COMMON_OPTIONS
#define COMMON_OPTIONS
Definition: huffyuvenc.c:1047
draw
static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: avf_showcwt.c:451
VAR_H
@ VAR_H
Definition: qrencode.c:54
internal.h
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:147
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
W
@ W
Definition: vf_addroi.c:27
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:148
VAR_main_w
@ VAR_main_w
Definition: qrencode.c:55
QREncodeContext::level
int level
Definition: qrencode.c:112
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
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:648
delta
float delta
Definition: vorbis_enc_data.h:430
VAR_dar
@ VAR_dar
Definition: qrencode.c:51
VAR_main_h
@ VAR_main_h
Definition: qrencode.c:54
VAR_vsub
@ VAR_vsub
Definition: qrencode.c:53
FFDrawContext
Definition: drawutils.h:35
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: internal.h:39
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:157
AVFilter
Filter definition.
Definition: avfilter.h:166
expand_text_functions
static FFExpandTextFunction expand_text_functions[]
Definition: qrencode.c:286
ret
ret
Definition: filter_design.txt:187
var_names
static const char *const var_names[]
Definition: qrencode.c:68
ff_vf_qrencode
const AVFilter ff_vf_qrencode
Definition: qrencode.c:809
QREncodeContext::textfile
char * textfile
Definition: qrencode.c:109
QREncodeContext::metadata
AVDictionary * metadata
Definition: qrencode.c:146
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:451
sws_init_context
av_warn_unused_result int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:2036
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
AVFrame::height
int height
Definition: frame.h:416
random_seed.h
qrencodesrc_options
static const AVOption qrencodesrc_options[]
Definition: qrencode.c:577
sws_freeContext
void sws_freeContext(struct SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2425
avfilter.h
AVFrame::metadata
AVDictionary * metadata
metadata.
Definition: frame.h:662
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:141
show_qrcode
static void show_qrcode(AVFilterContext *ctx, const QRcode *qrcode)
Definition: qrencode.c:345
fun2
static const ff_eval_func2 fun2[]
Definition: qrencode.c:189
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
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:233
func_eval_expr
static int func_eval_expr(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:247
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:127
QREncodeContext::x_pexpr
AVExpr * x_pexpr
Definition: qrencode.c:99
func_strftime
static int func_strftime(void *ctx, AVBPrint *bp, const char *function_name, unsigned argc, char **argv)
Definition: qrencode.c:225
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
QREncodeContext::y_pexpr
AVExpr * y_pexpr
Definition: qrencode.c:99
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:389
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VAR_rendered_padded_qr_w
@ VAR_rendered_padded_qr_w
Definition: qrencode.c:59
QREncodeContext::expanded_text
AVBPrint expanded_text
used to contain the expanded text
Definition: qrencode.c:142
AVDictionaryEntry::value
char * value
Definition: dict.h:91
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
drawutils.h
SwsContext
Definition: swscale_internal.h:299
ff_print_time
int ff_print_time(void *log_ctx, AVBPrint *bp, const char *strftime_fmt, char localtime)
Definition: textutils.c:201
swscale.h
QREncodeContext::rendered_qrcode_width_pexpr
AVExpr * rendered_qrcode_width_pexpr
Definition: qrencode.c:103
QREncodeContext::y_expr
char * y_expr
Definition: qrencode.c:98
Expansion
Expansion
Definition: qrencode.c:88
min
float min
Definition: vorbis_enc_data.h:429
QREncodeContext::text
unsigned char * text
Definition: qrencode.c:108
AVFILTERPAD_FLAG_NEEDS_WRITABLE
#define AVFILTERPAD_FLAG_NEEDS_WRITABLE
The filter expects writable frames from its input link, duplicating data buffers if needed.
Definition: internal.h:52