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  const char *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 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 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 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  while (1) {
322  Interval interval;
323 
324  skip_comments(&buf);
325  if (!(*buf))
326  break;
327 
328  if ((ret = parse_interval(&interval, interval_count, &buf, log_ctx)) < 0)
329  return ret;
330 
331  buf += strspn(buf, SPACES);
332  if (*buf) {
333  if (*buf != ';') {
334  av_log(log_ctx, AV_LOG_ERROR,
335  "Missing terminator or extraneous data found at the end of interval #%d\n",
336  interval_count);
337  return AVERROR(EINVAL);
338  }
339  buf++; /* skip ';' */
340  }
341  interval_count++;
342 
343  /* (re)allocate commands array if required */
344  if (*nb_intervals == n) {
345  n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
346  *intervals = av_realloc_f(*intervals, n, 2*sizeof(Interval));
347  if (!*intervals) {
348  av_log(log_ctx, AV_LOG_ERROR,
349  "Could not (re)allocate intervals array\n");
350  return AVERROR(ENOMEM);
351  }
352  }
353 
354  (*intervals)[(*nb_intervals)++] = interval;
355  }
356 
357  return 0;
358 }
359 
360 static int cmp_intervals(const void *a, const void *b)
361 {
362  const Interval *i1 = a;
363  const Interval *i2 = b;
364  int64_t ts_diff = i1->start_ts - i2->start_ts;
365  int ret;
366 
367  ret = ts_diff > 0 ? 1 : ts_diff < 0 ? -1 : 0;
368  return ret == 0 ? i1->index - i2->index : ret;
369 }
370 
371 static av_cold int init(AVFilterContext *ctx)
372 {
373  SendCmdContext *sendcmd = ctx->priv;
374  int ret, i, j;
375 
376  if (sendcmd->commands_filename && sendcmd->commands_str) {
377  av_log(ctx, AV_LOG_ERROR,
378  "Only one of the filename or commands options must be specified\n");
379  return AVERROR(EINVAL);
380  }
381 
382  if (sendcmd->commands_filename) {
383  uint8_t *file_buf, *buf;
384  size_t file_bufsize;
385  ret = av_file_map(sendcmd->commands_filename,
386  &file_buf, &file_bufsize, 0, ctx);
387  if (ret < 0)
388  return ret;
389 
390  /* create a 0-terminated string based on the read file */
391  buf = av_malloc(file_bufsize + 1);
392  if (!buf) {
393  av_file_unmap(file_buf, file_bufsize);
394  return AVERROR(ENOMEM);
395  }
396  memcpy(buf, file_buf, file_bufsize);
397  buf[file_bufsize] = 0;
398  av_file_unmap(file_buf, file_bufsize);
399  sendcmd->commands_str = buf;
400  }
401 
402  if ((ret = parse_intervals(&sendcmd->intervals, &sendcmd->nb_intervals,
403  sendcmd->commands_str, ctx)) < 0)
404  return ret;
405 
406  qsort(sendcmd->intervals, sendcmd->nb_intervals, sizeof(Interval), cmp_intervals);
407 
408  av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n");
409  for (i = 0; i < sendcmd->nb_intervals; i++) {
410  AVBPrint pbuf;
411  Interval *interval = &sendcmd->intervals[i];
412  av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n",
413  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index);
414  for (j = 0; j < interval->nb_commands; j++) {
415  Command *cmd = &interval->commands[j];
416  av_log(ctx, AV_LOG_VERBOSE,
417  " [%s] target:%s command:%s arg:%s index:%d\n",
418  make_command_flags_str(&pbuf, cmd->flags), cmd->target, cmd->command, cmd->arg, cmd->index);
419  }
420  }
421 
422  return 0;
423 }
424 
425 static void av_cold uninit(AVFilterContext *ctx)
426 {
427  SendCmdContext *sendcmd = ctx->priv;
428  int i, j;
429 
430  for (i = 0; i < sendcmd->nb_intervals; i++) {
431  Interval *interval = &sendcmd->intervals[i];
432  for (j = 0; j < interval->nb_commands; j++) {
433  Command *cmd = &interval->commands[j];
434  av_free(cmd->target);
435  av_free(cmd->command);
436  av_free(cmd->arg);
437  }
438  av_free(interval->commands);
439  }
440  av_freep(&sendcmd->intervals);
441 }
442 
443 static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
444 {
445  AVFilterContext *ctx = inlink->dst;
446  SendCmdContext *sendcmd = ctx->priv;
447  int64_t ts;
448  int i, j, ret;
449 
450  if (ref->pts == AV_NOPTS_VALUE)
451  goto end;
452 
453  ts = av_rescale_q(ref->pts, inlink->time_base, AV_TIME_BASE_Q);
454 
455 #define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts))
456 
457  for (i = 0; i < sendcmd->nb_intervals; i++) {
458  Interval *interval = &sendcmd->intervals[i];
459  int flags = 0;
460 
461  if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
462  flags += COMMAND_FLAG_ENTER;
463  interval->enabled = 1;
464  }
465  if (interval->enabled && !WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
466  flags += COMMAND_FLAG_LEAVE;
467  interval->enabled = 0;
468  }
469 
470  if (flags) {
471  AVBPrint pbuf;
472  av_log(ctx, AV_LOG_VERBOSE,
473  "[%s] interval #%d start_ts:%f end_ts:%f ts:%f\n",
474  make_command_flags_str(&pbuf, flags), interval->index,
475  (double)interval->start_ts/1000000, (double)interval->end_ts/1000000,
476  (double)ts/1000000);
477 
478  for (j = 0; flags && j < interval->nb_commands; j++) {
479  Command *cmd = &interval->commands[j];
480  char buf[1024];
481 
482  if (cmd->flags & flags) {
483  av_log(ctx, AV_LOG_VERBOSE,
484  "Processing command #%d target:%s command:%s arg:%s\n",
485  cmd->index, cmd->target, cmd->command, cmd->arg);
486  ret = avfilter_graph_send_command(inlink->graph,
487  cmd->target, cmd->command, cmd->arg,
488  buf, sizeof(buf),
490  av_log(ctx, AV_LOG_VERBOSE,
491  "Command reply for command #%d: ret:%s res:%s\n",
492  cmd->index, av_err2str(ret), buf);
493  }
494  }
495  }
496  }
497 
498 end:
499  switch (inlink->type) {
500  case AVMEDIA_TYPE_VIDEO:
501  case AVMEDIA_TYPE_AUDIO:
502  return ff_filter_frame(inlink->dst->outputs[0], ref);
503  }
504 
505  return AVERROR(ENOSYS);
506 }
507 
508 #if CONFIG_SENDCMD_FILTER
509 
510 #define sendcmd_options options
511 AVFILTER_DEFINE_CLASS(sendcmd);
512 
513 static av_cold int sendcmd_init(AVFilterContext *ctx)
514 {
515  return init(ctx);
516 }
517 
518 static const AVFilterPad sendcmd_inputs[] = {
519  {
520  .name = "default",
521  .type = AVMEDIA_TYPE_VIDEO,
522  .get_video_buffer = ff_null_get_video_buffer,
523  .filter_frame = filter_frame,
524  },
525  { NULL }
526 };
527 
528 static const AVFilterPad sendcmd_outputs[] = {
529  {
530  .name = "default",
531  .type = AVMEDIA_TYPE_VIDEO,
532  },
533  { NULL }
534 };
535 
536 AVFilter avfilter_vf_sendcmd = {
537  .name = "sendcmd",
538  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
539 
540  .init = sendcmd_init,
541  .uninit = uninit,
542  .priv_size = sizeof(SendCmdContext),
543  .inputs = sendcmd_inputs,
544  .outputs = sendcmd_outputs,
545  .priv_class = &sendcmd_class,
546 };
547 
548 #endif
549 
550 #if CONFIG_ASENDCMD_FILTER
551 
552 #define asendcmd_options options
553 AVFILTER_DEFINE_CLASS(asendcmd);
554 
555 static av_cold int asendcmd_init(AVFilterContext *ctx)
556 {
557  return init(ctx);
558 }
559 
560 static const AVFilterPad asendcmd_inputs[] = {
561  {
562  .name = "default",
563  .type = AVMEDIA_TYPE_AUDIO,
564  .get_audio_buffer = ff_null_get_audio_buffer,
565  .filter_frame = filter_frame,
566  },
567  { NULL }
568 };
569 
570 static const AVFilterPad asendcmd_outputs[] = {
571  {
572  .name = "default",
573  .type = AVMEDIA_TYPE_AUDIO,
574  },
575  { NULL }
576 };
577 
578 AVFilter avfilter_af_asendcmd = {
579  .name = "asendcmd",
580  .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
581 
582  .init = asendcmd_init,
583  .uninit = uninit,
584  .priv_size = sizeof(SendCmdContext),
585  .inputs = asendcmd_inputs,
586  .outputs = asendcmd_outputs,
587  .priv_class = &asendcmd_class,
588 };
589 
590 #endif
#define DELIMS
Definition: f_sendcmd.c:247
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:93
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static int cmp_intervals(const void *a, const void *b)
Definition: f_sendcmd.c:360
FIXME Range Coding of cr are ref
Definition: snow.txt:367
AVOption.
Definition: opt.h:251
void * av_realloc_f(void *ptr, size_t nelem, size_t elsize)
Allocate or reallocate a block of memory.
Definition: mem.c:168
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
external 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:530
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
AVFrame * ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
Definition: video.c:35
#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
char * target
Definition: f_sendcmd.c:60
static int parse_interval(Interval *interval, int interval_count, const char **buf, void *log_ctx)
Definition: f_sendcmd.c:249
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
const char * name
Pad name.
static const char *const cmds[]
char * commands_filename
Definition: f_sendcmd.c:78
uint8_t
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
#define av_cold
Definition: attributes.h:78
AVOptions.
static void skip_comments(const char **buf)
Definition: f_sendcmd.c:94
#define b
Definition: input.c:42
end end
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:159
Misc file utilities.
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
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
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...
#define SPACES
Definition: f_sendcmd.c:92
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Init a print buffer.
Definition: bprint.c:68
void * priv
private data for use by the filter
Definition: avfilter.h:545
const char * arg
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
#define FFMAX(a, b)
Definition: common.h:56
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:82
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:148
int enabled
current time detected inside this interval
Definition: f_sendcmd.c:70
#define AV_LOG_VERBOSE
Definition: log.h:157
Buffer to print data progressively.
Definition: bprint.h:75
#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:821
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:110
#define COMMAND_FLAG_LEAVE
Definition: f_sendcmd.c:38
#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:821
AVFrame * ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples)
get_audio_buffer() handler for filters which simply pass audio along
Definition: audio.c:36
NULL
Definition: eval.c:55
#define AV_BPRINT_SIZE_AUTOMATIC
Definition: bprint.h:90
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:202
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:596
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
Filter definition.
Definition: avfilter.h:436
static av_cold int init(AVFilterContext *ctx)
Definition: f_sendcmd.c:371
#define COMMAND_FLAG_ENTER
Definition: f_sendcmd.c:37
synthesis window for stochastic i
int flags
Definition: f_sendcmd.c:59
const char * name
filter name
Definition: avfilter.h:437
Interval * intervals
Definition: f_sendcmd.c:75
static char * make_command_flags_str(AVBPrint *pbuf, int flags)
Definition: f_sendcmd.c:40
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
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:539
static int flags
Definition: cpu.c:23
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:183
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
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.
int len
#define AVFILTER_DEFINE_CLASS(fname)
#define WITHIN_INTERVAL(ts, start_ts, end_ts)
An instance of a filter.
Definition: avfilter.h:524
void INT64 start
Definition: avisynth_c.h:594
internal API functions
static void av_cold uninit(AVFilterContext *ctx)
Definition: f_sendcmd.c:425
#define OFFSET(x)
Definition: f_sendcmd.c:82
static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
Definition: f_sendcmd.c:443
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
#define FLAGS
Definition: f_sendcmd.c:83
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190
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:116