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