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;
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;
}
AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
{
AVFilterContext *ret;
+ int preinited = 0;
if (!filter)
return NULL;
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) {
return ret;
err:
+ if (preinited)
+ filter->uninit(ret);
av_freep(&ret->inputs);
av_freep(&ret->input_pads);
ret->nb_inputs = 0;
}
} 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);
}
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;
return 0;
}
-#define FFERROR_NOT_READY FFERRTAG('N','R','D','Y')
-
static int ff_filter_activate_default(AVFilterContext *filter)
{
unsigned i;
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;