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