]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/avfilter.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavfilter / avfilter.c
index a57677c0e4462515275b77e188238419831a9720..d73698681edd627f45800f48fbb42db44bdbb11a 100644 (file)
@@ -26,6 +26,7 @@
 #include "libavutil/audioconvert.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
 #include "avfilter.h"
 #include "internal.h"
 
@@ -44,6 +45,15 @@ const char *avfilter_license(void)
     return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
 }
 
+static void command_queue_pop(AVFilterContext *filter)
+{
+    AVFilterCommand *c= filter->command_queue;
+    av_freep(&c->arg);
+    av_freep(&c->command);
+    filter->command_queue= c->next;
+    av_free(c);
+}
+
 AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
 {
     AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
@@ -221,6 +231,9 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
     if (link->out_chlayouts)
         avfilter_formats_changeref(&link->out_chlayouts,
                                    &filt->outputs[filt_dstpad_idx]->out_chlayouts);
+    if (link->out_packing)
+        avfilter_formats_changeref(&link->out_packing,
+                                   &filt->outputs[filt_dstpad_idx]->out_packing);
 
     return 0;
 }
@@ -248,24 +261,51 @@ int avfilter_config_links(AVFilterContext *filter)
             if ((ret = avfilter_config_links(link->src)) < 0)
                 return ret;
 
-            if (!(config_link = link->srcpad->config_props))
-                config_link  = avfilter_default_config_output_link;
-            if ((ret = config_link(link)) < 0)
+            if (!(config_link = link->srcpad->config_props)) {
+                if (link->src->input_count != 1) {
+                    av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
+                                                    "with more than one input "
+                                                    "must set config_props() "
+                                                    "callbacks on all outputs\n");
+                    return AVERROR(EINVAL);
+                }
+            } else if ((ret = config_link(link)) < 0)
                 return ret;
 
-            if (link->time_base.num == 0 && link->time_base.den == 0)
-                link->time_base = link->src && link->src->input_count ?
-                    link->src->inputs[0]->time_base : AV_TIME_BASE_Q;
-
-            if (link->sample_aspect_ratio.num == 0 && link->sample_aspect_ratio.den == 0)
-                link->sample_aspect_ratio = link->src->input_count ?
-                    link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1};
-
-            if (link->sample_rate == 0 && link->src && link->src->input_count)
-                link->sample_rate = link->src->inputs[0]->sample_rate;
-
-            if (link->channel_layout == 0 && link->src && link->src->input_count)
-                link->channel_layout = link->src->inputs[0]->channel_layout;
+            switch (link->type) {
+            case AVMEDIA_TYPE_VIDEO:
+                if (!link->time_base.num && !link->time_base.den)
+                    link->time_base = link->src->input_count ?
+                        link->src->inputs[0]->time_base : AV_TIME_BASE_Q;
+
+                if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
+                    link->sample_aspect_ratio = link->src->input_count ?
+                        link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1};
+
+                if (link->src->input_count) {
+                    if (!link->w)
+                        link->w = link->src->inputs[0]->w;
+                    if (!link->h)
+                        link->h = link->src->inputs[0]->h;
+                } else if (!link->w || !link->h) {
+                    av_log(link->src, AV_LOG_ERROR,
+                           "Video source filters must set their output link's "
+                           "width and height\n");
+                    return AVERROR(EINVAL);
+                }
+                break;
+
+            case AVMEDIA_TYPE_AUDIO:
+                if (link->src->input_count) {
+                    if (!link->sample_rate)
+                        link->sample_rate = link->src->inputs[0]->sample_rate;
+                } else if (!link->sample_rate) {
+                    av_log(link->src, AV_LOG_ERROR,
+                           "Audio source filters must set their output link's "
+                           "sample_rate\n");
+                    return AVERROR(EINVAL);
+                }
+            }
 
             if ((config_link = link->dstpad->config_props))
                 if ((ret = config_link(link)) < 0)
@@ -503,6 +543,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
     void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
     AVFilterPad *dst = link->dstpad;
     int perms = picref->perms;
+    AVFilterCommand *cmd= link->dst->command_queue;
 
     FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
 
@@ -525,6 +566,12 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
     else
         link->cur_buf = picref;
 
+    while(cmd && cmd->time <= picref->pts * av_q2d(link->time_base)){
+        avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
+        command_queue_pop(link->dst);
+        cmd= link->dst->command_queue;
+    }
+
     start_frame(link, link->cur_buf);
 }
 
@@ -586,6 +633,17 @@ void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
     draw_slice(link, y, h, slice_dir);
 }
 
+int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
+{
+    if(!strcmp(cmd, "ping")){
+        av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name);
+        return 0;
+    }else if(filter->filter->process_command) {
+        return filter->filter->process_command(filter, cmd, arg, res, res_len, flags);
+    }
+    return AVERROR(ENOSYS);
+}
+
 void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
 {
     void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
@@ -773,6 +831,9 @@ void avfilter_free(AVFilterContext *filter)
     av_freep(&filter->inputs);
     av_freep(&filter->outputs);
     av_freep(&filter->priv);
+    while(filter->command_queue){
+        command_queue_pop(filter);
+    }
     av_free(filter);
 }