FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
sw_scale.c
Go to the documentation of this file.
1 /*
2  *
3  * This file is part of FFmpeg.
4  *
5  * FFmpeg is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * FFmpeg is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include <string.h>
21 
22 #include "libavutil/common.h"
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/mem_internal.h"
26 
27 #include "libswscale/swscale.h"
29 
30 #include "checkasm.h"
31 
32 #define randomize_buffers(buf, size) \
33  do { \
34  int j; \
35  for (j = 0; j < size; j+=4) \
36  AV_WN32(buf + j, rnd()); \
37  } while (0)
38 
39 static void yuv2planeX_8_ref(const int16_t *filter, int filterSize,
40  const int16_t **src, uint8_t *dest, int dstW,
41  const uint8_t *dither, int offset)
42 {
43  // This corresponds to the yuv2planeX_8_c function
44  int i;
45  for (i = 0; i < dstW; i++) {
46  int val = dither[(i + offset) & 7] << 12;
47  int j;
48  for (j = 0; j < filterSize; j++)
49  val += src[j][i] * filter[j];
50 
51  dest[i]= av_clip_uint8(val >> 19);
52  }
53 }
54 
55 #define CMP_FUNC(bits) \
56 static int cmp_off_by_n_##bits(const uint##bits##_t *ref, const uint##bits##_t *test, \
57  size_t n, int accuracy) \
58 { \
59  for (size_t i = 0; i < n; i++) { \
60  if (abs((int)ref[i] - (int)test[i]) > accuracy) \
61  return 1; \
62  } \
63  return 0; \
64 }
65 
66 CMP_FUNC(8)
67 CMP_FUNC(16)
68 
69 #define SHOW_DIFF_FUNC(bits) \
70 static void print_data_##bits(const uint##bits##_t *p, size_t len, size_t offset) \
71 { \
72  size_t i = 0; \
73  for (; i < len; i++) { \
74  if (i % 8 == 0) { \
75  printf("0x%04zx: ", i+offset); \
76  } \
77  printf("0x%02x ", (uint32_t) p[i]); \
78  if (i % 8 == 7) { \
79  printf("\n"); \
80  } \
81  } \
82  if (i % 8 != 0) { \
83  printf("\n"); \
84  } \
85 } \
86 static size_t show_differences_##bits(const uint##bits##_t *a, const uint##bits##_t *b, \
87  size_t len) \
88 { \
89  for (size_t i = 0; i < len; i++) { \
90  if (a[i] != b[i]) { \
91  size_t offset_of_mismatch = i; \
92  size_t offset; \
93  if (i >= 8) i-=8; \
94  offset = i & (~7); \
95  printf("test a:\n"); \
96  print_data_##bits(&a[offset], 32, offset); \
97  printf("\ntest b:\n"); \
98  print_data_##bits(&b[offset], 32, offset); \
99  printf("\n"); \
100  return offset_of_mismatch; \
101  } \
102  } \
103  return len; \
104 }
105 
107 SHOW_DIFF_FUNC(16)
108 
109 static void check_yuv2yuv1(int accurate)
110 {
111  SwsContext *sws;
112  SwsInternal *c;
113  int osi, isi;
114  int dstW, offset;
115  size_t fail_offset;
116  const int input_sizes[] = {8, 24, 128, 144, 256, 512};
117  #define LARGEST_INPUT_SIZE 512
118 
119  const int offsets[] = {0, 3, 8, 11, 16, 19};
120  const int OFFSET_SIZES = sizeof(offsets)/sizeof(offsets[0]);
121  const char *accurate_str = (accurate) ? "accurate" : "approximate";
122 
123  declare_func(void,
124  const int16_t *src, uint8_t *dest,
125  int dstW, const uint8_t *dither, int offset);
126 
127  LOCAL_ALIGNED_16(int16_t, src_pixels, [LARGEST_INPUT_SIZE]);
128  LOCAL_ALIGNED_16(uint8_t, dst0, [LARGEST_INPUT_SIZE]);
129  LOCAL_ALIGNED_16(uint8_t, dst1, [LARGEST_INPUT_SIZE]);
130  LOCAL_ALIGNED_8(uint8_t, dither, [8]);
131 
132  randomize_buffers((uint8_t*)dither, 8);
133  randomize_buffers((uint8_t*)src_pixels, LARGEST_INPUT_SIZE * sizeof(int16_t));
135  if (accurate)
137  if (sws_init_context(sws, NULL, NULL) < 0)
138  fail();
139 
140  c = sws_internal(sws);
142  for (isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); ++isi) {
143  dstW = input_sizes[isi];
144  for (osi = 0; osi < OFFSET_SIZES; osi++) {
145  offset = offsets[osi];
146  if (check_func(c->yuv2plane1, "yuv2yuv1_%d_%d_%s", offset, dstW, accurate_str)){
147  memset(dst0, 0, LARGEST_INPUT_SIZE * sizeof(dst0[0]));
148  memset(dst1, 0, LARGEST_INPUT_SIZE * sizeof(dst1[0]));
149 
150  call_ref(src_pixels, dst0, dstW, dither, offset);
151  call_new(src_pixels, dst1, dstW, dither, offset);
152  if (cmp_off_by_n_8(dst0, dst1, dstW * sizeof(dst0[0]), accurate ? 0 : 2)) {
153  fail();
154  printf("failed: yuv2yuv1_%d_%di_%s\n", offset, dstW, accurate_str);
155  fail_offset = show_differences_8(dst0, dst1, LARGEST_INPUT_SIZE * sizeof(dst0[0]));
156  printf("failing values: src: 0x%04x dither: 0x%02x dst-c: %02x dst-asm: %02x\n",
157  (int) src_pixels[fail_offset],
158  (int) dither[(fail_offset + fail_offset) & 7],
159  (int) dst0[fail_offset],
160  (int) dst1[fail_offset]);
161  }
162  if (dstW == LARGEST_INPUT_SIZE)
163  bench_new(src_pixels, dst1, dstW, dither, offset);
164  }
165  }
166  }
168 }
169 
170 static void check_yuv2yuvX(int accurate, int bit_depth, int dst_pix_format)
171 {
172  SwsContext *sws;
173  SwsInternal *c;
174  int fsi, osi, isi, i, j;
175  int dstW;
176 #define LARGEST_FILTER 16
177  // ff_yuv2planeX_8_sse2 can't handle odd filter sizes
178  const int filter_sizes[] = {2, 4, 8, 16};
179  const int FILTER_SIZES = sizeof(filter_sizes)/sizeof(filter_sizes[0]);
180 #define LARGEST_INPUT_SIZE 512
181  static const int input_sizes[] = {8, 24, 128, 144, 256, 512};
182  const char *accurate_str = (accurate) ? "accurate" : "approximate";
183 
184  declare_func_emms(AV_CPU_FLAG_MMX, void, const int16_t *filter,
185  int filterSize, const int16_t **src, uint8_t *dest,
186  int dstW, const uint8_t *dither, int offset);
187 
188  const int16_t **src;
189  LOCAL_ALIGNED_16(int16_t, src_pixels, [LARGEST_FILTER * LARGEST_INPUT_SIZE]);
190  LOCAL_ALIGNED_16(int16_t, filter_coeff, [LARGEST_FILTER]);
191  LOCAL_ALIGNED_16(uint16_t, dst0, [LARGEST_INPUT_SIZE]);
192  LOCAL_ALIGNED_16(uint16_t, dst1, [LARGEST_INPUT_SIZE]);
194  union VFilterData{
195  const int16_t *src;
196  uint16_t coeff[8];
197  } *vFilterData;
198  uint8_t d_val = rnd();
199  memset(dither, d_val, LARGEST_INPUT_SIZE);
200  randomize_buffers((uint8_t*)src_pixels, LARGEST_FILTER * LARGEST_INPUT_SIZE * sizeof(int16_t));
202  sws->dst_format = dst_pix_format;
203  if (accurate)
205  if (sws_init_context(sws, NULL, NULL) < 0)
206  fail();
207 
208  c = sws_internal(sws);
209  c->dstBpc = bit_depth;
211  for(isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); ++isi){
212  dstW = input_sizes[isi];
213  for(osi = 0; osi < 64; osi += 16){
214  if (dstW <= osi)
215  continue;
216  for (fsi = 0; fsi < FILTER_SIZES; ++fsi) {
217  // Generate filter coefficients for the given filter size,
218  // with some properties:
219  // - The coefficients add up to the intended sum (4096, 1<<12)
220  // - The coefficients contain negative values
221  // - The filter intermediates don't overflow for worst case
222  // inputs (all positive coefficients are coupled with
223  // input_max and all negative coefficients with input_min,
224  // or vice versa).
225  // Produce a filter with all coefficients set to
226  // -((1<<12)/(filter_size-1)) except for one (randomly chosen)
227  // which is set to ((1<<13)-1).
228  for (i = 0; i < filter_sizes[fsi]; ++i)
229  filter_coeff[i] = -((1 << 12) / (filter_sizes[fsi] - 1));
230  filter_coeff[rnd() % filter_sizes[fsi]] = (1 << 13) - 1;
231 
232  src = av_malloc(sizeof(int16_t*) * filter_sizes[fsi]);
233  vFilterData = av_malloc((filter_sizes[fsi] + 2) * sizeof(union VFilterData));
234  memset(vFilterData, 0, (filter_sizes[fsi] + 2) * sizeof(union VFilterData));
235  for (i = 0; i < filter_sizes[fsi]; ++i) {
236  src[i] = &src_pixels[i * LARGEST_INPUT_SIZE];
237  vFilterData[i].src = src[i] - osi;
238  for(j = 0; j < 4; ++j)
239  vFilterData[i].coeff[j + 4] = filter_coeff[i];
240  }
241  if (check_func(c->yuv2planeX, "yuv2yuvX_%d%s_%d_%d_%d_%s", bit_depth, (bit_depth == 8) ? "" : (isBE(dst_pix_format) ? "BE" : "LE"), filter_sizes[fsi], osi, dstW, accurate_str)) {
242  // use vFilterData for the mmx function
243  const int16_t *filter = c->use_mmx_vfilter ? (const int16_t*)vFilterData : &filter_coeff[0];
244  memset(dst0, 0, LARGEST_INPUT_SIZE * sizeof(dst0[0]));
245  memset(dst1, 0, LARGEST_INPUT_SIZE * sizeof(dst1[0]));
246 
247  if (c->dstBpc == 8) {
248  // We can't use call_ref here, because we don't know if use_mmx_vfilter was set for that
249  // function or not, so we can't pass it the parameters correctly.
250 
251  yuv2planeX_8_ref(&filter_coeff[0], filter_sizes[fsi], src, (uint8_t*)dst0, dstW - osi, dither, osi);
252  call_new(filter, filter_sizes[fsi], src, (uint8_t*)dst1, dstW - osi, dither, osi);
253 
254  if (cmp_off_by_n_8((uint8_t*)dst0, (uint8_t*)dst1, LARGEST_INPUT_SIZE, accurate ? 0 : 2)) {
255  fail();
256  printf("failed: yuv2yuvX_%d_%d_%d_%d_%s\n", bit_depth, filter_sizes[fsi], osi, dstW, accurate_str);
257  show_differences_8((uint8_t*)dst0, (uint8_t*)dst1, LARGEST_INPUT_SIZE);
258  }
259  } else {
260  call_ref(&filter_coeff[0], filter_sizes[fsi], src, (uint8_t*)dst0, dstW - osi, dither, osi);
261  call_new(&filter_coeff[0], filter_sizes[fsi], src, (uint8_t*)dst1, dstW - osi, dither, osi);
262 
263  if (cmp_off_by_n_16(dst0, dst1, LARGEST_INPUT_SIZE, accurate ? 0 : 2)) {
264  fail();
265  printf("failed: yuv2yuvX_%d%s_%d_%d_%d_%s\n", bit_depth, isBE(dst_pix_format) ? "BE" : "LE", filter_sizes[fsi], osi, dstW, accurate_str);
266  show_differences_16(dst0, dst1, LARGEST_INPUT_SIZE);
267  }
268  }
269  if (dstW == LARGEST_INPUT_SIZE)
270  bench_new(filter, filter_sizes[fsi], src, (uint8_t*)dst1, dstW - osi, dither, osi);
271 
272  }
273  av_freep(&src);
274  av_freep(&vFilterData);
275  }
276  }
277  }
279 #undef FILTER_SIZES
280 }
281 
282 static void check_yuv2nv12cX(int accurate)
283 {
284  SwsContext *sws;
285  SwsInternal *c;
286 #define LARGEST_FILTER 16
287  const int filter_sizes[] = {2, 4, 8, 16};
288 #define LARGEST_INPUT_SIZE 512
289  static const int input_sizes[] = {8, 24, 128, 144, 256, 512};
290  const char *accurate_str = (accurate) ? "accurate" : "approximate";
291 
292  declare_func_emms(AV_CPU_FLAG_MMX, void, enum AVPixelFormat dstFormat,
293  const uint8_t *chrDither, const int16_t *chrFilter,
294  int chrFilterSize, const int16_t **chrUSrc,
295  const int16_t **chrVSrc, uint8_t *dest, int dstW);
296 
297  const int16_t *srcU[LARGEST_FILTER], *srcV[LARGEST_FILTER];
298  LOCAL_ALIGNED_16(int16_t, srcU_pixels, [LARGEST_FILTER * LARGEST_INPUT_SIZE]);
299  LOCAL_ALIGNED_16(int16_t, srcV_pixels, [LARGEST_FILTER * LARGEST_INPUT_SIZE]);
300  LOCAL_ALIGNED_16(int16_t, filter_coeff, [LARGEST_FILTER]);
301  LOCAL_ALIGNED_16(uint8_t, dst0, [LARGEST_INPUT_SIZE * 2]);
302  LOCAL_ALIGNED_16(uint8_t, dst1, [LARGEST_INPUT_SIZE * 2]);
304  uint8_t d_val = rnd();
305  memset(dither, d_val, LARGEST_INPUT_SIZE);
306  randomize_buffers((uint8_t*)srcU_pixels, LARGEST_FILTER * LARGEST_INPUT_SIZE * sizeof(int16_t));
307  randomize_buffers((uint8_t*)srcV_pixels, LARGEST_FILTER * LARGEST_INPUT_SIZE * sizeof(int16_t));
308  for (int i = 0; i < LARGEST_FILTER; i++) {
309  srcU[i] = &srcU_pixels[i * LARGEST_INPUT_SIZE];
310  srcV[i] = &srcV_pixels[i * LARGEST_INPUT_SIZE];
311  }
312 
315  if (accurate)
317  if (sws_init_context(sws, NULL, NULL) < 0)
318  fail();
319 
320  c = sws_internal(sws);
322  for (int isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); isi++){
323  const int dstW = input_sizes[isi];
324  for (int fsi = 0; fsi < FF_ARRAY_ELEMS(filter_sizes); fsi++) {
325  const int filter_size = filter_sizes[fsi];
326  for (int i = 0; i < filter_size; i++)
327  filter_coeff[i] = -((1 << 12) / (filter_size - 1));
328  filter_coeff[rnd() % filter_size] = (1 << 13) - 1;
329 
330  if (check_func(c->yuv2nv12cX, "yuv2nv12cX_%d_%d_%s", filter_size, dstW, accurate_str)){
331  memset(dst0, 0, LARGEST_INPUT_SIZE * sizeof(dst0[0]));
332  memset(dst1, 0, LARGEST_INPUT_SIZE * sizeof(dst1[0]));
333 
334  call_ref(sws->dst_format, dither, &filter_coeff[0], filter_size, srcU, srcV, dst0, dstW);
335  call_new(sws->dst_format, dither, &filter_coeff[0], filter_size, srcU, srcV, dst1, dstW);
336 
337  if (cmp_off_by_n_8(dst0, dst1, dstW * 2 * sizeof(dst0[0]), accurate ? 0 : 2)) {
338  fail();
339  printf("failed: yuv2nv12wX_%d_%d_%s\n", filter_size, dstW, accurate_str);
340  show_differences_8(dst0, dst1, dstW * 2 * sizeof(dst0[0]));
341  }
342  if (dstW == LARGEST_INPUT_SIZE)
343  bench_new(sws->dst_format, dither, &filter_coeff[0], filter_size, srcU, srcV, dst1, dstW);
344 
345  }
346  }
347  }
349 }
350 #undef LARGEST_FILTER
351 #undef LARGEST_INPUT_SIZE
352 
353 #undef SRC_PIXELS
354 #define SRC_PIXELS 512
355 
356 static void check_hscale(void)
357 {
358 #define MAX_FILTER_WIDTH 40
359 #define FILTER_SIZES 6
360  static const int filter_sizes[FILTER_SIZES] = { 4, 8, 12, 16, 32, 40 };
361 
362 #define HSCALE_PAIRS 2
363  static const int hscale_pairs[HSCALE_PAIRS][2] = {
364  { 8, 14 },
365  { 8, 18 },
366  };
367 
368 #define LARGEST_INPUT_SIZE 512
369  static const int input_sizes[] = {8, 24, 128, 144, 256, 512};
370 
371  int i, j, fsi, hpi, width, dstWi;
372  SwsContext *sws;
373  SwsInternal *c;
374 
375  // padded
376  LOCAL_ALIGNED_32(uint8_t, src, [FFALIGN(SRC_PIXELS + MAX_FILTER_WIDTH - 1, 4)]);
377  LOCAL_ALIGNED_32(uint32_t, dst0, [SRC_PIXELS]);
378  LOCAL_ALIGNED_32(uint32_t, dst1, [SRC_PIXELS]);
379 
380  // padded
382  LOCAL_ALIGNED_32(int32_t, filterPos, [SRC_PIXELS]);
383  LOCAL_ALIGNED_32(int16_t, filterAvx2, [SRC_PIXELS * MAX_FILTER_WIDTH + MAX_FILTER_WIDTH]);
384  LOCAL_ALIGNED_32(int32_t, filterPosAvx, [SRC_PIXELS]);
385 
386  // The dst parameter here is either int16_t or int32_t but we use void* to
387  // just cover both cases.
388  declare_func(void, SwsInternal *c, int16_t *dst, int dstW,
389  const uint8_t *src, const int16_t *filter,
390  const int32_t *filterPos, int filterSize);
391 
393  if (sws_init_context(sws, NULL, NULL) < 0)
394  fail();
395 
396  c = sws_internal(sws);
398 
399  for (hpi = 0; hpi < HSCALE_PAIRS; hpi++) {
400  for (fsi = 0; fsi < FILTER_SIZES; fsi++) {
401  for (dstWi = 0; dstWi < FF_ARRAY_ELEMS(input_sizes); dstWi++) {
402  width = filter_sizes[fsi];
403 
404  c->srcBpc = hscale_pairs[hpi][0];
405  c->dstBpc = hscale_pairs[hpi][1];
406  c->hLumFilterSize = c->hChrFilterSize = width;
407 
408  for (i = 0; i < SRC_PIXELS; i++) {
409  filterPos[i] = i;
410  filterPosAvx[i] = i;
411 
412  // These filter coefficients are chosen to try break two corner
413  // cases, namely:
414  //
415  // - Negative filter coefficients. The filters output signed
416  // values, and it should be possible to end up with negative
417  // output values.
418  //
419  // - Positive clipping. The hscale filter function has clipping
420  // at (1<<15) - 1
421  //
422  // The coefficients sum to the 1.0 point for the hscale
423  // functions (1 << 14).
424 
425  for (j = 0; j < width; j++) {
426  filter[i * width + j] = -((1 << 14) / (width - 1));
427  }
428  filter[i * width + (rnd() % width)] = ((1 << 15) - 1);
429  }
430 
431  for (i = 0; i < MAX_FILTER_WIDTH; i++) {
432  // These values should be unused in SIMD implementations but
433  // may still be read, random coefficients here should help show
434  // issues where they are used in error.
435 
436  filter[SRC_PIXELS * width + i] = rnd();
437  }
438  sws->dst_w = c->chrDstW = input_sizes[dstWi];
440  memcpy(filterAvx2, filter, sizeof(uint16_t) * (SRC_PIXELS * MAX_FILTER_WIDTH + MAX_FILTER_WIDTH));
441  ff_shuffle_filter_coefficients(c, filterPosAvx, width, filterAvx2, sws->dst_w);
442 
443  av_assert0(c->hyScale == c->hcScale);
444  if (check_func(c->hcScale, "hscale_%d_to_%d__fs_%d_dstW_%d", c->srcBpc, c->dstBpc + 1, width, sws->dst_w)) {
445  memset(dst0, 0, SRC_PIXELS * sizeof(dst0[0]));
446  memset(dst1, 0, SRC_PIXELS * sizeof(dst1[0]));
447 
448  call_ref(NULL, (int16_t *)dst0, sws->dst_w, src, filter, filterPos, width);
449  call_new(NULL, (int16_t *)dst1, sws->dst_w, src, filterAvx2, filterPosAvx, width);
450  if (memcmp(dst0, dst1, sws->dst_w * sizeof(dst0[0])))
451  fail();
452  bench_new(NULL, (int16_t *)dst0, sws->dst_w, src, filter, filterPosAvx, width);
453  }
454  }
455  }
456  }
458 }
459 
461 {
462  check_hscale();
463  report("hscale");
464  check_yuv2yuv1(0);
465  check_yuv2yuv1(1);
466  report("yuv2yuv1");
469  report("yuv2yuvX_8");
472  report("yuv2yuvX_9LE");
475  report("yuv2yuvX_9BE");
478  report("yuv2yuvX_10LE");
481  report("yuv2yuvX_10BE");
484  report("yuv2yuvX_12LE");
487  report("yuv2yuvX_12BE");
490  report("yuv2yuvX_14LE");
493  report("yuv2yuvX_14BE");
494  check_yuv2nv12cX(0);
495  check_yuv2nv12cX(1);
496  report("yuv2nv12cX");
497 }
FILTER_SIZES
#define FILTER_SIZES
declare_func_emms
#define declare_func_emms(cpu_flags, ret,...)
Definition: checkasm.h:196
AV_PIX_FMT_YUV420P9LE
@ AV_PIX_FMT_YUV420P9LE
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:154
check_yuv2yuv1
static void check_yuv2yuv1(int accurate)
Definition: sw_scale.c:109
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
printf
__device__ int printf(const char *,...)
mem_internal.h
sws_freeContext
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2244
check_func
#define check_func(func,...)
Definition: checkasm.h:190
AV_PIX_FMT_YUV420P14BE
@ AV_PIX_FMT_YUV420P14BE
planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:269
SwsContext::flags
unsigned flags
Bitmask of SWS_*.
Definition: swscale.h:195
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
call_ref
#define call_ref(...)
Definition: checkasm.h:205
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AV_PIX_FMT_YUV420P12LE
@ AV_PIX_FMT_YUV420P12LE
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:268
fail
#define fail()
Definition: checkasm.h:199
checkasm.h
sws_init_context
av_warn_unused_result int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:1879
val
static double val(void *priv, double ch)
Definition: aeval.c:77
check_hscale
static void check_hscale(void)
Definition: sw_scale.c:356
AV_PIX_FMT_YUV420P10LE
@ AV_PIX_FMT_YUV420P10LE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:156
rnd
#define rnd()
Definition: checkasm.h:183
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
ff_shuffle_filter_coefficients
int ff_shuffle_filter_coefficients(SwsInternal *c, int *filterPos, int filterSize, int16_t *filter, int dstW)
Definition: utils.c:93
intreadwrite.h
offsets
static const int offsets[]
Definition: hevc_pel.c:34
LARGEST_FILTER
#define LARGEST_FILTER
input_sizes
static const int input_sizes[]
Definition: sw_rgb.c:347
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:130
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
yuv2planeX_8_ref
static void yuv2planeX_8_ref(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Definition: sw_scale.c:39
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
LOCAL_ALIGNED_8
#define LOCAL_ALIGNED_8(t, v,...)
Definition: mem_internal.h:128
HSCALE_PAIRS
#define HSCALE_PAIRS
SRC_PIXELS
#define SRC_PIXELS
Definition: sw_scale.c:354
call_new
#define call_new(...)
Definition: checkasm.h:308
NULL
#define NULL
Definition: coverity.c:32
LOCAL_ALIGNED_32
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:132
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
AV_PIX_FMT_YUV420P14LE
@ AV_PIX_FMT_YUV420P14LE
planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:270
AV_PIX_FMT_YUV420P9BE
@ AV_PIX_FMT_YUV420P9BE
The following 12 formats have the disadvantage of needing 1 format for each bit depth.
Definition: pixfmt.h:153
isBE
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:748
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c:1018
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
AV_PIX_FMT_YUV420P12BE
@ AV_PIX_FMT_YUV420P12BE
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:267
AV_PIX_FMT_YUV420P10BE
@ AV_PIX_FMT_YUV420P10BE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:155
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
SwsContext::dst_format
int dst_format
Destination pixel format.
Definition: swscale.h:231
sws
static SwsContext * sws[3]
Definition: swscale.c:73
report
#define report
Definition: checkasm.h:202
bench_new
#define bench_new(...)
Definition: checkasm.h:379
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
check_yuv2yuvX
static void check_yuv2yuvX(int accurate, int bit_depth, int dst_pix_format)
Definition: sw_scale.c:170
ff_sws_init_scale
void ff_sws_init_scale(SwsInternal *c)
Definition: swscale.c:691
common.h
LARGEST_INPUT_SIZE
#define LARGEST_INPUT_SIZE
swscale_internal.h
SHOW_DIFF_FUNC
#define SHOW_DIFF_FUNC(bits)
Definition: sw_scale.c:69
SwsInternal
Definition: swscale_internal.h:317
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
randomize_buffers
#define randomize_buffers(buf, size)
Definition: sw_scale.c:32
AV_CPU_FLAG_MMX
#define AV_CPU_FLAG_MMX
standard MMX
Definition: cpu.h:30
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
mem.h
MAX_FILTER_WIDTH
#define MAX_FILTER_WIDTH
SwsContext::dst_w
int dst_w
Definition: swscale.h:229
CMP_FUNC
#define CMP_FUNC(bits)
Definition: sw_scale.c:55
check_yuv2nv12cX
static void check_yuv2nv12cX(int accurate)
Definition: sw_scale.c:282
declare_func
#define declare_func(ret,...)
Definition: checkasm.h:194
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
int32_t
int32_t
Definition: audioconvert.c:56
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:80
sws_internal
static SwsInternal * sws_internal(const SwsContext *sws)
Definition: swscale_internal.h:74
SWS_ACCURATE_RND
@ SWS_ACCURATE_RND
Force bit-exact output.
Definition: swscale.h:155
width
#define width
Definition: dsp.h:89
checkasm_check_sw_scale
void checkasm_check_sw_scale(void)
Definition: sw_scale.c:460
SwsContext
Main external API structure.
Definition: swscale.h:182
src
#define src
Definition: vp8dsp.c:248
swscale.h
dither
static const uint8_t dither[8][8]
Definition: vf_fspp.c:62