avfilter/framequeue: add missing check for ASSERT_LEVEL
[ffmpeg.git] / libavfilter / f_sendcmd.c
index 9b83935..fb30220 100644 (file)
@@ -39,7 +39,7 @@
 
 static inline char *make_command_flags_str(AVBPrint *pbuf, int flags)
 {
-    const char *flag_strings[] = { "enter", "leave" };
+    static const char * const flag_strings[] = { "enter", "leave" };
     int i, is_first = 1;
 
     av_bprint_init(pbuf, 0, AV_BPRINT_SIZE_AUTOMATIC);
@@ -80,17 +80,15 @@ typedef struct {
 } SendCmdContext;
 
 #define OFFSET(x) offsetof(SendCmdContext, x)
-#define FLAGS AV_OPT_FLAG_FILTERING_PARAM
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM
 static const AVOption options[] = {
     { "commands", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
     { "c",        "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
     { "filename", "set commands file",  OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
     { "f",        "set commands file",  OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
-    {NULL},
+    { NULL }
 };
 
-AVFILTER_DEFINE_CLASS(sendcmd);
-
 #define SPACES " \f\t\n\r"
 
 static void skip_comments(const char **buf)
@@ -136,7 +134,7 @@ static int parse_command(Command *cmd, int cmd_count, int interval_count,
                 char flag_buf[64];
                 av_strlcpy(flag_buf, *buf, sizeof(flag_buf));
                 av_log(log_ctx, AV_LOG_ERROR,
-                       "Unknown flag '%s' in in interval #%d, command #%d\n",
+                       "Unknown flag '%s' in interval #%d, command #%d\n",
                        flag_buf, interval_count, cmd_count);
                 return AVERROR(EINVAL);
             }
@@ -168,7 +166,7 @@ static int parse_command(Command *cmd, int cmd_count, int interval_count,
     cmd->target = av_get_token(buf, COMMAND_DELIMS);
     if (!cmd->target || !cmd->target[0]) {
         av_log(log_ctx, AV_LOG_ERROR,
-               "No target specified in in interval #%d, command #%d\n",
+               "No target specified in interval #%d, command #%d\n",
                interval_count, cmd_count);
         ret = AVERROR(EINVAL);
         goto fail;
@@ -178,7 +176,7 @@ static int parse_command(Command *cmd, int cmd_count, int interval_count,
     cmd->command = av_get_token(buf, COMMAND_DELIMS);
     if (!cmd->command || !cmd->command[0]) {
         av_log(log_ctx, AV_LOG_ERROR,
-               "No command specified in in interval #%d, command #%d\n",
+               "No command specified in interval #%d, command #%d\n",
                interval_count, cmd_count);
         ret = AVERROR(EINVAL);
         goto fail;
@@ -320,6 +318,9 @@ static int parse_intervals(Interval **intervals, int *nb_intervals,
     *intervals = NULL;
     *nb_intervals = 0;
 
+    if (!buf)
+        return 0;
+
     while (1) {
         Interval interval;
 
@@ -363,34 +364,24 @@ static int cmp_intervals(const void *a, const void *b)
 {
     const Interval *i1 = a;
     const Interval *i2 = b;
-    int64_t ts_diff = i1->start_ts - i2->start_ts;
-    int ret;
-
-    ret = ts_diff > 0 ? 1 : ts_diff < 0 ? -1 : 0;
-    return ret == 0 ? i1->index - i2->index : ret;
+    return 2 * FFDIFFSIGN(i1->start_ts, i2->start_ts) + FFDIFFSIGN(i1->index, i2->index);
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    SendCmdContext *sendcmd = ctx->priv;
+    SendCmdContext *s = ctx->priv;
     int ret, i, j;
 
-    sendcmd->class = &sendcmd_class;
-    av_opt_set_defaults(sendcmd);
-
-    if ((ret = av_set_options_string(sendcmd, args, "=", ":")) < 0)
-        return ret;
-
-    if (sendcmd->commands_filename && sendcmd->commands_str) {
+    if ((!!s->commands_filename + !!s->commands_str) != 1) {
         av_log(ctx, AV_LOG_ERROR,
-               "Only one of the filename or commands options must be specified\n");
+               "One and only one of the filename or commands options must be specified\n");
         return AVERROR(EINVAL);
     }
 
-    if (sendcmd->commands_filename) {
+    if (s->commands_filename) {
         uint8_t *file_buf, *buf;
         size_t file_bufsize;
-        ret = av_file_map(sendcmd->commands_filename,
+        ret = av_file_map(s->commands_filename,
                           &file_buf, &file_bufsize, 0, ctx);
         if (ret < 0)
             return ret;
@@ -404,19 +395,24 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
         memcpy(buf, file_buf, file_bufsize);
         buf[file_bufsize] = 0;
         av_file_unmap(file_buf, file_bufsize);
-        sendcmd->commands_str = buf;
+        s->commands_str = buf;
     }
 
-    if ((ret = parse_intervals(&sendcmd->intervals, &sendcmd->nb_intervals,
-                               sendcmd->commands_str, ctx)) < 0)
+    if ((ret = parse_intervals(&s->intervals, &s->nb_intervals,
+                               s->commands_str, ctx)) < 0)
         return ret;
 
-    qsort(sendcmd->intervals, sendcmd->nb_intervals, sizeof(Interval), cmp_intervals);
+    if (s->nb_intervals == 0) {
+        av_log(ctx, AV_LOG_ERROR, "No commands were specified\n");
+        return AVERROR(EINVAL);
+    }
+
+    qsort(s->intervals, s->nb_intervals, sizeof(Interval), cmp_intervals);
 
     av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n");
-    for (i = 0; i < sendcmd->nb_intervals; i++) {
+    for (i = 0; i < s->nb_intervals; i++) {
         AVBPrint pbuf;
-        Interval *interval = &sendcmd->intervals[i];
+        Interval *interval = &s->intervals[i];
         av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n",
                (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index);
         for (j = 0; j < interval->nb_commands; j++) {
@@ -430,30 +426,28 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
     return 0;
 }
 
-static void av_cold uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
-    SendCmdContext *sendcmd = ctx->priv;
+    SendCmdContext *s = ctx->priv;
     int i, j;
 
-    av_opt_free(sendcmd);
-
-    for (i = 0; i < sendcmd->nb_intervals; i++) {
-        Interval *interval = &sendcmd->intervals[i];
+    for (i = 0; i < s->nb_intervals; i++) {
+        Interval *interval = &s->intervals[i];
         for (j = 0; j < interval->nb_commands; j++) {
             Command *cmd = &interval->commands[j];
-            av_free(cmd->target);
-            av_free(cmd->command);
-            av_free(cmd->arg);
+            av_freep(&cmd->target);
+            av_freep(&cmd->command);
+            av_freep(&cmd->arg);
         }
-        av_free(interval->commands);
+        av_freep(&interval->commands);
     }
-    av_freep(&sendcmd->intervals);
+    av_freep(&s->intervals);
 }
 
-static int process_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
+static int filter_frame(AVFilterLink *inlink, AVFrame *ref)
 {
     AVFilterContext *ctx = inlink->dst;
-    SendCmdContext *sendcmd = ctx->priv;
+    SendCmdContext *s = ctx->priv;
     int64_t ts;
     int i, j, ret;
 
@@ -464,8 +458,8 @@ static int process_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
 
 #define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts))
 
-    for (i = 0; i < sendcmd->nb_intervals; i++) {
-        Interval *interval = &sendcmd->intervals[i];
+    for (i = 0; i < s->nb_intervals; i++) {
+        Interval *interval = &s->intervals[i];
         int flags = 0;
 
         if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
@@ -506,25 +500,25 @@ static int process_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
     }
 
 end:
-    /* give the reference away, do not store in cur_buf */
-    inlink->cur_buf = NULL;
-
     switch (inlink->type) {
-    case AVMEDIA_TYPE_VIDEO: return ff_start_frame   (inlink->dst->outputs[0], ref);
-    case AVMEDIA_TYPE_AUDIO: return ff_filter_frame(inlink->dst->outputs[0], ref);
+    case AVMEDIA_TYPE_VIDEO:
+    case AVMEDIA_TYPE_AUDIO:
+        return ff_filter_frame(inlink->dst->outputs[0], ref);
     }
+
     return AVERROR(ENOSYS);
 }
 
 #if CONFIG_SENDCMD_FILTER
 
+#define sendcmd_options options
+AVFILTER_DEFINE_CLASS(sendcmd);
+
 static const AVFilterPad sendcmd_inputs[] = {
     {
-        .name             = "default",
-        .type             = AVMEDIA_TYPE_VIDEO,
-        .get_video_buffer = ff_null_get_video_buffer,
-        .start_frame      = process_frame,
-        .end_frame        = ff_null_end_frame,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
     },
     { NULL }
 };
@@ -537,27 +531,29 @@ static const AVFilterPad sendcmd_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_sendcmd = {
-    .name      = "sendcmd",
+AVFilter ff_vf_sendcmd = {
+    .name        = "sendcmd",
     .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
-
-    .init = init,
-    .uninit = uninit,
-    .priv_size = sizeof(SendCmdContext),
-    .inputs    = sendcmd_inputs,
-    .outputs   = sendcmd_outputs,
+    .init        = init,
+    .uninit      = uninit,
+    .priv_size   = sizeof(SendCmdContext),
+    .inputs      = sendcmd_inputs,
+    .outputs     = sendcmd_outputs,
+    .priv_class  = &sendcmd_class,
 };
 
 #endif
 
 #if CONFIG_ASENDCMD_FILTER
 
+#define asendcmd_options options
+AVFILTER_DEFINE_CLASS(asendcmd);
+
 static const AVFilterPad asendcmd_inputs[] = {
     {
-        .name             = "default",
-        .type             = AVMEDIA_TYPE_AUDIO,
-        .get_audio_buffer = ff_null_get_audio_buffer,
-        .filter_frame     = process_frame,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
     },
     { NULL }
 };
@@ -570,15 +566,15 @@ static const AVFilterPad asendcmd_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_asendcmd = {
-    .name      = "asendcmd",
+AVFilter ff_af_asendcmd = {
+    .name        = "asendcmd",
     .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
-
-    .init = init,
-    .uninit = uninit,
-    .priv_size = sizeof(SendCmdContext),
-    .inputs    = asendcmd_inputs,
-    .outputs   = asendcmd_outputs,
+    .init        = init,
+    .uninit      = uninit,
+    .priv_size   = sizeof(SendCmdContext),
+    .inputs      = asendcmd_inputs,
+    .outputs     = asendcmd_outputs,
+    .priv_class  = &asendcmd_class,
 };
 
 #endif