1/* 2 * Aspect ratio modification video filter 3 * Copyright (c) 2010 Bobby Bingham 4 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * aspect ratio modification video filter 25 */ 26 27#include "avfilter.h" 28 29typedef struct { 30 AVRational aspect; 31} AspectContext; 32 33static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) 34{ 35 AspectContext *aspect = ctx->priv; 36 double ratio; 37 int64_t gcd; 38 39 if(args) { 40 if(sscanf(args, "%d:%d", &aspect->aspect.num, &aspect->aspect.den) < 2) { 41 if(sscanf(args, "%lf", &ratio) < 1) 42 return -1; 43 aspect->aspect = av_d2q(ratio, 100); 44 } else { 45 gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den)); 46 if(gcd) { 47 aspect->aspect.num /= gcd; 48 aspect->aspect.den /= gcd; 49 } 50 } 51 } 52 53 if(aspect->aspect.den == 0) 54 aspect->aspect = (AVRational) {0, 1}; 55 56 return 0; 57} 58 59static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) 60{ 61 AspectContext *aspect = link->dst->priv; 62 63 picref->pixel_aspect = aspect->aspect; 64 avfilter_start_frame(link->dst->outputs[0], picref); 65} 66 67#if CONFIG_ASPECT_FILTER 68/* for aspect filter, convert from frame aspect ratio to pixel aspect ratio */ 69static int frameaspect_config_props(AVFilterLink *inlink) 70{ 71 AspectContext *aspect = inlink->dst->priv; 72 73 av_reduce(&aspect->aspect.num, &aspect->aspect.den, 74 aspect->aspect.num * inlink->h, 75 aspect->aspect.den * inlink->w, 100); 76 77 return 0; 78} 79 80AVFilter avfilter_vf_aspect = { 81 .name = "aspect", 82 .description = NULL_IF_CONFIG_SMALL("Set the frame aspect ratio."), 83 84 .init = init, 85 86 .priv_size = sizeof(AspectContext), 87 88 .inputs = (AVFilterPad[]) {{ .name = "default", 89 .type = AVMEDIA_TYPE_VIDEO, 90 .config_props = frameaspect_config_props, 91 .get_video_buffer = avfilter_null_get_video_buffer, 92 .start_frame = start_frame, 93 .end_frame = avfilter_null_end_frame }, 94 { .name = NULL}}, 95 96 .outputs = (AVFilterPad[]) {{ .name = "default", 97 .type = AVMEDIA_TYPE_VIDEO, }, 98 { .name = NULL}}, 99}; 100#endif /* CONFIG_ASPECT_FILTER */ 101 102#if CONFIG_PIXELASPECT_FILTER 103AVFilter avfilter_vf_pixelaspect = { 104 .name = "pixelaspect", 105 .description = NULL_IF_CONFIG_SMALL("Set the pixel aspect ratio."), 106 107 .init = init, 108 109 .priv_size = sizeof(AspectContext), 110 111 .inputs = (AVFilterPad[]) {{ .name = "default", 112 .type = AVMEDIA_TYPE_VIDEO, 113 .get_video_buffer = avfilter_null_get_video_buffer, 114 .start_frame = start_frame, 115 .end_frame = avfilter_null_end_frame }, 116 { .name = NULL}}, 117 118 .outputs = (AVFilterPad[]) {{ .name = "default", 119 .type = AVMEDIA_TYPE_VIDEO, }, 120 { .name = NULL}}, 121}; 122#endif /* CONFIG_PIXELASPECT_FILTER */ 123 124