FFmpeg
vf_tiltandshift.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Vittorio Giovara
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 vf_tiltandshift.c
23  * Simple time and space inverter.
24  */
25 
26 #include <string.h>
27 
28 #include "libavutil/imgutils.h"
29 #include "libavutil/mem.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/pixdesc.h"
32 
33 #include "avfilter.h"
34 #include "filters.h"
35 #include "video.h"
36 
42 };
43 
44 typedef struct TiltandshiftContext {
45  const AVClass *class;
46 
47  /* set when all input frames have been processed and we have to
48  * empty buffers, pad and then return */
49  int eof_recv;
50 
51  /* live or static sliding */
52  int tilt;
53 
54  /* initial or final actions to perform (pad/hold a frame/black/nothing) */
57 
58  /* columns to hold or pad at the beginning or at the end (respectively) */
59  int hold;
60  int pad;
61 
62  /* buffers for black columns */
63  uint8_t *black_buffers[4];
65 
66  /* list containing all input frames */
67  size_t input_size;
70 
73 
75 {
76  if (s->input == NULL) {
77  s->input = frame;
78  } else {
79  AVFrame *head = s->input;
80  while (head->opaque)
81  head = head->opaque;
82  head->opaque = frame;
83  }
84  s->input_size++;
85  return 0;
86 }
87 
89 {
90  AVFrame *head = s->input;
91  if (head) {
92  s->input = head->opaque;
93  av_frame_free(&head);
94  }
95  s->input_size--;
96 }
97 
98 static const enum AVPixelFormat pix_fmts[] = {
104 };
105 
107 {
108  TiltandshiftContext *s = ctx->priv;
109  while (s->input)
111  av_freep(&s->black_buffers);
112 }
113 
114 static int config_props(AVFilterLink *outlink)
115 {
116  AVFilterContext *ctx = outlink->src;
117  TiltandshiftContext *s = ctx->priv;
118 
119  outlink->w = ctx->inputs[0]->w;
120  outlink->h = ctx->inputs[0]->h;
121  outlink->format = ctx->inputs[0]->format;
122 
123  // when we have to pad black or a frame at the start, skip navigating
124  // the list and use either the frame or black for the requested value
125  if (s->start != TILT_NONE && !s->hold)
126  s->hold = outlink->w;
127 
128  // Init black buffers if we pad with black at the start or at the end.
129  // For the end, we always have to init on NONE and BLACK because we never
130  // know if there are going to be enough input frames to fill an output one.
131  if (s->start == TILT_BLACK || s->end != TILT_FRAME) {
132  int i, j, ret;
133  uint8_t black_data[] = { 0x10, 0x80, 0x80, 0x10 };
135  if (!desc)
136  return AVERROR_BUG;
137 
138  if (outlink->format == AV_PIX_FMT_YUVJ420P ||
139  outlink->format == AV_PIX_FMT_YUVJ422P ||
140  outlink->format == AV_PIX_FMT_YUVJ444P ||
141  outlink->format == AV_PIX_FMT_YUVJ440P ||
142  outlink->color_range == AVCOL_RANGE_JPEG)
143  black_data[0] = black_data[3] = 0;
144 
145  ret = av_image_alloc(s->black_buffers, s->black_linesizes, 1,
146  outlink->h, outlink->format, 1);
147  if (ret < 0)
148  return ret;
149 
150  for (i = 0; i < FFMIN(desc->nb_components, 4); i++)
151  for (j = 0; j < (!i ? outlink->h
152  : -((-outlink->h) >> desc->log2_chroma_h)); j++)
153  memset(s->black_buffers[i] + j * s->black_linesizes[i],
154  black_data[i], 1);
155 
156  av_log(ctx, AV_LOG_VERBOSE, "Padding buffers initialized.\n");
157  }
158 
159  s->desc = av_pix_fmt_desc_get(outlink->format);
160  if (!s->desc)
161  return AVERROR_BUG;
162 
163  return 0;
164 }
165 
166 
167 static void copy_column(AVFilterLink *outlink,
168  uint8_t *dst_data[4], int dst_linesizes[4],
169  const uint8_t *src_data[4], const int src_linesizes[4],
170  int ncol, int tilt)
171 {
172  AVFilterContext *ctx = outlink->src;
173  TiltandshiftContext *s = ctx->priv;
174  uint8_t *dst[4];
175  const uint8_t *src[4];
176 
177  dst[0] = dst_data[0] + ncol;
178  dst[1] = dst_data[1] + (ncol >> s->desc->log2_chroma_w);
179  dst[2] = dst_data[2] + (ncol >> s->desc->log2_chroma_w);
180 
181  if (!tilt)
182  ncol = 0;
183  src[0] = src_data[0] + ncol;
184  src[1] = src_data[1] + (ncol >> s->desc->log2_chroma_w);
185  src[2] = src_data[2] + (ncol >> s->desc->log2_chroma_w);
186 
187  av_image_copy(dst, dst_linesizes, src, src_linesizes, outlink->format, 1, outlink->h);
188 }
189 
190 static int output_frame(AVFilterLink *outlink)
191 {
192  TiltandshiftContext *s = outlink->src->priv;
193  AVFrame *head;
194  int ret;
195 
196  int ncol = 0;
197  AVFrame *dst = ff_get_video_buffer(outlink, outlink->w, outlink->h);
198  if (!dst)
199  return AVERROR(ENOMEM);
200 
201  // in case we have to do any initial black padding
202  if (s->start == TILT_BLACK) {
203  for ( ; ncol < s->hold; ncol++)
204  copy_column(outlink, dst->data, dst->linesize,
205  (const uint8_t **)s->black_buffers, s->black_linesizes,
206  ncol, 0);
207  }
208 
209  head = s->input;
210  // copy a column from each input frame
211  for ( ; ncol < s->input_size; ncol++) {
212  AVFrame *src = head;
213 
214  copy_column(outlink, dst->data, dst->linesize,
215  (const uint8_t **)src->data, src->linesize,
216  ncol, s->tilt);
217 
218  // keep track of the last known frame in case we need it below
219  s->prev = head;
220  // advance to the next frame unless we have to hold it
221  if (s->hold <= ncol)
222  head = head->opaque;
223  }
224 
225  // pad any remaining space with black or last frame
226  if (s->end == TILT_FRAME) {
227  for ( ; ncol < outlink->w; ncol++)
228  copy_column(outlink, dst->data, dst->linesize,
229  (const uint8_t **)s->prev->data,
230  s->prev->linesize, ncol, 1);
231  } else { // TILT_BLACK and TILT_NONE
232  for ( ; ncol < outlink->w; ncol++)
233  copy_column(outlink, dst->data, dst->linesize,
234  (const uint8_t **)s->black_buffers, s->black_linesizes,
235  ncol, 0);
236  }
237 
238  // set correct timestamps and props as long as there is proper input
239  ret = av_frame_copy_props(dst, s->input);
240  if (ret < 0) {
241  av_frame_free(&dst);
242  return ret;
243  }
244 
245  // discard frame at the top of the list since it has been fully processed
247  // and it is safe to reduce the hold value (even if unused)
248  s->hold--;
249 
250  // output
251  return ff_filter_frame(outlink, dst);
252 }
253 
254 // This function just polls for new frames and queues them on a list
256 {
257  AVFilterLink *outlink = inlink->dst->outputs[0];
258  AVFilterContext *ctx = outlink->src;
259  TiltandshiftContext *s = inlink->dst->priv;
260 
261  int ret = list_add_frame(s, frame);
262  if (ret < 0) {
263  return ret;
264  }
265 
266  // load up enough frames to fill a frame and keep the queue filled on subsequent
267  // calls, until we receive EOF, and then we either pad or end
268  if (!s->eof_recv && s->input_size < outlink->w - s->pad) {
269  av_log(ctx, AV_LOG_DEBUG, "Not enough frames in the list (%zu/%d), waiting for more.\n", s->input_size, outlink->w - s->pad);
270  return 0;
271  }
272 
273  return output_frame(outlink);
274 }
275 
276 static int request_frame(AVFilterLink *outlink)
277 {
278  AVFilterContext *ctx = outlink->src;
279  TiltandshiftContext *s = ctx->priv;
280  int ret;
281 
282  // signal job finished when list is empty or when padding is either
283  // limited or disabled and eof was received
284  if ((s->input_size <= 0 || s->input_size == outlink->w - s->pad || s->end == TILT_NONE) && s->eof_recv) {
285  return AVERROR_EOF;
286  }
287 
288  ret = ff_request_frame(ctx->inputs[0]);
289  if (ret == AVERROR_EOF) {
290  s->eof_recv = 1;
291  } else if (ret < 0) {
292  return ret;
293  }
294 
295  if (s->eof_recv) {
296  while (s->input_size) {
297  av_log(ctx, AV_LOG_DEBUG, "Emptying buffers (%zu/%d).\n", s->input_size, outlink->w - s->pad);
298  ret = output_frame(outlink);
299  if (ret < 0) {
300  return ret;
301  }
302  }
303  }
304 
305  return 0;
306 }
307 
308 #define OFFSET(x) offsetof(TiltandshiftContext, x)
309 #define V AV_OPT_FLAG_VIDEO_PARAM
310 static const AVOption tiltandshift_options[] = {
311  { "tilt", "Tilt the video horizontally while shifting", OFFSET(tilt), AV_OPT_TYPE_INT,
312  { .i64 = 1 }, 0, 1, .flags = V, .unit = "tilt" },
313 
314  { "start", "Action at the start of input", OFFSET(start), AV_OPT_TYPE_INT,
315  { .i64 = TILT_NONE }, 0, TILT_OPT_MAX, .flags = V, .unit = "start" },
316  { "none", "Start immediately (default)", 0, AV_OPT_TYPE_CONST,
317  { .i64 = TILT_NONE }, INT_MIN, INT_MAX, .flags = V, .unit = "start" },
318  { "frame", "Use the first frames", 0, AV_OPT_TYPE_CONST,
319  { .i64 = TILT_FRAME }, INT_MIN, INT_MAX, .flags = V, .unit = "start" },
320  { "black", "Fill with black", 0, AV_OPT_TYPE_CONST,
321  { .i64 = TILT_BLACK }, INT_MIN, INT_MAX, .flags = V, .unit = "start" },
322 
323  { "end", "Action at the end of input", OFFSET(end), AV_OPT_TYPE_INT,
324  { .i64 = TILT_NONE }, 0, TILT_OPT_MAX, .flags = V, .unit = "end" },
325  { "none", "Do not pad at the end (default)", 0, AV_OPT_TYPE_CONST,
326  { .i64 = TILT_NONE }, INT_MIN, INT_MAX, .flags = V, .unit = "end" },
327  { "frame", "Use the last frame", 0, AV_OPT_TYPE_CONST,
328  { .i64 = TILT_FRAME }, INT_MIN, INT_MAX, .flags = V, .unit = "end" },
329  { "black", "Fill with black", 0, AV_OPT_TYPE_CONST,
330  { .i64 = TILT_BLACK }, INT_MIN, INT_MAX, .flags = V, .unit = "end" },
331 
332  { "hold", "Number of columns to hold at the start of the video", OFFSET(hold), AV_OPT_TYPE_INT,
333  { .i64 = 0 }, 0, INT_MAX, .flags = V, .unit = "hold" },
334  { "pad", "Number of columns to pad at the end of the video", OFFSET(pad), AV_OPT_TYPE_INT,
335  { .i64 = 0 }, 0, INT_MAX, .flags = V, .unit = "pad" },
336 
337  { NULL },
338 };
339 
340 AVFILTER_DEFINE_CLASS(tiltandshift);
341 
343  {
344  .name = "in",
345  .type = AVMEDIA_TYPE_VIDEO,
346  .filter_frame = filter_frame,
347  },
348 };
349 
351  {
352  .name = "out",
353  .type = AVMEDIA_TYPE_VIDEO,
354  .config_props = config_props,
355  .request_frame = request_frame,
356  },
357 };
358 
360  .name = "tiltandshift",
361  .description = NULL_IF_CONFIG_SMALL("Generate a tilt-and-shift'd video."),
362  .priv_size = sizeof(TiltandshiftContext),
363  .priv_class = &tiltandshift_class,
364  .uninit = uninit,
368 };
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
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
TILT_NONE
@ TILT_NONE
Definition: vf_tiltandshift.c:38
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
tiltandshift_inputs
static const AVFilterPad tiltandshift_inputs[]
Definition: vf_tiltandshift.c:342
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: filters.h:242
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1062
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3170
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
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
TiltandshiftContext
Definition: vf_tiltandshift.c:44
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
AVFrame::opaque
void * opaque
Frame owner's private data.
Definition: frame.h:537
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
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:717
AVOption
AVOption.
Definition: opt.h:429
V
#define V
Definition: vf_tiltandshift.c:309
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:475
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
list_remove_head
static void list_remove_head(TiltandshiftContext *s)
Definition: vf_tiltandshift.c:88
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_tiltandshift.c:106
video.h
TILT_BLACK
@ TILT_BLACK
Definition: vf_tiltandshift.c:40
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:472
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
TILT_OPT_MAX
@ TILT_OPT_MAX
Definition: vf_tiltandshift.c:41
av_cold
#define av_cold
Definition: attributes.h:90
OFFSET
#define OFFSET(x)
Definition: vf_tiltandshift.c:308
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:86
s
#define s(width, name)
Definition: cbs_vp9.c:198
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: vf_tiltandshift.c:255
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
ff_vf_tiltandshift
const AVFilter ff_vf_tiltandshift
Definition: vf_tiltandshift.c:359
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:87
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
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
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:85
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: vf_tiltandshift.c:276
tiltandshift_outputs
static const AVFilterPad tiltandshift_outputs[]
Definition: vf_tiltandshift.c:350
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_tiltandshift.c:98
av_image_alloc
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align)
Allocate an image with size w and h and pixel format pix_fmt, and fill pointers and linesizes accordi...
Definition: imgutils.c:218
TiltandshiftContext::tilt
int tilt
Definition: vf_tiltandshift.c:52
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
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
TiltandshiftContext::start
enum PaddingOption start
Definition: vf_tiltandshift.c:55
TiltandshiftContext::desc
const AVPixFmtDescriptor * desc
Definition: vf_tiltandshift.c:71
TiltandshiftContext::hold
int hold
Definition: vf_tiltandshift.c:59
config_props
static int config_props(AVFilterLink *outlink)
Definition: vf_tiltandshift.c:114
TiltandshiftContext::pad
int pad
Definition: vf_tiltandshift.c:60
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_YUVJ440P
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition: pixfmt.h:107
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
tiltandshift_options
static const AVOption tiltandshift_options[]
Definition: vf_tiltandshift.c:310
TILT_FRAME
@ TILT_FRAME
Definition: vf_tiltandshift.c:39
AVFilter
Filter definition.
Definition: avfilter.h:201
list_add_frame
static int list_add_frame(TiltandshiftContext *s, AVFrame *frame)
Definition: vf_tiltandshift.c:74
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
TiltandshiftContext::prev
AVFrame * prev
Definition: vf_tiltandshift.c:69
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
TiltandshiftContext::end
enum PaddingOption end
Definition: vf_tiltandshift.c:56
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
desc
const char * desc
Definition: libsvtav1.c:79
output_frame
static int output_frame(AVFilterLink *outlink)
Definition: vf_tiltandshift.c:190
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
TiltandshiftContext::input
AVFrame * input
Definition: vf_tiltandshift.c:68
mem.h
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
PaddingOption
PaddingOption
Definition: vf_tiltandshift.c:37
imgutils.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:79
copy_column
static void copy_column(AVFilterLink *outlink, uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], int ncol, int tilt)
Definition: vf_tiltandshift.c:167
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
TiltandshiftContext::black_buffers
uint8_t * black_buffers[4]
Definition: vf_tiltandshift.c:63
TiltandshiftContext::eof_recv
int eof_recv
Definition: vf_tiltandshift.c:49
av_image_copy
void av_image_copy(uint8_t *const dst_data[4], const int dst_linesizes[4], const uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:422
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
TiltandshiftContext::input_size
size_t input_size
Definition: vf_tiltandshift.c:67
src
#define src
Definition: vp8dsp.c:248
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(tiltandshift)
TiltandshiftContext::black_linesizes
int black_linesizes[4]
Definition: vf_tiltandshift.c:64