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