/*
- * Filter layer
+ * filter layer
* copyright (c) 2007 Bobby Bingham
*
* This file is part of FFmpeg.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
#include "avfilter.h"
-#include "allfilters.h"
+#include "imgconvert.h"
/** list of registered filters */
struct FilterList
void avfilter_unref_pic(AVFilterPicRef *ref)
{
- if(-- ref->pic->refcount == 0)
+ if(!(--ref->pic->refcount))
ref->pic->free(ref->pic);
av_free(ref);
}
(*count) ++;
for(i = idx+1; i < *count; i ++)
if(*links[i])
- (*(unsigned *)((uint8_t *)(*links[i]) + padidx_off)) ++;
+ (*(unsigned *)((uint8_t *) *links[i] + padidx_off)) ++;
}
int avfilter_link(AVFilterContext *src, unsigned srcpad,
return -1;
src->outputs[srcpad] =
- dst->inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
+ dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
link->src = src;
link->dst = dst;
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
unsigned in, unsigned out)
{
- AVFilterFormats *formats;
-
- av_log(NULL, AV_LOG_INFO, "auto-inserting filter '%s'\n",
+ av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s'\n",
filt->filter->name);
link->dst->inputs[link->dstpad] = NULL;
/* if any information on supported colorspaces already exists on the
* link, we need to preserve that */
- if((formats = link->out_formats))
+ if(link->out_formats)
avfilter_formats_changeref(&link->out_formats,
&filt->outputs[out]->out_formats);
unsigned i;
for(i = 0; i < filter->input_count; i ++) {
- AVFilterLink *link;
+ AVFilterLink *link = filter->inputs[i];
- if(!(link = filter->inputs[i])) continue;
+ if(!link) continue;
switch(link->init_state) {
case AVLINK_INIT:
continue;
case AVLINK_STARTINIT:
- av_log(filter, AV_LOG_ERROR, "circular filter chain detected\n");
- return -1;
+ av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
+ return 0;
case AVLINK_UNINIT:
link->init_state = AVLINK_STARTINIT;
return -1;
if((config_link = link_dpad(link).config_props))
- if(config_link(link))
- return -1;
+ if(config_link(link))
+ return -1;
link->init_state = AVLINK_INIT;
}
if(link_spad(link).poll_frame)
return link_spad(link).poll_frame(link);
- else
- 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]));
- }
+
+ 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;
}
void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
{
void (*start_frame)(AVFilterLink *, AVFilterPicRef *);
+ AVFilterPad *dst = &link_dpad(link);
- if(!(start_frame = link_dpad(link).start_frame))
+ if(!(start_frame = dst->start_frame))
start_frame = avfilter_default_start_frame;
/* prepare to copy the picture if it has insufficient permissions */
- if((link_dpad(link).min_perms & picref->perms) != link_dpad(link).min_perms ||
- link_dpad(link).rej_perms & picref->perms) {
+ 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",
link_dpad(link).min_perms, link_dpad(link).rej_perms);
*/
- link->cur_pic = avfilter_default_get_video_buffer(link, link_dpad(link).min_perms);
+ link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms);
link->srcpic = picref;
link->cur_pic->pts = link->srcpic->pts;
}
if(link->srcpic) {
avcodec_get_chroma_sub_sample(link->format, &hsub, &vsub);
- src[0] = link->srcpic-> data[0] + y * link->srcpic-> linesize[0];
- dst[0] = link->cur_pic->data[0] + y * link->cur_pic->linesize[0];
- for(i = 1; i < 4; i ++) {
+ for(i = 0; i < 4; i ++) {
if(link->srcpic->data[i]) {
- src[i] = link->srcpic-> data[i] + (y >> vsub) * link->srcpic-> linesize[i];
- dst[i] = link->cur_pic->data[i] + (y >> vsub) * link->cur_pic->linesize[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(j = 0; j < h; j ++) {
- memcpy(dst[0], src[0], link->cur_pic->linesize[0]);
- src[0] += link->srcpic ->linesize[0];
- dst[0] += link->cur_pic->linesize[0];
- }
- for(i = 1; i < 4; i ++) {
+
+ 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 >> vsub; j ++) {
- memcpy(dst[i], src[i], link->cur_pic->linesize[i]);
+ 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)
- return;
-
- link_dpad(link).draw_slice(link, y, h);
+ if(link_dpad(link).draw_slice)
+ link_dpad(link).draw_slice(link, y, h);
}
AVFilter *avfilter_get_by_name(const char *name)
filters = newfilt;
}
-void avfilter_init(void)
-{
- avfilter_register(&avfilter_vf_crop);
- avfilter_register(&avfilter_vf_fifo);
- avfilter_register(&avfilter_vf_format);
- avfilter_register(&avfilter_vf_fps);
- avfilter_register(&avfilter_vf_graph);
- avfilter_register(&avfilter_vf_graphdesc);
- avfilter_register(&avfilter_vf_graphfile);
- avfilter_register(&avfilter_vf_hflip);
- avfilter_register(&avfilter_vf_negate);
- avfilter_register(&avfilter_vf_noformat);
- avfilter_register(&avfilter_vf_overlay);
- avfilter_register(&avfilter_vf_rotate);
- avfilter_register(&avfilter_vf_scale);
- avfilter_register(&avfilter_vf_setpts);
- avfilter_register(&avfilter_vf_slicify);
- avfilter_register(&avfilter_vf_split);
- avfilter_register(&avfilter_vf_transpose);
- avfilter_register(&avfilter_vf_vflip);
-#ifdef CONFIG_AVFILTER_LAVF
- avfilter_register(&avfilter_vsrc_movie);
-#endif //CONFIG_AVFILTER_LAVF
-}
-
void avfilter_uninit(void)
{
struct FilterList *tmp;
return filter->filter->name;
}
+static const AVClass avfilter_class = {
+ "AVFilter",
+ filter_name
+};
+
AVFilterContext *avfilter_open(AVFilter *filter, const char *inst_name)
{
AVFilterContext *ret;
ret = av_malloc(sizeof(AVFilterContext));
- ret->av_class = av_mallocz(sizeof(AVClass));
- ret->av_class->item_name = filter_name;
+ ret->av_class = &avfilter_class;
ret->filter = filter;
ret->name = inst_name ? av_strdup(inst_name) : NULL;
ret->priv = av_mallocz(filter->priv_size);
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;
+ int ret=0;
if(filter->filter->init)
- if((ret = filter->filter->init(filter, args, opaque))) return ret;
- return 0;
+ ret = filter->filter->init(filter, args, opaque);
+ return ret;
}