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