#include "formats.h"
#include "internal.h"
+#include "libavutil/ffversion.h"
+const char av_filter_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
+
static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame);
void ff_tlog_ref(void *ctx, AVFrame *ref, int end)
if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
src->outputs[srcpad] || dst->inputs[dstpad])
- return -1;
+ return AVERROR(EINVAL);
if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
av_log(src, AV_LOG_ERROR,
AVFilterLink *inlink;
if (!link) continue;
+ if (!link->src || !link->dst) {
+ av_log(filter, AV_LOG_ERROR,
+ "Not all input and output are properly linked (%d).\n", i);
+ return AVERROR(EINVAL);
+ }
inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
link->current_pts = AV_NOPTS_VALUE;
if ((config_link = link->dstpad->config_props))
if ((ret = config_link(link)) < 0) {
- av_log(link->src, AV_LOG_ERROR,
+ av_log(link->dst, AV_LOG_ERROR,
"Failed to configure input pad on %s\n",
link->dst->name);
return ret;
for (i = 0; i < link->src->nb_inputs; i++) {
int val;
if (!link->src->inputs[i])
- return -1;
+ return AVERROR(EINVAL);
val = ff_poll_frame(link->src->inputs[i]);
min = FFMIN(min, val);
}
return min;
}
-static const char *const var_names[] = { "t", "n", "pos", NULL };
-enum { VAR_T, VAR_N, VAR_POS, VAR_VARS_NB };
+static const char *const var_names[] = {
+ "t",
+ "n",
+ "pos",
+ "w",
+ "h",
+ NULL
+};
+
+enum {
+ VAR_T,
+ VAR_N,
+ VAR_POS,
+ VAR_W,
+ VAR_H,
+ VAR_VARS_NB
+};
static int set_enable_expr(AVFilterContext *ctx, const char *expr)
{
}
static AVFilter *first_filter;
+static AVFilter **last_filter = &first_filter;
+#if !FF_API_NOCONST_GET_NAME
+const
+#endif
AVFilter *avfilter_get_by_name(const char *name)
{
const AVFilter *f = NULL;
int avfilter_register(AVFilter *filter)
{
- AVFilter **f = &first_filter;
- int i;
+ AVFilter **f = last_filter;
/* the filter must select generic or internal exclusively */
av_assert0((filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE) != AVFILTER_FLAG_SUPPORT_TIMELINE);
- for(i=0; filter->inputs && filter->inputs[i].name; i++) {
- const AVFilterPad *input = &filter->inputs[i];
- av_assert0( !input->filter_frame
- || (!input->start_frame && !input->end_frame));
- }
-
filter->next = NULL;
- while(avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter))
+ while(*f || avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter))
f = &(*f)->next;
+ last_filter = &filter->next;
return 0;
}
ret->nb_inputs = avfilter_pad_count(filter->inputs);
if (ret->nb_inputs ) {
- ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs);
+ ret->input_pads = av_malloc_array(ret->nb_inputs, sizeof(AVFilterPad));
if (!ret->input_pads)
goto err;
memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->nb_inputs);
- ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_inputs);
+ ret->inputs = av_mallocz_array(ret->nb_inputs, sizeof(AVFilterLink*));
if (!ret->inputs)
goto err;
}
ret->nb_outputs = avfilter_pad_count(filter->outputs);
if (ret->nb_outputs) {
- ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_outputs);
+ ret->output_pads = av_malloc_array(ret->nb_outputs, sizeof(AVFilterPad));
if (!ret->output_pads)
goto err;
memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->nb_outputs);
- ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_outputs);
+ ret->outputs = av_mallocz_array(ret->nb_outputs, sizeof(AVFilterLink*));
if (!ret->outputs)
goto err;
}
-#if FF_API_FOO_COUNT
-FF_DISABLE_DEPRECATION_WARNINGS
- ret->output_count = ret->nb_outputs;
- ret->input_count = ret->nb_inputs;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
return ret;
return AVERROR(EINVAL);
}
-#if FF_API_OLD_FILTER_OPTS
+#if FF_API_OLD_FILTER_OPTS || FF_API_OLD_FILTER_OPTS_ERROR
if ( !strcmp(filter->filter->name, "format") ||
!strcmp(filter->filter->name, "noformat") ||
!strcmp(filter->filter->name, "frei0r") ||
while ((p = strchr(p, ':')))
*p++ = '|';
+#if FF_API_OLD_FILTER_OPTS
if (deprecated)
av_log(filter, AV_LOG_WARNING, "This syntax is deprecated. Use "
"'|' to separate the list items.\n");
av_log(filter, AV_LOG_DEBUG, "compat: called with args=[%s]\n", copy);
ret = process_options(filter, &options, copy);
+#else
+ if (deprecated) {
+ av_log(filter, AV_LOG_ERROR, "This syntax is deprecated. Use "
+ "'|' to separate the list items ('%s' instead of '%s')\n",
+ copy, args);
+ ret = AVERROR(EINVAL);
+ } else {
+ ret = process_options(filter, &options, copy);
+ }
+#endif
av_freep(©);
if (ret < 0)
goto fail;
+ } else
#endif
- } else {
-#if CONFIG_MP_FILTER
- if (!strcmp(filter->filter->name, "mp")) {
- char *escaped;
-
- if (!strncmp(args, "filter=", 7))
- args += 7;
- ret = av_escape(&escaped, args, ":=", AV_ESCAPE_MODE_BACKSLASH, 0);
- if (ret < 0) {
- av_log(filter, AV_LOG_ERROR, "Unable to escape MPlayer filters arg '%s'\n", args);
- goto fail;
- }
- ret = process_options(filter, &options, escaped);
- av_free(escaped);
- } else
-#endif
+ {
ret = process_options(filter, &options, args);
if (ret < 0)
goto fail;
int (*filter_frame)(AVFilterLink *, AVFrame *);
AVFilterContext *dstctx = link->dst;
AVFilterPad *dst = link->dstpad;
- AVFrame *out;
+ AVFrame *out = NULL;
int ret;
AVFilterCommand *cmd= link->dst->command_queue;
int64_t pts;
if (dst->needs_writable && !av_frame_is_writable(frame)) {
av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
- /* Maybe use ff_copy_buffer_ref instead? */
switch (link->type) {
case AVMEDIA_TYPE_VIDEO:
out = ff_get_video_buffer(link, link->w, link->h);
case AVMEDIA_TYPE_AUDIO:
out = ff_get_audio_buffer(link, frame->nb_samples);
break;
- default: return AVERROR(EINVAL);
+ default:
+ ret = AVERROR(EINVAL);
+ goto fail;
}
if (!out) {
- av_frame_free(&frame);
- return AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
- av_frame_copy_props(out, frame);
+
+ ret = av_frame_copy_props(out, frame);
+ if (ret < 0)
+ goto fail;
switch (link->type) {
case AVMEDIA_TYPE_VIDEO:
av_get_channel_layout_nb_channels(frame->channel_layout),
frame->format);
break;
- default: return AVERROR(EINVAL);
+ default:
+ ret = AVERROR(EINVAL);
+ goto fail;
}
av_frame_free(&frame);
int64_t pos = av_frame_get_pkt_pos(out);
dstctx->var_values[VAR_N] = link->frame_count;
dstctx->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base);
+ dstctx->var_values[VAR_W] = link->w;
+ dstctx->var_values[VAR_H] = link->h;
dstctx->var_values[VAR_POS] = pos == -1 ? NAN : pos;
dstctx->is_disabled = fabs(av_expr_eval(dstctx->enable, dstctx->var_values, NULL)) < 0.5;
link->frame_requested = 0;
ff_update_link_current_pts(link, pts);
return ret;
+
+fail:
+ av_frame_free(&out);
+ av_frame_free(&frame);
+ return ret;
}
static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame)
/* Consistency checks */
if (link->type == AVMEDIA_TYPE_VIDEO) {
- if (strcmp(link->dst->filter->name, "scale")) {
+ if (strcmp(link->dst->filter->name, "buffersink") &&
+ strcmp(link->dst->filter->name, "format") &&
+ strcmp(link->dst->filter->name, "idet") &&
+ strcmp(link->dst->filter->name, "null") &&
+ strcmp(link->dst->filter->name, "scale")) {
av_assert1(frame->format == link->format);
av_assert1(frame->width == link->w);
av_assert1(frame->height == link->h);