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  ret = ff_draw_init2(&s->draw, inlink->format, inlink->colorspace, inlink->color_range, 0);
118  if (ret < 0) {
119  av_log(ctx, AV_LOG_ERROR, "Failed to initialize FFDrawContext\n");
120  return ret;
121  }
122  ff_draw_color(&s->draw, &s->color, s->rgba_color);
123 
124  var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
125  var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
126  var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
127  var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
128  var_values[VAR_A] = (double) inlink->w / inlink->h;
129  var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
130  (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
131  var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR];
132  var_values[VAR_HSUB] = 1 << s->draw.hsub_max;
133  var_values[VAR_VSUB] = 1 << s->draw.vsub_max;
134 
135  /* evaluate width and height */
136  av_expr_parse_and_eval(&res, (expr = s->w_expr),
137  var_names, var_values,
138  NULL, NULL, NULL, NULL, NULL, 0, ctx);
139  s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
140  if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
141  var_names, var_values,
142  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
143  goto eval_fail;
144  s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
145  if (!s->h)
146  var_values[VAR_OUT_H] = var_values[VAR_OH] = s->h = inlink->h;
147 
148  /* evaluate the width again, as it may depend on the evaluated output height */
149  if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
150  var_names, var_values,
151  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
152  goto eval_fail;
153  s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
154  if (!s->w)
155  var_values[VAR_OUT_W] = var_values[VAR_OW] = s->w = inlink->w;
156 
157  if (adjusted_aspect.num && adjusted_aspect.den) {
158  adjusted_aspect = av_div_q(adjusted_aspect, inlink->sample_aspect_ratio);
159  if (s->h < av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num)) {
160  s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = av_rescale(s->w, adjusted_aspect.den, adjusted_aspect.num);
161  } else {
162  s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = av_rescale(s->h, adjusted_aspect.num, adjusted_aspect.den);
163  }
164  }
165 
166  /* evaluate x and y */
167  av_expr_parse_and_eval(&res, (expr = s->x_expr),
168  var_names, var_values,
169  NULL, NULL, NULL, NULL, NULL, 0, ctx);
170  s->x = var_values[VAR_X] = res;
171  if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
172  var_names, var_values,
173  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
174  goto eval_fail;
175  s->y = var_values[VAR_Y] = res;
176  /* evaluate x again, as it may depend on the evaluated y value */
177  if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),
178  var_names, var_values,
179  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
180  goto eval_fail;
181  s->x = var_values[VAR_X] = res;
182 
183  if (s->x < 0 || s->x + inlink->w > s->w)
184  s->x = var_values[VAR_X] = (s->w - inlink->w) / 2;
185  if (s->y < 0 || s->y + inlink->h > s->h)
186  s->y = var_values[VAR_Y] = (s->h - inlink->h) / 2;
187 
188  s->w = ff_draw_round_to_sub(&s->draw, 0, -1, s->w);
189  s->h = ff_draw_round_to_sub(&s->draw, 1, -1, s->h);
190  /* sanity check params */
191  if (s->w < inlink->w || s->h < inlink->h) {
192  av_log(ctx, AV_LOG_ERROR, "Padded dimensions cannot be smaller than input dimensions.\n");
193  return AVERROR(EINVAL);
194  }
195 
196  s->x = ff_draw_round_to_sub(&s->draw, 0, -1, s->x);
197  s->y = ff_draw_round_to_sub(&s->draw, 1, -1, s->y);
198  s->in_w = ff_draw_round_to_sub(&s->draw, 0, -1, inlink->w);
199  s->in_h = ff_draw_round_to_sub(&s->draw, 1, -1, inlink->h);
200  s->inlink_w = inlink->w;
201  s->inlink_h = inlink->h;
202 
203  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",
204  inlink->w, inlink->h, s->w, s->h, s->x, s->y,
205  s->rgba_color[0], s->rgba_color[1], s->rgba_color[2], s->rgba_color[3]);
206 
207  if (s->x < 0 || s->y < 0 ||
208  s->w <= 0 || s->h <= 0 ||
209  (unsigned)s->x + (unsigned)inlink->w > s->w ||
210  (unsigned)s->y + (unsigned)inlink->h > s->h) {
212  "Input area %d:%d:%d:%d not within the padded area 0:0:%d:%d or zero-sized\n",
213  s->x, s->y, s->x + inlink->w, s->y + inlink->h, s->w, s->h);
214  return AVERROR(EINVAL);
215  }
216 
217  return 0;
218 
219 eval_fail:
221  "Error when evaluating the expression '%s'\n", expr);
222  return ret;
223 
224 }
225 
226 static int config_output(AVFilterLink *outlink)
227 {
228  PadContext *s = outlink->src->priv;
229 
230  outlink->w = s->w;
231  outlink->h = s->h;
232  return 0;
233 }
234 
236 {
237  PadContext *s = inlink->dst->priv;
238  AVFrame *frame;
239  int plane;
240 
241  if (s->inlink_w <= 0)
242  return NULL;
243 
244  frame = ff_get_video_buffer(inlink->dst->outputs[0],
245  w + (s->w - s->in_w),
246  h + (s->h - s->in_h) + (s->x > 0));
247 
248  if (!frame)
249  return NULL;
250 
251  frame->width = w;
252  frame->height = h;
253 
254  for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
255  int hsub = s->draw.hsub[plane];
256  int vsub = s->draw.vsub[plane];
257  frame->data[plane] += (s->x >> hsub) * s->draw.pixelstep[plane] +
258  (s->y >> vsub) * frame->linesize[plane];
259  }
260 
261  return frame;
262 }
263 
264 /* check whether each plane in this buffer can be padded without copying */
266 {
267  int planes[4] = { -1, -1, -1, -1}, *p = planes;
268  int i, j;
269 
270  /* get all planes in this buffer */
271  for (i = 0; i < FF_ARRAY_ELEMS(planes) && frame->data[i]; i++) {
272  if (av_frame_get_plane_buffer(frame, i) == buf)
273  *p++ = i;
274  }
275 
276  /* for each plane in this buffer, check that it can be padded without
277  * going over buffer bounds or other planes */
278  for (i = 0; i < FF_ARRAY_ELEMS(planes) && planes[i] >= 0; i++) {
279  int hsub = s->draw.hsub[planes[i]];
280  int vsub = s->draw.vsub[planes[i]];
281 
282  uint8_t *start = frame->data[planes[i]];
283  uint8_t *end = start + (frame->height >> vsub) *
284  frame->linesize[planes[i]];
285 
286  /* amount of free space needed before the start and after the end
287  * of the plane */
288  ptrdiff_t req_start = (s->x >> hsub) * s->draw.pixelstep[planes[i]] +
289  (s->y >> vsub) * frame->linesize[planes[i]];
290  ptrdiff_t req_end = ((s->w - s->x - frame->width) >> hsub) *
291  s->draw.pixelstep[planes[i]] +
292  ((s->h - s->y - frame->height) >> vsub) * frame->linesize[planes[i]];
293 
294  if (frame->linesize[planes[i]] < (s->w >> hsub) * s->draw.pixelstep[planes[i]])
295  return 1;
296  if (start - buf->data < req_start ||
297  (buf->data + buf->size) - end < req_end)
298  return 1;
299 
300  for (j = 0; j < FF_ARRAY_ELEMS(planes) && planes[j] >= 0; j++) {
301  int vsub1 = s->draw.vsub[planes[j]];
302  uint8_t *start1 = frame->data[planes[j]];
303  uint8_t *end1 = start1 + (frame->height >> vsub1) *
304  frame->linesize[planes[j]];
305  if (i == j)
306  continue;
307 
308  if (FFSIGN(start - end1) != FFSIGN(start - end1 - req_start) ||
309  FFSIGN(end - start1) != FFSIGN(end - start1 + req_end))
310  return 1;
311  }
312  }
313 
314  return 0;
315 }
316 
318 {
319  int i;
320 
322  return 1;
323 
324  for (i = 0; i < 4 && frame->buf[i]; i++)
325  if (buffer_needs_copy(s, frame, frame->buf[i]))
326  return 1;
327  return 0;
328 }
329 
331 {
332  PadContext *s = inlink->dst->priv;
333  AVFilterLink *outlink = inlink->dst->outputs[0];
334  AVFrame *out;
335  int needs_copy;
336  if(s->eval_mode == EVAL_MODE_FRAME && (
337  in->width != s->inlink_w
338  || in->height != s->inlink_h
339  || in->format != outlink->format
341  int ret;
342 
343  inlink->dst->inputs[0]->format = in->format;
344  inlink->dst->inputs[0]->w = in->width;
345  inlink->dst->inputs[0]->h = in->height;
346 
347  inlink->dst->inputs[0]->sample_aspect_ratio.den = in->sample_aspect_ratio.den;
348  inlink->dst->inputs[0]->sample_aspect_ratio.num = in->sample_aspect_ratio.num;
349 
350 
351  if ((ret = config_input(inlink)) < 0) {
352  s->inlink_w = -1;
353  return ret;
354  }
355  if ((ret = config_output(outlink)) < 0) {
356  s->inlink_w = -1;
357  return ret;
358  }
359  }
360 
361  needs_copy = frame_needs_copy(s, in);
362 
363  if (needs_copy) {
364  av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
365  out = ff_get_video_buffer(outlink,
366  FFMAX(inlink->w, s->w),
367  FFMAX(inlink->h, s->h));
368  if (!out) {
369  av_frame_free(&in);
370  return AVERROR(ENOMEM);
371  }
372 
374  } else {
375  int i;
376 
377  out = in;
378  for (i = 0; i < 4 && out->data[i] && out->linesize[i]; i++) {
379  int hsub = s->draw.hsub[i];
380  int vsub = s->draw.vsub[i];
381  out->data[i] -= (s->x >> hsub) * s->draw.pixelstep[i] +
382  (s->y >> vsub) * out->linesize[i];
383  }
384  }
385 
386  /* top bar */
387  if (s->y) {
388  ff_fill_rectangle(&s->draw, &s->color,
389  out->data, out->linesize,
390  0, 0, s->w, s->y);
391  }
392 
393  /* bottom bar */
394  if (s->h > s->y + s->in_h) {
395  ff_fill_rectangle(&s->draw, &s->color,
396  out->data, out->linesize,
397  0, s->y + s->in_h, s->w, s->h - s->y - s->in_h);
398  }
399 
400  /* left border */
401  ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize,
402  0, s->y, s->x, in->height);
403 
404  if (needs_copy) {
405  ff_copy_rectangle2(&s->draw,
406  out->data, out->linesize, in->data, in->linesize,
407  s->x, s->y, 0, 0, in->width, in->height);
408  }
409 
410  /* right border */
411  ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize,
412  s->x + s->in_w, s->y, s->w - s->x - s->in_w,
413  in->height);
414 
415  out->width = s->w;
416  out->height = s->h;
417 
418  if (in != out)
419  av_frame_free(&in);
420  return ff_filter_frame(outlink, out);
421 }
422 
423 #define OFFSET(x) offsetof(PadContext, x)
424 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
425 
426 static const AVOption pad_options[] = {
427  { "width", "set the pad area width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
428  { "w", "set the pad area width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
429  { "height", "set the pad area height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
430  { "h", "set the pad area height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
431  { "x", "set the x offset expression for the input image position", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
432  { "y", "set the y offset expression for the input image position", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
433  { "color", "set the color of the padded area border", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS },
434  { "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" },
435  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
436  { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
437  { "aspect", "pad to fit an aspect instead of a resolution", OFFSET(aspect), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, DBL_MAX, FLAGS },
438  { NULL }
439 };
440 
442 
444  {
445  .name = "default",
446  .type = AVMEDIA_TYPE_VIDEO,
447  .config_props = config_input,
448  .get_buffer.video = get_video_buffer,
449  .filter_frame = filter_frame,
450  },
451 };
452 
454  {
455  .name = "default",
456  .type = AVMEDIA_TYPE_VIDEO,
457  .config_props = config_output,
458  },
459 };
460 
462  .p.name = "pad",
463  .p.description = NULL_IF_CONFIG_SMALL("Pad the input video."),
464  .p.priv_class = &pad_class,
465  .priv_size = sizeof(PadContext),
469 };
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:1078
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
planes
static const struct @475 planes[]
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:70
get_video_buffer
static AVFrame * get_video_buffer(AVFilterLink *inlink, int w, int h)
Definition: vf_pad.c:235
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
pixdesc.h
AVFrame::width
int width
Definition: frame.h:482
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:330
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:203
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:453
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:431
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
formats.h
PadContext::w
int w
Definition: vf_pad.c:91
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:272
FFSIGN
#define FFSIGN(a)
Definition: common.h:75
ff_vf_pad
const FFFilter ff_vf_pad
Definition: vf_pad.c:461
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:226
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
FFFilter
Definition: filters.h:265
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:226
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
OFFSET
#define OFFSET(x)
Definition: vf_pad.c:423
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:633
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:443
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:638
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:109
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:805
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_pad.c:86
pad_options
static const AVOption pad_options[]
Definition: vf_pad.c:426
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:97
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:248
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:569
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:497
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:317
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:664
buffer_needs_copy
static int buffer_needs_copy(PadContext *s, AVFrame *frame, AVBufferRef *buf)
Definition: vf_pad.c:265
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:652
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:173
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:517
AVFrame::height
int height
Definition: frame.h:482
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:257
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:269
FLAGS
#define FLAGS
Definition: vf_pad.c:424
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:455
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