On 2011-12-31 17:17:53 +0100, Anton Khirnov wrote:
> 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
>  }

looks good, if avfilter is supposed to become mandatory for avconv,
resample_{width,height,pix_fmt} could be moved under
'#if !CONFIG_AVFILTER'

>  
> 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)

this resets the flags to SWS_BILINEAR and I'm wondering if there is a
way to set flags in the first case.

> +            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;

looks good otherwise, an option to disable this behavior might make
sense if one would like to handle variable frame sizes.

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

Reply via email to