vf_aspect.c
Go to the documentation of this file.
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 <float.h>
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;
41  int max;
42 #if FF_API_OLD_FILTER_OPTS
43  float aspect_den;
44 #endif
45  char *ratio_str;
47 
48 static av_cold int init(AVFilterContext *ctx)
49 {
50  AspectContext *s = ctx->priv;
51  int ret;
52 
53 #if FF_API_OLD_FILTER_OPTS
54  if (s->ratio_str && s->aspect_den > 0) {
55  double num;
57  "num:den syntax is deprecated, please use num/den or named options instead\n");
58  ret = av_expr_parse_and_eval(&num, s->ratio_str, NULL, NULL,
59  NULL, NULL, NULL, NULL, NULL, 0, ctx);
60  if (ret < 0) {
61  av_log(ctx, AV_LOG_ERROR, "Unable to parse ratio numerator \"%s\"\n", s->ratio_str);
62  return AVERROR(EINVAL);
63  }
64  s->aspect = av_d2q(num / s->aspect_den, s->max);
65  } else
66 #endif
67  if (s->ratio_str) {
68  ret = av_parse_ratio(&s->aspect, s->ratio_str, s->max, 0, ctx);
69  if (ret < 0 || s->aspect.num < 0 || s->aspect.den <= 0) {
70  av_log(ctx, AV_LOG_ERROR,
71  "Invalid string '%s' for aspect ratio\n", s->ratio_str);
72  return AVERROR(EINVAL);
73  }
74  }
75  return 0;
76 }
77 
79 {
80  AspectContext *aspect = link->dst->priv;
81 
82  frame->sample_aspect_ratio = aspect->aspect;
83  return ff_filter_frame(link->dst->outputs[0], frame);
84 }
85 
86 #define OFFSET(x) offsetof(AspectContext, x)
87 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
88 
89 static inline void compute_dar(AVRational *dar, AVRational sar, int w, int h)
90 {
91  if (sar.num && sar.den) {
92  av_reduce(&dar->num, &dar->den, sar.num * w, sar.den * h, INT_MAX);
93  } else {
94  av_reduce(&dar->num, &dar->den, w, h, INT_MAX);
95  }
96 }
97 
98 #if CONFIG_SETDAR_FILTER
99 
100 static int setdar_config_props(AVFilterLink *inlink)
101 {
102  AspectContext *aspect = inlink->dst->priv;
103  AVRational dar = aspect->aspect, old_dar;
104  AVRational old_sar = inlink->sample_aspect_ratio;
105 
106  if (aspect->aspect.num && aspect->aspect.den) {
107  av_reduce(&aspect->aspect.num, &aspect->aspect.den,
108  aspect->aspect.num * inlink->h,
109  aspect->aspect.den * inlink->w, INT_MAX);
110  inlink->sample_aspect_ratio = aspect->aspect;
111  } else {
112  inlink->sample_aspect_ratio = (AVRational){ 1, 1 };
113  dar = (AVRational){ inlink->w, inlink->h };
114  }
115 
116  compute_dar(&old_dar, old_sar, inlink->w, inlink->h);
117  av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d dar:%d/%d sar:%d/%d -> dar:%d/%d sar:%d/%d\n",
118  inlink->w, inlink->h, old_dar.num, old_dar.den, old_sar.num, old_sar.den,
119  dar.num, dar.den, inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den);
120 
121  return 0;
122 }
123 
124 static const AVOption setdar_options[] = {
125  { "dar", "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
126  { "ratio", "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
127  { "r", "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
128 #if FF_API_OLD_FILTER_OPTS
129  { "dar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
130 #endif
131  { "max", "set max value for nominator or denominator in the ratio", OFFSET(max), AV_OPT_TYPE_INT, {.i64=100}, 1, INT_MAX, FLAGS },
132  { NULL }
133 };
134 
135 AVFILTER_DEFINE_CLASS(setdar);
136 
137 static const AVFilterPad avfilter_vf_setdar_inputs[] = {
138  {
139  .name = "default",
140  .type = AVMEDIA_TYPE_VIDEO,
141  .config_props = setdar_config_props,
142  .get_video_buffer = ff_null_get_video_buffer,
143  .filter_frame = filter_frame,
144  },
145  { NULL }
146 };
147 
148 static const AVFilterPad avfilter_vf_setdar_outputs[] = {
149  {
150  .name = "default",
151  .type = AVMEDIA_TYPE_VIDEO,
152  },
153  { NULL }
154 };
155 
156 AVFilter avfilter_vf_setdar = {
157  .name = "setdar",
158  .description = NULL_IF_CONFIG_SMALL("Set the frame display aspect ratio."),
159  .init = init,
160  .priv_size = sizeof(AspectContext),
161  .priv_class = &setdar_class,
162 
163  .inputs = avfilter_vf_setdar_inputs,
164 
165  .outputs = avfilter_vf_setdar_outputs,
166 };
167 
168 #endif /* CONFIG_SETDAR_FILTER */
169 
170 #if CONFIG_SETSAR_FILTER
171 
172 static int setsar_config_props(AVFilterLink *inlink)
173 {
174  AspectContext *aspect = inlink->dst->priv;
175  AVRational old_sar = inlink->sample_aspect_ratio;
176  AVRational old_dar, dar;
177 
178  inlink->sample_aspect_ratio = aspect->aspect;
179 
180  compute_dar(&old_dar, old_sar, inlink->w, inlink->h);
181  compute_dar(&dar, aspect->aspect, inlink->w, inlink->h);
182  av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d sar:%d/%d dar:%d/%d -> sar:%d/%d dar:%d/%d\n",
183  inlink->w, inlink->h, old_sar.num, old_sar.den, old_dar.num, old_dar.den,
184  inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, dar.num, dar.den);
185 
186  return 0;
187 }
188 
189 static const AVOption setsar_options[] = {
190  { "sar", "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
191  { "ratio", "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
192  { "r", "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
193 #if FF_API_OLD_FILTER_OPTS
194  { "sar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
195 #endif
196  { "max", "set max value for nominator or denominator in the ratio", OFFSET(max), AV_OPT_TYPE_INT, {.i64=100}, 1, INT_MAX, FLAGS },
197  { NULL }
198 };
199 
200 AVFILTER_DEFINE_CLASS(setsar);
201 
202 static const AVFilterPad avfilter_vf_setsar_inputs[] = {
203  {
204  .name = "default",
205  .type = AVMEDIA_TYPE_VIDEO,
206  .config_props = setsar_config_props,
207  .get_video_buffer = ff_null_get_video_buffer,
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 
228  .inputs = avfilter_vf_setsar_inputs,
229 
230  .outputs = avfilter_vf_setsar_outputs,
231 };
232 
233 #endif /* CONFIG_SETSAR_FILTER */
int av_parse_ratio(AVRational *q, const char *str, int max, int log_offset, void *log_ctx)
Parse str and store the parsed ratio in q.
Definition: parseutils.c:43
#define OFFSET(x)
Definition: vf_aspect.c:86
const char * s
Definition: avisynth_c.h:668
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
AVOption.
Definition: opt.h:251
static void compute_dar(AVRational *dar, AVRational sar, int w, int h)
Definition: vf_aspect.c:89
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
external API header
if max(w)>1 w=0.9 *w/max(w)
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
int num
numerator
Definition: rational.h:44
AVFrame * ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
Definition: video.c:35
char * ratio_str
Definition: vf_aspect.c:45
output residual component w
const char * name
Pad name.
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
#define av_cold
Definition: attributes.h:78
AVOptions.
AVRational aspect
Definition: vf_aspect.c:40
frame
Definition: stft.m:14
A filter pad used for either input or output.
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition: eval.c:701
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
Definition: avfilter.h:545
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
static av_cold int init(AVFilterContext *ctx)
Definition: vf_aspect.c:48
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a link
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:36
#define AV_LOG_VERBOSE
Definition: log.h:157
struct AVRational AVRational
rational number numerator/denominator
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
ret
Definition: avfilter.c:821
NULL
Definition: eval.c:55
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:154
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
Describe the class of an AVClass context structure.
Definition: log.h:50
Filter definition.
Definition: avfilter.h:436
rational number numerator/denominator
Definition: rational.h:43
const char * name
filter name
Definition: avfilter.h:437
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:539
#define FLAGS
Definition: vf_aspect.c:87
common internal and external API header
int den
denominator
Definition: rational.h:45
#define AVFILTER_DEFINE_CLASS(fname)
An instance of a filter.
Definition: avfilter.h:524
internal API functions
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
static int filter_frame(AVFilterLink *link, AVFrame *frame)
Definition: vf_aspect.c:78
simple arithmetic expression evaluator