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