vf_(no)format: switch to an AVOptions-based system.
[libav.git] / libavfilter / vf_aspect.c
CommitLineData
3922deb5 1/*
3922deb5
BB
2 * Copyright (c) 2010 Bobby Bingham
3
2912e87a 4 * This file is part of Libav.
3922deb5 5 *
2912e87a 6 * Libav is free software; you can redistribute it and/or
3922deb5
BB
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
2912e87a 11 * Libav is distributed in the hope that it will be useful,
3922deb5
BB
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
2912e87a 17 * License along with Libav; if not, write to the Free Software
3922deb5
BB
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
ba87f080 22 * @file
cef4b74b 23 * aspect ratio modification video filters
3922deb5
BB
24 */
25
1d9c2dc8 26#include "libavutil/common.h"
0ebcdf5c 27#include "libavutil/mathematics.h"
3922deb5 28#include "avfilter.h"
9d0bfc50 29#include "internal.h"
c04c533f 30#include "video.h"
3922deb5
BB
31
32typedef struct {
33 AVRational aspect;
34} AspectContext;
35
a5e8c41c 36static av_cold int init(AVFilterContext *ctx, const char *args)
3922deb5
BB
37{
38 AspectContext *aspect = ctx->priv;
39 double ratio;
40 int64_t gcd;
7de19a32 41 char c = 0;
3922deb5 42
bdb47f3a 43 if (args) {
7de19a32
SS
44 if (sscanf(args, "%d:%d%c", &aspect->aspect.num, &aspect->aspect.den, &c) != 2)
45 if (sscanf(args, "%lf%c", &ratio, &c) == 1)
46 aspect->aspect = av_d2q(ratio, 100);
47
48 if (c || aspect->aspect.num <= 0 || aspect->aspect.den <= 0) {
49 av_log(ctx, AV_LOG_ERROR,
50 "Invalid string '%s' for aspect ratio.\n", args);
51 return AVERROR(EINVAL);
52 }
53
b7be04f3
SS
54 gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den));
55 if (gcd) {
56 aspect->aspect.num /= gcd;
57 aspect->aspect.den /= gcd;
58 }
3922deb5
BB
59 }
60
bdb47f3a 61 if (aspect->aspect.den == 0)
3922deb5
BB
62 aspect->aspect = (AVRational) {0, 1};
63
1a49a169 64 av_log(ctx, AV_LOG_VERBOSE, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den);
3922deb5
BB
65 return 0;
66}
67
7e350379 68static int filter_frame(AVFilterLink *link, AVFrame *frame)
3922deb5
BB
69{
70 AspectContext *aspect = link->dst->priv;
71
7e350379 72 frame->sample_aspect_ratio = aspect->aspect;
565e4993 73 return ff_filter_frame(link->dst->outputs[0], frame);
3922deb5
BB
74}
75
2fb21bf4
SS
76#if CONFIG_SETDAR_FILTER
77/* for setdar filter, convert from frame aspect ratio to pixel aspect ratio */
78static int setdar_config_props(AVFilterLink *inlink)
3922deb5
BB
79{
80 AspectContext *aspect = inlink->dst->priv;
eee0ef5e 81 AVRational dar = aspect->aspect;
3922deb5
BB
82
83 av_reduce(&aspect->aspect.num, &aspect->aspect.den,
84 aspect->aspect.num * inlink->h,
85 aspect->aspect.den * inlink->w, 100);
86
1a49a169 87 av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d -> dar:%d/%d sar:%d/%d\n",
6fd2b8bd 88 inlink->w, inlink->h, dar.num, dar.den, aspect->aspect.num, aspect->aspect.den);
910b5b82
MN
89
90 inlink->sample_aspect_ratio = aspect->aspect;
91
3922deb5
BB
92 return 0;
93}
94
568c70e7
MR
95static const AVFilterPad avfilter_vf_setdar_inputs[] = {
96 {
97 .name = "default",
98 .type = AVMEDIA_TYPE_VIDEO,
99 .config_props = setdar_config_props,
100 .get_video_buffer = ff_null_get_video_buffer,
565e4993 101 .filter_frame = filter_frame,
568c70e7
MR
102 },
103 { NULL }
104};
105
106static const AVFilterPad avfilter_vf_setdar_outputs[] = {
107 {
108 .name = "default",
109 .type = AVMEDIA_TYPE_VIDEO,
110 },
111 { NULL }
112};
113
2fb21bf4
SS
114AVFilter avfilter_vf_setdar = {
115 .name = "setdar",
116 .description = NULL_IF_CONFIG_SMALL("Set the frame display aspect ratio."),
3922deb5
BB
117
118 .init = init,
119
120 .priv_size = sizeof(AspectContext),
121
568c70e7
MR
122 .inputs = avfilter_vf_setdar_inputs,
123
124 .outputs = avfilter_vf_setdar_outputs,
3922deb5 125};
2fb21bf4 126#endif /* CONFIG_SETDAR_FILTER */
3922deb5 127
2fb21bf4 128#if CONFIG_SETSAR_FILTER
910b5b82
MN
129/* for setdar filter, convert from frame aspect ratio to pixel aspect ratio */
130static int setsar_config_props(AVFilterLink *inlink)
131{
132 AspectContext *aspect = inlink->dst->priv;
133
134 inlink->sample_aspect_ratio = aspect->aspect;
135
136 return 0;
137}
138
568c70e7
MR
139static const AVFilterPad avfilter_vf_setsar_inputs[] = {
140 {
141 .name = "default",
142 .type = AVMEDIA_TYPE_VIDEO,
143 .config_props = setsar_config_props,
144 .get_video_buffer = ff_null_get_video_buffer,
565e4993 145 .filter_frame = filter_frame,
568c70e7
MR
146 },
147 { NULL }
148};
149
150static const AVFilterPad avfilter_vf_setsar_outputs[] = {
151 {
152 .name = "default",
153 .type = AVMEDIA_TYPE_VIDEO,
154 },
155 { NULL }
156};
157
2fb21bf4
SS
158AVFilter avfilter_vf_setsar = {
159 .name = "setsar",
160 .description = NULL_IF_CONFIG_SMALL("Set the pixel sample aspect ratio."),
3922deb5
BB
161
162 .init = init,
163
164 .priv_size = sizeof(AspectContext),
165
568c70e7
MR
166 .inputs = avfilter_vf_setsar_inputs,
167
168 .outputs = avfilter_vf_setsar_outputs,
3922deb5 169};
2fb21bf4 170#endif /* CONFIG_SETSAR_FILTER */