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