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