FFmpeg
sw_rgb.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_internal.h"
25 #include "libavutil/pixdesc.h"
26 
27 #include "libswscale/rgb2rgb.h"
28 #include "libswscale/swscale.h"
30 
31 #include "checkasm.h"
32 
33 #define randomize_buffers(buf, size) \
34  do { \
35  int j; \
36  for (j = 0; j < size; j+=4) \
37  AV_WN32(buf + j, rnd()); \
38  } while (0)
39 
40 static const uint8_t width[] = {12, 16, 20, 32, 36, 128};
41 static const struct {uint8_t w, h;} planes[] = {
42  {12,16}, {16,16}, {20,23}, {32,18}, {8,128}, {128,128},
43  {1,1}, {1,4}, {3,8}, {13,16}, {21,9}, {63,7}, {127,5}
44 };
45 
46 #define MAX_STRIDE 128
47 #define MAX_HEIGHT 128
48 
49 static void check_shuffle_bytes(void * func, const char * report)
50 {
51  int i;
52  LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE]);
53  LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE]);
54  LOCAL_ALIGNED_32(uint8_t, dst0, [MAX_STRIDE]);
55  LOCAL_ALIGNED_32(uint8_t, dst1, [MAX_STRIDE]);
56 
57  declare_func(void, const uint8_t *src, uint8_t *dst, int src_size);
58 
59  memset(dst0, 0, MAX_STRIDE);
60  memset(dst1, 0, MAX_STRIDE);
62  memcpy(src1, src0, MAX_STRIDE);
63 
64  if (check_func(func, "%s", report)) {
65  for (i = 0; i < 6; i ++) {
66  call_ref(src0, dst0, width[i]);
67  call_new(src1, dst1, width[i]);
68  if (memcmp(dst0, dst1, MAX_STRIDE))
69  fail();
70  }
71  bench_new(src0, dst0, width[5]);
72  }
73 }
74 
75 static void check_interleaved_to_planar(void *func, const char *report, int odd_tail)
76 {
77  int i;
78 
79  LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE * MAX_HEIGHT * 2]);
80  LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE * MAX_HEIGHT * 2]);
81  LOCAL_ALIGNED_32(uint8_t, dst_y_0, [MAX_STRIDE * MAX_HEIGHT]);
82  LOCAL_ALIGNED_32(uint8_t, dst_y_1, [MAX_STRIDE * MAX_HEIGHT]);
83  LOCAL_ALIGNED_32(uint8_t, dst_u_0, [(MAX_STRIDE/2) * MAX_HEIGHT]);
84  LOCAL_ALIGNED_32(uint8_t, dst_u_1, [(MAX_STRIDE/2) * MAX_HEIGHT]);
85  LOCAL_ALIGNED_32(uint8_t, dst_v_0, [(MAX_STRIDE/2) * MAX_HEIGHT]);
86  LOCAL_ALIGNED_32(uint8_t, dst_v_1, [(MAX_STRIDE/2) * MAX_HEIGHT]);
87 
88  declare_func(void, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
89  const uint8_t *src, int width, int height,
90  int lumStride, int chromStride, int srcStride);
91 
93  memcpy(src1, src0, MAX_STRIDE * MAX_HEIGHT * 2);
94 
95  if (check_func(func, "%s", report)) {
96  for (i = 0; i < FF_ARRAY_ELEMS(planes); i ++) {
97  int w = planes[i].w, h = planes[i].h;
98  int srcStride = 2 * w + (w & 1 ? odd_tail : 0);
99 
100  memset(dst_y_0, 0, MAX_STRIDE * MAX_HEIGHT);
101  memset(dst_y_1, 0, MAX_STRIDE * MAX_HEIGHT);
102  memset(dst_u_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
103  memset(dst_u_1, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
104  memset(dst_v_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
105  memset(dst_v_1, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
106 
107  call_ref(dst_y_0, dst_u_0, dst_v_0, src0, w, h,
108  MAX_STRIDE, MAX_STRIDE / 2, srcStride);
109  call_new(dst_y_1, dst_u_1, dst_v_1, src1, w, h,
110  MAX_STRIDE, MAX_STRIDE / 2, srcStride);
111  if (memcmp(dst_y_0, dst_y_1, MAX_STRIDE * MAX_HEIGHT) ||
112  memcmp(dst_u_0, dst_u_1, (MAX_STRIDE/2) * MAX_HEIGHT) ||
113  memcmp(dst_v_0, dst_v_1, (MAX_STRIDE/2) * MAX_HEIGHT))
114  fail();
115  }
116  bench_new(dst_y_1, dst_u_1, dst_v_1, src1, planes[5].w, planes[5].h,
117  MAX_STRIDE, MAX_STRIDE / 2, 2 * planes[5].w);
118  }
119 }
120 
121 #define NUM_LINES 5
122 #define MAX_LINE_SIZE 1920
123 #define BUFSIZE (NUM_LINES * MAX_LINE_SIZE)
124 
125 static int cmp_off_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int accuracy)
126 {
127  for (size_t i = 0; i < n; i++) {
128  if (abs(ref[i] - test[i]) > accuracy)
129  return 1;
130  }
131  return 0;
132 }
133 
134 static void check_rgb24toyv12(SwsContext *sws)
135 {
136  static const int input_sizes[] = {16, 128, 512, MAX_LINE_SIZE, -MAX_LINE_SIZE};
137  SwsInternal *ctx = sws_internal(sws);
138 
139  LOCAL_ALIGNED_32(uint8_t, src, [BUFSIZE * 3]);
140  LOCAL_ALIGNED_32(uint8_t, buf_y_0, [BUFSIZE]);
141  LOCAL_ALIGNED_32(uint8_t, buf_y_1, [BUFSIZE]);
142  LOCAL_ALIGNED_32(uint8_t, buf_u_0, [BUFSIZE / 4]);
143  LOCAL_ALIGNED_32(uint8_t, buf_u_1, [BUFSIZE / 4]);
144  LOCAL_ALIGNED_32(uint8_t, buf_v_0, [BUFSIZE / 4]);
145  LOCAL_ALIGNED_32(uint8_t, buf_v_1, [BUFSIZE / 4]);
146 
147  declare_func(void, const uint8_t *src, uint8_t *ydst, uint8_t *udst,
148  uint8_t *vdst, int width, int height, int lumStride,
149  int chromStride, int srcStride, const int32_t *rgb2yuv);
150 
152 
153  for (int isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); isi++) {
154  int input_size = input_sizes[isi];
155  int negstride = input_size < 0;
156  const char *negstride_str = negstride ? "_negstride" : "";
157  int width = FFABS(input_size);
158  int linesize = width + 32;
159  /* calculate height based on specified width to use the entire buffer. */
160  int height = (BUFSIZE / linesize) & ~1;
161  uint8_t *src0 = src;
162  uint8_t *src1 = src;
163  uint8_t *dst_y_0 = buf_y_0;
164  uint8_t *dst_y_1 = buf_y_1;
165  uint8_t *dst_u_0 = buf_u_0;
166  uint8_t *dst_u_1 = buf_u_1;
167  uint8_t *dst_v_0 = buf_v_0;
168  uint8_t *dst_v_1 = buf_v_1;
169 
170  if (negstride) {
171  src0 += (height - 1) * (linesize * 3);
172  src1 += (height - 1) * (linesize * 3);
173  dst_y_0 += (height - 1) * linesize;
174  dst_y_1 += (height - 1) * linesize;
175  dst_u_0 += ((height / 2) - 1) * (linesize / 2);
176  dst_u_1 += ((height / 2) - 1) * (linesize / 2);
177  dst_v_0 += ((height / 2) - 1) * (linesize / 2);
178  dst_v_1 += ((height / 2) - 1) * (linesize / 2);
179  linesize *= -1;
180  }
181 
182  if (check_func(ff_rgb24toyv12, "rgb24toyv12_%d_%d%s", width, height, negstride_str)) {
183  memset(buf_y_0, 0xFF, BUFSIZE);
184  memset(buf_y_1, 0xFF, BUFSIZE);
185  memset(buf_u_0, 0xFF, BUFSIZE / 4);
186  memset(buf_u_1, 0xFF, BUFSIZE / 4);
187  memset(buf_v_0, 0xFF, BUFSIZE / 4);
188  memset(buf_v_1, 0xFF, BUFSIZE / 4);
189 
190  call_ref(src0, dst_y_0, dst_u_0, dst_v_0, width, height,
191  linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
192  call_new(src1, dst_y_1, dst_u_1, dst_v_1, width, height,
193  linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
194  if (cmp_off_by_n(buf_y_0, buf_y_1, BUFSIZE, 1) ||
195  cmp_off_by_n(buf_u_0, buf_u_1, BUFSIZE / 4, 1) ||
196  cmp_off_by_n(buf_v_0, buf_v_1, BUFSIZE / 4, 1))
197  fail();
198  bench_new(src1, dst_y_1, dst_u_1, dst_v_1, width, height,
199  linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
200  }
201  }
202 }
203 
204 #undef NUM_LINES
205 #undef MAX_LINE_SIZE
206 #undef BUFSIZE
207 
208 static void check_interleave_bytes(void)
209 {
210  LOCAL_ALIGNED_16(uint8_t, src0_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
211  LOCAL_ALIGNED_16(uint8_t, src1_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
212  LOCAL_ALIGNED_16(uint8_t, dst0_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]);
213  LOCAL_ALIGNED_16(uint8_t, dst1_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]);
214  // Intentionally using unaligned buffers, as this function doesn't have
215  // any alignment requirements.
216  uint8_t *src0 = src0_buf + 1;
217  uint8_t *src1 = src1_buf + 1;
218  uint8_t *dst0 = dst0_buf + 2;
219  uint8_t *dst1 = dst1_buf + 2;
220 
221  declare_func(void, const uint8_t *, const uint8_t *,
222  uint8_t *, int, int, int, int, int);
223 
226 
227  if (check_func(interleaveBytes, "interleave_bytes")) {
228  for (int i = 0; i <= 16; i++) {
229  // Try all widths [1,16], and try one random width.
230 
231  int w = i > 0 ? i : (1 + (rnd() % (MAX_STRIDE-2)));
232  int h = 1 + (rnd() % (MAX_HEIGHT-2));
233 
234  int src0_offset = 0, src0_stride = MAX_STRIDE;
235  int src1_offset = 0, src1_stride = MAX_STRIDE;
236  int dst_offset = 0, dst_stride = 2 * MAX_STRIDE;
237 
238  memset(dst0, 0, 2 * MAX_STRIDE * MAX_HEIGHT);
239  memset(dst1, 0, 2 * MAX_STRIDE * MAX_HEIGHT);
240 
241  // Try different combinations of negative strides
242  if (i & 1) {
243  src0_offset = (h-1)*src0_stride;
244  src0_stride = -src0_stride;
245  }
246  if (i & 2) {
247  src1_offset = (h-1)*src1_stride;
248  src1_stride = -src1_stride;
249  }
250  if (i & 4) {
251  dst_offset = (h-1)*dst_stride;
252  dst_stride = -dst_stride;
253  }
254 
255  call_ref(src0 + src0_offset, src1 + src1_offset, dst0 + dst_offset,
256  w, h, src0_stride, src1_stride, dst_stride);
257  call_new(src0 + src0_offset, src1 + src1_offset, dst1 + dst_offset,
258  w, h, src0_stride, src1_stride, dst_stride);
259  // Check a one pixel-pair edge around the destination area,
260  // to catch overwrites past the end.
261  checkasm_check(uint8_t, dst0, 2*MAX_STRIDE, dst1, 2*MAX_STRIDE,
262  2 * w + 2, h + 1, "dst");
263  }
264 
265  bench_new(src0, src1, dst1, 127, MAX_HEIGHT,
267  }
268  if (check_func(interleaveBytes, "interleave_bytes_aligned")) {
269  // Bench the function in a more typical case, with aligned
270  // buffers and widths.
271  bench_new(src0_buf, src1_buf, dst1_buf, 128, MAX_HEIGHT,
273  }
274 }
275 
276 static void check_deinterleave_bytes(void)
277 {
278  LOCAL_ALIGNED_16(uint8_t, src_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]);
279  LOCAL_ALIGNED_16(uint8_t, dst0_u_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
280  LOCAL_ALIGNED_16(uint8_t, dst0_v_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
281  LOCAL_ALIGNED_16(uint8_t, dst1_u_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
282  LOCAL_ALIGNED_16(uint8_t, dst1_v_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
283  // Intentionally using unaligned buffers, as this function doesn't have
284  // any alignment requirements.
285  uint8_t *src = src_buf + 2;
286  uint8_t *dst0_u = dst0_u_buf + 1;
287  uint8_t *dst0_v = dst0_v_buf + 1;
288  uint8_t *dst1_u = dst1_u_buf + 1;
289  uint8_t *dst1_v = dst1_v_buf + 1;
290 
291  declare_func(void, const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
292  int width, int height, int srcStride,
293  int dst1Stride, int dst2Stride);
294 
296 
297  if (check_func(deinterleaveBytes, "deinterleave_bytes")) {
298  for (int i = 0; i <= 16; i++) {
299  // Try all widths [1,16], and try one random width.
300 
301  int w = i > 0 ? i : (1 + (rnd() % (MAX_STRIDE-2)));
302  int h = 1 + (rnd() % (MAX_HEIGHT-2));
303 
304  int src_offset = 0, src_stride = 2 * MAX_STRIDE;
305  int dst_u_offset = 0, dst_u_stride = MAX_STRIDE;
306  int dst_v_offset = 0, dst_v_stride = MAX_STRIDE;
307 
308  memset(dst0_u, 0, MAX_STRIDE * MAX_HEIGHT);
309  memset(dst0_v, 0, MAX_STRIDE * MAX_HEIGHT);
310  memset(dst1_u, 0, MAX_STRIDE * MAX_HEIGHT);
311  memset(dst1_v, 0, MAX_STRIDE * MAX_HEIGHT);
312 
313  // Try different combinations of negative strides
314  if (i & 1) {
315  src_offset = (h-1)*src_stride;
316  src_stride = -src_stride;
317  }
318  if (i & 2) {
319  dst_u_offset = (h-1)*dst_u_stride;
320  dst_u_stride = -dst_u_stride;
321  }
322  if (i & 4) {
323  dst_v_offset = (h-1)*dst_v_stride;
324  dst_v_stride = -dst_v_stride;
325  }
326 
327  call_ref(src + src_offset, dst0_u + dst_u_offset, dst0_v + dst_v_offset,
328  w, h, src_stride, dst_u_stride, dst_v_stride);
329  call_new(src + src_offset, dst1_u + dst_u_offset, dst1_v + dst_v_offset,
330  w, h, src_stride, dst_u_stride, dst_v_stride);
331  // Check a one pixel-pair edge around the destination area,
332  // to catch overwrites past the end.
333  checkasm_check(uint8_t, dst0_u, MAX_STRIDE, dst1_u, MAX_STRIDE,
334  w + 1, h + 1, "dst_u");
335  checkasm_check(uint8_t, dst0_v, MAX_STRIDE, dst1_v, MAX_STRIDE,
336  w + 1, h + 1, "dst_v");
337  }
338 
339  bench_new(src, dst1_u, dst1_v, 127, MAX_HEIGHT,
341  }
342  if (check_func(deinterleaveBytes, "deinterleave_bytes_aligned")) {
343  // Bench the function in a more typical case, with aligned
344  // buffers and widths.
345  bench_new(src_buf, dst1_u_buf, dst1_v_buf, 128, MAX_HEIGHT,
347  }
348 }
349 
350 #define MAX_LINE_SIZE 1920
351 static const int input_sizes[] = {8, 128, 1080, MAX_LINE_SIZE};
352 static const enum AVPixelFormat rgb_formats[] = {
359 };
360 
361 static void check_rgb_to_y(SwsContext *sws)
362 {
363  SwsInternal *ctx = sws_internal(sws);
364 
365  LOCAL_ALIGNED_16(uint8_t, src24, [MAX_LINE_SIZE * 3]);
366  LOCAL_ALIGNED_16(uint8_t, src32, [MAX_LINE_SIZE * 4]);
367  LOCAL_ALIGNED_32(uint8_t, dst0_y, [MAX_LINE_SIZE * 2]);
368  LOCAL_ALIGNED_32(uint8_t, dst1_y, [MAX_LINE_SIZE * 2]);
369 
370  declare_func(void, uint8_t *dst, const uint8_t *src,
371  const uint8_t *unused1, const uint8_t *unused2, int width,
372  uint32_t *rgb2yuv, void *opq);
373 
374  randomize_buffers(src24, MAX_LINE_SIZE * 3);
375  randomize_buffers(src32, MAX_LINE_SIZE * 4);
376 
377  for (int i = 0; i < FF_ARRAY_ELEMS(rgb_formats); i++) {
379 
380  sws->src_format = rgb_formats[i];
382 
383  for (int j = 0; j < FF_ARRAY_ELEMS(input_sizes); j++) {
384  int w = input_sizes[j];
385 
386  if (check_func(ctx->lumToYV12, "%s_to_y_%d", desc->name, w)) {
387  const uint8_t *src = desc->nb_components == 3 ? src24 : src32;
388  memset(dst0_y, 0xFA, MAX_LINE_SIZE * 2);
389  memset(dst1_y, 0xFA, MAX_LINE_SIZE * 2);
390 
391  call_ref(dst0_y, src, NULL, NULL, w, ctx->input_rgb2yuv_table, NULL);
392  call_new(dst1_y, src, NULL, NULL, w, ctx->input_rgb2yuv_table, NULL);
393 
394  if (memcmp(dst0_y, dst1_y, w * 2))
395  fail();
396 
397  if (desc->nb_components == 3 ||
398  // only bench native endian formats
400  bench_new(dst1_y, src, NULL, NULL, w, ctx->input_rgb2yuv_table, NULL);
401  }
402  }
403  }
404 }
405 
406 static void check_rgb_to_uv(SwsContext *sws)
407 {
408  SwsInternal *ctx = sws_internal(sws);
409 
410  LOCAL_ALIGNED_16(uint8_t, src24, [MAX_LINE_SIZE * 3]);
411  LOCAL_ALIGNED_16(uint8_t, src32, [MAX_LINE_SIZE * 4]);
412  LOCAL_ALIGNED_16(uint8_t, dst0_u, [MAX_LINE_SIZE * 2]);
413  LOCAL_ALIGNED_16(uint8_t, dst0_v, [MAX_LINE_SIZE * 2]);
414  LOCAL_ALIGNED_16(uint8_t, dst1_u, [MAX_LINE_SIZE * 2]);
415  LOCAL_ALIGNED_16(uint8_t, dst1_v, [MAX_LINE_SIZE * 2]);
416 
417  declare_func(void, uint8_t *dstU, uint8_t *dstV,
418  const uint8_t *src1, const uint8_t *src2, const uint8_t *src3,
419  int width, uint32_t *pal, void *opq);
420 
421  randomize_buffers(src24, MAX_LINE_SIZE * 3);
422  randomize_buffers(src32, MAX_LINE_SIZE * 4);
423 
424  for (int i = 0; i < 2 * FF_ARRAY_ELEMS(rgb_formats); i++) {
425  enum AVPixelFormat src_fmt = rgb_formats[i / 2];
426  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src_fmt);
427 
428  ctx->chrSrcHSubSample = (i % 2) ? 0 : 1;
429  sws->src_format = src_fmt;
430  sws->dst_format = ctx->chrSrcHSubSample ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV444P;
432 
433  for (int j = 0; j < FF_ARRAY_ELEMS(input_sizes); j++) {
434  int w = input_sizes[j] >> ctx->chrSrcHSubSample;
435 
436  if (check_func(ctx->chrToYV12, "%s_to_uv%s_%d", desc->name,
437  ctx->chrSrcHSubSample ? "_half" : "",
438  input_sizes[j])) {
439  const uint8_t *src = desc->nb_components == 3 ? src24 : src32;
440  memset(dst0_u, 0xFF, MAX_LINE_SIZE * 2);
441  memset(dst0_v, 0xFF, MAX_LINE_SIZE * 2);
442  memset(dst1_u, 0xFF, MAX_LINE_SIZE * 2);
443  memset(dst1_v, 0xFF, MAX_LINE_SIZE * 2);
444 
445  call_ref(dst0_u, dst0_v, NULL, src, src, w, ctx->input_rgb2yuv_table, NULL);
446  call_new(dst1_u, dst1_v, NULL, src, src, w, ctx->input_rgb2yuv_table, NULL);
447 
448  if (memcmp(dst0_u, dst1_u, w * 2) || memcmp(dst0_v, dst1_v, w * 2))
449  fail();
450 
451  if (desc->nb_components == 3 ||
452  // only bench native endian formats
454  bench_new(dst1_u, dst1_v, NULL, src, src, w, ctx->input_rgb2yuv_table, NULL);
455  }
456  }
457  }
458 }
459 
460 static void check_rgba_to_a(SwsContext *sws)
461 {
462  SwsInternal *ctx = sws_internal(sws);
463 
464  LOCAL_ALIGNED_16(uint8_t, src, [MAX_LINE_SIZE * 4]);
465  LOCAL_ALIGNED_32(uint8_t, dst0_y, [MAX_LINE_SIZE * 2]);
466  LOCAL_ALIGNED_32(uint8_t, dst1_y, [MAX_LINE_SIZE * 2]);
467 
468  declare_func(void, uint8_t *dst, const uint8_t *src1,
469  const uint8_t *src2, const uint8_t *src3, int width,
470  uint32_t *rgb2yuv, void *opq);
471 
473 
474  for (int i = 0; i < FF_ARRAY_ELEMS(rgb_formats); i++) {
476  if (desc->nb_components < 4)
477  continue;
478 
479  sws->src_format = rgb_formats[i];
481 
482  for (int j = 0; j < FF_ARRAY_ELEMS(input_sizes); j++) {
483  int w = input_sizes[j];
484 
485  if (check_func(ctx->alpToYV12, "%s_to_y_%d", desc->name, w)) {
486  memset(dst0_y, 0xFA, MAX_LINE_SIZE * 2);
487  memset(dst1_y, 0xFA, MAX_LINE_SIZE * 2);
488 
489  call_ref(dst0_y, NULL, NULL, src, w, ctx->input_rgb2yuv_table, NULL);
490  call_new(dst1_y, NULL, NULL, src, w, ctx->input_rgb2yuv_table, NULL);
491 
492  if (memcmp(dst0_y, dst1_y, w * 2))
493  fail();
494 
495  // only bench native endian formats
497  bench_new(dst1_y, NULL, NULL, src, w, ctx->input_rgb2yuv_table, NULL);
498  }
499  }
500  }
501 }
502 
503 
504 static const int packed_rgb_fmts[] = {
537 };
538 
539 #define INPUT_SIZE 512
540 
541 static void check_yuv2packed1(void)
542 {
543  static const int alpha_values[] = {0, 2048, 4096};
544 
546  void, SwsInternal *c, const int16_t *lumSrc,
547  const int16_t *chrUSrc[2], const int16_t *chrVSrc[2],
548  const int16_t *alpSrc, uint8_t *dest,
549  int dstW, int uvalpha, int y);
550 
551  const int16_t *luma;
552  const int16_t *chru[2];
553  const int16_t *chrv[2];
554  const int16_t *alpha;
555 
556  LOCAL_ALIGNED_8(int32_t, src_y, [2 * INPUT_SIZE]);
557  LOCAL_ALIGNED_8(int32_t, src_u, [2 * INPUT_SIZE]);
558  LOCAL_ALIGNED_8(int32_t, src_v, [2 * INPUT_SIZE]);
559  LOCAL_ALIGNED_8(int32_t, src_a, [2 * INPUT_SIZE]);
560 
561  LOCAL_ALIGNED_8(uint8_t, dst0, [INPUT_SIZE * sizeof(int32_t[4])]);
562  LOCAL_ALIGNED_8(uint8_t, dst1, [INPUT_SIZE * sizeof(int32_t[4])]);
563 
564  randomize_buffers((uint8_t*)src_y, 2 * INPUT_SIZE * sizeof(int32_t));
565  randomize_buffers((uint8_t*)src_u, 2 * INPUT_SIZE * sizeof(int32_t));
566  randomize_buffers((uint8_t*)src_v, 2 * INPUT_SIZE * sizeof(int32_t));
567  randomize_buffers((uint8_t*)src_a, 2 * INPUT_SIZE * sizeof(int32_t));
568 
569  /* Limit to 14 bit input range */
570  for (int i = 0; i < 2 * INPUT_SIZE; i++) {
571  src_y[i] &= 0x3FFF3FFF;
572  src_a[i] &= 0x3FFF3FFF;
573  src_u[i] &= 0x3FFF3FFF;
574  src_v[i] &= 0x3FFF3FFF;
575  }
576 
577  luma = (int16_t *)src_y;
578  alpha = (int16_t *)src_a;
579  for (int i = 0; i < 2; i++) {
580  chru[i] = (int16_t *)(src_u + i*INPUT_SIZE);
581  chrv[i] = (int16_t *)(src_v + i*INPUT_SIZE);
582  }
583 
584  for (int fmi = 0; fmi < FF_ARRAY_ELEMS(packed_rgb_fmts); fmi++) {
586  int line_size = INPUT_SIZE * desc->comp[0].step;
587  SwsContext *sws;
588  SwsInternal *c;
589 
590  if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
591  line_size = AV_CEIL_RSHIFT(line_size, 3);
592 
596  if (!sws)
597  fail();
598 
599  c = sws_internal(sws);
600 
601  for (int ai = 0; ai < FF_ARRAY_ELEMS(alpha_values); ai++) {
602  const int chr_alpha = alpha_values[ai];
603  if (check_func(c->yuv2packed1, "yuv2%s_1_%d_%d", desc->name, chr_alpha, INPUT_SIZE)) {
604  memset(dst0, 0xFF, INPUT_SIZE * sizeof(int32_t[4]));
605  memset(dst1, 0xFF, INPUT_SIZE * sizeof(int32_t[4]));
606 
607  call_ref(c, luma, chru, chrv, alpha, dst0, INPUT_SIZE, chr_alpha, 0);
608  call_new(c, luma, chru, chrv, alpha, dst1, INPUT_SIZE, chr_alpha, 0);
609 
610  if (memcmp(dst0, dst1, line_size))
611  fail();
612 
613  bench_new(c, luma, chru, chrv, alpha, dst1, INPUT_SIZE, chr_alpha, 0);
614  }
615  }
616 
617  sws_freeContext(sws);
618  }
619 }
620 
621 static void check_yuv2packed2(void)
622 {
623  static const int alpha_values[] = {0, 2048, 4096};
624 
626  void, SwsInternal *c, const int16_t *lumSrc[2],
627  const int16_t *chrUSrc[2], const int16_t *chrVSrc[2],
628  const int16_t *alpSrc[2], uint8_t *dest,
629  int dstW, int yalpha, int uvalpha, int y);
630 
631  const int16_t *luma[2];
632  const int16_t *chru[2];
633  const int16_t *chrv[2];
634  const int16_t *alpha[2];
635 
636  LOCAL_ALIGNED_8(int32_t, src_y, [2 * INPUT_SIZE]);
637  LOCAL_ALIGNED_8(int32_t, src_u, [2 * INPUT_SIZE]);
638  LOCAL_ALIGNED_8(int32_t, src_v, [2 * INPUT_SIZE]);
639  LOCAL_ALIGNED_8(int32_t, src_a, [2 * INPUT_SIZE]);
640 
641  LOCAL_ALIGNED_8(uint8_t, dst0, [INPUT_SIZE * sizeof(int32_t[4])]);
642  LOCAL_ALIGNED_8(uint8_t, dst1, [INPUT_SIZE * sizeof(int32_t[4])]);
643 
644  randomize_buffers((uint8_t*)src_y, 2 * INPUT_SIZE * sizeof(int32_t));
645  randomize_buffers((uint8_t*)src_u, 2 * INPUT_SIZE * sizeof(int32_t));
646  randomize_buffers((uint8_t*)src_v, 2 * INPUT_SIZE * sizeof(int32_t));
647  randomize_buffers((uint8_t*)src_a, 2 * INPUT_SIZE * sizeof(int32_t));
648 
649  /* Limit to 14 bit input range */
650  for (int i = 0; i < 2 * INPUT_SIZE; i++) {
651  src_y[i] &= 0x3FFF3FFF;
652  src_u[i] &= 0x3FFF3FFF;
653  src_v[i] &= 0x3FFF3FFF;
654  src_a[i] &= 0x3FFF3FFF;
655  }
656 
657  for (int i = 0; i < 2; i++) {
658  luma[i] = (int16_t *)(src_y + i*INPUT_SIZE);
659  chru[i] = (int16_t *)(src_u + i*INPUT_SIZE);
660  chrv[i] = (int16_t *)(src_v + i*INPUT_SIZE);
661  alpha[i] = (int16_t *)(src_a + i*INPUT_SIZE);
662  }
663 
664  for (int fmi = 0; fmi < FF_ARRAY_ELEMS(packed_rgb_fmts); fmi++) {
666  int line_size = INPUT_SIZE * desc->comp[0].step;
667  SwsContext *sws;
668  SwsInternal *c;
669 
670  if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
671  line_size = AV_CEIL_RSHIFT(line_size, 3);
672 
676  if (!sws)
677  fail();
678 
679  c = sws_internal(sws);
680 
681  for (int ai = 0; ai < FF_ARRAY_ELEMS(alpha_values); ai++) {
682  const int lum_alpha = alpha_values[ai];
683  const int chr_alpha = alpha_values[ai];
684  if (check_func(c->yuv2packed2, "yuv2%s_2_%d_%d", desc->name, lum_alpha, INPUT_SIZE)) {
685  memset(dst0, 0xFF, INPUT_SIZE * sizeof(int32_t[4]));
686  memset(dst1, 0xFF, INPUT_SIZE * sizeof(int32_t[4]));
687 
688  call_ref(c, luma, chru, chrv, alpha, dst0, INPUT_SIZE, lum_alpha, chr_alpha, 0);
689  call_new(c, luma, chru, chrv, alpha, dst1, INPUT_SIZE, lum_alpha, chr_alpha, 0);
690 
691  if (memcmp(dst0, dst1, line_size))
692  fail();
693 
694  bench_new(c, luma, chru, chrv, alpha, dst1, INPUT_SIZE, lum_alpha, chr_alpha, 0);
695  }
696  }
697 
698  sws_freeContext(sws);
699  }
700 }
701 
702 static void check_yuv2packedX(void)
703 {
704 #define LARGEST_FILTER 16
705  static const int filter_sizes[] = {2, 16};
706 
708  void, SwsInternal *c, const int16_t *lumFilter,
709  const int16_t **lumSrcx, int lumFilterSize,
710  const int16_t *chrFilter, const int16_t **chrUSrcx,
711  const int16_t **chrVSrcx, int chrFilterSize,
712  const int16_t **alpSrcx, uint8_t *dest,
713  int dstW, int y);
714 
715  const int16_t *luma[LARGEST_FILTER];
716  const int16_t *chru[LARGEST_FILTER];
717  const int16_t *chrv[LARGEST_FILTER];
718  const int16_t *alpha[LARGEST_FILTER];
719 
720  LOCAL_ALIGNED_8(int16_t, luma_filter, [LARGEST_FILTER]);
721  LOCAL_ALIGNED_8(int16_t, chr_filter, [LARGEST_FILTER]);
722 
727 
728  LOCAL_ALIGNED_8(uint8_t, dst0, [INPUT_SIZE * sizeof(int32_t[4])]);
729  LOCAL_ALIGNED_8(uint8_t, dst1, [INPUT_SIZE * sizeof(int32_t[4])]);
730 
731  randomize_buffers((uint8_t*)src_y, LARGEST_FILTER * INPUT_SIZE * sizeof(int32_t));
732  randomize_buffers((uint8_t*)src_u, LARGEST_FILTER * INPUT_SIZE * sizeof(int32_t));
733  randomize_buffers((uint8_t*)src_v, LARGEST_FILTER * INPUT_SIZE * sizeof(int32_t));
734  randomize_buffers((uint8_t*)src_a, LARGEST_FILTER * INPUT_SIZE * sizeof(int32_t));
735 
736  /* Limit to 14 bit input range */
737  for (int i = 0; i < LARGEST_FILTER * INPUT_SIZE; i++) {
738  src_y[i] &= 0x3FFF3FFF;
739  src_u[i] &= 0x3FFF3FFF;
740  src_v[i] &= 0x3FFF3FFF;
741  src_a[i] &= 0x3FFF3FFF;
742  }
743 
744  for (int i = 0; i < LARGEST_FILTER; i++) {
745  luma[i] = (int16_t *)(src_y + i*INPUT_SIZE);
746  chru[i] = (int16_t *)(src_u + i*INPUT_SIZE);
747  chrv[i] = (int16_t *)(src_v + i*INPUT_SIZE);
748  alpha[i] = (int16_t *)(src_a + i*INPUT_SIZE);
749  }
750 
751  for (int fmi = 0; fmi < FF_ARRAY_ELEMS(packed_rgb_fmts); fmi++) {
753  int line_size = INPUT_SIZE * desc->comp[0].step;
754  SwsContext *sws;
755  SwsInternal *c;
756 
757  if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
758  line_size = AV_CEIL_RSHIFT(line_size, 3);
759 
763  if (!sws)
764  fail();
765 
766  c = sws_internal(sws);
767 
768  for (int fsi = 0; fsi < FF_ARRAY_ELEMS(filter_sizes); fsi++) {
769  const int luma_filter_size = filter_sizes[fsi];
770  const int chr_filter_size = filter_sizes[fsi];
771 
772  for (int i = 0; i < luma_filter_size; i++)
773  luma_filter[i] = -((1 << 12) / (luma_filter_size - 1));
774  luma_filter[rnd() % luma_filter_size] = (1 << 13) - 1;
775 
776  for (int i = 0; i < chr_filter_size; i++)
777  chr_filter[i] = -((1 << 12) / (chr_filter_size - 1));
778  chr_filter[rnd() % chr_filter_size] = (1 << 13) - 1;
779 
780  if (check_func(c->yuv2packedX, "yuv2%s_X_%d_%d", desc->name, luma_filter_size, INPUT_SIZE)) {
781  memset(dst0, 0xFF, INPUT_SIZE * sizeof(int32_t[4]));
782  memset(dst1, 0xFF, INPUT_SIZE * sizeof(int32_t[4]));
783 
784  call_ref(c, luma_filter, luma, luma_filter_size,
785  chr_filter, chru, chrv, chr_filter_size,
786  alpha, dst0, INPUT_SIZE, 0);
787 
788  call_new(c, luma_filter, luma, luma_filter_size,
789  chr_filter, chru, chrv, chr_filter_size,
790  alpha, dst1, INPUT_SIZE, 0);
791 
792  if (memcmp(dst0, dst1, line_size))
793  fail();
794 
795  bench_new(c, luma_filter, luma, luma_filter_size,
796  chr_filter, chru, chrv, chr_filter_size,
797  alpha, dst1, INPUT_SIZE, 0);
798  }
799  }
800 
801  sws_freeContext(sws);
802  }
803 }
804 
805 #undef INPUT_SIZE
806 #undef LARGEST_FILTER
807 
809 {
810  SwsContext *sws;
811 
813 
814  check_shuffle_bytes(shuffle_bytes_2103, "shuffle_bytes_2103");
815  report("shuffle_bytes_2103");
816 
817  check_shuffle_bytes(shuffle_bytes_0321, "shuffle_bytes_0321");
818  report("shuffle_bytes_0321");
819 
820  check_shuffle_bytes(shuffle_bytes_1230, "shuffle_bytes_1230");
821  report("shuffle_bytes_1230");
822 
823  check_shuffle_bytes(shuffle_bytes_3012, "shuffle_bytes_3012");
824  report("shuffle_bytes_3012");
825 
826  check_shuffle_bytes(shuffle_bytes_3210, "shuffle_bytes_3210");
827  report("shuffle_bytes_3210");
828 
829  check_shuffle_bytes(shuffle_bytes_3102, "shuffle_bytes_3102");
830  report("shuffle_bytes_3102");
831 
832  check_shuffle_bytes(shuffle_bytes_2013, "shuffle_bytes_2013");
833  report("shuffle_bytes_2013");
834 
835  check_shuffle_bytes(shuffle_bytes_1203, "shuffle_bytes_1203");
836  report("shuffle_bytes_1203");
837 
838  check_shuffle_bytes(shuffle_bytes_2130, "shuffle_bytes_2130");
839  report("shuffle_bytes_2130");
840 
841  {
842  /* rgb24tobgr24 operates on 3-byte pixels, so test widths must be
843  * multiples of 3 to avoid reading past the source buffer. */
844  static const int rgb24_width[] = {3, 12, 24, 36, 48, 126, 1920 * 3};
845  int i;
846 #define RGB24_BENCH_WIDTH (1920 * 3)
849  LOCAL_ALIGNED_32(uint8_t, dst0, [RGB24_BENCH_WIDTH]);
850  LOCAL_ALIGNED_32(uint8_t, dst1, [RGB24_BENCH_WIDTH]);
851 
852  declare_func(void, const uint8_t *src, uint8_t *dst, int src_size);
853 
854  memset(dst0, 0, RGB24_BENCH_WIDTH);
855  memset(dst1, 0, RGB24_BENCH_WIDTH);
857  memcpy(src1, src0, RGB24_BENCH_WIDTH);
858 
859  if (check_func(rgb24tobgr24, "rgb24tobgr24")) {
860  for (i = 0; i < FF_ARRAY_ELEMS(rgb24_width); i++) {
861  call_ref(src0, dst0, rgb24_width[i]);
862  call_new(src1, dst1, rgb24_width[i]);
863  if (memcmp(dst0, dst1, rgb24_width[i]))
864  fail();
865  }
867  }
868 #undef RGB24_BENCH_WIDTH
869  }
870  report("rgb24tobgr24");
871 
872  {
873  /* rgb32tobgr24: 4-byte pixels → 3-byte pixels.
874  * Test widths must be multiples of 4 (one pixel).
875  * Sizes chosen to exercise each codepath tier:
876  * 4 = scalar only (1 pixel)
877  * 16 = scalar only (4 pixels, loop iteration)
878  * 32 = medium only
879  * 48 = medium + scalar
880  * 64 = fast only (exact)
881  * 68 = fast + scalar (skip medium)
882  * 100 = fast + medium + scalar (all tiers)
883  * 128 = fast only (multi-iteration)
884  * 1920*4 = fast only (benchmark width)
885  */
886  static const int rgb32_widths[] = {4, 16, 32, 48, 64, 68, 100, 128, 1920 * 4};
887 #define RGB32_BENCH_WIDTH (1920 * 4)
888 #define RGB32_DST_SIZE (RGB32_BENCH_WIDTH * 3 / 4 + 8)
891  LOCAL_ALIGNED_32(uint8_t, dst0, [RGB32_DST_SIZE]);
892  LOCAL_ALIGNED_32(uint8_t, dst1, [RGB32_DST_SIZE]);
893 
894  declare_func(void, const uint8_t *src, uint8_t *dst, int src_size);
895 
897  memcpy(src1, src0, RGB32_BENCH_WIDTH);
898 
899  if (check_func(rgb32tobgr24, "rgb32tobgr24")) {
900  for (int i = 0; i < FF_ARRAY_ELEMS(rgb32_widths); i++) {
901  int out_size = rgb32_widths[i] * 3 / 4;
902  memset(dst0, 0xAA, RGB32_DST_SIZE);
903  memset(dst1, 0xAA, RGB32_DST_SIZE);
904  call_ref(src0, dst0, rgb32_widths[i]);
905  call_new(src1, dst1, rgb32_widths[i]);
906  if (memcmp(dst0, dst1, out_size) ||
907  dst0[out_size] != 0xAA ||
908  dst1[out_size] != 0xAA)
909  fail();
910  }
912  }
913 #undef RGB32_DST_SIZE
914 #undef RGB32_BENCH_WIDTH
915  }
916  report("rgb32tobgr24");
917 
918  {
919  /* rgb24tobgr32: 3-byte pixels → 4-byte pixels.
920  * Test widths must be multiples of 3 (one pixel).
921  * Sizes chosen to exercise each codepath tier:
922  * 3 = scalar only (1 pixel)
923  * 12 = scalar only (4 pixels, loop iteration)
924  * 24 = medium only
925  * 36 = medium + scalar
926  * 48 = fast only (exact)
927  * 51 = fast + scalar (skip medium)
928  * 126 = fast + medium + scalar (all tiers)
929  * 1920*3 = fast only (benchmark width)
930  */
931  static const int rgb24to32_widths[] = {3, 12, 24, 36, 48, 51, 126, 1920 * 3};
932 #define RGB24TO32_BENCH_WIDTH (1920 * 3)
933 #define RGB24TO32_DST_SIZE (RGB24TO32_BENCH_WIDTH * 4 / 3 + 8)
936  LOCAL_ALIGNED_32(uint8_t, dst0, [RGB24TO32_DST_SIZE]);
937  LOCAL_ALIGNED_32(uint8_t, dst1, [RGB24TO32_DST_SIZE]);
938 
939  declare_func(void, const uint8_t *src, uint8_t *dst, int src_size);
940 
942  memcpy(src1, src0, RGB24TO32_BENCH_WIDTH);
943 
944  if (check_func(rgb24tobgr32, "rgb24tobgr32")) {
945  for (int i = 0; i < FF_ARRAY_ELEMS(rgb24to32_widths); i++) {
946  int out_size = rgb24to32_widths[i] * 4 / 3;
947  memset(dst0, 0xAA, RGB24TO32_DST_SIZE);
948  memset(dst1, 0xAA, RGB24TO32_DST_SIZE);
949  call_ref(src0, dst0, rgb24to32_widths[i]);
950  call_new(src1, dst1, rgb24to32_widths[i]);
951  if (memcmp(dst0, dst1, out_size) ||
952  dst0[out_size] != 0xAA ||
953  dst1[out_size] != 0xAA)
954  fail();
955  }
957  }
958 #undef RGB24TO32_DST_SIZE
959 #undef RGB24TO32_BENCH_WIDTH
960  }
961  report("rgb24tobgr32");
962 
963  check_interleaved_to_planar(uyvytoyuv422, "uyvytoyuv422", 1);
964  report("uyvytoyuv422");
965  check_interleaved_to_planar(yuyvtoyuv422, "yuyvtoyuv422", 2);
966  report("yuyvtoyuv422");
967 
969  report("interleave_bytes");
970 
972  report("deinterleave_bytes");
973 
977  if (!sws)
978  fail();
979 
980  check_rgb_to_y(sws);
981  report("rgb_to_y");
982 
983  check_rgb_to_uv(sws);
984  report("rgb_to_uv");
985 
986  check_rgba_to_a(sws);
987  report("rgba_to_a");
988 
989  check_rgb24toyv12(sws);
990  report("rgb24toyv12");
991 
992  sws_freeContext(sws);
993 
995  report("yuv2packed1");
996 
998  report("yuv2packed2");
999 
1001  report("yuv2packedX");
1002 }
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:66
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
rgb32tobgr24
void(* rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:35
shuffle_bytes_3012
void(* shuffle_bytes_3012)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:57
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
mem_internal.h
planes
static const struct @608 planes[]
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_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
MAX_STRIDE
#define MAX_STRIDE
Definition: sw_rgb.c:46
src1
const pixel * src1
Definition: h264pred_template.c:420
AV_CPU_FLAG_MMXEXT
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
Definition: cpu.h:33
rgb_formats
static enum AVPixelFormat rgb_formats[]
Definition: sw_rgb.c:352
h
uint8_t h
Definition: sw_rgb.c:41
sws_freeContext
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2297
out_size
static int out_size
Definition: movenc.c:56
pixdesc.h
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
SWS_BITEXACT
@ SWS_BITEXACT
Definition: swscale.h:180
shuffle_bytes_3210
void(* shuffle_bytes_3210)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:58
test
Definition: idctdsp.c:35
rgb2yuv
static const char rgb2yuv[]
Definition: vf_scale_vulkan.c:86
AV_PIX_FMT_RGB32_1
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:512
check_func
#define check_func
Definition: test.h:480
RGB32_BENCH_WIDTH
#define RGB32_BENCH_WIDTH
yuyvtoyuv422
void(* yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, int width, int height, int lumStride, int chromStride, int srcStride)
Definition: rgb2rgb.c:103
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
bench_new
#define bench_new
Definition: test.h:486
BUFSIZE
#define BUFSIZE
Definition: sw_rgb.c:123
check_shuffle_bytes
static void check_shuffle_bytes(void *func, const char *report)
Definition: sw_rgb.c:49
AV_PIX_FMT_RGB555BE
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:114
call_ref
#define call_ref
Definition: test.h:484
check_yuv2packedX
static void check_yuv2packedX(void)
Definition: sw_rgb.c:702
shuffle_bytes_2130
void(* shuffle_bytes_2130)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:61
check_yuv2packed1
static void check_yuv2packed1(void)
Definition: sw_rgb.c:541
RGB24TO32_BENCH_WIDTH
#define RGB24TO32_BENCH_WIDTH
checkasm.h
cmp_off_by_n
static int cmp_off_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int accuracy)
Definition: sw_rgb.c:125
declare_func_emms
#define declare_func_emms
Definition: test.h:489
AV_PIX_FMT_BGR8
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:90
randomize_buffers
#define randomize_buffers(buf, size)
Definition: sw_rgb.c:33
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
check_rgb_to_y
static void check_rgb_to_y(SwsContext *sws)
Definition: sw_rgb.c:361
intreadwrite.h
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
input_sizes
static const int input_sizes[]
Definition: sw_rgb.c:351
declare_func
#define declare_func
Definition: test.h:488
shuffle_bytes_1230
void(* shuffle_bytes_1230)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:56
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:130
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
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
shuffle_bytes_2103
void(* shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:55
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
LARGEST_FILTER
#define LARGEST_FILTER
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
LOCAL_ALIGNED_8
#define LOCAL_ALIGNED_8(t, v,...)
Definition: mem_internal.h:128
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
INPUT_SIZE
#define INPUT_SIZE
Definition: sw_rgb.c:539
interleaveBytes
void(* interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst, int width, int height, int src1Stride, int src2Stride, int dstStride)
Definition: rgb2rgb.c:88
checkasm_check_sw_rgb
void checkasm_check_sw_rgb(void)
Definition: sw_rgb.c:808
fail
#define fail
Definition: test.h:478
AV_PIX_FMT_RGB565LE
@ AV_PIX_FMT_RGB565LE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:113
shuffle_bytes_3102
void(* shuffle_bytes_3102)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:59
NULL
#define NULL
Definition: coverity.c:32
LOCAL_ALIGNED_32
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:132
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_BGR565LE
@ AV_PIX_FMT_BGR565LE
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
Definition: pixfmt.h:118
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
RGB24TO32_DST_SIZE
#define RGB24TO32_DST_SIZE
check_rgb24toyv12
static void check_rgb24toyv12(SwsContext *sws)
Definition: sw_rgb.c:134
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)3R 3G 2B(lsb)
Definition: pixfmt.h:93
ff_sws_rgb2rgb_init
av_cold void ff_sws_rgb2rgb_init(void)
Definition: rgb2rgb.c:127
abs
#define abs(x)
Definition: cuda_runtime.h:35
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
RGB32_DST_SIZE
#define RGB32_DST_SIZE
AV_PIX_FMT_BGR555BE
@ AV_PIX_FMT_BGR555BE
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:119
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:101
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_BGR4_BYTE
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:92
MAX_HEIGHT
#define MAX_HEIGHT
Definition: sw_rgb.c:47
rgb24tobgr32
void(* rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:38
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
height
#define height
Definition: dsp.h:89
check_interleave_bytes
static void check_interleave_bytes(void)
Definition: sw_rgb.c:208
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
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
rnd
#define rnd
Definition: checkasm.h:140
MAX_LINE_SIZE
#define MAX_LINE_SIZE
Definition: sw_rgb.c:350
AV_PIX_FMT_FLAG_BITSTREAM
#define AV_PIX_FMT_FLAG_BITSTREAM
All values of a component are bit-wise packed end to end.
Definition: pixdesc.h:124
shuffle_bytes_0321
void(* shuffle_bytes_0321)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:54
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_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:511
AV_PIX_FMT_BGR565BE
@ AV_PIX_FMT_BGR565BE
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
Definition: pixfmt.h:117
check_rgba_to_a
static void check_rgba_to_a(SwsContext *sws)
Definition: sw_rgb.c:460
SwsContext::dst_format
int dst_format
Destination pixel format.
Definition: swscale.h:279
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
uyvytoyuv422
void(* uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, int width, int height, int lumStride, int chromStride, int srcStride)
Definition: rgb2rgb.c:97
AV_PIX_FMT_RGB555LE
@ AV_PIX_FMT_RGB555LE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined
Definition: pixfmt.h:115
ff_rgb24toyv12
void(* ff_rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, int width, int height, int lumStride, int chromStride, int srcStride, const int32_t *rgb2yuv)
Height should be a multiple of 2 and width should be a multiple of 2.
Definition: rgb2rgb.c:81
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
packed_rgb_fmts
static const int packed_rgb_fmts[]
Definition: sw_rgb.c:504
ff_sws_init_scale
void ff_sws_init_scale(SwsInternal *c)
Definition: swscale.c:697
src2
const pixel * src2
Definition: h264pred_template.c:421
common.h
swscale_internal.h
width
static const uint8_t width[]
Definition: sw_rgb.c:40
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
call_new
#define call_new
Definition: test.h:485
w
uint8_t w
Definition: sw_rgb.c:41
AV_CPU_FLAG_MMX
#define AV_CPU_FLAG_MMX
standard MMX
Definition: cpu.h:32
SwsInternal
Definition: swscale_internal.h:337
check_rgb_to_uv
static void check_rgb_to_uv(SwsContext *sws)
Definition: sw_rgb.c:406
deinterleaveBytes
void(* deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2, int width, int height, int srcStride, int dst1Stride, int dst2Stride)
Definition: rgb2rgb.c:91
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:1966
check_yuv2packed2
static void check_yuv2packed2(void)
Definition: sw_rgb.c:621
shuffle_bytes_2013
void(* shuffle_bytes_2013)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:60
shuffle_bytes_1203
void(* shuffle_bytes_1203)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:62
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
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
rgb24tobgr24
void(* rgb24tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:39
AV_PIX_FMT_RGB565BE
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:112
src0
const pixel *const src0
Definition: h264pred_template.c:419
desc
const char * desc
Definition: libsvtav1.c:83
report
#define report
Definition: test.h:479
SwsContext::src_format
int src_format
Source pixel format.
Definition: swscale.h:278
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AV_PIX_FMT_BGR555LE
@ AV_PIX_FMT_BGR555LE
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined
Definition: pixfmt.h:120
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
RGB24_BENCH_WIDTH
#define RGB24_BENCH_WIDTH
int32_t
int32_t
Definition: audioconvert.c:56
sws_internal
static SwsInternal * sws_internal(const SwsContext *sws)
Definition: swscale_internal.h:79
SWS_ACCURATE_RND
@ SWS_ACCURATE_RND
Force bit-exact output.
Definition: swscale.h:179
check_deinterleave_bytes
static void check_deinterleave_bytes(void)
Definition: sw_rgb.c:276
SwsContext
Main external API structure.
Definition: swscale.h:229
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
rgb2rgb.h
src
#define src
Definition: vp8dsp.c:248
check_interleaved_to_planar
static void check_interleaved_to_planar(void *func, const char *report, int odd_tail)
Definition: sw_rgb.c:75
swscale.h
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