FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups 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 "libavutil/avstring.h"
27 #include "libavutil/bprint.h"
28 #include "libavutil/file.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/parseutils.h"
31 #include "avfilter.h"
32 #include "internal.h"
33 #include "avfiltergraph.h"
34 #include "audio.h"
35 #include "video.h"
36 
37 #define COMMAND_FLAG_ENTER 1
38 #define COMMAND_FLAG_LEAVE 2
39 
40 static inline char *make_command_flags_str(AVBPrint *pbuf, int flags)
41 {
42  static const char * const flag_strings[] = { "enter", "leave" };
43  int i, is_first = 1;
44 
46  for (i = 0; i < FF_ARRAY_ELEMS(flag_strings); i++) {
47  if (flags & 1<<i) {
48  if (!is_first)
49  av_bprint_chars(pbuf, '+', 1);
50  av_bprintf(pbuf, "%s", flag_strings[i]);
51  is_first = 0;
52  }
53  }
54 
55  return pbuf->str;
56 }
57 
58 typedef struct {
59  int flags;
60  char *target, *command, *arg;
61  int index;
62 } Command;
63 
64 typedef struct {
65  int64_t start_ts; ///< start timestamp expressed as microseconds units
66  int64_t end_ts; ///< end timestamp expressed as microseconds units
67  int index; ///< unique index for these interval commands
70  int enabled; ///< current time detected inside this interval
71 } Interval;
72 
73 typedef struct {
74  const AVClass *class;
77 
79  char *commands_str;
81 
82 #define OFFSET(x) offsetof(SendCmdContext, x)
83 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM
84 static const AVOption options[] = {
85  { "commands", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
86  { "c", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
87  { "filename", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
88  { "f", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
89  { NULL }
90 };
91 
92 #define SPACES " \f\t\n\r"
93 
94 static void skip_comments(const char **buf)
95 {
96  while (**buf) {
97  /* skip leading spaces */
98  *buf += strspn(*buf, SPACES);
99  if (**buf != '#')
100  break;
101 
102  (*buf)++;
103 
104  /* skip comment until the end of line */
105  *buf += strcspn(*buf, "\n");
106  if (**buf)
107  (*buf)++;
108  }
109 }
110 
111 #define COMMAND_DELIMS " \f\t\n\r,;"
112 
113 static int parse_command(Command *cmd, int cmd_count, int interval_count,
114  const char **buf, void *log_ctx)
115 {
116  int ret;
117 
118  memset(cmd, 0, sizeof(Command));
119  cmd->index = cmd_count;
120 
121  /* format: [FLAGS] target command arg */
122  *buf += strspn(*buf, SPACES);
123 
124  /* parse flags */
125  if (**buf == '[') {
126  (*buf)++; /* skip "[" */
127 
128  while (**buf) {
129  int len = strcspn(*buf, "|+]");
130 
131  if (!strncmp(*buf, "enter", strlen("enter"))) cmd->flags |= COMMAND_FLAG_ENTER;
132  else if (!strncmp(*buf, "leave", strlen("leave"))) cmd->flags |= COMMAND_FLAG_LEAVE;
133  else {
134  char flag_buf[64];
135  av_strlcpy(flag_buf, *buf, sizeof(flag_buf));
136  av_log(log_ctx, AV_LOG_ERROR,
137  "Unknown flag '%s' in interval #%d, command #%d\n",
138  flag_buf, interval_count, cmd_count);
139  return AVERROR(EINVAL);
140  }
141  *buf += len;
142  if (**buf == ']')
143  break;
144  if (!strspn(*buf, "+|")) {
145  av_log(log_ctx, AV_LOG_ERROR,
146  "Invalid flags char '%c' in interval #%d, command #%d\n",
147  **buf, interval_count, cmd_count);
148  return AVERROR(EINVAL);
149  }
150  if (**buf)
151  (*buf)++;
152  }
153 
154  if (**buf != ']') {
155  av_log(log_ctx, AV_LOG_ERROR,
156  "Missing flag terminator or extraneous data found at the end of flags "
157  "in interval #%d, command #%d\n", interval_count, cmd_count);
158  return AVERROR(EINVAL);
159  }
160  (*buf)++; /* skip "]" */
161  } else {
162  cmd->flags = COMMAND_FLAG_ENTER;
163  }
164 
165  *buf += strspn(*buf, SPACES);
166  cmd->target = av_get_token(buf, COMMAND_DELIMS);
167  if (!cmd->target || !cmd->target[0]) {
168  av_log(log_ctx, AV_LOG_ERROR,
169  "No target specified in interval #%d, command #%d\n",
170  interval_count, cmd_count);
171  ret = AVERROR(EINVAL);
172  goto fail;
173  }
174 
175  *buf += strspn(*buf, SPACES);
176  cmd->command = av_get_token(buf, COMMAND_DELIMS);
177  if (!cmd->command || !cmd->command[0]) {
178  av_log(log_ctx, AV_LOG_ERROR,
179  "No command specified in interval #%d, command #%d\n",
180  interval_count, cmd_count);
181  ret = AVERROR(EINVAL);
182  goto fail;
183  }
184 
185  *buf += strspn(*buf, SPACES);
186  cmd->arg = av_get_token(buf, COMMAND_DELIMS);
187 
188  return 1;
189 
190 fail:
191  av_freep(&cmd->target);
192  av_freep(&cmd->command);
193  av_freep(&cmd->arg);
194  return ret;
195 }
196 
197 static int parse_commands(Command **cmds, int *nb_cmds, int interval_count,
198  const char **buf, void *log_ctx)
199 {
200  int cmd_count = 0;
201  int ret, n = 0;
202  AVBPrint pbuf;
203 
204  *cmds = NULL;
205  *nb_cmds = 0;
206 
207  while (**buf) {
208  Command cmd;
209 
210  if ((ret = parse_command(&cmd, cmd_count, interval_count, buf, log_ctx)) < 0)
211  return ret;
212  cmd_count++;
213 
214  /* (re)allocate commands array if required */
215  if (*nb_cmds == n) {
216  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
217  *cmds = av_realloc_f(*cmds, n, 2*sizeof(Command));
218  if (!*cmds) {
219  av_log(log_ctx, AV_LOG_ERROR,
220  "Could not (re)allocate command array\n");
221  return AVERROR(ENOMEM);
222  }
223  }
224 
225  (*cmds)[(*nb_cmds)++] = cmd;
226 
227  *buf += strspn(*buf, SPACES);
228  if (**buf && **buf != ';' && **buf != ',') {
229  av_log(log_ctx, AV_LOG_ERROR,
230  "Missing separator or extraneous data found at the end of "
231  "interval #%d, in command #%d\n",
232  interval_count, cmd_count);
233  av_log(log_ctx, AV_LOG_ERROR,
234  "Command was parsed as: flags:[%s] target:%s command:%s arg:%s\n",
235  make_command_flags_str(&pbuf, cmd.flags), cmd.target, cmd.command, cmd.arg);
236  return AVERROR(EINVAL);
237  }
238  if (**buf == ';')
239  break;
240  if (**buf == ',')
241  (*buf)++;
242  }
243 
244  return 0;
245 }
246 
247 #define DELIMS " \f\t\n\r,;"
248 
249 static int parse_interval(Interval *interval, int interval_count,
250  const char **buf, void *log_ctx)
251 {
252  char *intervalstr;
253  int ret;
254 
255  *buf += strspn(*buf, SPACES);
256  if (!**buf)
257  return 0;
258 
259  /* reset data */
260  memset(interval, 0, sizeof(Interval));
261  interval->index = interval_count;
262 
263  /* format: INTERVAL COMMANDS */
264 
265  /* parse interval */
266  intervalstr = av_get_token(buf, DELIMS);
267  if (intervalstr && intervalstr[0]) {
268  char *start, *end;
269 
270  start = av_strtok(intervalstr, "-", &end);
271  if ((ret = av_parse_time(&interval->start_ts, start, 1)) < 0) {
272  av_log(log_ctx, AV_LOG_ERROR,
273  "Invalid start time specification '%s' in interval #%d\n",
274  start, interval_count);
275  goto end;
276  }
277 
278  if (end) {
279  if ((ret = av_parse_time(&interval->end_ts, end, 1)) < 0) {
280  av_log(log_ctx, AV_LOG_ERROR,
281  "Invalid end time specification '%s' in interval #%d\n",
282  end, interval_count);
283  goto end;
284  }
285  } else {
286  interval->end_ts = INT64_MAX;
287  }
288  if (interval->end_ts < interval->start_ts) {
289  av_log(log_ctx, AV_LOG_ERROR,
290  "Invalid end time '%s' in interval #%d: "
291  "cannot be lesser than start time '%s'\n",
292  end, interval_count, start);
293  ret = AVERROR(EINVAL);
294  goto end;
295  }
296  } else {
297  av_log(log_ctx, AV_LOG_ERROR,
298  "No interval specified for interval #%d\n", interval_count);
299  ret = AVERROR(EINVAL);
300  goto end;
301  }
302 
303  /* parse commands */
304  ret = parse_commands(&interval->commands, &interval->nb_commands,
305  interval_count, buf, log_ctx);
306 
307 end:
308  av_free(intervalstr);
309  return ret;
310 }
311 
312 static int parse_intervals(Interval **intervals, int *nb_intervals,
313  const char *buf, void *log_ctx)
314 {
315  int interval_count = 0;
316  int ret, n = 0;
317 
318  *intervals = NULL;
319  *nb_intervals = 0;
320 
321  if (!buf)
322  return 0;
323 
324  while (1) {
325  Interval interval;
326 
327  skip_comments(&buf);
328  if (!(*buf))
329  break;
330 
331  if ((ret = parse_interval(&interval, interval_count, &buf, log_ctx)) < 0)
332  return ret;
333 
334  buf += strspn(buf, SPACES);
335  if (*buf) {
336  if (*buf != ';') {
337  av_log(log_ctx, AV_LOG_ERROR,
338  "Missing terminator or extraneous data found at the end of interval #%d\n",
339  interval_count);
340  return AVERROR(EINVAL);
341  }
342  buf++; /* skip ';' */
343  }
344  interval_count++;
345 
346  /* (re)allocate commands array if required */
347  if (*nb_intervals == n) {
348  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
349  *intervals = av_realloc_f(*intervals, n, 2*sizeof(Interval));
350  if (!*intervals) {
351  av_log(log_ctx, AV_LOG_ERROR,
352  "Could not (re)allocate intervals array\n");
353  return AVERROR(ENOMEM);
354  }
355  }
356 
357  (*intervals)[(*nb_intervals)++] = interval;
358  }
359 
360  return 0;
361 }
362 
363 static int cmp_intervals(const void *a, const void *b)
364 {
365  const Interval *i1 = a;
366  const Interval *i2 = b;
367  int64_t ts_diff = i1->start_ts - i2->start_ts;
368  int ret;
369 
370  ret = ts_diff > 0 ? 1 : ts_diff < 0 ? -1 : 0;
371  return ret == 0 ? i1->index - i2->index : ret;
372 }
373 
374 static av_cold int init(AVFilterContext *ctx)
375 {
376  SendCmdContext *sendcmd = ctx->priv;
377  int ret, i, j;
378 
379  if ((!!sendcmd->commands_filename + !!sendcmd->commands_str) != 1) {
380  av_log(ctx, AV_LOG_ERROR,
381  "One and only one of the filename or commands options must be specified\n");
382  return AVERROR(EINVAL);
383  }
384 
385  if (sendcmd->commands_filename) {
386  uint8_t *file_buf, *buf;
387  size_t file_bufsize;
388  ret = av_file_map(sendcmd->commands_filename,
389  &file_buf, &file_bufsize, 0, ctx);
390  if (ret < 0)
391  return ret;
392 
393  /* create a 0-terminated string based on the read file */
394  buf = av_malloc(file_bufsize + 1);
395  if (!buf) {
396  av_file_unmap(file_buf, file_bufsize);
397  return AVERROR(ENOMEM);
398  }
399  memcpy(buf, file_buf, file_bufsize);
400  buf[file_bufsize] = 0;
401  av_file_unmap(file_buf, file_bufsize);
402  sendcmd->commands_str = buf;
403  }
404 
405  if ((ret = parse_intervals(&sendcmd->intervals, &sendcmd->nb_intervals,
406  sendcmd->commands_str, ctx)) < 0)
407  return ret;
408 
409  if (sendcmd->nb_intervals == 0) {
410  av_log(ctx, AV_LOG_ERROR, "No commands were specified\n");
411  return AVERROR(EINVAL);
412  }
413 
414  qsort(sendcmd->intervals, sendcmd->nb_intervals, sizeof(Interval), cmp_intervals);
415 
416  av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n");
417  for (i = 0; i < sendcmd->nb_intervals; i++) {
418  AVBPrint pbuf;
419  Interval *interval = &sendcmd->intervals[i];
420  av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n",
421  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index);
422  for (j = 0; j < interval->nb_commands; j++) {
423  Command *cmd = &interval->commands[j];
424  av_log(ctx, AV_LOG_VERBOSE,
425  " [%s] target:%s command:%s arg:%s index:%d\n",
426  make_command_flags_str(&pbuf, cmd->flags), cmd->target, cmd->command, cmd->arg, cmd->index);
427  }
428  }
429 
430  return 0;
431 }
432 
433 static av_cold void uninit(AVFilterContext *ctx)
434 {
435  SendCmdContext *sendcmd = ctx->priv;
436  int i, j;
437 
438  for (i = 0; i < sendcmd->nb_intervals; i++) {
439  Interval *interval = &sendcmd->intervals[i];
440  for (j = 0; j < interval->nb_commands; j++) {
441  Command *cmd = &interval->commands[j];
442  av_freep(&cmd->target);
443  av_freep(&cmd->command);
444  av_freep(&cmd->arg);
445  }
446  av_freep(&interval->commands);
447  }
448  av_freep(&sendcmd->intervals);
449 }
450 
451 static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
452 {
453  AVFilterContext *ctx = inlink->dst;
454  SendCmdContext *sendcmd = ctx->priv;
455  int64_t ts;
456  int i, j, ret;
457 
458  if (ref->pts == AV_NOPTS_VALUE)
459  goto end;
460 
461  ts = av_rescale_q(ref->pts, inlink->time_base, AV_TIME_BASE_Q);
462 
463 #define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts))
464 
465  for (i = 0; i < sendcmd->nb_intervals; i++) {
466  Interval *interval = &sendcmd->intervals[i];
467  int flags = 0;
468 
469  if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
470  flags += COMMAND_FLAG_ENTER;
471  interval->enabled = 1;
472  }
473  if (interval->enabled && !WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
474  flags += COMMAND_FLAG_LEAVE;
475  interval->enabled = 0;
476  }
477 
478  if (flags) {
479  AVBPrint pbuf;
480  av_log(ctx, AV_LOG_VERBOSE,
481  "[%s] interval #%d start_ts:%f end_ts:%f ts:%f\n",
482  make_command_flags_str(&pbuf, flags), interval->index,
483  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000,
484  (double)ts/1000000);
485 
486  for (j = 0; flags && j < interval->nb_commands; j++) {
487  Command *cmd = &interval->commands[j];
488  char buf[1024];
489 
490  if (cmd->flags & flags) {
491  av_log(ctx, AV_LOG_VERBOSE,
492  "Processing command #%d target:%s command:%s arg:%s\n",
493  cmd->index, cmd->target, cmd->command, cmd->arg);
494  ret = avfilter_graph_send_command(inlink->graph,
495  cmd->target, cmd->command, cmd->arg,
496  buf, sizeof(buf),
498  av_log(ctx, AV_LOG_VERBOSE,
499  "Command reply for command #%d: ret:%s res:%s\n",
500  cmd->index, av_err2str(ret), buf);
501  }
502  }
503  }
504  }
505 
506 end:
507  switch (inlink->type) {
508  case AVMEDIA_TYPE_VIDEO:
509  case AVMEDIA_TYPE_AUDIO:
510  return ff_filter_frame(inlink->dst->outputs[0], ref);
511  }
512 
513  return AVERROR(ENOSYS);
514 }
515 
516 #if CONFIG_SENDCMD_FILTER
517 
518 #define sendcmd_options options
519 AVFILTER_DEFINE_CLASS(sendcmd);
520 
521 static const AVFilterPad sendcmd_inputs[] = {
522  {
523  .name = "default",
524  .type = AVMEDIA_TYPE_VIDEO,
525  .filter_frame = filter_frame,
526  },
527  { NULL }
528 };
529 
530 static const AVFilterPad sendcmd_outputs[] = {
531  {
532  .name = "default",
533  .type = AVMEDIA_TYPE_VIDEO,
534  },
535  { NULL }
536 };
537 
538 AVFilter ff_vf_sendcmd = {
539  .name = "sendcmd",
540  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
541  .init = init,
542  .uninit = uninit,
543  .priv_size = sizeof(SendCmdContext),
544  .inputs = sendcmd_inputs,
545  .outputs = sendcmd_outputs,
546  .priv_class = &sendcmd_class,
547 };
548 
549 #endif
550 
551 #if CONFIG_ASENDCMD_FILTER
552 
553 #define asendcmd_options options
554 AVFILTER_DEFINE_CLASS(asendcmd);
555 
556 static const AVFilterPad asendcmd_inputs[] = {
557  {
558  .name = "default",
559  .type = AVMEDIA_TYPE_AUDIO,
560  .filter_frame = filter_frame,
561  },
562  { NULL }
563 };
564 
565 static const AVFilterPad asendcmd_outputs[] = {
566  {
567  .name = "default",
568  .type = AVMEDIA_TYPE_AUDIO,
569  },
570  { NULL }
571 };
572 
573 AVFilter ff_af_asendcmd = {
574  .name = "asendcmd",
575  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
576  .init = init,
577  .uninit = uninit,
578  .priv_size = sizeof(SendCmdContext),
579  .inputs = asendcmd_inputs,
580  .outputs = asendcmd_outputs,
581  .priv_class = &asendcmd_class,
582 };
583 
584 #endif
#define NULL
Definition: coverity.c:32
#define DELIMS
Definition: f_sendcmd.c:247
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
#define av_realloc_f(p, o, n)
static int cmp_intervals(const void *a, const void *b)
Definition: f_sendcmd.c:363
AVOption.
Definition: opt.h:255
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:248
Main libavfilter public API header.
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:554
int nb_intervals
Definition: f_sendcmd.c:76
char * commands_str
Definition: f_sendcmd.c:79
int index
unique index for these interval commands
Definition: f_sendcmd.c:67
const char * b
Definition: vf_curves.c:109
#define FF_ARRAY_ELEMS(a)
char * command
Definition: f_sendcmd.c:60
static int parse_commands(Command **cmds, int *nb_cmds, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:197
static int parse_interval(Interval *interval, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:249
const char * name
Pad name.
Definition: internal.h:67
static const char *const cmds[]
Definition: jacosubdec.c:72
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1145
char * commands_filename
Definition: f_sendcmd.c:78
uint8_t
#define av_cold
Definition: attributes.h:74
#define av_malloc(s)
AVOptions.
static void skip_comments(const char **buf)
Definition: f_sendcmd.c:94
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:67
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:257
Misc file utilities.
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
int nb_commands
Definition: f_sendcmd.c:69
static int parse_intervals(Interval **intervals, int *nb_intervals, const char *buf, void *log_ctx)
Definition: f_sendcmd.c:312
int index
Definition: f_sendcmd.c:61
#define av_log(a,...)
char * target
Definition: f_sendcmd.c:60
A filter pad used for either input or output.
Definition: internal.h:61
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:140
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
Definition: file.c:129
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:49
#define SPACES
Definition: f_sendcmd.c:92
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
void * priv
private data for use by the filter
Definition: avfilter.h:654
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
const char * arg
Definition: jacosubdec.c:66
#define FFMAX(a, b)
Definition: common.h:64
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
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
static av_cold void uninit(AVFilterContext *ctx)
Definition: f_sendcmd.c:433
int enabled
current time detected inside this interval
Definition: f_sendcmd.c:70
#define COMMAND_DELIMS
Definition: f_sendcmd.c:111
static int parse_command(Command *cmd, int cmd_count, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:113
ret
Definition: avfilter.c:974
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
#define COMMAND_FLAG_LEAVE
Definition: f_sendcmd.c:38
int n
Definition: avisynth_c.h:547
#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:963
#define AV_BPRINT_SIZE_AUTOMATIC
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:253
char * arg
Definition: f_sendcmd.c:60
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Definition: vf_drawtext.c:765
void * buf
Definition: avisynth_c.h:553
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:470
static av_cold int init(AVFilterContext *ctx)
Definition: f_sendcmd.c:374
static const AVFilterPad inputs[]
Definition: af_ashowinfo.c:239
#define COMMAND_FLAG_ENTER
Definition: f_sendcmd.c:37
int flags
Definition: f_sendcmd.c:59
const char * name
Filter name.
Definition: avfilter.h:474
Interval * intervals
Definition: f_sendcmd.c:75
static char * make_command_flags_str(AVBPrint *pbuf, int flags)
Definition: f_sendcmd.c:40
misc parsing utilities
int64_t end_ts
end timestamp expressed as microseconds units
Definition: f_sendcmd.c:66
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:648
static int flags
Definition: cpu.c:47
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
int64_t start_ts
start timestamp expressed as microseconds units
Definition: f_sendcmd.c:65
Command * commands
Definition: f_sendcmd.c:68
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.
#define av_free(p)
int len
#define AVFILTER_DEFINE_CLASS(fname)
Definition: internal.h:313
#define WITHIN_INTERVAL(ts, start_ts, end_ts)
An instance of a filter.
Definition: avfilter.h:633
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:553
internal API functions
#define OFFSET(x)
Definition: f_sendcmd.c:82
static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
Definition: f_sendcmd.c:451
#define FLAGS
Definition: f_sendcmd.c:83
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:241
static const AVOption options[]
Definition: f_sendcmd.c:84
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140