FFmpeg
Loading...
Searching...
No Matches
utils.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024 Niklas Haas
3 * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
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#include "config.h"
23
24#define _DEFAULT_SOURCE
25#include <inttypes.h>
26#include <math.h>
27#include <stdio.h>
28#include <string.h>
29
31#include "libavutil/avassert.h"
32#include "libavutil/cpu.h"
33#include "libavutil/csp.h"
34#include "libavutil/emms.h"
35#include "libavutil/imgutils.h"
38#include "libavutil/mem.h"
39#include "libavutil/opt.h"
40#include "libavutil/pixdesc.h"
41#include "libavutil/refstruct.h"
43#include "libavutil/thread.h"
45#include "libavutil/ppc/cpu.h"
46#include "libavutil/x86/cpu.h"
48
49#include "rgb2rgb.h"
50#include "swscale.h"
51#include "swscale_internal.h"
52#include "graph.h"
53#include "jit.h"
54
55#if CONFIG_VULKAN
56#include "vulkan/ops.h"
57#endif
58
60{
61 if (ctx->backends)
62 return ctx->backends;
63
65 if (ctx->flags & SWS_UNSTABLE)
66 fallback |= SWS_BACKEND_UNSTABLE;
67
68 return fallback;
69}
70
71/**
72 * Allocate and return an SwsContext without performing initialization.
73 */
74static SwsContext *alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcFormat,
75 int dstW, int dstH, enum AVPixelFormat dstFormat,
76 int flags, const double *param)
77{
79 if (!sws)
80 return NULL;
81
82 sws->flags = flags;
83 sws->src_w = srcW;
84 sws->src_h = srcH;
85 sws->dst_w = dstW;
86 sws->dst_h = dstH;
87 sws->src_format = srcFormat;
88 sws->dst_format = dstFormat;
89
90 for (int i = 0; param && i < SWS_NUM_SCALER_PARAMS; i++)
91 sws->scaler_params[i] = param[i];
92
93 return sws;
94}
95
96static void set_cascade_chr_pos(SwsContext *cascade, const SwsContext *sws,
97 int src, int dst)
98{
99 if (src) {
100 cascade->src_h_chr_pos = sws->src_h_chr_pos;
101 cascade->src_v_chr_pos = sws->src_v_chr_pos;
102 }
103 if (dst) {
104 cascade->dst_h_chr_pos = sws->dst_h_chr_pos;
105 cascade->dst_v_chr_pos = sws->dst_v_chr_pos;
106 }
107}
108
110 int filterSize, int16_t *filter,
111 int dstW)
112{
113#if ARCH_X86_64
114 int i, j, k;
116 if (!filter)
117 return 0;
119 if ((c->srcBpc == 8) && (c->dstBpc <= 14)) {
120 int16_t *filterCopy = NULL;
121 if (filterSize > 4) {
122 filterCopy = av_malloc_array(dstW, filterSize * sizeof(*filterCopy));
123 if (!filterCopy)
124 return AVERROR(ENOMEM);
125 memcpy(filterCopy, filter, dstW * filterSize * sizeof(int16_t));
126 }
127 // Do not swap filterPos for pixels which won't be processed by
128 // the main loop.
129 for (i = 0; i + 16 <= dstW; i += 16) {
130 FFSWAP(int, filterPos[i + 2], filterPos[i + 4]);
131 FFSWAP(int, filterPos[i + 3], filterPos[i + 5]);
132 FFSWAP(int, filterPos[i + 10], filterPos[i + 12]);
133 FFSWAP(int, filterPos[i + 11], filterPos[i + 13]);
134 }
135 if (filterSize > 4) {
136 // 16 pixels are processed at a time.
137 for (i = 0; i + 16 <= dstW; i += 16) {
138 // 4 filter coeffs are processed at a time.
139 for (k = 0; k + 4 <= filterSize; k += 4) {
140 for (j = 0; j < 16; ++j) {
141 int from = (i + j) * filterSize + k;
142 int to = i * filterSize + j * 4 + k * 16;
143 memcpy(&filter[to], &filterCopy[from], 4 * sizeof(int16_t));
144 }
145 }
146 }
147 // 4 pixels are processed at a time in the tail.
148 for (; i < dstW; i += 4) {
149 // 4 filter coeffs are processed at a time.
150 int rem = dstW - i >= 4 ? 4 : dstW - i;
151 for (k = 0; k + 4 <= filterSize; k += 4) {
152 for (j = 0; j < rem; ++j) {
153 int from = (i + j) * filterSize + k;
154 int to = i * filterSize + j * 4 + k * 4;
155 memcpy(&filter[to], &filterCopy[from], 4 * sizeof(int16_t));
156 }
157 }
158 }
159 }
160 av_free(filterCopy);
161 }
162 }
163#endif
164 return 0;
165}
166
167static double getSplineCoeff(double a, double b, double c, double d,
168 double dist)
169{
170 if (dist <= 1.0)
171 return ((d * dist + c) * dist + b) * dist + a;
172 else
173 return getSplineCoeff(0.0,
174 b + 2.0 * c + 3.0 * d,
175 c + 3.0 * d,
176 -b - 3.0 * c - 6.0 * d,
177 dist - 1.0);
178}
179
180static av_cold int get_local_pos(SwsInternal *s, int chr_subsample, int pos, int dir)
181{
182 if (pos == -1 || pos <= -513) {
183 pos = (128 << chr_subsample) - 128;
184 }
185 pos += 128; // relative to ideal left edge
186 return pos >> chr_subsample;
187}
188
189static av_cold int get_center_offset(SwsInternal *s, int chr_subsample, int pos, int dir)
190{
191 return (get_local_pos(s, chr_subsample, pos, dir) - 128) * (1 << chr_subsample);
192}
193
194typedef struct {
195 int flag; ///< flag associated to the algorithm
196 const char *description; ///< human-readable description
197 int size_factor; ///< size factor used when initing the filters
199
201 { SWS_AREA, "area averaging", 1 /* downscale only, for upscale it is bilinear */ },
202 { SWS_BICUBIC, "bicubic", 4 },
203 { SWS_BICUBLIN, "luma bicubic / chroma bilinear", -1 },
204 { SWS_BILINEAR, "bilinear", 2 },
205 { SWS_FAST_BILINEAR, "fast bilinear", -1 },
206 { SWS_GAUSS, "Gaussian", 8 /* infinite ;) */ },
207 { SWS_LANCZOS, "Lanczos", -1 /* custom */ },
208 { SWS_POINT, "nearest neighbor / point", -1 },
209 { SWS_SINC, "sinc", 20 /* infinite ;) */ },
210 { SWS_SPLINE, "bicubic spline", 20 /* infinite :)*/ },
211 { SWS_X, "experimental", 8 },
212};
213
214static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
215 int *outFilterSize, int xInc, int srcW,
216 int dstW, int filterAlign, int one,
217 int scaler, int flags, int cpu_flags,
218 SwsVector *srcFilter, SwsVector *dstFilter,
219 double param[SWS_NUM_SCALER_PARAMS], int srcPos, int dstPos)
220{
221 int i;
222 int filterSize;
223 int filter2Size;
224 int minFilterSize;
226 int64_t *filter2 = NULL;
227 const int64_t fone = 1LL << (54 - FFMIN(av_log2(srcW/dstW), 8));
228 int ret = -1;
229
230 emms_c(); // FIXME should not be required but IS (even for non-MMX versions)
231
232 // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end
233 if (!FF_ALLOC_TYPED_ARRAY(*filterPos, dstW + 3))
234 goto nomem;
235
236 if (FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) { // unscaled
237 int i;
238 filterSize = 1;
239 if (!FF_ALLOCZ_TYPED_ARRAY(filter, dstW * filterSize))
240 goto nomem;
241
242 for (i = 0; i < dstW; i++) {
243 filter[i * filterSize] = fone;
244 (*filterPos)[i] = i;
245 }
246 } else if (scaler == SWS_POINT) { // lame looking point sampling mode
247 int i;
248 int64_t xDstInSrc;
249 filterSize = 1;
250 if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
251 goto nomem;
252
253 xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
254 for (i = 0; i < dstW; i++) {
255 int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
256
257 (*filterPos)[i] = xx;
258 filter[i] = fone;
259 xDstInSrc += xInc;
260 }
261 } else if ((xInc <= (1 << 16) && (scaler == SWS_AREA)) ||
262 (scaler == SWS_FAST_BILINEAR)) { // bilinear upscale
263 int i;
264 int64_t xDstInSrc;
265 filterSize = 2;
266 if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
267 goto nomem;
268
269 xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
270 for (i = 0; i < dstW; i++) {
271 int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
272 int j;
273
274 (*filterPos)[i] = xx;
275 // bilinear upscale / linear interpolate / area averaging
276 for (j = 0; j < filterSize; j++) {
277 int64_t coeff = fone - FFABS((int64_t)xx * (1 << 16) - xDstInSrc) * (fone >> 16);
278 if (coeff < 0)
279 coeff = 0;
280 filter[i * filterSize + j] = coeff;
281 xx++;
282 }
283 xDstInSrc += xInc;
284 }
285 } else {
286 int64_t xDstInSrc;
287 int sizeFactor = -1;
288
289 for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
290 if (scaler == scale_algorithms[i].flag && scale_algorithms[i].size_factor > 0) {
291 sizeFactor = scale_algorithms[i].size_factor;
292 break;
293 }
294 }
295 if (scaler == SWS_LANCZOS)
296 sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;
297 av_assert0(sizeFactor > 0);
298
299 if (sizeFactor > 50) {
300 ret = AVERROR(EINVAL);
301 goto fail;
302 }
303
304 if (xInc <= 1 << 16)
305 filterSize = 1 + sizeFactor; // upscale
306 else
307 filterSize = 1 + (sizeFactor * srcW + dstW - 1) / dstW;
308
309 filterSize = FFMIN(filterSize, srcW - 2);
310 filterSize = FFMAX(filterSize, 1);
311
312 filter = av_malloc_array(dstW, filterSize * sizeof(*filter));
313 if (!filter)
314 goto nomem;
315 xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7);
316 for (i = 0; i < dstW; i++) {
317 int xx = (xDstInSrc - (filterSize - 2) * (1LL<<16)) / (1 << 17);
318 int j;
319 (*filterPos)[i] = xx;
320 for (j = 0; j < filterSize; j++) {
321 int64_t d = (FFABS(((int64_t)xx * (1 << 17)) - xDstInSrc)) << 13;
322 double floatd;
324
325 if (xInc > 1 << 16)
326 d = d * dstW / srcW;
327 floatd = d * (1.0 / (1 << 30));
328
329 if (scaler == SWS_BICUBIC) {
330 int64_t B = (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1 << 24);
331 int64_t C = (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1 << 24);
332
333 if (d >= 1LL << 31) {
334 coeff = 0.0;
335 } else {
336 int64_t dd = (d * d) >> 30;
337 int64_t ddd = (dd * d) >> 30;
338
339 if (d < 1LL << 30)
340 coeff = (12 * (1 << 24) - 9 * B - 6 * C) * ddd +
341 (-18 * (1 << 24) + 12 * B + 6 * C) * dd +
342 (6 * (1 << 24) - 2 * B) * (1 << 30);
343 else
344 coeff = (-B - 6 * C) * ddd +
345 (6 * B + 30 * C) * dd +
346 (-12 * B - 48 * C) * d +
347 (8 * B + 24 * C) * (1 << 30);
348 }
349 coeff /= (1LL<<54)/fone;
350 } else if (scaler == SWS_X) {
351 double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;
352 double c;
353
354 if (floatd < 1.0)
355 c = cos(floatd * M_PI);
356 else
357 c = -1.0;
358 if (c < 0.0)
359 c = -pow(-c, A);
360 else
361 c = pow(c, A);
362 coeff = (c * 0.5 + 0.5) * fone;
363 } else if (scaler == SWS_AREA) {
364 int64_t d2 = d - (1 << 29);
365 if (d2 * xInc < -(1LL << (29 + 16)))
366 coeff = 1.0 * (1LL << (30 + 16));
367 else if (d2 * xInc < (1LL << (29 + 16)))
368 coeff = -d2 * xInc + (1LL << (29 + 16));
369 else
370 coeff = 0.0;
371 coeff *= fone >> (30 + 16);
372 } else if (scaler == SWS_GAUSS) {
373 double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
374 coeff = exp2(-p * floatd * floatd) * fone;
375 } else if (scaler == SWS_SINC) {
376 coeff = (d ? sin(floatd * M_PI) / (floatd * M_PI) : 1.0) * fone;
377 } else if (scaler == SWS_LANCZOS) {
378 double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
379 coeff = (d ? sin(floatd * M_PI) * sin(floatd * M_PI / p) /
380 (floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;
381 if (floatd > p)
382 coeff = 0;
383 } else if (scaler == SWS_BILINEAR) {
384 coeff = (1 << 30) - d;
385 if (coeff < 0)
386 coeff = 0;
387 coeff *= fone >> 30;
388 } else if (scaler == SWS_SPLINE) {
389 double p = -2.196152422706632;
390 coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;
391 } else {
392 av_assert0(0);
393 }
394
395 filter[i * filterSize + j] = coeff;
396 xx++;
397 }
398 xDstInSrc += 2LL * xInc;
399 }
400 }
401
402 /* apply src & dst Filter to filter -> filter2
403 * av_free(filter);
404 */
405 av_assert0(filterSize > 0);
406 filter2Size = filterSize;
407 if (srcFilter)
408 filter2Size += srcFilter->length - 1;
409 if (dstFilter)
410 filter2Size += dstFilter->length - 1;
411 av_assert0(filter2Size > 0);
412 filter2 = av_calloc(dstW, filter2Size * sizeof(*filter2));
413 if (!filter2)
414 goto nomem;
415 for (i = 0; i < dstW; i++) {
416 int j, k;
417
418 if (srcFilter) {
419 for (k = 0; k < srcFilter->length; k++) {
420 for (j = 0; j < filterSize; j++)
421 filter2[i * filter2Size + k + j] +=
422 srcFilter->coeff[k] * filter[i * filterSize + j];
423 }
424 } else {
425 for (j = 0; j < filterSize; j++)
426 filter2[i * filter2Size + j] = filter[i * filterSize + j];
427 }
428 // FIXME dstFilter
429
430 (*filterPos)[i] += (filterSize - 1) / 2 - (filter2Size - 1) / 2;
431 }
433
434 /* try to reduce the filter-size (step1 find size and shift left) */
435 // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not).
436 minFilterSize = 0;
437 for (i = dstW - 1; i >= 0; i--) {
438 int min = filter2Size;
439 int j;
440 int64_t cutOff = 0.0;
441
442 /* get rid of near zero elements on the left by shifting left */
443 for (j = 0; j < filter2Size; j++) {
444 int k;
445 cutOff += FFABS(filter2[i * filter2Size]);
446
447 if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
448 break;
449
450 /* preserve monotonicity because the core can't handle the
451 * filter otherwise */
452 if (i < dstW - 1 && (*filterPos)[i] >= (*filterPos)[i + 1])
453 break;
454
455 // move filter coefficients left
456 for (k = 1; k < filter2Size; k++)
457 filter2[i * filter2Size + k - 1] = filter2[i * filter2Size + k];
458 filter2[i * filter2Size + k - 1] = 0;
459 (*filterPos)[i]++;
460 }
461
462 cutOff = 0;
463 /* count near zeros on the right */
464 for (j = filter2Size - 1; j > 0; j--) {
465 cutOff += FFABS(filter2[i * filter2Size + j]);
466
467 if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
468 break;
469 min--;
470 }
471
472 if (min > minFilterSize)
473 minFilterSize = min;
474 }
475
476 if (PPC_ALTIVEC(cpu_flags)) {
477 // we can handle the special case 4, so we don't want to go the full 8
478 if (minFilterSize < 5)
479 filterAlign = 4;
480
481 /* We really don't want to waste our time doing useless computation, so
482 * fall back on the scalar C code for very small filters.
483 * Vectorizing is worth it only if you have a decent-sized vector. */
484 if (minFilterSize < 3)
485 filterAlign = 1;
486 }
487
488 if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX || have_neon(cpu_flags)) {
489 // special case for unscaled vertical filtering
490 if (minFilterSize == 1 && filterAlign == 2)
491 filterAlign = 1;
492 }
493
495 int reNum = minFilterSize & (0x07);
496
497 if (minFilterSize < 5)
498 filterAlign = 4;
499 if (reNum < 3)
500 filterAlign = 1;
501 }
502
503 av_assert0(minFilterSize > 0);
504 filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));
505 av_assert0(filterSize > 0);
506 filter = av_malloc_array(dstW, filterSize * sizeof(*filter));
507 if (!filter)
508 goto nomem;
509 if (filterSize >= MAX_FILTER_SIZE * 16 /
510 ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16)) {
512 goto fail;
513 }
514 *outFilterSize = filterSize;
515
516 if (flags & SWS_PRINT_INFO)
518 "SwScaler: reducing / aligning filtersize %d -> %d\n",
519 filter2Size, filterSize);
520 /* try to reduce the filter-size (step2 reduce it) */
521 for (i = 0; i < dstW; i++) {
522 int j;
523
524 for (j = 0; j < filterSize; j++) {
525 if (j >= filter2Size)
526 filter[i * filterSize + j] = 0;
527 else
528 filter[i * filterSize + j] = filter2[i * filter2Size + j];
529 if ((flags & SWS_BITEXACT) && j >= minFilterSize)
530 filter[i * filterSize + j] = 0;
531 }
532 }
533
534 // FIXME try to align filterPos if possible
535
536 // fix borders
537 for (i = 0; i < dstW; i++) {
538 int j;
539 if ((*filterPos)[i] < 0) {
540 // move filter coefficients left to compensate for filterPos
541 for (j = 1; j < filterSize; j++) {
542 int left = FFMAX(j + (*filterPos)[i], 0);
543 filter[i * filterSize + left] += filter[i * filterSize + j];
544 filter[i * filterSize + j] = 0;
545 }
546 (*filterPos)[i]= 0;
547 }
548
549 if ((*filterPos)[i] + filterSize > srcW) {
550 int shift = (*filterPos)[i] + FFMIN(filterSize - srcW, 0);
551 int64_t acc = 0;
552
553 for (j = filterSize - 1; j >= 0; j--) {
554 if ((*filterPos)[i] + j >= srcW) {
555 acc += filter[i * filterSize + j];
556 filter[i * filterSize + j] = 0;
557 }
558 }
559 for (j = filterSize - 1; j >= 0; j--) {
560 if (j < shift) {
561 filter[i * filterSize + j] = 0;
562 } else {
563 filter[i * filterSize + j] = filter[i * filterSize + j - shift];
564 }
565 }
566
567 (*filterPos)[i]-= shift;
568 filter[i * filterSize + srcW - 1 - (*filterPos)[i]] += acc;
569 }
570 av_assert0((*filterPos)[i] >= 0);
571 av_assert0((*filterPos)[i] < srcW);
572 if ((*filterPos)[i] + filterSize > srcW) {
573 for (j = 0; j < filterSize; j++) {
574 av_assert0((*filterPos)[i] + j < srcW || !filter[i * filterSize + j]);
575 }
576 }
577 }
578
579 // Note the +1 is for the MMX scaler which reads over the end
580 /* align at 16 for AltiVec (needed by hScale_altivec_real) */
581 *outFilter = av_calloc(dstW + 3, *outFilterSize * sizeof(**outFilter));
582 if (!*outFilter)
583 goto nomem;
584
585 /* normalize & store in outFilter */
586 for (i = 0; i < dstW; i++) {
587 int j;
588 int64_t error = 0;
589 int64_t sum = 0;
590
591 for (j = 0; j < filterSize; j++) {
592 sum += filter[i * filterSize + j];
593 }
594 sum = (sum + one / 2) / one;
595 if (!sum) {
596 av_log(NULL, AV_LOG_WARNING, "SwScaler: zero vector in scaling\n");
597 sum = 1;
598 }
599 for (j = 0; j < *outFilterSize; j++) {
600 int64_t v = filter[i * filterSize + j] + error;
601 int intV = ROUNDED_DIV(v, sum);
602 (*outFilter)[i * (*outFilterSize) + j] = intV;
603 error = v - intV * sum;
604 }
605 }
606
607 (*filterPos)[dstW + 0] =
608 (*filterPos)[dstW + 1] =
609 (*filterPos)[dstW + 2] = (*filterPos)[dstW - 1]; /* the MMX/SSE scaler will
610 * read over the end */
611 for (i = 0; i < *outFilterSize; i++) {
612 int k = (dstW - 1) * (*outFilterSize) + i;
613 (*outFilter)[k + 1 * (*outFilterSize)] =
614 (*outFilter)[k + 2 * (*outFilterSize)] =
615 (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];
616 }
617
618 ret = 0;
619 goto done;
620nomem:
621 ret = AVERROR(ENOMEM);
622fail:
623 if(ret < 0)
624 av_log(NULL, ret == RETCODE_USE_CASCADE ? AV_LOG_DEBUG : AV_LOG_ERROR, "sws: initFilter failed\n");
625done:
627 av_free(filter2);
628 return ret;
629}
630
631static void fill_rgb2yuv_table(SwsInternal *c, const int table[4], int dstRange)
632{
633 int64_t W, V, Z, Cy, Cu, Cv;
634 int64_t vr = table[0];
635 int64_t ub = table[1];
636 int64_t ug = -table[2];
637 int64_t vg = -table[3];
638 int64_t ONE = 65536;
639 int64_t cy = ONE;
640 uint8_t *p = (uint8_t*)c->input_rgb2yuv_table;
641 int i;
642 static const int8_t map[] = {
643 BY_IDX, GY_IDX, -1 , BY_IDX, BY_IDX, GY_IDX, -1 , BY_IDX,
644 RY_IDX, -1 , GY_IDX, RY_IDX, RY_IDX, -1 , GY_IDX, RY_IDX,
645 RY_IDX, GY_IDX, -1 , RY_IDX, RY_IDX, GY_IDX, -1 , RY_IDX,
646 BY_IDX, -1 , GY_IDX, BY_IDX, BY_IDX, -1 , GY_IDX, BY_IDX,
647 BU_IDX, GU_IDX, -1 , BU_IDX, BU_IDX, GU_IDX, -1 , BU_IDX,
648 RU_IDX, -1 , GU_IDX, RU_IDX, RU_IDX, -1 , GU_IDX, RU_IDX,
649 RU_IDX, GU_IDX, -1 , RU_IDX, RU_IDX, GU_IDX, -1 , RU_IDX,
650 BU_IDX, -1 , GU_IDX, BU_IDX, BU_IDX, -1 , GU_IDX, BU_IDX,
651 BV_IDX, GV_IDX, -1 , BV_IDX, BV_IDX, GV_IDX, -1 , BV_IDX,
652 RV_IDX, -1 , GV_IDX, RV_IDX, RV_IDX, -1 , GV_IDX, RV_IDX,
653 RV_IDX, GV_IDX, -1 , RV_IDX, RV_IDX, GV_IDX, -1 , RV_IDX,
654 BV_IDX, -1 , GV_IDX, BV_IDX, BV_IDX, -1 , GV_IDX, BV_IDX,
657 GY_IDX, -1 , GY_IDX, -1 , GY_IDX, -1 , GY_IDX, -1 ,
658 -1 , GY_IDX, -1 , GY_IDX, -1 , GY_IDX, -1 , GY_IDX,
661 GU_IDX, -1 , GU_IDX, -1 , GU_IDX, -1 , GU_IDX, -1 ,
662 -1 , GU_IDX, -1 , GU_IDX, -1 , GU_IDX, -1 , GU_IDX,
665 GV_IDX, -1 , GV_IDX, -1 , GV_IDX, -1 , GV_IDX, -1 ,
666 -1 , GV_IDX, -1 , GV_IDX, -1 , GV_IDX, -1 , GV_IDX, //23
667 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //24
668 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //25
669 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //26
670 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //27
671 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //28
672 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //29
673 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //30
674 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //31
675 BY_IDX, GY_IDX, RY_IDX, -1 , -1 , -1 , -1 , -1 , //32
676 BU_IDX, GU_IDX, RU_IDX, -1 , -1 , -1 , -1 , -1 , //33
677 BV_IDX, GV_IDX, RV_IDX, -1 , -1 , -1 , -1 , -1 , //34
678 };
679
680 dstRange = 0; //FIXME range = 1 is handled elsewhere
681
682 if (!dstRange) {
683 cy = cy * 255 / 219;
684 } else {
685 vr = vr * 224 / 255;
686 ub = ub * 224 / 255;
687 ug = ug * 224 / 255;
688 vg = vg * 224 / 255;
689 }
690 W = ROUNDED_DIV(ONE*ONE*ug, ub);
691 V = ROUNDED_DIV(ONE*ONE*vg, vr);
692 Z = ONE*ONE-W-V;
693
694 Cy = ROUNDED_DIV(cy*Z, ONE);
695 Cu = ROUNDED_DIV(ub*Z, ONE);
696 Cv = ROUNDED_DIV(vr*Z, ONE);
697
698 c->input_rgb2yuv_table[RY_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*V , Cy);
699 c->input_rgb2yuv_table[GY_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*ONE*ONE , Cy);
700 c->input_rgb2yuv_table[BY_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*W , Cy);
701
702 c->input_rgb2yuv_table[RU_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*V , Cu);
703 c->input_rgb2yuv_table[GU_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*ONE*ONE , Cu);
704 c->input_rgb2yuv_table[BU_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*(Z+W) , Cu);
705
706 c->input_rgb2yuv_table[RV_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*(V+Z) , Cv);
707 c->input_rgb2yuv_table[GV_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*ONE*ONE , Cv);
708 c->input_rgb2yuv_table[BV_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*W , Cv);
709
710 if(/*!dstRange && */!memcmp(table, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], sizeof(ff_yuv2rgb_coeffs[SWS_CS_DEFAULT]))) {
711 c->input_rgb2yuv_table[BY_IDX] = ((int)(0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
712 c->input_rgb2yuv_table[BV_IDX] = (-(int)(0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
713 c->input_rgb2yuv_table[BU_IDX] = ((int)(0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
714 c->input_rgb2yuv_table[GY_IDX] = ((int)(0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
715 c->input_rgb2yuv_table[GV_IDX] = (-(int)(0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
716 c->input_rgb2yuv_table[GU_IDX] = (-(int)(0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
717 c->input_rgb2yuv_table[RY_IDX] = ((int)(0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
718 c->input_rgb2yuv_table[RV_IDX] = ((int)(0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
719 c->input_rgb2yuv_table[RU_IDX] = (-(int)(0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
720 }
721 for(i=0; i<FF_ARRAY_ELEMS(map); i++)
722 AV_WL16(p + 16*4 + 2*i, map[i] >= 0 ? c->input_rgb2yuv_table[map[i]] : 0);
723}
724
725#if CONFIG_SMALL
726static void init_xyz_tables(uint16_t xyzgamma_tab[4096], uint16_t xyzgammainv_tab[65536],
727 uint16_t rgbgamma_tab[65536], uint16_t rgbgammainv_tab[4096])
728#else
729static uint16_t xyzgamma_tab[4096], rgbgammainv_tab[4096];
730static uint16_t rgbgamma_tab[65536], xyzgammainv_tab[65536];
731static av_cold void init_xyz_tables(void)
732#endif
733{
734 double xyzgamma = XYZ_GAMMA;
735 double rgbgamma = 1.0 / RGB_GAMMA;
736 double xyzgammainv = 1.0 / XYZ_GAMMA;
737 double rgbgammainv = RGB_GAMMA;
738
739 /* set input gamma vectors */
740 for (int i = 0; i < 4096; i++) {
741 xyzgamma_tab[i] = lrint(pow(i / 4095.0, xyzgamma) * 65535.0);
742 rgbgammainv_tab[i] = lrint(pow(i / 4095.0, rgbgammainv) * 65535.0);
743 }
744
745 /* set output gamma vectors */
746 for (int i = 0; i < 65536; i++) {
747 rgbgamma_tab[i] = lrint(pow(i / 65535.0, rgbgamma) * 4095.0);
748 xyzgammainv_tab[i] = lrint(pow(i / 65535.0, xyzgammainv) * 4095.0);
749 }
750}
751
753{
754 static const int16_t xyz2rgb_matrix[3][3] = {
755 {13270, -6295, -2041},
756 {-3969, 7682, 170},
757 { 228, -835, 4329} };
758 static const int16_t rgb2xyz_matrix[3][3] = {
759 {1689, 1464, 739},
760 { 871, 2929, 296},
761 { 79, 488, 3891} };
762
763 if (c->xyz2rgb.gamma.in)
764 return 0;
765
766 memcpy(c->xyz2rgb.mat, xyz2rgb_matrix, sizeof(c->xyz2rgb.mat));
767 memcpy(c->rgb2xyz.mat, rgb2xyz_matrix, sizeof(c->rgb2xyz.mat));
768
769#if CONFIG_SMALL
770 c->xyz2rgb.gamma.in = av_malloc(sizeof(uint16_t) * 2 * (4096 + 65536));
771 if (!c->xyz2rgb.gamma.in)
772 return AVERROR(ENOMEM);
773 c->rgb2xyz.gamma.in = c->xyz2rgb.gamma.in + 4096;
774 c->xyz2rgb.gamma.out = c->rgb2xyz.gamma.in + 4096;
775 c->rgb2xyz.gamma.out = c->xyz2rgb.gamma.out + 65536;
776 init_xyz_tables(c->xyz2rgb.gamma.in, c->rgb2xyz.gamma.out,
777 c->xyz2rgb.gamma.out, c->rgb2xyz.gamma.in);
778#else
779 c->xyz2rgb.gamma.in = xyzgamma_tab;
780 c->xyz2rgb.gamma.out = rgbgamma_tab;
781 c->rgb2xyz.gamma.in = rgbgammainv_tab;
782 c->rgb2xyz.gamma.out = xyzgammainv_tab;
783
784 static AVOnce xyz_init_static_once = AV_ONCE_INIT;
785 ff_thread_once(&xyz_init_static_once, init_xyz_tables);
786#endif
787 return 0;
788}
789
790static int handle_jpeg(/* enum AVPixelFormat */ int *format)
791{
792 switch (*format) {
795 return 1;
798 return 1;
801 return 1;
804 return 1;
807 return 1;
808 case AV_PIX_FMT_GRAY8:
809 case AV_PIX_FMT_YA8:
822 return 1;
823 default:
824 return 0;
825 }
826}
827
828static int handle_0alpha(/* enum AVPixelFormat */ int *format)
829{
830 switch (*format) {
831 case AV_PIX_FMT_0BGR : *format = AV_PIX_FMT_ABGR ; return 1;
832 case AV_PIX_FMT_BGR0 : *format = AV_PIX_FMT_BGRA ; return 4;
833 case AV_PIX_FMT_0RGB : *format = AV_PIX_FMT_ARGB ; return 1;
834 case AV_PIX_FMT_RGB0 : *format = AV_PIX_FMT_RGBA ; return 4;
835 default: return 0;
836 }
837}
838
839static int handle_xyz(/* enum AVPixelFormat */ int *format)
840{
841 switch (*format) {
842 case AV_PIX_FMT_XYZ12BE : *format = AV_PIX_FMT_RGB48BE; return 1;
843 case AV_PIX_FMT_XYZ12LE : *format = AV_PIX_FMT_RGB48LE; return 1;
844 default: return 0;
845 }
846}
847
849{
850 SwsInternal *c = sws_internal(sws);
851 c->src0Alpha |= handle_0alpha(&sws->src_format);
852 c->dst0Alpha |= handle_0alpha(&sws->dst_format);
853 c->srcXYZ |= handle_xyz(&sws->src_format);
854 c->dstXYZ |= handle_xyz(&sws->dst_format);
855 if (c->srcXYZ || c->dstXYZ)
856 return ff_sws_fill_xyztables(c);
857 else
858 return 0;
859}
860
862{
863 return !isYUV(format) && !isGray(format);
864}
865
866int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
867 int srcRange, const int table[4], int dstRange,
868 int brightness, int contrast, int saturation)
869{
870 SwsInternal *c = sws_internal(sws);
871 const AVPixFmtDescriptor *desc_dst;
872 const AVPixFmtDescriptor *desc_src;
873 int ret, need_reinit = 0;
874
875 if (c->nb_slice_ctx) {
876 int parent_ret = 0;
877 for (int i = 0; i < c->nb_slice_ctx; i++) {
878 int ret = sws_setColorspaceDetails(c->slice_ctx[i], inv_table,
879 srcRange, table, dstRange,
880 brightness, contrast, saturation);
881 if (ret < 0)
882 parent_ret = ret;
883 }
884
885 return parent_ret;
886 }
887
888 ret = handle_formats(sws);
889 if (ret < 0)
890 return ret;
891 desc_dst = av_pix_fmt_desc_get(sws->dst_format);
892 desc_src = av_pix_fmt_desc_get(sws->src_format);
893
895 dstRange = 0;
897 srcRange = 0;
898
899 if (sws->src_range != srcRange ||
900 sws->dst_range != dstRange ||
901 c->brightness != brightness ||
902 c->contrast != contrast ||
903 c->saturation != saturation ||
904 memcmp(c->srcColorspaceTable, inv_table, sizeof(int) * 4) ||
905 memcmp(c->dstColorspaceTable, table, sizeof(int) * 4)
906 )
907 need_reinit = 1;
908
909 memmove(c->srcColorspaceTable, inv_table, sizeof(int) * 4);
910 memmove(c->dstColorspaceTable, table, sizeof(int) * 4);
911
912
913
914 c->brightness = brightness;
915 c->contrast = contrast;
916 c->saturation = saturation;
917 sws->src_range = srcRange;
918 sws->dst_range = dstRange;
919
920 if (need_reinit)
922
923 c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
924 c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
925
926 if (c->cascaded_context[c->cascaded_mainindex])
927 return sws_setColorspaceDetails(c->cascaded_context[c->cascaded_mainindex],inv_table, srcRange,table, dstRange, brightness, contrast, saturation);
928
929 if (!need_reinit)
930 return 0;
931
932 if ((isYUV(sws->dst_format) || isGray(sws->dst_format)) && (isYUV(sws->src_format) || isGray(sws->src_format))) {
933 if (!c->cascaded_context[0] &&
934 memcmp(c->dstColorspaceTable, c->srcColorspaceTable, sizeof(int) * 4) &&
935 sws->src_w && sws->src_h && sws->dst_w && sws->dst_h) {
936 enum AVPixelFormat tmp_format;
937 int tmp_width, tmp_height;
938 int srcW = sws->src_w;
939 int srcH = sws->src_h;
940 int dstW = sws->dst_w;
941 int dstH = sws->dst_h;
942 int ret;
943 av_log(c, AV_LOG_VERBOSE, "YUV color matrix differs for YUV->YUV, using intermediate RGB to convert\n");
944
945 if (isNBPS(sws->dst_format) || is16BPS(sws->dst_format)) {
946 if (isALPHA(sws->src_format) && isALPHA(sws->dst_format)) {
947 tmp_format = AV_PIX_FMT_BGRA64;
948 } else {
949 tmp_format = AV_PIX_FMT_BGR48;
950 }
951 } else {
952 if (isALPHA(sws->src_format) && isALPHA(sws->dst_format)) {
953 tmp_format = AV_PIX_FMT_BGRA;
954 } else {
955 tmp_format = AV_PIX_FMT_BGR24;
956 }
957 }
958
959 if (srcW*(int64_t)srcH > dstW*(int64_t)dstH) {
960 tmp_width = dstW;
961 tmp_height = dstH;
962 } else {
963 tmp_width = srcW;
964 tmp_height = srcH;
965 }
966
967 ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
968 tmp_width, tmp_height, tmp_format, 64);
969 if (ret < 0)
970 return ret;
971
972 c->cascaded_context[0] = alloc_set_opts(srcW, srcH, sws->src_format,
973 tmp_width, tmp_height, tmp_format,
974 sws->flags, sws->scaler_params);
975 if (!c->cascaded_context[0])
976 return -1;
977
978 c->cascaded_context[0]->alpha_blend = sws->alpha_blend;
979 set_cascade_chr_pos(c->cascaded_context[0], sws, 1, 0);
980 ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
981 if (ret < 0)
982 return ret;
983 //we set both src and dst depending on that the RGB side will be ignored
984 sws_setColorspaceDetails(c->cascaded_context[0], inv_table,
985 srcRange, table, dstRange,
986 brightness, contrast, saturation);
987
988 c->cascaded_context[1] = alloc_set_opts(tmp_width, tmp_height, tmp_format,
989 dstW, dstH, sws->dst_format,
990 sws->flags, sws->scaler_params);
991 if (!c->cascaded_context[1])
992 return -1;
993 c->cascaded_context[1]->src_range = srcRange;
994 c->cascaded_context[1]->dst_range = dstRange;
995 set_cascade_chr_pos(c->cascaded_context[1], sws, 0, 1);
996 ret = sws_init_context(c->cascaded_context[1], NULL , NULL);
997 if (ret < 0)
998 return ret;
999 sws_setColorspaceDetails(c->cascaded_context[1], inv_table,
1000 srcRange, table, dstRange,
1001 0, 1 << 16, 1 << 16);
1002 return 0;
1003 }
1004 //We do not support this combination currently, we need to cascade more contexts to compensate
1005 if (c->cascaded_context[0] && memcmp(c->dstColorspaceTable, c->srcColorspaceTable, sizeof(int) * 4))
1006 return -1; //AVERROR_PATCHWELCOME;
1007 return 0;
1008 }
1009
1010 if (!isYUV(sws->dst_format) && !isGray(sws->dst_format)) {
1011 ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
1012 contrast, saturation);
1013 // FIXME factorize
1014
1015#if ARCH_PPC
1016 ff_yuv2rgb_init_tables_ppc(c, inv_table, brightness,
1017 contrast, saturation);
1018#endif
1019 }
1020
1021 fill_rgb2yuv_table(c, table, dstRange);
1022
1023 return 0;
1024}
1025
1026int sws_getColorspaceDetails(SwsContext *sws, int **inv_table,
1027 int *srcRange, int **table, int *dstRange,
1028 int *brightness, int *contrast, int *saturation)
1029{
1030 SwsInternal *c = sws_internal(sws);
1031 if (!c)
1032 return -1;
1033
1034 if (c->nb_slice_ctx) {
1035 return sws_getColorspaceDetails(c->slice_ctx[0], inv_table, srcRange,
1036 table, dstRange, brightness, contrast,
1037 saturation);
1038 }
1039
1040 *inv_table = c->srcColorspaceTable;
1041 *table = c->dstColorspaceTable;
1042 *srcRange = range_override_needed(sws->src_format) ? 1 : sws->src_range;
1043 *dstRange = range_override_needed(sws->dst_format) ? 1 : sws->dst_range;
1044 *brightness = c->brightness;
1045 *contrast = c->contrast;
1046 *saturation = c->saturation;
1047
1048 return 0;
1049}
1050
1052{
1054 if (!c)
1055 return NULL;
1056
1057 c->opts.av_class = &ff_sws_context_class;
1059 atomic_init(&c->stride_unaligned_warned, 0);
1060 atomic_init(&c->data_unaligned_warned, 0);
1061
1062 return &c->opts;
1063}
1064
1065static uint16_t * alloc_gamma_tbl(double e)
1066{
1067 int i = 0;
1068 uint16_t * tbl;
1069 tbl = (uint16_t*)av_malloc(sizeof(uint16_t) * 1 << 16);
1070 if (!tbl)
1071 return NULL;
1072
1073 for (i = 0; i < 65536; ++i) {
1074 tbl[i] = pow(i / 65535.0, e) * 65535.0;
1075 }
1076 return tbl;
1077}
1078
1080{
1081 switch(fmt) {
1082 case AV_PIX_FMT_ARGB: return AV_PIX_FMT_RGB24;
1083 case AV_PIX_FMT_RGBA: return AV_PIX_FMT_RGB24;
1084 case AV_PIX_FMT_ABGR: return AV_PIX_FMT_BGR24;
1085 case AV_PIX_FMT_BGRA: return AV_PIX_FMT_BGR24;
1086 case AV_PIX_FMT_YA8: return AV_PIX_FMT_GRAY8;
1087
1091
1092 case AV_PIX_FMT_GBRAP: return AV_PIX_FMT_GBRP;
1093
1096
1099
1102
1105
1110
1113
1132
1133// case AV_PIX_FMT_AYUV64LE:
1134// case AV_PIX_FMT_AYUV64BE:
1135// case AV_PIX_FMT_PAL8:
1136 default: return AV_PIX_FMT_NONE;
1137 }
1138}
1139
1140static int scaler_flag(SwsScaler scaler, int fallback)
1141{
1142 switch (scaler) {
1143 case SWS_SCALE_BILINEAR: return SWS_BILINEAR; break;
1144 case SWS_SCALE_BICUBIC: return SWS_BICUBIC; break;
1145 case SWS_SCALE_POINT: return SWS_POINT; break;
1146 case SWS_SCALE_AREA: return SWS_AREA; break;
1147 case SWS_SCALE_GAUSSIAN: return SWS_GAUSS; break;
1148 case SWS_SCALE_SINC: return SWS_SINC; break;
1149 case SWS_SCALE_LANCZOS: return SWS_LANCZOS; break;
1150 case SWS_SCALE_SPLINE: return SWS_SPLINE; break;
1151 default:
1152 return fallback;
1153 }
1154}
1155
1157 SwsFilter *dstFilter)
1158{
1159 int i;
1160 int usesVFilter, usesHFilter;
1161 int unscaled;
1162 SwsInternal *c = sws_internal(sws);
1163 SwsFilter dummyFilter = { NULL, NULL, NULL, NULL };
1164 int srcW = sws->src_w;
1165 int srcH = sws->src_h;
1166 int dstW = sws->dst_w;
1167 int dstH = sws->dst_h;
1168 int dst_stride = FFALIGN(dstW * sizeof(int16_t) + 66, 16);
1169 int flags, cpu_flags;
1170 enum AVPixelFormat srcFormat, dstFormat;
1171 const AVPixFmtDescriptor *desc_src;
1172 const AVPixFmtDescriptor *desc_dst;
1173 int ret = 0;
1174 enum AVPixelFormat tmpFmt;
1175 static const float float_mult = 1.0f / 255.0f;
1176
1178 flags = sws->flags;
1179 emms_c();
1180
1181 unscaled = (srcW == dstW && srcH == dstH);
1182
1183 if (!c->contrast && !c->saturation && !c->dstFormatBpp)
1186 sws->dst_range, 0, 1 << 16, 1 << 16);
1187
1188 ret = handle_formats(sws);
1189 if (ret < 0)
1190 return ret;
1191 srcFormat = sws->src_format;
1192 dstFormat = sws->dst_format;
1193 desc_src = av_pix_fmt_desc_get(srcFormat);
1194 desc_dst = av_pix_fmt_desc_get(dstFormat);
1195
1196 // If the source has no alpha then disable alpha blendaway
1197 if (c->src0Alpha)
1199
1200 if (!(unscaled && sws_isSupportedEndiannessConversion(srcFormat) &&
1201 av_pix_fmt_swap_endianness(srcFormat) == dstFormat)) {
1202 if (!sws_isSupportedInput(srcFormat)) {
1203 av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
1204 av_get_pix_fmt_name(srcFormat));
1205 return AVERROR(EINVAL);
1206 }
1207 if (!sws_isSupportedOutput(dstFormat)) {
1208 av_log(c, AV_LOG_ERROR, "%s is not supported as output pixel format\n",
1209 av_get_pix_fmt_name(dstFormat));
1210 return AVERROR(EINVAL);
1211 }
1212 }
1213 av_assert2(desc_src && desc_dst);
1214
1215 i = flags & (SWS_POINT |
1216 SWS_AREA |
1217 SWS_BILINEAR |
1219 SWS_BICUBIC |
1220 SWS_X |
1221 SWS_GAUSS |
1222 SWS_LANCZOS |
1223 SWS_SINC |
1224 SWS_SPLINE |
1225 SWS_BICUBLIN);
1226
1227 /* provide a default scaler if not set by caller */
1228 if (!i) {
1229 if (dstW < srcW && dstH < srcH)
1230 i = SWS_BICUBIC;
1231 else if (dstW > srcW && dstH > srcH)
1232 i = SWS_BICUBIC;
1233 else
1234 i = SWS_BICUBIC;
1235 flags |= i;
1236 sws->flags = flags;
1237 } else if (i & (i - 1)) {
1239 "Exactly one scaler algorithm must be chosen, got %X\n", i);
1240 return AVERROR(EINVAL);
1241 }
1242
1243 if (i == SWS_FAST_BILINEAR) {
1244 /* the fast bilinear scalers keep the source position in 16.16 fixed point */
1245 if (srcW < 8 || dstW <= 8 || srcW >= 65536) {
1246 i = SWS_BILINEAR;
1248 sws->flags = flags;
1249 }
1250 }
1251
1252 SwsScaler scaler_sub = sws->scaler_sub ? sws->scaler_sub : sws->scaler;
1253 int lum_scaler = scaler_flag(sws->scaler, i == SWS_BICUBLIN ? SWS_BICUBIC : i);
1254 int chr_scaler = scaler_flag(scaler_sub, i == SWS_BICUBLIN ? SWS_BILINEAR : i);
1255 const int info_scaler = sws->scaler == SWS_SCALE_AUTO &&
1256 i == SWS_BICUBLIN &&
1257 chr_scaler == SWS_BILINEAR ? i : lum_scaler;
1258
1259 /* sanity check */
1260 if (srcW < 1 || srcH < 1 || dstW < 1 || dstH < 1) {
1261 /* FIXME check if these are enough and try to lower them after
1262 * fixing the relevant parts of the code */
1263 av_log(c, AV_LOG_ERROR, "%dx%d -> %dx%d is invalid scaling dimension\n",
1264 srcW, srcH, dstW, dstH);
1265 return AVERROR(EINVAL);
1266 }
1267
1268 ret = av_image_check_size2(srcW, srcH, INT64_MAX, AV_PIX_FMT_NONE, 0, c);
1269 if (ret >= 0)
1270 ret = av_image_check_size2(dstW, dstH, INT64_MAX, AV_PIX_FMT_NONE, 0, c);
1271 if (ret < 0)
1272 return ret;
1273
1274 if (!dstFilter)
1275 dstFilter = &dummyFilter;
1276 if (!srcFilter)
1277 srcFilter = &dummyFilter;
1278
1279 int64_t lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW;
1280 int64_t lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH;
1281 c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
1282 c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
1283 c->vRounder = 4 * 0x0001000100010001ULL;
1284
1285 usesVFilter = (srcFilter->lumV && srcFilter->lumV->length > 1) ||
1286 (srcFilter->chrV && srcFilter->chrV->length > 1) ||
1287 (dstFilter->lumV && dstFilter->lumV->length > 1) ||
1288 (dstFilter->chrV && dstFilter->chrV->length > 1);
1289 usesHFilter = (srcFilter->lumH && srcFilter->lumH->length > 1) ||
1290 (srcFilter->chrH && srcFilter->chrH->length > 1) ||
1291 (dstFilter->lumH && dstFilter->lumH->length > 1) ||
1292 (dstFilter->chrH && dstFilter->chrH->length > 1);
1293
1294 av_pix_fmt_get_chroma_sub_sample(srcFormat, &c->chrSrcHSubSample, &c->chrSrcVSubSample);
1295 av_pix_fmt_get_chroma_sub_sample(dstFormat, &c->chrDstHSubSample, &c->chrDstVSubSample);
1296
1297 c->dst_slice_align = 1 << c->chrDstVSubSample;
1298
1299 if (isAnyRGB(dstFormat) && !(flags&SWS_FULL_CHR_H_INT)) {
1300 if (dstW&1) {
1301 av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to odd output size\n");
1303 sws->flags = flags;
1304 }
1305
1306 if ( c->chrSrcHSubSample == 0
1307 && c->chrSrcVSubSample == 0
1308 && sws->dither != SWS_DITHER_BAYER //SWS_FULL_CHR_H_INT is currently not supported with SWS_DITHER_BAYER
1309 && !(sws->flags & SWS_FAST_BILINEAR)
1310 ) {
1311 av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to input having non subsampled chroma\n");
1313 sws->flags = flags;
1314 }
1315 }
1316
1317 if (sws->dither == SWS_DITHER_AUTO) {
1319 sws->dither = SWS_DITHER_ED;
1320 }
1321
1322 if(dstFormat == AV_PIX_FMT_BGR4_BYTE ||
1323 dstFormat == AV_PIX_FMT_RGB4_BYTE ||
1324 dstFormat == AV_PIX_FMT_BGR8 ||
1325 dstFormat == AV_PIX_FMT_RGB8) {
1326 if (sws->dither == SWS_DITHER_AUTO)
1328 if (!(flags & SWS_FULL_CHR_H_INT)) {
1329 if (sws->dither == SWS_DITHER_ED || sws->dither == SWS_DITHER_A_DITHER || sws->dither == SWS_DITHER_X_DITHER || sws->dither == SWS_DITHER_NONE) {
1331 "Desired dithering only supported in full chroma interpolation for destination format '%s'\n",
1332 av_get_pix_fmt_name(dstFormat));
1334 sws->flags = flags;
1335 }
1336 }
1337 if (flags & SWS_FULL_CHR_H_INT) {
1338 if (sws->dither == SWS_DITHER_BAYER) {
1340 "Ordered dither is not supported in full chroma interpolation for destination format '%s'\n",
1341 av_get_pix_fmt_name(dstFormat));
1342 sws->dither = SWS_DITHER_ED;
1343 }
1344 }
1345 }
1346 if (isPlanarRGB(dstFormat)) {
1347 if (!(flags & SWS_FULL_CHR_H_INT)) {
1349 "%s output is not supported with half chroma resolution, switching to full\n",
1350 av_get_pix_fmt_name(dstFormat));
1352 sws->flags = flags;
1353 }
1354 }
1355
1356 /* reuse chroma for 2 pixels RGB/BGR unless user wants full
1357 * chroma interpolation */
1358 if (flags & SWS_FULL_CHR_H_INT &&
1359 isAnyRGB(dstFormat) &&
1360 !isPlanarRGB(dstFormat) &&
1361 dstFormat != AV_PIX_FMT_RGBA64LE &&
1362 dstFormat != AV_PIX_FMT_RGBA64BE &&
1363 dstFormat != AV_PIX_FMT_BGRA64LE &&
1364 dstFormat != AV_PIX_FMT_BGRA64BE &&
1365 dstFormat != AV_PIX_FMT_RGB48LE &&
1366 dstFormat != AV_PIX_FMT_RGB48BE &&
1367 dstFormat != AV_PIX_FMT_BGR48LE &&
1368 dstFormat != AV_PIX_FMT_BGR48BE &&
1369 dstFormat != AV_PIX_FMT_RGBA &&
1370 dstFormat != AV_PIX_FMT_ARGB &&
1371 dstFormat != AV_PIX_FMT_BGRA &&
1372 dstFormat != AV_PIX_FMT_ABGR &&
1373 dstFormat != AV_PIX_FMT_RGB24 &&
1374 dstFormat != AV_PIX_FMT_BGR24 &&
1375 dstFormat != AV_PIX_FMT_BGR4_BYTE &&
1376 dstFormat != AV_PIX_FMT_RGB4_BYTE &&
1377 dstFormat != AV_PIX_FMT_BGR8 &&
1378 dstFormat != AV_PIX_FMT_RGB8 &&
1379 dstFormat != AV_PIX_FMT_X2RGB10LE &&
1380 dstFormat != AV_PIX_FMT_X2BGR10LE
1381 ) {
1383 "full chroma interpolation for destination format '%s' not yet implemented\n",
1384 av_get_pix_fmt_name(dstFormat));
1386 sws->flags = flags;
1387 }
1388 if (isAnyRGB(dstFormat) && !(flags & SWS_FULL_CHR_H_INT))
1389 c->chrDstHSubSample = 1;
1390
1391 // drop some chroma lines if the user wants it
1392 c->vChrDrop = (flags & SWS_SRC_V_CHR_DROP_MASK) >>
1394 c->chrSrcVSubSample += c->vChrDrop;
1395
1396 /* drop every other pixel for chroma calculation unless user
1397 * wants full chroma */
1398 if (isAnyRGB(srcFormat) && !(srcW & 1) && !(flags & SWS_FULL_CHR_H_INP) &&
1399 srcFormat != AV_PIX_FMT_RGB8 && srcFormat != AV_PIX_FMT_BGR8 &&
1400 srcFormat != AV_PIX_FMT_RGB4 && srcFormat != AV_PIX_FMT_BGR4 &&
1401 srcFormat != AV_PIX_FMT_RGB4_BYTE && srcFormat != AV_PIX_FMT_BGR4_BYTE &&
1402 srcFormat != AV_PIX_FMT_GBRP9BE && srcFormat != AV_PIX_FMT_GBRP9LE &&
1403 srcFormat != AV_PIX_FMT_GBRP10BE && srcFormat != AV_PIX_FMT_GBRP10LE &&
1404 srcFormat != AV_PIX_FMT_GBRP10MSBBE && srcFormat != AV_PIX_FMT_GBRP10MSBLE &&
1405 srcFormat != AV_PIX_FMT_GBRAP10BE && srcFormat != AV_PIX_FMT_GBRAP10LE &&
1406 srcFormat != AV_PIX_FMT_GBRP12BE && srcFormat != AV_PIX_FMT_GBRP12LE &&
1407 srcFormat != AV_PIX_FMT_GBRP12MSBBE && srcFormat != AV_PIX_FMT_GBRP12MSBLE &&
1408 srcFormat != AV_PIX_FMT_GBRAP12BE && srcFormat != AV_PIX_FMT_GBRAP12LE &&
1409 srcFormat != AV_PIX_FMT_GBRAP14BE && srcFormat != AV_PIX_FMT_GBRAP14LE &&
1410 srcFormat != AV_PIX_FMT_GBRP14BE && srcFormat != AV_PIX_FMT_GBRP14LE &&
1411 srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE &&
1412 srcFormat != AV_PIX_FMT_GBRAP16BE && srcFormat != AV_PIX_FMT_GBRAP16LE &&
1413 srcFormat != AV_PIX_FMT_GBRPF32BE && srcFormat != AV_PIX_FMT_GBRPF32LE &&
1414 srcFormat != AV_PIX_FMT_GBRAPF32BE && srcFormat != AV_PIX_FMT_GBRAPF32LE &&
1415 srcFormat != AV_PIX_FMT_GBRPF16BE && srcFormat != AV_PIX_FMT_GBRPF16LE &&
1416 srcFormat != AV_PIX_FMT_GBRAPF16BE && srcFormat != AV_PIX_FMT_GBRAPF16LE &&
1417 ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
1419 c->chrSrcHSubSample = 1;
1420
1421 // Note the AV_CEIL_RSHIFT is so that we always round toward +inf.
1422 c->chrSrcW = AV_CEIL_RSHIFT(srcW, c->chrSrcHSubSample);
1423 c->chrSrcH = AV_CEIL_RSHIFT(srcH, c->chrSrcVSubSample);
1424 c->chrDstW = AV_CEIL_RSHIFT(dstW, c->chrDstHSubSample);
1425 c->chrDstH = AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample);
1426
1427 if (!FF_ALLOCZ_TYPED_ARRAY(c->formatConvBuffer, FFALIGN(srcW * 2 + 78, 16) * 2))
1428 goto nomem;
1429
1430 c->srcBpc = desc_src->comp[0].depth;
1431 if (c->srcBpc < 8)
1432 c->srcBpc = 8;
1433 c->dstBpc = desc_dst->comp[0].depth;
1434 if (c->dstBpc < 8)
1435 c->dstBpc = 8;
1436 if (isAnyRGB(srcFormat) || srcFormat == AV_PIX_FMT_PAL8)
1437 c->srcBpc = 16;
1438 if (c->dstBpc == 16)
1439 dst_stride <<= 1;
1440
1441 if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 14) {
1442 c->canMMXEXTBeUsed = dstW >= srcW && (dstW & 31) == 0 &&
1443 c->chrDstW >= c->chrSrcW &&
1444 (srcW & 15) == 0;
1445 if (!c->canMMXEXTBeUsed && dstW >= srcW && c->chrDstW >= c->chrSrcW && (srcW & 15) == 0
1446
1447 && (flags & SWS_FAST_BILINEAR)) {
1448 if (flags & SWS_PRINT_INFO)
1450 "output width is not a multiple of 32 -> no MMXEXT scaler\n");
1451 }
1452 if (usesHFilter || isNBPS(sws->src_format) || is16BPS(sws->src_format) || isAnyRGB(sws->src_format))
1453 c->canMMXEXTBeUsed = 0;
1454 } else
1455 c->canMMXEXTBeUsed = 0;
1456
1457 int64_t chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW;
1458 int64_t chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH;
1459
1460 /* Match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src
1461 * to pixel n-2 of dst, but only for the FAST_BILINEAR mode otherwise do
1462 * correct scaling.
1463 * n-2 is the last chrominance sample available.
1464 * This is not perfect, but no one should notice the difference, the more
1465 * correct variant would be like the vertical one, but that would require
1466 * some special code for the first and last pixel */
1467 if (flags & SWS_FAST_BILINEAR) {
1468 if (c->canMMXEXTBeUsed) {
1469 lumXInc += 1;
1470 chrXInc += 1;
1471 }
1472 // we don't use the x86 asm scaler if MMX is available
1473 else if (INLINE_MMX(cpu_flags) && c->dstBpc <= 14) {
1474 lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20;
1475 chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20;
1476 }
1477 }
1478 if (chrXInc < 10 || chrXInc > INT_MAX ||
1479 chrYInc < 10 || chrYInc > INT_MAX ||
1480 lumXInc < 10 || lumXInc > INT_MAX ||
1481 lumYInc < 10 || lumYInc > INT_MAX)
1482 return AVERROR_PATCHWELCOME;
1483
1484 c->lumXInc = lumXInc;
1485 c->lumYInc = lumYInc;
1486 c->chrXInc = chrXInc;
1487 c->chrYInc = chrYInc;
1488
1489
1490 // hardcoded for now
1491 c->gamma_value = 2.2;
1492 tmpFmt = AV_PIX_FMT_RGBA64LE;
1493
1494 if (!unscaled && sws->gamma_flag && (srcFormat != tmpFmt || dstFormat != tmpFmt)) {
1495 SwsInternal *c2;
1496 c->cascaded_context[0] = NULL;
1497
1498 ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1499 srcW, srcH, tmpFmt, 64);
1500 if (ret < 0)
1501 return ret;
1502
1503 c->cascaded_context[0] = alloc_set_opts(srcW, srcH, srcFormat,
1504 srcW, srcH, tmpFmt,
1505 flags, sws->scaler_params);
1506 if (!c->cascaded_context[0])
1507 return AVERROR(ENOMEM);
1508 set_cascade_chr_pos(c->cascaded_context[0], sws, 1, 0);
1509 ret = sws_init_context(c->cascaded_context[0], NULL, NULL);
1510 if (ret < 0)
1511 return ret;
1512
1513 c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFmt,
1514 dstW, dstH, tmpFmt,
1515 flags, srcFilter, dstFilter,
1516 sws->scaler_params);
1517
1518 if (!c->cascaded_context[1])
1519 return AVERROR(ENOMEM);
1520
1521 c2 = sws_internal(c->cascaded_context[1]);
1522 c2->is_internal_gamma = 1;
1523 c2->gamma = alloc_gamma_tbl( c->gamma_value);
1524 c2->inv_gamma = alloc_gamma_tbl(1.f/c->gamma_value);
1525 if (!c2->gamma || !c2->inv_gamma)
1526 return AVERROR(ENOMEM);
1527
1528 // is_internal_flag is set after creating the context
1529 // to properly create the gamma convert FilterDescriptor
1530 // we have to re-initialize it
1532 if ((ret = ff_init_filters(c2)) < 0) {
1533 sws_freeContext(c->cascaded_context[1]);
1534 c->cascaded_context[1] = NULL;
1535 return ret;
1536 }
1537
1538 c->cascaded_context[2] = NULL;
1539 if (dstFormat != tmpFmt) {
1540 ret = av_image_alloc(c->cascaded_tmp[1], c->cascaded_tmpStride[1],
1541 dstW, dstH, tmpFmt, 64);
1542 if (ret < 0)
1543 return ret;
1544
1545 c->cascaded_context[2] = alloc_set_opts(dstW, dstH, tmpFmt,
1546 dstW, dstH, dstFormat,
1547 flags, sws->scaler_params);
1548 if (!c->cascaded_context[2])
1549 return AVERROR(ENOMEM);
1550 set_cascade_chr_pos(c->cascaded_context[2], sws, 0, 1);
1551 ret = sws_init_context(c->cascaded_context[2], NULL, NULL);
1552 if (ret < 0)
1553 return ret;
1554 }
1555 return 0;
1556 }
1557
1558 if (!isGray(srcFormat) &&
1559 ((desc_dst->log2_chroma_w &&
1560 get_center_offset(c, desc_src->log2_chroma_w, sws->src_h_chr_pos, 0) !=
1561 get_center_offset(c, desc_dst->log2_chroma_w, sws->dst_h_chr_pos, 0)) ||
1562 (desc_dst->log2_chroma_h &&
1563 get_center_offset(c, desc_src->log2_chroma_h, sws->src_v_chr_pos, 1) !=
1564 get_center_offset(c, desc_dst->log2_chroma_h, sws->dst_v_chr_pos, 1))))
1565 unscaled = 0;
1566
1567 if (isBayer(srcFormat)) {
1568 if (!unscaled ||
1569 (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P &&
1570 dstFormat != AV_PIX_FMT_RGB48)) {
1571 enum AVPixelFormat tmpFormat = isBayer16BPS(srcFormat) ? AV_PIX_FMT_RGB48 : AV_PIX_FMT_RGB24;
1572
1573 ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1574 srcW, srcH, tmpFormat, 64);
1575 if (ret < 0)
1576 return ret;
1577
1578 c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
1579 srcW, srcH, tmpFormat,
1580 flags, srcFilter, NULL,
1581 sws->scaler_params);
1582 if (!c->cascaded_context[0])
1583 return AVERROR(ENOMEM);
1584
1585 c->cascaded_context[1] = alloc_set_opts(srcW, srcH, tmpFormat,
1586 dstW, dstH, dstFormat,
1587 flags, sws->scaler_params);
1588 if (!c->cascaded_context[1])
1589 return AVERROR(ENOMEM);
1590 set_cascade_chr_pos(c->cascaded_context[1], sws, 0, 1);
1591 ret = sws_init_context(c->cascaded_context[1], NULL, dstFilter);
1592 if (ret < 0)
1593 return ret;
1594 return 0;
1595 }
1596 }
1597
1598 if (unscaled && c->srcBpc == 8 && dstFormat == AV_PIX_FMT_GRAYF32){
1599 for (i = 0; i < 256; ++i){
1600 c->uint2float_lut[i] = (float)i * float_mult;
1601 }
1602 }
1603
1604 // float will be converted to uint16_t
1605 if (isFloat(srcFormat) && !isAnyRGB(srcFormat) &&
1606 (!unscaled || unscaled && dstFormat != srcFormat && (srcFormat != AV_PIX_FMT_GRAYF32 ||
1607 dstFormat != AV_PIX_FMT_GRAY8))){
1608 c->srcBpc = 16;
1609 }
1610
1611 if (CONFIG_SWSCALE_ALPHA && isALPHA(srcFormat) && !isALPHA(dstFormat)) {
1612 enum AVPixelFormat tmpFormat = alphaless_fmt(srcFormat);
1613
1614 if (tmpFormat != AV_PIX_FMT_NONE && sws->alpha_blend != SWS_ALPHA_BLEND_NONE) {
1615 if (!unscaled ||
1616 dstFormat != tmpFormat ||
1617 usesHFilter || usesVFilter ||
1618 sws->src_range != sws->dst_range
1619 ) {
1620 c->cascaded_mainindex = 1;
1621 ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1622 srcW, srcH, tmpFormat, 64);
1623 if (ret < 0)
1624 return ret;
1625
1626 c->cascaded_context[0] = alloc_set_opts(srcW, srcH, srcFormat,
1627 srcW, srcH, tmpFormat,
1628 flags, sws->scaler_params);
1629 if (!c->cascaded_context[0])
1630 return AVERROR(EINVAL);
1631 c->cascaded_context[0]->alpha_blend = sws->alpha_blend;
1632 ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
1633 if (ret < 0)
1634 return ret;
1635
1636 c->cascaded_context[1] = alloc_set_opts(srcW, srcH, tmpFormat,
1637 dstW, dstH, dstFormat,
1638 flags, sws->scaler_params);
1639 if (!c->cascaded_context[1])
1640 return AVERROR(EINVAL);
1641
1642 c->cascaded_context[1]->src_range = sws->src_range;
1643 c->cascaded_context[1]->dst_range = sws->dst_range;
1644 set_cascade_chr_pos(c->cascaded_context[1], sws, 1, 1);
1645 ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter);
1646 if (ret < 0)
1647 return ret;
1648
1649 return 0;
1650 }
1651 }
1652 }
1653
1654 /* alpha blend special case, note this has been split via cascaded contexts if its scaled */
1655 if (unscaled && !usesHFilter && !usesVFilter &&
1657 isALPHA(srcFormat) &&
1658 (sws->src_range == sws->dst_range || isAnyRGB(dstFormat)) &&
1659 alphaless_fmt(srcFormat) == dstFormat
1660 ) {
1661 c->convert_unscaled = ff_sws_alphablendaway;
1662
1663 if (flags & SWS_PRINT_INFO)
1665 "using alpha blendaway %s -> %s special converter\n",
1666 av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1667 return 0;
1668 }
1669
1670 /* unscaled special cases */
1671 if (unscaled && !usesHFilter && !usesVFilter &&
1672 (sws->src_range == sws->dst_range || isAnyRGB(dstFormat) ||
1673 isFloat(srcFormat) || isFloat(dstFormat) || isBayer(srcFormat))){
1674
1676
1677 if (c->convert_unscaled) {
1678 if (flags & SWS_PRINT_INFO)
1680 "using unscaled %s -> %s special converter\n",
1681 av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1682 return 0;
1683 }
1684 }
1685
1686 /* precalculate horizontal scaler filter coefficients */
1687 {
1688#if HAVE_MMXEXT_INLINE
1689// can't downscale !!!
1690 if (c->canMMXEXTBeUsed && (flags & SWS_FAST_BILINEAR)) {
1691 c->lumMmxextFilterCodeSize = ff_init_hscaler_mmxext(dstW, c->lumXInc, NULL,
1692 NULL, NULL, 8);
1693 c->chrMmxextFilterCodeSize = ff_init_hscaler_mmxext(c->chrDstW, c->chrXInc,
1694 NULL, NULL, NULL, 4);
1695
1696 c->lumMmxextFilterCode = ff_sws_jit_alloc(c->lumMmxextFilterCodeSize);
1697 c->chrMmxextFilterCode = ff_sws_jit_alloc(c->chrMmxextFilterCodeSize);
1698 if (!c->lumMmxextFilterCode || !c->chrMmxextFilterCode) {
1699 av_log(c, AV_LOG_ERROR, "Failed to allocate MMX2FilterCode\n");
1700 return AVERROR(ENOMEM);
1701 }
1702
1703 if (!FF_ALLOCZ_TYPED_ARRAY(c->hLumFilter, dstW / 8 + 8) ||
1704 !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilter, c->chrDstW / 4 + 8) ||
1705 !FF_ALLOCZ_TYPED_ARRAY(c->hLumFilterPos, dstW / 2 / 8 + 8) ||
1706 !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilterPos, c->chrDstW / 2 / 4 + 8))
1707 goto nomem;
1708
1709 ff_init_hscaler_mmxext( dstW, c->lumXInc, c->lumMmxextFilterCode,
1710 c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8);
1711 ff_init_hscaler_mmxext(c->chrDstW, c->chrXInc, c->chrMmxextFilterCode,
1712 c->hChrFilter, (uint32_t*)c->hChrFilterPos, 4);
1713
1714 if ((ret = ff_sws_jit_protect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize)) < 0 ||
1715 (ret = ff_sws_jit_protect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize)) < 0) {
1716 av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast bilinear scaler\n");
1717 goto fail;
1718 }
1719 } else
1720#endif /* HAVE_MMXEXT_INLINE */
1721 {
1722 const int filterAlign = X86_MMX(cpu_flags) ? 4 :
1723 PPC_ALTIVEC(cpu_flags) ? 8 :
1724 have_neon(cpu_flags) ? 4 :
1725 have_lsx(cpu_flags) ? 8 :
1726 have_lasx(cpu_flags) ? 8 : 1;
1727
1728 if ((ret = initFilter(&c->hLumFilter, &c->hLumFilterPos,
1729 &c->hLumFilterSize, c->lumXInc,
1730 srcW, dstW, filterAlign, 1 << 14,
1731 lum_scaler, flags,
1732 cpu_flags, srcFilter->lumH, dstFilter->lumH,
1733 sws->scaler_params,
1734 get_local_pos(c, 0, 0, 0),
1735 get_local_pos(c, 0, 0, 0))) < 0)
1736 goto fail;
1737 if (ff_shuffle_filter_coefficients(c, c->hLumFilterPos, c->hLumFilterSize, c->hLumFilter, dstW) < 0)
1738 goto nomem;
1739 if ((ret = initFilter(&c->hChrFilter, &c->hChrFilterPos,
1740 &c->hChrFilterSize, c->chrXInc,
1741 c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
1742 chr_scaler, flags,
1743 cpu_flags, srcFilter->chrH, dstFilter->chrH,
1744 sws->scaler_params,
1745 get_local_pos(c, c->chrSrcHSubSample, sws->src_h_chr_pos, 0),
1746 get_local_pos(c, c->chrDstHSubSample, sws->dst_h_chr_pos, 0))) < 0)
1747 goto fail;
1748 if (ff_shuffle_filter_coefficients(c, c->hChrFilterPos, c->hChrFilterSize, c->hChrFilter, c->chrDstW) < 0)
1749 goto nomem;
1750 }
1751 } // initialize horizontal stuff
1752
1753 /* precalculate vertical scaler filter coefficients */
1754 {
1755 const int filterAlign = X86_MMX(cpu_flags) ? 2 :
1756 PPC_ALTIVEC(cpu_flags) ? 8 :
1757 have_neon(cpu_flags) ? 2 : 1;
1758
1759 ret = initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
1760 c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
1761 lum_scaler, flags,
1762 cpu_flags, srcFilter->lumV, dstFilter->lumV,
1763 sws->scaler_params,
1764 get_local_pos(c, 0, 0, 1),
1765 get_local_pos(c, 0, 0, 1));
1766 int usecascade = (ret == RETCODE_USE_CASCADE);
1767 if (ret < 0 && !usecascade)
1768 goto fail;
1769 if ((ret = initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
1770 c->chrYInc, c->chrSrcH, c->chrDstH,
1771 filterAlign, (1 << 12),
1772 chr_scaler, flags,
1773 cpu_flags, srcFilter->chrV, dstFilter->chrV,
1774 sws->scaler_params,
1775 get_local_pos(c, c->chrSrcVSubSample, sws->src_v_chr_pos, 1),
1776 get_local_pos(c, c->chrDstVSubSample, sws->dst_v_chr_pos, 1))) < 0)
1777
1778 goto fail;
1779 if (usecascade) {
1780 ret = RETCODE_USE_CASCADE;
1781 goto fail;
1782 }
1783
1784#if HAVE_ALTIVEC
1786 if (ret < 0)
1787 goto fail;
1788#endif
1789 }
1790
1791 for (i = 0; i < 4; i++)
1792 if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], sws->dst_w + 3))
1793 goto nomem;
1794
1795 c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(sws->src_format) && isALPHA(sws->dst_format)) ? 1 : 0;
1796
1797 // 64 / c->scalingBpp is the same as 16 / sizeof(scaling_intermediate)
1798 c->uv_off = (dst_stride>>1) + 64 / (c->dstBpc &~ 7);
1799 c->uv_offx2 = dst_stride + 16;
1800
1801 av_assert0(c->chrDstH <= dstH);
1802
1803 if (flags & SWS_PRINT_INFO) {
1804 const char *scaler = NULL, *cpucaps;
1805
1806 for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
1807 if (info_scaler == scale_algorithms[i].flag) {
1808 scaler = scale_algorithms[i].description;
1809 break;
1810 }
1811 }
1812 if (!scaler)
1813 scaler = "ehh flags invalid?!";
1814 av_log(c, AV_LOG_INFO, "%s scaler, from %s to %s%s ",
1815 scaler,
1816 av_get_pix_fmt_name(srcFormat),
1817 dstFormat == AV_PIX_FMT_BGR555 || dstFormat == AV_PIX_FMT_BGR565 ||
1818 dstFormat == AV_PIX_FMT_RGB444BE || dstFormat == AV_PIX_FMT_RGB444LE ||
1819 dstFormat == AV_PIX_FMT_BGR444BE || dstFormat == AV_PIX_FMT_BGR444LE ?
1820 "dithered " : "",
1821 av_get_pix_fmt_name(dstFormat));
1822
1824 cpucaps = "MMXEXT";
1825 else if (INLINE_MMX(cpu_flags))
1826 cpucaps = "MMX";
1827 else if (PPC_ALTIVEC(cpu_flags))
1828 cpucaps = "AltiVec";
1829 else
1830 cpucaps = "C";
1831
1832 av_log(c, AV_LOG_INFO, "using %s\n", cpucaps);
1833
1834 av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
1836 "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1837 sws->src_w, sws->src_h, sws->dst_w, sws->dst_h, c->lumXInc, c->lumYInc);
1839 "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1840 c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH,
1841 c->chrXInc, c->chrYInc);
1842 }
1843
1845
1846 return ff_init_filters(c);
1847nomem:
1848 ret = AVERROR(ENOMEM);
1849fail: // FIXME replace things by appropriate error codes
1850 if (ret == RETCODE_USE_CASCADE) {
1851 int tmpW = sqrt(srcW * (int64_t)dstW);
1852 int tmpH = sqrt(srcH * (int64_t)dstH);
1853 enum AVPixelFormat tmpFormat = AV_PIX_FMT_YUV420P;
1854
1855 if (isALPHA(srcFormat))
1856 tmpFormat = AV_PIX_FMT_YUVA420P;
1857
1858 if (srcW*(int64_t)srcH <= 4LL*dstW*dstH)
1859 return AVERROR(EINVAL);
1860
1861 ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1862 tmpW, tmpH, tmpFormat, 64);
1863 if (ret < 0)
1864 return ret;
1865
1866 c->cascaded_context[0] = alloc_set_opts(srcW, srcH, srcFormat,
1867 tmpW, tmpH, tmpFormat,
1868 flags, sws->scaler_params);
1869 if (!c->cascaded_context[0])
1870 return AVERROR(ENOMEM);
1871 set_cascade_chr_pos(c->cascaded_context[0], sws, 1, 0);
1872 ret = sws_init_context(c->cascaded_context[0], srcFilter, NULL);
1873 if (ret < 0)
1874 return ret;
1875
1876 c->cascaded_context[1] = alloc_set_opts(tmpW, tmpH, tmpFormat,
1877 dstW, dstH, dstFormat,
1878 flags, sws->scaler_params);
1879 if (!c->cascaded_context[1])
1880 return AVERROR(ENOMEM);
1881 set_cascade_chr_pos(c->cascaded_context[1], sws, 0, 1);
1882 ret = sws_init_context(c->cascaded_context[1], NULL, dstFilter);
1883 if (ret < 0)
1884 return ret;
1885 return 0;
1886 }
1887 return ret;
1888}
1889
1891 SwsFilter *src_filter, SwsFilter *dst_filter)
1892{
1893 SwsInternal *c = sws_internal(sws);
1894 int ret;
1895
1896 ret = avpriv_slicethread_create2(&c->slicethread, (void*) sws,
1898 if (ret == AVERROR(ENOSYS)) {
1899 sws->threads = 1;
1900 return 0;
1901 } else if (ret < 0)
1902 return ret;
1903
1904 sws->threads = ret;
1905
1906 c->slice_ctx = av_calloc(sws->threads, sizeof(*c->slice_ctx));
1907 if (!c->slice_ctx)
1908 return AVERROR(ENOMEM);
1909
1910 for (int i = 0; i < sws->threads; i++) {
1911 SwsContext *slice;
1912 slice = c->slice_ctx[i] = sws_alloc_context();
1913 if (!slice)
1914 return AVERROR(ENOMEM);
1915 sws_internal(slice)->parent = sws;
1916 c->nb_slice_ctx++;
1917
1918 ret = av_opt_copy(slice, sws);
1919 if (ret < 0)
1920 return ret;
1921 slice->threads = 1;
1922
1923 ret = ff_sws_init_single_context(slice, src_filter, dst_filter);
1924 if (ret < 0)
1925 return ret;
1926
1927 if (slice->dither == SWS_DITHER_ED) {
1929 "Error-diffusion dither is in use, scaling will be single-threaded.");
1930 break;
1931 }
1932 }
1933
1934 return 0;
1935}
1936
1938 SwsFilter *dstFilter)
1939{
1940 SwsInternal *c = sws_internal(sws);
1941 static AVOnce rgb2rgb_once = AV_ONCE_INIT;
1942 enum AVPixelFormat src_format, dst_format;
1943 int ret;
1944
1945 c->is_legacy_init = 1;
1946 c->frame_src = av_frame_alloc();
1947 c->frame_dst = av_frame_alloc();
1948 if (!c->frame_src || !c->frame_dst)
1949 return AVERROR(ENOMEM);
1950
1951 if (ff_thread_once(&rgb2rgb_once, ff_sws_rgb2rgb_init) != 0)
1952 return AVERROR_UNKNOWN;
1953
1954 src_format = sws->src_format;
1955 dst_format = sws->dst_format;
1956 sws->src_range |= handle_jpeg(&sws->src_format);
1957 sws->dst_range |= handle_jpeg(&sws->dst_format);
1958
1959 if (src_format != sws->src_format || dst_format != sws->dst_format)
1960 av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
1961
1962 if (sws->threads != 1) {
1963 ret = context_init_threaded(sws, srcFilter, dstFilter);
1964 if (ret < 0 || sws->threads > 1)
1965 return ret;
1966 // threading disabled in this build, init as single-threaded
1967 }
1968
1969 return ff_sws_init_single_context(sws, srcFilter, dstFilter);
1970}
1971
1972SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
1973 int dstW, int dstH, enum AVPixelFormat dstFormat,
1974 int flags, SwsFilter *srcFilter,
1975 SwsFilter *dstFilter, const double *param)
1976{
1977 SwsContext *sws;
1978
1979 sws = alloc_set_opts(srcW, srcH, srcFormat,
1980 dstW, dstH, dstFormat,
1981 flags, param);
1982 if (!sws)
1983 return NULL;
1984
1985 if (sws_init_context(sws, srcFilter, dstFilter) < 0) {
1986 sws_freeContext(sws);
1987 return NULL;
1988 }
1989
1990 return sws;
1991}
1992
1994{
1995 int i;
1996 for (i=0; i<a->length; i++)
1997 if (isnan(a->coeff[i]))
1998 return 1;
1999 return 0;
2000}
2001
2003{
2004 int i;
2005 for (i=0; i<a->length; i++)
2006 a->coeff[i] = NAN;
2007}
2008
2010{
2011 SwsVector *vec;
2012
2013 if(length <= 0 || length > INT_MAX/ sizeof(double))
2014 return NULL;
2015
2016 vec = av_malloc(sizeof(SwsVector));
2017 if (!vec)
2018 return NULL;
2019 vec->length = length;
2020 vec->coeff = av_malloc(sizeof(double) * length);
2021 if (!vec->coeff)
2022 av_freep(&vec);
2023 return vec;
2024}
2025
2026SwsVector *sws_getGaussianVec(double variance, double quality)
2027{
2028 const int length = (int)(variance * quality + 0.5) | 1;
2029 int i;
2030 double middle = (length - 1) * 0.5;
2031 SwsVector *vec;
2032
2033 if(variance < 0 || quality < 0)
2034 return NULL;
2035
2036 vec = sws_allocVec(length);
2037
2038 if (!vec)
2039 return NULL;
2040
2041 for (i = 0; i < length; i++) {
2042 double dist = i - middle;
2043 vec->coeff[i] = exp(-dist * dist / (2 * variance * variance)) /
2044 sqrt(2 * variance * M_PI);
2045 }
2046
2047 sws_normalizeVec(vec, 1.0);
2048
2049 return vec;
2050}
2051
2052/**
2053 * Allocate and return a vector with length coefficients, all
2054 * with the same value c.
2055 */
2056static
2057SwsVector *sws_getConstVec(double c, int length)
2058{
2059 int i;
2060 SwsVector *vec = sws_allocVec(length);
2061
2062 if (!vec)
2063 return NULL;
2064
2065 for (i = 0; i < length; i++)
2066 vec->coeff[i] = c;
2067
2068 return vec;
2069}
2070
2071/**
2072 * Allocate and return a vector with just one coefficient, with
2073 * value 1.0.
2074 */
2075static
2077{
2078 return sws_getConstVec(1.0, 1);
2079}
2080
2081static double sws_dcVec(SwsVector *a)
2082{
2083 int i;
2084 double sum = 0;
2085
2086 for (i = 0; i < a->length; i++)
2087 sum += a->coeff[i];
2088
2089 return sum;
2090}
2091
2092void sws_scaleVec(SwsVector *a, double scalar)
2093{
2094 int i;
2095
2096 for (i = 0; i < a->length; i++)
2097 a->coeff[i] *= scalar;
2098}
2099
2101{
2103}
2104
2106{
2107 int length = FFMAX(a->length, b->length);
2108 int i;
2109 SwsVector *vec = sws_getConstVec(0.0, length);
2110
2111 if (!vec)
2112 return NULL;
2113
2114 for (i = 0; i < a->length; i++)
2115 vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
2116 for (i = 0; i < b->length; i++)
2117 vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] += b->coeff[i];
2118
2119 return vec;
2120}
2121
2122/* shift left / or right if "shift" is negative */
2124{
2125 int length = a->length + FFABS(shift) * 2;
2126 int i;
2127 SwsVector *vec = sws_getConstVec(0.0, length);
2128
2129 if (!vec)
2130 return NULL;
2131
2132 for (i = 0; i < a->length; i++) {
2133 vec->coeff[i + (length - 1) / 2 -
2134 (a->length - 1) / 2 - shift] = a->coeff[i];
2135 }
2136
2137 return vec;
2138}
2139
2140static
2142{
2143 SwsVector *shifted = sws_getShiftedVec(a, shift);
2144 if (!shifted) {
2145 makenan_vec(a);
2146 return;
2147 }
2148 av_free(a->coeff);
2149 a->coeff = shifted->coeff;
2150 a->length = shifted->length;
2151 av_free(shifted);
2152}
2153
2154static
2156{
2157 SwsVector *sum = sws_sumVec(a, b);
2158 if (!sum) {
2159 makenan_vec(a);
2160 return;
2161 }
2162 av_free(a->coeff);
2163 a->coeff = sum->coeff;
2164 a->length = sum->length;
2165 av_free(sum);
2166}
2167
2168/**
2169 * Print with av_log() a textual representation of the vector a
2170 * if log_level <= av_log_level.
2171 */
2172static
2173void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
2174{
2175 int i;
2176 double max = 0;
2177 double min = 0;
2178 double range;
2179
2180 for (i = 0; i < a->length; i++)
2181 if (a->coeff[i] > max)
2182 max = a->coeff[i];
2183
2184 for (i = 0; i < a->length; i++)
2185 if (a->coeff[i] < min)
2186 min = a->coeff[i];
2187
2188 range = max - min;
2189
2190 for (i = 0; i < a->length; i++) {
2191 int x = (int)((a->coeff[i] - min) * 60.0 / range + 0.5);
2192 av_log(log_ctx, log_level, "%1.3f ", a->coeff[i]);
2193 for (; x > 0; x--)
2194 av_log(log_ctx, log_level, " ");
2195 av_log(log_ctx, log_level, "|\n");
2196 }
2197}
2198
2200{
2201 if (!a)
2202 return;
2203 av_freep(&a->coeff);
2204 a->length = 0;
2205 av_free(a);
2206}
2207
2209{
2210 if (!filter)
2211 return;
2212
2213 sws_freeVec(filter->lumH);
2214 sws_freeVec(filter->lumV);
2215 sws_freeVec(filter->chrH);
2216 sws_freeVec(filter->chrV);
2217 av_free(filter);
2218}
2219
2220SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
2221 float lumaSharpen, float chromaSharpen,
2222 float chromaHShift, float chromaVShift,
2223 int verbose)
2224{
2225 SwsFilter *filter = av_malloc(sizeof(SwsFilter));
2226 if (!filter)
2227 return NULL;
2228
2229 if (lumaGBlur != 0.0) {
2230 filter->lumH = sws_getGaussianVec(lumaGBlur, 3.0);
2231 filter->lumV = sws_getGaussianVec(lumaGBlur, 3.0);
2232 } else {
2233 filter->lumH = sws_getIdentityVec();
2234 filter->lumV = sws_getIdentityVec();
2235 }
2236
2237 if (chromaGBlur != 0.0) {
2238 filter->chrH = sws_getGaussianVec(chromaGBlur, 3.0);
2239 filter->chrV = sws_getGaussianVec(chromaGBlur, 3.0);
2240 } else {
2241 filter->chrH = sws_getIdentityVec();
2242 filter->chrV = sws_getIdentityVec();
2243 }
2244
2245 if (!filter->lumH || !filter->lumV || !filter->chrH || !filter->chrV)
2246 goto fail;
2247
2248 if (chromaSharpen != 0.0) {
2250 if (!id)
2251 goto fail;
2252 sws_scaleVec(filter->chrH, -chromaSharpen);
2253 sws_scaleVec(filter->chrV, -chromaSharpen);
2254 sws_addVec(filter->chrH, id);
2255 sws_addVec(filter->chrV, id);
2256 sws_freeVec(id);
2257 }
2258
2259 if (lumaSharpen != 0.0) {
2261 if (!id)
2262 goto fail;
2263 sws_scaleVec(filter->lumH, -lumaSharpen);
2264 sws_scaleVec(filter->lumV, -lumaSharpen);
2265 sws_addVec(filter->lumH, id);
2266 sws_addVec(filter->lumV, id);
2267 sws_freeVec(id);
2268 }
2269
2270 if (chromaHShift != 0.0)
2271 sws_shiftVec(filter->chrH, (int)(chromaHShift + 0.5));
2272
2273 if (chromaVShift != 0.0)
2274 sws_shiftVec(filter->chrV, (int)(chromaVShift + 0.5));
2275
2276 sws_normalizeVec(filter->chrH, 1.0);
2277 sws_normalizeVec(filter->chrV, 1.0);
2278 sws_normalizeVec(filter->lumH, 1.0);
2279 sws_normalizeVec(filter->lumV, 1.0);
2280
2281 if (isnan_vec(filter->chrH) ||
2282 isnan_vec(filter->chrV) ||
2283 isnan_vec(filter->lumH) ||
2284 isnan_vec(filter->lumV))
2285 goto fail;
2286
2287 if (verbose)
2289 if (verbose)
2291
2292 return filter;
2293
2294fail:
2295 sws_freeVec(filter->lumH);
2296 sws_freeVec(filter->lumV);
2297 sws_freeVec(filter->chrH);
2298 sws_freeVec(filter->chrV);
2299 av_freep(&filter);
2300 return NULL;
2301}
2302
2304{
2305 SwsInternal *c = sws_internal(sws);
2306 int i;
2307 if (!c)
2308 return;
2309
2310 av_refstruct_unref(&c->hw_priv);
2311
2312 for (i = 0; i < FF_ARRAY_ELEMS(c->graph); i++)
2313 ff_sws_graph_free(&c->graph[i]);
2314 ff_frame_pool_uninit(&c->frame_pool);
2315
2316 for (i = 0; i < c->nb_slice_ctx; i++)
2317 sws_freeContext(c->slice_ctx[i]);
2318 av_freep(&c->slice_ctx);
2319
2320 avpriv_slicethread_free(&c->slicethread);
2321
2322 for (i = 0; i < 4; i++)
2323 av_freep(&c->dither_error[i]);
2324
2325 av_frame_free(&c->frame_src);
2326 av_frame_free(&c->frame_dst);
2327
2328 av_freep(&c->src_ranges.ranges);
2329
2330 av_freep(&c->vLumFilter);
2331 av_freep(&c->vChrFilter);
2332 av_freep(&c->hLumFilter);
2333 av_freep(&c->hChrFilter);
2334#if HAVE_ALTIVEC
2336#endif
2337
2338 av_freep(&c->vLumFilterPos);
2339 av_freep(&c->vChrFilterPos);
2340 av_freep(&c->hLumFilterPos);
2341 av_freep(&c->hChrFilterPos);
2342
2343#if HAVE_MMX_INLINE
2344 ff_sws_jit_free(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize);
2345 ff_sws_jit_free(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize);
2346 c->lumMmxextFilterCode = NULL;
2347 c->chrMmxextFilterCode = NULL;
2348#endif /* HAVE_MMX_INLINE */
2349
2350 av_freep(&c->yuvTable);
2351 av_freep(&c->formatConvBuffer);
2352
2353 sws_freeContext(c->cascaded_context[0]);
2354 sws_freeContext(c->cascaded_context[1]);
2355 sws_freeContext(c->cascaded_context[2]);
2356 memset(c->cascaded_context, 0, sizeof(c->cascaded_context));
2357 av_freep(&c->cascaded_tmp[0][0]);
2358 av_freep(&c->cascaded_tmp[1][0]);
2359
2360 av_freep(&c->gamma);
2361 av_freep(&c->inv_gamma);
2362#if CONFIG_SMALL
2363 av_freep(&c->xyz2rgb.gamma.in);
2364#endif
2365
2366 av_freep(&c->rgb0_scratch);
2367 av_freep(&c->xyz_scratch);
2368
2370
2371 av_free(c);
2372}
2373
2375{
2376 SwsContext *ctx = *pctx;
2377 if (!ctx)
2378 return;
2379
2381 *pctx = NULL;
2382}
2383
2385 int srcH, enum AVPixelFormat srcFormat,
2386 int dstW, int dstH,
2387 enum AVPixelFormat dstFormat, int flags,
2388 SwsFilter *srcFilter,
2389 SwsFilter *dstFilter,
2390 const double *param)
2391{
2392 SwsContext *sws;
2393 static const double default_param[2] = { SWS_PARAM_DEFAULT,
2395
2396 if (!param)
2397 param = default_param;
2398
2399 if (prev && (prev->src_w == srcW &&
2400 prev->src_h == srcH &&
2401 prev->src_format == srcFormat &&
2402 prev->dst_w == dstW &&
2403 prev->dst_h == dstH &&
2404 prev->dst_format == dstFormat &&
2405 prev->flags == flags &&
2406 !memcmp(prev->scaler_params, param,
2407 sizeof(prev->scaler_params)))) {
2408 return prev;
2409 }
2410
2411 if (!(sws = sws_alloc_context())) {
2412 sws_free_context(&prev);
2413 return NULL;
2414 }
2415
2416 if (prev) {
2417 av_opt_copy(sws, prev);
2418 sws_free_context(&prev);
2419 }
2420
2421 sws->src_w = srcW;
2422 sws->src_h = srcH;
2423 sws->src_format = srcFormat;
2424 sws->dst_w = dstW;
2425 sws->dst_h = dstH;
2426 sws->dst_format = dstFormat;
2427 sws->flags = flags;
2428 for (int i = 0; i < SWS_NUM_SCALER_PARAMS; i++)
2429 sws->scaler_params[i] = param[i];
2430
2431 if (sws_init_context(sws, srcFilter, dstFilter) < 0)
2432 sws_free_context(&sws);
2433
2434 return sws;
2435}
2436
2437int ff_range_add(RangeList *rl, unsigned int start, unsigned int len)
2438{
2439 Range *tmp;
2440 unsigned int idx;
2441
2442 /* find the first existing range after the new one */
2443 for (idx = 0; idx < rl->nb_ranges; idx++)
2444 if (rl->ranges[idx].start > start)
2445 break;
2446
2447 /* check for overlap */
2448 if (idx > 0) {
2449 Range *prev = &rl->ranges[idx - 1];
2450 if (prev->start + prev->len > start)
2451 return AVERROR(EINVAL);
2452 }
2453 if (idx < rl->nb_ranges) {
2454 Range *next = &rl->ranges[idx];
2455 if (start + len > next->start)
2456 return AVERROR(EINVAL);
2457 }
2458
2460 (rl->nb_ranges + 1) * sizeof(*rl->ranges));
2461 if (!tmp)
2462 return AVERROR(ENOMEM);
2463 rl->ranges = tmp;
2464
2465 memmove(rl->ranges + idx + 1, rl->ranges + idx,
2466 sizeof(*rl->ranges) * (rl->nb_ranges - idx));
2467 rl->ranges[idx].start = start;
2468 rl->ranges[idx].len = len;
2469 rl->nb_ranges++;
2470
2471 /* merge ranges */
2472 if (idx > 0) {
2473 Range *prev = &rl->ranges[idx - 1];
2474 Range *cur = &rl->ranges[idx];
2475 if (prev->start + prev->len == cur->start) {
2476 prev->len += cur->len;
2477 memmove(rl->ranges + idx - 1, rl->ranges + idx,
2478 sizeof(*rl->ranges) * (rl->nb_ranges - idx));
2479 rl->nb_ranges--;
2480 idx--;
2481 }
2482 }
2483 if (idx < rl->nb_ranges - 1) {
2484 Range *cur = &rl->ranges[idx];
2485 Range *next = &rl->ranges[idx + 1];
2486 if (cur->start + cur->len == next->start) {
2487 cur->len += next->len;
2488 memmove(rl->ranges + idx, rl->ranges + idx + 1,
2489 sizeof(*rl->ranges) * (rl->nb_ranges - idx - 1));
2490 rl->nb_ranges--;
2491 }
2492 }
2493
2494 return 0;
2495}
2496
2497int ff_sws_thread_exec(void *priv,
2498 int (*func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads),
2499 int nb_threads, int nb_jobs)
2500{
2501 AVSliceThread *slicethread;
2502 int ret = avpriv_slicethread_create2(&slicethread, priv, func, NULL, nb_threads);
2503 if (ret == AVERROR(ENOSYS)) {
2504 /* Fallback for build configurations without threading */
2505 for (int i = 0; i < nb_jobs; i++) {
2506 int ret = func(priv, i, 0, nb_jobs, 1);
2507 if (ret)
2508 return ret;
2509 }
2510 return 0;
2511 } else if (ret < 0) {
2512 return ret;
2513 }
2514
2515 ret = avpriv_slicethread_execute2(slicethread, nb_jobs, 0);
2516 avpriv_slicethread_free(&slicethread);
2517 return ret;
2518}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
static const char *const format[]
Definition af_aiir.c:445
#define MAX_FILTER_SIZE
int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
Definition alphablend.c:23
static AVFormatContext * ctx
#define A(x)
Definition vpx_arith.h:28
int32_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition avassert.h:68
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define V
Definition avdct.c:32
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
#define flag(name)
Definition cbs_h264.c:60
#define ub(width, name)
Definition cbs_h264.c:95
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static IPT saturation(const CmsCtx *ctx, IPT ipt)
Definition cms.c:559
#define AV_CEIL_RSHIFT(a, b)
Definition common.h:60
#define ROUNDED_DIV(a, b)
Definition common.h:58
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
Colorspace value utility functions for libavutil.
static __device__ float ceil(float a)
#define min(a, b)
#define max(a, b)
#define emms_c()
Definition emms.h:88
int8_t exp
Definition eval.c:76
void ff_sws_graph_free(SwsGraph **pgraph)
Uninitialize any state associate with this filter graph and free it.
Definition graph.c:948
#define fail
Definition test.h:479
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition error.h:73
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:601
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
int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of a plane of an image with...
Definition imgutils.c:289
void sws_freeFilter(SwsFilter *filter)
Definition utils.c:2208
#define SWS_CS_DEFAULT
Definition swscale.h:464
int sws_getColorspaceDetails(SwsContext *sws, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation)
Definition utils.c:1026
av_cold int sws_init_context(SwsContext *sws, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition utils.c:1937
#define SWS_SRC_V_CHR_DROP_MASK
Definition swscale.h:453
void sws_freeVec(SwsVector *a)
Definition utils.c:2199
SwsFilter * sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, float lumaSharpen, float chromaSharpen, float chromaHShift, float chromaVShift, int verbose)
Definition utils.c:2220
int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
Definition format.c:299
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition utils.c:1051
void sws_free_context(SwsContext **pctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
Definition utils.c:2374
#define SWS_SRC_V_CHR_DROP_SHIFT
Definition swscale.h:454
SwsVector * sws_allocVec(int length)
Allocate and return an uninitialized vector with length coefficients.
Definition utils.c:2009
SwsVector * sws_getGaussianVec(double variance, double quality)
Return a normalized Gaussian curve used to filter stuff quality = 3 is high quality,...
Definition utils.c:2026
SwsContext * sws_getCachedContext(SwsContext *prev, int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
Check if context can be reused, otherwise reallocate a new one.
Definition utils.c:2384
SwsBackend
Definition swscale.h:110
void sws_normalizeVec(SwsVector *a, double height)
Scale all the coefficients of a so that their sum equals height.
Definition utils.c:2100
#define SWS_MAX_REDUCE_CUTOFF
Filter kernel cut-off value.
Definition swscale.h:447
SwsContext * sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
Allocate and return an SwsContext.
Definition utils.c:1972
#define SWS_PARAM_DEFAULT
Definition swscale.h:456
SwsScaler
Definition swscale.h:96
void sws_freeContext(SwsContext *sws)
Free the swscaler context swsContext.
Definition utils.c:2303
void sws_scaleVec(SwsVector *a, double scalar)
Scale all the coefficients of a by the scalar value.
Definition utils.c:2092
int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation)
Definition utils.c:866
@ SWS_DITHER_ED
Definition swscale.h:81
@ SWS_DITHER_A_DITHER
Definition swscale.h:82
@ SWS_DITHER_X_DITHER
Definition swscale.h:83
@ SWS_DITHER_AUTO
Definition swscale.h:79
@ SWS_DITHER_BAYER
Definition swscale.h:80
@ SWS_DITHER_NONE
Definition swscale.h:78
@ SWS_ALPHA_BLEND_NONE
Definition swscale.h:89
@ SWS_BACKEND_UNSTABLE
Definition swscale.h:121
@ SWS_BACKEND_STABLE
Definition swscale.h:113
@ SWS_SCALE_SPLINE
unwindowned natural cubic spline
Definition swscale.h:105
@ SWS_SCALE_POINT
nearest neighbor (point sampling)
Definition swscale.h:100
@ SWS_SCALE_LANCZOS
3-tap sinc/sinc
Definition swscale.h:104
@ SWS_SCALE_BILINEAR
bilinear filtering
Definition swscale.h:98
@ SWS_SCALE_GAUSSIAN
2-tap gaussian approximation
Definition swscale.h:102
@ SWS_SCALE_BICUBIC
2-tap cubic BC-spline
Definition swscale.h:99
@ SWS_SCALE_AREA
area averaging
Definition swscale.h:101
@ SWS_SCALE_SINC
unwindowed sinc
Definition swscale.h:103
@ SWS_SCALE_AUTO
Definition swscale.h:97
@ SWS_PRINT_INFO
Emit verbose log of scaling parameters.
Definition swscale.h:141
@ SWS_SPLINE
unwindowed natural cubic spline
Definition swscale.h:207
@ SWS_BICUBIC
2-tap cubic B-spline
Definition swscale.h:199
@ SWS_BITEXACT
Definition swscale.h:178
@ SWS_AREA
area averaging
Definition swscale.h:202
@ SWS_BICUBLIN
bicubic luma, bilinear chroma
Definition swscale.h:203
@ SWS_ERROR_DIFFUSION
Set SwsContext.dither instead.
Definition swscale.h:191
@ SWS_BILINEAR
bilinear filtering
Definition swscale.h:198
@ SWS_UNSTABLE
Allow/prefer using experimental new code paths.
Definition swscale.h:185
@ SWS_FULL_CHR_H_INP
Perform full chroma interpolation when downscaling RGB sources.
Definition swscale.h:167
@ SWS_SINC
unwindowed sinc
Definition swscale.h:205
@ SWS_LANCZOS
3-tap sinc/sinc
Definition swscale.h:206
@ SWS_GAUSS
gaussian approximation
Definition swscale.h:204
@ SWS_FAST_BILINEAR
Scaler selection options.
Definition swscale.h:197
@ SWS_ACCURATE_RND
Force bit-exact output.
Definition swscale.h:177
@ SWS_X
experimental
Definition swscale.h:200
@ SWS_POINT
nearest neighbor
Definition swscale.h:201
@ SWS_FULL_CHR_H_INT
Perform full chroma upsampling when upscaling to RGB.
Definition swscale.h:154
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition opt.c:1758
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition opt.c:2226
int a
#define B
Definition huffyuv.h:42
const VDPAUPixFmtMap * map
misc image utilities
#define b
Definition input.c:43
#define av_log2
Definition intmath.h:84
#define AV_WL16(p, v)
void * ff_sws_jit_alloc(size_t size)
Definition jit.c:89
void ff_sws_jit_free(void *ptr, size_t size)
Definition jit.c:99
int ff_sws_jit_protect(void *ptr, size_t size)
Definition jit.c:94
#define W(a, i, v)
Definition jpegls.h:119
#define ONE
Definition jrevdct.c:137
#define C
static int shift(int a, int b)
Definition bonk.c:261
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition jacosubdec.c:66
const char * from
Definition jacosubdec.c:64
const char * to
Definition webvttdec.c:36
av_cold void ff_frame_pool_uninit(FFFramePool *pool)
Deallocate the frame pool.
Definition framepool.c:215
#define have_neon(flags)
Definition cpu.h:26
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
static atomic_int cpu_flags
Definition cpu.c:56
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition cpu.c:109
#define AV_CPU_FLAG_SLOW_GATHER
CPU has slow gathers.
Definition cpu.h:62
#define AV_CPU_FLAG_MMX
standard MMX
Definition cpu.h:32
#define FF_ALLOC_TYPED_ARRAY(p, nelem)
Definition internal.h:80
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem)
Definition internal.h:81
#define have_lsx(flags)
Definition cpu.h:28
#define have_lasx(flags)
Definition cpu.h:29
#define PPC_ALTIVEC(flags)
Definition cpu.h:25
#define AVOnce
Definition thread.h:202
static int ff_thread_once(char *control, void(*routine)(void))
Definition thread.h:205
#define AV_ONCE_INIT
Definition thread.h:203
#define EXTERNAL_AVX2_FAST(flags)
Definition cpu.h:73
#define X86_MMX(flags)
Definition cpu.h:25
#define INLINE_MMXEXT(flags)
Definition cpu.h:81
#define INLINE_MMX(flags)
Definition cpu.h:80
const AVClass ff_sws_context_class
Definition options.c:124
static av_cold int get_center_offset(SwsInternal *s, int chr_subsample, int pos, int dir)
Definition utils.c:189
static SwsVector * sws_getConstVec(double c, int length)
Allocate and return a vector with length coefficients, all with the same value c.
Definition utils.c:2057
static int handle_0alpha(int *format)
Definition utils.c:828
static int handle_xyz(int *format)
Definition utils.c:839
static SwsVector * sws_getIdentityVec(void)
Allocate and return a vector with just one coefficient, with value 1.0.
Definition utils.c:2076
static enum AVPixelFormat alphaless_fmt(enum AVPixelFormat fmt)
Definition utils.c:1079
static SwsVector * sws_sumVec(SwsVector *a, SwsVector *b)
Definition utils.c:2105
int ff_shuffle_filter_coefficients(SwsInternal *c, int *filterPos, int filterSize, int16_t *filter, int dstW)
Definition utils.c:109
av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter, SwsFilter *dstFilter)
Definition utils.c:1156
static SwsContext * alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, const double *param)
Allocate and return an SwsContext without performing initialization.
Definition utils.c:74
static uint16_t * alloc_gamma_tbl(double e)
Definition utils.c:1065
static av_cold void init_xyz_tables(void)
Definition utils.c:731
static void set_cascade_chr_pos(SwsContext *cascade, const SwsContext *sws, int src, int dst)
Definition utils.c:96
static const ScaleAlgorithm scale_algorithms[]
Definition utils.c:200
static int context_init_threaded(SwsContext *sws, SwsFilter *src_filter, SwsFilter *dst_filter)
Definition utils.c:1890
static void sws_addVec(SwsVector *a, SwsVector *b)
Definition utils.c:2155
static int handle_formats(SwsContext *sws)
Definition utils.c:848
static double getSplineCoeff(double a, double b, double c, double d, double dist)
Definition utils.c:167
static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, int *outFilterSize, int xInc, int srcW, int dstW, int filterAlign, int one, int scaler, int flags, int cpu_flags, SwsVector *srcFilter, SwsVector *dstFilter, double param[SWS_NUM_SCALER_PARAMS], int srcPos, int dstPos)
Definition utils.c:214
SwsBackend ff_sws_enabled_backends(const SwsContext *ctx)
Definition utils.c:59
static uint16_t xyzgammainv_tab[65536]
Definition utils.c:730
int ff_sws_thread_exec(void *priv, int(*func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), int nb_threads, int nb_jobs)
Helper for dispatching a single function across multiple threads.
Definition utils.c:2497
static uint16_t xyzgamma_tab[4096]
Definition utils.c:729
static int handle_jpeg(int *format)
Definition utils.c:790
static void makenan_vec(SwsVector *a)
Definition utils.c:2002
static double sws_dcVec(SwsVector *a)
Definition utils.c:2081
static int isnan_vec(SwsVector *a)
Definition utils.c:1993
static void sws_shiftVec(SwsVector *a, int shift)
Definition utils.c:2141
static av_cold int get_local_pos(SwsInternal *s, int chr_subsample, int pos, int dir)
Definition utils.c:180
av_cold int ff_sws_fill_xyztables(SwsInternal *c)
Definition utils.c:752
static uint16_t rgbgammainv_tab[4096]
Definition utils.c:729
static int scaler_flag(SwsScaler scaler, int fallback)
Definition utils.c:1140
int ff_range_add(RangeList *rl, unsigned int start, unsigned int len)
Definition utils.c:2437
static SwsVector * sws_getShiftedVec(SwsVector *a, int shift)
Definition utils.c:2123
static void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
Print with av_log() a textual representation of the vector a if log_level <= av_log_level.
Definition utils.c:2173
static uint16_t rgbgamma_tab[65536]
Definition utils.c:730
static void fill_rgb2yuv_table(SwsInternal *c, const int table[4], int dstRange)
Definition utils.c:631
static int range_override_needed(enum AVPixelFormat format)
Definition utils.c:861
#define FFSWAP(type, a, b)
Definition macros.h:52
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
#define NAN
#define M_PI
Definition mathematics.h:67
enum AVColorRange range
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
static const uint64_t c2
Definition murmur3.c:53
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
#define sws_isSupportedOutput(x)
#define sws_isSupportedInput(x)
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition pixdesc.c:3512
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition pixdesc.c:3436
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3404
enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt)
Utility function to swap the endianness of a pixel format.
Definition pixdesc.c:3539
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
#define AV_PIX_FMT_YUV420P16
Definition pixfmt.h:559
#define AV_PIX_FMT_YUV444P9
Definition pixfmt.h:547
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:548
#define AV_PIX_FMT_YUV422P9
Definition pixfmt.h:546
#define AV_PIX_FMT_BGR555
Definition pixfmt.h:541
#define AV_PIX_FMT_BGR48
Definition pixfmt.h:539
#define AV_PIX_FMT_GBRP10
Definition pixfmt.h:567
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:549
#define AV_PIX_FMT_GBRP12
Definition pixfmt.h:568
#define AV_PIX_FMT_YUV420P9
Definition pixfmt.h:545
#define AV_PIX_FMT_RGB48
Definition pixfmt.h:534
#define AV_PIX_FMT_GRAYF32
Definition pixfmt.h:591
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
Definition pixfmt.h:104
@ AV_PIX_FMT_XYZ12LE
packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as lit...
Definition pixfmt.h:196
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ AV_PIX_FMT_GRAY10LE
Y , 10bpp, little-endian.
Definition pixfmt.h:321
@ AV_PIX_FMT_GBRP10BE
planar GBR 4:4:4 30bpp, big-endian
Definition pixfmt.h:169
@ AV_PIX_FMT_YA16BE
16 bits gray, 16 bits alpha (big-endian)
Definition pixfmt.h:209
@ AV_PIX_FMT_YUVA420P9BE
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian
Definition pixfmt.h:175
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition pixfmt.h:106
@ AV_PIX_FMT_GBRPF16BE
IEEE-754 half precision planer GBR 4:4:4, 48bpp, big-endian.
Definition pixfmt.h:466
@ AV_PIX_FMT_GBRPF32BE
IEEE-754 single precision planar GBR 4:4:4, 96bpp, big-endian.
Definition pixfmt.h:341
@ AV_PIX_FMT_YUVA444P9LE
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
Definition pixfmt.h:180
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition pixfmt.h:265
@ AV_PIX_FMT_YUVA444P10LE
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition pixfmt.h:186
@ AV_PIX_FMT_GBRP9LE
planar GBR 4:4:4 27bpp, little-endian
Definition pixfmt.h:168
@ AV_PIX_FMT_GBRP10MSBBE
planar GBR 4:4:4 30bpp, lowest bits zero, big-endian
Definition pixfmt.h:495
@ AV_PIX_FMT_YUVA420P10BE
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
Definition pixfmt.h:181
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition pixfmt.h:99
@ AV_PIX_FMT_GBRP12BE
planar GBR 4:4:4 36bpp, big-endian
Definition pixfmt.h:279
@ AV_PIX_FMT_YUVA422P9LE
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian
Definition pixfmt.h:178
@ AV_PIX_FMT_GRAY12LE
Y , 12bpp, little-endian.
Definition pixfmt.h:319
@ AV_PIX_FMT_GBRAP12BE
planar GBR 4:4:4:4 48bpp, big-endian
Definition pixfmt.h:310
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition pixfmt.h:102
@ AV_PIX_FMT_GRAY12BE
Y , 12bpp, big-endian.
Definition pixfmt.h:318
@ AV_PIX_FMT_X2BGR10LE
packed BGR 10:10:10, 30bpp, (msb)2X 10B 10G 10R(lsb), little-endian, X=unused/undefined
Definition pixfmt.h:386
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_BGR48BE
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big...
Definition pixfmt.h:145
@ AV_PIX_FMT_YA16LE
16 bits gray, 16 bits alpha (little-endian)
Definition pixfmt.h:210
@ AV_PIX_FMT_YUVA420P10LE
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition pixfmt.h:182
@ AV_PIX_FMT_GRAY14LE
Y , 14bpp, little-endian.
Definition pixfmt.h:361
@ AV_PIX_FMT_RGB48BE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition pixfmt.h:109
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition pixfmt.h:101
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition pixfmt.h:108
@ AV_PIX_FMT_YUVA422P10LE
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition pixfmt.h:184
@ AV_PIX_FMT_GBRPF16LE
IEEE-754 half precision planer GBR 4:4:4, 48bpp, little-endian.
Definition pixfmt.h:467
@ 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
@ AV_PIX_FMT_RGBA64BE
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition pixfmt.h:202
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)3R 3G 2B(lsb)
Definition pixfmt.h:93
@ AV_PIX_FMT_GBRAP14BE
planar GBR 4:4:4:4 56bpp, big-endian
Definition pixfmt.h:432
@ AV_PIX_FMT_RGBA64LE
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition pixfmt.h:203
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition pixfmt.h:264
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition pixfmt.h:80
@ AV_PIX_FMT_GBRAP16BE
planar GBRA 4:4:4:4 64bpp, big-endian
Definition pixfmt.h:213
@ AV_PIX_FMT_GBRPF32LE
IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian.
Definition pixfmt.h:342
@ AV_PIX_FMT_YUVA444P9BE
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian
Definition pixfmt.h:179
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition pixfmt.h:90
@ AV_PIX_FMT_RGB444LE
packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), little-endian, X=unused/undefined
Definition pixfmt.h:136
@ AV_PIX_FMT_GBRP10MSBLE
planar GBR 4:4:4 30bpp, lowest bits zero, little-endian
Definition pixfmt.h:496
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition pixfmt.h:95
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition pixfmt.h:92
@ AV_PIX_FMT_YUVA420P9LE
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian
Definition pixfmt.h:176
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition pixfmt.h:100
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_XYZ12BE
packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big...
Definition pixfmt.h:197
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition pixfmt.h:174
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition pixfmt.h:283
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition pixfmt.h:212
@ AV_PIX_FMT_GBRP12LE
planar GBR 4:4:4 36bpp, little-endian
Definition pixfmt.h:280
@ AV_PIX_FMT_GRAY9BE
Y , 9bpp, big-endian.
Definition pixfmt.h:338
@ AV_PIX_FMT_YUVA444P16LE
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition pixfmt.h:192
@ AV_PIX_FMT_YUVA422P10BE
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
Definition pixfmt.h:183
@ AV_PIX_FMT_YUVA422P16BE
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
Definition pixfmt.h:189
@ AV_PIX_FMT_BGRA64BE
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition pixfmt.h:204
@ AV_PIX_FMT_GBRP16BE
planar GBR 4:4:4 48bpp, big-endian
Definition pixfmt.h:171
@ AV_PIX_FMT_GBRAP12LE
planar GBR 4:4:4:4 48bpp, little-endian
Definition pixfmt.h:311
@ AV_PIX_FMT_GBRP9BE
planar GBR 4:4:4 27bpp, big-endian
Definition pixfmt.h:167
@ AV_PIX_FMT_YUVA420P16LE
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition pixfmt.h:188
@ AV_PIX_FMT_BGR444BE
packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), big-endian, X=unused/undefined
Definition pixfmt.h:139
@ AV_PIX_FMT_RGB48LE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition pixfmt.h:110
@ AV_PIX_FMT_GBRAPF32BE
IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian.
Definition pixfmt.h:343
@ AV_PIX_FMT_GBRP12MSBLE
planar GBR 4:4:4 36bpp, lowest bits zero, little-endian
Definition pixfmt.h:498
@ AV_PIX_FMT_BGR444LE
packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), little-endian, X=unused/undefined
Definition pixfmt.h:138
@ AV_PIX_FMT_YUVA420P16BE
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
Definition pixfmt.h:187
@ AV_PIX_FMT_X2RGB10LE
packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined
Definition pixfmt.h:384
@ 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
@ AV_PIX_FMT_GBRAPF32LE
IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian.
Definition pixfmt.h:344
@ AV_PIX_FMT_GBRAP14LE
planar GBR 4:4:4:4 56bpp, little-endian
Definition pixfmt.h:433
@ AV_PIX_FMT_RGB444BE
packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), big-endian, X=unused/undefined
Definition pixfmt.h:137
@ AV_PIX_FMT_BGR48LE
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as lit...
Definition pixfmt.h:146
@ AV_PIX_FMT_GBRP14LE
planar GBR 4:4:4 42bpp, little-endian
Definition pixfmt.h:282
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition pixfmt.h:263
@ AV_PIX_FMT_GRAY16LE
Y , 16bpp, little-endian.
Definition pixfmt.h:105
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition pixfmt.h:173
@ AV_PIX_FMT_GBRP10LE
planar GBR 4:4:4 30bpp, little-endian
Definition pixfmt.h:170
@ AV_PIX_FMT_GBRAP10BE
planar GBR 4:4:4:4 40bpp, big-endian
Definition pixfmt.h:313
@ AV_PIX_FMT_GBRAPF16BE
IEEE-754 half precision planar GBRA 4:4:4:4, 64bpp, big-endian.
Definition pixfmt.h:468
@ AV_PIX_FMT_BGRA64LE
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition pixfmt.h:205
@ AV_PIX_FMT_GBRAP10LE
planar GBR 4:4:4:4 40bpp, little-endian
Definition pixfmt.h:314
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition pixfmt.h:84
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
@ AV_PIX_FMT_GRAY9LE
Y , 9bpp, little-endian.
Definition pixfmt.h:339
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition pixfmt.h:165
@ AV_PIX_FMT_GBRAP16LE
planar GBRA 4:4:4:4 64bpp, little-endian
Definition pixfmt.h:214
@ AV_PIX_FMT_GBRAPF16LE
IEEE-754 half precision planar GBRA 4:4:4:4, 64bpp, little-endian.
Definition pixfmt.h:469
@ AV_PIX_FMT_GRAY10BE
Y , 10bpp, big-endian.
Definition pixfmt.h:320
@ AV_PIX_FMT_YUVA444P10BE
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
Definition pixfmt.h:185
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition pixfmt.h:140
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition pixfmt.h:262
@ AV_PIX_FMT_GRAY14BE
Y , 14bpp, big-endian.
Definition pixfmt.h:360
@ AV_PIX_FMT_GBRP14BE
planar GBR 4:4:4 42bpp, big-endian
Definition pixfmt.h:281
@ 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
@ AV_PIX_FMT_YUVA444P16BE
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
Definition pixfmt.h:191
@ AV_PIX_FMT_YUVA422P16LE
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition pixfmt.h:190
@ AV_PIX_FMT_GBRP16LE
planar GBR 4:4:4 48bpp, little-endian
Definition pixfmt.h:172
@ AV_PIX_FMT_YUVA422P9BE
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian
Definition pixfmt.h:177
@ AV_PIX_FMT_RGB4
packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in ...
Definition pixfmt.h:94
@ AV_PIX_FMT_BGR4
packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in ...
Definition pixfmt.h:91
@ 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
@ AV_PIX_FMT_GBRP12MSBBE
planar GBR 4:4:4 36bpp, lowest bits zero, big-endian
Definition pixfmt.h:497
#define AV_PIX_FMT_BGR565
Definition pixfmt.h:540
#define AV_PIX_FMT_YUV422P16
Definition pixfmt.h:560
#define AV_PIX_FMT_BGRA64
Definition pixfmt.h:543
#define AV_PIX_FMT_GRAY16
Definition pixfmt.h:531
#define AV_PIX_FMT_GBRP16
Definition pixfmt.h:570
#define AV_PIX_FMT_GBRP14
Definition pixfmt.h:569
#define AV_PIX_FMT_YUV444P16
Definition pixfmt.h:561
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:551
static const uint16_t table[]
Definition prosumer.c:203
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:121
av_cold void ff_sws_rgb2rgb_init(void)
Definition rgb2rgb.c:127
#define FF_ARRAY_ELEMS(a)
int ff_free_filters(SwsInternal *c)
Definition slice.c:386
int ff_init_filters(SwsInternal *c)
Definition slice.c:246
void avpriv_slicethread_free(AVSliceThread **pctx)
Destroy slice threading context.
int avpriv_slicethread_execute2(AVSliceThread *ctx, int nb_jobs, int execute_main)
Execute slice threading.
int avpriv_slicethread_create2(AVSliceThread **pctx, void *priv, int(*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), int(*main_func)(void *priv), int nb_threads)
Create slice threading context.
struct AVSliceThread AVSliceThread
Definition slicethread.h:25
unsigned int pos
Definition spdifenc.c:431
#define atomic_init(obj, value)
Definition stdatomic.h:119
Describe the class of an AVClass context structure.
Definition log.h:76
int depth
Number of bits in the component.
Definition pixdesc.h:57
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition pixdesc.h:105
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition pixdesc.h:80
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition pixdesc.h:89
unsigned int nb_ranges
AVRational start
unsigned int len
int flag
flag associated to the algorithm
Definition utils.c:195
int size_factor
size factor used when initing the filters
Definition utils.c:197
const char * description
human-readable description
Definition utils.c:196
Main external API structure.
Definition swscale.h:227
int src_h
Width and height of the source frame.
Definition swscale.h:272
int dst_format
Destination pixel format.
Definition swscale.h:275
int gamma_flag
Use gamma correct scaling.
Definition swscale.h:264
int threads
How many threads to use for processing, or 0 for automatic selection.
Definition swscale.h:249
SwsScaler scaler
Scaling filter.
Definition swscale.h:294
int dst_h
Width and height of the destination frame.
Definition swscale.h:273
SwsAlphaBlend alpha_blend
Alpha blending mode.
Definition swscale.h:259
double scaler_params[SWS_NUM_SCALER_PARAMS]
Definition swscale.h:244
int dst_w
Definition swscale.h:273
int dst_h_chr_pos
Destination horizontal chroma position.
Definition swscale.h:281
SwsScaler scaler_sub
Scaler used specifically for up/downsampling subsampled (chroma) planes.
Definition swscale.h:302
int src_w
Deprecated frame property overrides, for the legacy API only.
Definition swscale.h:272
int src_format
Source pixel format.
Definition swscale.h:274
int src_v_chr_pos
Source vertical chroma position in luma grid / 256.
Definition swscale.h:278
int dst_v_chr_pos
Destination vertical chroma position.
Definition swscale.h:280
SwsDither dither
Dither mode.
Definition swscale.h:254
int dst_range
Destination is full range.
Definition swscale.h:277
unsigned flags
Bitmask of SWS_*.
Definition swscale.h:238
int src_range
Source is full range.
Definition swscale.h:276
int src_h_chr_pos
Source horizontal chroma position.
Definition swscale.h:279
SwsVector * chrV
Definition swscale.h:488
SwsVector * lumH
Definition swscale.h:485
SwsVector * lumV
Definition swscale.h:486
SwsVector * chrH
Definition swscale.h:487
SwsContext * parent
double * coeff
pointer to the list of coefficients
Definition swscale.h:479
int length
number of coefficients in the vector
Definition swscale.h:480
void ff_sws_init_scale(SwsInternal *c)
Definition swscale.c:697
int ff_sws_slice_worker(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
Definition swscale.c:1663
av_cold void ff_sws_init_range_convert(SwsInternal *c)
Definition swscale.c:626
external API header
#define SWS_NUM_SCALER_PARAMS
Extra parameters for fine-tuning certain scalers.
Definition swscale.h:243
#define SWSINTERNAL_ADDITIONAL_ASM_SIZE
#define APCK_SIZE
static av_always_inline int isBayer(enum AVPixelFormat pix_fmt)
#define BU_IDX
#define RV_IDX
int ff_init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode, int16_t *filter, int32_t *filterPos, int numSplits)
static av_always_inline int isFloat(enum AVPixelFormat pix_fmt)
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
#define RY_IDX
#define BV_IDX
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
#define GV_IDX
#define RETCODE_USE_CASCADE
#define XYZ_GAMMA
static av_always_inline int isGray(enum AVPixelFormat pix_fmt)
static SwsInternal * sws_internal(const SwsContext *sws)
#define GU_IDX
void ff_get_unscaled_swscale(SwsInternal *c)
Set c->convert_unscaled to an unscaled converter if one exists for the specific source and destinatio...
int ff_sws_init_altivec_bufs(SwsInternal *c)
#define BY_IDX
#define RGB_GAMMA
void ff_sws_free_altivec_bufs(SwsInternal *c)
static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
#define GY_IDX
static av_always_inline int isPlanarRGB(enum AVPixelFormat pix_fmt)
int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation)
#define RU_IDX
#define RGB2YUV_SHIFT
static av_always_inline int isBayer16BPS(enum AVPixelFormat pix_fmt)
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
const int32_t ff_yuv2rgb_coeffs[11][4]
Definition yuv2rgb.c:47
static av_always_inline int isYUV(enum AVPixelFormat pix_fmt)
#define lrint
Definition tablegen.h:53
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static void error(const char *err)
static uint8_t tmp[40]
Definition aes_ctr.c:52
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
#define src
Definition vp8dsp.c:248
#define height
Definition dsp.h:99
#define Z
Definition uops_tmpl.h:88
static const double coeff[2][5]
static const uint8_t quality[]
Definition vmixdec.c:58
int len
static double c[64]
av_cold void ff_yuv2rgb_init_tables_ppc(SwsInternal *c, const int inv_table[4], int brightness, int contrast, int saturation)