FFmpeg  4.3
f_sendcmd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Stefano Sabatini
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * send commands filter
24  */
25 
26 #include "libavutil/avstring.h"
27 #include "libavutil/bprint.h"
28 #include "libavutil/eval.h"
29 #include "libavutil/file.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/parseutils.h"
32 #include "avfilter.h"
33 #include "internal.h"
34 #include "audio.h"
35 #include "video.h"
36 
37 #define COMMAND_FLAG_ENTER 1
38 #define COMMAND_FLAG_LEAVE 2
39 #define COMMAND_FLAG_EXPR 4
40 
41 static const char *const var_names[] = {
42  "N", /* frame number */
43  "T", /* frame time in seconds */
44  "POS", /* original position in the file of the frame */
45  "PTS", /* frame pts */
46  "TS", /* interval start time in seconds */
47  "TE", /* interval end time in seconds */
48  "TI", /* interval interpolated value: TI = (T - TS) / (TE - TS) */
49  NULL
50 };
51 
52 enum var_name {
61 };
62 
63 static inline char *make_command_flags_str(AVBPrint *pbuf, int flags)
64 {
65  static const char * const flag_strings[] = { "enter", "leave", "expr" };
66  int i, is_first = 1;
67 
69  for (i = 0; i < FF_ARRAY_ELEMS(flag_strings); i++) {
70  if (flags & 1<<i) {
71  if (!is_first)
72  av_bprint_chars(pbuf, '+', 1);
73  av_bprintf(pbuf, "%s", flag_strings[i]);
74  is_first = 0;
75  }
76  }
77 
78  return pbuf->str;
79 }
80 
81 typedef struct Command {
82  int flags;
83  char *target, *command, *arg;
84  int index;
85 } Command;
86 
87 typedef struct Interval {
88  int64_t start_ts; ///< start timestamp expressed as microseconds units
89  int64_t end_ts; ///< end timestamp expressed as microseconds units
90  int index; ///< unique index for these interval commands
93  int enabled; ///< current time detected inside this interval
94 } Interval;
95 
96 typedef struct SendCmdContext {
97  const AVClass *class;
100 
104 
105 #define OFFSET(x) offsetof(SendCmdContext, x)
106 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM
107 static const AVOption options[] = {
108  { "commands", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
109  { "c", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
110  { "filename", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
111  { "f", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
112  { NULL }
113 };
114 
115 #define SPACES " \f\t\n\r"
116 
117 static void skip_comments(const char **buf)
118 {
119  while (**buf) {
120  /* skip leading spaces */
121  *buf += strspn(*buf, SPACES);
122  if (**buf != '#')
123  break;
124 
125  (*buf)++;
126 
127  /* skip comment until the end of line */
128  *buf += strcspn(*buf, "\n");
129  if (**buf)
130  (*buf)++;
131  }
132 }
133 
134 #define COMMAND_DELIMS " \f\t\n\r,;"
135 
136 static int parse_command(Command *cmd, int cmd_count, int interval_count,
137  const char **buf, void *log_ctx)
138 {
139  int ret;
140 
141  memset(cmd, 0, sizeof(Command));
142  cmd->index = cmd_count;
143 
144  /* format: [FLAGS] target command arg */
145  *buf += strspn(*buf, SPACES);
146 
147  /* parse flags */
148  if (**buf == '[') {
149  (*buf)++; /* skip "[" */
150 
151  while (**buf) {
152  int len = strcspn(*buf, "|+]");
153 
154  if (!strncmp(*buf, "enter", strlen("enter"))) cmd->flags |= COMMAND_FLAG_ENTER;
155  else if (!strncmp(*buf, "leave", strlen("leave"))) cmd->flags |= COMMAND_FLAG_LEAVE;
156  else if (!strncmp(*buf, "expr", strlen("expr"))) cmd->flags |= COMMAND_FLAG_EXPR;
157  else {
158  char flag_buf[64];
159  av_strlcpy(flag_buf, *buf, sizeof(flag_buf));
160  av_log(log_ctx, AV_LOG_ERROR,
161  "Unknown flag '%s' in interval #%d, command #%d\n",
162  flag_buf, interval_count, cmd_count);
163  return AVERROR(EINVAL);
164  }
165  *buf += len;
166  if (**buf == ']')
167  break;
168  if (!strspn(*buf, "+|")) {
169  av_log(log_ctx, AV_LOG_ERROR,
170  "Invalid flags char '%c' in interval #%d, command #%d\n",
171  **buf, interval_count, cmd_count);
172  return AVERROR(EINVAL);
173  }
174  if (**buf)
175  (*buf)++;
176  }
177 
178  if (**buf != ']') {
179  av_log(log_ctx, AV_LOG_ERROR,
180  "Missing flag terminator or extraneous data found at the end of flags "
181  "in interval #%d, command #%d\n", interval_count, cmd_count);
182  return AVERROR(EINVAL);
183  }
184  (*buf)++; /* skip "]" */
185  } else {
186  cmd->flags = COMMAND_FLAG_ENTER;
187  }
188 
189  *buf += strspn(*buf, SPACES);
190  cmd->target = av_get_token(buf, COMMAND_DELIMS);
191  if (!cmd->target || !cmd->target[0]) {
192  av_log(log_ctx, AV_LOG_ERROR,
193  "No target specified in interval #%d, command #%d\n",
194  interval_count, cmd_count);
195  ret = AVERROR(EINVAL);
196  goto fail;
197  }
198 
199  *buf += strspn(*buf, SPACES);
200  cmd->command = av_get_token(buf, COMMAND_DELIMS);
201  if (!cmd->command || !cmd->command[0]) {
202  av_log(log_ctx, AV_LOG_ERROR,
203  "No command specified in interval #%d, command #%d\n",
204  interval_count, cmd_count);
205  ret = AVERROR(EINVAL);
206  goto fail;
207  }
208 
209  *buf += strspn(*buf, SPACES);
210  cmd->arg = av_get_token(buf, COMMAND_DELIMS);
211 
212  return 1;
213 
214 fail:
215  av_freep(&cmd->target);
216  av_freep(&cmd->command);
217  av_freep(&cmd->arg);
218  return ret;
219 }
220 
221 static int parse_commands(Command **cmds, int *nb_cmds, int interval_count,
222  const char **buf, void *log_ctx)
223 {
224  int cmd_count = 0;
225  int ret, n = 0;
226  AVBPrint pbuf;
227 
228  *cmds = NULL;
229  *nb_cmds = 0;
230 
231  while (**buf) {
232  Command cmd;
233 
234  if ((ret = parse_command(&cmd, cmd_count, interval_count, buf, log_ctx)) < 0)
235  return ret;
236  cmd_count++;
237 
238  /* (re)allocate commands array if required */
239  if (*nb_cmds == n) {
240  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
241  *cmds = av_realloc_f(*cmds, n, 2*sizeof(Command));
242  if (!*cmds) {
243  av_log(log_ctx, AV_LOG_ERROR,
244  "Could not (re)allocate command array\n");
245  return AVERROR(ENOMEM);
246  }
247  }
248 
249  (*cmds)[(*nb_cmds)++] = cmd;
250 
251  *buf += strspn(*buf, SPACES);
252  if (**buf && **buf != ';' && **buf != ',') {
253  av_log(log_ctx, AV_LOG_ERROR,
254  "Missing separator or extraneous data found at the end of "
255  "interval #%d, in command #%d\n",
256  interval_count, cmd_count);
257  av_log(log_ctx, AV_LOG_ERROR,
258  "Command was parsed as: flags:[%s] target:%s command:%s arg:%s\n",
259  make_command_flags_str(&pbuf, cmd.flags), cmd.target, cmd.command, cmd.arg);
260  return AVERROR(EINVAL);
261  }
262  if (**buf == ';')
263  break;
264  if (**buf == ',')
265  (*buf)++;
266  }
267 
268  return 0;
269 }
270 
271 #define DELIMS " \f\t\n\r,;"
272 
273 static int parse_interval(Interval *interval, int interval_count,
274  const char **buf, void *log_ctx)
275 {
276  char *intervalstr;
277  int ret;
278 
279  *buf += strspn(*buf, SPACES);
280  if (!**buf)
281  return 0;
282 
283  /* reset data */
284  memset(interval, 0, sizeof(Interval));
285  interval->index = interval_count;
286 
287  /* format: INTERVAL COMMANDS */
288 
289  /* parse interval */
290  intervalstr = av_get_token(buf, DELIMS);
291  if (intervalstr && intervalstr[0]) {
292  char *start, *end;
293 
294  start = av_strtok(intervalstr, "-", &end);
295  if (!start) {
296  ret = AVERROR(EINVAL);
297  av_log(log_ctx, AV_LOG_ERROR,
298  "Invalid interval specification '%s' in interval #%d\n",
299  intervalstr, interval_count);
300  goto end;
301  }
302  if ((ret = av_parse_time(&interval->start_ts, start, 1)) < 0) {
303  av_log(log_ctx, AV_LOG_ERROR,
304  "Invalid start time specification '%s' in interval #%d\n",
305  start, interval_count);
306  goto end;
307  }
308 
309  if (end) {
310  if ((ret = av_parse_time(&interval->end_ts, end, 1)) < 0) {
311  av_log(log_ctx, AV_LOG_ERROR,
312  "Invalid end time specification '%s' in interval #%d\n",
313  end, interval_count);
314  goto end;
315  }
316  } else {
317  interval->end_ts = INT64_MAX;
318  }
319  if (interval->end_ts < interval->start_ts) {
320  av_log(log_ctx, AV_LOG_ERROR,
321  "Invalid end time '%s' in interval #%d: "
322  "cannot be lesser than start time '%s'\n",
323  end, interval_count, start);
324  ret = AVERROR(EINVAL);
325  goto end;
326  }
327  } else {
328  av_log(log_ctx, AV_LOG_ERROR,
329  "No interval specified for interval #%d\n", interval_count);
330  ret = AVERROR(EINVAL);
331  goto end;
332  }
333 
334  /* parse commands */
335  ret = parse_commands(&interval->commands, &interval->nb_commands,
336  interval_count, buf, log_ctx);
337 
338 end:
339  av_free(intervalstr);
340  return ret;
341 }
342 
343 static int parse_intervals(Interval **intervals, int *nb_intervals,
344  const char *buf, void *log_ctx)
345 {
346  int interval_count = 0;
347  int ret, n = 0;
348 
349  *intervals = NULL;
350  *nb_intervals = 0;
351 
352  if (!buf)
353  return 0;
354 
355  while (1) {
356  Interval interval;
357 
358  skip_comments(&buf);
359  if (!(*buf))
360  break;
361 
362  if ((ret = parse_interval(&interval, interval_count, &buf, log_ctx)) < 0)
363  return ret;
364 
365  buf += strspn(buf, SPACES);
366  if (*buf) {
367  if (*buf != ';') {
368  av_log(log_ctx, AV_LOG_ERROR,
369  "Missing terminator or extraneous data found at the end of interval #%d\n",
370  interval_count);
371  return AVERROR(EINVAL);
372  }
373  buf++; /* skip ';' */
374  }
375  interval_count++;
376 
377  /* (re)allocate commands array if required */
378  if (*nb_intervals == n) {
379  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
380  *intervals = av_realloc_f(*intervals, n, 2*sizeof(Interval));
381  if (!*intervals) {
382  av_log(log_ctx, AV_LOG_ERROR,
383  "Could not (re)allocate intervals array\n");
384  return AVERROR(ENOMEM);
385  }
386  }
387 
388  (*intervals)[(*nb_intervals)++] = interval;
389  }
390 
391  return 0;
392 }
393 
394 static int cmp_intervals(const void *a, const void *b)
395 {
396  const Interval *i1 = a;
397  const Interval *i2 = b;
398  return 2 * FFDIFFSIGN(i1->start_ts, i2->start_ts) + FFDIFFSIGN(i1->index, i2->index);
399 }
400 
402 {
403  SendCmdContext *s = ctx->priv;
404  int ret, i, j;
405 
406  if ((!!s->commands_filename + !!s->commands_str) != 1) {
407  av_log(ctx, AV_LOG_ERROR,
408  "One and only one of the filename or commands options must be specified\n");
409  return AVERROR(EINVAL);
410  }
411 
412  if (s->commands_filename) {
413  uint8_t *file_buf, *buf;
414  size_t file_bufsize;
416  &file_buf, &file_bufsize, 0, ctx);
417  if (ret < 0)
418  return ret;
419 
420  /* create a 0-terminated string based on the read file */
421  buf = av_malloc(file_bufsize + 1);
422  if (!buf) {
423  av_file_unmap(file_buf, file_bufsize);
424  return AVERROR(ENOMEM);
425  }
426  memcpy(buf, file_buf, file_bufsize);
427  buf[file_bufsize] = 0;
428  av_file_unmap(file_buf, file_bufsize);
429  s->commands_str = buf;
430  }
431 
432  if ((ret = parse_intervals(&s->intervals, &s->nb_intervals,
433  s->commands_str, ctx)) < 0)
434  return ret;
435 
436  if (s->nb_intervals == 0) {
437  av_log(ctx, AV_LOG_ERROR, "No commands were specified\n");
438  return AVERROR(EINVAL);
439  }
440 
441  qsort(s->intervals, s->nb_intervals, sizeof(Interval), cmp_intervals);
442 
443  av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n");
444  for (i = 0; i < s->nb_intervals; i++) {
445  AVBPrint pbuf;
446  Interval *interval = &s->intervals[i];
447  av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n",
448  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index);
449  for (j = 0; j < interval->nb_commands; j++) {
450  Command *cmd = &interval->commands[j];
451  av_log(ctx, AV_LOG_VERBOSE,
452  " [%s] target:%s command:%s arg:%s index:%d\n",
453  make_command_flags_str(&pbuf, cmd->flags), cmd->target, cmd->command, cmd->arg, cmd->index);
454  }
455  }
456 
457  return 0;
458 }
459 
461 {
462  SendCmdContext *s = ctx->priv;
463  int i, j;
464 
465  for (i = 0; i < s->nb_intervals; i++) {
466  Interval *interval = &s->intervals[i];
467  for (j = 0; j < interval->nb_commands; j++) {
468  Command *cmd = &interval->commands[j];
469  av_freep(&cmd->target);
470  av_freep(&cmd->command);
471  av_freep(&cmd->arg);
472  }
473  av_freep(&interval->commands);
474  }
475  av_freep(&s->intervals);
476 }
477 
478 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
479 #define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
480 
481 static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
482 {
483  AVFilterContext *ctx = inlink->dst;
484  SendCmdContext *s = ctx->priv;
485  int64_t ts;
486  int i, j, ret;
487 
488  if (ref->pts == AV_NOPTS_VALUE)
489  goto end;
490 
491  ts = av_rescale_q(ref->pts, inlink->time_base, AV_TIME_BASE_Q);
492 
493 #define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts))
494 
495  for (i = 0; i < s->nb_intervals; i++) {
496  Interval *interval = &s->intervals[i];
497  int flags = 0;
498 
499  if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
500  flags += COMMAND_FLAG_ENTER;
501  interval->enabled = 1;
502  }
503  if (interval->enabled && !WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
504  flags += COMMAND_FLAG_LEAVE;
505  interval->enabled = 0;
506  }
507  if (interval->enabled)
508  flags += COMMAND_FLAG_EXPR;
509 
510  if (flags) {
511  AVBPrint pbuf;
512  av_log(ctx, AV_LOG_VERBOSE,
513  "[%s] interval #%d start_ts:%f end_ts:%f ts:%f\n",
514  make_command_flags_str(&pbuf, flags), interval->index,
515  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000,
516  (double)ts/1000000);
517 
518  for (j = 0; flags && j < interval->nb_commands; j++) {
519  Command *cmd = &interval->commands[j];
520  char *cmd_arg = cmd->arg;
521  char buf[1024];
522 
523  if (cmd->flags & flags) {
524  if (cmd->flags & COMMAND_FLAG_EXPR) {
525  double var_values[VAR_VARS_NB], res;
526  double start = TS2T(interval->start_ts, AV_TIME_BASE_Q);
527  double end = TS2T(interval->end_ts, AV_TIME_BASE_Q);
528  double current = TS2T(ref->pts, inlink->time_base);
529 
530  var_values[VAR_N] = inlink->frame_count_in;
531  var_values[VAR_POS] = ref->pkt_pos == -1 ? NAN : ref->pkt_pos;
532  var_values[VAR_PTS] = TS2D(ref->pts);
533  var_values[VAR_T] = current;
534  var_values[VAR_TS] = start;
535  var_values[VAR_TE] = end;
536  var_values[VAR_TI] = (current - start) / (end - start);
537 
538  if ((ret = av_expr_parse_and_eval(&res, cmd->arg, var_names, var_values,
539  NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
540  av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for command argument.\n", cmd->arg);
541  av_frame_free(&ref);
542  return AVERROR(EINVAL);
543  }
544 
545  cmd_arg = av_asprintf("%g", res);
546  if (!cmd_arg) {
547  av_frame_free(&ref);
548  return AVERROR(ENOMEM);
549  }
550  }
551  av_log(ctx, AV_LOG_VERBOSE,
552  "Processing command #%d target:%s command:%s arg:%s\n",
553  cmd->index, cmd->target, cmd->command, cmd_arg);
554  ret = avfilter_graph_send_command(inlink->graph,
555  cmd->target, cmd->command, cmd_arg,
556  buf, sizeof(buf),
558  av_log(ctx, AV_LOG_VERBOSE,
559  "Command reply for command #%d: ret:%s res:%s\n",
560  cmd->index, av_err2str(ret), buf);
561  if (cmd->flags & COMMAND_FLAG_EXPR)
562  av_freep(&cmd_arg);
563  }
564  }
565  }
566  }
567 
568 end:
569  switch (inlink->type) {
570  case AVMEDIA_TYPE_VIDEO:
571  case AVMEDIA_TYPE_AUDIO:
572  return ff_filter_frame(inlink->dst->outputs[0], ref);
573  }
574 
575  return AVERROR(ENOSYS);
576 }
577 
578 #if CONFIG_SENDCMD_FILTER
579 
580 #define sendcmd_options options
581 AVFILTER_DEFINE_CLASS(sendcmd);
582 
583 static const AVFilterPad sendcmd_inputs[] = {
584  {
585  .name = "default",
586  .type = AVMEDIA_TYPE_VIDEO,
587  .filter_frame = filter_frame,
588  },
589  { NULL }
590 };
591 
592 static const AVFilterPad sendcmd_outputs[] = {
593  {
594  .name = "default",
595  .type = AVMEDIA_TYPE_VIDEO,
596  },
597  { NULL }
598 };
599 
601  .name = "sendcmd",
602  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
603  .init = init,
604  .uninit = uninit,
605  .priv_size = sizeof(SendCmdContext),
606  .inputs = sendcmd_inputs,
607  .outputs = sendcmd_outputs,
608  .priv_class = &sendcmd_class,
609 };
610 
611 #endif
612 
613 #if CONFIG_ASENDCMD_FILTER
614 
615 #define asendcmd_options options
616 AVFILTER_DEFINE_CLASS(asendcmd);
617 
618 static const AVFilterPad asendcmd_inputs[] = {
619  {
620  .name = "default",
621  .type = AVMEDIA_TYPE_AUDIO,
622  .filter_frame = filter_frame,
623  },
624  { NULL }
625 };
626 
627 static const AVFilterPad asendcmd_outputs[] = {
628  {
629  .name = "default",
630  .type = AVMEDIA_TYPE_AUDIO,
631  },
632  { NULL }
633 };
634 
636  .name = "asendcmd",
637  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
638  .init = init,
639  .uninit = uninit,
640  .priv_size = sizeof(SendCmdContext),
641  .inputs = asendcmd_inputs,
642  .outputs = asendcmd_outputs,
643  .priv_class = &asendcmd_class,
644 };
645 
646 #endif
#define NULL
Definition: coverity.c:32
#define DELIMS
Definition: f_sendcmd.c:271
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
#define av_realloc_f(p, o, n)
static int cmp_intervals(const void *a, const void *b)
Definition: f_sendcmd.c:394
AVOption.
Definition: opt.h:246
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
Definition: frame.h:571
Main libavfilter public API header.
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
Definition: parseutils.c:587
int nb_intervals
Definition: f_sendcmd.c:99
char * commands_str
Definition: f_sendcmd.c:102
int index
unique index for these interval commands
Definition: f_sendcmd.c:90
const char * b
Definition: vf_curves.c:116
char * command
Definition: f_sendcmd.c:83
static int parse_commands(Command **cmds, int *nb_cmds, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:221
static int parse_interval(Interval *interval, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:273
const char * name
Pad name.
Definition: internal.h:60
static const char *const cmds[]
Definition: jacosubdec.c:72
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
char * commands_filename
Definition: f_sendcmd.c:101
uint8_t
#define av_cold
Definition: attributes.h:88
#define av_malloc(s)
AVOptions.
static void skip_comments(const char **buf)
Definition: f_sendcmd.c:117
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
AVFilter ff_vf_sendcmd
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:393
Misc file utilities.
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
int nb_commands
Definition: f_sendcmd.c:92
static int parse_intervals(Interval **intervals, int *nb_intervals, const char *buf, void *log_ctx)
Definition: f_sendcmd.c:343
int index
Definition: f_sendcmd.c:84
#define av_log(a,...)
char * target
Definition: f_sendcmd.c:83
A filter pad used for either input or output.
Definition: internal.h:54
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
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:776
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
Definition: file.c:144
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, int log_offset, void *log_ctx)
Read the file with name filename, and put its content in a newly allocated buffer or map it with mmap...
Definition: file.c:53
#define SPACES
Definition: f_sendcmd.c:115
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
#define FFMAX(a, b)
Definition: common.h:94
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
#define fail()
Definition: checkasm.h:123
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
Definition: avstring.c:149
static av_cold void uninit(AVFilterContext *ctx)
Definition: f_sendcmd.c:460
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
var_name
Definition: aeval.c:46
#define FFDIFFSIGN(x, y)
Comparator.
Definition: common.h:92
int enabled
current time detected inside this interval
Definition: f_sendcmd.c:93
#define NAN
Definition: mathematics.h:64
#define COMMAND_DELIMS
Definition: f_sendcmd.c:134
static int parse_command(Command *cmd, int cmd_count, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:136
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
#define COMMAND_FLAG_LEAVE
Definition: f_sendcmd.c:38
#define AVFILTER_CMD_FLAG_ONE
Stop once a filter understood the command (for target=all for example), fast filters are favored auto...
Definition: avfilter.h:691
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define FF_ARRAY_ELEMS(a)
#define TS2D(ts)
Definition: f_sendcmd.c:478
#define AV_BPRINT_SIZE_AUTOMATIC
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
char * arg
Definition: f_sendcmd.c:83
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
static av_cold int init(AVFilterContext *ctx)
Definition: f_sendcmd.c:401
#define COMMAND_FLAG_ENTER
Definition: f_sendcmd.c:37
int flags
Definition: f_sendcmd.c:82
const char * name
Filter name.
Definition: avfilter.h:148
Interval * intervals
Definition: f_sendcmd.c:98
static char * make_command_flags_str(AVBPrint *pbuf, int flags)
Definition: f_sendcmd.c:63
misc parsing utilities
int64_t end_ts
end timestamp expressed as microseconds units
Definition: f_sendcmd.c:89
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
#define flags(name, subs,...)
Definition: cbs_av1.c:564
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
int64_t start_ts
start timestamp expressed as microseconds units
Definition: f_sendcmd.c:88
Command * commands
Definition: f_sendcmd.c:91
int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
Send a command to one or more filter instances.
static const char *const var_names[]
Definition: f_sendcmd.c:41
#define av_free(p)
int len
#define AVFILTER_DEFINE_CLASS(fname)
Definition: internal.h:314
#define WITHIN_INTERVAL(ts, start_ts, end_ts)
An instance of a filter.
Definition: avfilter.h:338
#define av_freep(p)
internal API functions
#define OFFSET(x)
Definition: f_sendcmd.c:105
static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
Definition: f_sendcmd.c:481
#define COMMAND_FLAG_EXPR
Definition: f_sendcmd.c:39
#define FLAGS
Definition: f_sendcmd.c:106
AVFilter ff_af_asendcmd
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
static const AVOption options[]
Definition: f_sendcmd.c:107
simple arithmetic expression evaluator
#define TS2T(ts, tb)
Definition: f_sendcmd.c:479
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140