Based on code by Michael Niedermayer.
---
 avconv.c                  |   12 +-------
 libavfilter/vsrc_buffer.c |   61 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/avconv.c b/avconv.c
index f3e6e28..56a8ee4 100644
--- a/avconv.c
+++ b/avconv.c
@@ -1244,6 +1244,7 @@ static void do_video_resample(OutputStream *ost,
     AVCodecContext *dec = ist->st->codec;
     *out_picture = in_picture;
 
+#if !CONFIG_AVFILTER
     resample_changed = ost->resample_width   != dec->width  ||
                        ost->resample_height  != dec->height ||
                        ost->resample_pix_fmt != dec->pix_fmt;
@@ -1258,7 +1259,6 @@ static void do_video_resample(OutputStream *ost,
             ost->video_resample = 1;
     }
 
-#if !CONFIG_AVFILTER
     if (ost->video_resample) {
         *out_picture = &ost->pict_tmp;
         if (resample_changed) {
@@ -1280,20 +1280,12 @@ static void do_video_resample(OutputStream *ost,
         sws_scale(ost->img_resample_ctx, in_picture->data, 
in_picture->linesize,
               0, ost->resample_height, (*out_picture)->data, 
(*out_picture)->linesize);
     }
-#else
-    if (resample_changed) {
-        avfilter_graph_free(&ost->graph);
-        if (configure_video_filters(ist, ost)) {
-            av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
-            exit_program(1);
-        }
-    }
-#endif
     if (resample_changed) {
         ost->resample_width   = dec->width;
         ost->resample_height  = dec->height;
         ost->resample_pix_fmt = dec->pix_fmt;
     }
+#endif
 }
 
 
diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c
index 2755da8..7918094 100644
--- a/libavfilter/vsrc_buffer.c
+++ b/libavfilter/vsrc_buffer.c
@@ -36,10 +36,59 @@ typedef struct {
     AVRational        pixel_aspect;
 } BufferSourceContext;
 
+static int insert_scaler(AVFilterContext *s, int width, int height,
+                         int pix_fmt)
+{
+    BufferSourceContext *c = s->priv;
+    AVFilterContext *scale = s->outputs[0]->dst;
+    AVFilterLink *link;
+    char scale_param[64];
+    int ret;
+
+    av_log(s, AV_LOG_INFO,
+            "Buffer video input changed from size:%dx%d fmt:%s to size:%dx%d 
fmt:%s\n",
+            c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name,
+            width, height, av_pix_fmt_descriptors[pix_fmt].name);
+
+    if (!scale || strcmp(scale->filter->name, "scale")) {
+        AVFilter *f = avfilter_get_by_name("scale");
+
+        av_log(s, AV_LOG_INFO, "Inserting scaler filter\n");
+        if ((ret = avfilter_open(&scale, f, "Input equalizer")) < 0)
+            return ret;
+
+        snprintf(scale_param, sizeof(scale_param), "%d:%d", c->w, c->h);
+        if ((ret = avfilter_init_filter(scale, scale_param, NULL)) < 0 ||
+            (ret = avfilter_insert_filter(s->outputs[0], scale, 0, 0)) < 0) {
+            avfilter_free(scale);
+            return ret;
+        }
+
+        scale->outputs[0]->time_base = scale->inputs[0]->time_base;
+        scale->outputs[0]->format    = c->pix_fmt;
+    } else if (!strcmp(scale->filter->name, "scale")) {
+        snprintf(scale_param, sizeof(scale_param), "%d:%d",
+                 scale->outputs[0]->w, scale->outputs[0]->h);
+        if ((ret = avfilter_init_filter(scale, scale_param, NULL)) < 0)
+            return ret;
+    }
+
+    c->pix_fmt = scale->inputs[0]->format = pix_fmt;
+    c->w       = scale->inputs[0]->w      = width;
+    c->h       = scale->inputs[0]->h      = height;
+
+    link = scale->outputs[0];
+    if ((ret =  link->srcpad->config_props(link)) < 0)
+        return ret;
+
+    return 0;
+}
+
 int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
                              int64_t pts, AVRational pixel_aspect)
 {
     BufferSourceContext *c = buffer_filter->priv;
+    int ret;
 
     if (c->buf) {
         av_log(buffer_filter, AV_LOG_ERROR,
@@ -49,6 +98,12 @@ int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, 
AVFrame *frame,
         //return -1;
     }
 
+    /* on resolution change add a scaler */
+    if (frame->width != c->w || frame->height != c->h || frame->format != 
c->pix_fmt)
+        if ((ret = insert_scaler(buffer_filter, frame->width, frame->height,
+                                 frame->format)) < 0)
+            return ret;
+
     c->buf = avfilter_get_video_buffer(buffer_filter->outputs[0], 
AV_PERM_WRITE,
                                        c->w, c->h);
     av_image_copy(c->buf->data, c->buf->linesize, frame->data, frame->linesize,
@@ -64,6 +119,7 @@ int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, 
AVFrame *frame,
 int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
 {
     BufferSourceContext *c = s->priv;
+    int ret;
 
     if (c->buf) {
         av_log(s, AV_LOG_ERROR,
@@ -73,6 +129,11 @@ int av_buffersrc_buffer(AVFilterContext *s, 
AVFilterBufferRef *buf)
         return AVERROR(EINVAL);
     }
 
+    /* on resolution change add a scaler */
+    if (buf->video->w != c->w || buf->video->h != c->h || buf->format != 
c->pix_fmt)
+        if ((ret = insert_scaler(s, buf->video->w, buf->video->h, 
buf->format)) < 0)
+            return ret;
+
     c->buf = buf;
 
     return 0;
-- 
1.7.7.3

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to