FFmpeg
vf_pad.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 vmrsss
3  * Copyright (c) 2009 Stefano Sabatini
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  * video padding filter
25  */
26 
27 #include <float.h> /* DBL_MAX */
28 
29 #include "avfilter.h"
30 #include "filters.h"
31 #include "formats.h"
32 #include "video.h"
33 #include "libavutil/avstring.h"
34 #include "libavutil/common.h"
35 #include "libavutil/eval.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/colorspace.h"
38 #include "libavutil/imgutils.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/mathematics.h"
41 #include "libavutil/opt.h"
42 
43 #include "drawutils.h"
44 
45 static const char *const var_names[] = {
46  "in_w", "iw",
47  "in_h", "ih",
48  "out_w", "ow",
49  "out_h", "oh",
50  "x",
51  "y",
52  "a",
53  "sar",
54  "dar",
55  "hsub",
56  "vsub",
57  NULL
58 };
59 
60 enum var_name {
73 };
74 
75 static int query_formats(const AVFilterContext *ctx,
76  AVFilterFormatsConfig **cfg_in,
77  AVFilterFormatsConfig **cfg_out)
78 {
79  return ff_set_common_formats2(ctx, cfg_in, cfg_out,
81 }
82 
83 enum EvalMode {
87 };
88 
89 typedef struct PadContext {
90  const AVClass *class;
91  int w, h; ///< output dimensions, a value of 0 will result in the input size
92  int x, y; ///< offsets of the input area with respect to the padded area
93  int in_w, in_h; ///< width and height for the padded input video, which has to be aligned to the chroma values in order to avoid chroma issues
96 
97  char *w_expr; ///< width expression string
98  char *h_expr; ///< height expression string
99  char *x_expr; ///< width expression string
100  char *y_expr; ///< height expression string
101  uint8_t rgba_color[4]; ///< color for the padding area
104 
105  int eval_mode; ///< expression evaluation mode
106 } PadContext;
107 
109 {
110  AVFilterContext *ctx = inlink->dst;
111  PadContext *s = ctx->priv;
112  AVRational adjusted_aspect = s->aspect;
113  int ret;
114  double var_values[VARS_NB], res;
115  char *expr;
116 
117  ff_draw_init2(&s->draw, inlink->format, inlink->colorspace, inlink->color_range, 0);
118  ff_draw_color(&s->draw, &s->color, s->rgba_color);
119 
120  var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
121  var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
122  var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
123  var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
124  var_values[VAR_A] = (double) inlink->w / inlink->h;
125  var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
126  (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
127  var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR];
128  var_values[VAR_HSUB] = 1 << s->draw.hsub_max;
129  var_values[VAR_VSUB] = 1 << s->draw.vsub_max;
130 
131  /* evaluate width and height */
132  av_expr_parse_and_eval(&res, (expr = s->w_expr),
133  var_names, var_values,
134  NULL, NULL, NULL, NULL, NULL, 0, ctx);
135  s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
136  if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
137  var_names, var_values,
138  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
139  goto eval_fail;
140  s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
141  if (!s->h)
142  var_values[VAR_OUT_H] = var_values[VAR_OH] = s->h = inlink->h;
143 
144  /* evaluate the width again, as it may depend on the evaluated output height */
145  if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
146  var_names, var_values,
147  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
148  goto eval_fail;
149  s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
150  if (!s->w)
151  var_values[VAR_OUT_W] = var_values[VAR_OW] = s->w = inlink->w;
152 
153  if (adjusted_aspect.num && adjusted_aspect.den) {
154  adjusted_aspect = av_div_q(adjusted_aspect, inlink->sample_aspect_ratio);
155  if (s->h < av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num)) {
156  s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num);
157  } else {
158  s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = av_rescale(s->h, adjusted_aspect.num, adjusted_aspect.den);
159  }
160  }
161 
162  /* evaluate x and y */
163  av_expr_parse_and_eval(&res, (expr = s->x_expr),
164  var_names, var_values,
165  NULL, NULL, NULL, NULL, NULL, 0, ctx);
166  s->x = var_values[VAR_X] = res;
167  if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
168  var_names, var_values,
169  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
170  goto eval_fail;
171  s->y = var_values[VAR_Y] = res;
172  /* evaluate x again, as it may depend on the evaluated y value */
173  if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),
174  var_names, var_values,
175  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
176  goto eval_fail;
177  s->x = var_values[VAR_X] = res;
178 
179  if (s->x < 0 || s->x + inlink->w > s->w)
180  s->x = var_values[VAR_X] = (s->w - inlink->w) / 2;
181  if (s->y < 0 || s->y + inlink->h > s->h)
182  s->y = var_values[VAR_Y] = (s->h - inlink->h) / 2;
183 
184  s->w = ff_draw_round_to_sub(&s->draw, 0, -1, s->w);
185  s->h = ff_draw_round_to_sub(&s->draw, 1, -1, s->h);
186  /* sanity check params */
187  if (s->w < inlink->w || s->h < inlink->h) {
188  av_log(ctx, AV_LOG_ERROR, "Padded dimensions cannot be smaller than input dimensions.\n");
189  return AVERROR(EINVAL);
190  }
191 
192  s->x = ff_draw_round_to_sub(&s->draw, 0, -1, s->x);
193  s->y = ff_draw_round_to_sub(&s->draw, 1, -1, s->y);
194  s->in_w = ff_draw_round_to_sub(&s->draw, 0, -1, inlink->w);
195  s->in_h = ff_draw_round_to_sub(&s->draw, 1, -1, inlink->h);
196  s->inlink_w = inlink->w;
197  s->inlink_h = inlink->h;
198 
199  av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X\n",
200  inlink->w, inlink->h, s->w, s->h, s->x, s->y,
201  s->rgba_color[0], s->rgba_color[1], s->rgba_color[2], s->rgba_color[3]);
202 
203  if (s->x < 0 || s->y < 0 ||
204  s->w <= 0 || s->h <= 0 ||
205  (unsigned)s->x + (unsigned)inlink->w > s->w ||
206  (unsigned)s->y + (unsigned)inlink->h > s->h) {
208  "Input area %d:%d:%d:%d not within the padded area 0:0:%d:%d or zero-sized\n",
209  s->x, s->y, s->x + inlink->w, s->y + inlink->h, s->w, s->h);
210  return AVERROR(EINVAL);
211  }
212 
213  return 0;
214 
215 eval_fail:
217  "Error when evaluating the expression '%s'\n", expr);
218  return ret;
219 
220 }
221 
222 static int config_output(AVFilterLink *outlink)
223 {
224  PadContext *s = outlink->src->priv;
225 
226  outlink->w = s->w;
227  outlink->h = s->h;
228  return 0;
229 }
230 
232 {
233  PadContext *s = inlink->dst->priv;
234  AVFrame *frame;
235  int plane;
236 
237  if (s->inlink_w <= 0)
238  return NULL;
239 
240  frame = ff_get_video_buffer(inlink->dst->outputs[0],
241  w + (s->w - s->in_w),
242  h + (s->h - s->in_h) + (s->x > 0));
243 
244  if (!frame)
245  return NULL;
246 
247  frame->width = w;
248  frame->height = h;
249 
250  for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
251  int hsub = s->draw.hsub[plane];
252  int vsub = s->draw.vsub[plane];
253  frame->data[plane] += (s->x >> hsub) * s->draw.pixelstep[plane] +
254  (s->y >> vsub) * frame->linesize[plane];
255  }
256 
257  return frame;
258 }
259 
260 /* check whether each plane in this buffer can be padded without copying */
262 {
263  int planes[4] = { -1, -1, -1, -1}, *p = planes;
264  int i, j;
265 
266  /* get all planes in this buffer */
267  for (i = 0; i < FF_ARRAY_ELEMS(planes) && frame->data[i]; i++) {
268  if (av_frame_get_plane_buffer(frame, i) == buf)
269  *p++ = i;
270  }
271 
272  /* for each plane in this buffer, check that it can be padded without
273  * going over buffer bounds or other planes */
274  for (i = 0; i < FF_ARRAY_ELEMS(planes) && planes[i] >= 0; i++) {
275  int hsub = s->draw.hsub[planes[i]];
276  int vsub = s->draw.vsub[planes[i]];
277 
278  uint8_t *start = frame->data[planes[i]];
279  uint8_t *end = start + (frame->height >> vsub) *
280  frame->linesize[planes[i]];
281 
282  /* amount of free space needed before the start and after the end
283  * of the plane */
284  ptrdiff_t req_start = (s->x >> hsub) * s->draw.pixelstep[planes[i]] +
285  (s->y >> vsub) * frame->linesize[planes[i]];
286  ptrdiff_t req_end = ((s->w - s->x - frame->width) >> hsub) *
287  s->draw.pixelstep[planes[i]] +
288  ((s->h - s->y - frame->height) >> vsub) * frame->linesize[planes[i]];
289 
290  if (frame->linesize[planes[i]] < (s->w >> hsub) * s->draw.pixelstep[planes[i]])
291  return 1;
292  if (start - buf->data < req_start ||
293  (buf->data + buf->size) - end < req_end)
294  return 1;
295 
296  for (j = 0; j < FF_ARRAY_ELEMS(planes) && planes[j] >= 0; j++) {
297  int vsub1 = s->draw.vsub[planes[j]];
298  uint8_t *start1 = frame->data[planes[j]];
299  uint8_t *end1 = start1 + (frame->height >> vsub1) *
300  frame->linesize[planes[j]];
301  if (i == j)
302  continue;
303 
304  if (FFSIGN(start - end1) != FFSIGN(start - end1 - req_start) ||
305  FFSIGN(end - start1) != FFSIGN(end - start1 + req_end))
306  return 1;
307  }
308  }
309 
310  return 0;
311 }
312 
314 {
315  int i;
316 
318  return 1;
319 
320  for (i = 0; i < 4 && frame->buf[i]; i++)
321  if (buffer_needs_copy(s, frame, frame->buf[i]))
322  return 1;
323  return 0;
324 }
325 
327 {
328  PadContext *s = inlink->dst->priv;
329  AVFilterLink *outlink = inlink->dst->outputs[0];
330  AVFrame *out;
331  int needs_copy;
332  if(s->eval_mode == EVAL_MODE_FRAME && (
333  in->width != s->inlink_w
334  || in->height != s->inlink_h
335  || in->format != outlink->format
337  int ret;
338 
339  inlink->dst->inputs[0]->format = in->format;
340  inlink->dst->inputs[0]->w = in->width;
341  inlink->dst->inputs[0]->h = in->height;
342 
343  inlink->dst->inputs[0]->sample_aspect_ratio.den = in->sample_aspect_ratio.den;
344  inlink->dst->inputs[0]->sample_aspect_ratio.num = in->sample_aspect_ratio.num;
345 
346 
347  if ((ret = config_input(inlink)) < 0) {
348  s->inlink_w = -1;
349  return ret;
350  }
351  if ((ret = config_output(outlink)) < 0) {
352  s->inlink_w = -1;
353  return ret;
354  }
355  }
356 
357  needs_copy = frame_needs_copy(s, in);
358 
359  if (needs_copy) {
360  av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
361  out = ff_get_video_buffer(outlink,
362  FFMAX(inlink->w, s->w),
363  FFMAX(inlink->h, s->h));
364  if (!out) {
365  av_frame_free(&in);
366  return AVERROR(ENOMEM);
367  }
368 
370  } else {
371  int i;
372 
373  out = in;
374  for (i = 0; i < 4 && out->data[i] && out->linesize[i]; i++) {
375  int hsub = s->draw.hsub[i];
376  int vsub = s->draw.vsub[i];
377  out->data[i] -= (s->x >> hsub) * s->draw.pixelstep[i] +
378  (s->y >> vsub) * out->linesize[i];
379  }
380  }
381 
382  /* top bar */
383  if (s->y) {
384  ff_fill_rectangle(&s->draw, &s->color,
385  out->data, out->linesize,
386  0, 0, s->w, s->y);
387  }
388 
389  /* bottom bar */
390  if (s->h > s->y + s->in_h) {
391  ff_fill_rectangle(&s->draw, &s->color,
392  out->data, out->linesize,
393  0, s->y + s->in_h, s->w, s->h - s->y - s->in_h);
394  }
395 
396  /* left border */
397  ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize,
398  0, s->y, s->x, in->height);
399 
400  if (needs_copy) {
401  ff_copy_rectangle2(&s->draw,
402  out->data, out->linesize, in->data, in->linesize,
403  s->x, s->y, 0, 0, in->width, in->height);
404  }
405 
406  /* right border */
407  ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize,
408  s->x + s->in_w, s->y, s->w - s->x - s->in_w,
409  in->height);
410 
411  out->width = s->w;
412  out->height = s->h;
413 
414  if (in != out)
415  av_frame_free(&in);
416  return ff_filter_frame(outlink, out);
417 }
418 
419 #define OFFSET(x) offsetof(PadContext, x)
420 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
421 
422 static const AVOption pad_options[] = {
423  { "width", "set the pad area width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
424  { "w", "set the pad area width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
425  { "height", "set the pad area height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
426  { "h", "set the pad area height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
427  { "x", "set the x offset expression for the input image position", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
428  { "y", "set the y offset expression for the input image position", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
429  { "color", "set the color of the padded area border", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS },
430  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" },
431  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
432  { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
433  { "aspect", "pad to fit an aspect instead of a resolution", OFFSET(aspect), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, DBL_MAX, FLAGS },
434  { NULL }
435 };
436 
438 
440  {
441  .name = "default",
442  .type = AVMEDIA_TYPE_VIDEO,
443  .config_props = config_input,
444  .get_buffer.video = get_video_buffer,
445  .filter_frame = filter_frame,
446  },
447 };
448 
450  {
451  .name = "default",
452  .type = AVMEDIA_TYPE_VIDEO,
453  .config_props = config_output,
454  },
455 };
456 
458  .name = "pad",
459  .description = NULL_IF_CONFIG_SMALL("Pad the input video."),
460  .priv_size = sizeof(PadContext),
461  .priv_class = &pad_class,
465 };
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:116
VAR_IN_W
@ VAR_IN_W
Definition: vf_pad.c:61
FFDrawColor
Definition: drawutils.h:51
VAR_Y
@ VAR_Y
Definition: vf_pad.c:66
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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. Frame references ownership and permissions
opt.h
var_name
var_name
Definition: noise.c:47
PadContext::w_expr
char * w_expr
width expression string
Definition: vf_pad.c:97
PadContext::eval_mode
int eval_mode
expression evaluation mode
Definition: vf_pad.c:105
out
FILE * out
Definition: movenc.c:55
PadContext::y
int y
offsets of the input area with respect to the padded area
Definition: vf_pad.c:92
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1062
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
PadContext::y_expr
char * y_expr
height expression string
Definition: vf_pad.c:100
av_div_q
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
ff_set_common_formats2
int ff_set_common_formats2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, AVFilterFormats *formats)
Definition: formats.c:1007
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
get_video_buffer
static AVFrame * get_video_buffer(AVFilterLink *inlink, int w, int h)
Definition: vf_pad.c:231
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
pixdesc.h
AVFrame::width
int width
Definition: frame.h:461
w
uint8_t w
Definition: llviddspenc.c:38
VAR_HSUB
@ VAR_HSUB
Definition: vf_pad.c:70
AVOption
AVOption.
Definition: opt.h:429
var_names
static const char *const var_names[]
Definition: vf_pad.c:45
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_pad.c:326
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
float.h
mathematics.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
AV_OPT_TYPE_RATIONAL
@ AV_OPT_TYPE_RATIONAL
Underlying C type is AVRational.
Definition: opt.h:280
video.h
avfilter_vf_pad_outputs
static const AVFilterPad avfilter_vf_pad_outputs[]
Definition: vf_pad.c:449
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:410
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
formats.h
ff_vf_pad
const AVFilter ff_vf_pad
Definition: vf_pad.c:457
PadContext::w
int w
Definition: vf_pad.c:91
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:472
FFSIGN
#define FFSIGN(a)
Definition: common.h:75
VAR_SAR
@ VAR_SAR
Definition: vf_pad.c:68
EVAL_MODE_INIT
@ EVAL_MODE_INIT
Definition: vf_pad.c:84
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_pad.c:222
colorspace.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_copy_rectangle2
void ff_copy_rectangle2(FFDrawContext *draw, uint8_t *dst[], int dst_linesize[], uint8_t *src[], int src_linesize[], int dst_x, int dst_y, int src_x, int src_y, int w, int h)
Copy a rectangle from an image to another.
Definition: drawutils.c:224
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_pad.c:108
PadContext
Definition: vf_pad.c:89
filters.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(pad)
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
NAN
#define NAN
Definition: mathematics.h:115
PadContext::h
int h
output dimensions, a value of 0 will result in the input size
Definition: vf_pad.c:91
if
if(ret)
Definition: filter_design.txt:179
planes
static const struct @465 planes[]
OFFSET
#define OFFSET(x)
Definition: vf_pad.c:419
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
VAR_DAR
@ VAR_DAR
Definition: vf_pad.c:69
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:713
VAR_OUT_W
@ VAR_OUT_W
Definition: vf_pad.c:63
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_OPT_TYPE_COLOR
@ AV_OPT_TYPE_COLOR
Underlying C type is uint8_t[4].
Definition: opt.h:323
parseutils.h
double
double
Definition: af_crystalizer.c:132
avfilter_vf_pad_inputs
static const AVFilterPad avfilter_vf_pad_inputs[]
Definition: vf_pad.c:439
VAR_OW
@ VAR_OW
Definition: vf_pad.c:63
VAR_OH
@ VAR_OH
Definition: vf_pad.c:64
av_frame_get_plane_buffer
AVBufferRef * av_frame_get_plane_buffer(const AVFrame *frame, int plane)
Get the buffer reference a given data plane is stored in.
Definition: frame.c:718
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:111
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_pad.c:85
VAR_OUT_H
@ VAR_OUT_H
Definition: vf_pad.c:64
eval.h
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
av_expr_parse_and_eval
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:803
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_pad.c:86
pad_options
static const AVOption pad_options[]
Definition: vf_pad.c:422
ff_draw_init2
int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, enum AVColorRange range, unsigned flags)
Init a draw context.
Definition: drawutils.c:95
query_formats
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vf_pad.c:75
ff_fill_rectangle
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:246
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:649
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:476
PadContext::h_expr
char * h_expr
height expression string
Definition: vf_pad.c:98
VARS_NB
@ VARS_NB
Definition: vf_pad.c:72
PadContext::x_expr
char * x_expr
width expression string
Definition: vf_pad.c:99
PadContext::inlink_w
int inlink_w
Definition: vf_pad.c:94
PadContext::x
int x
Definition: vf_pad.c:92
frame_needs_copy
static int frame_needs_copy(PadContext *s, AVFrame *frame)
Definition: vf_pad.c:313
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
VAR_A
@ VAR_A
Definition: vf_pad.c:67
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_draw_supported_pixel_formats
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:662
buffer_needs_copy
static int buffer_needs_copy(PadContext *s, AVFrame *frame, AVBufferRef *buf)
Definition: vf_pad.c:261
common.h
EvalMode
EvalMode
Definition: af_volume.h:39
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
VAR_IH
@ VAR_IH
Definition: vf_pad.c:62
ff_draw_round_to_sub
int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, int value)
Round a dimension according to subsampling.
Definition: drawutils.c:650
FFDrawContext
Definition: drawutils.h:36
VAR_X
@ VAR_X
Definition: vf_pad.c:65
VAR_IN_H
@ VAR_IN_H
Definition: vf_pad.c:62
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
PadContext::draw
FFDrawContext draw
Definition: vf_pad.c:102
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:171
AVFilter
Filter definition.
Definition: avfilter.h:201
PadContext::color
FFDrawColor color
Definition: vf_pad.c:103
PadContext::in_w
int in_w
Definition: vf_pad.c:93
ret
ret
Definition: filter_design.txt:187
frame
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 the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:496
AVFrame::height
int height
Definition: frame.h:461
PadContext::aspect
AVRational aspect
Definition: vf_pad.c:95
PadContext::rgba_color
uint8_t rgba_color[4]
color for the padding area
Definition: vf_pad.c:101
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FLAGS
#define FLAGS
Definition: vf_pad.c:420
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
PadContext::in_h
int in_h
width and height for the padded input video, which has to be aligned to the chroma values in order to...
Definition: vf_pad.c:93
PadContext::inlink_h
int inlink_h
Definition: vf_pad.c:94
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:434
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
drawutils.h
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
VAR_VSUB
@ VAR_VSUB
Definition: vf_pad.c:71
VAR_IW
@ VAR_IW
Definition: vf_pad.c:61