From 3922deb5773396f14df9c7ff9e60f84bf185b945 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Wed, 17 Mar 2010 03:43:14 +0000 Subject: [PATCH] Add video filter to manipulate aspect ratio Originally committed as revision 22573 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavfilter/Makefile | 2 + libavfilter/allfilters.c | 4 +- libavfilter/vf_aspect.c | 135 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_aspect.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 904cceffd0..29857c0496 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -14,10 +14,12 @@ OBJS = allfilters.o \ graphparser.o \ parseutils.o \ +OBJS-$(CONFIG_ASPECT_FILTER) += vf_aspect.o OBJS-$(CONFIG_CROP_FILTER) += vf_crop.o OBJS-$(CONFIG_FORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_NULL_FILTER) += vf_null.o +OBJS-$(CONFIG_PIXELASPECT_FILTER) += vf_aspect.o OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o OBJS-$(CONFIG_SLICIFY_FILTER) += vf_slicify.o OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 4be7642da9..899f38d591 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -34,15 +34,17 @@ void avfilter_register_all(void) return; initialized = 1; + REGISTER_FILTER (ASPECT, aspect, vf); REGISTER_FILTER (CROP, crop, vf); REGISTER_FILTER (FORMAT, format, vf); REGISTER_FILTER (NOFORMAT, noformat, vf); REGISTER_FILTER (NULL, null, vf); + REGISTER_FILTER (PIXELASPECT, pixelaspect, vf); REGISTER_FILTER (SCALE, scale, vf); REGISTER_FILTER (SLICIFY, slicify, vf); REGISTER_FILTER (VFLIP, vflip, vf); REGISTER_FILTER (NULLSRC, nullsrc, vsrc); - REGISTER_FILTER(NULLSINK, nullsink, vsink); + REGISTER_FILTER (NULLSINK, nullsink, vsink); } diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c new file mode 100644 index 0000000000..f1961ce217 --- /dev/null +++ b/libavfilter/vf_aspect.c @@ -0,0 +1,135 @@ +/* + * Aspect ratio modification video filter + * Copyright (c) 2010 Bobby Bingham + + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libavfilter/vf_aspect.c + * aspect ratio modification video filter + */ + +#include "avfilter.h" + +typedef struct { + AVRational aspect; +} AspectContext; + +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) +{ + AspectContext *aspect = ctx->priv; + double ratio; + int64_t gcd; + + if(args) { + if(sscanf(args, "%d:%d", &aspect->aspect.num, &aspect->aspect.den) < 2) { + if(sscanf(args, "%lf", &ratio) < 1) + return -1; + aspect->aspect = av_d2q(ratio, 100); + } else { + gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den)); + if(gcd) { + aspect->aspect.num /= gcd; + aspect->aspect.den /= gcd; + } + } + } + + if(aspect->aspect.den == 0) + aspect->aspect = (AVRational) {0, 1}; + + return 0; +} + + +static AVFilterPicRef *get_video_buffer(AVFilterLink *link, int perms, + int w, int h) +{ + return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); +} + +static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) +{ + AspectContext *aspect = link->dst->priv; + + picref->pixel_aspect = aspect->aspect; + avfilter_start_frame(link->dst->outputs[0], picref); +} + +static void end_frame(AVFilterLink *link) +{ + avfilter_end_frame(link->dst->outputs[0]); +} + +#if CONFIG_ASPECT_FILTER +/* for aspect filter, convert from frame aspect ratio to pixel aspect ratio */ +static int frameaspect_config_props(AVFilterLink *inlink) +{ + AspectContext *aspect = inlink->dst->priv; + + av_reduce(&aspect->aspect.num, &aspect->aspect.den, + aspect->aspect.num * inlink->h, + aspect->aspect.den * inlink->w, 100); + + return 0; +} + +AVFilter avfilter_vf_aspect = { + .name = "aspect", + .description = NULL_IF_CONFIG_SMALL("Set the frame aspect ratio."), + + .init = init, + + .priv_size = sizeof(AspectContext), + + .inputs = (AVFilterPad[]) {{ .name = "default", + .type = CODEC_TYPE_VIDEO, + .config_props = frameaspect_config_props, + .get_video_buffer = get_video_buffer, + .start_frame = start_frame, + .end_frame = end_frame }, + { .name = NULL}}, + + .outputs = (AVFilterPad[]) {{ .name = "default", + .type = CODEC_TYPE_VIDEO, }, + { .name = NULL}}, +}; +#endif /* CONFIG_ASPECT_FILTER */ + +#if CONFIG_PIXELASPECT_FILTER +AVFilter avfilter_vf_pixelaspect = { + .name = "pixelaspect", + .description = NULL_IF_CONFIG_SMALL("Set the pixel aspect ratio."), + + .init = init, + + .priv_size = sizeof(AspectContext), + + .inputs = (AVFilterPad[]) {{ .name = "default", + .type = CODEC_TYPE_VIDEO, + .get_video_buffer = get_video_buffer, + .start_frame = start_frame, + .end_frame = end_frame }, + { .name = NULL}}, + + .outputs = (AVFilterPad[]) {{ .name = "default", + .type = CODEC_TYPE_VIDEO, }, + { .name = NULL}}, +}; +#endif /* CONFIG_PIXELASPECT_FILTER */ +