FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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][4] = {
725  {13270, -6295, -2041},
726  {-3969, 7682, 170},
727  { 228, -835, 4329} };
728  static const int16_t rgb2xyz_matrix[3][4] = {
729  {1689, 1464, 739},
730  { 871, 2929, 296},
731  { 79, 488, 3891} };
732 
733  if (c->xyzgamma)
734  return 0;
735 
736  memcpy(c->xyz2rgb_matrix, xyz2rgb_matrix, sizeof(c->xyz2rgb_matrix));
737  memcpy(c->rgb2xyz_matrix, rgb2xyz_matrix, sizeof(c->rgb2xyz_matrix));
738 
739 #if CONFIG_SMALL
740  c->xyzgamma = av_malloc(sizeof(uint16_t) * 2 * (4096 + 65536));
741  if (!c->xyzgamma)
742  return AVERROR(ENOMEM);
743  c->rgbgammainv = c->xyzgamma + 4096;
744  c->rgbgamma = c->rgbgammainv + 4096;
745  c->xyzgammainv = c->rgbgamma + 65536;
746  init_xyz_tables(c->xyzgamma, c->xyzgammainv, c->rgbgamma, c->rgbgammainv);
747 #else
748  c->xyzgamma = xyzgamma_tab;
749  c->rgbgamma = rgbgamma_tab;
750  c->xyzgammainv = xyzgammainv_tab;
751  c->rgbgammainv = rgbgammainv_tab;
752 
753  static AVOnce xyz_init_static_once = AV_ONCE_INIT;
754  ff_thread_once(&xyz_init_static_once, init_xyz_tables);
755 #endif
756  return 0;
757 }
758 
760 {
761  switch (*format) {
762  case AV_PIX_FMT_YUVJ420P:
764  return 1;
765  case AV_PIX_FMT_YUVJ411P:
767  return 1;
768  case AV_PIX_FMT_YUVJ422P:
770  return 1;
771  case AV_PIX_FMT_YUVJ444P:
773  return 1;
774  case AV_PIX_FMT_YUVJ440P:
776  return 1;
777  case AV_PIX_FMT_GRAY8:
778  case AV_PIX_FMT_YA8:
779  case AV_PIX_FMT_GRAY9LE:
780  case AV_PIX_FMT_GRAY9BE:
781  case AV_PIX_FMT_GRAY10LE:
782  case AV_PIX_FMT_GRAY10BE:
783  case AV_PIX_FMT_GRAY12LE:
784  case AV_PIX_FMT_GRAY12BE:
785  case AV_PIX_FMT_GRAY14LE:
786  case AV_PIX_FMT_GRAY14BE:
787  case AV_PIX_FMT_GRAY16LE:
788  case AV_PIX_FMT_GRAY16BE:
789  case AV_PIX_FMT_YA16BE:
790  case AV_PIX_FMT_YA16LE:
791  return 1;
792  default:
793  return 0;
794  }
795 }
796 
798 {
799  switch (*format) {
800  case AV_PIX_FMT_0BGR : *format = AV_PIX_FMT_ABGR ; return 1;
801  case AV_PIX_FMT_BGR0 : *format = AV_PIX_FMT_BGRA ; return 4;
802  case AV_PIX_FMT_0RGB : *format = AV_PIX_FMT_ARGB ; return 1;
803  case AV_PIX_FMT_RGB0 : *format = AV_PIX_FMT_RGBA ; return 4;
804  default: return 0;
805  }
806 }
807 
808 static int handle_xyz(enum AVPixelFormat *format)
809 {
810  switch (*format) {
811  case AV_PIX_FMT_XYZ12BE : *format = AV_PIX_FMT_RGB48BE; return 1;
812  case AV_PIX_FMT_XYZ12LE : *format = AV_PIX_FMT_RGB48LE; return 1;
813  default: return 0;
814  }
815 }
816 
818 {
820  c->src0Alpha |= handle_0alpha(&sws->src_format);
821  c->dst0Alpha |= handle_0alpha(&sws->dst_format);
822  c->srcXYZ |= handle_xyz(&sws->src_format);
823  c->dstXYZ |= handle_xyz(&sws->dst_format);
824  if (c->srcXYZ || c->dstXYZ)
825  return fill_xyztables(c);
826  else
827  return 0;
828 }
829 
831 {
832  return !isYUV(format) && !isGray(format);
833 }
834 
835 int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
836  int srcRange, const int table[4], int dstRange,
837  int brightness, int contrast, int saturation)
838 {
840  const AVPixFmtDescriptor *desc_dst;
841  const AVPixFmtDescriptor *desc_src;
842  int ret, need_reinit = 0;
843 
844  if (c->nb_slice_ctx) {
845  int parent_ret = 0;
846  for (int i = 0; i < c->nb_slice_ctx; i++) {
847  int ret = sws_setColorspaceDetails(c->slice_ctx[i], inv_table,
848  srcRange, table, dstRange,
849  brightness, contrast, saturation);
850  if (ret < 0)
851  parent_ret = ret;
852  }
853 
854  return parent_ret;
855  }
856 
858  if (ret < 0)
859  return ret;
860  desc_dst = av_pix_fmt_desc_get(sws->dst_format);
861  desc_src = av_pix_fmt_desc_get(sws->src_format);
862 
864  dstRange = 0;
866  srcRange = 0;
867 
868  if (sws->src_range != srcRange ||
869  sws->dst_range != dstRange ||
870  c->brightness != brightness ||
871  c->contrast != contrast ||
872  c->saturation != saturation ||
873  memcmp(c->srcColorspaceTable, inv_table, sizeof(int) * 4) ||
874  memcmp(c->dstColorspaceTable, table, sizeof(int) * 4)
875  )
876  need_reinit = 1;
877 
878  memmove(c->srcColorspaceTable, inv_table, sizeof(int) * 4);
879  memmove(c->dstColorspaceTable, table, sizeof(int) * 4);
880 
881 
882 
883  c->brightness = brightness;
884  c->contrast = contrast;
885  c->saturation = saturation;
886  sws->src_range = srcRange;
887  sws->dst_range = dstRange;
888 
889  if (need_reinit)
891 
892  c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
893  c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
894 
895  if (c->cascaded_context[c->cascaded_mainindex])
896  return sws_setColorspaceDetails(c->cascaded_context[c->cascaded_mainindex],inv_table, srcRange,table, dstRange, brightness, contrast, saturation);
897 
898  if (!need_reinit)
899  return 0;
900 
902  if (!c->cascaded_context[0] &&
903  memcmp(c->dstColorspaceTable, c->srcColorspaceTable, sizeof(int) * 4) &&
904  sws->src_w && sws->src_h && sws->dst_w && sws->dst_h) {
905  enum AVPixelFormat tmp_format;
906  int tmp_width, tmp_height;
907  int srcW = sws->src_w;
908  int srcH = sws->src_h;
909  int dstW = sws->dst_w;
910  int dstH = sws->dst_h;
911  int ret;
912  av_log(c, AV_LOG_VERBOSE, "YUV color matrix differs for YUV->YUV, using intermediate RGB to convert\n");
913 
914  if (isNBPS(sws->dst_format) || is16BPS(sws->dst_format)) {
916  tmp_format = AV_PIX_FMT_BGRA64;
917  } else {
918  tmp_format = AV_PIX_FMT_BGR48;
919  }
920  } else {
922  tmp_format = AV_PIX_FMT_BGRA;
923  } else {
924  tmp_format = AV_PIX_FMT_BGR24;
925  }
926  }
927 
928  if (srcW*srcH > dstW*dstH) {
929  tmp_width = dstW;
930  tmp_height = dstH;
931  } else {
932  tmp_width = srcW;
933  tmp_height = srcH;
934  }
935 
936  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
937  tmp_width, tmp_height, tmp_format, 64);
938  if (ret < 0)
939  return ret;
940 
941  c->cascaded_context[0] = alloc_set_opts(srcW, srcH, sws->src_format,
942  tmp_width, tmp_height, tmp_format,
944  if (!c->cascaded_context[0])
945  return -1;
946 
947  c->cascaded_context[0]->alpha_blend = sws->alpha_blend;
948  ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
949  if (ret < 0)
950  return ret;
951  //we set both src and dst depending on that the RGB side will be ignored
952  sws_setColorspaceDetails(c->cascaded_context[0], inv_table,
953  srcRange, table, dstRange,
954  brightness, contrast, saturation);
955 
956  c->cascaded_context[1] = alloc_set_opts(tmp_width, tmp_height, tmp_format,
957  dstW, dstH, sws->dst_format,
959  if (!c->cascaded_context[1])
960  return -1;
961  c->cascaded_context[1]->src_range = srcRange;
962  c->cascaded_context[1]->dst_range = dstRange;
963  ret = sws_init_context(c->cascaded_context[1], NULL , NULL);
964  if (ret < 0)
965  return ret;
966  sws_setColorspaceDetails(c->cascaded_context[1], inv_table,
967  srcRange, table, dstRange,
968  0, 1 << 16, 1 << 16);
969  return 0;
970  }
971  //We do not support this combination currently, we need to cascade more contexts to compensate
972  if (c->cascaded_context[0] && memcmp(c->dstColorspaceTable, c->srcColorspaceTable, sizeof(int) * 4))
973  return -1; //AVERROR_PATCHWELCOME;
974  return 0;
975  }
976 
977  if (!isYUV(sws->dst_format) && !isGray(sws->dst_format)) {
978  ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
979  contrast, saturation);
980  // FIXME factorize
981 
982 #if ARCH_PPC
983  ff_yuv2rgb_init_tables_ppc(c, inv_table, brightness,
984  contrast, saturation);
985 #endif
986  }
987 
988  fill_rgb2yuv_table(c, table, dstRange);
989 
990  return 0;
991 }
992 
994  int *srcRange, int **table, int *dstRange,
995  int *brightness, int *contrast, int *saturation)
996 {
998  if (!c)
999  return -1;
1000 
1001  if (c->nb_slice_ctx) {
1002  return sws_getColorspaceDetails(c->slice_ctx[0], inv_table, srcRange,
1003  table, dstRange, brightness, contrast,
1004  saturation);
1005  }
1006 
1007  *inv_table = c->srcColorspaceTable;
1008  *table = c->dstColorspaceTable;
1009  *srcRange = range_override_needed(sws->src_format) ? 1 : sws->src_range;
1010  *dstRange = range_override_needed(sws->dst_format) ? 1 : sws->dst_range;
1011  *brightness = c->brightness;
1012  *contrast = c->contrast;
1013  *saturation = c->saturation;
1014 
1015  return 0;
1016 }
1017 
1019 {
1021  if (!c)
1022  return NULL;
1023 
1024  c->opts.av_class = &ff_sws_context_class;
1026  atomic_init(&c->stride_unaligned_warned, 0);
1027  atomic_init(&c->data_unaligned_warned, 0);
1028 
1029  return &c->opts;
1030 }
1031 
1032 static uint16_t * alloc_gamma_tbl(double e)
1033 {
1034  int i = 0;
1035  uint16_t * tbl;
1036  tbl = (uint16_t*)av_malloc(sizeof(uint16_t) * 1 << 16);
1037  if (!tbl)
1038  return NULL;
1039 
1040  for (i = 0; i < 65536; ++i) {
1041  tbl[i] = pow(i / 65535.0, e) * 65535.0;
1042  }
1043  return tbl;
1044 }
1045 
1047 {
1048  switch(fmt) {
1049  case AV_PIX_FMT_ARGB: return AV_PIX_FMT_RGB24;
1050  case AV_PIX_FMT_RGBA: return AV_PIX_FMT_RGB24;
1051  case AV_PIX_FMT_ABGR: return AV_PIX_FMT_BGR24;
1052  case AV_PIX_FMT_BGRA: return AV_PIX_FMT_BGR24;
1053  case AV_PIX_FMT_YA8: return AV_PIX_FMT_GRAY8;
1054 
1058 
1059  case AV_PIX_FMT_GBRAP: return AV_PIX_FMT_GBRP;
1060 
1063 
1066 
1069 
1072 
1077 
1078  case AV_PIX_FMT_YA16BE: return AV_PIX_FMT_GRAY16;
1079  case AV_PIX_FMT_YA16LE: return AV_PIX_FMT_GRAY16;
1080 
1099 
1100 // case AV_PIX_FMT_AYUV64LE:
1101 // case AV_PIX_FMT_AYUV64BE:
1102 // case AV_PIX_FMT_PAL8:
1103  default: return AV_PIX_FMT_NONE;
1104  }
1105 }
1106 
1108  SwsFilter *dstFilter)
1109 {
1110  int i;
1111  int usesVFilter, usesHFilter;
1112  int unscaled;
1114  SwsFilter dummyFilter = { NULL, NULL, NULL, NULL };
1115  int srcW = sws->src_w;
1116  int srcH = sws->src_h;
1117  int dstW = sws->dst_w;
1118  int dstH = sws->dst_h;
1119  int dst_stride = FFALIGN(dstW * sizeof(int16_t) + 66, 16);
1120  int flags, cpu_flags;
1121  enum AVPixelFormat srcFormat, dstFormat;
1122  const AVPixFmtDescriptor *desc_src;
1123  const AVPixFmtDescriptor *desc_dst;
1124  int ret = 0;
1125  enum AVPixelFormat tmpFmt;
1126  static const float float_mult = 1.0f / 255.0f;
1127 
1129  flags = sws->flags;
1130  emms_c();
1131 
1132  unscaled = (srcW == dstW && srcH == dstH);
1133 
1134  if (!c->contrast && !c->saturation && !c->dstFormatBpp)
1137  sws->dst_range, 0, 1 << 16, 1 << 16);
1138 
1139  ret = handle_formats(sws);
1140  if (ret < 0)
1141  return ret;
1142  srcFormat = sws->src_format;
1143  dstFormat = sws->dst_format;
1144  desc_src = av_pix_fmt_desc_get(srcFormat);
1145  desc_dst = av_pix_fmt_desc_get(dstFormat);
1146 
1147  // If the source has no alpha then disable alpha blendaway
1148  if (c->src0Alpha)
1150 
1151  if (!(unscaled && sws_isSupportedEndiannessConversion(srcFormat) &&
1152  av_pix_fmt_swap_endianness(srcFormat) == dstFormat)) {
1153  if (!sws_isSupportedInput(srcFormat)) {
1154  av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
1155  av_get_pix_fmt_name(srcFormat));
1156  return AVERROR(EINVAL);
1157  }
1158  if (!sws_isSupportedOutput(dstFormat)) {
1159  av_log(c, AV_LOG_ERROR, "%s is not supported as output pixel format\n",
1160  av_get_pix_fmt_name(dstFormat));
1161  return AVERROR(EINVAL);
1162  }
1163  }
1164  av_assert2(desc_src && desc_dst);
1165 
1166  i = flags & (SWS_POINT |
1167  SWS_AREA |
1168  SWS_BILINEAR |
1170  SWS_BICUBIC |
1171  SWS_X |
1172  SWS_GAUSS |
1173  SWS_LANCZOS |
1174  SWS_SINC |
1175  SWS_SPLINE |
1176  SWS_BICUBLIN);
1177 
1178  /* provide a default scaler if not set by caller */
1179  if (!i) {
1180  if (dstW < srcW && dstH < srcH)
1181  flags |= SWS_BICUBIC;
1182  else if (dstW > srcW && dstH > srcH)
1183  flags |= SWS_BICUBIC;
1184  else
1185  flags |= SWS_BICUBIC;
1186  sws->flags = flags;
1187  } else if (i & (i - 1)) {
1189  "Exactly one scaler algorithm must be chosen, got %X\n", i);
1190  return AVERROR(EINVAL);
1191  }
1192  /* sanity check */
1193  if (srcW < 1 || srcH < 1 || dstW < 1 || dstH < 1) {
1194  /* FIXME check if these are enough and try to lower them after
1195  * fixing the relevant parts of the code */
1196  av_log(c, AV_LOG_ERROR, "%dx%d -> %dx%d is invalid scaling dimension\n",
1197  srcW, srcH, dstW, dstH);
1198  return AVERROR(EINVAL);
1199  }
1200  if (flags & SWS_FAST_BILINEAR) {
1201  if (srcW < 8 || dstW < 8) {
1203  sws->flags = flags;
1204  }
1205  }
1206 
1207  if (!dstFilter)
1208  dstFilter = &dummyFilter;
1209  if (!srcFilter)
1210  srcFilter = &dummyFilter;
1211 
1212  c->lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW;
1213  c->lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH;
1214  c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
1215  c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
1216  c->vRounder = 4 * 0x0001000100010001ULL;
1217 
1218  usesVFilter = (srcFilter->lumV && srcFilter->lumV->length > 1) ||
1219  (srcFilter->chrV && srcFilter->chrV->length > 1) ||
1220  (dstFilter->lumV && dstFilter->lumV->length > 1) ||
1221  (dstFilter->chrV && dstFilter->chrV->length > 1);
1222  usesHFilter = (srcFilter->lumH && srcFilter->lumH->length > 1) ||
1223  (srcFilter->chrH && srcFilter->chrH->length > 1) ||
1224  (dstFilter->lumH && dstFilter->lumH->length > 1) ||
1225  (dstFilter->chrH && dstFilter->chrH->length > 1);
1226 
1227  av_pix_fmt_get_chroma_sub_sample(srcFormat, &c->chrSrcHSubSample, &c->chrSrcVSubSample);
1228  av_pix_fmt_get_chroma_sub_sample(dstFormat, &c->chrDstHSubSample, &c->chrDstVSubSample);
1229 
1230  c->dst_slice_align = 1 << c->chrDstVSubSample;
1231 
1232  if (isAnyRGB(dstFormat) && !(flags&SWS_FULL_CHR_H_INT)) {
1233  if (dstW&1) {
1234  av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to odd output size\n");
1236  sws->flags = flags;
1237  }
1238 
1239  if ( c->chrSrcHSubSample == 0
1240  && c->chrSrcVSubSample == 0
1241  && sws->dither != SWS_DITHER_BAYER //SWS_FULL_CHR_H_INT is currently not supported with SWS_DITHER_BAYER
1242  && !(sws->flags & SWS_FAST_BILINEAR)
1243  ) {
1244  av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to input having non subsampled chroma\n");
1246  sws->flags = flags;
1247  }
1248  }
1249 
1250  if (sws->dither == SWS_DITHER_AUTO) {
1251  if (flags & SWS_ERROR_DIFFUSION)
1253  }
1254 
1255  if(dstFormat == AV_PIX_FMT_BGR4_BYTE ||
1256  dstFormat == AV_PIX_FMT_RGB4_BYTE ||
1257  dstFormat == AV_PIX_FMT_BGR8 ||
1258  dstFormat == AV_PIX_FMT_RGB8) {
1259  if (sws->dither == SWS_DITHER_AUTO)
1261  if (!(flags & SWS_FULL_CHR_H_INT)) {
1264  "Desired dithering only supported in full chroma interpolation for destination format '%s'\n",
1265  av_get_pix_fmt_name(dstFormat));
1267  sws->flags = flags;
1268  }
1269  }
1270  if (flags & SWS_FULL_CHR_H_INT) {
1271  if (sws->dither == SWS_DITHER_BAYER) {
1273  "Ordered dither is not supported in full chroma interpolation for destination format '%s'\n",
1274  av_get_pix_fmt_name(dstFormat));
1276  }
1277  }
1278  }
1279  if (isPlanarRGB(dstFormat)) {
1280  if (!(flags & SWS_FULL_CHR_H_INT)) {
1282  "%s output is not supported with half chroma resolution, switching to full\n",
1283  av_get_pix_fmt_name(dstFormat));
1285  sws->flags = flags;
1286  }
1287  }
1288 
1289  /* reuse chroma for 2 pixels RGB/BGR unless user wants full
1290  * chroma interpolation */
1291  if (flags & SWS_FULL_CHR_H_INT &&
1292  isAnyRGB(dstFormat) &&
1293  !isPlanarRGB(dstFormat) &&
1294  dstFormat != AV_PIX_FMT_RGBA64LE &&
1295  dstFormat != AV_PIX_FMT_RGBA64BE &&
1296  dstFormat != AV_PIX_FMT_BGRA64LE &&
1297  dstFormat != AV_PIX_FMT_BGRA64BE &&
1298  dstFormat != AV_PIX_FMT_RGB48LE &&
1299  dstFormat != AV_PIX_FMT_RGB48BE &&
1300  dstFormat != AV_PIX_FMT_BGR48LE &&
1301  dstFormat != AV_PIX_FMT_BGR48BE &&
1302  dstFormat != AV_PIX_FMT_RGBA &&
1303  dstFormat != AV_PIX_FMT_ARGB &&
1304  dstFormat != AV_PIX_FMT_BGRA &&
1305  dstFormat != AV_PIX_FMT_ABGR &&
1306  dstFormat != AV_PIX_FMT_RGB24 &&
1307  dstFormat != AV_PIX_FMT_BGR24 &&
1308  dstFormat != AV_PIX_FMT_BGR4_BYTE &&
1309  dstFormat != AV_PIX_FMT_RGB4_BYTE &&
1310  dstFormat != AV_PIX_FMT_BGR8 &&
1311  dstFormat != AV_PIX_FMT_RGB8 &&
1312  dstFormat != AV_PIX_FMT_X2RGB10LE &&
1313  dstFormat != AV_PIX_FMT_X2BGR10LE
1314  ) {
1316  "full chroma interpolation for destination format '%s' not yet implemented\n",
1317  av_get_pix_fmt_name(dstFormat));
1319  sws->flags = flags;
1320  }
1321  if (isAnyRGB(dstFormat) && !(flags & SWS_FULL_CHR_H_INT))
1322  c->chrDstHSubSample = 1;
1323 
1324  // drop some chroma lines if the user wants it
1325  c->vChrDrop = (flags & SWS_SRC_V_CHR_DROP_MASK) >>
1327  c->chrSrcVSubSample += c->vChrDrop;
1328 
1329  /* drop every other pixel for chroma calculation unless user
1330  * wants full chroma */
1331  if (isAnyRGB(srcFormat) && !(srcW & 1) && !(flags & SWS_FULL_CHR_H_INP) &&
1332  srcFormat != AV_PIX_FMT_RGB8 && srcFormat != AV_PIX_FMT_BGR8 &&
1333  srcFormat != AV_PIX_FMT_RGB4 && srcFormat != AV_PIX_FMT_BGR4 &&
1334  srcFormat != AV_PIX_FMT_RGB4_BYTE && srcFormat != AV_PIX_FMT_BGR4_BYTE &&
1335  srcFormat != AV_PIX_FMT_GBRP9BE && srcFormat != AV_PIX_FMT_GBRP9LE &&
1336  srcFormat != AV_PIX_FMT_GBRP10BE && srcFormat != AV_PIX_FMT_GBRP10LE &&
1337  srcFormat != AV_PIX_FMT_GBRAP10BE && srcFormat != AV_PIX_FMT_GBRAP10LE &&
1338  srcFormat != AV_PIX_FMT_GBRP12BE && srcFormat != AV_PIX_FMT_GBRP12LE &&
1339  srcFormat != AV_PIX_FMT_GBRAP12BE && srcFormat != AV_PIX_FMT_GBRAP12LE &&
1340  srcFormat != AV_PIX_FMT_GBRAP14BE && srcFormat != AV_PIX_FMT_GBRAP14LE &&
1341  srcFormat != AV_PIX_FMT_GBRP14BE && srcFormat != AV_PIX_FMT_GBRP14LE &&
1342  srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE &&
1343  srcFormat != AV_PIX_FMT_GBRAP16BE && srcFormat != AV_PIX_FMT_GBRAP16LE &&
1344  srcFormat != AV_PIX_FMT_GBRPF32BE && srcFormat != AV_PIX_FMT_GBRPF32LE &&
1345  srcFormat != AV_PIX_FMT_GBRAPF32BE && srcFormat != AV_PIX_FMT_GBRAPF32LE &&
1346  srcFormat != AV_PIX_FMT_GBRPF16BE && srcFormat != AV_PIX_FMT_GBRPF16LE &&
1347  srcFormat != AV_PIX_FMT_GBRAPF16BE && srcFormat != AV_PIX_FMT_GBRAPF16LE &&
1348  ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
1349  (flags & SWS_FAST_BILINEAR)))
1350  c->chrSrcHSubSample = 1;
1351 
1352  // Note the AV_CEIL_RSHIFT is so that we always round toward +inf.
1353  c->chrSrcW = AV_CEIL_RSHIFT(srcW, c->chrSrcHSubSample);
1354  c->chrSrcH = AV_CEIL_RSHIFT(srcH, c->chrSrcVSubSample);
1355  c->chrDstW = AV_CEIL_RSHIFT(dstW, c->chrDstHSubSample);
1356  c->chrDstH = AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample);
1357 
1358  if (!FF_ALLOCZ_TYPED_ARRAY(c->formatConvBuffer, FFALIGN(srcW * 2 + 78, 16) * 2))
1359  goto nomem;
1360 
1361  c->srcBpc = desc_src->comp[0].depth;
1362  if (c->srcBpc < 8)
1363  c->srcBpc = 8;
1364  c->dstBpc = desc_dst->comp[0].depth;
1365  if (c->dstBpc < 8)
1366  c->dstBpc = 8;
1367  if (isAnyRGB(srcFormat) || srcFormat == AV_PIX_FMT_PAL8)
1368  c->srcBpc = 16;
1369  if (c->dstBpc == 16)
1370  dst_stride <<= 1;
1371 
1372  if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 14) {
1373  c->canMMXEXTBeUsed = dstW >= srcW && (dstW & 31) == 0 &&
1374  c->chrDstW >= c->chrSrcW &&
1375  (srcW & 15) == 0;
1376  if (!c->canMMXEXTBeUsed && dstW >= srcW && c->chrDstW >= c->chrSrcW && (srcW & 15) == 0
1377 
1378  && (flags & SWS_FAST_BILINEAR)) {
1379  if (flags & SWS_PRINT_INFO)
1380  av_log(c, AV_LOG_INFO,
1381  "output width is not a multiple of 32 -> no MMXEXT scaler\n");
1382  }
1383  if (usesHFilter || isNBPS(sws->src_format) || is16BPS(sws->src_format) || isAnyRGB(sws->src_format))
1384  c->canMMXEXTBeUsed = 0;
1385  } else
1386  c->canMMXEXTBeUsed = 0;
1387 
1388  c->chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW;
1389  c->chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH;
1390 
1391  /* Match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src
1392  * to pixel n-2 of dst, but only for the FAST_BILINEAR mode otherwise do
1393  * correct scaling.
1394  * n-2 is the last chrominance sample available.
1395  * This is not perfect, but no one should notice the difference, the more
1396  * correct variant would be like the vertical one, but that would require
1397  * some special code for the first and last pixel */
1398  if (flags & SWS_FAST_BILINEAR) {
1399  if (c->canMMXEXTBeUsed) {
1400  c->lumXInc += 20;
1401  c->chrXInc += 20;
1402  }
1403  // we don't use the x86 asm scaler if MMX is available
1404  else if (INLINE_MMX(cpu_flags) && c->dstBpc <= 14) {
1405  c->lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20;
1406  c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20;
1407  }
1408  }
1409 
1410  // hardcoded for now
1411  c->gamma_value = 2.2;
1412  tmpFmt = AV_PIX_FMT_RGBA64LE;
1413 
1414  if (!unscaled && sws->gamma_flag && (srcFormat != tmpFmt || dstFormat != tmpFmt)) {
1415  SwsInternal *c2;
1416  c->cascaded_context[0] = NULL;
1417 
1418  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1419  srcW, srcH, tmpFmt, 64);
1420  if (ret < 0)
1421  return ret;
1422 
1423  c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
1424  srcW, srcH, tmpFmt,
1425  flags, NULL, NULL,
1426  sws->scaler_params);
1427  if (!c->cascaded_context[0]) {
1428  return AVERROR(ENOMEM);
1429  }
1430 
1431  c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFmt,
1432  dstW, dstH, tmpFmt,
1433  flags, srcFilter, dstFilter,
1434  sws->scaler_params);
1435 
1436  if (!c->cascaded_context[1])
1437  return AVERROR(ENOMEM);
1438 
1439  c2 = sws_internal(c->cascaded_context[1]);
1440  c2->is_internal_gamma = 1;
1441  c2->gamma = alloc_gamma_tbl( c->gamma_value);
1442  c2->inv_gamma = alloc_gamma_tbl(1.f/c->gamma_value);
1443  if (!c2->gamma || !c2->inv_gamma)
1444  return AVERROR(ENOMEM);
1445 
1446  // is_internal_flag is set after creating the context
1447  // to properly create the gamma convert FilterDescriptor
1448  // we have to re-initialize it
1450  if ((ret = ff_init_filters(c2)) < 0) {
1451  sws_freeContext(c->cascaded_context[1]);
1452  c->cascaded_context[1] = NULL;
1453  return ret;
1454  }
1455 
1456  c->cascaded_context[2] = NULL;
1457  if (dstFormat != tmpFmt) {
1458  ret = av_image_alloc(c->cascaded_tmp[1], c->cascaded_tmpStride[1],
1459  dstW, dstH, tmpFmt, 64);
1460  if (ret < 0)
1461  return ret;
1462 
1463  c->cascaded_context[2] = sws_getContext(dstW, dstH, tmpFmt,
1464  dstW, dstH, dstFormat,
1465  flags, NULL, NULL,
1466  sws->scaler_params);
1467  if (!c->cascaded_context[2])
1468  return AVERROR(ENOMEM);
1469  }
1470  return 0;
1471  }
1472 
1473  if (isBayer(srcFormat)) {
1474  if (!unscaled ||
1475  (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P &&
1476  dstFormat != AV_PIX_FMT_RGB48)) {
1477  enum AVPixelFormat tmpFormat = isBayer16BPS(srcFormat) ? AV_PIX_FMT_RGB48 : AV_PIX_FMT_RGB24;
1478 
1479  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1480  srcW, srcH, tmpFormat, 64);
1481  if (ret < 0)
1482  return ret;
1483 
1484  c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
1485  srcW, srcH, tmpFormat,
1486  flags, srcFilter, NULL,
1487  sws->scaler_params);
1488  if (!c->cascaded_context[0])
1489  return AVERROR(ENOMEM);
1490 
1491  c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat,
1492  dstW, dstH, dstFormat,
1493  flags, NULL, dstFilter,
1494  sws->scaler_params);
1495  if (!c->cascaded_context[1])
1496  return AVERROR(ENOMEM);
1497  return 0;
1498  }
1499  }
1500 
1501  if (unscaled && c->srcBpc == 8 && dstFormat == AV_PIX_FMT_GRAYF32){
1502  for (i = 0; i < 256; ++i){
1503  c->uint2float_lut[i] = (float)i * float_mult;
1504  }
1505  }
1506 
1507  // float will be converted to uint16_t
1508  if ((srcFormat == AV_PIX_FMT_GRAYF32BE || srcFormat == AV_PIX_FMT_GRAYF32LE) &&
1509  (!unscaled || unscaled && dstFormat != srcFormat && (srcFormat != AV_PIX_FMT_GRAYF32 ||
1510  dstFormat != AV_PIX_FMT_GRAY8))){
1511  c->srcBpc = 16;
1512  }
1513 
1514  if (CONFIG_SWSCALE_ALPHA && isALPHA(srcFormat) && !isALPHA(dstFormat)) {
1515  enum AVPixelFormat tmpFormat = alphaless_fmt(srcFormat);
1516 
1517  if (tmpFormat != AV_PIX_FMT_NONE && sws->alpha_blend != SWS_ALPHA_BLEND_NONE) {
1518  if (!unscaled ||
1519  dstFormat != tmpFormat ||
1520  usesHFilter || usesVFilter ||
1521  sws->src_range != sws->dst_range
1522  ) {
1523  c->cascaded_mainindex = 1;
1524  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1525  srcW, srcH, tmpFormat, 64);
1526  if (ret < 0)
1527  return ret;
1528 
1529  c->cascaded_context[0] = alloc_set_opts(srcW, srcH, srcFormat,
1530  srcW, srcH, tmpFormat,
1531  flags, sws->scaler_params);
1532  if (!c->cascaded_context[0])
1533  return AVERROR(EINVAL);
1534  c->cascaded_context[0]->alpha_blend = sws->alpha_blend;
1535  ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
1536  if (ret < 0)
1537  return ret;
1538 
1539  c->cascaded_context[1] = alloc_set_opts(srcW, srcH, tmpFormat,
1540  dstW, dstH, dstFormat,
1541  flags, sws->scaler_params);
1542  if (!c->cascaded_context[1])
1543  return AVERROR(EINVAL);
1544 
1545  c->cascaded_context[1]->src_range = sws->src_range;
1546  c->cascaded_context[1]->dst_range = sws->dst_range;
1547  ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter);
1548  if (ret < 0)
1549  return ret;
1550 
1551  return 0;
1552  }
1553  }
1554  }
1555 
1556  /* alpha blend special case, note this has been split via cascaded contexts if its scaled */
1557  if (unscaled && !usesHFilter && !usesVFilter &&
1559  isALPHA(srcFormat) &&
1560  (sws->src_range == sws->dst_range || isAnyRGB(dstFormat)) &&
1561  alphaless_fmt(srcFormat) == dstFormat
1562  ) {
1563  c->convert_unscaled = ff_sws_alphablendaway;
1564 
1565  if (flags & SWS_PRINT_INFO)
1566  av_log(c, AV_LOG_INFO,
1567  "using alpha blendaway %s -> %s special converter\n",
1568  av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1569  return 0;
1570  }
1571 
1572  /* unscaled special cases */
1573  if (unscaled && !usesHFilter && !usesVFilter &&
1574  (sws->src_range == sws->dst_range || isAnyRGB(dstFormat) ||
1575  isFloat(srcFormat) || isFloat(dstFormat) || isBayer(srcFormat))){
1576 
1578 
1579  if (c->convert_unscaled) {
1580  if (flags & SWS_PRINT_INFO)
1581  av_log(c, AV_LOG_INFO,
1582  "using unscaled %s -> %s special converter\n",
1583  av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1584  return 0;
1585  }
1586  }
1587 
1588 #if HAVE_MMAP && HAVE_MPROTECT && defined(MAP_ANONYMOUS)
1589 #define USE_MMAP 1
1590 #else
1591 #define USE_MMAP 0
1592 #endif
1593 
1594  /* precalculate horizontal scaler filter coefficients */
1595  {
1596 #if HAVE_MMXEXT_INLINE
1597 // can't downscale !!!
1598  if (c->canMMXEXTBeUsed && (flags & SWS_FAST_BILINEAR)) {
1599  c->lumMmxextFilterCodeSize = ff_init_hscaler_mmxext(dstW, c->lumXInc, NULL,
1600  NULL, NULL, 8);
1601  c->chrMmxextFilterCodeSize = ff_init_hscaler_mmxext(c->chrDstW, c->chrXInc,
1602  NULL, NULL, NULL, 4);
1603 
1604 #if USE_MMAP
1605  c->lumMmxextFilterCode = mmap(NULL, c->lumMmxextFilterCodeSize,
1606  PROT_READ | PROT_WRITE,
1607  MAP_PRIVATE | MAP_ANONYMOUS,
1608  -1, 0);
1609  c->chrMmxextFilterCode = mmap(NULL, c->chrMmxextFilterCodeSize,
1610  PROT_READ | PROT_WRITE,
1611  MAP_PRIVATE | MAP_ANONYMOUS,
1612  -1, 0);
1613 #elif HAVE_VIRTUALALLOC
1614  c->lumMmxextFilterCode = VirtualAlloc(NULL,
1615  c->lumMmxextFilterCodeSize,
1616  MEM_COMMIT,
1617  PAGE_EXECUTE_READWRITE);
1618  c->chrMmxextFilterCode = VirtualAlloc(NULL,
1619  c->chrMmxextFilterCodeSize,
1620  MEM_COMMIT,
1621  PAGE_EXECUTE_READWRITE);
1622 #else
1623  c->lumMmxextFilterCode = av_malloc(c->lumMmxextFilterCodeSize);
1624  c->chrMmxextFilterCode = av_malloc(c->chrMmxextFilterCodeSize);
1625 #endif
1626 
1627 #ifdef MAP_ANONYMOUS
1628  if (c->lumMmxextFilterCode == MAP_FAILED || c->chrMmxextFilterCode == MAP_FAILED)
1629 #else
1630  if (!c->lumMmxextFilterCode || !c->chrMmxextFilterCode)
1631 #endif
1632  {
1633  av_log(c, AV_LOG_ERROR, "Failed to allocate MMX2FilterCode\n");
1634  return AVERROR(ENOMEM);
1635  }
1636 
1637  if (!FF_ALLOCZ_TYPED_ARRAY(c->hLumFilter, dstW / 8 + 8) ||
1638  !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilter, c->chrDstW / 4 + 8) ||
1639  !FF_ALLOCZ_TYPED_ARRAY(c->hLumFilterPos, dstW / 2 / 8 + 8) ||
1640  !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilterPos, c->chrDstW / 2 / 4 + 8))
1641  goto nomem;
1642 
1643  ff_init_hscaler_mmxext( dstW, c->lumXInc, c->lumMmxextFilterCode,
1644  c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8);
1645  ff_init_hscaler_mmxext(c->chrDstW, c->chrXInc, c->chrMmxextFilterCode,
1646  c->hChrFilter, (uint32_t*)c->hChrFilterPos, 4);
1647 
1648 #if USE_MMAP
1649  if ( mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1
1650  || mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1) {
1651  av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast bilinear scaler\n");
1652  ret = AVERROR(EINVAL);
1653  goto fail;
1654  }
1655 #endif
1656  } else
1657 #endif /* HAVE_MMXEXT_INLINE */
1658  {
1659  const int filterAlign = X86_MMX(cpu_flags) ? 4 :
1660  PPC_ALTIVEC(cpu_flags) ? 8 :
1661  have_neon(cpu_flags) ? 4 :
1662  have_lsx(cpu_flags) ? 8 :
1663  have_lasx(cpu_flags) ? 8 : 1;
1664 
1665  if ((ret = initFilter(&c->hLumFilter, &c->hLumFilterPos,
1666  &c->hLumFilterSize, c->lumXInc,
1667  srcW, dstW, filterAlign, 1 << 14,
1669  cpu_flags, srcFilter->lumH, dstFilter->lumH,
1670  sws->scaler_params,
1671  get_local_pos(c, 0, 0, 0),
1672  get_local_pos(c, 0, 0, 0))) < 0)
1673  goto fail;
1674  if (ff_shuffle_filter_coefficients(c, c->hLumFilterPos, c->hLumFilterSize, c->hLumFilter, dstW) < 0)
1675  goto nomem;
1676  if ((ret = initFilter(&c->hChrFilter, &c->hChrFilterPos,
1677  &c->hChrFilterSize, c->chrXInc,
1678  c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
1680  cpu_flags, srcFilter->chrH, dstFilter->chrH,
1681  sws->scaler_params,
1682  get_local_pos(c, c->chrSrcHSubSample, sws->src_h_chr_pos, 0),
1683  get_local_pos(c, c->chrDstHSubSample, sws->dst_h_chr_pos, 0))) < 0)
1684  goto fail;
1685  if (ff_shuffle_filter_coefficients(c, c->hChrFilterPos, c->hChrFilterSize, c->hChrFilter, c->chrDstW) < 0)
1686  goto nomem;
1687  }
1688  } // initialize horizontal stuff
1689 
1690  /* precalculate vertical scaler filter coefficients */
1691  {
1692  const int filterAlign = X86_MMX(cpu_flags) ? 2 :
1693  PPC_ALTIVEC(cpu_flags) ? 8 :
1694  have_neon(cpu_flags) ? 2 : 1;
1695 
1696  if ((ret = initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
1697  c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
1699  cpu_flags, srcFilter->lumV, dstFilter->lumV,
1700  sws->scaler_params,
1701  get_local_pos(c, 0, 0, 1),
1702  get_local_pos(c, 0, 0, 1))) < 0)
1703  goto fail;
1704  if ((ret = initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
1705  c->chrYInc, c->chrSrcH, c->chrDstH,
1706  filterAlign, (1 << 12),
1708  cpu_flags, srcFilter->chrV, dstFilter->chrV,
1709  sws->scaler_params,
1710  get_local_pos(c, c->chrSrcVSubSample, sws->src_v_chr_pos, 1),
1711  get_local_pos(c, c->chrDstVSubSample, sws->dst_v_chr_pos, 1))) < 0)
1712 
1713  goto fail;
1714 
1715 #if HAVE_ALTIVEC
1716  if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * sws->dst_h) ||
1717  !FF_ALLOC_TYPED_ARRAY(c->vCCoeffsBank, c->vChrFilterSize * c->chrDstH))
1718  goto nomem;
1719 
1720  for (i = 0; i < c->vLumFilterSize * sws->dst_h; i++) {
1721  int j;
1722  short *p = (short *)&c->vYCoeffsBank[i];
1723  for (j = 0; j < 8; j++)
1724  p[j] = c->vLumFilter[i];
1725  }
1726 
1727  for (i = 0; i < c->vChrFilterSize * c->chrDstH; i++) {
1728  int j;
1729  short *p = (short *)&c->vCCoeffsBank[i];
1730  for (j = 0; j < 8; j++)
1731  p[j] = c->vChrFilter[i];
1732  }
1733 #endif
1734  }
1735 
1736  for (i = 0; i < 4; i++)
1737  if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], sws->dst_w + 3))
1738  goto nomem;
1739 
1740  c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(sws->src_format) && isALPHA(sws->dst_format)) ? 1 : 0;
1741 
1742  // 64 / c->scalingBpp is the same as 16 / sizeof(scaling_intermediate)
1743  c->uv_off = (dst_stride>>1) + 64 / (c->dstBpc &~ 7);
1744  c->uv_offx2 = dst_stride + 16;
1745 
1746  av_assert0(c->chrDstH <= dstH);
1747 
1748  if (flags & SWS_PRINT_INFO) {
1749  const char *scaler = NULL, *cpucaps;
1750 
1751  for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
1752  if (flags & scale_algorithms[i].flag) {
1753  scaler = scale_algorithms[i].description;
1754  break;
1755  }
1756  }
1757  if (!scaler)
1758  scaler = "ehh flags invalid?!";
1759  av_log(c, AV_LOG_INFO, "%s scaler, from %s to %s%s ",
1760  scaler,
1761  av_get_pix_fmt_name(srcFormat),
1762  dstFormat == AV_PIX_FMT_BGR555 || dstFormat == AV_PIX_FMT_BGR565 ||
1763  dstFormat == AV_PIX_FMT_RGB444BE || dstFormat == AV_PIX_FMT_RGB444LE ||
1764  dstFormat == AV_PIX_FMT_BGR444BE || dstFormat == AV_PIX_FMT_BGR444LE ?
1765  "dithered " : "",
1766  av_get_pix_fmt_name(dstFormat));
1767 
1768  if (INLINE_MMXEXT(cpu_flags))
1769  cpucaps = "MMXEXT";
1770  else if (INLINE_MMX(cpu_flags))
1771  cpucaps = "MMX";
1772  else if (PPC_ALTIVEC(cpu_flags))
1773  cpucaps = "AltiVec";
1774  else
1775  cpucaps = "C";
1776 
1777  av_log(c, AV_LOG_INFO, "using %s\n", cpucaps);
1778 
1779  av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
1781  "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1782  sws->src_w, sws->src_h, sws->dst_w, sws->dst_h, c->lumXInc, c->lumYInc);
1784  "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1785  c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH,
1786  c->chrXInc, c->chrYInc);
1787  }
1788 
1790 
1791  return ff_init_filters(c);
1792 nomem:
1793  ret = AVERROR(ENOMEM);
1794 fail: // FIXME replace things by appropriate error codes
1795  if (ret == RETCODE_USE_CASCADE) {
1796  int tmpW = sqrt(srcW * (int64_t)dstW);
1797  int tmpH = sqrt(srcH * (int64_t)dstH);
1798  enum AVPixelFormat tmpFormat = AV_PIX_FMT_YUV420P;
1799 
1800  if (isALPHA(srcFormat))
1801  tmpFormat = AV_PIX_FMT_YUVA420P;
1802 
1803  if (srcW*(int64_t)srcH <= 4LL*dstW*dstH)
1804  return AVERROR(EINVAL);
1805 
1806  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1807  tmpW, tmpH, tmpFormat, 64);
1808  if (ret < 0)
1809  return ret;
1810 
1811  c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
1812  tmpW, tmpH, tmpFormat,
1813  flags, srcFilter, NULL,
1814  sws->scaler_params);
1815  if (!c->cascaded_context[0])
1816  return AVERROR(ENOMEM);
1817 
1818  c->cascaded_context[1] = sws_getContext(tmpW, tmpH, tmpFormat,
1819  dstW, dstH, dstFormat,
1820  flags, NULL, dstFilter,
1821  sws->scaler_params);
1822  if (!c->cascaded_context[1])
1823  return AVERROR(ENOMEM);
1824  return 0;
1825  }
1826  return ret;
1827 }
1828 
1830  SwsFilter *src_filter, SwsFilter *dst_filter)
1831 {
1833  int ret;
1834 
1835  ret = avpriv_slicethread_create(&c->slicethread, (void*) sws,
1837  if (ret == AVERROR(ENOSYS)) {
1838  sws->threads = 1;
1839  return 0;
1840  } else if (ret < 0)
1841  return ret;
1842 
1843  sws->threads = ret;
1844 
1845  c->slice_ctx = av_calloc(sws->threads, sizeof(*c->slice_ctx));
1846  c->slice_err = av_calloc(sws->threads, sizeof(*c->slice_err));
1847  if (!c->slice_ctx || !c->slice_err)
1848  return AVERROR(ENOMEM);
1849 
1850  for (int i = 0; i < sws->threads; i++) {
1851  SwsContext *slice;
1852  slice = c->slice_ctx[i] = sws_alloc_context();
1853  if (!slice)
1854  return AVERROR(ENOMEM);
1855  sws_internal(slice)->parent = sws;
1856  c->nb_slice_ctx++;
1857 
1858  ret = av_opt_copy(slice, sws);
1859  if (ret < 0)
1860  return ret;
1861  slice->threads = 1;
1862 
1863  ret = ff_sws_init_single_context(slice, src_filter, dst_filter);
1864  if (ret < 0)
1865  return ret;
1866 
1867  if (slice->dither == SWS_DITHER_ED) {
1869  "Error-diffusion dither is in use, scaling will be single-threaded.");
1870  break;
1871  }
1872  }
1873 
1874  return 0;
1875 }
1876 
1878  SwsFilter *dstFilter)
1879 {
1881  static AVOnce rgb2rgb_once = AV_ONCE_INIT;
1882  enum AVPixelFormat src_format, dst_format;
1883  int ret;
1884 
1885  c->frame_src = av_frame_alloc();
1886  c->frame_dst = av_frame_alloc();
1887  if (!c->frame_src || !c->frame_dst)
1888  return AVERROR(ENOMEM);
1889 
1890  if (ff_thread_once(&rgb2rgb_once, ff_sws_rgb2rgb_init) != 0)
1891  return AVERROR_UNKNOWN;
1892 
1893  src_format = sws->src_format;
1894  dst_format = sws->dst_format;
1897 
1898  if (src_format != sws->src_format || dst_format != sws->dst_format)
1899  av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
1900 
1901  if (sws->threads != 1) {
1902  ret = context_init_threaded(sws, srcFilter, dstFilter);
1903  if (ret < 0 || sws->threads > 1)
1904  return ret;
1905  // threading disabled in this build, init as single-threaded
1906  }
1907 
1908  return ff_sws_init_single_context(sws, srcFilter, dstFilter);
1909 }
1910 
1911 SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
1912  int dstW, int dstH, enum AVPixelFormat dstFormat,
1913  int flags, SwsFilter *srcFilter,
1914  SwsFilter *dstFilter, const double *param)
1915 {
1916  SwsContext *sws;
1917 
1918  sws = alloc_set_opts(srcW, srcH, srcFormat,
1919  dstW, dstH, dstFormat,
1920  flags, param);
1921  if (!sws)
1922  return NULL;
1923 
1924  if (sws_init_context(sws, srcFilter, dstFilter) < 0) {
1926  return NULL;
1927  }
1928 
1929  return sws;
1930 }
1931 
1932 static int isnan_vec(SwsVector *a)
1933 {
1934  int i;
1935  for (i=0; i<a->length; i++)
1936  if (isnan(a->coeff[i]))
1937  return 1;
1938  return 0;
1939 }
1940 
1941 static void makenan_vec(SwsVector *a)
1942 {
1943  int i;
1944  for (i=0; i<a->length; i++)
1945  a->coeff[i] = NAN;
1946 }
1947 
1949 {
1950  SwsVector *vec;
1951 
1952  if(length <= 0 || length > INT_MAX/ sizeof(double))
1953  return NULL;
1954 
1955  vec = av_malloc(sizeof(SwsVector));
1956  if (!vec)
1957  return NULL;
1958  vec->length = length;
1959  vec->coeff = av_malloc(sizeof(double) * length);
1960  if (!vec->coeff)
1961  av_freep(&vec);
1962  return vec;
1963 }
1964 
1965 SwsVector *sws_getGaussianVec(double variance, double quality)
1966 {
1967  const int length = (int)(variance * quality + 0.5) | 1;
1968  int i;
1969  double middle = (length - 1) * 0.5;
1970  SwsVector *vec;
1971 
1972  if(variance < 0 || quality < 0)
1973  return NULL;
1974 
1975  vec = sws_allocVec(length);
1976 
1977  if (!vec)
1978  return NULL;
1979 
1980  for (i = 0; i < length; i++) {
1981  double dist = i - middle;
1982  vec->coeff[i] = exp(-dist * dist / (2 * variance * variance)) /
1983  sqrt(2 * variance * M_PI);
1984  }
1985 
1986  sws_normalizeVec(vec, 1.0);
1987 
1988  return vec;
1989 }
1990 
1991 /**
1992  * Allocate and return a vector with length coefficients, all
1993  * with the same value c.
1994  */
1995 static
1996 SwsVector *sws_getConstVec(double c, int length)
1997 {
1998  int i;
1999  SwsVector *vec = sws_allocVec(length);
2000 
2001  if (!vec)
2002  return NULL;
2003 
2004  for (i = 0; i < length; i++)
2005  vec->coeff[i] = c;
2006 
2007  return vec;
2008 }
2009 
2010 /**
2011  * Allocate and return a vector with just one coefficient, with
2012  * value 1.0.
2013  */
2014 static
2016 {
2017  return sws_getConstVec(1.0, 1);
2018 }
2019 
2020 static double sws_dcVec(SwsVector *a)
2021 {
2022  int i;
2023  double sum = 0;
2024 
2025  for (i = 0; i < a->length; i++)
2026  sum += a->coeff[i];
2027 
2028  return sum;
2029 }
2030 
2031 void sws_scaleVec(SwsVector *a, double scalar)
2032 {
2033  int i;
2034 
2035  for (i = 0; i < a->length; i++)
2036  a->coeff[i] *= scalar;
2037 }
2038 
2040 {
2042 }
2043 
2045 {
2046  int length = FFMAX(a->length, b->length);
2047  int i;
2048  SwsVector *vec = sws_getConstVec(0.0, length);
2049 
2050  if (!vec)
2051  return NULL;
2052 
2053  for (i = 0; i < a->length; i++)
2054  vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
2055  for (i = 0; i < b->length; i++)
2056  vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] += b->coeff[i];
2057 
2058  return vec;
2059 }
2060 
2061 /* shift left / or right if "shift" is negative */
2063 {
2064  int length = a->length + FFABS(shift) * 2;
2065  int i;
2066  SwsVector *vec = sws_getConstVec(0.0, length);
2067 
2068  if (!vec)
2069  return NULL;
2070 
2071  for (i = 0; i < a->length; i++) {
2072  vec->coeff[i + (length - 1) / 2 -
2073  (a->length - 1) / 2 - shift] = a->coeff[i];
2074  }
2075 
2076  return vec;
2077 }
2078 
2079 static
2081 {
2082  SwsVector *shifted = sws_getShiftedVec(a, shift);
2083  if (!shifted) {
2084  makenan_vec(a);
2085  return;
2086  }
2087  av_free(a->coeff);
2088  a->coeff = shifted->coeff;
2089  a->length = shifted->length;
2090  av_free(shifted);
2091 }
2092 
2093 static
2095 {
2096  SwsVector *sum = sws_sumVec(a, b);
2097  if (!sum) {
2098  makenan_vec(a);
2099  return;
2100  }
2101  av_free(a->coeff);
2102  a->coeff = sum->coeff;
2103  a->length = sum->length;
2104  av_free(sum);
2105 }
2106 
2107 /**
2108  * Print with av_log() a textual representation of the vector a
2109  * if log_level <= av_log_level.
2110  */
2111 static
2112 void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
2113 {
2114  int i;
2115  double max = 0;
2116  double min = 0;
2117  double range;
2118 
2119  for (i = 0; i < a->length; i++)
2120  if (a->coeff[i] > max)
2121  max = a->coeff[i];
2122 
2123  for (i = 0; i < a->length; i++)
2124  if (a->coeff[i] < min)
2125  min = a->coeff[i];
2126 
2127  range = max - min;
2128 
2129  for (i = 0; i < a->length; i++) {
2130  int x = (int)((a->coeff[i] - min) * 60.0 / range + 0.5);
2131  av_log(log_ctx, log_level, "%1.3f ", a->coeff[i]);
2132  for (; x > 0; x--)
2133  av_log(log_ctx, log_level, " ");
2134  av_log(log_ctx, log_level, "|\n");
2135  }
2136 }
2137 
2139 {
2140  if (!a)
2141  return;
2142  av_freep(&a->coeff);
2143  a->length = 0;
2144  av_free(a);
2145 }
2146 
2148 {
2149  if (!filter)
2150  return;
2151 
2152  sws_freeVec(filter->lumH);
2153  sws_freeVec(filter->lumV);
2154  sws_freeVec(filter->chrH);
2155  sws_freeVec(filter->chrV);
2156  av_free(filter);
2157 }
2158 
2159 SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
2160  float lumaSharpen, float chromaSharpen,
2161  float chromaHShift, float chromaVShift,
2162  int verbose)
2163 {
2164  SwsFilter *filter = av_malloc(sizeof(SwsFilter));
2165  if (!filter)
2166  return NULL;
2167 
2168  if (lumaGBlur != 0.0) {
2169  filter->lumH = sws_getGaussianVec(lumaGBlur, 3.0);
2170  filter->lumV = sws_getGaussianVec(lumaGBlur, 3.0);
2171  } else {
2172  filter->lumH = sws_getIdentityVec();
2173  filter->lumV = sws_getIdentityVec();
2174  }
2175 
2176  if (chromaGBlur != 0.0) {
2177  filter->chrH = sws_getGaussianVec(chromaGBlur, 3.0);
2178  filter->chrV = sws_getGaussianVec(chromaGBlur, 3.0);
2179  } else {
2180  filter->chrH = sws_getIdentityVec();
2181  filter->chrV = sws_getIdentityVec();
2182  }
2183 
2184  if (!filter->lumH || !filter->lumV || !filter->chrH || !filter->chrV)
2185  goto fail;
2186 
2187  if (chromaSharpen != 0.0) {
2188  SwsVector *id = sws_getIdentityVec();
2189  if (!id)
2190  goto fail;
2191  sws_scaleVec(filter->chrH, -chromaSharpen);
2192  sws_scaleVec(filter->chrV, -chromaSharpen);
2193  sws_addVec(filter->chrH, id);
2194  sws_addVec(filter->chrV, id);
2195  sws_freeVec(id);
2196  }
2197 
2198  if (lumaSharpen != 0.0) {
2199  SwsVector *id = sws_getIdentityVec();
2200  if (!id)
2201  goto fail;
2202  sws_scaleVec(filter->lumH, -lumaSharpen);
2203  sws_scaleVec(filter->lumV, -lumaSharpen);
2204  sws_addVec(filter->lumH, id);
2205  sws_addVec(filter->lumV, id);
2206  sws_freeVec(id);
2207  }
2208 
2209  if (chromaHShift != 0.0)
2210  sws_shiftVec(filter->chrH, (int)(chromaHShift + 0.5));
2211 
2212  if (chromaVShift != 0.0)
2213  sws_shiftVec(filter->chrV, (int)(chromaVShift + 0.5));
2214 
2215  sws_normalizeVec(filter->chrH, 1.0);
2216  sws_normalizeVec(filter->chrV, 1.0);
2217  sws_normalizeVec(filter->lumH, 1.0);
2218  sws_normalizeVec(filter->lumV, 1.0);
2219 
2220  if (isnan_vec(filter->chrH) ||
2221  isnan_vec(filter->chrV) ||
2222  isnan_vec(filter->lumH) ||
2223  isnan_vec(filter->lumV))
2224  goto fail;
2225 
2226  if (verbose)
2228  if (verbose)
2230 
2231  return filter;
2232 
2233 fail:
2234  sws_freeVec(filter->lumH);
2235  sws_freeVec(filter->lumV);
2236  sws_freeVec(filter->chrH);
2237  sws_freeVec(filter->chrV);
2238  av_freep(&filter);
2239  return NULL;
2240 }
2241 
2243 {
2245  int i;
2246  if (!c)
2247  return;
2248 
2249  for (i = 0; i < FF_ARRAY_ELEMS(c->graph); i++)
2250  ff_sws_graph_free(&c->graph[i]);
2251 
2252  for (i = 0; i < c->nb_slice_ctx; i++)
2253  sws_freeContext(c->slice_ctx[i]);
2254  av_freep(&c->slice_ctx);
2255  av_freep(&c->slice_err);
2256 
2257  avpriv_slicethread_free(&c->slicethread);
2258 
2259  for (i = 0; i < 4; i++)
2260  av_freep(&c->dither_error[i]);
2261 
2262  av_frame_free(&c->frame_src);
2263  av_frame_free(&c->frame_dst);
2264 
2265  av_freep(&c->src_ranges.ranges);
2266 
2267  av_freep(&c->vLumFilter);
2268  av_freep(&c->vChrFilter);
2269  av_freep(&c->hLumFilter);
2270  av_freep(&c->hChrFilter);
2271 #if HAVE_ALTIVEC
2272  av_freep(&c->vYCoeffsBank);
2273  av_freep(&c->vCCoeffsBank);
2274 #endif
2275 
2276  av_freep(&c->vLumFilterPos);
2277  av_freep(&c->vChrFilterPos);
2278  av_freep(&c->hLumFilterPos);
2279  av_freep(&c->hChrFilterPos);
2280 
2281 #if HAVE_MMX_INLINE
2282 #if USE_MMAP
2283  if (c->lumMmxextFilterCode)
2284  munmap(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize);
2285  if (c->chrMmxextFilterCode)
2286  munmap(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize);
2287 #elif HAVE_VIRTUALALLOC
2288  if (c->lumMmxextFilterCode)
2289  VirtualFree(c->lumMmxextFilterCode, 0, MEM_RELEASE);
2290  if (c->chrMmxextFilterCode)
2291  VirtualFree(c->chrMmxextFilterCode, 0, MEM_RELEASE);
2292 #else
2293  av_free(c->lumMmxextFilterCode);
2294  av_free(c->chrMmxextFilterCode);
2295 #endif
2296  c->lumMmxextFilterCode = NULL;
2297  c->chrMmxextFilterCode = NULL;
2298 #endif /* HAVE_MMX_INLINE */
2299 
2300  av_freep(&c->yuvTable);
2301  av_freep(&c->formatConvBuffer);
2302 
2303  sws_freeContext(c->cascaded_context[0]);
2304  sws_freeContext(c->cascaded_context[1]);
2305  sws_freeContext(c->cascaded_context[2]);
2306  memset(c->cascaded_context, 0, sizeof(c->cascaded_context));
2307  av_freep(&c->cascaded_tmp[0][0]);
2308  av_freep(&c->cascaded_tmp[1][0]);
2309 
2310  av_freep(&c->gamma);
2311  av_freep(&c->inv_gamma);
2312 #if CONFIG_SMALL
2313  av_freep(&c->xyzgamma);
2314 #endif
2315 
2316  av_freep(&c->rgb0_scratch);
2317  av_freep(&c->xyz_scratch);
2318 
2319  ff_free_filters(c);
2320 
2321  av_free(c);
2322 }
2323 
2325 {
2326  SwsContext *ctx = *pctx;
2327  if (!ctx)
2328  return;
2329 
2331  *pctx = NULL;
2332 }
2333 
2335  int srcH, enum AVPixelFormat srcFormat,
2336  int dstW, int dstH,
2337  enum AVPixelFormat dstFormat, int flags,
2338  SwsFilter *srcFilter,
2339  SwsFilter *dstFilter,
2340  const double *param)
2341 {
2342  SwsContext *sws;
2343  static const double default_param[2] = { SWS_PARAM_DEFAULT,
2345 
2346  if (!param)
2347  param = default_param;
2348 
2349  if (prev && (prev->src_w == srcW &&
2350  prev->src_h == srcH &&
2351  prev->src_format == srcFormat &&
2352  prev->dst_w == dstW &&
2353  prev->dst_h == dstH &&
2354  prev->dst_format == dstFormat &&
2355  prev->flags == flags &&
2356  prev->scaler_params[0] == param[0] &&
2357  prev->scaler_params[1] == param[1])) {
2358  return prev;
2359  }
2360 
2361  if (!(sws = sws_alloc_context())) {
2362  sws_free_context(&prev);
2363  return NULL;
2364  }
2365 
2366  if (prev) {
2367  av_opt_copy(sws, prev);
2368  sws_free_context(&prev);
2369  }
2370 
2371  sws->src_w = srcW;
2372  sws->src_h = srcH;
2373  sws->src_format = srcFormat;
2374  sws->dst_w = dstW;
2375  sws->dst_h = dstH;
2376  sws->dst_format = dstFormat;
2377  sws->flags = flags;
2378  sws->scaler_params[0] = param[0];
2379  sws->scaler_params[1] = param[1];
2380 
2381  if (sws_init_context(sws, srcFilter, dstFilter) < 0)
2383 
2384  return sws;
2385 }
2386 
2387 int ff_range_add(RangeList *rl, unsigned int start, unsigned int len)
2388 {
2389  Range *tmp;
2390  unsigned int idx;
2391 
2392  /* find the first existing range after the new one */
2393  for (idx = 0; idx < rl->nb_ranges; idx++)
2394  if (rl->ranges[idx].start > start)
2395  break;
2396 
2397  /* check for overlap */
2398  if (idx > 0) {
2399  Range *prev = &rl->ranges[idx - 1];
2400  if (prev->start + prev->len > start)
2401  return AVERROR(EINVAL);
2402  }
2403  if (idx < rl->nb_ranges) {
2404  Range *next = &rl->ranges[idx];
2405  if (start + len > next->start)
2406  return AVERROR(EINVAL);
2407  }
2408 
2410  (rl->nb_ranges + 1) * sizeof(*rl->ranges));
2411  if (!tmp)
2412  return AVERROR(ENOMEM);
2413  rl->ranges = tmp;
2414 
2415  memmove(rl->ranges + idx + 1, rl->ranges + idx,
2416  sizeof(*rl->ranges) * (rl->nb_ranges - idx));
2417  rl->ranges[idx].start = start;
2418  rl->ranges[idx].len = len;
2419  rl->nb_ranges++;
2420 
2421  /* merge ranges */
2422  if (idx > 0) {
2423  Range *prev = &rl->ranges[idx - 1];
2424  Range *cur = &rl->ranges[idx];
2425  if (prev->start + prev->len == cur->start) {
2426  prev->len += cur->len;
2427  memmove(rl->ranges + idx - 1, rl->ranges + idx,
2428  sizeof(*rl->ranges) * (rl->nb_ranges - idx));
2429  rl->nb_ranges--;
2430  idx--;
2431  }
2432  }
2433  if (idx < rl->nb_ranges - 1) {
2434  Range *cur = &rl->ranges[idx];
2435  Range *next = &rl->ranges[idx + 1];
2436  if (cur->start + cur->len == next->start) {
2437  cur->len += next->len;
2438  memmove(rl->ranges + idx, rl->ranges + idx + 1,
2439  sizeof(*rl->ranges) * (rl->nb_ranges - idx - 1));
2440  rl->nb_ranges--;
2441  }
2442  }
2443 
2444  return 0;
2445 }
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:842
flags
const SwsFlags flags[]
Definition: swscale.c:61
INLINE_MMX
#define INLINE_MMX(flags)
Definition: cpu.h:87
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:3396
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:835
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:910
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:2015
libm.h
ub
#define ub(width, name)
Definition: cbs_apv.c:85
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:3341
SwsContext::src_w
int src_w
Deprecated frame property overrides, for the legacy API only.
Definition: swscale.h:228
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:2242
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
EXTERNAL_AVX2_FAST
#define EXTERNAL_AVX2_FAST(flags)
Definition: cpu.h:79
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:455
alphaless_fmt
static enum AVPixelFormat alphaless_fmt(enum AVPixelFormat fmt)
Definition: utils.c:1046
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:797
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:787
RU_IDX
#define RU_IDX
Definition: swscale_internal.h:452
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:456
BV_IDX
#define BV_IDX
Definition: swscale_internal.h:457
have_lasx
#define have_lasx(flags)
Definition: cpu.h:29
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:528
SwsContext::flags
unsigned flags
Bitmask of SWS_*.
Definition: swscale.h:195
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:3293
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:2062
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:2138
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
isnan_vec
static int isnan_vec(SwsVector *a)
Definition: utils.c:1932
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
handle_jpeg
static int handle_jpeg(enum AVPixelFormat *format)
Definition: utils.c:759
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:727
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:546
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:196
SwsContext::src_v_chr_pos
int src_v_chr_pos
Source vertical chroma position in luma grid / 256.
Definition: swscale.h:234
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:544
Range::len
unsigned int len
Definition: swscale_internal.h:81
ONE
@ ONE
Definition: vc1_parser.c:49
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:526
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:2334
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:1877
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:3369
isNBPS
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:741
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:511
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:59
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:51
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:531
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:90
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:540
SwsContext::dither
SwsDither dither
Dither mode.
Definition: swscale.h:210
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:367
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:2387
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:2112
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:205
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:541
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:391
sws_allocVec
SwsVector * sws_allocVec(int length)
Allocate and return an uninitialized vector with length coefficients.
Definition: utils.c:1948
SWS_DITHER_BAYER
@ SWS_DITHER_BAYER
Definition: swscale.h:82
W
@ W
Definition: vf_addroi.c:27
from
const char * from
Definition: jacosubdec.c:66
to
const char * to
Definition: webvttdec.c:35
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:525
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:539
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:1965
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:565
GY_IDX
#define GY_IDX
Definition: swscale_internal.h:450
NAN
#define NAN
Definition: mathematics.h:115
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)
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
fill_xyztables
static int fill_xyztables(SwsInternal *c)
Definition: utils.c:722
alloc_gamma_tbl
static uint16_t * alloc_gamma_tbl(double e)
Definition: utils.c:1032
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:547
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:363
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:519
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
tmp
static uint8_t tmp[20]
Definition: aes_ctr.c:47
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:220
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:2159
RangeList
Definition: swscale_internal.h:84
ROUNDED_DIV
#define ROUNDED_DIV(a, b)
Definition: common.h:58
V
#define V
Definition: avdct.c:31
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:1941
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:232
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:529
ff_sws_init_range_convert
av_cold void ff_sws_init_range_convert(SwsInternal *c)
Definition: swscale.c:622
sws_addVec
static void sws_addVec(SwsVector *a, SwsVector *b)
Definition: utils.c:2094
SwsVector::coeff
double * coeff
pointer to the list of coefficients
Definition: swscale.h:390
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:830
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
ff_sws_context_class
const AVClass ff_sws_context_class
Definition: options.c:97
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:237
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:2031
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:1996
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:365
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:637
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:1518
SwsFilter::chrV
SwsVector * chrV
Definition: swscale.h:399
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:449
SwsInternal::parent
SwsContext * parent
Definition: swscale_internal.h:322
PPC_ALTIVEC
#define PPC_ALTIVEC(flags)
Definition: cpu.h:25
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c:1018
SwsVector
Definition: swscale.h:389
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:1107
isAnyRGB
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:856
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:514
SWS_POINT
@ SWS_POINT
nearest neighbor
Definition: swscale.h:102
SwsContext::alpha_blend
SwsAlphaBlend alpha_blend
Alpha blending mode.
Definition: swscale.h:215
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:521
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:755
SwsContext::src_h
int src_h
Width and height of the source frame.
Definition: swscale.h:228
AV_PIX_FMT_GBRP9BE
@ AV_PIX_FMT_GBRP9BE
planar GBR 4:4:4 27bpp, big-endian
Definition: pixfmt.h:167
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:993
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:395
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:397
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:231
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:451
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:808
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:523
sws_isSupportedEndiannessConversion
int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
Definition: format.c:275
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:2080
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:691
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:545
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
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
len
int len
Definition: vorbis_enc_data.h:426
AV_PIX_FMT_BGR565
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:520
SwsContext::dst_h
int dst_h
Width and height of the destination frame.
Definition: swscale.h:229
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:527
sws_freeFilter
void sws_freeFilter(SwsFilter *filter)
Definition: utils.c:2147
isFloat
static av_always_inline int isFloat(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:864
RangeList::ranges
Range * ranges
Definition: swscale_internal.h:85
SWS_CS_DEFAULT
#define SWS_CS_DEFAULT
Definition: swscale.h:375
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:317
ret
ret
Definition: filter_design.txt:187
XYZ_GAMMA
#define XYZ_GAMMA
Definition: swscale_internal.h:548
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
verbose
int verbose
Definition: checkasm.c:412
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:1911
flag
#define flag(name)
Definition: cbs_av1.c:495
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:30
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:200
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:549
SWS_ERROR_DIFFUSION
@ SWS_ERROR_DIFFUSION
Set SwsContext.dither instead.
Definition: swscale.h:162
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
INLINE_MMXEXT
#define INLINE_MMXEXT(flags)
Definition: cpu.h:88
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:849
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:454
SwsContext::dst_w
int dst_w
Definition: swscale.h:229
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:230
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:233
AV_PIX_FMT_GRAY14LE
@ AV_PIX_FMT_GRAY14LE
Y , 14bpp, little-endian.
Definition: pixfmt.h:361
SwsFilter::lumH
SwsVector * lumH
Definition: swscale.h:396
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
sws_sumVec
static SwsVector * sws_sumVec(SwsVector *a, SwsVector *b)
Definition: utils.c:2044
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:30
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:2324
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:235
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:453
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:236
SWS_SINC
@ SWS_SINC
unwindowed sinc
Definition: swscale.h:106
SwsContext
Main external API structure.
Definition: swscale.h:182
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:817
SwsFilter::chrH
SwsVector * chrH
Definition: swscale.h:398
SWS_SRC_V_CHR_DROP_MASK
#define SWS_SRC_V_CHR_DROP_MASK
Definition: swscale.h:362
sws_dcVec
static double sws_dcVec(SwsVector *a)
Definition: utils.c:2020
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:2039
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:3261
isALPHA
static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:878
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:1829