FFmpeg
vf_rotate.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Stefano Sabatini
3  * Copyright (c) 2008 Vitor Sessak
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  * rotation filter, partially based on the tests/rotozoom.c program
25 */
26 
27 #include "libavutil/avstring.h"
28 #include "libavutil/eval.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/parseutils.h"
32 #include "libavutil/pixdesc.h"
33 
34 #include "avfilter.h"
35 #include "drawutils.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 #include <float.h>
40 
41 static const char * const var_names[] = {
42  "in_w" , "iw", ///< width of the input video
43  "in_h" , "ih", ///< height of the input video
44  "out_w", "ow", ///< width of the input video
45  "out_h", "oh", ///< height of the input video
46  "hsub", "vsub",
47  "n", ///< number of frame
48  "t", ///< timestamp expressed in seconds
49  NULL
50 };
51 
52 enum var_name {
61 };
62 
63 typedef struct RotContext {
64  const AVClass *class;
65  double angle;
66  char *angle_expr_str; ///< expression for the angle
67  AVExpr *angle_expr; ///< parsed expression for the angle
69  int outh, outw;
70  uint8_t fillcolor[4]; ///< color expressed either in YUVA or RGBA colorspace for the padding area
73  int hsub, vsub;
74  int nb_planes;
76  float sinx, cosx;
80  uint8_t *(*interpolate_bilinear)(uint8_t *dst_color,
81  const uint8_t *src, int src_linesize, int src_linestep,
82  int x, int y, int max_x, int max_y);
83 } RotContext;
84 
85 typedef struct ThreadData {
86  AVFrame *in, *out;
87  int inw, inh;
88  int outw, outh;
89  int plane;
90  int xi, yi;
91  int xprime, yprime;
92  int c, s;
93 } ThreadData;
94 
95 #define OFFSET(x) offsetof(RotContext, x)
96 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
97 
98 static const AVOption rotate_options[] = {
99  { "angle", "set angle (in radians)", OFFSET(angle_expr_str), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
100  { "a", "set angle (in radians)", OFFSET(angle_expr_str), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
101  { "out_w", "set output width expression", OFFSET(outw_expr_str), AV_OPT_TYPE_STRING, {.str="iw"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
102  { "ow", "set output width expression", OFFSET(outw_expr_str), AV_OPT_TYPE_STRING, {.str="iw"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
103  { "out_h", "set output height expression", OFFSET(outh_expr_str), AV_OPT_TYPE_STRING, {.str="ih"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
104  { "oh", "set output height expression", OFFSET(outh_expr_str), AV_OPT_TYPE_STRING, {.str="ih"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
105  { "fillcolor", "set background fill color", OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
106  { "c", "set background fill color", OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, .flags=FLAGS },
107  { "bilinear", "use bilinear interpolation", OFFSET(use_bilinear), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, .flags=FLAGS },
108  { NULL }
109 };
110 
112 
114 {
115  RotContext *rot = ctx->priv;
116 
117  if (!strcmp(rot->fillcolor_str, "none"))
118  rot->fillcolor_enable = 0;
119  else if (av_parse_color(rot->fillcolor, rot->fillcolor_str, -1, ctx) >= 0)
120  rot->fillcolor_enable = 1;
121  else
122  return AVERROR(EINVAL);
123  return 0;
124 }
125 
127 {
128  RotContext *rot = ctx->priv;
129 
130  av_expr_free(rot->angle_expr);
131  rot->angle_expr = NULL;
132 }
133 
135 {
136  static const enum AVPixelFormat pix_fmts[] = {
157  };
158 
159  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
160  if (!fmts_list)
161  return AVERROR(ENOMEM);
162  return ff_set_common_formats(ctx, fmts_list);
163 }
164 
165 static double get_rotated_w(void *opaque, double angle)
166 {
167  RotContext *rot = opaque;
168  double inw = rot->var_values[VAR_IN_W];
169  double inh = rot->var_values[VAR_IN_H];
170  float sinx = sin(angle);
171  float cosx = cos(angle);
172 
173  return FFMAX(0, inh * sinx) + FFMAX(0, -inw * cosx) +
174  FFMAX(0, inw * cosx) + FFMAX(0, -inh * sinx);
175 }
176 
177 static double get_rotated_h(void *opaque, double angle)
178 {
179  RotContext *rot = opaque;
180  double inw = rot->var_values[VAR_IN_W];
181  double inh = rot->var_values[VAR_IN_H];
182  float sinx = sin(angle);
183  float cosx = cos(angle);
184 
185  return FFMAX(0, -inh * cosx) + FFMAX(0, -inw * sinx) +
186  FFMAX(0, inh * cosx) + FFMAX(0, inw * sinx);
187 }
188 
189 static double (* const func1[])(void *, double) = {
192  NULL
193 };
194 
195 static const char * const func1_names[] = {
196  "rotw",
197  "roth",
198  NULL
199 };
200 
201 #define FIXP (1<<16)
202 #define FIXP2 (1<<20)
203 #define INT_PI 3294199 //(M_PI * FIXP2)
204 
205 /**
206  * Compute the sin of a using integer values.
207  * Input is scaled by FIXP2 and output values are scaled by FIXP.
208  */
209 static int64_t int_sin(int64_t a)
210 {
211  int64_t a2, res = 0;
212  int i;
213  if (a < 0) a = INT_PI-a; // 0..inf
214  a %= 2 * INT_PI; // 0..2PI
215 
216  if (a >= INT_PI*3/2) a -= 2*INT_PI; // -PI/2 .. 3PI/2
217  if (a >= INT_PI/2 ) a = INT_PI - a; // -PI/2 .. PI/2
218 
219  /* compute sin using Taylor series approximated to the fifth term */
220  a2 = (a*a)/(FIXP2);
221  for (i = 2; i < 11; i += 2) {
222  res += a;
223  a = -a*a2 / (FIXP2*i*(i+1));
224  }
225  return (res + 8)>>4;
226 }
227 
228 /**
229  * Interpolate the color in src at position x and y using bilinear
230  * interpolation.
231  */
233  const uint8_t *src, int src_linesize, int src_linestep,
234  int x, int y, int max_x, int max_y)
235 {
236  int int_x = av_clip(x>>16, 0, max_x);
237  int int_y = av_clip(y>>16, 0, max_y);
238  int frac_x = x&0xFFFF;
239  int frac_y = y&0xFFFF;
240  int i;
241  int int_x1 = FFMIN(int_x+1, max_x);
242  int int_y1 = FFMIN(int_y+1, max_y);
243 
244  for (i = 0; i < src_linestep; i++) {
245  int s00 = src[src_linestep * int_x + i + src_linesize * int_y ];
246  int s01 = src[src_linestep * int_x1 + i + src_linesize * int_y ];
247  int s10 = src[src_linestep * int_x + i + src_linesize * int_y1];
248  int s11 = src[src_linestep * int_x1 + i + src_linesize * int_y1];
249  int s0 = (((1<<16) - frac_x)*s00 + frac_x*s01);
250  int s1 = (((1<<16) - frac_x)*s10 + frac_x*s11);
251 
252  dst_color[i] = ((int64_t)((1<<16) - frac_y)*s0 + (int64_t)frac_y*s1) >> 32;
253  }
254 
255  return dst_color;
256 }
257 
258 /**
259  * Interpolate the color in src at position x and y using bilinear
260  * interpolation.
261  */
263  const uint8_t *src, int src_linesize, int src_linestep,
264  int x, int y, int max_x, int max_y)
265 {
266  int int_x = av_clip(x>>16, 0, max_x);
267  int int_y = av_clip(y>>16, 0, max_y);
268  int frac_x = x&0xFFFF;
269  int frac_y = y&0xFFFF;
270  int i;
271  int int_x1 = FFMIN(int_x+1, max_x);
272  int int_y1 = FFMIN(int_y+1, max_y);
273 
274  for (i = 0; i < src_linestep; i+=2) {
275  int s00 = AV_RL16(&src[src_linestep * int_x + i + src_linesize * int_y ]);
276  int s01 = AV_RL16(&src[src_linestep * int_x1 + i + src_linesize * int_y ]);
277  int s10 = AV_RL16(&src[src_linestep * int_x + i + src_linesize * int_y1]);
278  int s11 = AV_RL16(&src[src_linestep * int_x1 + i + src_linesize * int_y1]);
279  int s0 = (((1<<16) - frac_x)*s00 + frac_x*s01);
280  int s1 = (((1<<16) - frac_x)*s10 + frac_x*s11);
281 
282  AV_WL16(&dst_color[i], ((int64_t)((1<<16) - frac_y)*s0 + (int64_t)frac_y*s1) >> 32);
283  }
284 
285  return dst_color;
286 }
287 
288 static int config_props(AVFilterLink *outlink)
289 {
290  AVFilterContext *ctx = outlink->src;
291  RotContext *rot = ctx->priv;
292  AVFilterLink *inlink = ctx->inputs[0];
293  const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format);
294  int ret;
295  double res;
296  char *expr;
297 
298  ff_draw_init(&rot->draw, inlink->format, 0);
299  ff_draw_color(&rot->draw, &rot->color, rot->fillcolor);
300 
301  rot->hsub = pixdesc->log2_chroma_w;
302  rot->vsub = pixdesc->log2_chroma_h;
303 
304  if (pixdesc->comp[0].depth == 8)
306  else
308 
309  rot->var_values[VAR_IN_W] = rot->var_values[VAR_IW] = inlink->w;
310  rot->var_values[VAR_IN_H] = rot->var_values[VAR_IH] = inlink->h;
311  rot->var_values[VAR_HSUB] = 1<<rot->hsub;
312  rot->var_values[VAR_VSUB] = 1<<rot->vsub;
313  rot->var_values[VAR_N] = NAN;
314  rot->var_values[VAR_T] = NAN;
315  rot->var_values[VAR_OUT_W] = rot->var_values[VAR_OW] = NAN;
316  rot->var_values[VAR_OUT_H] = rot->var_values[VAR_OH] = NAN;
317 
318  av_expr_free(rot->angle_expr);
319  rot->angle_expr = NULL;
320  if ((ret = av_expr_parse(&rot->angle_expr, expr = rot->angle_expr_str, var_names,
321  func1_names, func1, NULL, NULL, 0, ctx)) < 0) {
322  av_log(ctx, AV_LOG_ERROR,
323  "Error occurred parsing angle expression '%s'\n", rot->angle_expr_str);
324  return ret;
325  }
326 
327 #define SET_SIZE_EXPR(name, opt_name) do { \
328  ret = av_expr_parse_and_eval(&res, expr = rot->name##_expr_str, \
329  var_names, rot->var_values, \
330  func1_names, func1, NULL, NULL, rot, 0, ctx); \
331  if (ret < 0 || isnan(res) || isinf(res) || res <= 0) { \
332  av_log(ctx, AV_LOG_ERROR, \
333  "Error parsing or evaluating expression for option %s: " \
334  "invalid expression '%s' or non-positive or indefinite value %f\n", \
335  opt_name, expr, res); \
336  return ret; \
337  } \
338 } while (0)
339 
340  /* evaluate width and height */
341  av_expr_parse_and_eval(&res, expr = rot->outw_expr_str, var_names, rot->var_values,
342  func1_names, func1, NULL, NULL, rot, 0, ctx);
343  rot->var_values[VAR_OUT_W] = rot->var_values[VAR_OW] = res;
344  rot->outw = res + 0.5;
345  SET_SIZE_EXPR(outh, "out_h");
346  rot->var_values[VAR_OUT_H] = rot->var_values[VAR_OH] = res;
347  rot->outh = res + 0.5;
348 
349  /* evaluate the width again, as it may depend on the evaluated output height */
350  SET_SIZE_EXPR(outw, "out_w");
351  rot->var_values[VAR_OUT_W] = rot->var_values[VAR_OW] = res;
352  rot->outw = res + 0.5;
353 
354  /* compute number of planes */
355  rot->nb_planes = av_pix_fmt_count_planes(inlink->format);
356  outlink->w = rot->outw;
357  outlink->h = rot->outh;
358  return 0;
359 }
360 
361 static av_always_inline void copy_elem(uint8_t *pout, const uint8_t *pin, int elem_size)
362 {
363  int v;
364  switch (elem_size) {
365  case 1:
366  *pout = *pin;
367  break;
368  case 2:
369  *((uint16_t *)pout) = *((uint16_t *)pin);
370  break;
371  case 3:
372  v = AV_RB24(pin);
373  AV_WB24(pout, v);
374  break;
375  case 4:
376  *((uint32_t *)pout) = *((uint32_t *)pin);
377  break;
378  default:
379  memcpy(pout, pin, elem_size);
380  break;
381  }
382 }
383 
384 static av_always_inline void simple_rotate_internal(uint8_t *dst, const uint8_t *src, int src_linesize, int angle, int elem_size, int len)
385 {
386  int i;
387  switch(angle) {
388  case 0:
389  memcpy(dst, src, elem_size * len);
390  break;
391  case 1:
392  for (i = 0; i<len; i++)
393  copy_elem(dst + i*elem_size, src + (len-i-1)*src_linesize, elem_size);
394  break;
395  case 2:
396  for (i = 0; i<len; i++)
397  copy_elem(dst + i*elem_size, src + (len-i-1)*elem_size, elem_size);
398  break;
399  case 3:
400  for (i = 0; i<len; i++)
401  copy_elem(dst + i*elem_size, src + i*src_linesize, elem_size);
402  break;
403  }
404 }
405 
406 static av_always_inline void simple_rotate(uint8_t *dst, const uint8_t *src, int src_linesize, int angle, int elem_size, int len)
407 {
408  switch(elem_size) {
409  case 1 : simple_rotate_internal(dst, src, src_linesize, angle, 1, len); break;
410  case 2 : simple_rotate_internal(dst, src, src_linesize, angle, 2, len); break;
411  case 3 : simple_rotate_internal(dst, src, src_linesize, angle, 3, len); break;
412  case 4 : simple_rotate_internal(dst, src, src_linesize, angle, 4, len); break;
413  default: simple_rotate_internal(dst, src, src_linesize, angle, elem_size, len); break;
414  }
415 }
416 
417 #define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
418 
419 static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
420 {
421  ThreadData *td = arg;
422  AVFrame *in = td->in;
423  AVFrame *out = td->out;
424  RotContext *rot = ctx->priv;
425  const int outw = td->outw, outh = td->outh;
426  const int inw = td->inw, inh = td->inh;
427  const int plane = td->plane;
428  const int xi = td->xi, yi = td->yi;
429  const int c = td->c, s = td->s;
430  const int start = (outh * job ) / nb_jobs;
431  const int end = (outh * (job+1)) / nb_jobs;
432  int xprime = td->xprime + start * s;
433  int yprime = td->yprime + start * c;
434  int i, j, x, y;
435 
436  for (j = start; j < end; j++) {
437  x = xprime + xi + FIXP*(inw-1)/2;
438  y = yprime + yi + FIXP*(inh-1)/2;
439 
440  if (fabs(rot->angle - 0) < FLT_EPSILON && outw == inw && outh == inh) {
441  simple_rotate(out->data[plane] + j * out->linesize[plane],
442  in->data[plane] + j * in->linesize[plane],
443  in->linesize[plane], 0, rot->draw.pixelstep[plane], outw);
444  } else if (fabs(rot->angle - M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) {
445  simple_rotate(out->data[plane] + j * out->linesize[plane],
446  in->data[plane] + j * rot->draw.pixelstep[plane],
447  in->linesize[plane], 1, rot->draw.pixelstep[plane], outw);
448  } else if (fabs(rot->angle - M_PI) < FLT_EPSILON && outw == inw && outh == inh) {
449  simple_rotate(out->data[plane] + j * out->linesize[plane],
450  in->data[plane] + (outh-j-1) * in->linesize[plane],
451  in->linesize[plane], 2, rot->draw.pixelstep[plane], outw);
452  } else if (fabs(rot->angle - 3*M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) {
453  simple_rotate(out->data[plane] + j * out->linesize[plane],
454  in->data[plane] + (outh-j-1) * rot->draw.pixelstep[plane],
455  in->linesize[plane], 3, rot->draw.pixelstep[plane], outw);
456  } else {
457 
458  for (i = 0; i < outw; i++) {
459  int32_t v;
460  int x1, y1;
461  uint8_t *pin, *pout;
462  x1 = x>>16;
463  y1 = y>>16;
464 
465  /* the out-of-range values avoid border artifacts */
466  if (x1 >= -1 && x1 <= inw && y1 >= -1 && y1 <= inh) {
467  uint8_t inp_inv[4]; /* interpolated input value */
468  pout = out->data[plane] + j * out->linesize[plane] + i * rot->draw.pixelstep[plane];
469  if (rot->use_bilinear) {
470  pin = rot->interpolate_bilinear(inp_inv,
471  in->data[plane], in->linesize[plane], rot->draw.pixelstep[plane],
472  x, y, inw-1, inh-1);
473  } else {
474  int x2 = av_clip(x1, 0, inw-1);
475  int y2 = av_clip(y1, 0, inh-1);
476  pin = in->data[plane] + y2 * in->linesize[plane] + x2 * rot->draw.pixelstep[plane];
477  }
478  switch (rot->draw.pixelstep[plane]) {
479  case 1:
480  *pout = *pin;
481  break;
482  case 2:
483  v = AV_RL16(pin);
484  AV_WL16(pout, v);
485  break;
486  case 3:
487  v = AV_RB24(pin);
488  AV_WB24(pout, v);
489  break;
490  case 4:
491  *((uint32_t *)pout) = *((uint32_t *)pin);
492  break;
493  default:
494  memcpy(pout, pin, rot->draw.pixelstep[plane]);
495  break;
496  }
497  }
498  x += c;
499  y -= s;
500  }
501  }
502  xprime += s;
503  yprime += c;
504  }
505 
506  return 0;
507 }
508 
510 {
511  AVFilterContext *ctx = inlink->dst;
512  AVFilterLink *outlink = ctx->outputs[0];
513  AVFrame *out;
514  RotContext *rot = ctx->priv;
515  int angle_int, s, c, plane;
516  double res;
517 
518  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
519  if (!out) {
520  av_frame_free(&in);
521  return AVERROR(ENOMEM);
522  }
523  av_frame_copy_props(out, in);
524 
525  rot->var_values[VAR_N] = inlink->frame_count_out;
526  rot->var_values[VAR_T] = TS2T(in->pts, inlink->time_base);
527  rot->angle = res = av_expr_eval(rot->angle_expr, rot->var_values, rot);
528 
529  av_log(ctx, AV_LOG_DEBUG, "n:%f time:%f angle:%f/PI\n",
530  rot->var_values[VAR_N], rot->var_values[VAR_T], rot->angle/M_PI);
531 
532  angle_int = res * FIXP * 16;
533  s = int_sin(angle_int);
534  c = int_sin(angle_int + INT_PI/2);
535 
536  /* fill background */
537  if (rot->fillcolor_enable)
538  ff_fill_rectangle(&rot->draw, &rot->color, out->data, out->linesize,
539  0, 0, outlink->w, outlink->h);
540 
541  for (plane = 0; plane < rot->nb_planes; plane++) {
542  int hsub = plane == 1 || plane == 2 ? rot->hsub : 0;
543  int vsub = plane == 1 || plane == 2 ? rot->vsub : 0;
544  const int outw = AV_CEIL_RSHIFT(outlink->w, hsub);
545  const int outh = AV_CEIL_RSHIFT(outlink->h, vsub);
546  ThreadData td = { .in = in, .out = out,
547  .inw = AV_CEIL_RSHIFT(inlink->w, hsub),
548  .inh = AV_CEIL_RSHIFT(inlink->h, vsub),
549  .outh = outh, .outw = outw,
550  .xi = -(outw-1) * c / 2, .yi = (outw-1) * s / 2,
551  .xprime = -(outh-1) * s / 2,
552  .yprime = -(outh-1) * c / 2,
553  .plane = plane, .c = c, .s = s };
554 
555 
556  ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outh, ff_filter_get_nb_threads(ctx)));
557  }
558 
559  av_frame_free(&in);
560  return ff_filter_frame(outlink, out);
561 }
562 
563 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
564  char *res, int res_len, int flags)
565 {
566  RotContext *rot = ctx->priv;
567  int ret;
568 
569  if (!strcmp(cmd, "angle") || !strcmp(cmd, "a")) {
570  AVExpr *old = rot->angle_expr;
571  ret = av_expr_parse(&rot->angle_expr, args, var_names,
572  NULL, NULL, NULL, NULL, 0, ctx);
573  if (ret < 0) {
574  av_log(ctx, AV_LOG_ERROR,
575  "Error when parsing the expression '%s' for angle command\n", args);
576  rot->angle_expr = old;
577  return ret;
578  }
579  av_expr_free(old);
580  } else
581  ret = AVERROR(ENOSYS);
582 
583  return ret;
584 }
585 
586 static const AVFilterPad rotate_inputs[] = {
587  {
588  .name = "default",
589  .type = AVMEDIA_TYPE_VIDEO,
590  .filter_frame = filter_frame,
591  },
592  { NULL }
593 };
594 
595 static const AVFilterPad rotate_outputs[] = {
596  {
597  .name = "default",
598  .type = AVMEDIA_TYPE_VIDEO,
599  .config_props = config_props,
600  },
601  { NULL }
602 };
603 
605  .name = "rotate",
606  .description = NULL_IF_CONFIG_SMALL("Rotate the input image."),
607  .priv_size = sizeof(RotContext),
608  .init = init,
609  .uninit = uninit,
612  .inputs = rotate_inputs,
613  .outputs = rotate_outputs,
614  .priv_class = &rotate_class,
616 };
int fillcolor_enable
Definition: vf_rotate.c:72
int plane
Definition: avisynth_c.h:384
static av_always_inline void simple_rotate(uint8_t *dst, const uint8_t *src, int src_linesize, int angle, int elem_size, int len)
Definition: vf_rotate.c:406
static av_cold int init(AVFilterContext *ctx)
Definition: vf_rotate.c:113
#define NULL
Definition: coverity.c:32
AVFrame * out
Definition: af_adeclick.c:488
static const char *const func1_names[]
Definition: vf_rotate.c:195
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:159
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2562
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
int hsub
Definition: vf_rotate.c:73
static const AVOption rotate_options[]
Definition: vf_rotate.c:98
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:189
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:239
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:683
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
uint8_t fillcolor[4]
color expressed either in YUVA or RGBA colorspace for the padding area
Definition: vf_rotate.c:70
#define src
Definition: vp8dsp.c:254
static av_always_inline void simple_rotate_internal(uint8_t *dst, const uint8_t *src, int src_linesize, int angle, int elem_size, int len)
Definition: vf_rotate.c:384
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:131
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
#define TS2T(ts, tb)
Definition: vf_rotate.c:417
static const AVFilterPad rotate_inputs[]
Definition: vf_rotate.c:586
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:125
const char * name
Pad name.
Definition: internal.h:60
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian ...
Definition: pixfmt.h:179
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
char * fillcolor_str
Definition: vf_rotate.c:71
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:82
static uint8_t * interpolate_bilinear16(uint8_t *dst_color, const uint8_t *src, int src_linesize, int src_linestep, int x, int y, int max_x, int max_y)
Interpolate the color in src at position x and y using bilinear interpolation.
Definition: vf_rotate.c:262
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:238
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:251
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
Definition: eval.c:157
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:191
int plane
Definition: vf_blend.c:57
#define INT_PI
Definition: vf_rotate.c:203
#define av_log(a,...)
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx)
Put the RGBA values that correspond to color_string in rgba_color.
Definition: parseutils.c:354
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_rotate.c:126
A filter pad used for either input or output.
Definition: internal.h:54
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:157
static uint8_t * interpolate_bilinear8(uint8_t *dst_color, const uint8_t *src, int src_linesize, int src_linestep, int x, int y, int max_x, int max_y)
Interpolate the color in src at position x and y using bilinear interpolation.
Definition: vf_rotate.c:232
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:165
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:764
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_rotate.c:419
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:569
#define td
Definition: regdef.h:70
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
static double(*const func1[])(void *, double)
Definition: vf_rotate.c:189
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define OFFSET(x)
Definition: vf_rotate.c:95
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
#define s0
Definition: regdef.h:37
const char * arg
Definition: jacosubdec.c:66
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:231
int outw
Definition: vf_rotate.c:69
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
Definition: pixfmt.h:183
#define FFMAX(a, b)
Definition: common.h:94
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
var_name
Definition: aeval.c:46
static int query_formats(AVFilterContext *ctx)
Definition: vf_rotate.c:134
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define NAN
Definition: mathematics.h:64
#define FFMIN(a, b)
Definition: common.h:96
#define xi(width, name, var, range_min, range_max, subs,...)
Definition: cbs_h2645.c:386
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
static int config_props(AVFilterLink *outlink)
Definition: vf_rotate.c:288
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
AVFILTER_DEFINE_CLASS(rotate)
#define a2
Definition: regdef.h:48
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
double angle
Definition: vf_rotate.c:65
#define s(width, name)
Definition: cbs_vp9.c:257
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:243
static int64_t int_sin(int64_t a)
Compute the sin of a using integer values.
Definition: vf_rotate.c:209
float cosx
Definition: vf_rotate.c:76
uint8_t *(* interpolate_bilinear)(uint8_t *dst_color, const uint8_t *src, int src_linesize, int src_linestep, int x, int y, int max_x, int max_y)
Definition: vf_rotate.c:80
AVExpr * angle_expr
parsed expression for the angle
Definition: vf_rotate.c:67
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
static const AVFilterPad rotate_outputs[]
Definition: vf_rotate.c:595
char * angle_expr_str
expression for the angle
Definition: vf_rotate.c:66
misc drawing utilities
int vsub
Definition: vf_rotate.c:73
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:87
static double get_rotated_h(void *opaque, double angle)
Definition: vf_rotate.c:177
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
Used for passing data between threads.
Definition: dsddec.c:64
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
int xprime
Definition: vf_rotate.c:91
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_rotate.c:563
char * outh_expr_str
Definition: vf_rotate.c:68
FFDrawContext draw
Definition: vf_rotate.c:78
int yprime
Definition: vf_rotate.c:91
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
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:195
#define SET_SIZE_EXPR(name, opt_name)
int nb_planes
Definition: vf_rotate.c:74
#define FIXP
Definition: vf_rotate.c:201
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:240
const char * name
Filter name.
Definition: avfilter.h:148
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:178
#define s1
Definition: regdef.h:38
float sinx
Definition: vf_rotate.c:76
static av_always_inline void copy_elem(uint8_t *pout, const uint8_t *pin, int elem_size)
Definition: vf_rotate.c:361
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
int outw
Definition: vf_rotate.c:88
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:163
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:135
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
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
static void rotate(const float rot_mat[3][3], float *vec)
Rotate vector with given rotation matrix.
Definition: vf_v360.c:2399
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
AVFilter ff_vf_rotate
Definition: vf_rotate.c:604
avfilter_execute_func * execute
Definition: internal.h:155
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:185
int len
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:754
FFDrawColor color
Definition: vf_rotate.c:79
int pixelstep[MAX_PLANES]
Definition: drawutils.h:52
A list of supported formats for one end of a filter link.
Definition: formats.h:64
static double get_rotated_w(void *opaque, double angle)
Definition: vf_rotate.c:165
int use_bilinear
Definition: vf_rotate.c:75
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:318
An instance of a filter.
Definition: avfilter.h:338
double var_values[VAR_VARS_NB]
Definition: vf_rotate.c:77
static const char *const var_names[]
Definition: vf_rotate.c:41
int outh
Definition: vf_rotate.c:69
FILE * out
Definition: movenc.c:54
void INT64 start
Definition: avisynth_c.h:766
#define av_always_inline
Definition: attributes.h:39
#define FLAGS
Definition: vf_rotate.c:96
#define M_PI
Definition: mathematics.h:52
AVFrame * in
Definition: af_afftdn.c:1083
int outh
Definition: vf_rotate.c:88
char * outw_expr_str
Definition: vf_rotate.c:68
internal API functions
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
int depth
Number of bits in the component.
Definition: pixdesc.h:58
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:237
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_rotate.c:509
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
#define FIXP2
Definition: vf_rotate.c:202
simple arithmetic expression evaluator
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58