tests/checkasm/vc1dsp: Improve mspel test

Up until now, only the fullpel test (i.e. the test without pixel
interpolation) has been tested at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2026-07-01 20:00:46 +02:00
parent a693a4cd80
commit 296d86c8bb
+61 -19
View File
@@ -441,34 +441,76 @@ static void check_unescape(void)
static void check_mspel_pixels(void)
{
LOCAL_ALIGNED_16(uint8_t, src0, [32 * 32]);
LOCAL_ALIGNED_16(uint8_t, src1, [32 * 32]);
LOCAL_ALIGNED_16(uint8_t, dst0, [32 * 32]);
LOCAL_ALIGNED_16(uint8_t, dst1, [32 * 32]);
enum {
MAX_BLOCK_SIZE = 16,
MAX_STRIDE = 64,
/// BUF_SIZE is bigger than necessary in order to test strides > block width.
BUF_SIZE = (MAX_BLOCK_SIZE - 1) * MAX_STRIDE + MAX_BLOCK_SIZE,
/**
* Due to qpel interpolation the input needs one extra line at the top
* and two at the bottom; horizontal interpolation also needs one pixel
* to the left and two to the right. At least the x86 implementation
* actually accesses three pixels to the right.
* The input is not subject to alignment requirements; making the input buffer
* bigger (by MAX_BLOCK_SIZE - 1) allows us to use a random misalignment.
*/
INPUT_BUF_SIZE = (MAX_BLOCK_SIZE - 1) + 1 +
(MAX_BLOCK_SIZE + 1 + 2 - 1) * MAX_STRIDE + MAX_BLOCK_SIZE + 2 + 1,
};
DECLARE_ALIGNED(16, uint8_t, dstbuf0)[BUF_SIZE];
DECLARE_ALIGNED(16, uint8_t, dstbuf1)[BUF_SIZE];
uint8_t srcbuf0[INPUT_BUF_SIZE];
uint8_t srcbuf1[INPUT_BUF_SIZE];
VC1DSPContext h;
const test tests[] = {
VC1DSP_SIZED_TEST(put_vc1_mspel_pixels_tab[0][0], 16, 16)
VC1DSP_SIZED_TEST(put_vc1_mspel_pixels_tab[1][0], 8, 8)
VC1DSP_SIZED_TEST(avg_vc1_mspel_pixels_tab[0][0], 16, 16)
VC1DSP_SIZED_TEST(avg_vc1_mspel_pixels_tab[1][0], 8, 8)
const struct MSPelTest {
const char *name;
size_t offset;
} tests[] = {
#define MSPEL_TEST(elem) { .name = #elem, offsetof(VC1DSPContext, elem) }
MSPEL_TEST(put_vc1_mspel_pixels_tab),
MSPEL_TEST(avg_vc1_mspel_pixels_tab),
};
ff_vc1dsp_init(&h);
for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) {
void (*func)(uint8_t *, const uint8_t*, ptrdiff_t, int) = *(void **)((intptr_t) &h + tests[t].offset);
if (check_func(func, "vc1dsp.%s", tests[t].name)) {
declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, const uint8_t*, ptrdiff_t, int);
RANDOMIZE_BUFFER8(dst, 32 * 32);
RANDOMIZE_BUFFER8(src, 32 * 32);
call_ref(dst0, src0, 32, 0);
call_new(dst1, src1, 32, 0);
if (memcmp(dst0, dst1, 32 * 32)) {
fail();
const vc1op_pixels_func (*func)[16] = (vc1op_pixels_func(*)[16])((char*)&h + tests[t].offset);
for (unsigned j = 0; j < 2; ++j) {
const unsigned blocksize = 16 >> j;
for (unsigned dxy = 0; dxy < 16; ++dxy) {
if (!check_func(func[j][dxy], "vc1dsp.%s_mc%u%u_%u", tests[t].name, dxy & 3, dxy >> 2, blocksize))
continue;
declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, const uint8_t*, ptrdiff_t, int);
size_t dst_offset = (rnd() % (MAX_BLOCK_SIZE / blocksize)) * blocksize;
ptrdiff_t stride = (rnd() % (MAX_STRIDE / blocksize) + 1) * blocksize;
size_t src_offset = 1 + stride + rnd() % MAX_BLOCK_SIZE;
const uint8_t *src0 = srcbuf0 + src_offset, *src1 = srcbuf1 + src_offset;
uint8_t *dst0 = dstbuf0 + dst_offset, *dst1 = dstbuf1 + dst_offset;
if (rnd() & 1) {
// Flip stride.
dst1 += (blocksize - 1) * stride;
dst0 += (blocksize - 1) * stride;
// We need one line above src and two lines below the block,
// hence blocksize * stride.
src0 += blocksize * stride;
src1 += blocksize * stride;
stride = -stride;
}
RANDOMIZE_BUFFER8(srcbuf, sizeof(srcbuf0));
for (int round = 0; round <= 1; ++round) {
RANDOMIZE_BUFFER8(dstbuf, sizeof(dstbuf0));
call_ref(dst0, src0, stride, round);
call_new(dst1, src1, stride, round);
if (memcmp(dstbuf0, dstbuf1, sizeof(dstbuf0))) {
fail();
}
}
bench_new(dst1, src1, stride, 0);
}
bench_new(dst1, src0, 32, 0);
}
}
}