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 /**
142  * Clears fields and frees the buffers used by @p cmd
143  */
144 static void clear_command(Command *cmd)
145 {
146  cmd->flags = 0;
147  cmd->index = 0;
148  av_freep(&cmd->target);
149  av_freep(&cmd->command);
150  av_freep(&cmd->arg);
151 }
152 
153 static int parse_command(Command *cmd, int cmd_count, int interval_count,
154  const char **buf, void *log_ctx)
155 {
156  int ret;
157 
158  memset(cmd, 0, sizeof(Command));
159  cmd->index = cmd_count;
160 
161  /* format: [FLAGS] target command arg */
162  *buf += strspn(*buf, SPACES);
163 
164  /* parse flags */
165  if (**buf == '[') {
166  (*buf)++; /* skip "[" */
167 
168  while (**buf) {
169  int len = strcspn(*buf, "|+]");
170 
171  if (!strncmp(*buf, "enter", strlen("enter"))) cmd->flags |= COMMAND_FLAG_ENTER;
172  else if (!strncmp(*buf, "leave", strlen("leave"))) cmd->flags |= COMMAND_FLAG_LEAVE;
173  else if (!strncmp(*buf, "expr", strlen("expr"))) cmd->flags |= COMMAND_FLAG_EXPR;
174  else {
175  char flag_buf[64];
176  av_strlcpy(flag_buf, *buf, sizeof(flag_buf));
177  av_log(log_ctx, AV_LOG_ERROR,
178  "Unknown flag '%s' in interval #%d, command #%d\n",
179  flag_buf, interval_count, cmd_count);
180  return AVERROR(EINVAL);
181  }
182  *buf += len;
183  if (**buf == ']')
184  break;
185  if (!strspn(*buf, "+|")) {
186  av_log(log_ctx, AV_LOG_ERROR,
187  "Invalid flags char '%c' in interval #%d, command #%d\n",
188  **buf, interval_count, cmd_count);
189  return AVERROR(EINVAL);
190  }
191  if (**buf)
192  (*buf)++;
193  }
194 
195  if (**buf != ']') {
196  av_log(log_ctx, AV_LOG_ERROR,
197  "Missing flag terminator or extraneous data found at the end of flags "
198  "in interval #%d, command #%d\n", interval_count, cmd_count);
199  return AVERROR(EINVAL);
200  }
201  (*buf)++; /* skip "]" */
202  } else {
203  cmd->flags = COMMAND_FLAG_ENTER;
204  }
205 
206  *buf += strspn(*buf, SPACES);
207  cmd->target = av_get_token(buf, COMMAND_DELIMS);
208  if (!cmd->target || !cmd->target[0]) {
209  av_log(log_ctx, AV_LOG_ERROR,
210  "No target specified in interval #%d, command #%d\n",
211  interval_count, cmd_count);
212  ret = AVERROR(EINVAL);
213  goto fail;
214  }
215 
216  *buf += strspn(*buf, SPACES);
217  cmd->command = av_get_token(buf, COMMAND_DELIMS);
218  if (!cmd->command || !cmd->command[0]) {
219  av_log(log_ctx, AV_LOG_ERROR,
220  "No command specified in interval #%d, command #%d\n",
221  interval_count, cmd_count);
222  ret = AVERROR(EINVAL);
223  goto fail;
224  }
225 
226  *buf += strspn(*buf, SPACES);
227  cmd->arg = av_get_token(buf, COMMAND_DELIMS);
228 
229  return 1;
230 
231 fail:
232  clear_command(cmd);
233  return ret;
234 }
235 
236 static int parse_commands(Command **cmds, int *nb_cmds, int interval_count,
237  const char **buf, void *log_ctx)
238 {
239  int cmd_count = 0;
240  int ret, n = 0;
241  AVBPrint pbuf;
242 
243  *cmds = NULL;
244  *nb_cmds = 0;
245 
246  while (**buf) {
247  Command cmd;
248 
249  if ((ret = parse_command(&cmd, cmd_count, interval_count, buf, log_ctx)) < 0)
250  return ret;
251  cmd_count++;
252 
253  /* (re)allocate commands array if required */
254  if (*nb_cmds == n) {
255  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
256  *cmds = av_realloc_f(*cmds, n, 2*sizeof(Command));
257  if (!*cmds) {
258  av_log(log_ctx, AV_LOG_ERROR,
259  "Could not (re)allocate command array\n");
260  clear_command(&cmd);
261  return AVERROR(ENOMEM);
262  }
263  }
264 
265  (*cmds)[(*nb_cmds)++] = cmd;
266 
267  *buf += strspn(*buf, SPACES);
268  if (**buf && **buf != ';' && **buf != ',') {
269  av_log(log_ctx, AV_LOG_ERROR,
270  "Missing separator or extraneous data found at the end of "
271  "interval #%d, in command #%d\n",
272  interval_count, cmd_count);
273  av_log(log_ctx, AV_LOG_ERROR,
274  "Command was parsed as: flags:[%s] target:%s command:%s arg:%s\n",
275  make_command_flags_str(&pbuf, cmd.flags), cmd.target, cmd.command, cmd.arg);
276  return AVERROR(EINVAL);
277  }
278  if (**buf == ';')
279  break;
280  if (**buf == ',')
281  (*buf)++;
282  }
283 
284  return 0;
285 }
286 
287 #define DELIMS " \f\t\n\r,;"
288 
289 static int parse_interval(Interval *interval, int interval_count,
290  const char **buf, void *log_ctx)
291 {
292  char *intervalstr;
293  int ret;
294 
295  *buf += strspn(*buf, SPACES);
296  if (!**buf)
297  return 0;
298 
299  /* reset data */
300  memset(interval, 0, sizeof(Interval));
301  interval->index = interval_count;
302 
303  /* format: INTERVAL COMMANDS */
304 
305  /* parse interval */
306  intervalstr = av_get_token(buf, DELIMS);
307  if (intervalstr && intervalstr[0]) {
308  char *start, *end;
309 
310  start = av_strtok(intervalstr, "-", &end);
311  if (!start) {
312  ret = AVERROR(EINVAL);
313  av_log(log_ctx, AV_LOG_ERROR,
314  "Invalid interval specification '%s' in interval #%d\n",
315  intervalstr, interval_count);
316  goto end;
317  }
318  if ((ret = av_parse_time(&interval->start_ts, start, 1)) < 0) {
319  av_log(log_ctx, AV_LOG_ERROR,
320  "Invalid start time specification '%s' in interval #%d\n",
321  start, interval_count);
322  goto end;
323  }
324 
325  if (end) {
326  if ((ret = av_parse_time(&interval->end_ts, end, 1)) < 0) {
327  av_log(log_ctx, AV_LOG_ERROR,
328  "Invalid end time specification '%s' in interval #%d\n",
329  end, interval_count);
330  goto end;
331  }
332  } else {
333  interval->end_ts = INT64_MAX;
334  }
335  if (interval->end_ts < interval->start_ts) {
336  av_log(log_ctx, AV_LOG_ERROR,
337  "Invalid end time '%s' in interval #%d: "
338  "cannot be lesser than start time '%s'\n",
339  end, interval_count, start);
340  ret = AVERROR(EINVAL);
341  goto end;
342  }
343  } else {
344  av_log(log_ctx, AV_LOG_ERROR,
345  "No interval specified for interval #%d\n", interval_count);
346  ret = AVERROR(EINVAL);
347  goto end;
348  }
349 
350  /* parse commands */
351  ret = parse_commands(&interval->commands, &interval->nb_commands,
352  interval_count, buf, log_ctx);
353 
354 end:
355  av_free(intervalstr);
356  return ret;
357 }
358 
359 static int parse_intervals(Interval **intervals, int *nb_intervals,
360  const char *buf, void *log_ctx)
361 {
362  int interval_count = 0;
363  int ret, n = 0;
364 
365  *intervals = NULL;
366  *nb_intervals = 0;
367 
368  if (!buf)
369  return 0;
370 
371  while (1) {
372  Interval interval;
373 
374  skip_comments(&buf);
375  if (!(*buf))
376  break;
377 
378  if ((ret = parse_interval(&interval, interval_count, &buf, log_ctx)) < 0)
379  return ret;
380 
381  buf += strspn(buf, SPACES);
382  if (*buf) {
383  if (*buf != ';') {
384  av_log(log_ctx, AV_LOG_ERROR,
385  "Missing terminator or extraneous data found at the end of interval #%d\n",
386  interval_count);
387  return AVERROR(EINVAL);
388  }
389  buf++; /* skip ';' */
390  }
391  interval_count++;
392 
393  /* (re)allocate commands array if required */
394  if (*nb_intervals == n) {
395  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
396  *intervals = av_realloc_f(*intervals, n, 2*sizeof(Interval));
397  if (!*intervals) {
398  av_log(log_ctx, AV_LOG_ERROR,
399  "Could not (re)allocate intervals array\n");
400  return AVERROR(ENOMEM);
401  }
402  }
403 
404  (*intervals)[(*nb_intervals)++] = interval;
405  }
406 
407  return 0;
408 }
409 
410 static int cmp_intervals(const void *a, const void *b)
411 {
412  const Interval *i1 = a;
413  const Interval *i2 = b;
414  return 2 * FFDIFFSIGN(i1->start_ts, i2->start_ts) + FFDIFFSIGN(i1->index, i2->index);
415 }
416 
418 {
419  SendCmdContext *s = ctx->priv;
420  int ret, i, j;
421 
422  if ((!!s->commands_filename + !!s->commands_str) != 1) {
424  "One and only one of the filename or commands options must be specified\n");
425  return AVERROR(EINVAL);
426  }
427 
428  if (s->commands_filename) {
429  uint8_t *file_buf, *buf;
430  size_t file_bufsize;
431  ret = av_file_map(s->commands_filename,
432  &file_buf, &file_bufsize, 0, ctx);
433  if (ret < 0)
434  return ret;
435 
436  /* create a 0-terminated string based on the read file */
437  buf = av_malloc(file_bufsize + 1);
438  if (!buf) {
439  av_file_unmap(file_buf, file_bufsize);
440  return AVERROR(ENOMEM);
441  }
442  memcpy(buf, file_buf, file_bufsize);
443  buf[file_bufsize] = 0;
444  av_file_unmap(file_buf, file_bufsize);
445  s->commands_str = buf;
446  }
447 
448  if ((ret = parse_intervals(&s->intervals, &s->nb_intervals,
449  s->commands_str, ctx)) < 0)
450  return ret;
451 
452  if (s->nb_intervals == 0) {
453  av_log(ctx, AV_LOG_ERROR, "No commands were specified\n");
454  return AVERROR(EINVAL);
455  }
456 
457  qsort(s->intervals, s->nb_intervals, sizeof(Interval), cmp_intervals);
458 
459  av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n");
460  for (i = 0; i < s->nb_intervals; i++) {
461  AVBPrint pbuf;
462  Interval *interval = &s->intervals[i];
463  av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n",
464  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index);
465  for (j = 0; j < interval->nb_commands; j++) {
466  Command *cmd = &interval->commands[j];
468  " [%s] target:%s command:%s arg:%s index:%d\n",
469  make_command_flags_str(&pbuf, cmd->flags), cmd->target, cmd->command, cmd->arg, cmd->index);
470  }
471  }
472 
473  return 0;
474 }
475 
477 {
478  SendCmdContext *s = ctx->priv;
479  int i, j;
480 
481  for (i = 0; i < s->nb_intervals; i++) {
482  Interval *interval = &s->intervals[i];
483  for (j = 0; j < interval->nb_commands; j++) {
484  Command *cmd = &interval->commands[j];
485  clear_command(cmd);
486  }
487  av_freep(&interval->commands);
488  }
489  av_freep(&s->intervals);
490 }
491 
493 {
495  AVFilterContext *ctx = inlink->dst;
496  SendCmdContext *s = ctx->priv;
497  int64_t ts;
498  int i, j, ret;
499 
500  if (ref->pts == AV_NOPTS_VALUE)
501  goto end;
502 
503  ts = av_rescale_q(ref->pts, inlink->time_base, AV_TIME_BASE_Q);
504 
505 #define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts))
506 
507  for (i = 0; i < s->nb_intervals; i++) {
508  Interval *interval = &s->intervals[i];
509  int flags = 0;
510 
511  if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
513  interval->enabled = 1;
514  }
515  if (interval->enabled && !WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
517  interval->enabled = 0;
518  }
519  if (interval->enabled)
521 
522  if (flags) {
523  AVBPrint pbuf;
525  "[%s] interval #%d start_ts:%f end_ts:%f ts:%f\n",
526  make_command_flags_str(&pbuf, flags), interval->index,
527  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000,
528  (double)ts/1000000);
529 
530  for (j = 0; flags && j < interval->nb_commands; j++) {
531  Command *cmd = &interval->commands[j];
532  char *cmd_arg = cmd->arg;
533  char buf[1024];
534 
535  if (cmd->flags & flags) {
536  if (cmd->flags & COMMAND_FLAG_EXPR) {
537  double var_values[VAR_VARS_NB], res;
538  double start = TS2T(interval->start_ts, AV_TIME_BASE_Q);
539  double end = TS2T(interval->end_ts, AV_TIME_BASE_Q);
540  double current = TS2T(ref->pts, inlink->time_base);
541 
542  var_values[VAR_N] = inl->frame_count_in;
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 FFFilter ff_vf_sendcmd = {
604  .p.name = "sendcmd",
605  .p.description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
606  .p.flags = AVFILTER_FLAG_METADATA_ONLY,
607  .p.priv_class = &sendcmd_class,
608  .init = init,
609  .uninit = uninit,
610  .priv_size = sizeof(SendCmdContext),
611  FILTER_INPUTS(sendcmd_inputs),
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 FFFilter ff_af_asendcmd = {
628  .p.name = "asendcmd",
629  .p.description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
630  .p.priv_class = &sendcmd_class,
631  .p.flags = AVFILTER_FLAG_METADATA_ONLY,
632  .init = init,
633  .uninit = uninit,
634  .priv_size = sizeof(SendCmdContext),
635  FILTER_INPUTS(asendcmd_inputs),
637 };
638 
639 #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:462
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:1062
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:410
parse_command
static int parse_command(Command *cmd, int cmd_count, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:153
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
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:287
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
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:215
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:196
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:210
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:201
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:231
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:289
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:76
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: f_sendcmd.c:476
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:492
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:247
TS2T
#define TS2T(ts, tb)
Definition: filters.h:481
init
static av_cold int init(AVFilterContext *ctx)
Definition: f_sendcmd.c:417
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:236
clear_command
static void clear_command(Command *cmd)
Clears fields and frees the buffers used by cmd.
Definition: f_sendcmd.c:144
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:178
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:269
Interval::enabled
int enabled
current time detected inside this interval
Definition: f_sendcmd.c:98
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
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:359
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