Reproduced, thank you.
----
Okay, it's a bug in env->BitBlt.
fft3d calls it in CoverbufToPlanarPlane
Code:
for (h=0; h<dst_height; h++)
{
env->BitBlt(dstp, dst_pitch, coverbuf1, coverpitch, dst_width, 1); // copy pure frame size only
dstp += dst_pitch;
coverbuf1 += coverpitch;
}
That in BitBlt, passing the height == 1 condition, goes to
Code:
#ifdef X86_32
if (GetCPUFlags() & CPUF_INTEGER_SSE)
memcpy_amd(dstp, srcp, src_pitch*height); // SSE
else
#endif
memcpy(dstp, srcp, src_pitch*height); // fallback
}
which in any case ends up broken because you actually have to copy row_size bytes instead of src_pitch bytes in this case.
So either we could remove the height == 1 check, replace src_pitch with row_size (they're equal when height != 1) or fix fft3d to call BitBlt once for the whole frame instead of every line.
Original Avisynth actually does it right:
Code:
if (height == 1 || (src_pitch == dst_pitch && dst_pitch == row_size)) {
memcpy_amd(dstp, srcp, row_size*height);
} else {
asm_BitBlt_ISSE(dstp,dst_pitch,srcp,src_pitch,row_size,height);
}