Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * Copyright (c) 2010 Bobby Bingham
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
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
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
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
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
 
21
/**
22
 * @file
23
 * aspect ratio modification video filters
24
 */
25
 
26
#include 
27
 
28
#include "libavutil/common.h"
29
#include "libavutil/eval.h"
30
#include "libavutil/mathematics.h"
31
#include "libavutil/opt.h"
32
#include "libavutil/parseutils.h"
33
 
34
#include "avfilter.h"
35
#include "internal.h"
36
#include "video.h"
37
 
38
typedef struct {
39
    const AVClass *class;
40
    AVRational dar;
41
    AVRational sar;
42
    int max;
43
#if FF_API_OLD_FILTER_OPTS
44
    float aspect_den;
45
#endif
46
    char *ratio_str;
47
} AspectContext;
48
 
49
static av_cold int init(AVFilterContext *ctx)
50
{
51
    AspectContext *s = ctx->priv;
52
    int ret;
53
 
54
#if FF_API_OLD_FILTER_OPTS
55
    if (s->ratio_str && s->aspect_den > 0) {
56
        double num;
57
        av_log(ctx, AV_LOG_WARNING,
58
               "num:den syntax is deprecated, please use num/den or named options instead\n");
59
        ret = av_expr_parse_and_eval(&num, s->ratio_str, NULL, NULL,
60
                                     NULL, NULL, NULL, NULL, NULL, 0, ctx);
61
        if (ret < 0) {
62
            av_log(ctx, AV_LOG_ERROR, "Unable to parse ratio numerator \"%s\"\n", s->ratio_str);
63
            return AVERROR(EINVAL);
64
        }
65
        s->sar = s->dar = av_d2q(num / s->aspect_den, s->max);
66
    } else
67
#endif
68
    if (s->ratio_str) {
69
        ret = av_parse_ratio(&s->sar, s->ratio_str, s->max, 0, ctx);
70
        if (ret < 0 || s->sar.num < 0 || s->sar.den <= 0) {
71
            av_log(ctx, AV_LOG_ERROR,
72
                   "Invalid string '%s' for aspect ratio\n", s->ratio_str);
73
            return AVERROR(EINVAL);
74
        }
75
        s->dar = s->sar;
76
    }
77
    return 0;
78
}
79
 
80
static int filter_frame(AVFilterLink *link, AVFrame *frame)
81
{
82
    AspectContext *s = link->dst->priv;
83
 
84
    frame->sample_aspect_ratio = s->sar;
85
    return ff_filter_frame(link->dst->outputs[0], frame);
86
}
87
 
88
#define OFFSET(x) offsetof(AspectContext, x)
89
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
90
 
91
static inline void compute_dar(AVRational *dar, AVRational sar, int w, int h)
92
{
93
    if (sar.num && sar.den) {
94
        av_reduce(&dar->num, &dar->den, sar.num * w, sar.den * h, INT_MAX);
95
    } else {
96
        av_reduce(&dar->num, &dar->den, w, h, INT_MAX);
97
    }
98
}
99
 
100
#if CONFIG_SETDAR_FILTER
101
 
102
static int setdar_config_props(AVFilterLink *inlink)
103
{
104
    AspectContext *s = inlink->dst->priv;
105
    AVRational dar;
106
    AVRational old_dar;
107
    AVRational old_sar = inlink->sample_aspect_ratio;
108
 
109
    if (s->dar.num && s->dar.den) {
110
        av_reduce(&s->sar.num, &s->sar.den,
111
                   s->dar.num * inlink->h,
112
                   s->dar.den * inlink->w, INT_MAX);
113
        inlink->sample_aspect_ratio = s->sar;
114
        dar = s->dar;
115
    } else {
116
        inlink->sample_aspect_ratio = (AVRational){ 1, 1 };
117
        dar = (AVRational){ inlink->w, inlink->h };
118
    }
119
 
120
    compute_dar(&old_dar, old_sar, inlink->w, inlink->h);
121
    av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d dar:%d/%d sar:%d/%d -> dar:%d/%d sar:%d/%d\n",
122
           inlink->w, inlink->h, old_dar.num, old_dar.den, old_sar.num, old_sar.den,
123
           dar.num, dar.den, inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den);
