FFmpeg
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 "config_components.h"
27 
28 #include "libavutil/avstring.h"
29 #include "libavutil/bprint.h"
30 #include "libavutil/eval.h"
31 #include "libavutil/file.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/parseutils.h"
35 #include "avfilter.h"
36 #include "internal.h"
37 #include "audio.h"
38 #include "video.h"
39 
40 #define COMMAND_FLAG_ENTER 1
41 #define COMMAND_FLAG_LEAVE 2
42 #define COMMAND_FLAG_EXPR 4
43 
44 static const char *const var_names[] = {
45  "N", /* frame number */
46  "T", /* frame time in seconds */
47 #if FF_API_FRAME_PKT
48  "POS", /* original position in the file of the frame */
49 #endif
50  "PTS", /* frame pts */
51  "TS", /* interval start time in seconds */
52  "TE", /* interval end time in seconds */
53  "TI", /* interval interpolated value: TI = (T - TS) / (TE - TS) */
54  "W", /* width for video frames */
55  "H", /* height for video frames */
56  NULL
57 };
58 
59 enum var_name {
62 #if FF_API_FRAME_PKT
63  VAR_POS,
64 #endif
72 };
73 
74 static inline char *make_command_flags_str(AVBPrint *pbuf, int flags)
75 {
76  static const char * const flag_strings[] = { "enter", "leave", "expr" };
77  int i, is_first = 1;
78 
80  for (i = 0; i < FF_ARRAY_ELEMS(flag_strings); i++) {
81  if (flags & 1<<i) {
82  if (!is_first)
83  av_bprint_chars(pbuf, '+', 1);
84  av_bprintf(pbuf, "%s", flag_strings[i]);
85  is_first = 0;
86  }
87  }
88 
89  return pbuf->str;
90 }
91 
92 typedef struct Command {
93  int flags;
94  char *target, *command, *arg;
95  int index;
96 } Command;
97 
98 typedef struct Interval {
99  int64_t start_ts; ///< start timestamp expressed as microseconds units
100  int64_t end_ts; ///< end timestamp expressed as microseconds units
101  int index; ///< unique index for these interval commands
104  int enabled; ///< current time detected inside this interval
105 } Interval;
106 
107 typedef struct SendCmdContext {
108  const AVClass *class;
111 
115 
116 #define OFFSET(x) offsetof(SendCmdContext, x)
117 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM
118 static const AVOption options[] = {
119  { "commands", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
120  { "c", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
121  { "filename", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
122  { "f", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
123  { NULL }
124 };
125 
126 #define SPACES " \f\t\n\r"
127 
128 static void skip_comments(const char **buf)
129 {
130  while (**buf) {
131  /* skip leading spaces */
132  *buf += strspn(*buf, SPACES);
133  if (**buf != '#')
134  break;
135 
136  (*buf)++;
137 
138  /* skip comment until the end of line */
139  *buf += strcspn(*buf, "\n");
140  if (**buf)
141  (*buf)++;
142  }
143 }
144 
145 #define COMMAND_DELIMS " \f\t\n\r,;"
146 
147 static int parse_command(Command *cmd, int cmd_count, int interval_count,
148  const char **buf, void *log_ctx)
149 {
150  int ret;
151 
152  memset(cmd, 0, sizeof(Command));
153  cmd->index = cmd_count;
154 
155  /* format: [FLAGS] target command arg */
156  *buf += strspn(*buf, SPACES);
157 
158  /* parse flags */
159  if (**buf == '[') {
160  (*buf)++; /* skip "[" */
161 
162  while (**buf) {
163  int len = strcspn(*buf, "|+]");
164 
165  if (!strncmp(*buf, "enter", strlen("enter"))) cmd->flags |= COMMAND_FLAG_ENTER;
166  else if (!strncmp(*buf, "leave", strlen("leave"))) cmd->flags |= COMMAND_FLAG_LEAVE;
167  else if (!strncmp(*buf, "expr", strlen("expr"))) cmd->flags |= COMMAND_FLAG_EXPR;
168  else {
169  char flag_buf[64];
170  av_strlcpy(flag_buf, *buf, sizeof(flag_buf));
171  av_log(log_ctx, AV_LOG_ERROR,
172  "Unknown flag '%s' in interval #%d, command #%d\n",
173  flag_buf, interval_count, cmd_count);
174  return AVERROR(EINVAL);
175  }
176  *buf += len;
177  if (**buf == ']')
178  break;
179  if (!strspn(*buf, "+|")) {
180  av_log(log_ctx, AV_LOG_ERROR,
181  "Invalid flags char '%c' in interval #%d, command #%d\n",
182  **buf, interval_count, cmd_count);
183  return AVERROR(EINVAL);
184  }
185  if (**buf)
186  (*buf)++;
187  }
188 
189  if (**buf != ']') {
190  av_log(log_ctx, AV_LOG_ERROR,
191  "Missing flag terminator or extraneous data found at the end of flags "
192  "in interval #%d, command #%d\n", interval_count, cmd_count);
193  return AVERROR(EINVAL);
194  }
195  (*buf)++; /* skip "]" */
196  } else {
197  cmd->flags = COMMAND_FLAG_ENTER;
198  }
199 
200  *buf += strspn(*buf, SPACES);
201  cmd->target = av_get_token(buf, COMMAND_DELIMS);
202  if (!cmd->target || !cmd->target[0]) {
203  av_log(log_ctx, AV_LOG_ERROR,
204  "No target specified in interval #%d, command #%d\n",
205  interval_count, cmd_count);
206  ret = AVERROR(EINVAL);
207  goto fail;
208  }
209 
210  *buf += strspn(*buf, SPACES);
211  cmd->command = av_get_token(buf, COMMAND_DELIMS);
212  if (!cmd->command || !cmd->command[0]) {
213  av_log(log_ctx, AV_LOG_ERROR,
214  "No command specified in interval #%d, command #%d\n",
215  interval_count, cmd_count);
216  ret = AVERROR(EINVAL);
217  goto fail;
218  }
219 
220  *buf += strspn(*buf, SPACES);
221  cmd->arg = av_get_token(buf, COMMAND_DELIMS);
222 
223  return 1;
224 
225 fail:
226  av_freep(&cmd->target);
227  av_freep(&cmd->command);
228  av_freep(&cmd->arg);
229  return ret;
230 }
231 
232 static int parse_commands(Command **cmds, int *nb_cmds, int interval_count,
233  const char **buf, void *log_ctx)
234 {
235  int cmd_count = 0;
236  int ret, n = 0;
237  AVBPrint pbuf;
238 
239  *cmds = NULL;
240  *nb_cmds = 0;
241 
242  while (**buf) {
243  Command cmd;
244 
245  if ((ret = parse_command(&cmd, cmd_count, interval_count, buf, log_ctx)) < 0)
246  return ret;
247  cmd_count++;
248 
249  /* (re)allocate commands array if required */
250  if (*nb_cmds == n) {
251  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
252  *cmds = av_realloc_f(*cmds, n, 2*sizeof(Command));
253  if (!*cmds) {
254  av_log(log_ctx, AV_LOG_ERROR,
255  "Could not (re)allocate command array\n");
256  return AVERROR(ENOMEM);
257  }
258  }
259 
260  (*cmds)[(*nb_cmds)++] = cmd;
261 
262  *buf += strspn(*buf, SPACES);
263  if (**buf && **buf != ';' && **buf != ',') {
264  av_log(log_ctx, AV_LOG_ERROR,
265  "Missing separator or extraneous data found at the end of "
266  "interval #%d, in command #%d\n",
267  interval_count, cmd_count);
268  av_log(log_ctx, AV_LOG_ERROR,
269  "Command was parsed as: flags:[%s] target:%s command:%s arg:%s\n",
270  make_command_flags_str(&pbuf, cmd.flags), cmd.target, cmd.command, cmd.arg);
271  return AVERROR(EINVAL);
272  }
273  if (**buf == ';')
274  break;
275  if (**buf == ',')
276  (*buf)++;
277  }
278 
279  return 0;
280 }
281 
282 #define DELIMS " \f\t\n\r,;"
283 
284 static int parse_interval(Interval *interval, int interval_count,
285  const char **buf, void *log_ctx)
286 {
287  char *intervalstr;
288  int ret;
289 
290  *buf += strspn(*buf, SPACES);
291  if (!**buf)
292  return 0;
293 
294  /* reset data */
295  memset(interval, 0, sizeof(Interval));
296  interval->index = interval_count;
297 
298  /* format: INTERVAL COMMANDS */
299 
300  /* parse interval */
301  intervalstr = av_get_token(buf, DELIMS);
302  if (intervalstr && intervalstr[0]) {
303  char *start, *end;
304 
305  start = av_strtok(intervalstr, "-", &end);
306  if (!start) {
307  ret = AVERROR(EINVAL);
308  av_log(log_ctx, AV_LOG_ERROR,
309  "Invalid interval specification '%s' in interval #%d\n",
310  intervalstr, interval_count);
311  goto end;
312  }
313  if ((ret = av_parse_time(&interval->start_ts, start, 1)) < 0) {
314  av_log(log_ctx, AV_LOG_ERROR,
315  "Invalid start time specification '%s' in interval #%d\n",
316  start, interval_count);
317  goto end;
318  }
319 
320  if (end) {
321  if ((ret = av_parse_time(&interval->end_ts, end, 1)) < 0) {
322  av_log(log_ctx, AV_LOG_ERROR,
323  "Invalid end time specification '%s' in interval #%d\n",
324  end, interval_count);
325  goto end;
326  }
327  } else {
328  interval->end_ts = INT64_MAX;
329  }
330  if (interval->end_ts < interval->start_ts) {
331  av_log(log_ctx, AV_LOG_ERROR,
332  "Invalid end time '%s' in interval #%d: "
333  "cannot be lesser than start time '%s'\n",
334  end, interval_count, start);
335  ret = AVERROR(EINVAL);
336  goto end;
337  }
338  } else {
339  av_log(log_ctx, AV_LOG_ERROR,
340  "No interval specified for interval #%d\n", interval_count);
341  ret = AVERROR(EINVAL);
342  goto end;
343  }
344 
345  /* parse commands */
346  ret = parse_commands(&interval->commands, &interval->nb_commands,
347  interval_count, buf, log_ctx);
348 
349 end:
350  av_free(intervalstr);
351  return ret;
352 }
353 
354 static int parse_intervals(Interval **intervals, int *nb_intervals,
355  const char *buf, void *log_ctx)
356 {
357  int interval_count = 0;
358  int ret, n = 0;
359 
360  *intervals = NULL;
361  *nb_intervals = 0;
362 
363  if (!buf)
364  return 0;
365 
366  while (1) {
367  Interval interval;
368 
369  skip_comments(&buf);
370  if (!(*buf))
371  break;
372 
373  if ((ret = parse_interval(&interval, interval_count, &buf, log_ctx)) < 0)
374  return ret;
375 
376  buf += strspn(buf, SPACES);
377  if (*buf) {
378  if (*buf != ';') {
379  av_log(log_ctx, AV_LOG_ERROR,
380  "Missing terminator or extraneous data found at the end of interval #%d\n",
381  interval_count);
382  return AVERROR(EINVAL);
383  }
384  buf++; /* skip ';' */
385  }
386  interval_count++;
387 
388  /* (re)allocate commands array if required */
389  if (*nb_intervals == n) {
390  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
391  *intervals = av_realloc_f(*intervals, n, 2*sizeof(Interval));
392  if (!*intervals) {
393  av_log(log_ctx, AV_LOG_ERROR,
394  "Could not (re)allocate intervals array\n");
395  return AVERROR(ENOMEM);
396  }
397  }
398 
399  (*intervals)[(*nb_intervals)++] = interval;
400  }
401 
402  return 0;
403 }
404 
405 static int cmp_intervals(const void *a, const void *b)
406 {
407  const Interval *i1 = a;
408  const Interval *i2 = b;
409  return 2 * FFDIFFSIGN(i1->start_ts, i2->start_ts) + FFDIFFSIGN(i1->index, i2->index);
410 }
411 
413 {
414  SendCmdContext *s = ctx->priv;
415  int ret, i, j;
416 
417  if ((!!s->commands_filename + !!s->commands_str) != 1) {
419  "One and only one of the filename or commands options must be specified\n");
420  return AVERROR(EINVAL);
421  }
422 
423  if (s->commands_filename) {
424  uint8_t *file_buf, *buf;
425  size_t file_bufsize;
426  ret = av_file_map(s->commands_filename,
427  &file_buf, &file_bufsize, 0, ctx);
428  if (ret < 0)
429  return ret;
430 
431  /* create a 0-terminated string based on the read file */
432  buf = av_malloc(file_bufsize + 1);
433  if (!buf) {
434  av_file_unmap(file_buf, file_bufsize);
435  return AVERROR(ENOMEM);
436  }
437  memcpy(buf, file_buf, file_bufsize);
438  buf[file_bufsize] = 0;
439  av_file_unmap(file_buf, file_bufsize);
440  s->commands_str = buf;
441  }
442 
443  if ((ret = parse_intervals(&s->intervals, &s->nb_intervals,
444  s->commands_str, ctx)) < 0)
445  return ret;
446 
447  if (s->nb_intervals == 0) {
448  av_log(ctx, AV_LOG_ERROR, "No commands were specified\n");
449  return AVERROR(EINVAL);
450  }
451 
452  qsort(s->intervals, s->nb_intervals, sizeof(Interval), cmp_intervals);
453 
454  av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n");
455  for (i = 0; i < s->nb_intervals; i++) {
456  AVBPrint pbuf;
457  Interval *interval = &s->intervals[i];
458  av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n",
459  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index);
460  for (j = 0; j < interval->nb_commands; j++) {
461  Command *cmd = &interval->commands[j];
463  " [%s] target:%s command:%s arg:%s index:%d\n",
464  make_command_flags_str(&pbuf, cmd->flags), cmd->target, cmd->command, cmd->arg, cmd->index);
465  }
466  }
467 
468  return 0;
469 }
470 
472 {
473  SendCmdContext *s = ctx->priv;
474  int i, j;
475 
476  for (i = 0; i < s->nb_intervals; i++) {
477  Interval *interval = &s->intervals[i];
478  for (j = 0; j < interval->nb_commands; j++) {
479  Command *cmd = &interval->commands[j];
480  av_freep(&cmd->target);
481  av_freep(&cmd->command);
482  av_freep(&cmd->arg);
483  }
484  av_freep(&interval->commands);
485  }
486  av_freep(&s->intervals);
487 }
488 
490 {
491  AVFilterContext *ctx = inlink->dst;
492  SendCmdContext *s = ctx->priv;
493  int64_t ts;
494  int i, j, ret;
495 
496  if (ref->pts == AV_NOPTS_VALUE)
497  goto end;
498 
499  ts = av_rescale_q(ref->pts, inlink->time_base, AV_TIME_BASE_Q);
500 
501 #define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts))
502 
503  for (i = 0; i < s->nb_intervals; i++) {
504  Interval *interval = &s->intervals[i];
505  int flags = 0;
506 
507  if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
509  interval->enabled = 1;
510  }
511  if (interval->enabled && !WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
513  interval->enabled = 0;
514  }
515  if (interval->enabled)
517 
518  if (flags) {
519  AVBPrint pbuf;
521  "[%s] interval #%d start_ts:%f end_ts:%f ts:%f\n",
522  make_command_flags_str(&pbuf, flags), interval->index,
523  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000,
524  (double)ts/1000000);
525 
526  for (j = 0; flags && j < interval->nb_commands; j++) {
527  Command *cmd = &interval->commands[j];
528  char *cmd_arg = cmd->arg;
529  char buf[1024];
530 
531  if (cmd->flags & flags) {
532  if (cmd->flags & COMMAND_FLAG_EXPR) {
533  double var_values[VAR_VARS_NB], res;
534  double start = TS2T(interval->start_ts, AV_TIME_BASE_Q);
535  double end = TS2T(interval->end_ts, AV_TIME_BASE_Q);
536  double current = TS2T(ref->pts, inlink->time_base);
537 
538  var_values[VAR_N] = inlink->frame_count_in;
539 #if FF_API_FRAME_PKT
541  var_values[VAR_POS] = ref->pkt_pos == -1 ? NAN : ref->pkt_pos;
543 #endif
544  var_values[VAR_PTS] = TS2D(ref->pts);
545  var_values[VAR_T] = current;
546  var_values[VAR_TS] = start;
547  var_values[VAR_TE] = end;
548  var_values[VAR_TI] = (current - start) / (end - start);
549  var_values[VAR_W] = ref->width;
550  var_values[VAR_H] = ref->height;
551 
552  if ((ret = av_expr_parse_and_eval(&res, cmd->arg, var_names, var_values,
553  NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
554  av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for command argument.\n", cmd->arg);
555  av_frame_free(&ref);
556  return AVERROR(EINVAL);
557  }
558 
559  cmd_arg = av_asprintf("%g", res);
560  if (!cmd_arg) {
561  av_frame_free(&ref);
562  return AVERROR(ENOMEM);
563  }
564  }
566  "Processing command #%d target:%s command:%s arg:%s\n",
567  cmd->index, cmd->target, cmd->command, cmd_arg);
569  cmd->target, cmd->command, cmd_arg,
570  buf, sizeof(buf),
573  "Command reply for command #%d: ret:%s res:%s\n",
574  cmd->index, av_err2str(ret), buf);
575  if (cmd->flags & COMMAND_FLAG_EXPR)
576  av_freep(&cmd_arg);
577  }
578  }
579  }
580  }
581 
582 end:
583  switch (inlink->type) {
584  case AVMEDIA_TYPE_VIDEO:
585  case AVMEDIA_TYPE_AUDIO:
586  return ff_filter_frame(inlink->dst->outputs[0], ref);
587  }
588 
589  return AVERROR(ENOSYS);
590 }
591 
592 AVFILTER_DEFINE_CLASS_EXT(sendcmd, "(a)sendcmd", options);
593 
594 #if CONFIG_SENDCMD_FILTER
595 
596 static const AVFilterPad sendcmd_inputs[] = {
597  {
598  .name = "default",
599  .type = AVMEDIA_TYPE_VIDEO,
600  .filter_frame = filter_frame,
601  },
602 };
603 
604 const AVFilter ff_vf_sendcmd = {
605  .name = "sendcmd",
606  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
607  .init = init,
608  .uninit = uninit,
609  .priv_size = sizeof(SendCmdContext),
611  FILTER_INPUTS(sendcmd_inputs),
613  .priv_class = &sendcmd_class,
614 };
615 
616 #endif
617 
618 #if CONFIG_ASENDCMD_FILTER
619 
620 static const AVFilterPad asendcmd_inputs[] = {
621  {
622  .name = "default",
623  .type = AVMEDIA_TYPE_AUDIO,
624  .filter_frame = filter_frame,
625  },
626 };
627 
628 const AVFilter ff_af_asendcmd = {
629  .name = "asendcmd",
630  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
631  .priv_class = &sendcmd_class,
632  .init = init,
633  .uninit = uninit,
634  .priv_size = sizeof(SendCmdContext),
636  FILTER_INPUTS(asendcmd_inputs),
638 };
639 
640 #endif
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
AVFILTER_CMD_FLAG_ONE
#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:693
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
WITHIN_INTERVAL
#define WITHIN_INTERVAL(ts, start_ts, end_ts)
var_name
var_name
Definition: noise.c:47
VAR_T
@ VAR_T
Definition: f_sendcmd.c:61
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
make_command_flags_str
static char * make_command_flags_str(AVBPrint *pbuf, int flags)
Definition: f_sendcmd.c:74
VAR_TE
@ VAR_TE
Definition: f_sendcmd.c:67
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
COMMAND_DELIMS
#define COMMAND_DELIMS
Definition: f_sendcmd.c:145
cmp_intervals
static int cmp_intervals(const void *a, const void *b)
Definition: f_sendcmd.c:405
parse_command
static int parse_command(Command *cmd, int cmd_count, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:147
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
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
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:115
VAR_H
@ VAR_H
Definition: f_sendcmd.c:70
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
VAR_TI
@ VAR_TI
Definition: f_sendcmd.c:68
AVOption
AVOption.
Definition: opt.h:357
b
#define b
Definition: input.c:41
DELIMS
#define DELIMS
Definition: f_sendcmd.c:282
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
Interval::index
int index
unique index for these interval commands
Definition: f_sendcmd.c:101
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
video.h
SendCmdContext::commands_str
char * commands_str
Definition: f_sendcmd.c:113
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
COMMAND_FLAG_LEAVE
#define COMMAND_FLAG_LEAVE
Definition: f_sendcmd.c:41
Command::target
char * target
Definition: f_sendcmd.c:94
av_file_map
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:55
Command::command
char * command
Definition: f_sendcmd.c:94
fail
#define fail()
Definition: checkasm.h:182
AV_BPRINT_SIZE_AUTOMATIC
#define AV_BPRINT_SIZE_AUTOMATIC
Interval::nb_commands
int nb_commands
Definition: f_sendcmd.c:103
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
FFDIFFSIGN
#define FFDIFFSIGN(x, y)
Comparator.
Definition: macros.h:45
OFFSET
#define OFFSET(x)
Definition: f_sendcmd.c:116
TS2T
#define TS2T(ts, tb)
Definition: internal.h:259
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_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
s
#define s(width, name)
Definition: cbs_vp9.c:198
VAR_TS
@ VAR_TS
Definition: f_sendcmd.c:66
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
COMMAND_FLAG_ENTER
#define COMMAND_FLAG_ENTER
Definition: f_sendcmd.c:40
av_strtok
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:178
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:49
av_rescale_q
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
parse_interval
static int parse_interval(Interval *interval, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:284
Command
Definition: f_sendcmd.c:92
SendCmdContext::commands_filename
char * commands_filename
Definition: f_sendcmd.c:112
NAN
#define NAN
Definition: mathematics.h:115
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
av_file_unmap
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
Definition: file.c:146
options
static const AVOption options[]
Definition: f_sendcmd.c:118
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:32
FLAGS
#define FLAGS
Definition: f_sendcmd.c:117
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
TS2D
#define TS2D(ts)
Definition: internal.h:258
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: f_sendcmd.c:471
NULL
#define NULL
Definition: coverity.c:32
SendCmdContext
Definition: f_sendcmd.c:107
VAR_POS
@ VAR_POS
Definition: noise.c:56
cmds
static const char *const cmds[]
Definition: jacosubdec.c:72
parseutils.h
ff_audio_default_filterpad
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
Definition: audio.c:33
av_parse_time
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:589
Interval::end_ts
int64_t end_ts
end timestamp expressed as microseconds units
Definition: f_sendcmd.c:100
VAR_VARS_NB
@ VAR_VARS_NB
Definition: f_sendcmd.c:71
var_names
static const char *const var_names[]
Definition: f_sendcmd.c:44
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
Definition: f_sendcmd.c:489
VAR_W
@ VAR_W
Definition: f_sendcmd.c:69
VAR_PTS
@ VAR_PTS
Definition: f_sendcmd.c:65
eval.h
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_expr_parse_and_eval
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:803
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
SPACES
#define SPACES
Definition: f_sendcmd.c:126
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
init
static av_cold int init(AVFilterContext *ctx)
Definition: f_sendcmd.c:412
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
Interval
Definition: f_sendcmd.c:98
internal.h
Interval::commands
Command * commands
Definition: f_sendcmd.c:102
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
parse_commands
static int parse_commands(Command **cmds, int *nb_cmds, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:232
ff_vf_sendcmd
const AVFilter ff_vf_sendcmd
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
skip_comments
static void skip_comments(const char **buf)
Definition: f_sendcmd.c:128
AVFilter
Filter definition.
Definition: avfilter.h:166
ret
ret
Definition: filter_design.txt:187
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
Command::arg
char * arg
Definition: f_sendcmd.c:94
COMMAND_FLAG_EXPR
#define COMMAND_FLAG_EXPR
Definition: f_sendcmd.c:42
Command::flags
int flags
Definition: f_sendcmd.c:93
Command::index
int index
Definition: f_sendcmd.c:95
avfilter.h
av_get_token
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:143
SendCmdContext::intervals
Interval * intervals
Definition: f_sendcmd.c:109
AVFILTER_FLAG_METADATA_ONLY
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition: avfilter.h:133
VAR_N
@ VAR_N
Definition: f_sendcmd.c:60
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
ff_af_asendcmd
const AVFilter ff_af_asendcmd
file.h
AVFILTER_DEFINE_CLASS_EXT
AVFILTER_DEFINE_CLASS_EXT(sendcmd, "(a)sendcmd", options)
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
Interval::enabled
int enabled
current time detected inside this interval
Definition: f_sendcmd.c:104
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
audio.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_strlcpy
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:85
avfilter_graph_send_command
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.
Definition: avfiltergraph.c:1261
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_bprint_chars
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:145
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:249
parse_intervals
static int parse_intervals(Interval **intervals, int *nb_intervals, const char *buf, void *log_ctx)
Definition: f_sendcmd.c:354
Interval::start_ts
int64_t start_ts
start timestamp expressed as microseconds units
Definition: f_sendcmd.c:99
SendCmdContext::nb_intervals
int nb_intervals
Definition: f_sendcmd.c:110