2 * This file is part of FFmpeg.
4 * FFmpeg is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "libavutil/common.h"
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/mem_internal.h"
24 #include "libavutil/pixdesc.h"
26 #include "libswscale/swscale.h"
27 #include "libswscale/swscale_internal.h"
31 #define randomize_buffers(buf, size) \
33 for (int j = 0; j < size; j += 4) \
34 AV_WN32(buf + j, rnd()); \
37 static void check_semiplanar(int dst_pix_fmt
)
39 static const int src_fmts
[] = {
43 const AVPixFmtDescriptor
*dst_desc
= av_pix_fmt_desc_get(dst_pix_fmt
);
45 #define MAX_LINE_SIZE 1920
46 static const int input_sizes
[] = {8, 128, 1080, MAX_LINE_SIZE
};
48 declare_func_emms(AV_CPU_FLAG_MMX
| AV_CPU_FLAG_MMXEXT
,
49 int, SwsInternal
*c
, const uint8_t *src
[],
50 int srcStride
[], int srcSliceY
, int srcSliceH
,
51 uint8_t *dst
[], int dstStride
[]);
53 LOCAL_ALIGNED_8(uint8_t, src_y
, [MAX_LINE_SIZE
* NUM_LINES
]);
54 LOCAL_ALIGNED_8(uint8_t, src_uv
, [MAX_LINE_SIZE
* NUM_LINES
* 2]);
55 const uint8_t *src
[4] = { src_y
, src_uv
};
57 LOCAL_ALIGNED_8(uint8_t, dst0_y
, [MAX_LINE_SIZE
* NUM_LINES
]);
58 LOCAL_ALIGNED_8(uint8_t, dst0_u
, [MAX_LINE_SIZE
* NUM_LINES
/ 2]);
59 LOCAL_ALIGNED_8(uint8_t, dst0_v
, [MAX_LINE_SIZE
* NUM_LINES
/ 2]);
60 uint8_t *dst0
[4] = { dst0_y
, dst0_u
, dst0_v
};
62 LOCAL_ALIGNED_8(uint8_t, dst1_y
, [MAX_LINE_SIZE
* NUM_LINES
]);
63 LOCAL_ALIGNED_8(uint8_t, dst1_u
, [MAX_LINE_SIZE
* NUM_LINES
/ 2]);
64 LOCAL_ALIGNED_8(uint8_t, dst1_v
, [MAX_LINE_SIZE
* NUM_LINES
/ 2]);
65 uint8_t *dst1
[4] = { dst1_y
, dst1_u
, dst1_v
};
67 randomize_buffers(src_y
, MAX_LINE_SIZE
* NUM_LINES
);
68 randomize_buffers(src_uv
, MAX_LINE_SIZE
* NUM_LINES
* 2);
70 for (int sfi
= 0; sfi
< FF_ARRAY_ELEMS(src_fmts
); sfi
++) {
71 int src_pix_fmt
= src_fmts
[sfi
];
72 const AVPixFmtDescriptor
*src_desc
= av_pix_fmt_desc_get(src_pix_fmt
);
73 for (int isi
= 0; isi
< FF_ARRAY_ELEMS(input_sizes
); isi
++) {
77 int width
= input_sizes
[isi
];
79 int srcSliceH
= NUM_LINES
;
86 MAX_LINE_SIZE
>> dst_desc
->log2_chroma_w
,
87 MAX_LINE_SIZE
>> dst_desc
->log2_chroma_w
,
90 // override log level to prevent spamming of the message
91 // "No accelerated colorspace conversion found from %s to %s"
92 log_level
= av_log_get_level();
93 av_log_set_level(AV_LOG_ERROR
);
94 sws
= sws_getContext(width
, srcSliceH
, src_pix_fmt
,
95 width
, srcSliceH
, dst_pix_fmt
,
97 av_log_set_level(log_level
);
101 c
= sws_internal(sws
);
102 if (check_func(c
->convert_unscaled
, "%s_%s_%d", src_desc
->name
, dst_desc
->name
, width
)) {
103 memset(dst0_y
, 0xFF, MAX_LINE_SIZE
* NUM_LINES
);
104 memset(dst0_u
, 0xFF, MAX_LINE_SIZE
* NUM_LINES
/ 2);
105 memset(dst0_v
, 0xFF, MAX_LINE_SIZE
* NUM_LINES
/ 2);
106 memset(dst1_y
, 0xFF, MAX_LINE_SIZE
* NUM_LINES
);
107 memset(dst1_u
, 0xFF, MAX_LINE_SIZE
* NUM_LINES
/ 2);
108 memset(dst1_v
, 0xFF, MAX_LINE_SIZE
* NUM_LINES
/ 2);
110 call_ref(c
, src
, srcStride
, srcSliceY
,
111 srcSliceH
, dst0
, dstStride
);
112 call_new(c
, src
, srcStride
, srcSliceY
,
113 srcSliceH
, dst1
, dstStride
);
115 if (memcmp(dst0_y
, dst1_y
, MAX_LINE_SIZE
* NUM_LINES
) ||
116 memcmp(dst0_u
, dst1_u
, MAX_LINE_SIZE
* NUM_LINES
/ 2) ||
117 memcmp(dst0_v
, dst1_v
, MAX_LINE_SIZE
* NUM_LINES
/ 2))
120 bench_new(c
, src
, srcStride
, srcSliceY
,
121 srcSliceH
, dst0
, dstStride
);
123 sws_freeContext(sws
);
131 void checkasm_check_sw_yuv2yuv(void)
133 check_semiplanar(AV_PIX_FMT_YUV420P
);