]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/avfilter.c
Add a filter to cut video frames into smaller slices.
[ffmpeg] / libavfilter / avfilter.c
index c78862354fd3f9a16dd7ef8fadc3fc3688a3501a..3e2d60ad037b51cbc87fcc08a328d3b3a63c2fed 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -55,8 +56,8 @@ AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms)
     pic->free = avfilter_default_free_video_buffer;
     avpicture_alloc((AVPicture *)pic, pic->format, ref->w, ref->h);
 
-    memcpy(ref->data, pic->data, sizeof(int *) * 4);
-    memcpy(ref->linesize, pic->linesize, sizeof(int *) * 4);
+    memcpy(ref->data,     pic->data,     sizeof(pic->data));
+    memcpy(ref->linesize, pic->linesize, sizeof(pic->linesize));
 
     return ref;
 }
@@ -87,10 +88,30 @@ void avfilter_unref_pic(AVFilterPicRef *ref)
     av_free(ref);
 }
 
+/**
+ * default config_link() implementation for output video links to simplify
+ * the implementation of one input one output video filters */
+static int default_config_output_link(AVFilterLink *link)
+{
+    link->w = link->src->inputs[0]->w;
+    link->h = link->src->inputs[0]->h;
+
+    return 0;
+}
+
+/**
+ * default query_formats() implementation for output video links to simplify
+ * the implementation of one input one output video filters */
+static int *default_query_output_formats(AVFilterLink *link)
+{
+    return avfilter_make_format_list(1, link->src->inputs[0]->format);
+}
+
 int avfilter_link(AVFilterContext *src, unsigned srcpad,
                   AVFilterContext *dst, unsigned dstpad)
 {
     AVFilterLink *link;
+    int *fmts[2], i, j;
 
     if(src->outputs[srcpad] || dst->inputs[dstpad])
         return -1;
@@ -104,7 +125,38 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad,
     link->dstpad = dstpad;
     link->cur_pic = NULL;
 
-    src->filter->outputs[dstpad].set_video_props(link);
+    /* find a format both filters support - TODO: auto-insert conversion filter */
+    if(src->filter->outputs[srcpad].query_formats)
+        fmts[0] = src->filter->outputs[srcpad].query_formats(link);
+    else
+        fmts[0] = default_query_output_formats(link);
+    fmts[1] = dst->filter-> inputs[dstpad].query_formats(link);
+    for(i = 0; fmts[0][i] != -1; i ++)
+        for(j = 0; fmts[1][j] != -1; j ++)
+            if(fmts[0][i] == fmts[1][j]) {
+                link->format = fmts[0][i];
+                goto format_done;
+            }
+
+format_done:
+    av_free(fmts[0]);
+    av_free(fmts[1]);
+    if(link->format == -1) {
+        /* failed to find a format.  fail at creating the link */
+        av_free(link);
+        src->outputs[srcpad] = NULL;
+        dst->inputs[dstpad]  = NULL;
+        return -1;
+    }
+
+    if (src->filter->outputs[srcpad].config_props)
+        src->filter->outputs[srcpad].config_props(link);
+    else
+        default_config_output_link(link);
+
+    if (dst->filter->inputs[dstpad].config_props)
+        dst->filter->inputs[dstpad].config_props(link);
+
     return 0;
 }
 
@@ -186,6 +238,7 @@ void avfilter_init(void)
     avfilter_register(&vsrc_dummy);
     avfilter_register(&vf_crop);
     avfilter_register(&vf_passthrough);
+    avfilter_register(&vf_slicify);
     avfilter_register(&vo_sdl);
 }
 
@@ -257,15 +310,27 @@ AVFilterContext *avfilter_create_by_name(char *name)
     return avfilter_create(filt);
 }
 
-int avfilter_init_filter(AVFilterContext *filter)
+int avfilter_init_filter(AVFilterContext *filter, const char *args)
 {
     int ret, i;
 
     if(filter->filter->init)
-        if((ret = filter->filter->init(filter))) return ret;
-    for(i = 0; i < pad_count(filter->filter->outputs); i ++)
-        if(filter->outputs[i])
-            filter->filter->outputs[i].set_video_props(filter->outputs[i]);
+        if((ret = filter->filter->init(filter, args))) return ret;
     return 0;
 }
 
+int *avfilter_make_format_list(int len, ...)
+{
+    int *ret, i;
+    va_list vl;
+
+    ret = av_malloc(sizeof(int) * (len + 1));
+    va_start(vl, len);
+    for(i = 0; i < len; i ++)
+        ret[i] = va_arg(vl, int);
+    va_end(vl);
+    ret[len] = -1;
+
+    return ret;
+}
+