FFmpeg
utils.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2024 Niklas Haas
3  * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config.h"
23 
24 #define _DEFAULT_SOURCE
25 #define _SVID_SOURCE // needed for MAP_ANONYMOUS
26 #define _DARWIN_C_SOURCE // needed for MAP_ANON
27 #include <inttypes.h>
28 #include <math.h>
29 #include <stdio.h>
30 #include <string.h>
31 #if HAVE_MMAP
32 #include <sys/mman.h>
33 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
34 #define MAP_ANONYMOUS MAP_ANON
35 #endif
36 #endif
37 #if HAVE_VIRTUALALLOC
38 #include <windows.h>
39 #endif
40 
41 #include "libavutil/attributes.h"
42 #include "libavutil/avassert.h"
43 #include "libavutil/cpu.h"
44 #include "libavutil/csp.h"
45 #include "libavutil/emms.h"
46 #include "libavutil/imgutils.h"
47 #include "libavutil/intreadwrite.h"
48 #include "libavutil/libm.h"
49 #include "libavutil/mathematics.h"
50 #include "libavutil/mem.h"
51 #include "libavutil/opt.h"
52 #include "libavutil/pixdesc.h"
53 #include "libavutil/slicethread.h"
54 #include "libavutil/thread.h"
55 #include "libavutil/aarch64/cpu.h"
56 #include "libavutil/ppc/cpu.h"
57 #include "libavutil/x86/asm.h"
58 #include "libavutil/x86/cpu.h"
60 
61 #include "rgb2rgb.h"
62 #include "swscale.h"
63 #include "swscale_internal.h"
64 #include "graph.h"
65 
66 /**
67  * Allocate and return an SwsContext without performing initialization.
68  */
69 static SwsContext *alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcFormat,
70  int dstW, int dstH, enum AVPixelFormat dstFormat,
71  int flags, const double *param)
72 {
74  if (!sws)
75  return NULL;
76 
77  sws->flags = flags;
78  sws->src_w = srcW;
79  sws->src_h = srcH;
80  sws->dst_w = dstW;
81  sws->dst_h = dstH;
82  sws->src_format = srcFormat;
83  sws->dst_format = dstFormat;
84 
85  if (param) {
86  sws->scaler_params[0] = param[0];
87  sws->scaler_params[1] = param[1];
88  }
89 
90  return sws;
91 }
92 
94  int filterSize, int16_t *filter,
95  int dstW)
96 {
97 #if ARCH_X86_64
98  int i, j, k;
100  if (!filter)
101  return 0;
103  if ((c->srcBpc == 8) && (c->dstBpc <= 14)) {
104  int16_t *filterCopy = NULL;
105  if (filterSize > 4) {
106  if (!FF_ALLOC_TYPED_ARRAY(filterCopy, dstW * filterSize))
107  return AVERROR(ENOMEM);
108  memcpy(filterCopy, filter, dstW * filterSize * sizeof(int16_t));
109  }
110  // Do not swap filterPos for pixels which won't be processed by
111  // the main loop.
112  for (i = 0; i + 16 <= dstW; i += 16) {
113  FFSWAP(int, filterPos[i + 2], filterPos[i + 4]);
114  FFSWAP(int, filterPos[i + 3], filterPos[i + 5]);
115  FFSWAP(int, filterPos[i + 10], filterPos[i + 12]);
116  FFSWAP(int, filterPos[i + 11], filterPos[i + 13]);
117  }
118  if (filterSize > 4) {
119  // 16 pixels are processed at a time.
120  for (i = 0; i + 16 <= dstW; i += 16) {
121  // 4 filter coeffs are processed at a time.
122  for (k = 0; k + 4 <= filterSize; k += 4) {
123  for (j = 0; j < 16; ++j) {
124  int from = (i + j) * filterSize + k;
125  int to = i * filterSize + j * 4 + k * 16;
126  memcpy(&filter[to], &filterCopy[from], 4 * sizeof(int16_t));
127  }
128  }
129  }
130  // 4 pixels are processed at a time in the tail.
131  for (; i < dstW; i += 4) {
132  // 4 filter coeffs are processed at a time.
133  int rem = dstW - i >= 4 ? 4 : dstW - i;
134  for (k = 0; k + 4 <= filterSize; k += 4) {
135  for (j = 0; j < rem; ++j) {
136  int from = (i + j) * filterSize + k;
137  int to = i * filterSize + j * 4 + k * 4;
138  memcpy(&filter[to], &filterCopy[from], 4 * sizeof(int16_t));
139  }
140  }
141  }
142  }
143  av_free(filterCopy);
144  }
145  }
146 #endif
147  return 0;
148 }
149 
150 static double getSplineCoeff(double a, double b, double c, double d,
151  double dist)
152 {
153  if (dist <= 1.0)
154  return ((d * dist + c) * dist + b) * dist + a;
155  else
156  return getSplineCoeff(0.0,
157  b + 2.0 * c + 3.0 * d,
158  c + 3.0 * d,
159  -b - 3.0 * c - 6.0 * d,
160  dist - 1.0);
161 }
162 
163 static av_cold int get_local_pos(SwsInternal *s, int chr_subsample, int pos, int dir)
164 {
165  if (pos == -1 || pos <= -513) {
166  pos = (128 << chr_subsample) - 128;
167  }
168  pos += 128; // relative to ideal left edge
169  return pos >> chr_subsample;
170 }
171 
172 typedef struct {
173  int flag; ///< flag associated to the algorithm
174  const char *description; ///< human-readable description
175  int size_factor; ///< size factor used when initing the filters
177 
179  { SWS_AREA, "area averaging", 1 /* downscale only, for upscale it is bilinear */ },
180  { SWS_BICUBIC, "bicubic", 4 },
181  { SWS_BICUBLIN, "luma bicubic / chroma bilinear", -1 },
182  { SWS_BILINEAR, "bilinear", 2 },
183  { SWS_FAST_BILINEAR, "fast bilinear", -1 },
184  { SWS_GAUSS, "Gaussian", 8 /* infinite ;) */ },
185  { SWS_LANCZOS, "Lanczos", -1 /* custom */ },
186  { SWS_POINT, "nearest neighbor / point", -1 },
187  { SWS_SINC, "sinc", 20 /* infinite ;) */ },
188  { SWS_SPLINE, "bicubic spline", 20 /* infinite :)*/ },
189  { SWS_X, "experimental", 8 },
190 };
191 
192 static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
193  int *outFilterSize, int xInc, int srcW,
194  int dstW, int filterAlign, int one,
195  int flags, int cpu_flags,
196  SwsVector *srcFilter, SwsVector *dstFilter,
197  double param[2], int srcPos, int dstPos)
198 {
199  int i;
200  int filterSize;
201  int filter2Size;
202  int minFilterSize;
203  int64_t *filter = NULL;
204  int64_t *filter2 = NULL;
205  const int64_t fone = 1LL << (54 - FFMIN(av_log2(srcW/dstW), 8));
206  int ret = -1;
207 
208  emms_c(); // FIXME should not be required but IS (even for non-MMX versions)
209 
210  // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end
211  if (!FF_ALLOC_TYPED_ARRAY(*filterPos, dstW + 3))
212  goto nomem;
213 
214  if (FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) { // unscaled
215  int i;
216  filterSize = 1;
217  if (!FF_ALLOCZ_TYPED_ARRAY(filter, dstW * filterSize))
218  goto nomem;
219 
220  for (i = 0; i < dstW; i++) {
221  filter[i * filterSize] = fone;
222  (*filterPos)[i] = i;
223  }
224  } else if (flags & SWS_POINT) { // lame looking point sampling mode
225  int i;
226  int64_t xDstInSrc;
227  filterSize = 1;
228  if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
229  goto nomem;
230 
231  xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
232  for (i = 0; i < dstW; i++) {
233  int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
234 
235  (*filterPos)[i] = xx;
236  filter[i] = fone;
237  xDstInSrc += xInc;
238  }
239  } else if ((xInc <= (1 << 16) && (flags & SWS_AREA)) ||
240  (flags & SWS_FAST_BILINEAR)) { // bilinear upscale
241  int i;
242  int64_t xDstInSrc;
243  filterSize = 2;
244  if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
245  goto nomem;
246 
247  xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
248  for (i = 0; i < dstW; i++) {
249  int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
250  int j;
251 
252  (*filterPos)[i] = xx;
253  // bilinear upscale / linear interpolate / area averaging
254  for (j = 0; j < filterSize; j++) {
255  int64_t coeff = fone - FFABS((int64_t)xx * (1 << 16) - xDstInSrc) * (fone >> 16);
256  if (coeff < 0)
257  coeff = 0;
258  filter[i * filterSize + j] = coeff;
259  xx++;
260  }
261  xDstInSrc += xInc;
262  }
263  } else {
264  int64_t xDstInSrc;
265  int sizeFactor = -1;
266 
267  for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
268  if (flags & scale_algorithms[i].flag && scale_algorithms[i].size_factor > 0) {
269  sizeFactor = scale_algorithms[i].size_factor;
270  break;
271  }
272  }
273  if (flags & SWS_LANCZOS)
274  sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;
275  av_assert0(sizeFactor > 0);
276 
277  if (xInc <= 1 << 16)
278  filterSize = 1 + sizeFactor; // upscale
279  else
280  filterSize = 1 + (sizeFactor * srcW + dstW - 1) / dstW;
281 
282  filterSize = FFMIN(filterSize, srcW - 2);
283  filterSize = FFMAX(filterSize, 1);
284 
285  if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
286  goto nomem;
287  xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7);
288  for (i = 0; i < dstW; i++) {
289  int xx = (xDstInSrc - (filterSize - 2) * (1LL<<16)) / (1 << 17);
290  int j;
291  (*filterPos)[i] = xx;
292  for (j = 0; j < filterSize; j++) {
293  int64_t d = (FFABS(((int64_t)xx * (1 << 17)) - xDstInSrc)) << 13;
294  double floatd;
295  int64_t coeff;
296 
297  if (xInc > 1 << 16)
298  d = d * dstW / srcW;
299  floatd = d * (1.0 / (1 << 30));
300 
301  if (flags & SWS_BICUBIC) {
302  int64_t B = (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1 << 24);
303  int64_t C = (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1 << 24);
304 
305  if (d >= 1LL << 31) {
306  coeff = 0.0;
307  } else {
308  int64_t dd = (d * d) >> 30;
309  int64_t ddd = (dd * d) >> 30;
310 
311  if (d < 1LL << 30)
312  coeff = (12 * (1 << 24) - 9 * B - 6 * C) * ddd +
313  (-18 * (1 << 24) + 12 * B + 6 * C) * dd +
314  (6 * (1 << 24) - 2 * B) * (1 << 30);
315  else
316  coeff = (-B - 6 * C) * ddd +
317  (6 * B + 30 * C) * dd +
318  (-12 * B - 48 * C) * d +
319  (8 * B + 24 * C) * (1 << 30);
320  }
321  coeff /= (1LL<<54)/fone;
322  } else if (flags & SWS_X) {
323  double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;
324  double c;
325 
326  if (floatd < 1.0)
327  c = cos(floatd * M_PI);
328  else
329  c = -1.0;
330  if (c < 0.0)
331  c = -pow(-c, A);
332  else
333  c = pow(c, A);
334  coeff = (c * 0.5 + 0.5) * fone;
335  } else if (flags & SWS_AREA) {
336  int64_t d2 = d - (1 << 29);
337  if (d2 * xInc < -(1LL << (29 + 16)))
338  coeff = 1.0 * (1LL << (30 + 16));
339  else if (d2 * xInc < (1LL << (29 + 16)))
340  coeff = -d2 * xInc + (1LL << (29 + 16));
341  else
342  coeff = 0.0;
343  coeff *= fone >> (30 + 16);
344  } else if (flags & SWS_GAUSS) {
345  double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
346  coeff = exp2(-p * floatd * floatd) * fone;
347  } else if (flags & SWS_SINC) {
348  coeff = (d ? sin(floatd * M_PI) / (floatd * M_PI) : 1.0) * fone;
349  } else if (flags & SWS_LANCZOS) {
350  double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
351  coeff = (d ? sin(floatd * M_PI) * sin(floatd * M_PI / p) /
352  (floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;
353  if (floatd > p)
354  coeff = 0;
355  } else if (flags & SWS_BILINEAR) {
356  coeff = (1 << 30) - d;
357  if (coeff < 0)
358  coeff = 0;
359  coeff *= fone >> 30;
360  } else if (flags & SWS_SPLINE) {
361  double p = -2.196152422706632;
362  coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;
363  } else {
364  av_assert0(0);
365  }
366 
367  filter[i * filterSize + j] = coeff;
368  xx++;
369  }
370  xDstInSrc += 2LL * xInc;
371  }
372  }
373 
374  /* apply src & dst Filter to filter -> filter2
375  * av_free(filter);
376  */
377  av_assert0(filterSize > 0);
378  filter2Size = filterSize;
379  if (srcFilter)
380  filter2Size += srcFilter->length - 1;
381  if (dstFilter)
382  filter2Size += dstFilter->length - 1;
383  av_assert0(filter2Size > 0);
384  if (!FF_ALLOCZ_TYPED_ARRAY(filter2, dstW * filter2Size))
385  goto nomem;
386  for (i = 0; i < dstW; i++) {
387  int j, k;
388 
389  if (srcFilter) {
390  for (k = 0; k < srcFilter->length; k++) {
391  for (j = 0; j < filterSize; j++)
392  filter2[i * filter2Size + k + j] +=
393  srcFilter->coeff[k] * filter[i * filterSize + j];
394  }
395  } else {
396  for (j = 0; j < filterSize; j++)
397  filter2[i * filter2Size + j] = filter[i * filterSize + j];
398  }
399  // FIXME dstFilter
400 
401  (*filterPos)[i] += (filterSize - 1) / 2 - (filter2Size - 1) / 2;
402  }
403  av_freep(&filter);
404 
405  /* try to reduce the filter-size (step1 find size and shift left) */
406  // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not).
407  minFilterSize = 0;
408  for (i = dstW - 1; i >= 0; i--) {
409  int min = filter2Size;
410  int j;
411  int64_t cutOff = 0.0;
412 
413  /* get rid of near zero elements on the left by shifting left */
414  for (j = 0; j < filter2Size; j++) {
415  int k;
416  cutOff += FFABS(filter2[i * filter2Size]);
417 
418  if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
419  break;
420 
421  /* preserve monotonicity because the core can't handle the
422  * filter otherwise */
423  if (i < dstW - 1 && (*filterPos)[i] >= (*filterPos)[i + 1])
424  break;
425 
426  // move filter coefficients left
427  for (k = 1; k < filter2Size; k++)
428  filter2[i * filter2Size + k - 1] = filter2[i * filter2Size + k];
429  filter2[i * filter2Size + k - 1] = 0;
430  (*filterPos)[i]++;
431  }
432 
433  cutOff = 0;
434  /* count near zeros on the right */
435  for (j = filter2Size - 1; j > 0; j--) {
436  cutOff += FFABS(filter2[i * filter2Size + j]);
437 
438  if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
439  break;
440  min--;
441  }
442 
443  if (min > minFilterSize)
444  minFilterSize = min;
445  }
446 
447  if (PPC_ALTIVEC(cpu_flags)) {
448  // we can handle the special case 4, so we don't want to go the full 8
449  if (minFilterSize < 5)
450  filterAlign = 4;
451 
452  /* We really don't want to waste our time doing useless computation, so
453  * fall back on the scalar C code for very small filters.
454  * Vectorizing is worth it only if you have a decent-sized vector. */
455  if (minFilterSize < 3)
456  filterAlign = 1;
457  }
458 
459  if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX || have_neon(cpu_flags)) {
460  // special case for unscaled vertical filtering
461  if (minFilterSize == 1 && filterAlign == 2)
462  filterAlign = 1;
463  }
464 
466  int reNum = minFilterSize & (0x07);
467 
468  if (minFilterSize < 5)
469  filterAlign = 4;
470  if (reNum < 3)
471  filterAlign = 1;
472  }
473 
474  av_assert0(minFilterSize > 0);
475  filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));
476  av_assert0(filterSize > 0);
477  filter = av_malloc_array(dstW, filterSize * sizeof(*filter));
478  if (!filter)
479  goto nomem;
480  if (filterSize >= MAX_FILTER_SIZE * 16 /
481  ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16)) {
483  goto fail;
484  }
485  *outFilterSize = filterSize;
486 
487  if (flags & SWS_PRINT_INFO)
489  "SwScaler: reducing / aligning filtersize %d -> %d\n",
490  filter2Size, filterSize);
491  /* try to reduce the filter-size (step2 reduce it) */
492  for (i = 0; i < dstW; i++) {
493  int j;
494 
495  for (j = 0; j < filterSize; j++) {
496  if (j >= filter2Size)
497  filter[i * filterSize + j] = 0;
498  else
499  filter[i * filterSize + j] = filter2[i * filter2Size + j];
500  if ((flags & SWS_BITEXACT) && j >= minFilterSize)
501  filter[i * filterSize + j] = 0;
502  }
503  }
504 
505  // FIXME try to align filterPos if possible
506 
507  // fix borders
508  for (i = 0; i < dstW; i++) {
509  int j;
510  if ((*filterPos)[i] < 0) {
511  // move filter coefficients left to compensate for filterPos
512  for (j = 1; j < filterSize; j++) {
513  int left = FFMAX(j + (*filterPos)[i], 0);
514  filter[i * filterSize + left] += filter[i * filterSize + j];
515  filter[i * filterSize + j] = 0;
516  }
517  (*filterPos)[i]= 0;
518  }
519 
520  if ((*filterPos)[i] + filterSize > srcW) {
521  int shift = (*filterPos)[i] + FFMIN(filterSize - srcW, 0);
522  int64_t acc = 0;
523 
524  for (j = filterSize - 1; j >= 0; j--) {
525  if ((*filterPos)[i] + j >= srcW) {
526  acc += filter[i * filterSize + j];
527  filter[i * filterSize + j] = 0;
528  }
529  }
530  for (j = filterSize - 1; j >= 0; j--) {
531  if (j < shift) {
532  filter[i * filterSize + j] = 0;
533  } else {
534  filter[i * filterSize + j] = filter[i * filterSize + j - shift];
535  }
536  }
537 
538  (*filterPos)[i]-= shift;
539  filter[i * filterSize + srcW - 1 - (*filterPos)[i]] += acc;
540  }
541  av_assert0((*filterPos)[i] >= 0);
542  av_assert0((*filterPos)[i] < srcW);
543  if ((*filterPos)[i] + filterSize > srcW) {
544  for (j = 0; j < filterSize; j++) {
545  av_assert0((*filterPos)[i] + j < srcW || !filter[i * filterSize + j]);
546  }
547  }
548  }
549 
550  // Note the +1 is for the MMX scaler which reads over the end
551  /* align at 16 for AltiVec (needed by hScale_altivec_real) */
552  if (!FF_ALLOCZ_TYPED_ARRAY(*outFilter, *outFilterSize * (dstW + 3)))
553  goto nomem;
554 
555  /* normalize & store in outFilter */
556  for (i = 0; i < dstW; i++) {
557  int j;
558  int64_t error = 0;
559  int64_t sum = 0;
560 
561  for (j = 0; j < filterSize; j++) {
562  sum += filter[i * filterSize + j];
563  }
564  sum = (sum + one / 2) / one;
565  if (!sum) {
566  av_log(NULL, AV_LOG_WARNING, "SwScaler: zero vector in scaling\n");
567  sum = 1;
568  }
569  for (j = 0; j < *outFilterSize; j++) {
570  int64_t v = filter[i * filterSize + j] + error;
571  int intV = ROUNDED_DIV(v, sum);
572  (*outFilter)[i * (*outFilterSize) + j] = intV;
573  error = v - intV * sum;
574  }
575  }
576 
577  (*filterPos)[dstW + 0] =
578  (*filterPos)[dstW + 1] =
579  (*filterPos)[dstW + 2] = (*filterPos)[dstW - 1]; /* the MMX/SSE scaler will
580  * read over the end */
581  for (i = 0; i < *outFilterSize; i++) {
582  int k = (dstW - 1) * (*outFilterSize) + i;
583  (*outFilter)[k + 1 * (*outFilterSize)] =
584  (*outFilter)[k + 2 * (*outFilterSize)] =
585  (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];
586  }
587 
588  ret = 0;
589  goto done;
590 nomem:
591  ret = AVERROR(ENOMEM);
592 fail:
593  if(ret < 0)
594  av_log(NULL, ret == RETCODE_USE_CASCADE ? AV_LOG_DEBUG : AV_LOG_ERROR, "sws: initFilter failed\n");
595 done:
596  av_free(filter);
597  av_free(filter2);
598  return ret;
599 }
600 
601 static void fill_rgb2yuv_table(SwsInternal *c, const int table[4], int dstRange)
602 {
603  int64_t W, V, Z, Cy, Cu, Cv;
604  int64_t vr = table[0];
605  int64_t ub = table[1];
606  int64_t ug = -table[2];
607  int64_t vg = -table[3];
608  int64_t ONE = 65536;
609  int64_t cy = ONE;
610  uint8_t *p = (uint8_t*)c->input_rgb2yuv_table;
611  int i;
612  static const int8_t map[] = {
613  BY_IDX, GY_IDX, -1 , BY_IDX, BY_IDX, GY_IDX, -1 , BY_IDX,
614  RY_IDX, -1 , GY_IDX, RY_IDX, RY_IDX, -1 , GY_IDX, RY_IDX,
615  RY_IDX, GY_IDX, -1 , RY_IDX, RY_IDX, GY_IDX, -1 , RY_IDX,
616  BY_IDX, -1 , GY_IDX, BY_IDX, BY_IDX, -1 , GY_IDX, BY_IDX,
617  BU_IDX, GU_IDX, -1 , BU_IDX, BU_IDX, GU_IDX, -1 , BU_IDX,
618  RU_IDX, -1 , GU_IDX, RU_IDX, RU_IDX, -1 , GU_IDX, RU_IDX,
619  RU_IDX, GU_IDX, -1 , RU_IDX, RU_IDX, GU_IDX, -1 , RU_IDX,
620  BU_IDX, -1 , GU_IDX, BU_IDX, BU_IDX, -1 , GU_IDX, BU_IDX,
621  BV_IDX, GV_IDX, -1 , BV_IDX, BV_IDX, GV_IDX, -1 , BV_IDX,
622  RV_IDX, -1 , GV_IDX, RV_IDX, RV_IDX, -1 , GV_IDX, RV_IDX,
623  RV_IDX, GV_IDX, -1 , RV_IDX, RV_IDX, GV_IDX, -1 , RV_IDX,
624  BV_IDX, -1 , GV_IDX, BV_IDX, BV_IDX, -1 , GV_IDX, BV_IDX,
627  GY_IDX, -1 , GY_IDX, -1 , GY_IDX, -1 , GY_IDX, -1 ,
628  -1 , GY_IDX, -1 , GY_IDX, -1 , GY_IDX, -1 , GY_IDX,
631  GU_IDX, -1 , GU_IDX, -1 , GU_IDX, -1 , GU_IDX, -1 ,
632  -1 , GU_IDX, -1 , GU_IDX, -1 , GU_IDX, -1 , GU_IDX,
635  GV_IDX, -1 , GV_IDX, -1 , GV_IDX, -1 , GV_IDX, -1 ,
636  -1 , GV_IDX, -1 , GV_IDX, -1 , GV_IDX, -1 , GV_IDX, //23
637  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //24
638  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //25
639  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //26
640  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //27
641  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //28
642  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //29
643  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //30
644  -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , //31
645  BY_IDX, GY_IDX, RY_IDX, -1 , -1 , -1 , -1 , -1 , //32
646  BU_IDX, GU_IDX, RU_IDX, -1 , -1 , -1 , -1 , -1 , //33
647  BV_IDX, GV_IDX, RV_IDX, -1 , -1 , -1 , -1 , -1 , //34
648  };
649 
650  dstRange = 0; //FIXME range = 1 is handled elsewhere
651 
652  if (!dstRange) {
653  cy = cy * 255 / 219;
654  } else {
655  vr = vr * 224 / 255;
656  ub = ub * 224 / 255;
657  ug = ug * 224 / 255;
658  vg = vg * 224 / 255;
659  }
660  W = ROUNDED_DIV(ONE*ONE*ug, ub);
661  V = ROUNDED_DIV(ONE*ONE*vg, vr);
662  Z = ONE*ONE-W-V;
663 
664  Cy = ROUNDED_DIV(cy*Z, ONE);
665  Cu = ROUNDED_DIV(ub*Z, ONE);
666  Cv = ROUNDED_DIV(vr*Z, ONE);
667 
668  c->input_rgb2yuv_table[RY_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*V , Cy);
669  c->input_rgb2yuv_table[GY_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*ONE*ONE , Cy);
670  c->input_rgb2yuv_table[BY_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*W , Cy);
671 
672  c->input_rgb2yuv_table[RU_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*V , Cu);
673  c->input_rgb2yuv_table[GU_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*ONE*ONE , Cu);
674  c->input_rgb2yuv_table[BU_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*(Z+W) , Cu);
675 
676  c->input_rgb2yuv_table[RV_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*(V+Z) , Cv);
677  c->input_rgb2yuv_table[GV_IDX] = -ROUNDED_DIV((1 << RGB2YUV_SHIFT)*ONE*ONE , Cv);
678  c->input_rgb2yuv_table[BV_IDX] = ROUNDED_DIV((1 << RGB2YUV_SHIFT)*W , Cv);
679 
680  if(/*!dstRange && */!memcmp(table, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], sizeof(ff_yuv2rgb_coeffs[SWS_CS_DEFAULT]))) {
681  c->input_rgb2yuv_table[BY_IDX] = ((int)(0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
682  c->input_rgb2yuv_table[BV_IDX] = (-(int)(0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
683  c->input_rgb2yuv_table[BU_IDX] = ((int)(0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
684  c->input_rgb2yuv_table[GY_IDX] = ((int)(0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
685  c->input_rgb2yuv_table[GV_IDX] = (-(int)(0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
686  c->input_rgb2yuv_table[GU_IDX] = (-(int)(0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
687  c->input_rgb2yuv_table[RY_IDX] = ((int)(0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
688  c->input_rgb2yuv_table[RV_IDX] = ((int)(0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
689  c->input_rgb2yuv_table[RU_IDX] = (-(int)(0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
690  }
691  for(i=0; i<FF_ARRAY_ELEMS(map); i++)
692  AV_WL16(p + 16*4 + 2*i, map[i] >= 0 ? c->input_rgb2yuv_table[map[i]] : 0);
693 }
694 
695 #if CONFIG_SMALL
696 static void init_xyz_tables(uint16_t xyzgamma_tab[4096], uint16_t xyzgammainv_tab[65536],
697  uint16_t rgbgamma_tab[65536], uint16_t rgbgammainv_tab[4096])
698 #else
699 static uint16_t xyzgamma_tab[4096], rgbgammainv_tab[4096];
700 static uint16_t rgbgamma_tab[65536], xyzgammainv_tab[65536];
701 static av_cold void init_xyz_tables(void)
702 #endif
703 {
704  double xyzgamma = XYZ_GAMMA;
705  double rgbgamma = 1.0 / RGB_GAMMA;
706  double xyzgammainv = 1.0 / XYZ_GAMMA;
707  double rgbgammainv = RGB_GAMMA;
708 
709  /* set input gamma vectors */
710  for (int i = 0; i < 4096; i++) {
711  xyzgamma_tab[i] = lrint(pow(i / 4095.0, xyzgamma) * 65535.0);
712  rgbgammainv_tab[i] = lrint(pow(i / 4095.0, rgbgammainv) * 65535.0);
713  }
714 
715  /* set output gamma vectors */
716  for (int i = 0; i < 65536; i++) {
717  rgbgamma_tab[i] = lrint(pow(i / 65535.0, rgbgamma) * 4095.0);
718  xyzgammainv_tab[i] = lrint(pow(i / 65535.0, xyzgammainv) * 4095.0);
719  }
720 }
721 
723 {
724  static const int16_t xyz2rgb_matrix[3][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_GBRP10MSBBE && srcFormat != AV_PIX_FMT_GBRP10MSBLE &&
1338  srcFormat != AV_PIX_FMT_GBRAP10BE && srcFormat != AV_PIX_FMT_GBRAP10LE &&
1339  srcFormat != AV_PIX_FMT_GBRP12BE && srcFormat != AV_PIX_FMT_GBRP12LE &&
1340  srcFormat != AV_PIX_FMT_GBRP12MSBBE && srcFormat != AV_PIX_FMT_GBRP12MSBLE &&
1341  srcFormat != AV_PIX_FMT_GBRAP12BE && srcFormat != AV_PIX_FMT_GBRAP12LE &&
1342  srcFormat != AV_PIX_FMT_GBRAP14BE && srcFormat != AV_PIX_FMT_GBRAP14LE &&
1343  srcFormat != AV_PIX_FMT_GBRP14BE && srcFormat != AV_PIX_FMT_GBRP14LE &&
1344  srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE &&
1345  srcFormat != AV_PIX_FMT_GBRAP16BE && srcFormat != AV_PIX_FMT_GBRAP16LE &&
1346  srcFormat != AV_PIX_FMT_GBRPF32BE && srcFormat != AV_PIX_FMT_GBRPF32LE &&
1347  srcFormat != AV_PIX_FMT_GBRAPF32BE && srcFormat != AV_PIX_FMT_GBRAPF32LE &&
1348  srcFormat != AV_PIX_FMT_GBRPF16BE && srcFormat != AV_PIX_FMT_GBRPF16LE &&
1349  srcFormat != AV_PIX_FMT_GBRAPF16BE && srcFormat != AV_PIX_FMT_GBRAPF16LE &&
1350  ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
1351  (flags & SWS_FAST_BILINEAR)))
1352  c->chrSrcHSubSample = 1;
1353 
1354  // Note the AV_CEIL_RSHIFT is so that we always round toward +inf.
1355  c->chrSrcW = AV_CEIL_RSHIFT(srcW, c->chrSrcHSubSample);
1356  c->chrSrcH = AV_CEIL_RSHIFT(srcH, c->chrSrcVSubSample);
1357  c->chrDstW = AV_CEIL_RSHIFT(dstW, c->chrDstHSubSample);
1358  c->chrDstH = AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample);
1359 
1360  if (!FF_ALLOCZ_TYPED_ARRAY(c->formatConvBuffer, FFALIGN(srcW * 2 + 78, 16) * 2))
1361  goto nomem;
1362 
1363  c->srcBpc = desc_src->comp[0].depth;
1364  if (c->srcBpc < 8)
1365  c->srcBpc = 8;
1366  c->dstBpc = desc_dst->comp[0].depth;
1367  if (c->dstBpc < 8)
1368  c->dstBpc = 8;
1369  if (isAnyRGB(srcFormat) || srcFormat == AV_PIX_FMT_PAL8)
1370  c->srcBpc = 16;
1371  if (c->dstBpc == 16)
1372  dst_stride <<= 1;
1373 
1374  if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 14) {
1375  c->canMMXEXTBeUsed = dstW >= srcW && (dstW & 31) == 0 &&
1376  c->chrDstW >= c->chrSrcW &&
1377  (srcW & 15) == 0;
1378  if (!c->canMMXEXTBeUsed && dstW >= srcW && c->chrDstW >= c->chrSrcW && (srcW & 15) == 0
1379 
1380  && (flags & SWS_FAST_BILINEAR)) {
1381  if (flags & SWS_PRINT_INFO)
1382  av_log(c, AV_LOG_INFO,
1383  "output width is not a multiple of 32 -> no MMXEXT scaler\n");
1384  }
1385  if (usesHFilter || isNBPS(sws->src_format) || is16BPS(sws->src_format) || isAnyRGB(sws->src_format))
1386  c->canMMXEXTBeUsed = 0;
1387  } else
1388  c->canMMXEXTBeUsed = 0;
1389 
1390  c->chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW;
1391  c->chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH;
1392 
1393  /* Match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src
1394  * to pixel n-2 of dst, but only for the FAST_BILINEAR mode otherwise do
1395  * correct scaling.
1396  * n-2 is the last chrominance sample available.
1397  * This is not perfect, but no one should notice the difference, the more
1398  * correct variant would be like the vertical one, but that would require
1399  * some special code for the first and last pixel */
1400  if (flags & SWS_FAST_BILINEAR) {
1401  if (c->canMMXEXTBeUsed) {
1402  c->lumXInc += 20;
1403  c->chrXInc += 20;
1404  }
1405  // we don't use the x86 asm scaler if MMX is available
1406  else if (INLINE_MMX(cpu_flags) && c->dstBpc <= 14) {
1407  c->lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20;
1408  c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20;
1409  }
1410  }
1411 
1412  // hardcoded for now
1413  c->gamma_value = 2.2;
1414  tmpFmt = AV_PIX_FMT_RGBA64LE;
1415 
1416  if (!unscaled && sws->gamma_flag && (srcFormat != tmpFmt || dstFormat != tmpFmt)) {
1417  SwsInternal *c2;
1418  c->cascaded_context[0] = NULL;
1419 
1420  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1421  srcW, srcH, tmpFmt, 64);
1422  if (ret < 0)
1423  return ret;
1424 
1425  c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
1426  srcW, srcH, tmpFmt,
1427  flags, NULL, NULL,
1428  sws->scaler_params);
1429  if (!c->cascaded_context[0]) {
1430  return AVERROR(ENOMEM);
1431  }
1432 
1433  c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFmt,
1434  dstW, dstH, tmpFmt,
1435  flags, srcFilter, dstFilter,
1436  sws->scaler_params);
1437 
1438  if (!c->cascaded_context[1])
1439  return AVERROR(ENOMEM);
1440 
1441  c2 = sws_internal(c->cascaded_context[1]);
1442  c2->is_internal_gamma = 1;
1443  c2->gamma = alloc_gamma_tbl( c->gamma_value);
1444  c2->inv_gamma = alloc_gamma_tbl(1.f/c->gamma_value);
1445  if (!c2->gamma || !c2->inv_gamma)
1446  return AVERROR(ENOMEM);
1447 
1448  // is_internal_flag is set after creating the context
1449  // to properly create the gamma convert FilterDescriptor
1450  // we have to re-initialize it
1452  if ((ret = ff_init_filters(c2)) < 0) {
1453  sws_freeContext(c->cascaded_context[1]);
1454  c->cascaded_context[1] = NULL;
1455  return ret;
1456  }
1457 
1458  c->cascaded_context[2] = NULL;
1459  if (dstFormat != tmpFmt) {
1460  ret = av_image_alloc(c->cascaded_tmp[1], c->cascaded_tmpStride[1],
1461  dstW, dstH, tmpFmt, 64);
1462  if (ret < 0)
1463  return ret;
1464 
1465  c->cascaded_context[2] = sws_getContext(dstW, dstH, tmpFmt,
1466  dstW, dstH, dstFormat,
1467  flags, NULL, NULL,
1468  sws->scaler_params);
1469  if (!c->cascaded_context[2])
1470  return AVERROR(ENOMEM);
1471  }
1472  return 0;
1473  }
1474 
1475  if (isBayer(srcFormat)) {
1476  if (!unscaled ||
1477  (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P &&
1478  dstFormat != AV_PIX_FMT_RGB48)) {
1479  enum AVPixelFormat tmpFormat = isBayer16BPS(srcFormat) ? AV_PIX_FMT_RGB48 : AV_PIX_FMT_RGB24;
1480 
1481  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1482  srcW, srcH, tmpFormat, 64);
1483  if (ret < 0)
1484  return ret;
1485 
1486  c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
1487  srcW, srcH, tmpFormat,
1488  flags, srcFilter, NULL,
1489  sws->scaler_params);
1490  if (!c->cascaded_context[0])
1491  return AVERROR(ENOMEM);
1492 
1493  c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat,
1494  dstW, dstH, dstFormat,
1495  flags, NULL, dstFilter,
1496  sws->scaler_params);
1497  if (!c->cascaded_context[1])
1498  return AVERROR(ENOMEM);
1499  return 0;
1500  }
1501  }
1502 
1503  if (unscaled && c->srcBpc == 8 && dstFormat == AV_PIX_FMT_GRAYF32){
1504  for (i = 0; i < 256; ++i){
1505  c->uint2float_lut[i] = (float)i * float_mult;
1506  }
1507  }
1508 
1509  // float will be converted to uint16_t
1510  if ((srcFormat == AV_PIX_FMT_GRAYF32BE || srcFormat == AV_PIX_FMT_GRAYF32LE) &&
1511  (!unscaled || unscaled && dstFormat != srcFormat && (srcFormat != AV_PIX_FMT_GRAYF32 ||
1512  dstFormat != AV_PIX_FMT_GRAY8))){
1513  c->srcBpc = 16;
1514  }
1515 
1516  if (CONFIG_SWSCALE_ALPHA && isALPHA(srcFormat) && !isALPHA(dstFormat)) {
1517  enum AVPixelFormat tmpFormat = alphaless_fmt(srcFormat);
1518 
1519  if (tmpFormat != AV_PIX_FMT_NONE && sws->alpha_blend != SWS_ALPHA_BLEND_NONE) {
1520  if (!unscaled ||
1521  dstFormat != tmpFormat ||
1522  usesHFilter || usesVFilter ||
1523  sws->src_range != sws->dst_range
1524  ) {
1525  c->cascaded_mainindex = 1;
1526  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1527  srcW, srcH, tmpFormat, 64);
1528  if (ret < 0)
1529  return ret;
1530 
1531  c->cascaded_context[0] = alloc_set_opts(srcW, srcH, srcFormat,
1532  srcW, srcH, tmpFormat,
1533  flags, sws->scaler_params);
1534  if (!c->cascaded_context[0])
1535  return AVERROR(EINVAL);
1536  c->cascaded_context[0]->alpha_blend = sws->alpha_blend;
1537  ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
1538  if (ret < 0)
1539  return ret;
1540 
1541  c->cascaded_context[1] = alloc_set_opts(srcW, srcH, tmpFormat,
1542  dstW, dstH, dstFormat,
1543  flags, sws->scaler_params);
1544  if (!c->cascaded_context[1])
1545  return AVERROR(EINVAL);
1546 
1547  c->cascaded_context[1]->src_range = sws->src_range;
1548  c->cascaded_context[1]->dst_range = sws->dst_range;
1549  ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter);
1550  if (ret < 0)
1551  return ret;
1552 
1553  return 0;
1554  }
1555  }
1556  }
1557 
1558  /* alpha blend special case, note this has been split via cascaded contexts if its scaled */
1559  if (unscaled && !usesHFilter && !usesVFilter &&
1561  isALPHA(srcFormat) &&
1562  (sws->src_range == sws->dst_range || isAnyRGB(dstFormat)) &&
1563  alphaless_fmt(srcFormat) == dstFormat
1564  ) {
1565  c->convert_unscaled = ff_sws_alphablendaway;
1566 
1567  if (flags & SWS_PRINT_INFO)
1568  av_log(c, AV_LOG_INFO,
1569  "using alpha blendaway %s -> %s special converter\n",
1570  av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1571  return 0;
1572  }
1573 
1574  /* unscaled special cases */
1575  if (unscaled && !usesHFilter && !usesVFilter &&
1576  (sws->src_range == sws->dst_range || isAnyRGB(dstFormat) ||
1577  isFloat(srcFormat) || isFloat(dstFormat) || isBayer(srcFormat))){
1578 
1580 
1581  if (c->convert_unscaled) {
1582  if (flags & SWS_PRINT_INFO)
1583  av_log(c, AV_LOG_INFO,
1584  "using unscaled %s -> %s special converter\n",
1585  av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1586  return 0;
1587  }
1588  }
1589 
1590 #if HAVE_MMAP && HAVE_MPROTECT && defined(MAP_ANONYMOUS)
1591 #define USE_MMAP 1
1592 #else
1593 #define USE_MMAP 0
1594 #endif
1595 
1596  /* precalculate horizontal scaler filter coefficients */
1597  {
1598 #if HAVE_MMXEXT_INLINE
1599 // can't downscale !!!
1600  if (c->canMMXEXTBeUsed && (flags & SWS_FAST_BILINEAR)) {
1601  c->lumMmxextFilterCodeSize = ff_init_hscaler_mmxext(dstW, c->lumXInc, NULL,
1602  NULL, NULL, 8);
1603  c->chrMmxextFilterCodeSize = ff_init_hscaler_mmxext(c->chrDstW, c->chrXInc,
1604  NULL, NULL, NULL, 4);
1605 
1606 #if USE_MMAP
1607  c->lumMmxextFilterCode = mmap(NULL, c->lumMmxextFilterCodeSize,
1608  PROT_READ | PROT_WRITE,
1609  MAP_PRIVATE | MAP_ANONYMOUS,
1610  -1, 0);
1611  c->chrMmxextFilterCode = mmap(NULL, c->chrMmxextFilterCodeSize,
1612  PROT_READ | PROT_WRITE,
1613  MAP_PRIVATE | MAP_ANONYMOUS,
1614  -1, 0);
1615 #elif HAVE_VIRTUALALLOC
1616  c->lumMmxextFilterCode = VirtualAlloc(NULL,
1617  c->lumMmxextFilterCodeSize,
1618  MEM_COMMIT,
1619  PAGE_EXECUTE_READWRITE);
1620  c->chrMmxextFilterCode = VirtualAlloc(NULL,
1621  c->chrMmxextFilterCodeSize,
1622  MEM_COMMIT,
1623  PAGE_EXECUTE_READWRITE);
1624 #else
1625  c->lumMmxextFilterCode = av_malloc(c->lumMmxextFilterCodeSize);
1626  c->chrMmxextFilterCode = av_malloc(c->chrMmxextFilterCodeSize);
1627 #endif
1628 
1629 #ifdef MAP_ANONYMOUS
1630  if (c->lumMmxextFilterCode == MAP_FAILED || c->chrMmxextFilterCode == MAP_FAILED)
1631 #else
1632  if (!c->lumMmxextFilterCode || !c->chrMmxextFilterCode)
1633 #endif
1634  {
1635  av_log(c, AV_LOG_ERROR, "Failed to allocate MMX2FilterCode\n");
1636  return AVERROR(ENOMEM);
1637  }
1638 
1639  if (!FF_ALLOCZ_TYPED_ARRAY(c->hLumFilter, dstW / 8 + 8) ||
1640  !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilter, c->chrDstW / 4 + 8) ||
1641  !FF_ALLOCZ_TYPED_ARRAY(c->hLumFilterPos, dstW / 2 / 8 + 8) ||
1642  !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilterPos, c->chrDstW / 2 / 4 + 8))
1643  goto nomem;
1644 
1645  ff_init_hscaler_mmxext( dstW, c->lumXInc, c->lumMmxextFilterCode,
1646  c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8);
1647  ff_init_hscaler_mmxext(c->chrDstW, c->chrXInc, c->chrMmxextFilterCode,
1648  c->hChrFilter, (uint32_t*)c->hChrFilterPos, 4);
1649 
1650 #if USE_MMAP
1651  if ( mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1
1652  || mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1) {
1653  av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast bilinear scaler\n");
1654  ret = AVERROR(EINVAL);
1655  goto fail;
1656  }
1657 #endif
1658  } else
1659 #endif /* HAVE_MMXEXT_INLINE */
1660  {
1661  const int filterAlign = X86_MMX(cpu_flags) ? 4 :
1662  PPC_ALTIVEC(cpu_flags) ? 8 :
1663  have_neon(cpu_flags) ? 4 :
1664  have_lsx(cpu_flags) ? 8 :
1665  have_lasx(cpu_flags) ? 8 : 1;
1666 
1667  if ((ret = initFilter(&c->hLumFilter, &c->hLumFilterPos,
1668  &c->hLumFilterSize, c->lumXInc,
1669  srcW, dstW, filterAlign, 1 << 14,
1671  cpu_flags, srcFilter->lumH, dstFilter->lumH,
1672  sws->scaler_params,
1673  get_local_pos(c, 0, 0, 0),
1674  get_local_pos(c, 0, 0, 0))) < 0)
1675  goto fail;
1676  if (ff_shuffle_filter_coefficients(c, c->hLumFilterPos, c->hLumFilterSize, c->hLumFilter, dstW) < 0)
1677  goto nomem;
1678  if ((ret = initFilter(&c->hChrFilter, &c->hChrFilterPos,
1679  &c->hChrFilterSize, c->chrXInc,
1680  c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
1682  cpu_flags, srcFilter->chrH, dstFilter->chrH,
1683  sws->scaler_params,
1684  get_local_pos(c, c->chrSrcHSubSample, sws->src_h_chr_pos, 0),
1685  get_local_pos(c, c->chrDstHSubSample, sws->dst_h_chr_pos, 0))) < 0)
1686  goto fail;
1687  if (ff_shuffle_filter_coefficients(c, c->hChrFilterPos, c->hChrFilterSize, c->hChrFilter, c->chrDstW) < 0)
1688  goto nomem;
1689  }
1690  } // initialize horizontal stuff
1691 
1692  /* precalculate vertical scaler filter coefficients */
1693  {
1694  const int filterAlign = X86_MMX(cpu_flags) ? 2 :
1695  PPC_ALTIVEC(cpu_flags) ? 8 :
1696  have_neon(cpu_flags) ? 2 : 1;
1697 
1698  if ((ret = initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
1699  c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
1701  cpu_flags, srcFilter->lumV, dstFilter->lumV,
1702  sws->scaler_params,
1703  get_local_pos(c, 0, 0, 1),
1704  get_local_pos(c, 0, 0, 1))) < 0)
1705  goto fail;
1706  if ((ret = initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
1707  c->chrYInc, c->chrSrcH, c->chrDstH,
1708  filterAlign, (1 << 12),
1710  cpu_flags, srcFilter->chrV, dstFilter->chrV,
1711  sws->scaler_params,
1712  get_local_pos(c, c->chrSrcVSubSample, sws->src_v_chr_pos, 1),
1713  get_local_pos(c, c->chrDstVSubSample, sws->dst_v_chr_pos, 1))) < 0)
1714 
1715  goto fail;
1716 
1717 #if HAVE_ALTIVEC
1718  if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * sws->dst_h) ||
1719  !FF_ALLOC_TYPED_ARRAY(c->vCCoeffsBank, c->vChrFilterSize * c->chrDstH))
1720  goto nomem;
1721 
1722  for (i = 0; i < c->vLumFilterSize * sws->dst_h; i++) {
1723  int j;
1724  short *p = (short *)&c->vYCoeffsBank[i];
1725  for (j = 0; j < 8; j++)
1726  p[j] = c->vLumFilter[i];
1727  }
1728 
1729  for (i = 0; i < c->vChrFilterSize * c->chrDstH; i++) {
1730  int j;
1731  short *p = (short *)&c->vCCoeffsBank[i];
1732  for (j = 0; j < 8; j++)
1733  p[j] = c->vChrFilter[i];
1734  }
1735 #endif
1736  }
1737 
1738  for (i = 0; i < 4; i++)
1739  if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], sws->dst_w + 3))
1740  goto nomem;
1741 
1742  c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(sws->src_format) && isALPHA(sws->dst_format)) ? 1 : 0;
1743 
1744  // 64 / c->scalingBpp is the same as 16 / sizeof(scaling_intermediate)
1745  c->uv_off = (dst_stride>>1) + 64 / (c->dstBpc &~ 7);
1746  c->uv_offx2 = dst_stride + 16;
1747 
1748  av_assert0(c->chrDstH <= dstH);
1749 
1750  if (flags & SWS_PRINT_INFO) {
1751  const char *scaler = NULL, *cpucaps;
1752 
1753  for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
1754  if (flags & scale_algorithms[i].flag) {
1755  scaler = scale_algorithms[i].description;
1756  break;
1757  }
1758  }
1759  if (!scaler)
1760  scaler = "ehh flags invalid?!";
1761  av_log(c, AV_LOG_INFO, "%s scaler, from %s to %s%s ",
1762  scaler,
1763  av_get_pix_fmt_name(srcFormat),
1764  dstFormat == AV_PIX_FMT_BGR555 || dstFormat == AV_PIX_FMT_BGR565 ||
1765  dstFormat == AV_PIX_FMT_RGB444BE || dstFormat == AV_PIX_FMT_RGB444LE ||
1766  dstFormat == AV_PIX_FMT_BGR444BE || dstFormat == AV_PIX_FMT_BGR444LE ?
1767  "dithered " : "",
1768  av_get_pix_fmt_name(dstFormat));
1769 
1770  if (INLINE_MMXEXT(cpu_flags))
1771  cpucaps = "MMXEXT";
1772  else if (INLINE_MMX(cpu_flags))
1773  cpucaps = "MMX";
1774  else if (PPC_ALTIVEC(cpu_flags))
1775  cpucaps = "AltiVec";
1776  else
1777  cpucaps = "C";
1778 
1779  av_log(c, AV_LOG_INFO, "using %s\n", cpucaps);
1780 
1781  av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
1783  "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1784  sws->src_w, sws->src_h, sws->dst_w, sws->dst_h, c->lumXInc, c->lumYInc);
1786  "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1787  c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH,
1788  c->chrXInc, c->chrYInc);
1789  }
1790 
1792 
1793  return ff_init_filters(c);
1794 nomem:
1795  ret = AVERROR(ENOMEM);
1796 fail: // FIXME replace things by appropriate error codes
1797  if (ret == RETCODE_USE_CASCADE) {
1798  int tmpW = sqrt(srcW * (int64_t)dstW);
1799  int tmpH = sqrt(srcH * (int64_t)dstH);
1800  enum AVPixelFormat tmpFormat = AV_PIX_FMT_YUV420P;
1801 
1802  if (isALPHA(srcFormat))
1803  tmpFormat = AV_PIX_FMT_YUVA420P;
1804 
1805  if (srcW*(int64_t)srcH <= 4LL*dstW*dstH)
1806  return AVERROR(EINVAL);
1807 
1808  ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
1809  tmpW, tmpH, tmpFormat, 64);
1810  if (ret < 0)
1811  return ret;
1812 
1813  c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
1814  tmpW, tmpH, tmpFormat,
1815  flags, srcFilter, NULL,
1816  sws->scaler_params);
1817  if (!c->cascaded_context[0])
1818  return AVERROR(ENOMEM);
1819 
1820  c->cascaded_context[1] = sws_getContext(tmpW, tmpH, tmpFormat,
1821  dstW, dstH, dstFormat,
1822  flags, NULL, dstFilter,
1823  sws->scaler_params);
1824  if (!c->cascaded_context[1])
1825  return AVERROR(ENOMEM);
1826  return 0;
1827  }
1828  return ret;
1829 }
1830 
1832  SwsFilter *src_filter, SwsFilter *dst_filter)
1833 {
1835  int ret;
1836 
1837  ret = avpriv_slicethread_create(&c->slicethread, (void*) sws,
1839  if (ret == AVERROR(ENOSYS)) {
1840  sws->threads = 1;
1841  return 0;
1842  } else if (ret < 0)
1843  return ret;
1844 
1845  sws->threads = ret;
1846 
1847  c->slice_ctx = av_calloc(sws->threads, sizeof(*c->slice_ctx));
1848  c->slice_err = av_calloc(sws->threads, sizeof(*c->slice_err));
1849  if (!c->slice_ctx || !c->slice_err)
1850  return AVERROR(ENOMEM);
1851 
1852  for (int i = 0; i < sws->threads; i++) {
1853  SwsContext *slice;
1854  slice = c->slice_ctx[i] = sws_alloc_context();
1855  if (!slice)
1856  return AVERROR(ENOMEM);
1857  sws_internal(slice)->parent = sws;
1858  c->nb_slice_ctx++;
1859 
1860  ret = av_opt_copy(slice, sws);
1861  if (ret < 0)
1862  return ret;
1863  slice->threads = 1;
1864 
1865  ret = ff_sws_init_single_context(slice, src_filter, dst_filter);
1866  if (ret < 0)
1867  return ret;
1868 
1869  if (slice->dither == SWS_DITHER_ED) {
1871  "Error-diffusion dither is in use, scaling will be single-threaded.");
1872  break;
1873  }
1874  }
1875 
1876  return 0;
1877 }
1878 
1880  SwsFilter *dstFilter)
1881 {
1883  static AVOnce rgb2rgb_once = AV_ONCE_INIT;
1884  enum AVPixelFormat src_format, dst_format;
1885  int ret;
1886 
1887  c->frame_src = av_frame_alloc();
1888  c->frame_dst = av_frame_alloc();
1889  if (!c->frame_src || !c->frame_dst)
1890  return AVERROR(ENOMEM);
1891 
1892  if (ff_thread_once(&rgb2rgb_once, ff_sws_rgb2rgb_init) != 0)
1893  return AVERROR_UNKNOWN;
1894 
1895  src_format = sws->src_format;
1896  dst_format = sws->dst_format;
1899 
1900  if (src_format != sws->src_format || dst_format != sws->dst_format)
1901  av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
1902 
1903  if (sws->threads != 1) {
1904  ret = context_init_threaded(sws, srcFilter, dstFilter);
1905  if (ret < 0 || sws->threads > 1)
1906  return ret;
1907  // threading disabled in this build, init as single-threaded
1908  }
1909 
1910  return ff_sws_init_single_context(sws, srcFilter, dstFilter);
1911 }
1912 
1913 SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
1914  int dstW, int dstH, enum AVPixelFormat dstFormat,
1915  int flags, SwsFilter *srcFilter,
1916  SwsFilter *dstFilter, const double *param)
1917 {
1918  SwsContext *sws;
1919 
1920  sws = alloc_set_opts(srcW, srcH, srcFormat,
1921  dstW, dstH, dstFormat,
1922  flags, param);
1923  if (!sws)
1924  return NULL;
1925 
1926  if (sws_init_context(sws, srcFilter, dstFilter) < 0) {
1928  return NULL;
1929  }
1930 
1931  return sws;
1932 }
1933 
1934 static int isnan_vec(SwsVector *a)
1935 {
1936  int i;
1937  for (i=0; i<a->length; i++)
1938  if (isnan(a->coeff[i]))
1939  return 1;
1940  return 0;
1941 }
1942 
1943 static void makenan_vec(SwsVector *a)
1944 {
1945  int i;
1946  for (i=0; i<a->length; i++)
1947  a->coeff[i] = NAN;
1948 }
1949 
1951 {
1952  SwsVector *vec;
1953 
1954  if(length <= 0 || length > INT_MAX/ sizeof(double))
1955  return NULL;
1956 
1957  vec = av_malloc(sizeof(SwsVector));
1958  if (!vec)
1959  return NULL;
1960  vec->length = length;
1961  vec->coeff = av_malloc(sizeof(double) * length);
1962  if (!vec->coeff)
1963  av_freep(&vec);
1964  return vec;
1965 }
1966 
1967 SwsVector *sws_getGaussianVec(double variance, double quality)
1968 {
1969  const int length = (int)(variance * quality + 0.5) | 1;
1970  int i;
1971  double middle = (length - 1) * 0.5;
1972  SwsVector *vec;
1973 
1974  if(variance < 0 || quality < 0)
1975  return NULL;
1976 
1977  vec = sws_allocVec(length);
1978 
1979  if (!vec)
1980  return NULL;
1981 
1982  for (i = 0; i < length; i++) {
1983  double dist = i - middle;
1984  vec->coeff[i] = exp(-dist * dist / (2 * variance * variance)) /
1985  sqrt(2 * variance * M_PI);
1986  }
1987 
1988  sws_normalizeVec(vec, 1.0);
1989 
1990  return vec;
1991 }
1992 
1993 /**
1994  * Allocate and return a vector with length coefficients, all
1995  * with the same value c.
1996  */
1997 static
1998 SwsVector *sws_getConstVec(double c, int length)
1999 {
2000  int i;
2001  SwsVector *vec = sws_allocVec(length);
2002 
2003  if (!vec)
2004  return NULL;
2005 
2006  for (i = 0; i < length; i++)
2007  vec->coeff[i] = c;
2008 
2009  return vec;
2010 }
2011 
2012 /**
2013  * Allocate and return a vector with just one coefficient, with
2014  * value 1.0.
2015  */
2016 static
2018 {
2019  return sws_getConstVec(1.0, 1);
2020 }
2021 
2022 static double sws_dcVec(SwsVector *a)
2023 {
2024  int i;
2025  double sum = 0;
2026 
2027  for (i = 0; i < a->length; i++)
2028  sum += a->coeff[i];
2029 
2030  return sum;
2031 }
2032 
2033 void sws_scaleVec(SwsVector *a, double scalar)
2034 {
2035  int i;
2036 
2037  for (i = 0; i < a->length; i++)
2038  a->coeff[i] *= scalar;
2039 }
2040 
2042 {
2044 }
2045 
2047 {
2048  int length = FFMAX(a->length, b->length);
2049  int i;
2050  SwsVector *vec = sws_getConstVec(0.0, length);
2051 
2052  if (!vec)
2053  return NULL;
2054 
2055  for (i = 0; i < a->length; i++)
2056  vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
2057  for (i = 0; i < b->length; i++)
2058  vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] += b->coeff[i];
2059 
2060  return vec;
2061 }
2062 
2063 /* shift left / or right if "shift" is negative */
2065 {
2066  int length = a->length + FFABS(shift) * 2;
2067  int i;
2068  SwsVector *vec = sws_getConstVec(0.0, length);
2069 
2070  if (!vec)
2071  return NULL;
2072 
2073  for (i = 0; i < a->length; i++) {
2074  vec->coeff[i + (length - 1) / 2 -
2075  (a->length - 1) / 2 - shift] = a->coeff[i];
2076  }
2077 
2078  return vec;
2079 }
2080 
2081 static
2083 {
2084  SwsVector *shifted = sws_getShiftedVec(a, shift);
2085  if (!shifted) {
2086  makenan_vec(a);
2087  return;
2088  }
2089  av_free(a->coeff);
2090  a->coeff = shifted->coeff;
2091  a->length = shifted->length;
2092  av_free(shifted);
2093 }
2094 
2095 static
2097 {
2098  SwsVector *sum = sws_sumVec(a, b);
2099  if (!sum) {
2100  makenan_vec(a);
2101  return;
2102  }
2103  av_free(a->coeff);
2104  a->coeff = sum->coeff;
2105  a->length = sum->length;
2106  av_free(sum);
2107 }
2108 
2109 /**
2110  * Print with av_log() a textual representation of the vector a
2111  * if log_level <= av_log_level.
2112  */
2113 static
2114 void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
2115 {
2116  int i;
2117  double max = 0;
2118  double min = 0;
2119  double range;
2120 
2121  for (i = 0; i < a->length; i++)
2122  if (a->coeff[i] > max)
2123  max = a->coeff[i];
2124 
2125  for (i = 0; i < a->length; i++)
2126  if (a->coeff[i] < min)
2127  min = a->coeff[i];
2128 
2129  range = max - min;
2130 
2131  for (i = 0; i < a->length; i++) {
2132  int x = (int)((a->coeff[i] - min) * 60.0 / range + 0.5);
2133  av_log(log_ctx, log_level, "%1.3f ", a->coeff[i]);
2134  for (; x > 0; x--)
2135  av_log(log_ctx, log_level, " ");
2136  av_log(log_ctx, log_level, "|\n");
2137  }
2138 }
2139 
2141 {
2142  if (!a)
2143  return;
2144  av_freep(&a->coeff);
2145  a->length = 0;
2146  av_free(a);
2147 }
2148 
2150 {
2151  if (!filter)
2152  return;
2153 
2154  sws_freeVec(filter->lumH);
2155  sws_freeVec(filter->lumV);
2156  sws_freeVec(filter->chrH);
2157  sws_freeVec(filter->chrV);
2158  av_free(filter);
2159 }
2160 
2161 SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
2162  float lumaSharpen, float chromaSharpen,
2163  float chromaHShift, float chromaVShift,
2164  int verbose)
2165 {
2166  SwsFilter *filter = av_malloc(sizeof(SwsFilter));
2167  if (!filter)
2168  return NULL;
2169 
2170  if (lumaGBlur != 0.0) {
2171  filter->lumH = sws_getGaussianVec(lumaGBlur, 3.0);
2172  filter->lumV = sws_getGaussianVec(lumaGBlur, 3.0);
2173  } else {
2174  filter->lumH = sws_getIdentityVec();
2175  filter->lumV = sws_getIdentityVec();
2176  }
2177 
2178  if (chromaGBlur != 0.0) {
2179  filter->chrH = sws_getGaussianVec(chromaGBlur, 3.0);
2180  filter->chrV = sws_getGaussianVec(chromaGBlur, 3.0);
2181  } else {
2182  filter->chrH = sws_getIdentityVec();
2183  filter->chrV = sws_getIdentityVec();
2184  }
2185 
2186  if (!filter->lumH || !filter->lumV || !filter->chrH || !filter->chrV)
2187  goto fail;
2188 
2189  if (chromaSharpen != 0.0) {
2190  SwsVector *id = sws_getIdentityVec();
2191  if (!id)
2192  goto fail;
2193  sws_scaleVec(filter->chrH, -chromaSharpen);
2194  sws_scaleVec(filter->chrV, -chromaSharpen);
2195  sws_addVec(filter->chrH, id);
2196  sws_addVec(filter->chrV, id);
2197  sws_freeVec(id);
2198  }
2199 
2200  if (lumaSharpen != 0.0) {
2201  SwsVector *id = sws_getIdentityVec();
2202  if (!id)
2203  goto fail;
2204  sws_scaleVec(filter->lumH, -lumaSharpen);
2205  sws_scaleVec(filter->lumV, -lumaSharpen);
2206  sws_addVec(filter->lumH, id);
2207  sws_addVec(filter->lumV, id);
2208  sws_freeVec(id);
2209  }
2210 
2211  if (chromaHShift != 0.0)
2212  sws_shiftVec(filter->chrH, (int)(chromaHShift + 0.5));
2213 
2214  if (chromaVShift != 0.0)
2215  sws_shiftVec(filter->chrV, (int)(chromaVShift + 0.5));
2216 
2217  sws_normalizeVec(filter->chrH, 1.0);
2218  sws_normalizeVec(filter->chrV, 1.0);
2219  sws_normalizeVec(filter->lumH, 1.0);
2220  sws_normalizeVec(filter->lumV, 1.0);
2221 
2222  if (isnan_vec(filter->chrH) ||
2223  isnan_vec(filter->chrV) ||
2224  isnan_vec(filter->lumH) ||
2225  isnan_vec(filter->lumV))
2226  goto fail;
2227 
2228  if (verbose)
2230  if (verbose)
2232 
2233  return filter;
2234 
2235 fail:
2236  sws_freeVec(filter->lumH);
2237  sws_freeVec(filter->lumV);
2238  sws_freeVec(filter->chrH);
2239  sws_freeVec(filter->chrV);
2240  av_freep(&filter);
2241  return NULL;
2242 }
2243 
2245 {
2247  int i;
2248  if (!c)
2249  return;
2250 
2251  for (i = 0; i < FF_ARRAY_ELEMS(c->graph); i++)
2252  ff_sws_graph_free(&c->graph[i]);
2253 
2254  for (i = 0; i < c->nb_slice_ctx; i++)
2255  sws_freeContext(c->slice_ctx[i]);
2256  av_freep(&c->slice_ctx);
2257  av_freep(&c->slice_err);
2258 
2259  avpriv_slicethread_free(&c->slicethread);
2260 
2261  for (i = 0; i < 4; i++)
2262  av_freep(&c->dither_error[i]);
2263 
2264  av_frame_free(&c->frame_src);
2265  av_frame_free(&c->frame_dst);
2266 
2267  av_freep(&c->src_ranges.ranges);
2268 
2269  av_freep(&c->vLumFilter);
2270  av_freep(&c->vChrFilter);
2271  av_freep(&c->hLumFilter);
2272  av_freep(&c->hChrFilter);
2273 #if HAVE_ALTIVEC
2274  av_freep(&c->vYCoeffsBank);
2275  av_freep(&c->vCCoeffsBank);
2276 #endif
2277 
2278  av_freep(&c->vLumFilterPos);
2279  av_freep(&c->vChrFilterPos);
2280  av_freep(&c->hLumFilterPos);
2281  av_freep(&c->hChrFilterPos);
2282 
2283 #if HAVE_MMX_INLINE
2284 #if USE_MMAP
2285  if (c->lumMmxextFilterCode)
2286  munmap(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize);
2287  if (c->chrMmxextFilterCode)
2288  munmap(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize);
2289 #elif HAVE_VIRTUALALLOC
2290  if (c->lumMmxextFilterCode)
2291  VirtualFree(c->lumMmxextFilterCode, 0, MEM_RELEASE);
2292  if (c->chrMmxextFilterCode)
2293  VirtualFree(c->chrMmxextFilterCode, 0, MEM_RELEASE);
2294 #else
2295  av_free(c->lumMmxextFilterCode);
2296  av_free(c->chrMmxextFilterCode);
2297 #endif
2298  c->lumMmxextFilterCode = NULL;
2299  c->chrMmxextFilterCode = NULL;
2300 #endif /* HAVE_MMX_INLINE */
2301 
2302  av_freep(&c->yuvTable);
2303  av_freep(&c->formatConvBuffer);
2304 
2305  sws_freeContext(c->cascaded_context[0]);
2306  sws_freeContext(c->cascaded_context[1]);
2307  sws_freeContext(c->cascaded_context[2]);
2308  memset(c->cascaded_context, 0, sizeof(c->cascaded_context));
2309  av_freep(&c->cascaded_tmp[0][0]);
2310  av_freep(&c->cascaded_tmp[1][0]);
2311 
2312  av_freep(&c->gamma);
2313  av_freep(&c->inv_gamma);
2314 #if CONFIG_SMALL
2315  av_freep(&c->xyzgamma);
2316 #endif
2317 
2318  av_freep(&c->rgb0_scratch);
2319  av_freep(&c->xyz_scratch);
2320 
2321  ff_free_filters(c);
2322 
2323  av_free(c);
2324 }
2325 
2327 {
2328  SwsContext *ctx = *pctx;
2329  if (!ctx)
2330  return;
2331 
2333  *pctx = NULL;
2334 }
2335 
2337  int srcH, enum AVPixelFormat srcFormat,
2338  int dstW, int dstH,
2339  enum AVPixelFormat dstFormat, int flags,
2340  SwsFilter *srcFilter,
2341  SwsFilter *dstFilter,
2342  const double *param)
2343 {
2344  SwsContext *sws;
2345  static const double default_param[2] = { SWS_PARAM_DEFAULT,
2347 
2348  if (!param)
2349  param = default_param;
2350 
2351  if (prev && (prev->src_w == srcW &&
2352  prev->src_h == srcH &&
2353  prev->src_format == srcFormat &&
2354  prev->dst_w == dstW &&
2355  prev->dst_h == dstH &&
2356  prev->dst_format == dstFormat &&
2357  prev->flags == flags &&
2358  prev->scaler_params[0] == param[0] &&
2359  prev->scaler_params[1] == param[1])) {
2360  return prev;
2361  }
2362 
2363  if (!(sws = sws_alloc_context())) {
2364  sws_free_context(&prev);
2365  return NULL;
2366  }
2367 
2368  if (prev) {
2369  av_opt_copy(sws, prev);
2370  sws_free_context(&prev);
2371  }
2372 
2373  sws->src_w = srcW;
2374  sws->src_h = srcH;
2375  sws->src_format = srcFormat;
2376  sws->dst_w = dstW;
2377  sws->dst_h = dstH;
2378  sws->dst_format = dstFormat;
2379  sws->flags = flags;
2380  sws->scaler_params[0] = param[0];
2381  sws->scaler_params[1] = param[1];
2382 
2383  if (sws_init_context(sws, srcFilter, dstFilter) < 0)
2385 
2386  return sws;
2387 }
2388 
2389 int ff_range_add(RangeList *rl, unsigned int start, unsigned int len)
2390 {
2391  Range *tmp;
2392  unsigned int idx;
2393 
2394  /* find the first existing range after the new one */
2395  for (idx = 0; idx < rl->nb_ranges; idx++)
2396  if (rl->ranges[idx].start > start)
2397  break;
2398 
2399  /* check for overlap */
2400  if (idx > 0) {
2401  Range *prev = &rl->ranges[idx - 1];
2402  if (prev->start + prev->len > start)
2403  return AVERROR(EINVAL);
2404  }
2405  if (idx < rl->nb_ranges) {
2406  Range *next = &rl->ranges[idx];
2407  if (start + len > next->start)
2408  return AVERROR(EINVAL);
2409  }
2410 
2412  (rl->nb_ranges + 1) * sizeof(*rl->ranges));
2413  if (!tmp)
2414  return AVERROR(ENOMEM);
2415  rl->ranges = tmp;
2416 
2417  memmove(rl->ranges + idx + 1, rl->ranges + idx,
2418  sizeof(*rl->ranges) * (rl->nb_ranges - idx));
2419  rl->ranges[idx].start = start;
2420  rl->ranges[idx].len = len;
2421  rl->nb_ranges++;
2422 
2423  /* merge ranges */
2424  if (idx > 0) {
2425  Range *prev = &rl->ranges[idx - 1];
2426  Range *cur = &rl->ranges[idx];
2427  if (prev->start + prev->len == cur->start) {
2428  prev->len += cur->len;
2429  memmove(rl->ranges + idx - 1, rl->ranges + idx,
2430  sizeof(*rl->ranges) * (rl->nb_ranges - idx));
2431  rl->nb_ranges--;
2432  idx--;
2433  }
2434  }
2435  if (idx < rl->nb_ranges - 1) {
2436  Range *cur = &rl->ranges[idx];
2437  Range *next = &rl->ranges[idx + 1];
2438  if (cur->start + cur->len == next->start) {
2439  cur->len += next->len;
2440  memmove(rl->ranges + idx, rl->ranges + idx + 1,
2441  sizeof(*rl->ranges) * (rl->nb_ranges - idx - 1));
2442  rl->nb_ranges--;
2443  }
2444  }
2445 
2446  return 0;
2447 }
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:3492
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:2017
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:3437
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:2244
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c: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:537
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:3389
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:106
max
#define max(a, b)
Definition: cuda_runtime.h:33
mathematics.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:109
AV_PIX_FMT_YUVA444P9BE
@ AV_PIX_FMT_YUVA444P9BE
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian
Definition: pixfmt.h:179
sws_getShiftedVec
static SwsVector * sws_getShiftedVec(SwsVector *a, int shift)
Definition: utils.c:2064
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
SWS_BICUBLIN
@ SWS_BICUBLIN
bicubic luma, bilinear chroma
Definition: swscale.h: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:2140
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
isnan_vec
static int isnan_vec(SwsVector *a)
Definition: utils.c:1934
AV_PIX_FMT_GBRAP12LE
@ AV_PIX_FMT_GBRAP12LE
planar GBR 4:4:4:4 48bpp, little-endian
Definition: pixfmt.h:311
SWS_FAST_BILINEAR
@ SWS_FAST_BILINEAR
Scaler selection options.
Definition: swscale.h: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:558
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:556
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:535
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:2336
AV_PIX_FMT_GRAY9LE
@ AV_PIX_FMT_GRAY9LE
Y , 9bpp, little-endian.
Definition: pixfmt.h:339
sws_init_context
av_cold int sws_init_context(SwsContext *sws, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:1879
ff_sws_alphablendaway
int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
Definition: alphablend.c:23
av_pix_fmt_get_chroma_sub_sample
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition: pixdesc.c:3465
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:520
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:540
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:549
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:2389
AV_PIX_FMT_GBRAP16BE
@ AV_PIX_FMT_GBRAP16BE
planar GBRA 4:4:4:4 64bpp, big-endian
Definition: pixfmt.h:213
sws_printVec2
static void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
Print with av_log() a textual representation of the vector a if log_level <= av_log_level.
Definition: utils.c:2114
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_PIX_FMT_GBRP16LE
@ AV_PIX_FMT_GBRP16LE
planar GBR 4:4:4 48bpp, little-endian
Definition: pixfmt.h:172
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
SwsContext::threads
int threads
How many threads to use for processing, or 0 for automatic selection.
Definition: swscale.h:205
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:550
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:1950
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:534
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:548
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:1967
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:580
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
AV_PIX_FMT_GBRP10MSBLE
@ AV_PIX_FMT_GBRP10MSBLE
planar GBR 4:4:4 30bpp, lowest bits zero, little-endian
Definition: pixfmt.h:496
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:559
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:528
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:2161
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:1943
AV_PIX_FMT_YUVA444P9LE
@ AV_PIX_FMT_YUVA444P9LE
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
Definition: pixfmt.h:180
SwsContext::src_range
int src_range
Source is full range.
Definition: swscale.h: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:538
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:2096
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
AV_PIX_FMT_GBRP12MSBLE
@ AV_PIX_FMT_GBRP12MSBLE
planar GBR 4:4:4 36bpp, lowest bits zero, little-endian
Definition: pixfmt.h:498
ff_sws_context_class
const AVClass ff_sws_context_class
Definition: options.c: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:2033
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
sws_getConstVec
static SwsVector * sws_getConstVec(double c, int length)
Allocate and return a vector with length coefficients, all with the same value c.
Definition: utils.c:1998
AV_PIX_FMT_BGR4_BYTE
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:92
av_opt_copy
int av_opt_copy(void *dst, const void *src)
Copy options from src object into dest object.
Definition: opt.c: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
AV_PIX_FMT_GBRP10MSBBE
@ AV_PIX_FMT_GBRP10MSBBE
planar GBR 4:4:4 30bpp, lowest bits zero, big-endian
Definition: pixfmt.h:495
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c: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:523
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:530
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
AV_PIX_FMT_GBRP12MSBBE
@ AV_PIX_FMT_GBRP12MSBBE
planar GBR 4:4:4 36bpp, lowest bits zero, big-endian
Definition: pixfmt.h:497
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2594
ff_shuffle_filter_coefficients
int ff_shuffle_filter_coefficients(SwsInternal *c, int *filterPos, int filterSize, int16_t *filter, int dstW)
Definition: utils.c:93
sws_getColorspaceDetails
int sws_getColorspaceDetails(SwsContext *sws, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation)
Definition: utils.c: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:532
sws_isSupportedEndiannessConversion
int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
Definition: format.c:283
AV_PIX_FMT_RGB48BE
@ AV_PIX_FMT_RGB48BE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:109
ff_yuv2rgb_coeffs
const int32_t ff_yuv2rgb_coeffs[11][4]
Definition: yuv2rgb.c:47
sws_shiftVec
static void sws_shiftVec(SwsVector *a, int shift)
Definition: utils.c:2082
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:557
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:529
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:536
sws_freeFilter
void sws_freeFilter(SwsFilter *filter)
Definition: utils.c:2149
isFloat
static av_always_inline int isFloat(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h: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:1913
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:2046
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:80
AV_PIX_FMT_GRAY14BE
@ AV_PIX_FMT_GRAY14BE
Y , 14bpp, big-endian.
Definition: pixfmt.h:360
X86_MMX
#define X86_MMX(flags)
Definition: cpu.h: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:2326
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:2022
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
sws_normalizeVec
void sws_normalizeVec(SwsVector *a, double height)
Scale all the coefficients of a so that their sum equals height.
Definition: utils.c:2041
cpu.h
AV_PIX_FMT_YUVA420P9BE
@ AV_PIX_FMT_YUVA420P9BE
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian
Definition: pixfmt.h:175
APCK_SIZE
#define APCK_SIZE
Definition: swscale_internal.h: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:3357
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:1831