124
 
125
    return 0;
126
}
127
 
128
static const AVOption setdar_options[] = {
129
    { "dar",   "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
130
    { "ratio", "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
131
    { "r",     "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
132
#if FF_API_OLD_FILTER_OPTS
133
    { "dar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
134
#endif
135
    { "max",   "set max value for nominator or denominator in the ratio", OFFSET(max), AV_OPT_TYPE_INT, {.i64=100}, 1, INT_MAX, FLAGS },
136
    { NULL }
137
};
138
 
139
AVFILTER_DEFINE_CLASS(setdar);
140
 
141
static const AVFilterPad avfilter_vf_setdar_inputs[] = {
142
    {
143
        .name         = "default",
144
        .type         = AVMEDIA_TYPE_VIDEO,
145
        .config_props = setdar_config_props,
146
        .filter_frame = filter_frame,
147
    },
148
    { NULL }
149
};
150
 
151
static const AVFilterPad avfilter_vf_setdar_outputs[] = {
152
    {
153
        .name = "default",
154
        .type = AVMEDIA_TYPE_VIDEO,
155
    },
156
    { NULL }
157
};
158
 
159
AVFilter avfilter_vf_setdar = {
160
    .name        = "setdar",
161
    .description = NULL_IF_CONFIG_SMALL("Set the frame display aspect ratio."),
162
    .init        = init,
163
    .priv_size   = sizeof(AspectContext),
164
    .priv_class  = &setdar_class,
165
    .inputs      = avfilter_vf_setdar_inputs,
166
    .outputs     = avfilter_vf_setdar_outputs,
167
};
168
 
169
#endif /* CONFIG_SETDAR_FILTER */
170
 
171
#if CONFIG_SETSAR_FILTER
172
 
173
static int setsar_config_props(AVFilterLink *inlink)
174
{
175
    AspectContext *s = inlink->dst->priv;
176
    AVRational old_sar = inlink->sample_aspect_ratio;
177
    AVRational old_dar, dar;
178
 
179
    inlink->sample_aspect_ratio = s->sar;
180
 
181
    compute_dar(&old_dar, old_sar, inlink->w, inlink->h);
182
    compute_dar(&dar, s->sar, inlink->w, inlink->h);
183
    av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d sar:%d/%d dar:%d/%d -> sar:%d/%d dar:%d/%d\n",
184
           inlink->w, inlink->h, old_sar.num, old_sar.den, old_dar.num, old_dar.den,
185
           inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, dar.num, dar.den);
186
 
187
    return 0;
188
}
189
 
190
static const AVOption setsar_options[] = {
191
    { "sar",   "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
192
    { "ratio", "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
193
    { "r",     "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
194
#if FF_API_OLD_FILTER_OPTS
195
    { "sar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
196
#endif
197
    { "max",   "set max value for nominator or denominator in the ratio", OFFSET(max), AV_OPT_TYPE_INT, {.i64=100}, 1, INT_MAX, FLAGS },
198
    { NULL }
199
};
200
 
201
AVFILTER_DEFINE_CLASS(setsar);
202
 
203
static const AVFilterPad avfilter_vf_setsar_inputs[] = {
204
    {
205
        .name         = "default",
206
        .type         = AVMEDIA_TYPE_VIDEO,
207
        .config_props = setsar_config_props,
208
        .filter_frame = filter_frame,
209
    },
210
    { NULL }
211
};
212
 
213
static const AVFilterPad avfilter_vf_setsar_outputs[] = {
214
    {
215
        .name = "default",
216
        .type = AVMEDIA_TYPE_VIDEO,
217
    },
218
    { NULL }
219
};
220
 
221
AVFilter avfilter_vf_setsar = {
222
    .name        = "setsar",
223
    .description = NULL_IF_CONFIG_SMALL("Set the pixel sample aspect ratio."),
224
    .init        = init,
225
    .priv_size   = sizeof(AspectContext),
226
    .priv_class  = &setsar_class,
227
    .inputs      = avfilter_vf_setsar_inputs,
228
    .outputs     = avfilter_vf_setsar_outputs,
229
};
230
 
231
#endif /* CONFIG_SETSAR_FILTER */