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