Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2016/06/25 03:16:22... | ... |
@@ -60,7 +60,7 @@ enum var_name { |
60 | 60 |
VAR_VARS_NB |
61 | 61 |
}; |
62 | 62 |
|
63 |
-typedef struct { |
|
63 |
+typedef struct RotContext { |
|
64 | 64 |
const AVClass *class; |
65 | 65 |
double angle; |
66 | 66 |
char *angle_expr_str; ///< expression for the angle |
... | ... |
@@ -77,6 +77,9 @@ typedef struct { |
77 | 77 |
double var_values[VAR_VARS_NB]; |
78 | 78 |
FFDrawContext draw; |
79 | 79 |
FFDrawColor color; |
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); |
|
80 | 83 |
} RotContext; |
81 | 84 |
|
82 | 85 |
typedef struct ThreadData { |
... | ... |
@@ -142,6 +145,14 @@ static int query_formats(AVFilterContext *ctx) |
142 | 142 |
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, |
143 | 143 |
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, |
144 | 144 |
AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA420P, |
145 |
+ AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUVA420P10LE, |
|
146 |
+ AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUVA444P10LE, |
|
147 |
+ AV_PIX_FMT_YUV420P12LE, |
|
148 |
+ AV_PIX_FMT_YUV444P12LE, |
|
149 |
+ AV_PIX_FMT_YUV444P16LE, AV_PIX_FMT_YUVA444P16LE, |
|
150 |
+ AV_PIX_FMT_YUV420P16LE, AV_PIX_FMT_YUVA420P16LE, |
|
151 |
+ AV_PIX_FMT_YUV444P9LE, AV_PIX_FMT_YUVA444P9LE, |
|
152 |
+ AV_PIX_FMT_YUV420P9LE, AV_PIX_FMT_YUVA420P9LE, |
|
145 | 153 |
AV_PIX_FMT_NONE |
146 | 154 |
}; |
147 | 155 |
|
... | ... |
@@ -187,6 +198,93 @@ static const char * const func1_names[] = { |
187 | 187 |
NULL |
188 | 188 |
}; |
189 | 189 |
|
190 |
+#define FIXP (1<<16) |
|
191 |
+#define FIXP2 (1<<20) |
|
192 |
+#define INT_PI 3294199 //(M_PI * FIXP2) |
|
193 |
+ |
|
194 |
+/** |
|
195 |
+ * Compute the sin of a using integer values. |
|
196 |
+ * Input is scaled by FIXP2 and output values are scaled by FIXP. |
|
197 |
+ */ |
|
198 |
+static int64_t int_sin(int64_t a) |
|
199 |
+{ |
|
200 |
+ int64_t a2, res = 0; |
|
201 |
+ int i; |
|
202 |
+ if (a < 0) a = INT_PI-a; // 0..inf |
|
203 |
+ a %= 2 * INT_PI; // 0..2PI |
|
204 |
+ |
|
205 |
+ if (a >= INT_PI*3/2) a -= 2*INT_PI; // -PI/2 .. 3PI/2 |
|
206 |
+ if (a >= INT_PI/2 ) a = INT_PI - a; // -PI/2 .. PI/2 |
|
207 |
+ |
|
208 |
+ /* compute sin using Taylor series approximated to the fifth term */ |
|
209 |
+ a2 = (a*a)/(FIXP2); |
|
210 |
+ for (i = 2; i < 11; i += 2) { |
|
211 |
+ res += a; |
|
212 |
+ a = -a*a2 / (FIXP2*i*(i+1)); |
|
213 |
+ } |
|
214 |
+ return (res + 8)>>4; |
|
215 |
+} |
|
216 |
+ |
|
217 |
+/** |
|
218 |
+ * Interpolate the color in src at position x and y using bilinear |
|
219 |
+ * interpolation. |
|
220 |
+ */ |
|
221 |
+static uint8_t *interpolate_bilinear8(uint8_t *dst_color, |
|
222 |
+ const uint8_t *src, int src_linesize, int src_linestep, |
|
223 |
+ int x, int y, int max_x, int max_y) |
|
224 |
+{ |
|
225 |
+ int int_x = av_clip(x>>16, 0, max_x); |
|
226 |
+ int int_y = av_clip(y>>16, 0, max_y); |
|
227 |
+ int frac_x = x&0xFFFF; |
|
228 |
+ int frac_y = y&0xFFFF; |
|
229 |
+ int i; |
|
230 |
+ int int_x1 = FFMIN(int_x+1, max_x); |
|
231 |
+ int int_y1 = FFMIN(int_y+1, max_y); |
|
232 |
+ |
|
233 |
+ for (i = 0; i < src_linestep; i++) { |
|
234 |
+ int s00 = src[src_linestep * int_x + i + src_linesize * int_y ]; |
|
235 |
+ int s01 = src[src_linestep * int_x1 + i + src_linesize * int_y ]; |
|
236 |
+ int s10 = src[src_linestep * int_x + i + src_linesize * int_y1]; |
|
237 |
+ int s11 = src[src_linestep * int_x1 + i + src_linesize * int_y1]; |
|
238 |
+ int s0 = (((1<<16) - frac_x)*s00 + frac_x*s01); |
|
239 |
+ int s1 = (((1<<16) - frac_x)*s10 + frac_x*s11); |
|
240 |
+ |
|
241 |
+ dst_color[i] = ((int64_t)((1<<16) - frac_y)*s0 + (int64_t)frac_y*s1) >> 32; |
|
242 |
+ } |
|
243 |
+ |
|
244 |
+ return dst_color; |
|
245 |
+} |
|
246 |
+ |
|
247 |
+/** |
|
248 |
+ * Interpolate the color in src at position x and y using bilinear |
|
249 |
+ * interpolation. |
|
250 |
+ */ |
|
251 |
+static uint8_t *interpolate_bilinear16(uint8_t *dst_color, |
|
252 |
+ const uint8_t *src, int src_linesize, int src_linestep, |
|
253 |
+ int x, int y, int max_x, int max_y) |
|
254 |
+{ |
|
255 |
+ int int_x = av_clip(x>>16, 0, max_x); |
|
256 |
+ int int_y = av_clip(y>>16, 0, max_y); |
|
257 |
+ int frac_x = x&0xFFFF; |
|
258 |
+ int frac_y = y&0xFFFF; |
|
259 |
+ int i; |
|
260 |
+ int int_x1 = FFMIN(int_x+1, max_x); |
|
261 |
+ int int_y1 = FFMIN(int_y+1, max_y); |
|
262 |
+ |
|
263 |
+ for (i = 0; i < src_linestep; i+=2) { |
|
264 |
+ int s00 = AV_RL16(&src[src_linestep * int_x + i + src_linesize * int_y ]); |
|
265 |
+ int s01 = AV_RL16(&src[src_linestep * int_x1 + i + src_linesize * int_y ]); |
|
266 |
+ int s10 = AV_RL16(&src[src_linestep * int_x + i + src_linesize * int_y1]); |
|
267 |
+ int s11 = AV_RL16(&src[src_linestep * int_x1 + i + src_linesize * int_y1]); |
|
268 |
+ int s0 = (((1<<16) - frac_x)*s00 + frac_x*s01); |
|
269 |
+ int s1 = (((1<<16) - frac_x)*s10 + frac_x*s11); |
|
270 |
+ |
|
271 |
+ AV_WL16(&dst_color[i], ((int64_t)((1<<16) - frac_y)*s0 + (int64_t)frac_y*s1) >> 32); |
|
272 |
+ } |
|
273 |
+ |
|
274 |
+ return dst_color; |
|
275 |
+} |
|
276 |
+ |
|
190 | 277 |
static int config_props(AVFilterLink *outlink) |
191 | 278 |
{ |
192 | 279 |
AVFilterContext *ctx = outlink->src; |
... | ... |
@@ -203,6 +301,11 @@ static int config_props(AVFilterLink *outlink) |
203 | 203 |
rot->hsub = pixdesc->log2_chroma_w; |
204 | 204 |
rot->vsub = pixdesc->log2_chroma_h; |
205 | 205 |
|
206 |
+ if (pixdesc->comp[0].depth == 8) |
|
207 |
+ rot->interpolate_bilinear = interpolate_bilinear8; |
|
208 |
+ else |
|
209 |
+ rot->interpolate_bilinear = interpolate_bilinear16; |
|
210 |
+ |
|
206 | 211 |
rot->var_values[VAR_IN_W] = rot->var_values[VAR_IW] = inlink->w; |
207 | 212 |
rot->var_values[VAR_IN_H] = rot->var_values[VAR_IH] = inlink->h; |
208 | 213 |
rot->var_values[VAR_HSUB] = 1<<rot->hsub; |
... | ... |
@@ -255,63 +358,6 @@ static int config_props(AVFilterLink *outlink) |
255 | 255 |
return 0; |
256 | 256 |
} |
257 | 257 |
|
258 |
-#define FIXP (1<<16) |
|
259 |
-#define FIXP2 (1<<20) |
|
260 |
-#define INT_PI 3294199 //(M_PI * FIXP2) |
|
261 |
- |
|
262 |
-/** |
|
263 |
- * Compute the sin of a using integer values. |
|
264 |
- * Input is scaled by FIXP2 and output values are scaled by FIXP. |
|
265 |
- */ |
|
266 |
-static int64_t int_sin(int64_t a) |
|
267 |
-{ |
|
268 |
- int64_t a2, res = 0; |
|
269 |
- int i; |
|
270 |
- if (a < 0) a = INT_PI-a; // 0..inf |
|
271 |
- a %= 2 * INT_PI; // 0..2PI |
|
272 |
- |
|
273 |
- if (a >= INT_PI*3/2) a -= 2*INT_PI; // -PI/2 .. 3PI/2 |
|
274 |
- if (a >= INT_PI/2 ) a = INT_PI - a; // -PI/2 .. PI/2 |
|
275 |
- |
|
276 |
- /* compute sin using Taylor series approximated to the fifth term */ |
|
277 |
- a2 = (a*a)/(FIXP2); |
|
278 |
- for (i = 2; i < 11; i += 2) { |
|
279 |
- res += a; |
|
280 |
- a = -a*a2 / (FIXP2*i*(i+1)); |
|
281 |
- } |
|
282 |
- return (res + 8)>>4; |
|
283 |
-} |
|
284 |
- |
|
285 |
-/** |
|
286 |
- * Interpolate the color in src at position x and y using bilinear |
|
287 |
- * interpolation. |
|
288 |
- */ |
|
289 |
-static uint8_t *interpolate_bilinear(uint8_t *dst_color, |
|
290 |
- const uint8_t *src, int src_linesize, int src_linestep, |
|
291 |
- int x, int y, int max_x, int max_y) |
|
292 |
-{ |
|
293 |
- int int_x = av_clip(x>>16, 0, max_x); |
|
294 |
- int int_y = av_clip(y>>16, 0, max_y); |
|
295 |
- int frac_x = x&0xFFFF; |
|
296 |
- int frac_y = y&0xFFFF; |
|
297 |
- int i; |
|
298 |
- int int_x1 = FFMIN(int_x+1, max_x); |
|
299 |
- int int_y1 = FFMIN(int_y+1, max_y); |
|
300 |
- |
|
301 |
- for (i = 0; i < src_linestep; i++) { |
|
302 |
- int s00 = src[src_linestep * int_x + i + src_linesize * int_y ]; |
|
303 |
- int s01 = src[src_linestep * int_x1 + i + src_linesize * int_y ]; |
|
304 |
- int s10 = src[src_linestep * int_x + i + src_linesize * int_y1]; |
|
305 |
- int s11 = src[src_linestep * int_x1 + i + src_linesize * int_y1]; |
|
306 |
- int s0 = (((1<<16) - frac_x)*s00 + frac_x*s01); |
|
307 |
- int s1 = (((1<<16) - frac_x)*s10 + frac_x*s11); |
|
308 |
- |
|
309 |
- dst_color[i] = ((int64_t)((1<<16) - frac_y)*s0 + (int64_t)frac_y*s1) >> 32; |
|
310 |
- } |
|
311 |
- |
|
312 |
- return dst_color; |
|
313 |
-} |
|
314 |
- |
|
315 | 258 |
static av_always_inline void copy_elem(uint8_t *pout, const uint8_t *pin, int elem_size) |
316 | 259 |
{ |
317 | 260 |
int v; |
... | ... |
@@ -421,9 +467,9 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) |
421 | 421 |
uint8_t inp_inv[4]; /* interpolated input value */ |
422 | 422 |
pout = out->data[plane] + j * out->linesize[plane] + i * rot->draw.pixelstep[plane]; |
423 | 423 |
if (rot->use_bilinear) { |
424 |
- pin = interpolate_bilinear(inp_inv, |
|
425 |
- in->data[plane], in->linesize[plane], rot->draw.pixelstep[plane], |
|
426 |
- x, y, inw-1, inh-1); |
|
424 |
+ pin = rot->interpolate_bilinear(inp_inv, |
|
425 |
+ in->data[plane], in->linesize[plane], rot->draw.pixelstep[plane], |
|
426 |
+ x, y, inw-1, inh-1); |
|
427 | 427 |
} else { |
428 | 428 |
int x2 = av_clip(x1, 0, inw-1); |
429 | 429 |
int y2 = av_clip(y1, 0, inh-1); |
... | ... |
@@ -434,7 +480,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) |
434 | 434 |
*pout = *pin; |
435 | 435 |
break; |
436 | 436 |
case 2: |
437 |
- *((uint16_t *)pout) = *((uint16_t *)pin); |
|
437 |
+ v = AV_RL16(pin); |
|
438 |
+ AV_WL16(pout, v); |
|
438 | 439 |
break; |
439 | 440 |
case 3: |
440 | 441 |
v = AV_RB24(pin); |
... | ... |
@@ -13,8 +13,22 @@ rgb24 f4438057d046e6d98ade4e45294b21be |
13 | 13 |
rgba b6e1b441c365e03b5ffdf9b7b68d9a0c |
14 | 14 |
yuv410p 5d4d992a7728431aa4e0700f87fb7fd8 |
15 | 15 |
yuv420p a014c7eb7a8385d1dd092b7a583f1bff |
16 |
+yuv420p10le 15c83294ef560d57f25d16ae6e0fc70c |
|
17 |
+yuv420p12le c19a477a07fcf88e37ab37b416d064c0 |
|
18 |
+yuv420p16le dae8da9edd4255051e3e546ae7ed9bd3 |
|
19 |
+yuv420p9le 83a6d32c91c15a3bc334bb9abf920654 |
|
16 | 20 |
yuv444p 8f90fb3a757878c545a8bfe5d19a9bab |
21 |
+yuv444p10le 6d736fa464ff2de2b07e0a56af8444b7 |
|
22 |
+yuv444p12le 08a81b2ea9c7c8b447e40ef8f4a46a4a |
|
23 |
+yuv444p16le 781c22317c02b3dd4225709000bdb847 |
|
24 |
+yuv444p9le caef947b8aff5b52285385c6ae9b2439 |
|
17 | 25 |
yuva420p b227672e56215e184e702c02a771d7f3 |
26 |
+yuva420p10le 01e94ee605714396e69b013c11dda348 |
|
27 |
+yuva420p16le b1930ab28ffe031c78ca28d3406311c8 |
|
28 |
+yuva420p9le 0e9c9803aaaddc9f38e419de587793c2 |
|
18 | 29 |
yuva444p 459fad5abfd16db9bb6a52761dc74cc1 |
30 |
+yuva444p10le 92f820d3481b7ebcb48b98a73e7b4c90 |
|
31 |
+yuva444p16le 2ed56ea50fafda4d226c9b133755dad8 |
|
32 |
+yuva444p9le 4eeb5988df0740fea720da1e31bbb829 |
|
19 | 33 |
yuvj420p 8f3d8f1b4577d11082d5ab8a901e048d |
20 | 34 |
yuvj444p b161e6d5a941e2a4bb7bc56ef8af623f |