]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/avfilter.c
avdevice/decklink_dec: Added Closed caption decode from VANC
[ffmpeg] / libavfilter / avfilter.c
index e60b0247bce690b6759d79bdefee65b883ab0ab3..58917ed44548dbd3f748c3b0a70df3ed641fd75d 100644 (file)
@@ -427,6 +427,24 @@ int ff_request_frame(AVFilterLink *link)
     return 0;
 }
 
+static int64_t guess_status_pts(AVFilterContext *ctx, int status)
+{
+    unsigned i;
+    int64_t r = INT64_MAX;
+
+    for (i = 0; i < ctx->nb_inputs; i++)
+        if (ctx->inputs[i]->status_out == status)
+            r = FFMIN(r, ctx->inputs[i]->current_pts);
+    if (r < INT64_MAX)
+        return r;
+    av_log(ctx, AV_LOG_WARNING, "EOF timestamp not reliable\n");
+    for (i = 0; i < ctx->nb_inputs; i++)
+        r = FFMIN(r, ctx->inputs[i]->status_in_pts);
+    if (r < INT64_MAX)
+        return r;
+    return AV_NOPTS_VALUE;
+}
+
 static int ff_request_frame_to_filter(AVFilterLink *link)
 {
     int ret = -1;
@@ -440,7 +458,7 @@ static int ff_request_frame_to_filter(AVFilterLink *link)
         ret = ff_request_frame(link->src->inputs[0]);
     if (ret < 0) {
         if (ret != AVERROR(EAGAIN) && ret != link->status_in)
-            ff_avfilter_link_set_in_status(link, ret, AV_NOPTS_VALUE);
+            ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret));
         if (ret == AVERROR_EOF)
             ret = 0;
     }
@@ -692,6 +710,7 @@ static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, voi
 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
 {
     AVFilterContext *ret;
+    int preinited = 0;
 
     if (!filter)
         return NULL;
@@ -708,6 +727,11 @@ AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
         if (!ret->priv)
             goto err;
     }
+    if (filter->preinit) {
+        if (filter->preinit(ret) < 0)
+            goto err;
+        preinited = 1;
+    }
 
     av_opt_set_defaults(ret);
     if (filter->priv_class) {
@@ -745,6 +769,8 @@ AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
     return ret;
 
 err:
+    if (preinited)
+        filter->uninit(ret);
     av_freep(&ret->inputs);
     av_freep(&ret->input_pads);
     ret->nb_inputs = 0;
@@ -889,7 +915,7 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,
             }
         } else {
         av_dict_set(options, key, value, 0);
-        if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) {
+        if ((ret = av_opt_set(ctx->priv, key, value, AV_OPT_SEARCH_CHILDREN)) < 0) {
             if (!av_opt_find(ctx->priv, key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {
             if (ret == AVERROR_OPTION_NOT_FOUND)
                 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
@@ -940,7 +966,7 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
     }
 
     if (ctx->filter->priv_class) {
-        ret = av_opt_set_dict(ctx->priv, options);
+        ret = av_opt_set_dict2(ctx->priv, options, AV_OPT_SEARCH_CHILDREN);
         if (ret < 0) {
             av_log(ctx, AV_LOG_ERROR, "Error applying options to the filter.\n");
             return ret;
@@ -1304,8 +1330,6 @@ static int forward_status_change(AVFilterContext *filter, AVFilterLink *in)
     return 0;
 }
 
-#define FFERROR_NOT_READY FFERRTAG('N','R','D','Y')
-
 static int ff_filter_activate_default(AVFilterContext *filter)
 {
     unsigned i;
@@ -1644,6 +1668,26 @@ void ff_inlink_request_frame(AVFilterLink *link)
     ff_filter_set_ready(link->src, 100);
 }
 
+void ff_inlink_set_status(AVFilterLink *link, int status)
+{
+    if (link->status_out)
+        return;
+    link->frame_wanted_out = 0;
+    link->frame_blocked_in = 0;
+    ff_avfilter_link_set_out_status(link, status, AV_NOPTS_VALUE);
+    while (ff_framequeue_queued_frames(&link->fifo)) {
+           AVFrame *frame = ff_framequeue_take(&link->fifo);
+           av_frame_free(&frame);
+    }
+    if (!link->status_in)
+        link->status_in = status;
+}
+
+int ff_outlink_get_status(AVFilterLink *link)
+{
+    return link->status_in;
+}
+
 const AVClass *avfilter_get_class(void)
 {
     return &avfilter_class;