FFmpeg
transform.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Georg Martius <georg.martius@web.de>
3  * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.org>
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  * transform input video
25  */
26 
27 #include "libavutil/common.h"
28 #include "libavutil/avassert.h"
29 
30 #include "transform.h"
31 
32 #define INTERPOLATE_METHOD(name) \
33  static uint8_t name(float x, float y, const uint8_t *src, \
34  int width, int height, int stride, uint8_t def)
35 
36 #define PIXEL(img, x, y, w, h, stride, def) \
37  ((x) < 0 || (y) < 0) ? (def) : \
38  (((x) >= (w) || (y) >= (h)) ? (def) : \
39  img[(x) + (y) * (stride)])
40 
41 /**
42  * Nearest neighbor interpolation
43  */
44 INTERPOLATE_METHOD(interpolate_nearest)
45 {
46  return PIXEL(src, (int)(x + 0.5), (int)(y + 0.5), width, height, stride, def);
47 }
48 
49 /**
50  * Bilinear interpolation
51  */
52 INTERPOLATE_METHOD(interpolate_bilinear)
53 {
54  int x_c, x_f, y_c, y_f;
55  int v1, v2, v3, v4;
56 
57  if (x < -1 || x > width || y < -1 || y > height) {
58  return def;
59  } else {
60  x_f = (int)x;
61  x_c = x_f + 1;
62 
63  y_f = (int)y;
64  y_c = y_f + 1;
65 
66  v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
67  v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
68  v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
69  v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
70 
71  return (v1*(x - x_f)*(y - y_f) + v2*((x - x_f)*(y_c - y)) +
72  v3*(x_c - x)*(y - y_f) + v4*((x_c - x)*(y_c - y)));
73  }
74 }
75 
76 /**
77  * Biquadratic interpolation
78  */
79 INTERPOLATE_METHOD(interpolate_biquadratic)
80 {
81  int x_c, x_f, y_c, y_f;
82  uint8_t v1, v2, v3, v4;
83  float f1, f2, f3, f4;
84 
85  if (x < - 1 || x > width || y < -1 || y > height)
86  return def;
87  else {
88  x_f = (int)x;
89  x_c = x_f + 1;
90  y_f = (int)y;
91  y_c = y_f + 1;
92 
93  v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
94  v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
95  v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
96  v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
97 
98  f1 = 1 - sqrt((x_c - x) * (y_c - y));
99  f2 = 1 - sqrt((x_c - x) * (y - y_f));
100  f3 = 1 - sqrt((x - x_f) * (y_c - y));
101  f4 = 1 - sqrt((x - x_f) * (y - y_f));
102  return (v1 * f1 + v2 * f2 + v3 * f3 + v4 * f4) / (f1 + f2 + f3 + f4);
103  }
104 }
105 
107  float x_shift,
108  float y_shift,
109  float angle,
110  float scale_x,
111  float scale_y,
112  float *matrix
113 ) {
114  matrix[0] = scale_x * cos(angle);
115  matrix[1] = -sin(angle);
116  matrix[2] = x_shift;
117  matrix[3] = -matrix[1];
118  matrix[4] = scale_y * cos(angle);
119  matrix[5] = y_shift;
120  matrix[6] = 0;
121  matrix[7] = 0;
122  matrix[8] = 1;
123 }
124 
125 int ff_affine_transform(const uint8_t *src, uint8_t *dst,
126  int src_stride, int dst_stride,
127  int width, int height, const float *matrix,
129  enum FillMethod fill)
130 {
131  int x, y;
132  float x_s, y_s;
133  uint8_t def = 0;
134  uint8_t (*func)(float, float, const uint8_t *, int, int, int, uint8_t) = NULL;
135 
136  switch(interpolate) {
137  case INTERPOLATE_NEAREST:
138  func = interpolate_nearest;
139  break;
141  func = interpolate_bilinear;
142  break;
144  func = interpolate_biquadratic;
145  break;
146  default:
147  return AVERROR(EINVAL);
148  }
149 
150  for (y = 0; y < height; y++) {
151  for(x = 0; x < width; x++) {
152  x_s = x * matrix[0] + y * matrix[1] + matrix[2];
153  y_s = x * matrix[3] + y * matrix[4] + matrix[5];
154 
155  switch(fill) {
156  case FILL_ORIGINAL:
157  def = src[y * src_stride + x];
158  break;
159  case FILL_CLAMP:
160  y_s = av_clipf(y_s, 0, height - 1);
161  x_s = av_clipf(x_s, 0, width - 1);
162  def = src[(int)y_s * src_stride + (int)x_s];
163  break;
164  case FILL_MIRROR:
165  x_s = avpriv_mirror(x_s, width-1);
166  y_s = avpriv_mirror(y_s, height-1);
167 
168  av_assert2(x_s >= 0 && y_s >= 0);
169  av_assert2(x_s < width && y_s < height);
170  def = src[(int)y_s * src_stride + (int)x_s];
171  }
172 
173  dst[y * dst_stride + x] = func(x_s, y_s, src, width, height, src_stride, def);
174  }
175  }
176  return 0;
177 }
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:68
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
matrix
Definition: vc1dsp.c:42
FILL_CLAMP
@ FILL_CLAMP
Definition: transform.h:54
InterpolateMethod
InterpolateMethod
Definition: transform.h:39
FILL_ORIGINAL
@ FILL_ORIGINAL
Definition: transform.h:53
INTERPOLATE_NEAREST
@ INTERPOLATE_NEAREST
Definition: lut3d.h:31
avassert.h
float
float
Definition: af_crystalizer.c:121
width
#define width
INTERPOLATE_METHOD
#define INTERPOLATE_METHOD(name)
Definition: transform.c:32
NULL
#define NULL
Definition: coverity.c:32
av_clipf
av_clipf
Definition: af_crystalizer.c:121
avpriv_mirror
static av_always_inline av_const int avpriv_mirror(int x, int w)
Definition: internal.h:168
PIXEL
#define PIXEL(img, x, y, w, h, stride, def)
Definition: transform.c:36
FILL_MIRROR
@ FILL_MIRROR
Definition: transform.h:55
height
#define height
INTERPOLATE_BILINEAR
@ INTERPOLATE_BILINEAR
Definition: transform.h:41
interpolate
static void interpolate(float *out, float v1, float v2, int size)
Definition: twinvq.c:84
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
ff_get_matrix
void ff_get_matrix(float x_shift, float y_shift, float angle, float scale_x, float scale_y, float *matrix)
Get an affine transformation matrix from given translation, rotation, and zoom factors.
Definition: transform.c:106
common.h
stride
#define stride
Definition: h264pred_template.c:537
transform.h
ff_affine_transform
int ff_affine_transform(const uint8_t *src, uint8_t *dst, int src_stride, int dst_stride, int width, int height, const float *matrix, enum InterpolateMethod interpolate, enum FillMethod fill)
Do an affine transformation with the given interpolation method.
Definition: transform.c:125
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
FillMethod
FillMethod
Definition: transform.h:51
int
int
Definition: ffmpeg_filter.c:409
INTERPOLATE_BIQUADRATIC
@ INTERPOLATE_BIQUADRATIC
Definition: transform.h:42