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