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