summaryrefslogtreecommitdiff
path: root/contrib/ffmpeg/libavfilter
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ffmpeg/libavfilter')
-rw-r--r--contrib/ffmpeg/libavfilter/allfilters.c43
-rw-r--r--contrib/ffmpeg/libavfilter/avfilter.c390
-rw-r--r--contrib/ffmpeg/libavfilter/avfilter.h616
-rw-r--r--contrib/ffmpeg/libavfilter/defaults.c158
-rw-r--r--contrib/ffmpeg/libavfilter/formats.c148
5 files changed, 1355 insertions, 0 deletions
diff --git a/contrib/ffmpeg/libavfilter/allfilters.c b/contrib/ffmpeg/libavfilter/allfilters.c
new file mode 100644
index 000000000..fafd6d1c6
--- /dev/null
+++ b/contrib/ffmpeg/libavfilter/allfilters.c
@@ -0,0 +1,43 @@
+/*
+ * filter registration
+ * copyright (c) 2008 Vitor Sessak
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avfilter.h"
+
+#define REGISTER_VF(X,x) { \
+ extern AVFilter avfilter_vf_##x ; \
+ if(ENABLE_VF_##X ) avfilter_register(&avfilter_vf_##x ); }
+
+
+#define REGISTER_VSRC(X,x) { \
+ extern AVFilter avfilter_vsrc_##x ; \
+ if(ENABLE_VSRC_##X ) avfilter_register(&avfilter_vsrc_##x ); }
+
+void avfilter_register_all(void)
+{
+ static int initialized;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+// REGISTER_VF(CROP,crop);
+
+}
diff --git a/contrib/ffmpeg/libavfilter/avfilter.c b/contrib/ffmpeg/libavfilter/avfilter.c
new file mode 100644
index 000000000..0182e4701
--- /dev/null
+++ b/contrib/ffmpeg/libavfilter/avfilter.c
@@ -0,0 +1,390 @@
+/*
+ * filter layer
+ * copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avfilter.h"
+#include "imgconvert.h"
+
+/** list of registered filters */
+struct FilterList
+{
+ AVFilter *filter;
+ struct FilterList *next;
+} *filters = NULL;
+
+/** helper macros to get the in/out pad on the dst/src filter */
+#define link_dpad(link) link->dst-> input_pads[link->dstpad]
+#define link_spad(link) link->src->output_pads[link->srcpad]
+
+AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask)
+{
+ AVFilterPicRef *ret = av_malloc(sizeof(AVFilterPicRef));
+ *ret = *ref;
+ ret->perms &= pmask;
+ ret->pic->refcount ++;
+ return ret;
+}
+
+void avfilter_unref_pic(AVFilterPicRef *ref)
+{
+ if(!(--ref->pic->refcount))
+ ref->pic->free(ref->pic);
+ av_free(ref);
+}
+
+void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
+ AVFilterPad **pads, AVFilterLink ***links,
+ AVFilterPad *newpad)
+{
+ unsigned i;
+
+ idx = FFMIN(idx, *count);
+
+ *pads = av_realloc(*pads, sizeof(AVFilterPad) * (*count + 1));
+ *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
+ memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad) * (*count-idx));
+ memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
+ memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
+ (*links)[idx] = NULL;
+
+ (*count) ++;
+ for(i = idx+1; i < *count; i ++)
+ if(*links[i])
+ (*(unsigned *)((uint8_t *) *links[i] + padidx_off)) ++;
+}
+
+int avfilter_link(AVFilterContext *src, unsigned srcpad,
+ AVFilterContext *dst, unsigned dstpad)
+{
+ AVFilterLink *link;
+
+ if(src->output_count <= srcpad || dst->input_count <= dstpad ||
+ src->outputs[srcpad] || dst->inputs[dstpad])
+ return -1;
+
+ src->outputs[srcpad] =
+ dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
+
+ link->src = src;
+ link->dst = dst;
+ link->srcpad = srcpad;
+ link->dstpad = dstpad;
+ link->format = -1;
+
+ return 0;
+}
+
+int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
+ unsigned in, unsigned out)
+{
+ av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s'\n",
+ filt->filter->name);
+
+ link->dst->inputs[link->dstpad] = NULL;
+ if(avfilter_link(filt, out, link->dst, link->dstpad)) {
+ /* failed to link output filter to new filter */
+ link->dst->inputs[link->dstpad] = link;
+ return -1;
+ }
+
+ /* re-hookup the link to the new destination filter we inserted */
+ link->dst = filt;
+ link->dstpad = in;
+ filt->inputs[in] = link;
+
+ /* if any information on supported colorspaces already exists on the
+ * link, we need to preserve that */
+ if(link->out_formats)
+ avfilter_formats_changeref(&link->out_formats,
+ &filt->outputs[out]->out_formats);
+
+ return 0;
+}
+
+int avfilter_config_links(AVFilterContext *filter)
+{
+ int (*config_link)(AVFilterLink *);
+ unsigned i;
+
+ for(i = 0; i < filter->input_count; i ++) {
+ AVFilterLink *link = filter->inputs[i];
+
+ if(!link) continue;
+
+ switch(link->init_state) {
+ case AVLINK_INIT:
+ continue;
+ case AVLINK_STARTINIT:
+ av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
+ return 0;
+ case AVLINK_UNINIT:
+ link->init_state = AVLINK_STARTINIT;
+
+ if(avfilter_config_links(link->src))
+ return -1;
+
+ if(!(config_link = link_spad(link).config_props))
+ config_link = avfilter_default_config_output_link;
+ if(config_link(link))
+ return -1;
+
+ if((config_link = link_dpad(link).config_props))
+ if(config_link(link))
+ return -1;
+
+ link->init_state = AVLINK_INIT;
+ }
+ }
+
+ return 0;
+}
+
+AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms)
+{
+ AVFilterPicRef *ret = NULL;
+
+ if(link_dpad(link).get_video_buffer)
+ ret = link_dpad(link).get_video_buffer(link, perms);
+
+ if(!ret)
+ ret = avfilter_default_get_video_buffer(link, perms);
+
+ return ret;
+}
+
+int avfilter_request_frame(AVFilterLink *link)
+{
+ if(link_spad(link).request_frame)
+ return link_spad(link).request_frame(link);
+ else if(link->src->inputs[0])
+ return avfilter_request_frame(link->src->inputs[0]);
+ else return -1;
+}
+
+int avfilter_poll_frame(AVFilterLink *link)
+{
+ int i, min=INT_MAX;
+
+ if(link_spad(link).poll_frame)
+ return link_spad(link).poll_frame(link);
+
+ for (i=0; i<link->src->input_count; i++) {
+ if(!link->src->inputs[i])
+ return -1;
+ min = FFMIN(min, avfilter_poll_frame(link->src->inputs[i]));
+ }
+
+ return min;
+}
+
+/* XXX: should we do the duplicating of the picture ref here, instead of
+ * forcing the source filter to do it? */
+void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
+{
+ void (*start_frame)(AVFilterLink *, AVFilterPicRef *);
+ AVFilterPad *dst = &link_dpad(link);
+
+ if(!(start_frame = dst->start_frame))
+ start_frame = avfilter_default_start_frame;
+
+ /* prepare to copy the picture if it has insufficient permissions */
+ if((dst->min_perms & picref->perms) != dst->min_perms ||
+ dst->rej_perms & picref->perms) {
+ /*
+ av_log(link->dst, AV_LOG_INFO,
+ "frame copy needed (have perms %x, need %x, reject %x)\n",
+ picref->perms,
+ link_dpad(link).min_perms, link_dpad(link).rej_perms);
+ */
+
+ link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms);
+ link->srcpic = picref;
+ link->cur_pic->pts = link->srcpic->pts;
+ }
+ else
+ link->cur_pic = picref;
+
+ start_frame(link, link->cur_pic);
+}
+
+void avfilter_end_frame(AVFilterLink *link)
+{
+ void (*end_frame)(AVFilterLink *);
+
+ if(!(end_frame = link_dpad(link).end_frame))
+ end_frame = avfilter_default_end_frame;
+
+ end_frame(link);
+
+ /* unreference the source picture if we're feeding the destination filter
+ * a copied version dues to permission issues */
+ if(link->srcpic) {
+ avfilter_unref_pic(link->srcpic);
+ link->srcpic = NULL;
+ }
+
+}
+
+void avfilter_draw_slice(AVFilterLink *link, int y, int h)
+{
+ uint8_t *src[4], *dst[4];
+ int i, j, hsub, vsub;
+
+ /* copy the slice if needed for permission reasons */
+ if(link->srcpic) {
+ avcodec_get_chroma_sub_sample(link->format, &hsub, &vsub);
+
+ for(i = 0; i < 4; i ++) {
+ if(link->srcpic->data[i]) {
+ src[i] = link->srcpic-> data[i] +
+ (y >> (i==0 ? 0 : vsub)) * link->srcpic-> linesize[i];
+ dst[i] = link->cur_pic->data[i] +
+ (y >> (i==0 ? 0 : vsub)) * link->cur_pic->linesize[i];
+ } else
+ src[i] = dst[i] = NULL;
+ }
+
+ for(i = 0; i < 4; i ++) {
+ int planew =
+ ff_get_plane_bytewidth(link->format, link->cur_pic->w, i);
+
+ if(!src[i]) continue;
+
+ for(j = 0; j < h >> (i==0 ? 0 : vsub); j ++) {
+ memcpy(dst[i], src[i], planew);
+ src[i] += link->srcpic ->linesize[i];
+ dst[i] += link->cur_pic->linesize[i];
+ }
+ }
+ }
+
+ if(link_dpad(link).draw_slice)
+ link_dpad(link).draw_slice(link, y, h);
+}
+
+AVFilter *avfilter_get_by_name(const char *name)
+{
+ struct FilterList *filt;
+
+ for(filt = filters; filt; filt = filt->next)
+ if(!strcmp(filt->filter->name, name))
+ return filt->filter;
+
+ return NULL;
+}
+
+void avfilter_register(AVFilter *filter)
+{
+ struct FilterList *newfilt = av_malloc(sizeof(struct FilterList));
+
+ newfilt->filter = filter;
+ newfilt->next = filters;
+ filters = newfilt;
+}
+
+void avfilter_uninit(void)
+{
+ struct FilterList *tmp;
+
+ for(; filters; filters = tmp) {
+ tmp = filters->next;
+ av_free(filters);
+ }
+}
+
+static int pad_count(const AVFilterPad *pads)
+{
+ int count;
+
+ for(count = 0; pads->name; count ++) pads ++;
+ return count;
+}
+
+static const char *filter_name(void *p)
+{
+ AVFilterContext *filter = p;
+ return filter->filter->name;
+}
+
+AVFilterContext *avfilter_open(AVFilter *filter, const char *inst_name)
+{
+ AVFilterContext *ret;
+
+ if (!filter)
+ return 0;
+
+ ret = av_malloc(sizeof(AVFilterContext));
+
+ ret->av_class = av_mallocz(sizeof(AVClass));
+ ret->av_class->item_name = filter_name;
+ ret->filter = filter;
+ ret->name = inst_name ? av_strdup(inst_name) : NULL;
+ ret->priv = av_mallocz(filter->priv_size);
+
+ ret->input_count = pad_count(filter->inputs);
+ ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->input_count);
+ memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad)*ret->input_count);
+ ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);
+
+ ret->output_count = pad_count(filter->outputs);
+ ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->output_count);
+ memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad)*ret->output_count);
+ ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);
+
+ return ret;
+}
+
+void avfilter_destroy(AVFilterContext *filter)
+{
+ int i;
+
+ if(filter->filter->uninit)
+ filter->filter->uninit(filter);
+
+ for(i = 0; i < filter->input_count; i ++) {
+ if(filter->inputs[i])
+ filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL;
+ av_freep(&filter->inputs[i]);
+ }
+ for(i = 0; i < filter->output_count; i ++) {
+ if(filter->outputs[i])
+ filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL;
+ av_freep(&filter->outputs[i]);
+ }
+
+ av_freep(&filter->name);
+ av_freep(&filter->input_pads);
+ av_freep(&filter->output_pads);
+ av_freep(&filter->inputs);
+ av_freep(&filter->outputs);
+ av_freep(&filter->priv);
+ av_freep(&filter->av_class);
+ av_free(filter);
+}
+
+int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
+{
+ int ret=0;
+
+ if(filter->filter->init)
+ ret = filter->filter->init(filter, args, opaque);
+ return ret;
+}
+
diff --git a/contrib/ffmpeg/libavfilter/avfilter.h b/contrib/ffmpeg/libavfilter/avfilter.h
new file mode 100644
index 000000000..1a2aa0f35
--- /dev/null
+++ b/contrib/ffmpeg/libavfilter/avfilter.h
@@ -0,0 +1,616 @@
+/*
+ * filter layer
+ * copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FFMPEG_AVFILTER_H
+#define FFMPEG_AVFILTER_H
+
+#define LIBAVFILTER_VERSION_MAJOR 0
+#define LIBAVFILTER_VERSION_MINOR 0
+#define LIBAVFILTER_VERSION_MICRO 0
+
+#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
+ LIBAVFILTER_VERSION_MINOR, \
+ LIBAVFILTER_VERSION_MICRO)
+#define LIBAVFILTER_VERSION AV_VERSION(LIBAVFILTER_VERSION_MAJOR, \
+ LIBAVFILTER_VERSION_MINOR, \
+ LIBAVFILTER_VERSION_MICRO)
+#define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT
+
+#include <stddef.h>
+#include "avcodec.h"
+
+typedef struct AVFilterContext AVFilterContext;
+typedef struct AVFilterLink AVFilterLink;
+typedef struct AVFilterPad AVFilterPad;
+
+/* TODO: look for other flags which may be useful in this structure (interlace
+ * flags, etc)
+ */
+/**
+ * A reference-counted picture data type used by the filter system. Filters
+ * should not store pointers to this structure directly, but instead use the
+ * AVFilterPicRef structure below.
+ */
+typedef struct AVFilterPic
+{
+ uint8_t *data[4]; ///< picture data for each plane
+ int linesize[4]; ///< number of bytes per line
+ enum PixelFormat format; ///< colorspace
+
+ unsigned refcount; ///< number of references to this image
+
+ /** private data to be used by a custom free function */
+ void *priv;
+ /**
+ * A pointer to the function to deallocate this image if the default
+ * function is not sufficient. This could, for example, add the memory
+ * back into a memory pool to be reused later without the overhead of
+ * reallocating it from scratch.
+ */
+ void (*free)(struct AVFilterPic *pic);
+} AVFilterPic;
+
+/**
+ * A reference to an AVFilterPic. Since filters can manipulate the origin of
+ * a picture to, for example, crop image without any memcpy, the picture origin
+ * and dimensions are per-reference properties. Linesize is also useful for
+ * image flipping, frame to field filters, etc, and so is also per-reference.
+ *
+ * TODO: add anything necessary for frame reordering
+ */
+typedef struct AVFilterPicRef
+{
+ AVFilterPic *pic; ///< the picture that this is a reference to
+ uint8_t *data[4]; ///< picture data for each plane
+ int linesize[4]; ///< number of bytes per line
+ int w; ///< image width
+ int h; ///< image height
+
+ int64_t pts; ///< presentation timestamp in units of 1/AV_TIME_BASE
+
+ AVRational pixel_aspect; ///< pixel aspect ratio
+
+ int perms; ///< permissions
+#define AV_PERM_READ 0x01 ///< can read from the buffer
+#define AV_PERM_WRITE 0x02 ///< can write to the buffer
+#define AV_PERM_PRESERVE 0x04 ///< nobody else can overwrite the buffer
+#define AV_PERM_REUSE 0x08 ///< can output the buffer multiple times, with the same contents each time
+#define AV_PERM_REUSE2 0x10 ///< can output the buffer multiple times, modified each time
+} AVFilterPicRef;
+
+/**
+ * Add a new reference to a picture.
+ * @param ref an existing reference to the picture
+ * @param pmask a bitmask containing the allowable permissions in the new
+ * reference
+ * @return a new reference to the picture with the same properties as the
+ * old, excluding any permissions denied by pmask
+ */
+AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask);
+
+/**
+ * Remove a reference to a picture. If this is the last reference to the
+ * picture, the picture itself is also automatically freed.
+ * @param ref reference to the picture
+ */
+void avfilter_unref_pic(AVFilterPicRef *ref);
+
+/**
+ * A list of supported formats for one end of a filter link. This is used
+ * during the format negotiation process to try to pick the best format to
+ * use to minimize the number of necessary conversions. Each filter gives a
+ * list of the formats supported by each input and output pad. The list
+ * given for each pad need not be distinct - they may be references to the
+ * same list of formats, as is often the case when a filter supports multiple
+ * formats, but will always outut the same format as it is given in input.
+ *
+ * In this way, a list of possible input formats and a list of possible
+ * output formats are associated with each link. When a set of formats is
+ * negotiated over a link, the input and output lists are merged to form a
+ * new list containing only the common elements of each list. In the case
+ * that there were no common elements, a format conversion is necessary.
+ * Otherwise, the lists are merged, and all other links which reference
+ * either of the format lists involved in the merge are also affected.
+ *
+ * For example, consider the filter chain:
+ * filter (a) --> (b) filter (b) --> (c) filter
+ *
+ * where the letters in parenthesis indicate a list of formats supported on
+ * the input or output of the link. Suppose the lists are as follows:
+ * (a) = {A, B}
+ * (b) = {A, B, C}
+ * (c) = {B, C}
+ *
+ * First, the first link's lists are merged, yielding:
+ * filter (a) --> (a) filter (a) --> (c) filter
+ *
+ * Notice that format list (b) now refers to the same list as filter list (a).
+ * Next, the lists for the second link are merged, yielding:
+ * filter (a) --> (a) filter (a) --> (a) filter
+ *
+ * where (a) = {B}.
+ *
+ * Unfortunately, when the format lists at the two ends of a link are merged,
+ * we must ensure that all links which reference either pre-merge format list
+ * get updated as well. Therefore, we have the format list structure store a
+ * pointer to each of the pointers to itself.
+ */
+typedef struct AVFilterFormats AVFilterFormats;
+struct AVFilterFormats
+{
+ unsigned format_count; ///< number of formats
+ int *formats; ///< list of formats
+
+ unsigned refcount; ///< number of references to this list
+ AVFilterFormats ***refs; ///< references to this list
+};
+
+/**
+ * Helper function to create a list of supported formats. This is intended
+ * for use in AVFilter->query_formats().
+ * @param len the number of formats supported
+ * @param ... a list of the supported formats
+ * @return the format list, with no existing references
+ */
+AVFilterFormats *avfilter_make_format_list(int len, ...);
+
+/**
+ * Returns a list of all colorspaces supported by FFmpeg.
+ */
+AVFilterFormats *avfilter_all_colorspaces(void);
+
+/**
+ * Returns a format list which contains the intersection of the formats of
+ * a and b. And all the references of a and b, and a and b will be
+ * deallocated.
+ *
+ * If a and b do not share any common formats, neither is modified, and NULL
+ * is returned.
+ */
+AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b);
+
+/**
+ * Adds *ref as a new reference to f.
+ * That is the pointers will point like in the ascii art below:
+ * ________
+ * | f |<--------.
+ * | ____ | |
+ * | |refs| | __|_
+ * | |* * | | | | |
+ * | |* *--------->|*ref|
+ * | |____| | |____|
+ * |________|
+ */
+void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref);
+
+/**
+ * Remove *ref as a reference to the format list it currently points to,
+ * deallocate that list if this was the last reference, and set *ref to NULL.
+ */
+void avfilter_formats_unref(AVFilterFormats **ref);
+
+/**
+ *
+ * Before After
+ * ________ ________
+ * | f |<---------. | f |<---------.
+ * | ____ | ___|___ | ____ | ___|___
+ * | |refs| | | | | | |refs| | | | | NULL
+ * | |* *--------->|*oldref| | |* *--------->|*newref| ^
+ * | |* * | | |_______| | |* * | | |_______| ___|___
+ * | |____| | | |____| | | | |
+ * |________| |________| |*oldref|
+ * |_______|
+ */
+void avfilter_formats_changeref(AVFilterFormats **oldref,
+ AVFilterFormats **newref);
+
+/**
+ * A filter pad used for either input or output.
+ */
+struct AVFilterPad
+{
+ /**
+ * Pad name. The name is unique among inputs and among outputs, but an
+ * input may have the same name as an output. This may be NULL if this
+ * pad has no need to ever be referenced by name.
+ */
+ const char *name;
+
+ /**
+ * AVFilterPad type. Only video supported now, hopefully someone will
+ * add audio in the future.
+ */
+ enum CodecType type;
+
+ /**
+ * Minimum required permissions on incoming buffers. Any buffers with
+ * insufficient permissions will be automatically copied by the filter
+ * system to a new buffer which provides the needed access permissions.
+ *
+ * Input pads only.
+ */
+ int min_perms;
+
+ /**
+ * Permissions which are not accepted on incoming buffers. Any buffer
+ * which has any of these permissions set be automatically copied by the
+ * filter system to a new buffer which does not have those permissions.
+ * This can be used to easily disallow buffers with AV_PERM_REUSE.
+ *
+ * Input pads only.
+ */
+ int rej_perms;
+
+ /**
+ * Callback called before passing the first slice of a new frame. If
+ * NULL, the filter layer will default to storing a reference to the
+ * picture inside the link structure.
+ *
+ * Input video pads only.
+ */
+ void (*start_frame)(AVFilterLink *link, AVFilterPicRef *picref);
+
+ /**
+ * Callback function to get a buffer. If NULL, the filter system will
+ * handle buffer requests.
+ *
+ * Input video pads only.
+ */
+ AVFilterPicRef *(*get_video_buffer)(AVFilterLink *link, int perms);
+
+ /**
+ * Callback called after the slices of a frame are completely sent. If
+ * NULL, the filter layer will default to releasing the reference stored
+ * in the link structure during start_frame().
+ *
+ * Input video pads only.
+ */
+ void (*end_frame)(AVFilterLink *link);
+
+ /**
+ * Slice drawing callback. This is where a filter receives video data
+ * and should do its processing.
+ *
+ * Input video pads only.
+ */
+ void (*draw_slice)(AVFilterLink *link, int y, int height);
+
+ /**
+ * Frame poll callback. This returns the number of immediately available
+ * frames. It should return a positive value if the next request_frame()
+ * is guaranteed to return one frame (with no delay).
+ *
+ * Defaults to just calling the source poll_frame() method.
+ *
+ * Output video pads only.
+ */
+ int (*poll_frame)(AVFilterLink *link);
+
+ /**
+ * Frame request callback. A call to this should result in at least one
+ * frame being output over the given link. This should return zero on
+ * success, and another value on error.
+ *
+ * Output video pads only.
+ */
+ int (*request_frame)(AVFilterLink *link);
+
+ /**
+ * Link configuration callback.
+ *
+ * For output pads, this should set the link properties such as
+ * width/height. This should NOT set the format property - that is
+ * negotiated between filters by the filter system using the
+ * query_formats() callback before this function is called.
+ *
+ * For input pads, this should check the properties of the link, and update
+ * the filter's internal state as necessary.
+ *
+ * For both input and output filters, this should return zero on success,
+ * and another value on error.
+ */
+ int (*config_props)(AVFilterLink *link);
+};
+
+/** Default handler for start_frame() for video inputs */
+void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref);
+/** Default handler for end_frame() for video inputs */
+void avfilter_default_end_frame(AVFilterLink *link);
+/** Default handler for config_props() for video outputs */
+int avfilter_default_config_output_link(AVFilterLink *link);
+/** Default handler for config_props() for video inputs */
+int avfilter_default_config_input_link (AVFilterLink *link);
+/** Default handler for get_video_buffer() for video inputs */
+AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link,
+ int perms);
+/**
+ * A helper for query_formats() which sets all links to the same list of
+ * formats. If there are no links hooked to this filter, the list of formats is
+ * freed.
+ */
+void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats);
+/** Default handler for query_formats() */
+int avfilter_default_query_formats(AVFilterContext *ctx);
+
+/**
+ * Filter definition. This defines the pads a filter contains, and all the
+ * callback functions used to interact with the filter.
+ */
+typedef struct
+{
+ const char *name; ///< filter name
+
+ int priv_size; ///< size of private data to allocate for the filter
+
+ /**
+ * Filter initialization function. Args contains the user-supplied
+ * parameters. FIXME: maybe an AVOption-based system would be better?
+ * opaque is data provided by the code requesting creation of the filter,
+ * and is used to pass data to the filter.
+ */
+ int (*init)(AVFilterContext *ctx, const char *args, void *opaque);
+
+ /**
+ * Filter uninitialization function. Should deallocate any memory held
+ * by the filter, release any picture references, etc. This does not need
+ * to deallocate the AVFilterContext->priv memory itself.
+ */
+ void (*uninit)(AVFilterContext *ctx);
+
+ /**
+ * Query formats supported by the filter and its pads. Should set the
+ * in_formats for links connected to its output pads, and out_formats
+ * for links connected to its input pads.
+ *
+ * Should return zero on success.
+ */
+ int (*query_formats)(AVFilterContext *);
+
+ const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none
+ const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none
+} AVFilter;
+
+/** An instance of a filter */
+struct AVFilterContext
+{
+ AVClass *av_class; ///< needed for av_log()
+
+ AVFilter *filter; ///< the AVFilter of which this is an instance
+
+ char *name; ///< name of this filter instance
+
+ unsigned input_count; ///< number of input pads
+ AVFilterPad *input_pads; ///< array of input pads
+ AVFilterLink **inputs; ///< array of pointers to input links
+
+ unsigned output_count; ///< number of output pads
+ AVFilterPad *output_pads; ///< array of output pads
+ AVFilterLink **outputs; ///< array of pointers to output links
+
+ void *priv; ///< private data for use by the filter
+};
+
+/**
+ * A link between two filters. This contains pointers to the source and
+ * destination filters between which this link exists, and the indices of
+ * the pads involved. In addition, this link also contains the parameters
+ * which have been negotiated and agreed upon between the filter, such as
+ * image dimensions, format, etc
+ */
+struct AVFilterLink
+{
+ AVFilterContext *src; ///< source filter
+ unsigned int srcpad; ///< index of the output pad on the source filter
+
+ AVFilterContext *dst; ///< dest filter
+ unsigned int dstpad; ///< index of the input pad on the dest filter
+
+ /** stage of the initialization of the link properties (dimensions, etc) */
+ enum {
+ AVLINK_UNINIT = 0, ///< not started
+ AVLINK_STARTINIT, ///< started, but incomplete
+ AVLINK_INIT ///< complete
+ } init_state;
+
+ int w; ///< agreed upon image width
+ int h; ///< agreed upon image height
+ enum PixelFormat format; ///< agreed upon image colorspace
+
+ /**
+ * Lists of formats supported by the input and output filters respectively.
+ * These lists are used for negotiating the format to actually be used,
+ * which will be loaded into the format member, above, when chosen.
+ */
+ AVFilterFormats *in_formats;
+ AVFilterFormats *out_formats;
+
+ /**
+ * The picture reference currently being sent across the link by the source
+ * filter. This is used internally by the filter system to allow
+ * automatic copying of pictures which do not have sufficient permissions
+ * for the destination. This should not be accessed directly by the
+ * filters.
+ */
+ AVFilterPicRef *srcpic;
+
+ AVFilterPicRef *cur_pic;
+ AVFilterPicRef *outpic;
+};
+
+/**
+ * Link two filters together.
+ * @param src the source filter
+ * @param srcpad index of the output pad on the source filter
+ * @param dst the destination filter
+ * @param dstpad index of the input pad on the destination filter
+ * @return zero on success
+ */
+int avfilter_link(AVFilterContext *src, unsigned srcpad,
+ AVFilterContext *dst, unsigned dstpad);
+
+/**
+ * Negotiate the colorspace, dimensions, etc of all inputs to a filter.
+ * @param filter the filter to negotiate the properties for its inputs
+ * @return zero on successful negotiation
+ */
+int avfilter_config_links(AVFilterContext *filter);
+
+/**
+ * Request a picture buffer with a specific set of permissions
+ * @param link the output link to the filter from which the picture will
+ * be requested
+ * @param perms the required access permissions
+ * @return A reference to the picture. This must be unreferenced with
+ * avfilter_unref_pic when you are finished with it.
+ */
+AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms);
+
+/**
+ * Request an input frame from the filter at the other end of the link.
+ * @param link the input link
+ * @return zero on success
+ */
+int avfilter_request_frame(AVFilterLink *link);
+
+/**
+ * Poll a frame from the filter chain.
+ * @param link the input link
+ * @return the number of imediately available frames
+ */
+int avfilter_poll_frame(AVFilterLink *link);
+
+/**
+ * Notify the next filter of the start of a frame.
+ * @param link the output link the frame will be sent over
+ * @param picref A reference to the frame about to be sent. The data for this
+ * frame need only be valid once draw_slice() is called for that
+ * portion. The receiving filter will free this reference when
+ * it no longer needs it.
+ */
+void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref);
+
+/**
+ * Notify the next filter that the current frame has finished
+ * @param link the output link the frame was sent over
+ */
+void avfilter_end_frame(AVFilterLink *link);
+
+/**
+ * Send a slice to the next filter.
+ * @param link the output link over which the frame is being sent
+ * @param y offset in pixels from the top of the image for this slice
+ * @param h height of this slice in pixels
+ */
+void avfilter_draw_slice(AVFilterLink *link, int y, int h);
+
+/** Initialize the filter system. Registers all builtin filters */
+void avfilter_register_all(void);
+
+/** Uninitialize the filter system. Unregisters all filters */
+void avfilter_uninit(void);
+
+/**
+ * Register a filter. This is only needed if you plan to use
+ * avfilter_get_by_name later to lookup the AVFilter structure by name. A
+ * filter can still by instantiated with avfilter_open even if it is not
+ * registered.
+ * @param filter the filter to register
+ */
+void avfilter_register(AVFilter *filter);
+
+/**
+ * Gets a filter definition matching the given name.
+ * @param name the filter name to find
+ * @return the filter definition, if any matching one is registered.
+ * NULL if none found.
+ */
+AVFilter *avfilter_get_by_name(const char *name);
+
+/**
+ * Create a filter instance.
+ * @param filter the filter to create an instance of
+ * @param inst_name Name to give to the new instance. Can be NULL for none.
+ * @return Pointer to the new instance on success. NULL on failure.
+ */
+AVFilterContext *avfilter_open(AVFilter *filter, const char *inst_name);
+
+/**
+ * Initialize a filter.
+ * @param filter the filter to initialize
+ * @param args A string of parameters to use when initializing the filter.
+ * The format and meaning of this string varies by filter.
+ * @param opaque Any extra non-string data needed by the filter. The meaning
+ * of this parameter varies by filter.
+ * @return zero on success
+ */
+int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque);
+
+/**
+ * Destroy a filter.
+ * @param filter the filter to destroy
+ */
+void avfilter_destroy(AVFilterContext *filter);
+
+/**
+ * Insert a filter in the middle of an existing link.
+ * @param link the link into which the filter should be inserted
+ * @param filt the filter to be inserted
+ * @param in the input pad on the filter to connect
+ * @param out the output pad on the filter to connect
+ * @return zero on success
+ */
+int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
+ unsigned in, unsigned out);
+
+/**
+ * Insert a new pad.
+ * @param idx Insertion point. Pad is inserted at the end if this point
+ * is beyond the end of the list of pads.
+ * @param count Pointer to the number of pads in the list
+ * @param padidx_off Offset within an AVFilterLink structure to the element
+ * to increment when inserting a new pad causes link
+ * numbering to change
+ * @param pads Pointer to the pointer to the beginning of the list of pads
+ * @param links Pointer to the pointer to the beginning of the list of links
+ * @param newpad The new pad to add. A copy is made when adding.
+ */
+void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
+ AVFilterPad **pads, AVFilterLink ***links,
+ AVFilterPad *newpad);
+
+/** insert a new input pad for the filter */
+static inline void avfilter_insert_inpad(AVFilterContext *f, unsigned index,
+ AVFilterPad *p)
+{
+ avfilter_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad),
+ &f->input_pads, &f->inputs, p);
+}
+
+/** insert a new output pad for the filter */
+static inline void avfilter_insert_outpad(AVFilterContext *f, unsigned index,
+ AVFilterPad *p)
+{
+ avfilter_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad),
+ &f->output_pads, &f->outputs, p);
+}
+
+#endif /* FFMPEG_AVFILTER_H */
diff --git a/contrib/ffmpeg/libavfilter/defaults.c b/contrib/ffmpeg/libavfilter/defaults.c
new file mode 100644
index 000000000..ab184973a
--- /dev/null
+++ b/contrib/ffmpeg/libavfilter/defaults.c
@@ -0,0 +1,158 @@
+/*
+ * Filter layer - default implementations
+ * copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avfilter.h"
+#include "imgconvert.h"
+
+/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
+void avfilter_default_free_video_buffer(AVFilterPic *pic)
+{
+ av_free(pic->data[0]);
+ av_free(pic);
+}
+
+#define ALIGN(a) do{ \
+ (a) = ((a) + 15) & (~15); \
+ } while(0);
+
+/* TODO: set the buffer's priv member to a context structure for the whole
+ * filter chain. This will allow for a buffer pool instead of the constant
+ * alloc & free cycle currently implemented. */
+AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms)
+{
+ AVFilterPic *pic = av_mallocz(sizeof(AVFilterPic));
+ AVFilterPicRef *ref = av_mallocz(sizeof(AVFilterPicRef));
+ int i, tempsize;
+ char *buf;
+
+ ref->pic = pic;
+ ref->w = link->w;
+ ref->h = link->h;
+
+ /* make sure the buffer gets read permission or it's useless for output */
+ ref->perms = perms | AV_PERM_READ;
+
+ pic->refcount = 1;
+ pic->format = link->format;
+ pic->free = avfilter_default_free_video_buffer;
+ ff_fill_linesize((AVPicture *)pic, pic->format, ref->w);
+
+ for (i=0; i<4;i++)
+ ALIGN(pic->linesize[i]);
+
+ tempsize = ff_fill_pointer((AVPicture *)pic, NULL, pic->format, ref->h);
+ buf = av_malloc(tempsize);
+ ff_fill_pointer((AVPicture *)pic, buf, pic->format, ref->h);
+
+ memcpy(ref->data, pic->data, sizeof(pic->data));
+ memcpy(ref->linesize, pic->linesize, sizeof(pic->linesize));
+
+ return ref;
+}
+
+void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
+{
+ AVFilterLink *out = NULL;
+
+ if(link->dst->output_count)
+ out = link->dst->outputs[0];
+
+ if(out) {
+ out->outpic = avfilter_get_video_buffer(out, AV_PERM_WRITE);
+ out->outpic->pts = picref->pts;
+ avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0));
+ }
+}
+
+void avfilter_default_end_frame(AVFilterLink *link)
+{
+ AVFilterLink *out = NULL;
+
+ if(link->dst->output_count)
+ out = link->dst->outputs[0];
+
+ avfilter_unref_pic(link->cur_pic);
+ link->cur_pic = NULL;
+
+ if(out) {
+ if(out->outpic) {
+ avfilter_unref_pic(out->outpic);
+ out->outpic = NULL;
+ }
+ avfilter_end_frame(out);
+ }
+}
+
+/**
+ * default config_link() implementation for output video links to simplify
+ * the implementation of one input one output video filters */
+int avfilter_default_config_output_link(AVFilterLink *link)
+{
+ if(link->src->input_count && link->src->inputs[0]) {
+ link->w = link->src->inputs[0]->w;
+ link->h = link->src->inputs[0]->h;
+ } else {
+ /* XXX: any non-simple filter which would cause this branch to be taken
+ * really should implement its own config_props() for this link. */
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * A helper for query_formats() which sets all links to the same list of
+ * formats. If there are no links hooked to this filter, the list of formats is
+ * freed.
+ *
+ * FIXME: this will need changed for filters with a mix of pad types
+ * (video + audio, etc)
+ */
+void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
+{
+ int count = 0, i;
+
+ for(i = 0; i < ctx->input_count; i ++) {
+ if(ctx->inputs[i]) {
+ avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats);
+ count ++;
+ }
+ }
+ for(i = 0; i < ctx->output_count; i ++) {
+ if(ctx->outputs[i]) {
+ avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats);
+ count ++;
+ }
+ }
+
+ if(!count) {
+ av_free(formats->formats);
+ av_free(formats->refs);
+ av_free(formats);
+ }
+}
+
+int avfilter_default_query_formats(AVFilterContext *ctx)
+{
+ avfilter_set_common_formats(ctx, avfilter_all_colorspaces());
+ return 0;
+}
+
diff --git a/contrib/ffmpeg/libavfilter/formats.c b/contrib/ffmpeg/libavfilter/formats.c
new file mode 100644
index 000000000..33fec163a
--- /dev/null
+++ b/contrib/ffmpeg/libavfilter/formats.c
@@ -0,0 +1,148 @@
+/*
+ * Filter layer - format negotiation
+ * copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avfilter.h"
+
+/**
+ * Add all refs from a to ret and destroy a.
+ */
+static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a)
+{
+ int i;
+
+ for(i = 0; i < a->refcount; i ++) {
+ ret->refs[ret->refcount] = a->refs[i];
+ *ret->refs[ret->refcount++] = ret;
+ }
+
+ av_free(a->refs);
+ av_free(a->formats);
+ av_free(a);
+}
+
+AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
+{
+ AVFilterFormats *ret;
+ unsigned i, j, k = 0;
+
+ ret = av_mallocz(sizeof(AVFilterFormats));
+
+ /* merge list of formats */
+ ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
+ b->format_count));
+ for(i = 0; i < a->format_count; i ++)
+ for(j = 0; j < b->format_count; j ++)
+ if(a->formats[i] == b->formats[j])
+ ret->formats[k++] = a->formats[i];
+
+ ret->format_count = k;
+ /* check that there was at least one common format */
+ if(!ret->format_count) {
+ av_free(ret->formats);
+ av_free(ret);
+ return NULL;
+ }
+
+ ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount));
+
+ merge_ref(ret, a);
+ merge_ref(ret, b);
+
+ return ret;
+}
+
+AVFilterFormats *avfilter_make_format_list(int len, ...)
+{
+ AVFilterFormats *ret;
+ int i;
+ va_list vl;
+
+ ret = av_mallocz(sizeof(AVFilterFormats));
+ ret->formats = av_malloc(sizeof(*ret->formats) * len);
+ ret->format_count = len;
+
+ va_start(vl, len);
+ for(i = 0; i < len; i ++)
+ ret->formats[i] = va_arg(vl, int);
+ va_end(vl);
+
+ return ret;
+}
+
+AVFilterFormats *avfilter_all_colorspaces(void)
+{
+ AVFilterFormats *ret;
+ int i;
+
+ ret = av_mallocz(sizeof(AVFilterFormats));
+ ret->formats = av_malloc(sizeof(*ret->formats) * PIX_FMT_NB);
+ ret->format_count = PIX_FMT_NB;
+
+ for(i = 0; i < PIX_FMT_NB; i ++)
+ ret->formats[i] = i;
+
+ return ret;
+}
+
+void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
+{
+ *ref = f;
+ f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount);
+ f->refs[f->refcount-1] = ref;
+}
+
+static int find_ref_index(AVFilterFormats **ref)
+{
+ int i;
+ for(i = 0; i < (*ref)->refcount; i ++)
+ if((*ref)->refs[i] == ref)
+ return i;
+ return -1;
+}
+
+void avfilter_formats_unref(AVFilterFormats **ref)
+{
+ int idx = find_ref_index(ref);
+
+ if(idx >= 0)
+ memmove((*ref)->refs + idx, (*ref)->refs + idx+1,
+ sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1));
+
+ if(!--(*ref)->refcount) {
+ av_free((*ref)->formats);
+ av_free((*ref)->refs);
+ av_free(*ref);
+ }
+ *ref = NULL;
+}
+
+void avfilter_formats_changeref(AVFilterFormats **oldref,
+ AVFilterFormats **newref)
+{
+ int idx = find_ref_index(oldref);
+
+ if(idx >= 0) {
+ (*oldref)->refs[idx] = newref;
+ *newref = *oldref;
+ *oldref = NULL;
+ }
+}
+