annotate ffmpeg/libavfilter/f_sendcmd.c @ 13:844d341cf643 tip

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