/* #define DEBUG */
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/rational.h"
-#include "libavutil/audioconvert.h"
+#include "libavutil/samplefmt.h"
+#include "audio.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
+#include "video.h"
unsigned avfilter_version(void) {
return LIBAVFILTER_VERSION_INT;
link->srcpad = &src->output_pads[srcpad];
link->dstpad = &dst->input_pads[dstpad];
link->type = src->output_pads[srcpad].type;
- assert(PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
+ assert(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
link->format = -1;
return 0;
int ret;
unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
- av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s' "
+ av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
"between the filter '%s' and the filter '%s'\n",
filt->name, link->src->name, link->dst->name);
av_dlog(ctx,
"link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s",
link, link->w, link->h,
- av_pix_fmt_descriptors[link->format].name,
+ av_get_pix_fmt_name(link->format),
link->src ? link->src->filter->name : "",
link->dst ? link->dst->filter->name : "",
end ? "\n" : "");
av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);
av_dlog(ctx,
- "link[%p r:%"PRId64" cl:%s fmt:%-16s %-16s->%-16s]%s",
+ "link[%p r:%d cl:%s fmt:%-16s %-16s->%-16s]%s",
link, link->sample_rate, buf,
av_get_sample_fmt_name(link->format),
link->src ? link->src->filter->name : "",
{
int count;
+ if (!pads)
+ return 0;
+
for(count = 0; pads->name; count ++) pads ++;
return count;
}
}
static const AVClass avfilter_class = {
- "AVFilter",
- filter_name,
- NULL,
- LIBAVUTIL_VERSION_INT,
+ .class_name = "AVFilter",
+ .item_name = filter_name,
+ .version = LIBAVUTIL_VERSION_INT,
};
int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
return pads[pad_idx].type;
}
-#if FF_API_DEFAULT_CONFIG_OUTPUT_LINK
-int avfilter_default_config_output_link(AVFilterLink *link)
-{
- return 0;
-}
-#endif
-#if FF_API_FILTERS_PUBLIC
-void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
- AVFilterPad **pads, AVFilterLink ***links,
- AVFilterPad *newpad)
-{
- ff_insert_pad(idx, count, padidx_off, pads, links, newpad);
-}
-void avfilter_insert_inpad(AVFilterContext *f, unsigned index,
- AVFilterPad *p)
-{
- ff_insert_pad(index, &f->nb_inputs, offsetof(AVFilterLink, dstpad),
- &f->input_pads, &f->inputs, p);
-#if FF_API_FOO_COUNT
- f->input_count = f->nb_inputs;
-#endif
-}
-void avfilter_insert_outpad(AVFilterContext *f, unsigned index,
- AVFilterPad *p)
+static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
{
- ff_insert_pad(index, &f->nb_outputs, offsetof(AVFilterLink, srcpad),
- &f->output_pads, &f->outputs, p);
-#if FF_API_FOO_COUNT
- f->output_count = f->nb_outputs;
-#endif
-}
-int avfilter_poll_frame(AVFilterLink *link)
-{
- return ff_poll_frame(link);
+ return ff_filter_frame(link->dst->outputs[0], frame);
}
-int avfilter_request_frame(AVFilterLink *link)
+
+int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
{
- return ff_request_frame(link);
+ int (*filter_frame)(AVFilterLink *, AVFrame *);
+ AVFilterPad *dst = link->dstpad;
+ AVFrame *out;
+
+ FF_DPRINTF_START(NULL, filter_frame);
+ ff_dlog_link(NULL, link, 1);
+
+ if (!(filter_frame = dst->filter_frame))
+ filter_frame = default_filter_frame;
+
+ /* copy the frame if needed */
+ if (dst->needs_writable && !av_frame_is_writable(frame)) {
+ av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ out = ff_get_video_buffer(link, link->w, link->h);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ out = ff_get_audio_buffer(link, frame->nb_samples);
+ break;
+ default: return AVERROR(EINVAL);
+ }
+ if (!out) {
+ av_frame_free(&frame);
+ return AVERROR(ENOMEM);
+ }
+ av_frame_copy_props(out, frame);
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ av_image_copy(out->data, out->linesize, frame->data, frame->linesize,
+ frame->format, frame->width, frame->height);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ av_samples_copy(out->extended_data, frame->extended_data,
+ 0, 0, frame->nb_samples,
+ av_get_channel_layout_nb_channels(frame->channel_layout),
+ frame->format);
+ break;
+ default: return AVERROR(EINVAL);
+ }
+
+ av_frame_free(&frame);
+ } else
+ out = frame;
+
+ return filter_frame(link, out);
}
-#endif