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