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