libbpg-0.9.6
This commit is contained in:
parent
3035b41edf
commit
35a8402710
248 changed files with 232891 additions and 100 deletions
33
x265/source/test/CMakeLists.txt
Normal file
33
x265/source/test/CMakeLists.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
# vim: syntax=cmake
|
||||
enable_language(ASM_YASM)
|
||||
|
||||
if(MSVC_IDE)
|
||||
set(YASM_SRC checkasm-a.obj)
|
||||
add_custom_command(
|
||||
OUTPUT checkasm-a.obj
|
||||
COMMAND ${YASM_EXECUTABLE}
|
||||
ARGS ${YASM_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/checkasm-a.asm -o checkasm-a.obj
|
||||
DEPENDS checkasm-a.asm)
|
||||
else()
|
||||
set(YASM_SRC checkasm-a.asm)
|
||||
endif()
|
||||
|
||||
check_symbol_exists(__rdtsc "intrin.h" HAVE_RDTSC)
|
||||
if(HAVE_RDTSC)
|
||||
add_definitions(-DHAVE_RDTSC=1)
|
||||
endif()
|
||||
|
||||
add_executable(TestBench ${YASM_SRC}
|
||||
testbench.cpp testharness.h
|
||||
pixelharness.cpp pixelharness.h
|
||||
mbdstharness.cpp mbdstharness.h
|
||||
ipfilterharness.cpp ipfilterharness.h
|
||||
intrapredharness.cpp intrapredharness.h)
|
||||
target_link_libraries(TestBench x265-static ${PLATFORM_LIBS})
|
||||
if(LINKER_OPTIONS)
|
||||
if(EXTRA_LIB)
|
||||
list(APPEND LINKER_OPTIONS "-L..")
|
||||
endif(EXTRA_LIB)
|
||||
string(REPLACE ";" " " LINKER_OPTION_STR "${LINKER_OPTIONS}")
|
||||
set_target_properties(TestBench PROPERTIES LINK_FLAGS "${LINKER_OPTION_STR}")
|
||||
endif()
|
225
x265/source/test/checkasm-a.asm
Normal file
225
x265/source/test/checkasm-a.asm
Normal file
|
@ -0,0 +1,225 @@
|
|||
;*****************************************************************************
|
||||
;* checkasm-a.asm: assembly check tool
|
||||
;*****************************************************************************
|
||||
;* Copyright (C) 2008-2014 x264 project
|
||||
;*
|
||||
;* Authors: Loren Merritt <lorenm@u.washington.edu>
|
||||
;* Henrik Gramner <henrik@gramner.com>
|
||||
;*
|
||||
;* This program is free software; you can redistribute it and/or modify
|
||||
;* it under the terms of the GNU General Public License as published by
|
||||
;* the Free Software Foundation; either version 2 of the License, or
|
||||
;* (at your option) any later version.
|
||||
;*
|
||||
;* This program is distributed in the hope that it will be useful,
|
||||
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;* GNU General Public License for more details.
|
||||
;*
|
||||
;* You should have received a copy of the GNU General Public License
|
||||
;* along with this program; if not, write to the Free Software
|
||||
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
;*
|
||||
;* This program is also available under a commercial proprietary license.
|
||||
;* For more information, contact us at license @ x265.com.
|
||||
;*****************************************************************************
|
||||
|
||||
%include "../common/x86/x86inc.asm"
|
||||
|
||||
SECTION_RODATA
|
||||
|
||||
error_message: db "failed to preserve register", 0
|
||||
|
||||
%if ARCH_X86_64
|
||||
; just random numbers to reduce the chance of incidental match
|
||||
ALIGN 16
|
||||
x6: ddq 0x79445c159ce790641a1b2550a612b48c
|
||||
x7: ddq 0x86b2536fcd8cf6362eed899d5a28ddcd
|
||||
x8: ddq 0x3f2bf84fc0fcca4eb0856806085e7943
|
||||
x9: ddq 0xd229e1f5b281303facbd382dcf5b8de2
|
||||
x10: ddq 0xab63e2e11fa38ed971aeaff20b095fd9
|
||||
x11: ddq 0x77d410d5c42c882d89b0c0765892729a
|
||||
x12: ddq 0x24b3c1d2a024048bc45ea11a955d8dd5
|
||||
x13: ddq 0xdd7b8919edd427862e8ec680de14b47c
|
||||
x14: ddq 0x11e53e2b2ac655ef135ce6888fa02cbf
|
||||
x15: ddq 0x6de8f4c914c334d5011ff554472a7a10
|
||||
n7: dq 0x21f86d66c8ca00ce
|
||||
n8: dq 0x75b6ba21077c48ad
|
||||
n9: dq 0xed56bb2dcb3c7736
|
||||
n10: dq 0x8bda43d3fd1a7e06
|
||||
n11: dq 0xb64a9c9e5d318408
|
||||
n12: dq 0xdf9a54b303f1d3a3
|
||||
n13: dq 0x4a75479abd64e097
|
||||
n14: dq 0x249214109d5d1c88
|
||||
%endif
|
||||
|
||||
SECTION .text
|
||||
|
||||
cextern_naked puts
|
||||
|
||||
; max number of args used by any x265 asm function.
|
||||
; (max_args % 4) must equal 3 for stack alignment
|
||||
%define max_args 15
|
||||
|
||||
%if ARCH_X86_64
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; void x265_checkasm_stack_clobber( uint64_t clobber, ... )
|
||||
;-----------------------------------------------------------------------------
|
||||
cglobal checkasm_stack_clobber, 1,2
|
||||
; Clobber the stack with junk below the stack pointer
|
||||
%define size (max_args+6)*8
|
||||
SUB rsp, size
|
||||
mov r1, size-8
|
||||
.loop:
|
||||
mov [rsp+r1], r0
|
||||
sub r1, 8
|
||||
jge .loop
|
||||
ADD rsp, size
|
||||
RET
|
||||
|
||||
%if WIN64
|
||||
%assign free_regs 7
|
||||
%else
|
||||
%assign free_regs 9
|
||||
%endif
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; intptr_t x265_checkasm_call( intptr_t (*func)(), int *ok, ... )
|
||||
;-----------------------------------------------------------------------------
|
||||
cglobal checkasm_call_float
|
||||
INIT_XMM
|
||||
cglobal checkasm_call, 2,15,16,max_args*8+8
|
||||
mov r6, r0
|
||||
mov [rsp+max_args*8], r1
|
||||
|
||||
; All arguments have been pushed on the stack instead of registers in order to
|
||||
; test for incorrect assumptions that 32-bit ints are zero-extended to 64-bit.
|
||||
mov r0, r6mp
|
||||
mov r1, r7mp
|
||||
mov r2, r8mp
|
||||
mov r3, r9mp
|
||||
%if UNIX64
|
||||
mov r4, r10mp
|
||||
mov r5, r11mp
|
||||
%assign i 6
|
||||
%rep max_args-6
|
||||
mov r9, [rsp+stack_offset+(i+1)*8]
|
||||
mov [rsp+(i-6)*8], r9
|
||||
%assign i i+1
|
||||
%endrep
|
||||
%else
|
||||
%assign i 4
|
||||
%rep max_args-4
|
||||
mov r9, [rsp+stack_offset+(i+7)*8]
|
||||
mov [rsp+i*8], r9
|
||||
%assign i i+1
|
||||
%endrep
|
||||
%endif
|
||||
|
||||
%if WIN64
|
||||
%assign i 6
|
||||
%rep 16-6
|
||||
mova m %+ i, [x %+ i]
|
||||
%assign i i+1
|
||||
%endrep
|
||||
%endif
|
||||
|
||||
%assign i 14
|
||||
%rep 15-free_regs
|
||||
mov r %+ i, [n %+ i]
|
||||
%assign i i-1
|
||||
%endrep
|
||||
call r6
|
||||
%assign i 14
|
||||
%rep 15-free_regs
|
||||
xor r %+ i, [n %+ i]
|
||||
or r14, r %+ i
|
||||
%assign i i-1
|
||||
%endrep
|
||||
|
||||
%if WIN64
|
||||
%assign i 6
|
||||
%rep 16-6
|
||||
pxor m %+ i, [x %+ i]
|
||||
por m6, m %+ i
|
||||
%assign i i+1
|
||||
%endrep
|
||||
packsswb m6, m6
|
||||
movq r5, m6
|
||||
or r14, r5
|
||||
%endif
|
||||
|
||||
jz .ok
|
||||
mov r9, rax
|
||||
mov r10, rdx
|
||||
lea r0, [error_message]
|
||||
call puts
|
||||
mov r1, [rsp+max_args*8]
|
||||
mov dword [r1], 0
|
||||
mov rdx, r10
|
||||
mov rax, r9
|
||||
.ok:
|
||||
RET
|
||||
|
||||
%else
|
||||
|
||||
; just random numbers to reduce the chance of incidental match
|
||||
%define n3 dword 0x6549315c
|
||||
%define n4 dword 0xe02f3e23
|
||||
%define n5 dword 0xb78d0d1d
|
||||
%define n6 dword 0x33627ba7
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; intptr_t x265_checkasm_call( intptr_t (*func)(), int *ok, ... )
|
||||
;-----------------------------------------------------------------------------
|
||||
cglobal checkasm_call_float
|
||||
cglobal checkasm_call, 1,7
|
||||
mov r3, n3
|
||||
mov r4, n4
|
||||
mov r5, n5
|
||||
mov r6, n6
|
||||
%rep max_args
|
||||
push dword [esp+24+max_args*4]
|
||||
%endrep
|
||||
call r0
|
||||
add esp, max_args*4
|
||||
xor r3, n3
|
||||
xor r4, n4
|
||||
xor r5, n5
|
||||
xor r6, n6
|
||||
or r3, r4
|
||||
or r5, r6
|
||||
or r3, r5
|
||||
jz .ok
|
||||
mov r3, eax
|
||||
mov r4, edx
|
||||
lea r1, [error_message]
|
||||
push r1
|
||||
call puts
|
||||
add esp, 4
|
||||
mov r1, r1m
|
||||
mov dword [r1], 0
|
||||
mov edx, r4
|
||||
mov eax, r3
|
||||
.ok:
|
||||
REP_RET
|
||||
|
||||
%endif ; ARCH_X86_64
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; int x265_stack_pagealign( int (*func)(), int align )
|
||||
;-----------------------------------------------------------------------------
|
||||
cglobal stack_pagealign, 2,2
|
||||
movsxdifnidn r1, r1d
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
%if WIN64
|
||||
sub rsp, 32 ; shadow space
|
||||
%endif
|
||||
and rsp, ~0xfff
|
||||
sub rsp, r1
|
||||
call r0
|
||||
leave
|
||||
RET
|
||||
|
318
x265/source/test/intrapredharness.cpp
Normal file
318
x265/source/test/intrapredharness.cpp
Normal file
|
@ -0,0 +1,318 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Min Chen <chenm003@163.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "predict.h"
|
||||
#include "intrapredharness.h"
|
||||
|
||||
using namespace X265_NS;
|
||||
|
||||
IntraPredHarness::IntraPredHarness()
|
||||
{
|
||||
for (int i = 0; i < INPUT_SIZE; i++)
|
||||
pixel_buff[i] = rand() % PIXEL_MAX;
|
||||
|
||||
/* [0] --- Random values
|
||||
* [1] --- Minimum
|
||||
* [2] --- Maximum */
|
||||
for (int i = 0; i < BUFFSIZE; i++)
|
||||
{
|
||||
pixel_test_buff[0][i] = rand() % PIXEL_MAX;
|
||||
pixel_test_buff[1][i] = PIXEL_MIN;
|
||||
pixel_test_buff[2][i] = PIXEL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
bool IntraPredHarness::check_dc_primitive(intra_pred_t ref, intra_pred_t opt, int width)
|
||||
{
|
||||
int j = Predict::ADI_BUF_STRIDE;
|
||||
intptr_t stride = FENC_STRIDE;
|
||||
|
||||
#if _DEBUG
|
||||
memset(pixel_out_vec, 0xCD, OUTPUT_SIZE);
|
||||
memset(pixel_out_c, 0xCD, OUTPUT_SIZE);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
int rand_filter = rand() & 1;
|
||||
if (width > 16)
|
||||
rand_filter = 0;
|
||||
|
||||
ref(pixel_out_c, stride, pixel_buff + j - Predict::ADI_BUF_STRIDE, 0, rand_filter);
|
||||
checked(opt, pixel_out_vec, stride, pixel_buff + j - Predict::ADI_BUF_STRIDE, 0, rand_filter);
|
||||
|
||||
for (int k = 0; k < width; k++)
|
||||
{
|
||||
if (memcmp(pixel_out_vec + k * FENC_STRIDE, pixel_out_c + k * FENC_STRIDE, width * sizeof(pixel)))
|
||||
return false;
|
||||
}
|
||||
|
||||
reportfail();
|
||||
j += FENC_STRIDE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntraPredHarness::check_planar_primitive(intra_pred_t ref, intra_pred_t opt, int width)
|
||||
{
|
||||
int j = Predict::ADI_BUF_STRIDE;
|
||||
intptr_t stride = FENC_STRIDE;
|
||||
|
||||
#if _DEBUG
|
||||
memset(pixel_out_vec, 0xCD, OUTPUT_SIZE);
|
||||
memset(pixel_out_c, 0xCD, OUTPUT_SIZE);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
ref(pixel_out_c, stride, pixel_buff + j - Predict::ADI_BUF_STRIDE, 0, 0);
|
||||
checked(opt, pixel_out_vec, stride, pixel_buff + j - Predict::ADI_BUF_STRIDE, 0, 0);
|
||||
|
||||
for (int k = 0; k < width; k++)
|
||||
{
|
||||
if (memcmp(pixel_out_vec + k * FENC_STRIDE, pixel_out_c + k * FENC_STRIDE, width * sizeof(pixel)))
|
||||
return false;
|
||||
}
|
||||
|
||||
reportfail();
|
||||
j += FENC_STRIDE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntraPredHarness::check_angular_primitive(const intra_pred_t ref[], const intra_pred_t opt[], int sizeIdx)
|
||||
{
|
||||
int j = Predict::ADI_BUF_STRIDE;
|
||||
intptr_t stride = FENC_STRIDE;
|
||||
|
||||
#if _DEBUG
|
||||
memset(pixel_out_vec, 0xCD, OUTPUT_SIZE);
|
||||
memset(pixel_out_c, 0xCD, OUTPUT_SIZE);
|
||||
#endif
|
||||
|
||||
int width = 1 << (sizeIdx + 2);
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
int bFilter = (width <= 16) && (rand() % 2);
|
||||
for (int pmode = 2; pmode <= 34; pmode++)
|
||||
{
|
||||
if (!opt[pmode])
|
||||
continue;
|
||||
|
||||
checked(opt[pmode], pixel_out_vec, stride, pixel_buff + j, pmode, bFilter);
|
||||
ref[pmode](pixel_out_c, stride, pixel_buff + j, pmode, bFilter);
|
||||
|
||||
for (int k = 0; k < width; k++)
|
||||
{
|
||||
if (memcmp(pixel_out_vec + k * FENC_STRIDE, pixel_out_c + k * FENC_STRIDE, width * sizeof(pixel)))
|
||||
{
|
||||
printf("ang_%dx%d, Mode = %d, Row = %d failed !!\n", width, width, pmode, k);
|
||||
ref[pmode](pixel_out_c, stride, pixel_buff + j, pmode, bFilter);
|
||||
opt[pmode](pixel_out_vec, stride, pixel_buff + j, pmode, bFilter);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
reportfail();
|
||||
}
|
||||
|
||||
j += FENC_STRIDE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntraPredHarness::check_allangs_primitive(const intra_allangs_t ref, const intra_allangs_t opt, int sizeIdx)
|
||||
{
|
||||
int j = Predict::ADI_BUF_STRIDE;
|
||||
int isLuma;
|
||||
|
||||
#if _DEBUG
|
||||
memset(pixel_out_33_vec, 0xCD, OUTPUT_SIZE_33);
|
||||
memset(pixel_out_33_c, 0xCD, OUTPUT_SIZE_33);
|
||||
#endif
|
||||
|
||||
const int width = 1 << (sizeIdx + 2);
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
isLuma = (width <= 16) ? true : false; // bFilter is true for 4x4, 8x8, 16x16 and false for 32x32
|
||||
|
||||
pixel * refAbove0 = pixel_buff + j + 3 * FENC_STRIDE; // keep this offset, since vector code may broken input buffer range [-(width-1), 0];
|
||||
pixel * refLeft0 = refAbove0 + 3 * width + FENC_STRIDE;
|
||||
|
||||
refLeft0[0] = refAbove0[0];
|
||||
|
||||
ref(pixel_out_33_c, refAbove0, refLeft0, isLuma);
|
||||
checked(opt, pixel_out_33_vec, refAbove0, refLeft0, isLuma);
|
||||
|
||||
for (int p = 2 - 2; p <= 34 - 2; p++)
|
||||
{
|
||||
for (int k = 0; k < width; k++)
|
||||
{
|
||||
if (memcmp(pixel_out_33_c + p * (width * width) + k * width, pixel_out_33_vec + p * (width * width) + k * width, width * sizeof(pixel)))
|
||||
{
|
||||
printf("\nFailed: (%dx%d) Mode(%2d), Line[%2d], bfilter=%d\n", width, width, p + 2, k, isLuma);
|
||||
opt(pixel_out_33_vec, refAbove0, refLeft0, isLuma);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reportfail();
|
||||
j += FENC_STRIDE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntraPredHarness::check_intra_filter_primitive(const intra_filter_t ref, const intra_filter_t opt)
|
||||
{
|
||||
memset(pixel_out_c, 0, 64 * 64 * sizeof(pixel));
|
||||
memset(pixel_out_vec, 0, 64 * 64 * sizeof(pixel));
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
int index = rand() % TEST_CASES;
|
||||
|
||||
ref(pixel_test_buff[index] + j, pixel_out_c);
|
||||
checked(opt, pixel_test_buff[index] + j, pixel_out_vec);
|
||||
|
||||
if (memcmp(pixel_out_c, pixel_out_vec, 64 * 64 * sizeof(pixel)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += FENC_STRIDE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool IntraPredHarness::testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt)
|
||||
{
|
||||
for (int i = BLOCK_4x4; i <= BLOCK_32x32; i++)
|
||||
{
|
||||
const int size = (1 << (i + 2));
|
||||
if (opt.cu[i].intra_pred[PLANAR_IDX])
|
||||
{
|
||||
if (!check_planar_primitive(ref.cu[i].intra_pred[PLANAR_IDX], opt.cu[i].intra_pred[PLANAR_IDX], size))
|
||||
{
|
||||
printf("intra_planar %dx%d failed\n", size, size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.cu[i].intra_pred[DC_IDX])
|
||||
{
|
||||
if (!check_dc_primitive(ref.cu[i].intra_pred[DC_IDX], opt.cu[i].intra_pred[DC_IDX], size))
|
||||
{
|
||||
printf("intra_dc %dx%d failed\n", size, size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_angular_primitive(ref.cu[i].intra_pred, opt.cu[i].intra_pred, i))
|
||||
{
|
||||
printf("intra_angular failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt.cu[i].intra_pred_allangs)
|
||||
{
|
||||
if (!check_allangs_primitive(ref.cu[i].intra_pred_allangs, opt.cu[i].intra_pred_allangs, i))
|
||||
{
|
||||
printf("intra_allangs failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.cu[i].intra_filter)
|
||||
{
|
||||
if (!check_intra_filter_primitive(ref.cu[i].intra_filter, opt.cu[i].intra_filter))
|
||||
{
|
||||
printf("intra_filter_%dx%d failed\n", size, size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IntraPredHarness::measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt)
|
||||
{
|
||||
int width = 64;
|
||||
uint16_t srcStride = 96;
|
||||
|
||||
for (int i = BLOCK_4x4; i <= BLOCK_32x32; i++)
|
||||
{
|
||||
const int size = (1 << (i + 2));
|
||||
if (opt.cu[i].intra_pred[PLANAR_IDX])
|
||||
{
|
||||
printf("intra_planar_%dx%d", size, size);
|
||||
REPORT_SPEEDUP(opt.cu[i].intra_pred[PLANAR_IDX], ref.cu[i].intra_pred[PLANAR_IDX],
|
||||
pixel_out_vec, FENC_STRIDE, pixel_buff + srcStride, 0, 0);
|
||||
}
|
||||
if (opt.cu[i].intra_pred[DC_IDX])
|
||||
{
|
||||
printf("intra_dc_%dx%d[f=0]", size, size);
|
||||
REPORT_SPEEDUP(opt.cu[i].intra_pred[DC_IDX], ref.cu[i].intra_pred[DC_IDX],
|
||||
pixel_out_vec, FENC_STRIDE, pixel_buff + srcStride, 0, 0);
|
||||
if (size <= 16)
|
||||
{
|
||||
printf("intra_dc_%dx%d[f=1]", size, size);
|
||||
REPORT_SPEEDUP(opt.cu[i].intra_pred[DC_IDX], ref.cu[i].intra_pred[DC_IDX],
|
||||
pixel_out_vec, FENC_STRIDE, pixel_buff + srcStride, 0, 1);
|
||||
}
|
||||
}
|
||||
if (opt.cu[i].intra_pred_allangs)
|
||||
{
|
||||
bool bFilter = (size <= 16);
|
||||
pixel * refAbove = pixel_buff + srcStride;
|
||||
pixel * refLeft = refAbove + 3 * size;
|
||||
refLeft[0] = refAbove[0];
|
||||
printf("intra_allangs%dx%d", size, size);
|
||||
REPORT_SPEEDUP(opt.cu[i].intra_pred_allangs, ref.cu[i].intra_pred_allangs,
|
||||
pixel_out_33_vec, refAbove, refLeft, bFilter);
|
||||
}
|
||||
for (int mode = 2; mode <= 34; mode += 1)
|
||||
{
|
||||
if (opt.cu[i].intra_pred[mode])
|
||||
{
|
||||
width = 1 << (i + 2);
|
||||
bool bFilter = (width <= 16);
|
||||
pixel * refAbove = pixel_buff + srcStride;
|
||||
pixel * refLeft = refAbove + 3 * width;
|
||||
refLeft[0] = refAbove[0];
|
||||
printf("intra_ang_%dx%d[%2d]", width, width, mode);
|
||||
REPORT_SPEEDUP(opt.cu[i].intra_pred[mode], ref.cu[i].intra_pred[mode],
|
||||
pixel_out_vec, FENC_STRIDE, pixel_buff + srcStride, mode, bFilter);
|
||||
}
|
||||
}
|
||||
if (opt.cu[i].intra_filter)
|
||||
{
|
||||
printf("intra_filter_%dx%d", size, size);
|
||||
REPORT_SPEEDUP(opt.cu[i].intra_filter, ref.cu[i].intra_filter, pixel_buff, pixel_out_c);
|
||||
}
|
||||
}
|
||||
}
|
69
x265/source/test/intrapredharness.h
Normal file
69
x265/source/test/intrapredharness.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Min Chen <chenm003@163.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _INTRAPREDHARNESS_H_1
|
||||
#define _INTRAPREDHARNESS_H_1 1
|
||||
|
||||
#include "testharness.h"
|
||||
#include "primitives.h"
|
||||
|
||||
class IntraPredHarness : public TestHarness
|
||||
{
|
||||
protected:
|
||||
|
||||
enum { INPUT_SIZE = 4 * 65 * 65 * 100 };
|
||||
enum { OUTPUT_SIZE = 64 * FENC_STRIDE };
|
||||
enum { OUTPUT_SIZE_33 = 33 * OUTPUT_SIZE };
|
||||
enum { TEST_CASES = 3 };
|
||||
enum { INCR = 32 };
|
||||
enum { STRIDE = 64 };
|
||||
enum { ITERS = 100 };
|
||||
enum { MAX_HEIGHT = 64 };
|
||||
enum { PAD_ROWS = 64 };
|
||||
enum { BUFFSIZE = STRIDE * (MAX_HEIGHT + PAD_ROWS) + INCR * ITERS };
|
||||
|
||||
pixel pixel_test_buff[TEST_CASES][BUFFSIZE];
|
||||
ALIGN_VAR_16(pixel, pixel_buff[INPUT_SIZE]);
|
||||
pixel pixel_out_c[OUTPUT_SIZE];
|
||||
pixel pixel_out_vec[OUTPUT_SIZE];
|
||||
pixel pixel_out_33_c[OUTPUT_SIZE_33];
|
||||
pixel pixel_out_33_vec[OUTPUT_SIZE_33];
|
||||
|
||||
bool check_dc_primitive(intra_pred_t ref, intra_pred_t opt, int width);
|
||||
bool check_planar_primitive(intra_pred_t ref, intra_pred_t opt, int width);
|
||||
bool check_angular_primitive(const intra_pred_t ref[], const intra_pred_t opt[], int size);
|
||||
bool check_allangs_primitive(const intra_allangs_t ref, const intra_allangs_t opt, int size);
|
||||
bool check_intra_filter_primitive(const intra_filter_t ref, const intra_filter_t opt);
|
||||
|
||||
public:
|
||||
|
||||
IntraPredHarness();
|
||||
|
||||
const char *getName() const { return "intrapred"; }
|
||||
|
||||
bool testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
|
||||
void measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
};
|
||||
|
||||
#endif // ifndef _INTRAPREDHARNESS_H_1
|
776
x265/source/test/ipfilterharness.cpp
Normal file
776
x265/source/test/ipfilterharness.cpp
Normal file
|
@ -0,0 +1,776 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Deepthi Devaki <deepthidevaki@multicorewareinc.com>,
|
||||
* Rajesh Paulraj <rajesh@multicorewareinc.com>
|
||||
* Praveen Kumar Tiwari <praveen@multicorewareinc.com>
|
||||
* Min Chen <chenm003@163.com> <min.chen@multicorewareinc.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "ipfilterharness.h"
|
||||
|
||||
using namespace X265_NS;
|
||||
|
||||
IPFilterHarness::IPFilterHarness()
|
||||
{
|
||||
/* [0] --- Random values
|
||||
* [1] --- Minimum
|
||||
* [2] --- Maximum */
|
||||
for (int i = 0; i < TEST_BUF_SIZE; i++)
|
||||
{
|
||||
pixel_test_buff[0][i] = rand() & PIXEL_MAX;
|
||||
short_test_buff[0][i] = (rand() % (2 * SMAX)) - SMAX;
|
||||
|
||||
pixel_test_buff[1][i] = PIXEL_MIN;
|
||||
short_test_buff[1][i] = SMIN;
|
||||
|
||||
pixel_test_buff[2][i] = PIXEL_MAX;
|
||||
short_test_buff[2][i] = SMAX;
|
||||
}
|
||||
|
||||
memset(IPF_C_output_p, 0xCD, TEST_BUF_SIZE * sizeof(pixel));
|
||||
memset(IPF_vec_output_p, 0xCD, TEST_BUF_SIZE * sizeof(pixel));
|
||||
memset(IPF_C_output_s, 0xCD, TEST_BUF_SIZE * sizeof(int16_t));
|
||||
memset(IPF_vec_output_s, 0xCD, TEST_BUF_SIZE * sizeof(int16_t));
|
||||
|
||||
int pixelMax = (1 << X265_DEPTH) - 1;
|
||||
int shortMax = (1 << 15) - 1;
|
||||
for (int i = 0; i < TEST_BUF_SIZE; i++)
|
||||
{
|
||||
pixel_buff[i] = (pixel)(rand() & pixelMax);
|
||||
int isPositive = (rand() & 1) ? 1 : -1;
|
||||
short_buff[i] = (int16_t)(isPositive * (rand() & shortMax));
|
||||
}
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterChroma_primitive(filter_pp_t ref, filter_pp_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 8; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100 + 2;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
checked(opt, pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_vec_output_p, IPF_C_output_p, TEST_BUF_SIZE * sizeof(pixel)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterChroma_ps_primitive(filter_ps_t ref, filter_ps_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 8; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
checked(opt, pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_vec_output_s, IPF_C_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
{
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
return false;
|
||||
}
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterChroma_hps_primitive(filter_hps_t ref, filter_hps_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 8; coeffIdx++)
|
||||
{
|
||||
// 0 : Interpolate W x H, 1 : Interpolate W x (H + 7)
|
||||
for (int isRowExt = 0; isRowExt < 2; isRowExt++)
|
||||
{
|
||||
rand_srcStride = rand() % 100 + 2;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx,
|
||||
isRowExt);
|
||||
|
||||
checked(opt, pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx,
|
||||
isRowExt);
|
||||
|
||||
if (memcmp(IPF_vec_output_s, IPF_C_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterChroma_sp_primitive(filter_sp_t ref, filter_sp_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 8; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
checked(opt, short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_vec_output_p, IPF_C_output_p, TEST_BUF_SIZE * sizeof(pixel)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterChroma_ss_primitive(filter_ss_t ref, filter_ss_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 8; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
checked(opt, short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_C_output_s, IPF_vec_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterLuma_primitive(filter_pp_t ref, filter_pp_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 4; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
checked(opt, pixel_test_buff[index] + 3 * rand_srcStride + 6,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride + 6,
|
||||
rand_srcStride,
|
||||
IPF_C_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_vec_output_p, IPF_C_output_p, TEST_BUF_SIZE))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterLuma_ps_primitive(filter_ps_t ref, filter_ps_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 4; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
checked(opt, pixel_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_vec_output_s, IPF_C_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterLuma_hps_primitive(filter_hps_t ref, filter_hps_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 4; coeffIdx++)
|
||||
{
|
||||
// 0 : Interpolate W x H, 1 : Interpolate W x (H + 7)
|
||||
for (int isRowExt = 0; isRowExt < 2; isRowExt++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride + 6,
|
||||
rand_srcStride,
|
||||
IPF_C_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx,
|
||||
isRowExt);
|
||||
|
||||
checked(opt, pixel_test_buff[index] + 3 * rand_srcStride + 6,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx,
|
||||
isRowExt);
|
||||
|
||||
if (memcmp(IPF_vec_output_s, IPF_C_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterLuma_sp_primitive(filter_sp_t ref, filter_sp_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 4; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
checked(opt, short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_vec_output_p, IPF_C_output_p, TEST_BUF_SIZE * sizeof(pixel)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterLuma_ss_primitive(filter_ss_t ref, filter_ss_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdx = 0; coeffIdx < 4; coeffIdx++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_C_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
checked(opt, short_test_buff[index] + 3 * rand_srcStride,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_s,
|
||||
rand_dstStride,
|
||||
coeffIdx);
|
||||
|
||||
if (memcmp(IPF_C_output_s, IPF_vec_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterLumaHV_primitive(filter_hv_pp_t ref, filter_hv_pp_t opt)
|
||||
{
|
||||
intptr_t rand_srcStride, rand_dstStride;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
|
||||
for (int coeffIdxX = 0; coeffIdxX < 4; coeffIdxX++)
|
||||
{
|
||||
for (int coeffIdxY = 0; coeffIdxY < 4; coeffIdxY++)
|
||||
{
|
||||
rand_srcStride = rand() % 100;
|
||||
rand_dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(pixel_test_buff[index] + 3 * rand_srcStride + 3,
|
||||
rand_srcStride,
|
||||
IPF_C_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdxX,
|
||||
coeffIdxY);
|
||||
|
||||
checked(opt, pixel_test_buff[index] + 3 * rand_srcStride + 3,
|
||||
rand_srcStride,
|
||||
IPF_vec_output_p,
|
||||
rand_dstStride,
|
||||
coeffIdxX,
|
||||
coeffIdxY);
|
||||
|
||||
if (memcmp(IPF_vec_output_p, IPF_C_output_p, TEST_BUF_SIZE * sizeof(pixel)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterLumaP2S_primitive(filter_p2s_t ref, filter_p2s_t opt)
|
||||
{
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
intptr_t rand_srcStride = rand() % 100;
|
||||
int index = i % TEST_CASES;
|
||||
intptr_t dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(pixel_test_buff[index] + i, rand_srcStride, IPF_C_output_s, dstStride);
|
||||
|
||||
checked(opt, pixel_test_buff[index] + i, rand_srcStride, IPF_vec_output_s, dstStride);
|
||||
|
||||
if (memcmp(IPF_vec_output_s, IPF_C_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::check_IPFilterChromaP2S_primitive(filter_p2s_t ref, filter_p2s_t opt)
|
||||
{
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
intptr_t rand_srcStride = rand() % 100;
|
||||
int index = i % TEST_CASES;
|
||||
intptr_t dstStride = rand() % 100 + 64;
|
||||
|
||||
ref(pixel_test_buff[index] + i, rand_srcStride, IPF_C_output_s, dstStride);
|
||||
|
||||
checked(opt, pixel_test_buff[index] + i, rand_srcStride, IPF_vec_output_s, dstStride);
|
||||
|
||||
if (memcmp(IPF_vec_output_s, IPF_C_output_s, TEST_BUF_SIZE * sizeof(int16_t)))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPFilterHarness::testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt)
|
||||
{
|
||||
|
||||
for (int value = 0; value < NUM_PU_SIZES; value++)
|
||||
{
|
||||
if (opt.pu[value].luma_hpp)
|
||||
{
|
||||
if (!check_IPFilterLuma_primitive(ref.pu[value].luma_hpp, opt.pu[value].luma_hpp))
|
||||
{
|
||||
printf("luma_hpp[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.pu[value].luma_hps)
|
||||
{
|
||||
if (!check_IPFilterLuma_hps_primitive(ref.pu[value].luma_hps, opt.pu[value].luma_hps))
|
||||
{
|
||||
printf("luma_hps[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.pu[value].luma_vpp)
|
||||
{
|
||||
if (!check_IPFilterLuma_primitive(ref.pu[value].luma_vpp, opt.pu[value].luma_vpp))
|
||||
{
|
||||
printf("luma_vpp[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.pu[value].luma_vps)
|
||||
{
|
||||
if (!check_IPFilterLuma_ps_primitive(ref.pu[value].luma_vps, opt.pu[value].luma_vps))
|
||||
{
|
||||
printf("luma_vps[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.pu[value].luma_vsp)
|
||||
{
|
||||
if (!check_IPFilterLuma_sp_primitive(ref.pu[value].luma_vsp, opt.pu[value].luma_vsp))
|
||||
{
|
||||
printf("luma_vsp[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.pu[value].luma_vss)
|
||||
{
|
||||
if (!check_IPFilterLuma_ss_primitive(ref.pu[value].luma_vss, opt.pu[value].luma_vss))
|
||||
{
|
||||
printf("luma_vss[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.pu[value].luma_hvpp)
|
||||
{
|
||||
if (!check_IPFilterLumaHV_primitive(ref.pu[value].luma_hvpp, opt.pu[value].luma_hvpp))
|
||||
{
|
||||
printf("luma_hvpp[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.pu[value].convert_p2s)
|
||||
{
|
||||
if (!check_IPFilterLumaP2S_primitive(ref.pu[value].convert_p2s, opt.pu[value].convert_p2s))
|
||||
{
|
||||
printf("convert_p2s[%s]", lumaPartStr[value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int csp = X265_CSP_I420; csp < X265_CSP_COUNT; csp++)
|
||||
{
|
||||
for (int value = 0; value < NUM_PU_SIZES; value++)
|
||||
{
|
||||
if (opt.chroma[csp].pu[value].filter_hpp)
|
||||
{
|
||||
if (!check_IPFilterChroma_primitive(ref.chroma[csp].pu[value].filter_hpp, opt.chroma[csp].pu[value].filter_hpp))
|
||||
{
|
||||
printf("chroma_hpp[%s]", chromaPartStr[csp][value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_hps)
|
||||
{
|
||||
if (!check_IPFilterChroma_hps_primitive(ref.chroma[csp].pu[value].filter_hps, opt.chroma[csp].pu[value].filter_hps))
|
||||
{
|
||||
printf("chroma_hps[%s]", chromaPartStr[csp][value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vpp)
|
||||
{
|
||||
if (!check_IPFilterChroma_primitive(ref.chroma[csp].pu[value].filter_vpp, opt.chroma[csp].pu[value].filter_vpp))
|
||||
{
|
||||
printf("chroma_vpp[%s]", chromaPartStr[csp][value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vps)
|
||||
{
|
||||
if (!check_IPFilterChroma_ps_primitive(ref.chroma[csp].pu[value].filter_vps, opt.chroma[csp].pu[value].filter_vps))
|
||||
{
|
||||
printf("chroma_vps[%s]", chromaPartStr[csp][value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vsp)
|
||||
{
|
||||
if (!check_IPFilterChroma_sp_primitive(ref.chroma[csp].pu[value].filter_vsp, opt.chroma[csp].pu[value].filter_vsp))
|
||||
{
|
||||
printf("chroma_vsp[%s]", chromaPartStr[csp][value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vss)
|
||||
{
|
||||
if (!check_IPFilterChroma_ss_primitive(ref.chroma[csp].pu[value].filter_vss, opt.chroma[csp].pu[value].filter_vss))
|
||||
{
|
||||
printf("chroma_vss[%s]", chromaPartStr[csp][value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].p2s)
|
||||
{
|
||||
if (!check_IPFilterChromaP2S_primitive(ref.chroma[csp].pu[value].p2s, opt.chroma[csp].pu[value].p2s))
|
||||
{
|
||||
printf("chroma_p2s[%s]", chromaPartStr[csp][value]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IPFilterHarness::measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt)
|
||||
{
|
||||
int16_t srcStride = 96;
|
||||
int16_t dstStride = 96;
|
||||
int maxVerticalfilterHalfDistance = 3;
|
||||
|
||||
for (int value = 0; value < NUM_PU_SIZES; value++)
|
||||
{
|
||||
if (opt.pu[value].luma_hpp)
|
||||
{
|
||||
printf("luma_hpp[%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].luma_hpp, ref.pu[value].luma_hpp,
|
||||
pixel_buff + srcStride, srcStride, IPF_vec_output_p, dstStride, 1);
|
||||
}
|
||||
|
||||
if (opt.pu[value].luma_hps)
|
||||
{
|
||||
printf("luma_hps[%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].luma_hps, ref.pu[value].luma_hps,
|
||||
pixel_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_s, dstStride, 1, 1);
|
||||
}
|
||||
|
||||
if (opt.pu[value].luma_vpp)
|
||||
{
|
||||
printf("luma_vpp[%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].luma_vpp, ref.pu[value].luma_vpp,
|
||||
pixel_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_p, dstStride, 1);
|
||||
}
|
||||
|
||||
if (opt.pu[value].luma_vps)
|
||||
{
|
||||
printf("luma_vps[%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].luma_vps, ref.pu[value].luma_vps,
|
||||
pixel_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_s, dstStride, 1);
|
||||
}
|
||||
|
||||
if (opt.pu[value].luma_vsp)
|
||||
{
|
||||
printf("luma_vsp[%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].luma_vsp, ref.pu[value].luma_vsp,
|
||||
short_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_p, dstStride, 1);
|
||||
}
|
||||
|
||||
if (opt.pu[value].luma_vss)
|
||||
{
|
||||
printf("luma_vss[%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].luma_vss, ref.pu[value].luma_vss,
|
||||
short_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_s, dstStride, 1);
|
||||
}
|
||||
|
||||
if (opt.pu[value].luma_hvpp)
|
||||
{
|
||||
printf("luma_hv [%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].luma_hvpp, ref.pu[value].luma_hvpp,
|
||||
pixel_buff + 3 * srcStride, srcStride, IPF_vec_output_p, srcStride, 1, 3);
|
||||
}
|
||||
|
||||
if (opt.pu[value].convert_p2s)
|
||||
{
|
||||
printf("convert_p2s[%s]\t", lumaPartStr[value]);
|
||||
REPORT_SPEEDUP(opt.pu[value].convert_p2s, ref.pu[value].convert_p2s,
|
||||
pixel_buff, srcStride,
|
||||
IPF_vec_output_s, dstStride);
|
||||
}
|
||||
}
|
||||
|
||||
for (int csp = X265_CSP_I420; csp < X265_CSP_COUNT; csp++)
|
||||
{
|
||||
printf("= Color Space %s =\n", x265_source_csp_names[csp]);
|
||||
for (int value = 0; value < NUM_PU_SIZES; value++)
|
||||
{
|
||||
if (opt.chroma[csp].pu[value].filter_hpp)
|
||||
{
|
||||
printf("chroma_hpp[%s]", chromaPartStr[csp][value]);
|
||||
REPORT_SPEEDUP(opt.chroma[csp].pu[value].filter_hpp, ref.chroma[csp].pu[value].filter_hpp,
|
||||
pixel_buff + srcStride, srcStride, IPF_vec_output_p, dstStride, 1);
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_hps)
|
||||
{
|
||||
printf("chroma_hps[%s]", chromaPartStr[csp][value]);
|
||||
REPORT_SPEEDUP(opt.chroma[csp].pu[value].filter_hps, ref.chroma[csp].pu[value].filter_hps,
|
||||
pixel_buff + srcStride, srcStride, IPF_vec_output_s, dstStride, 1, 1);
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vpp)
|
||||
{
|
||||
printf("chroma_vpp[%s]", chromaPartStr[csp][value]);
|
||||
REPORT_SPEEDUP(opt.chroma[csp].pu[value].filter_vpp, ref.chroma[csp].pu[value].filter_vpp,
|
||||
pixel_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_p, dstStride, 1);
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vps)
|
||||
{
|
||||
printf("chroma_vps[%s]", chromaPartStr[csp][value]);
|
||||
REPORT_SPEEDUP(opt.chroma[csp].pu[value].filter_vps, ref.chroma[csp].pu[value].filter_vps,
|
||||
pixel_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_s, dstStride, 1);
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vsp)
|
||||
{
|
||||
printf("chroma_vsp[%s]", chromaPartStr[csp][value]);
|
||||
REPORT_SPEEDUP(opt.chroma[csp].pu[value].filter_vsp, ref.chroma[csp].pu[value].filter_vsp,
|
||||
short_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_p, dstStride, 1);
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].filter_vss)
|
||||
{
|
||||
printf("chroma_vss[%s]", chromaPartStr[csp][value]);
|
||||
REPORT_SPEEDUP(opt.chroma[csp].pu[value].filter_vss, ref.chroma[csp].pu[value].filter_vss,
|
||||
short_buff + maxVerticalfilterHalfDistance * srcStride, srcStride,
|
||||
IPF_vec_output_s, dstStride, 1);
|
||||
}
|
||||
if (opt.chroma[csp].pu[value].p2s)
|
||||
{
|
||||
printf("chroma_p2s[%s]\t", chromaPartStr[csp][value]);
|
||||
REPORT_SPEEDUP(opt.chroma[csp].pu[value].p2s, ref.chroma[csp].pu[value].p2s,
|
||||
pixel_buff, srcStride, IPF_vec_output_s, dstStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
78
x265/source/test/ipfilterharness.h
Normal file
78
x265/source/test/ipfilterharness.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Deepthi Devaki <deepthidevaki@multicorewareinc.com>,
|
||||
* Rajesh Paulraj <rajesh@multicorewareinc.com>
|
||||
* Praveen Kumar Tiwari <praveen@multicorewareinc.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _IPFILTERHARNESS_H_1
|
||||
#define _IPFILTERHARNESS_H_1 1
|
||||
|
||||
#include "testharness.h"
|
||||
#include "primitives.h"
|
||||
|
||||
class IPFilterHarness : public TestHarness
|
||||
{
|
||||
protected:
|
||||
|
||||
// Assuming max_height = max_width = max_srcStride = max_dstStride = 100
|
||||
enum { TEST_BUF_SIZE = 200 * 200 };
|
||||
enum { ITERS = 100 };
|
||||
enum { TEST_CASES = 3 };
|
||||
enum { SMAX = 1 << 12 };
|
||||
enum { SMIN = -1 << 12 };
|
||||
|
||||
ALIGN_VAR_32(pixel, pixel_buff[TEST_BUF_SIZE]);
|
||||
int16_t short_buff[TEST_BUF_SIZE];
|
||||
int16_t IPF_vec_output_s[TEST_BUF_SIZE];
|
||||
int16_t IPF_C_output_s[TEST_BUF_SIZE];
|
||||
pixel IPF_vec_output_p[TEST_BUF_SIZE];
|
||||
pixel IPF_C_output_p[TEST_BUF_SIZE];
|
||||
|
||||
pixel pixel_test_buff[TEST_CASES][TEST_BUF_SIZE];
|
||||
int16_t short_test_buff[TEST_CASES][TEST_BUF_SIZE];
|
||||
|
||||
bool check_IPFilterChroma_primitive(filter_pp_t ref, filter_pp_t opt);
|
||||
bool check_IPFilterChroma_ps_primitive(filter_ps_t ref, filter_ps_t opt);
|
||||
bool check_IPFilterChroma_hps_primitive(filter_hps_t ref, filter_hps_t opt);
|
||||
bool check_IPFilterChroma_sp_primitive(filter_sp_t ref, filter_sp_t opt);
|
||||
bool check_IPFilterChroma_ss_primitive(filter_ss_t ref, filter_ss_t opt);
|
||||
bool check_IPFilterLuma_primitive(filter_pp_t ref, filter_pp_t opt);
|
||||
bool check_IPFilterLuma_ps_primitive(filter_ps_t ref, filter_ps_t opt);
|
||||
bool check_IPFilterLuma_hps_primitive(filter_hps_t ref, filter_hps_t opt);
|
||||
bool check_IPFilterLuma_sp_primitive(filter_sp_t ref, filter_sp_t opt);
|
||||
bool check_IPFilterLuma_ss_primitive(filter_ss_t ref, filter_ss_t opt);
|
||||
bool check_IPFilterLumaHV_primitive(filter_hv_pp_t ref, filter_hv_pp_t opt);
|
||||
bool check_IPFilterLumaP2S_primitive(filter_p2s_t ref, filter_p2s_t opt);
|
||||
bool check_IPFilterChromaP2S_primitive(filter_p2s_t ref, filter_p2s_t opt);
|
||||
|
||||
public:
|
||||
|
||||
IPFilterHarness();
|
||||
|
||||
const char *getName() const { return "interp"; }
|
||||
|
||||
bool testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
|
||||
void measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
};
|
||||
|
||||
#endif // ifndef _FILTERHARNESS_H_1
|
523
x265/source/test/mbdstharness.cpp
Normal file
523
x265/source/test/mbdstharness.cpp
Normal file
|
@ -0,0 +1,523 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Steve Borho <steve@borho.org>
|
||||
* Min Chen <min.chen@multicorewareinc.com>
|
||||
* Praveen Kumar Tiwari <praveen@multicorewareinc.com>
|
||||
* Nabajit Deka <nabajit@multicorewareinc.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "mbdstharness.h"
|
||||
|
||||
using namespace X265_NS;
|
||||
|
||||
struct DctConf
|
||||
{
|
||||
const char *name;
|
||||
int width;
|
||||
};
|
||||
|
||||
const DctConf dctInfo[] =
|
||||
{
|
||||
{ "dct4x4\t", 4 },
|
||||
{ "dct8x8\t", 8 },
|
||||
{ "dct16x16", 16 },
|
||||
{ "dct32x32", 32 },
|
||||
};
|
||||
|
||||
const DctConf idctInfo[] =
|
||||
{
|
||||
{ "idct4x4\t", 4 },
|
||||
{ "idct8x8\t", 8 },
|
||||
{ "idct16x16", 16 },
|
||||
{ "idct32x32", 32 },
|
||||
};
|
||||
|
||||
MBDstHarness::MBDstHarness()
|
||||
{
|
||||
const int idct_max = (1 << (X265_DEPTH + 4)) - 1;
|
||||
|
||||
/* [0] --- Random values
|
||||
* [1] --- Minimum
|
||||
* [2] --- Maximum */
|
||||
for (int i = 0; i < TEST_BUF_SIZE; i++)
|
||||
{
|
||||
short_test_buff[0][i] = (rand() & PIXEL_MAX) - (rand() & PIXEL_MAX);
|
||||
int_test_buff[0][i] = rand() % PIXEL_MAX;
|
||||
int_idct_test_buff[0][i] = (rand() % (SHORT_MAX - SHORT_MIN)) - SHORT_MAX;
|
||||
short_denoise_test_buff1[0][i] = short_denoise_test_buff2[0][i] = (rand() & SHORT_MAX) - (rand() & SHORT_MAX);
|
||||
|
||||
short_test_buff[1][i] = -PIXEL_MAX;
|
||||
int_test_buff[1][i] = -PIXEL_MAX;
|
||||
int_idct_test_buff[1][i] = SHORT_MIN;
|
||||
short_denoise_test_buff1[1][i] = short_denoise_test_buff2[1][i] = -SHORT_MAX;
|
||||
|
||||
short_test_buff[2][i] = PIXEL_MAX;
|
||||
int_test_buff[2][i] = PIXEL_MAX;
|
||||
int_idct_test_buff[2][i] = SHORT_MAX;
|
||||
short_denoise_test_buff1[2][i] = short_denoise_test_buff2[2][i] = SHORT_MAX;
|
||||
|
||||
mbuf1[i] = rand() & PIXEL_MAX;
|
||||
mbufdct[i] = (rand() & PIXEL_MAX) - (rand() & PIXEL_MAX);
|
||||
mbufidct[i] = (rand() & idct_max);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
memset(mshortbuf2, 0, MAX_TU_SIZE * sizeof(int16_t));
|
||||
memset(mshortbuf3, 0, MAX_TU_SIZE * sizeof(int16_t));
|
||||
|
||||
memset(mintbuf1, 0, MAX_TU_SIZE * sizeof(int));
|
||||
memset(mintbuf2, 0, MAX_TU_SIZE * sizeof(int));
|
||||
memset(mintbuf3, 0, MAX_TU_SIZE * sizeof(int));
|
||||
memset(mintbuf4, 0, MAX_TU_SIZE * sizeof(int));
|
||||
#endif // if _DEBUG
|
||||
}
|
||||
|
||||
bool MBDstHarness::check_dct_primitive(dct_t ref, dct_t opt, intptr_t width)
|
||||
{
|
||||
int j = 0;
|
||||
intptr_t cmp_size = sizeof(short) * width * width;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = rand() % TEST_CASES;
|
||||
|
||||
ref(short_test_buff[index] + j, mshortbuf2, width);
|
||||
checked(opt, short_test_buff[index] + j, mshortbuf3, width);
|
||||
|
||||
if (memcmp(mshortbuf2, mshortbuf3, cmp_size))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MBDstHarness::check_idct_primitive(idct_t ref, idct_t opt, intptr_t width)
|
||||
{
|
||||
int j = 0;
|
||||
intptr_t cmp_size = sizeof(int16_t) * width * width;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = rand() % TEST_CASES;
|
||||
|
||||
ref(short_test_buff[index] + j, mshortbuf2, width);
|
||||
checked(opt, short_test_buff[index] + j, mshortbuf3, width);
|
||||
|
||||
if (memcmp(mshortbuf2, mshortbuf3, cmp_size))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MBDstHarness::check_dequant_primitive(dequant_normal_t ref, dequant_normal_t opt)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = rand() % TEST_CASES;
|
||||
int log2TrSize = (rand() % 4) + 2;
|
||||
|
||||
int width = (1 << log2TrSize);
|
||||
int height = width;
|
||||
int qp = rand() % (QP_MAX_SPEC + QP_BD_OFFSET + 1);
|
||||
int per = qp / 6;
|
||||
int rem = qp % 6;
|
||||
static const int invQuantScales[6] = { 40, 45, 51, 57, 64, 72 };
|
||||
int scale = invQuantScales[rem] << per;
|
||||
int transformShift = MAX_TR_DYNAMIC_RANGE - X265_DEPTH - log2TrSize;
|
||||
int shift = QUANT_IQUANT_SHIFT - QUANT_SHIFT - transformShift;
|
||||
|
||||
ref(short_test_buff[index] + j, mshortbuf2, width * height, scale, shift);
|
||||
checked(opt, short_test_buff[index] + j, mshortbuf3, width * height, scale, shift);
|
||||
|
||||
if (memcmp(mshortbuf2, mshortbuf3, sizeof(int16_t) * height * width))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MBDstHarness::check_dequant_primitive(dequant_scaling_t ref, dequant_scaling_t opt)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
|
||||
memset(mshortbuf2, 0, MAX_TU_SIZE * sizeof(int16_t));
|
||||
memset(mshortbuf3, 0, MAX_TU_SIZE * sizeof(int16_t));
|
||||
|
||||
int log2TrSize = (rand() % 4) + 2;
|
||||
|
||||
int width = (1 << log2TrSize);
|
||||
int height = width;
|
||||
|
||||
int qp = rand() % (QP_MAX_SPEC + QP_BD_OFFSET + 1);
|
||||
int per = qp / 6;
|
||||
int transformShift = MAX_TR_DYNAMIC_RANGE - X265_DEPTH - log2TrSize;
|
||||
int shift = QUANT_IQUANT_SHIFT - QUANT_SHIFT - transformShift;
|
||||
|
||||
int cmp_size = sizeof(int16_t) * height * width;
|
||||
int index1 = rand() % TEST_CASES;
|
||||
|
||||
ref(short_test_buff[index1] + j, int_test_buff[index1] + j, mshortbuf2, width * height, per, shift);
|
||||
checked(opt, short_test_buff[index1] + j, int_test_buff[index1] + j, mshortbuf3, width * height, per, shift);
|
||||
|
||||
if (memcmp(mshortbuf2, mshortbuf3, cmp_size))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MBDstHarness::check_quant_primitive(quant_t ref, quant_t opt)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int width = 1 << (rand() % 4 + 2);
|
||||
int height = width;
|
||||
|
||||
uint32_t optReturnValue = 0;
|
||||
uint32_t refReturnValue = 0;
|
||||
|
||||
int sliceType = rand() % 2;
|
||||
int log2TrSize = rand() % 4 + 2;
|
||||
int qp = rand() % (QP_MAX_SPEC + QP_BD_OFFSET + 1);
|
||||
int per = qp / 6;
|
||||
int transformShift = MAX_TR_DYNAMIC_RANGE - X265_DEPTH - log2TrSize;
|
||||
|
||||
int bits = QUANT_SHIFT + per + transformShift;
|
||||
int valueToAdd = (sliceType == 1 ? 171 : 85) << (bits - 9);
|
||||
int cmp_size = sizeof(int) * height * width;
|
||||
int cmp_size1 = sizeof(short) * height * width;
|
||||
int numCoeff = height * width;
|
||||
|
||||
int index1 = rand() % TEST_CASES;
|
||||
int index2 = rand() % TEST_CASES;
|
||||
|
||||
refReturnValue = ref(short_test_buff[index1] + j, int_test_buff[index2] + j, mintbuf1, mshortbuf2, bits, valueToAdd, numCoeff);
|
||||
optReturnValue = (uint32_t)checked(opt, short_test_buff[index1] + j, int_test_buff[index2] + j, mintbuf3, mshortbuf3, bits, valueToAdd, numCoeff);
|
||||
|
||||
if (memcmp(mintbuf1, mintbuf3, cmp_size))
|
||||
return false;
|
||||
|
||||
if (memcmp(mshortbuf2, mshortbuf3, cmp_size1))
|
||||
return false;
|
||||
|
||||
if (optReturnValue != refReturnValue)
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MBDstHarness::check_nquant_primitive(nquant_t ref, nquant_t opt)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int width = (rand() % 4 + 1) * 4;
|
||||
int height = width;
|
||||
|
||||
uint32_t optReturnValue = 0;
|
||||
uint32_t refReturnValue = 0;
|
||||
|
||||
int bits = rand() % 32;
|
||||
int valueToAdd = rand() % (1 << bits);
|
||||
int cmp_size = sizeof(short) * height * width;
|
||||
int numCoeff = height * width;
|
||||
|
||||
int index1 = rand() % TEST_CASES;
|
||||
int index2 = rand() % TEST_CASES;
|
||||
|
||||
refReturnValue = ref(short_test_buff[index1] + j, int_test_buff[index2] + j, mshortbuf2, bits, valueToAdd, numCoeff);
|
||||
optReturnValue = (uint32_t)checked(opt, short_test_buff[index1] + j, int_test_buff[index2] + j, mshortbuf3, bits, valueToAdd, numCoeff);
|
||||
|
||||
if (memcmp(mshortbuf2, mshortbuf3, cmp_size))
|
||||
return false;
|
||||
|
||||
if (optReturnValue != refReturnValue)
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool MBDstHarness::check_count_nonzero_primitive(count_nonzero_t ref, count_nonzero_t opt)
|
||||
{
|
||||
int j = 0;
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
int index = i % TEST_CASES;
|
||||
int opt_cnt = (int)checked(opt, short_test_buff[index] + j);
|
||||
int ref_cnt = ref(short_test_buff[index] + j);
|
||||
if (ref_cnt != opt_cnt)
|
||||
return false;
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MBDstHarness::check_denoise_dct_primitive(denoiseDct_t ref, denoiseDct_t opt)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
for (int s = 0; s < 4; s++)
|
||||
{
|
||||
int log2TrSize = s + 2;
|
||||
int num = 1 << (log2TrSize * 2);
|
||||
int cmp_size = sizeof(int) * num;
|
||||
int cmp_short = sizeof(short) * num;
|
||||
|
||||
for (int i = 0; i < ITERS; i++)
|
||||
{
|
||||
memset(mubuf1, 0, num * sizeof(uint32_t));
|
||||
memset(mubuf2, 0, num * sizeof(uint32_t));
|
||||
memset(mushortbuf1, 0, num * sizeof(uint16_t));
|
||||
|
||||
for (int k = 0; k < num; k++)
|
||||
mushortbuf1[k] = rand() % UNSIGNED_SHORT_MAX;
|
||||
|
||||
int index = rand() % TEST_CASES;
|
||||
|
||||
ref(short_denoise_test_buff1[index] + j, mubuf1, mushortbuf1, num);
|
||||
checked(opt, short_denoise_test_buff2[index] + j, mubuf2, mushortbuf1, num);
|
||||
|
||||
if (memcmp(short_denoise_test_buff1[index] + j, short_denoise_test_buff2[index] + j, cmp_short))
|
||||
return false;
|
||||
|
||||
if (memcmp(mubuf1, mubuf2, cmp_size))
|
||||
return false;
|
||||
|
||||
reportfail();
|
||||
j += INCR;
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MBDstHarness::testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt)
|
||||
{
|
||||
for (int i = 0; i < NUM_TR_SIZE; i++)
|
||||
{
|
||||
if (opt.cu[i].dct)
|
||||
{
|
||||
if (!check_dct_primitive(ref.cu[i].dct, opt.cu[i].dct, dctInfo[i].width))
|
||||
{
|
||||
printf("\n%s failed\n", dctInfo[i].name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_TR_SIZE; i++)
|
||||
{
|
||||
if (opt.cu[i].idct)
|
||||
{
|
||||
if (!check_idct_primitive(ref.cu[i].idct, opt.cu[i].idct, idctInfo[i].width))
|
||||
{
|
||||
printf("%s failed\n", idctInfo[i].name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.dst4x4)
|
||||
{
|
||||
if (!check_dct_primitive(ref.dst4x4, opt.dst4x4, 4))
|
||||
{
|
||||
printf("dst4x4: Failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.idst4x4)
|
||||
{
|
||||
if (!check_idct_primitive(ref.idst4x4, opt.idst4x4, 4))
|
||||
{
|
||||
printf("idst4x4: Failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.dequant_normal)
|
||||
{
|
||||
if (!check_dequant_primitive(ref.dequant_normal, opt.dequant_normal))
|
||||
{
|
||||
printf("dequant: Failed!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.dequant_scaling)
|
||||
{
|
||||
if (!check_dequant_primitive(ref.dequant_scaling, opt.dequant_scaling))
|
||||
{
|
||||
printf("dequant_scaling: Failed!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.quant)
|
||||
{
|
||||
if (!check_quant_primitive(ref.quant, opt.quant))
|
||||
{
|
||||
printf("quant: Failed!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.nquant)
|
||||
{
|
||||
if (!check_nquant_primitive(ref.nquant, opt.nquant))
|
||||
{
|
||||
printf("nquant: Failed!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < NUM_TR_SIZE; i++)
|
||||
{
|
||||
if (opt.cu[i].count_nonzero)
|
||||
{
|
||||
if (!check_count_nonzero_primitive(ref.cu[i].count_nonzero, opt.cu[i].count_nonzero))
|
||||
{
|
||||
printf("count_nonzero[%dx%d] Failed!\n", 4 << i, 4 << i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opt.dequant_scaling)
|
||||
{
|
||||
if (!check_dequant_primitive(ref.dequant_scaling, opt.dequant_scaling))
|
||||
{
|
||||
printf("dequant_scaling: Failed!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.denoiseDct)
|
||||
{
|
||||
if (!check_denoise_dct_primitive(ref.denoiseDct, opt.denoiseDct))
|
||||
{
|
||||
printf("denoiseDct: Failed!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MBDstHarness::measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt)
|
||||
{
|
||||
if (opt.dst4x4)
|
||||
{
|
||||
printf("dst4x4\t");
|
||||
REPORT_SPEEDUP(opt.dst4x4, ref.dst4x4, mbuf1, mshortbuf2, 4);
|
||||
}
|
||||
|
||||
for (int value = 0; value < NUM_TR_SIZE; value++)
|
||||
{
|
||||
if (opt.cu[value].dct)
|
||||
{
|
||||
printf("%s\t", dctInfo[value].name);
|
||||
REPORT_SPEEDUP(opt.cu[value].dct, ref.cu[value].dct, mbuf1, mshortbuf2, dctInfo[value].width);
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.idst4x4)
|
||||
{
|
||||
printf("idst4x4\t");
|
||||
REPORT_SPEEDUP(opt.idst4x4, ref.idst4x4, mbuf1, mshortbuf2, 4);
|
||||
}
|
||||
|
||||
for (int value = 0; value < NUM_TR_SIZE; value++)
|
||||
{
|
||||
if (opt.cu[value].idct)
|
||||
{
|
||||
printf("%s\t", idctInfo[value].name);
|
||||
REPORT_SPEEDUP(opt.cu[value].idct, ref.cu[value].idct, mshortbuf3, mshortbuf2, idctInfo[value].width);
|
||||
}
|
||||
}
|
||||
|
||||
if (opt.dequant_normal)
|
||||
{
|
||||
printf("dequant_normal\t");
|
||||
REPORT_SPEEDUP(opt.dequant_normal, ref.dequant_normal, short_test_buff[0], mshortbuf2, 32 * 32, 70, 1);
|
||||
}
|
||||
|
||||
if (opt.dequant_scaling)
|
||||
{
|
||||
printf("dequant_scaling\t");
|
||||
REPORT_SPEEDUP(opt.dequant_scaling, ref.dequant_scaling, short_test_buff[0], mintbuf3, mshortbuf2, 32 * 32, 5, 1);
|
||||
}
|
||||
|
||||
if (opt.quant)
|
||||
{
|
||||
printf("quant\t\t");
|
||||
REPORT_SPEEDUP(opt.quant, ref.quant, short_test_buff[0], int_test_buff[1], mintbuf3, mshortbuf2, 23, 23785, 32 * 32);
|
||||
}
|
||||
|
||||
if (opt.nquant)
|
||||
{
|
||||
printf("nquant\t\t");
|
||||
REPORT_SPEEDUP(opt.nquant, ref.nquant, short_test_buff[0], int_test_buff[1], mshortbuf2, 23, 23785, 32 * 32);
|
||||
}
|
||||
for (int value = 0; value < NUM_TR_SIZE; value++)
|
||||
{
|
||||
if (opt.cu[value].count_nonzero)
|
||||
{
|
||||
printf("count_nonzero[%dx%d]", 4 << value, 4 << value);
|
||||
REPORT_SPEEDUP(opt.cu[value].count_nonzero, ref.cu[value].count_nonzero, mbuf1);
|
||||
}
|
||||
}
|
||||
if (opt.denoiseDct)
|
||||
{
|
||||
printf("denoiseDct\t");
|
||||
REPORT_SPEEDUP(opt.denoiseDct, ref.denoiseDct, short_denoise_test_buff1[0], mubuf1, mushortbuf1, 32 * 32);
|
||||
}
|
||||
}
|
86
x265/source/test/mbdstharness.h
Normal file
86
x265/source/test/mbdstharness.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Steve Borho <steve@borho.org>
|
||||
* Min Chen <min.chen@multicorewareinc.com>
|
||||
* Praveen Kumar Tiwari <praveen@multicorewareinc.com>
|
||||
* Nabajit Deka <nabajit@multicorewareinc.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _MBDSTHARNESS_H_1
|
||||
#define _MBDSTHARNESS_H_1 1
|
||||
|
||||
#include "testharness.h"
|
||||
#include "primitives.h"
|
||||
|
||||
class MBDstHarness : public TestHarness
|
||||
{
|
||||
protected:
|
||||
|
||||
enum { ITERS = 128 };
|
||||
enum { INCR = 16 };
|
||||
enum { MAX_TU_SIZE = 32 * 32 };
|
||||
enum { TEST_BUF_SIZE = MAX_TU_SIZE + ITERS * INCR };
|
||||
enum { TEST_CASES = 3 };
|
||||
|
||||
ALIGN_VAR_32(int16_t, mbuf1[TEST_BUF_SIZE]);
|
||||
int16_t mbufdct[TEST_BUF_SIZE];
|
||||
int mbufidct[TEST_BUF_SIZE];
|
||||
|
||||
int16_t mshortbuf2[MAX_TU_SIZE];
|
||||
int16_t mshortbuf3[MAX_TU_SIZE];
|
||||
|
||||
int mintbuf1[MAX_TU_SIZE];
|
||||
int mintbuf2[MAX_TU_SIZE];
|
||||
int mintbuf3[MAX_TU_SIZE];
|
||||
int mintbuf4[MAX_TU_SIZE];
|
||||
|
||||
int16_t short_test_buff[TEST_CASES][TEST_BUF_SIZE];
|
||||
int int_test_buff[TEST_CASES][TEST_BUF_SIZE];
|
||||
int int_idct_test_buff[TEST_CASES][TEST_BUF_SIZE];
|
||||
|
||||
uint32_t mubuf1[MAX_TU_SIZE];
|
||||
uint32_t mubuf2[MAX_TU_SIZE];
|
||||
uint16_t mushortbuf1[MAX_TU_SIZE];
|
||||
|
||||
int16_t short_denoise_test_buff1[TEST_CASES][TEST_BUF_SIZE];
|
||||
int16_t short_denoise_test_buff2[TEST_CASES][TEST_BUF_SIZE];
|
||||
|
||||
bool check_dequant_primitive(dequant_scaling_t ref, dequant_scaling_t opt);
|
||||
bool check_dequant_primitive(dequant_normal_t ref, dequant_normal_t opt);
|
||||
bool check_quant_primitive(quant_t ref, quant_t opt);
|
||||
bool check_nquant_primitive(nquant_t ref, nquant_t opt);
|
||||
bool check_dct_primitive(dct_t ref, dct_t opt, intptr_t width);
|
||||
bool check_idct_primitive(idct_t ref, idct_t opt, intptr_t width);
|
||||
bool check_count_nonzero_primitive(count_nonzero_t ref, count_nonzero_t opt);
|
||||
bool check_denoise_dct_primitive(denoiseDct_t ref, denoiseDct_t opt);
|
||||
|
||||
public:
|
||||
|
||||
MBDstHarness();
|
||||
|
||||
const char *getName() const { return "transforms"; }
|
||||
|
||||
bool testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
|
||||
void measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
};
|
||||
|
||||
#endif // ifndef _MBDSTHARNESS_H_1
|
2970
x265/source/test/pixelharness.cpp
Normal file
2970
x265/source/test/pixelharness.cpp
Normal file
File diff suppressed because it is too large
Load diff
135
x265/source/test/pixelharness.h
Normal file
135
x265/source/test/pixelharness.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Steve Borho <steve@borho.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _PIXELHARNESS_H_1
|
||||
#define _PIXELHARNESS_H_1 1
|
||||
|
||||
#include "testharness.h"
|
||||
#include "primitives.h"
|
||||
|
||||
class PixelHarness : public TestHarness
|
||||
{
|
||||
protected:
|
||||
|
||||
enum { INCR = 32 };
|
||||
enum { STRIDE = 64 };
|
||||
enum { ITERS = 100 };
|
||||
enum { MAX_HEIGHT = 64 };
|
||||
enum { PAD_ROWS = 64 };
|
||||
enum { BUFFSIZE = STRIDE * (MAX_HEIGHT + PAD_ROWS) + INCR * ITERS };
|
||||
enum { TEST_CASES = 3 };
|
||||
enum { SMAX = 1 << 12 };
|
||||
enum { SMIN = -1 << 12 };
|
||||
|
||||
ALIGN_VAR_32(pixel, pbuf1[BUFFSIZE]);
|
||||
pixel pbuf2[BUFFSIZE];
|
||||
pixel pbuf3[BUFFSIZE];
|
||||
pixel pbuf4[BUFFSIZE];
|
||||
int ibuf1[BUFFSIZE];
|
||||
int8_t psbuf1[BUFFSIZE];
|
||||
int8_t psbuf2[BUFFSIZE];
|
||||
int8_t psbuf3[BUFFSIZE];
|
||||
int8_t psbuf4[BUFFSIZE];
|
||||
int8_t psbuf5[BUFFSIZE];
|
||||
|
||||
int16_t sbuf1[BUFFSIZE];
|
||||
int16_t sbuf2[BUFFSIZE];
|
||||
int16_t sbuf3[BUFFSIZE];
|
||||
|
||||
pixel pixel_test_buff[TEST_CASES][BUFFSIZE];
|
||||
int16_t short_test_buff[TEST_CASES][BUFFSIZE];
|
||||
int16_t short_test_buff1[TEST_CASES][BUFFSIZE];
|
||||
int16_t short_test_buff2[TEST_CASES][BUFFSIZE];
|
||||
int int_test_buff[TEST_CASES][BUFFSIZE];
|
||||
uint16_t ushort_test_buff[TEST_CASES][BUFFSIZE];
|
||||
uint8_t uchar_test_buff[TEST_CASES][BUFFSIZE];
|
||||
double double_test_buff[TEST_CASES][BUFFSIZE];
|
||||
|
||||
bool check_pixelcmp(pixelcmp_t ref, pixelcmp_t opt);
|
||||
bool check_pixel_sse(pixel_sse_t ref, pixel_sse_t opt);
|
||||
bool check_pixel_sse_ss(pixel_sse_ss_t ref, pixel_sse_ss_t opt);
|
||||
bool check_pixelcmp_x3(pixelcmp_x3_t ref, pixelcmp_x3_t opt);
|
||||
bool check_pixelcmp_x4(pixelcmp_x4_t ref, pixelcmp_x4_t opt);
|
||||
bool check_copy_pp(copy_pp_t ref, copy_pp_t opt);
|
||||
bool check_copy_sp(copy_sp_t ref, copy_sp_t opt);
|
||||
bool check_copy_ps(copy_ps_t ref, copy_ps_t opt);
|
||||
bool check_copy_ss(copy_ss_t ref, copy_ss_t opt);
|
||||
bool check_pixelavg_pp(pixelavg_pp_t ref, pixelavg_pp_t opt);
|
||||
bool check_pixel_sub_ps(pixel_sub_ps_t ref, pixel_sub_ps_t opt);
|
||||
bool check_pixel_add_ps(pixel_add_ps_t ref, pixel_add_ps_t opt);
|
||||
bool check_scale1D_pp(scale1D_t ref, scale1D_t opt);
|
||||
bool check_scale2D_pp(scale2D_t ref, scale2D_t opt);
|
||||
bool check_ssd_s(pixel_ssd_s_t ref, pixel_ssd_s_t opt);
|
||||
bool check_blockfill_s(blockfill_s_t ref, blockfill_s_t opt);
|
||||
bool check_calresidual(calcresidual_t ref, calcresidual_t opt);
|
||||
bool check_transpose(transpose_t ref, transpose_t opt);
|
||||
bool check_weightp(weightp_pp_t ref, weightp_pp_t opt);
|
||||
bool check_weightp(weightp_sp_t ref, weightp_sp_t opt);
|
||||
bool check_downscale_t(downscale_t ref, downscale_t opt);
|
||||
bool check_cpy2Dto1D_shl_t(cpy2Dto1D_shl_t ref, cpy2Dto1D_shl_t opt);
|
||||
bool check_cpy2Dto1D_shr_t(cpy2Dto1D_shr_t ref, cpy2Dto1D_shr_t opt);
|
||||
bool check_cpy1Dto2D_shl_t(cpy1Dto2D_shl_t ref, cpy1Dto2D_shl_t opt);
|
||||
bool check_cpy1Dto2D_shr_t(cpy1Dto2D_shr_t ref, cpy1Dto2D_shr_t opt);
|
||||
bool check_copy_cnt_t(copy_cnt_t ref, copy_cnt_t opt);
|
||||
bool check_pixel_var(var_t ref, var_t opt);
|
||||
bool check_ssim_4x4x2_core(ssim_4x4x2_core_t ref, ssim_4x4x2_core_t opt);
|
||||
bool check_ssim_end(ssim_end4_t ref, ssim_end4_t opt);
|
||||
bool check_addAvg(addAvg_t, addAvg_t);
|
||||
bool check_saoCuOrgE0_t(saoCuOrgE0_t ref, saoCuOrgE0_t opt);
|
||||
bool check_saoCuOrgE1_t(saoCuOrgE1_t ref, saoCuOrgE1_t opt);
|
||||
bool check_saoCuOrgE2_t(saoCuOrgE2_t ref[], saoCuOrgE2_t opt[]);
|
||||
bool check_saoCuOrgE3_t(saoCuOrgE3_t ref, saoCuOrgE3_t opt);
|
||||
bool check_saoCuOrgE3_32_t(saoCuOrgE3_t ref, saoCuOrgE3_t opt);
|
||||
bool check_saoCuOrgB0_t(saoCuOrgB0_t ref, saoCuOrgB0_t opt);
|
||||
bool check_saoCuStatsBO_t(saoCuStatsBO_t ref, saoCuStatsBO_t opt);
|
||||
bool check_saoCuStatsE0_t(saoCuStatsE0_t ref, saoCuStatsE0_t opt);
|
||||
bool check_saoCuStatsE1_t(saoCuStatsE1_t ref, saoCuStatsE1_t opt);
|
||||
bool check_saoCuStatsE2_t(saoCuStatsE2_t ref, saoCuStatsE2_t opt);
|
||||
bool check_saoCuStatsE3_t(saoCuStatsE3_t ref, saoCuStatsE3_t opt);
|
||||
bool check_planecopy_sp(planecopy_sp_t ref, planecopy_sp_t opt);
|
||||
bool check_planecopy_cp(planecopy_cp_t ref, planecopy_cp_t opt);
|
||||
bool check_cutree_propagate_cost(cutree_propagate_cost ref, cutree_propagate_cost opt);
|
||||
bool check_psyCost_pp(pixelcmp_t ref, pixelcmp_t opt);
|
||||
bool check_psyCost_ss(pixelcmp_ss_t ref, pixelcmp_ss_t opt);
|
||||
bool check_calSign(sign_t ref, sign_t opt);
|
||||
bool check_scanPosLast(scanPosLast_t ref, scanPosLast_t opt);
|
||||
bool check_findPosFirstLast(findPosFirstLast_t ref, findPosFirstLast_t opt);
|
||||
bool check_costCoeffNxN(costCoeffNxN_t ref, costCoeffNxN_t opt);
|
||||
bool check_costCoeffRemain(costCoeffRemain_t ref, costCoeffRemain_t opt);
|
||||
bool check_costC1C2Flag(costC1C2Flag_t ref, costC1C2Flag_t opt);
|
||||
bool check_planeClipAndMax(planeClipAndMax_t ref, planeClipAndMax_t opt);
|
||||
|
||||
public:
|
||||
|
||||
PixelHarness();
|
||||
|
||||
const char *getName() const { return "pixel"; }
|
||||
|
||||
bool testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
bool testPU(int part, const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
|
||||
void measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
void measurePartition(int part, const EncoderPrimitives& ref, const EncoderPrimitives& opt);
|
||||
};
|
||||
|
||||
#endif // ifndef _PIXELHARNESS_H_1
|
36
x265/source/test/rate-control-tests.txt
Normal file
36
x265/source/test/rate-control-tests.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
# List of command lines to be run by rate control regression tests, see https://bitbucket.org/sborho/test-harness
|
||||
|
||||
#These tests should yeild deterministic results
|
||||
# This test is listed first since it currently reproduces bugs
|
||||
big_buck_bunny_360p24.y4m,--preset medium --bitrate 1000 --pass 1 -F4,--preset medium --bitrate 1000 --pass 2 -F4
|
||||
fire_1920x1080_30.yuv, --preset slow --bitrate 2000 --tune zero-latency
|
||||
|
||||
|
||||
# VBV tests, non-deterministic so testing for correctness and bitrate
|
||||
# fluctuations - up to 1% bitrate fluctuation is allowed between runs
|
||||
night_cars_1920x1080_30.yuv,--preset medium --crf 25 --vbv-bufsize 5000 --vbv-maxrate 5000 -F6 --crf-max 34 --crf-min 22
|
||||
ducks_take_off_420_720p50.y4m,--preset slow --bitrate 1600 --vbv-bufsize 1600 --vbv-maxrate 1600 --strict-cbr --aq-mode 2 --aq-strength 0.5
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset veryslow --bitrate 4000 --vbv-bufsize 3000 --vbv-maxrate 4000 --tune grain
|
||||
fire_1920x1080_30.yuv,--preset medium --bitrate 1000 --vbv-maxrate 1500 --vbv-bufsize 1500 --aud --pmode --tune ssim
|
||||
112_1920x1080_25.yuv,--preset ultrafast --bitrate 10000 --vbv-maxrate 10000 --vbv-bufsize 15000 --hrd --strict-cbr
|
||||
Traffic_4096x2048_30.yuv,--preset superfast --bitrate 20000 --vbv-maxrate 20000 --vbv-bufsize 20000 --repeat-headers --strict-cbr
|
||||
Traffic_4096x2048_30.yuv,--preset faster --bitrate 8000 --vbv-maxrate 8000 --vbv-bufsize 6000 --aud --repeat-headers --no-open-gop --hrd --pmode --pme
|
||||
News-4k.y4m,--preset veryfast --bitrate 3000 --vbv-maxrate 5000 --vbv-bufsize 5000 --repeat-headers --temporal-layers
|
||||
NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset medium --bitrate 18000 --vbv-bufsize 20000 --vbv-maxrate 18000 --strict-cbr
|
||||
NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset medium --bitrate 8000 --vbv-bufsize 12000 --vbv-maxrate 10000 --tune grain
|
||||
big_buck_bunny_360p24.y4m,--preset medium --bitrate 400 --vbv-bufsize 600 --vbv-maxrate 600 --aud --hrd --tune fast-decode
|
||||
sita_1920x1080_30.yuv,--preset superfast --crf 25 --vbv-bufsize 3000 --vbv-maxrate 4000 --vbv-bufsize 5000 --hrd --crf-max 30
|
||||
sita_1920x1080_30.yuv,--preset superfast --bitrate 3000 --vbv-bufsize 3000 --vbv-maxrate 3000 --aud --strict-cbr
|
||||
|
||||
|
||||
|
||||
# multi-pass rate control tests
|
||||
big_buck_bunny_360p24.y4m,--preset slow --crf 40 --pass 1 -f 5000,--preset slow --bitrate 200 --pass 2 -f 5000
|
||||
big_buck_bunny_360p24.y4m,--preset medium --bitrate 700 --pass 1 -F4 --slow-firstpass -f 5000 ,--preset medium --bitrate 700 --vbv-bufsize 900 --vbv-maxrate 700 --pass 2 -F4 -f 5000
|
||||
112_1920x1080_25.yuv,--preset fast --bitrate 1000 --vbv-maxrate 1000 --vbv-bufsize 1000 --strict-cbr --pass 1 -F4,--preset fast --bitrate 1000 --vbv-maxrate 3000 --vbv-bufsize 3000 --pass 2 -F4
|
||||
pine_tree_1920x1080_30.yuv,--preset veryfast --crf 12 --pass 1 -F4,--preset faster --bitrate 4000 --pass 2 -F4
|
||||
SteamLocomotiveTrain_2560x1600_60_10bit_crop.yuv, --tune grain --preset ultrafast --bitrate 5000 --vbv-maxrate 5000 --vbv-bufsize 8000 --strict-cbr -F4 --pass 1, --tune grain --preset ultrafast --bitrate 8000 --vbv-maxrate 8000 --vbv-bufsize 8000 -F4 --pass 2
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset medium --crf 40 --pass 1, --preset faster --bitrate 200 --pass 2 -F4
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset superfast --bitrate 2500 --pass 1 -F4 --slow-firstpass,--preset superfast --bitrate 2500 --pass 2 -F4
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset medium --crf 26 --vbv-maxrate 1000 --vbv-bufsize 1000 --pass 1,--preset fast --bitrate 1000 --vbv-maxrate 1000 --vbv-bufsize 700 --pass 3 -F4,--preset slow --bitrate 500 --vbv-maxrate 500 --vbv-bufsize 700 --pass 2 -F4
|
||||
|
134
x265/source/test/regression-tests.txt
Normal file
134
x265/source/test/regression-tests.txt
Normal file
|
@ -0,0 +1,134 @@
|
|||
# List of command lines to be run by regression tests, see https://bitbucket.org/sborho/test-harness
|
||||
|
||||
# the vast majority of the commands are tested for results matching the
|
||||
# most recent commit which was known to change outputs. The output
|
||||
# bitstream must be bit-exact or the test fails. If no golden outputs
|
||||
# are available the bitstream is validated (decoded) and then saved as a
|
||||
# new golden output
|
||||
|
||||
# Note: --nr-intra, --nr-inter, and --bitrate (ABR) give different
|
||||
# outputs for different frame encoder counts. In order for outputs to be
|
||||
# consistent across many machines, you must force a certain -FN so it is
|
||||
# not auto-detected.
|
||||
|
||||
BasketballDrive_1920x1080_50.y4m,--preset faster --aq-strength 2 --merange 190
|
||||
BasketballDrive_1920x1080_50.y4m,--preset medium --ctu 16 --max-tu-size 8 --subme 7 --qg-size 16 --cu-lossless
|
||||
BasketballDrive_1920x1080_50.y4m,--preset medium --keyint -1 --nr-inter 100 -F4 --no-sao
|
||||
BasketballDrive_1920x1080_50.y4m,--preset slow --nr-intra 100 -F4 --aq-strength 3 --qg-size 16 --limit-refs 1
|
||||
BasketballDrive_1920x1080_50.y4m,--preset slower --lossless --chromaloc 3 --subme 0
|
||||
BasketballDrive_1920x1080_50.y4m,--preset superfast --psy-rd 1 --ctu 16 --no-wpp
|
||||
BasketballDrive_1920x1080_50.y4m,--preset ultrafast --signhide --colormatrix bt709
|
||||
BasketballDrive_1920x1080_50.y4m,--preset veryfast --tune zerolatency --no-temporal-mvp
|
||||
BasketballDrive_1920x1080_50.y4m,--preset veryslow --crf 4 --cu-lossless --pmode --limit-refs 1
|
||||
Coastguard-4k.y4m,--preset medium --rdoq-level 1 --tune ssim --no-signhide --me umh
|
||||
Coastguard-4k.y4m,--preset slow --tune psnr --cbqpoffs -1 --crqpoffs 1 --limit-refs 1
|
||||
Coastguard-4k.y4m,--preset superfast --tune grain --overscan=crop
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset fast --aq-mode 0 --sar 2 --range full
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset faster --max-tu-size 4 --min-cu-size 32
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset medium --no-wpp --no-cutree --no-strong-intra-smoothing --limit-refs 1
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset slow --no-wpp --tune ssim --transfer smpte240m
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset slower --tune ssim --tune fastdecode --limit-refs 2
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset superfast --weightp --no-wpp --sao
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset ultrafast --weightp --tune zerolatency --qg-size 16
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset veryfast --temporal-layers --tune grain
|
||||
CrowdRun_1920x1080_50_10bit_444.yuv,--preset medium --dither --keyint -1 --rdoq-level 1
|
||||
CrowdRun_1920x1080_50_10bit_444.yuv,--preset superfast --weightp --dither --no-psy-rd
|
||||
CrowdRun_1920x1080_50_10bit_444.yuv,--preset ultrafast --weightp --no-wpp --no-open-gop
|
||||
CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryfast --temporal-layers --repeat-headers --limit-refs 2
|
||||
CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryslow --tskip --tskip-fast --no-scenecut
|
||||
DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset medium --tune psnr --bframes 16
|
||||
DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset slow --temporal-layers --no-psy-rd --qg-size 32 --limit-refs 0 --cu-lossless
|
||||
DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset superfast --weightp --qg-size 16
|
||||
DucksAndLegs_1920x1080_60_10bit_444.yuv,--preset medium --nr-inter 500 -F4 --no-psy-rdoq
|
||||
DucksAndLegs_1920x1080_60_10bit_444.yuv,--preset slower --no-weightp --rdoq-level 0 --limit-refs 3
|
||||
DucksAndLegs_1920x1080_60_10bit_444.yuv,--preset veryfast --weightp --nr-intra 1000 -F4
|
||||
FourPeople_1280x720_60.y4m,--preset medium --qp 38 --no-psy-rd
|
||||
FourPeople_1280x720_60.y4m,--preset superfast --no-wpp --lookahead-slices 2
|
||||
Keiba_832x480_30.y4m,--preset medium --pmode --tune grain
|
||||
Keiba_832x480_30.y4m,--preset slower --fast-intra --nr-inter 500 -F4 --limit-refs 0
|
||||
Keiba_832x480_30.y4m,--preset superfast --no-fast-intra --nr-intra 1000 -F4
|
||||
Kimono1_1920x1080_24_10bit_444.yuv,--preset medium --min-cu-size 32
|
||||
Kimono1_1920x1080_24_10bit_444.yuv,--preset superfast --weightb
|
||||
KristenAndSara_1280x720_60.y4m,--preset medium --no-cutree --max-tu-size 16
|
||||
KristenAndSara_1280x720_60.y4m,--preset slower --pmode --max-tu-size 8 --limit-refs 0
|
||||
KristenAndSara_1280x720_60.y4m,--preset superfast --min-cu-size 16 --qg-size 16 --limit-refs 1
|
||||
KristenAndSara_1280x720_60.y4m,--preset ultrafast --strong-intra-smoothing
|
||||
NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset medium --tune grain --limit-refs 2
|
||||
NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset superfast --tune psnr
|
||||
News-4k.y4m,--preset medium --tune ssim --no-sao --qg-size 16
|
||||
News-4k.y4m,--preset superfast --lookahead-slices 6 --aq-mode 0
|
||||
OldTownCross_1920x1080_50_10bit_422.yuv,--preset medium --no-weightp
|
||||
OldTownCross_1920x1080_50_10bit_422.yuv,--preset slower --tune fastdecode
|
||||
OldTownCross_1920x1080_50_10bit_422.yuv,--preset superfast --weightp
|
||||
ParkScene_1920x1080_24.y4m,--preset medium --qp 40 --rdpenalty 2 --tu-intra-depth 3
|
||||
ParkScene_1920x1080_24.y4m,--preset slower --no-weightp
|
||||
ParkScene_1920x1080_24_10bit_444.yuv,--preset superfast --weightp --lookahead-slices 4
|
||||
RaceHorses_416x240_30.y4m,--preset medium --tskip-fast --tskip
|
||||
RaceHorses_416x240_30.y4m,--preset slower --keyint -1 --rdoq-level 0
|
||||
RaceHorses_416x240_30.y4m,--preset superfast --no-cutree
|
||||
RaceHorses_416x240_30.y4m,--preset veryslow --tskip-fast --tskip --limit-refs 3
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset fast --lookahead-slices 2 --b-intra --limit-refs 1
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset faster --rdoq-level 0 --dither
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset slow --tune grain
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset ultrafast --tune psnr --limit-refs 1
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset veryfast --weightb
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset placebo --limit-refs 1
|
||||
SteamLocomotiveTrain_2560x1600_60_10bit_crop.yuv,--preset medium --dither
|
||||
big_buck_bunny_360p24.y4m,--preset faster --keyint 240 --min-keyint 60 --rc-lookahead 200
|
||||
big_buck_bunny_360p24.y4m,--preset medium --keyint 60 --min-keyint 48 --weightb --limit-refs 3
|
||||
big_buck_bunny_360p24.y4m,--preset slow --psy-rdoq 2.0 --rdoq-level 1 --no-b-intra
|
||||
big_buck_bunny_360p24.y4m,--preset superfast --psy-rdoq 2.0
|
||||
big_buck_bunny_360p24.y4m,--preset ultrafast --deblock=2
|
||||
big_buck_bunny_360p24.y4m,--preset veryfast --no-deblock
|
||||
city_4cif_60fps.y4m,--preset medium --crf 4 --cu-lossless --sao-non-deblock
|
||||
city_4cif_60fps.y4m,--preset superfast --rdpenalty 1 --tu-intra-depth 2
|
||||
city_4cif_60fps.y4m,--preset slower --scaling-list default
|
||||
city_4cif_60fps.y4m,--preset veryslow --rdpenalty 2 --sao-non-deblock --no-b-intra --limit-refs 0
|
||||
ducks_take_off_420_720p50.y4m,--preset fast --deblock 6 --bframes 16 --rc-lookahead 40
|
||||
ducks_take_off_420_720p50.y4m,--preset faster --qp 24 --deblock -6 --limit-refs 2
|
||||
ducks_take_off_420_720p50.y4m,--preset medium --tskip --tskip-fast --constrained-intra
|
||||
ducks_take_off_420_720p50.y4m,--preset slow --scaling-list default --qp 40
|
||||
ducks_take_off_420_720p50.y4m,--preset ultrafast --constrained-intra --rd 1
|
||||
ducks_take_off_420_720p50.y4m,--preset veryslow --constrained-intra --bframes 2
|
||||
ducks_take_off_444_720p50.y4m,--preset medium --qp 38 --no-scenecut
|
||||
ducks_take_off_444_720p50.y4m,--preset superfast --weightp --rd 0 --limit-refs 2
|
||||
ducks_take_off_444_720p50.y4m,--preset slower --psy-rd 1 --psy-rdoq 2.0 --rdoq-level 1 --limit-refs 1
|
||||
mobile_calendar_422_ntsc.y4m,--preset medium --bitrate 500 -F4
|
||||
mobile_calendar_422_ntsc.y4m,--preset slower --tskip --tskip-fast
|
||||
mobile_calendar_422_ntsc.y4m,--preset superfast --weightp --rd 0
|
||||
mobile_calendar_422_ntsc.y4m,--preset veryslow --tskip --limit-refs 2
|
||||
old_town_cross_444_720p50.y4m,--preset faster --rd 1 --tune zero-latency
|
||||
old_town_cross_444_720p50.y4m,--preset medium --keyint -1 --no-weightp --ref 6
|
||||
old_town_cross_444_720p50.y4m,--preset slow --rdoq-level 1 --early-skip --ref 7 --no-b-pyramid
|
||||
old_town_cross_444_720p50.y4m,--preset slower --crf 4 --cu-lossless
|
||||
old_town_cross_444_720p50.y4m,--preset superfast --weightp --min-cu 16
|
||||
old_town_cross_444_720p50.y4m,--preset ultrafast --weightp --min-cu 32
|
||||
old_town_cross_444_720p50.y4m,--preset veryfast --qp 1 --tune ssim
|
||||
parkrun_ter_720p50.y4m,--preset medium --no-open-gop --sao-non-deblock --crf 4 --cu-lossless
|
||||
parkrun_ter_720p50.y4m,--preset slower --fast-intra --no-rect --tune grain
|
||||
silent_cif_420.y4m,--preset medium --me full --rect --amp
|
||||
silent_cif_420.y4m,--preset superfast --weightp --rect
|
||||
silent_cif_420.y4m,--preset placebo --ctu 32 --no-sao --qg-size 16
|
||||
vtc1nw_422_ntsc.y4m,--preset medium --scaling-list default --ctu 16 --ref 5
|
||||
vtc1nw_422_ntsc.y4m,--preset slower --nr-inter 1000 -F4 --tune fast-decode --qg-size 16
|
||||
vtc1nw_422_ntsc.y4m,--preset superfast --weightp --nr-intra 100 -F4
|
||||
washdc_422_ntsc.y4m,--preset faster --rdoq-level 1 --max-merge 5
|
||||
washdc_422_ntsc.y4m,--preset medium --no-weightp --max-tu-size 4 --limit-refs 1
|
||||
washdc_422_ntsc.y4m,--preset slower --psy-rdoq 2.0 --rdoq-level 2 --qg-size 32 --limit-refs 1
|
||||
washdc_422_ntsc.y4m,--preset superfast --psy-rd 1 --tune zerolatency
|
||||
washdc_422_ntsc.y4m,--preset ultrafast --weightp --tu-intra-depth 4
|
||||
washdc_422_ntsc.y4m,--preset veryfast --tu-inter-depth 4
|
||||
washdc_422_ntsc.y4m,--preset veryslow --crf 4 --cu-lossless --limit-refs 3
|
||||
BasketballDrive_1920x1080_50.y4m,--preset medium --no-cutree --analysis-mode=save --bitrate 15000,--preset medium --no-cutree --analysis-mode=load --bitrate 13000,--preset medium --no-cutree --analysis-mode=load --bitrate 11000,--preset medium --no-cutree --analysis-mode=load --bitrate 9000,--preset medium --no-cutree --analysis-mode=load --bitrate 7000
|
||||
NebutaFestival_2560x1600_60_10bit_crop.yuv,--preset slow --no-cutree --analysis-mode=save --bitrate 15000,--preset slow --no-cutree --analysis-mode=load --bitrate 13000,--preset slow --no-cutree --analysis-mode=load --bitrate 11000,--preset slow --no-cutree --analysis-mode=load --bitrate 9000,--preset slow --no-cutree --analysis-mode=load --bitrate 7000
|
||||
old_town_cross_444_720p50.y4m,--preset veryslow --no-cutree --analysis-mode=save --bitrate 15000 --early-skip,--preset veryslow --no-cutree --analysis-mode=load --bitrate 13000 --early-skip,--preset veryslow --no-cutree --analysis-mode=load --bitrate 11000 --early-skip,--preset veryslow --no-cutree --analysis-mode=load --bitrate 9000 --early-skip,--preset veryslow --no-cutree --analysis-mode=load --bitrate 7000 --early-skip
|
||||
Johnny_1280x720_60.y4m,--preset medium --no-cutree --analysis-mode=save --bitrate 15000 --tskip-fast,--preset medium --no-cutree --analysis-mode=load --bitrate 13000 --tskip-fast,--preset medium --no-cutree --analysis-mode=load --bitrate 11000 --tskip-fast,--preset medium --no-cutree --analysis-mode=load --bitrate 9000 --tskip-fast,--preset medium --no-cutree --analysis-mode=load --bitrate 7000 --tskip-fast
|
||||
BasketballDrive_1920x1080_50.y4m,--preset medium --recon-y4m-exec "ffplay -i pipe:0 -autoexit"
|
||||
FourPeople_1280x720_60.y4m,--preset ultrafast --recon-y4m-exec "ffplay -i pipe:0 -autoexit"
|
||||
FourPeople_1280x720_60.y4m,--preset veryslow --recon-y4m-exec "ffplay -i pipe:0 -autoexit"
|
||||
|
||||
# interlace test, even though input YUV is not field seperated
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset fast --interlace bff
|
||||
CrowdRun_1920x1080_50_10bit_422.yuv,--preset faster --interlace tff
|
||||
|
||||
# vim: tw=200
|
21
x265/source/test/smoke-tests.txt
Normal file
21
x265/source/test/smoke-tests.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
# List of command lines to be run by smoke tests, see https://bitbucket.org/sborho/test-harness
|
||||
|
||||
# consider VBV tests a failure if new bitrate is more than 5% different
|
||||
# from the old bitrate
|
||||
# vbv-tolerance = 0.05
|
||||
|
||||
big_buck_bunny_360p24.y4m,--preset=superfast --bitrate 400 --vbv-bufsize 600 --vbv-maxrate 400 --hrd --aud --repeat-headers
|
||||
big_buck_bunny_360p24.y4m,--preset=medium --bitrate 1000 -F4 --cu-lossless --scaling-list default
|
||||
big_buck_bunny_360p24.y4m,--preset=slower --no-weightp --pme --qg-size 16
|
||||
washdc_422_ntsc.y4m,--preset=faster --no-strong-intra-smoothing --keyint 1 --qg-size 16
|
||||
washdc_422_ntsc.y4m,--preset=medium --qp 40 --nr-inter 400 -F4
|
||||
washdc_422_ntsc.y4m,--preset=veryslow --pmode --tskip --rdoq-level 0
|
||||
old_town_cross_444_720p50.y4m,--preset=ultrafast --weightp --keyint -1
|
||||
old_town_cross_444_720p50.y4m,--preset=fast --keyint 20 --min-cu-size 16
|
||||
old_town_cross_444_720p50.y4m,--preset=slow --sao-non-deblock --pmode --qg-size 32
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset=veryfast --max-tu-size 8
|
||||
RaceHorses_416x240_30_10bit.yuv,--preset=slower --bitrate 500 -F4 --rdoq-level 1
|
||||
CrowdRun_1920x1080_50_10bit_444.yuv,--preset=ultrafast --constrained-intra --min-keyint 5 --keyint 10
|
||||
CrowdRun_1920x1080_50_10bit_444.yuv,--preset=medium --max-tu-size 16
|
||||
DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset=veryfast --min-cu 16
|
||||
DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset=fast --weightb --interlace bff
|
246
x265/source/test/testbench.cpp
Normal file
246
x265/source/test/testbench.cpp
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Gopu Govindaswamy <gopu@govindaswamy.org>
|
||||
* Mandar Gurav <mandar@multicorewareinc.com>
|
||||
* Mahesh Pittala <mahesh@multicorewareinc.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "primitives.h"
|
||||
#include "pixelharness.h"
|
||||
#include "mbdstharness.h"
|
||||
#include "ipfilterharness.h"
|
||||
#include "intrapredharness.h"
|
||||
#include "param.h"
|
||||
#include "cpu.h"
|
||||
|
||||
using namespace X265_NS;
|
||||
|
||||
const char* lumaPartStr[NUM_PU_SIZES] =
|
||||
{
|
||||
" 4x4", " 8x8", "16x16", "32x32", "64x64",
|
||||
" 8x4", " 4x8",
|
||||
" 16x8", " 8x16",
|
||||
"32x16", "16x32",
|
||||
"64x32", "32x64",
|
||||
"16x12", "12x16", " 16x4", " 4x16",
|
||||
"32x24", "24x32", " 32x8", " 8x32",
|
||||
"64x48", "48x64", "64x16", "16x64",
|
||||
};
|
||||
|
||||
const char* chromaPartStr420[NUM_PU_SIZES] =
|
||||
{
|
||||
" 2x2", " 4x4", " 8x8", "16x16", "32x32",
|
||||
" 4x2", " 2x4",
|
||||
" 8x4", " 4x8",
|
||||
" 16x8", " 8x16",
|
||||
"32x16", "16x32",
|
||||
" 8x6", " 6x8", " 8x2", " 2x8",
|
||||
"16x12", "12x16", " 16x4", " 4x16",
|
||||
"32x24", "24x32", " 32x8", " 8x32",
|
||||
};
|
||||
|
||||
const char* chromaPartStr422[NUM_PU_SIZES] =
|
||||
{
|
||||
" 2x4", " 4x8", " 8x16", "16x32", "32x64",
|
||||
" 4x4", " 2x8",
|
||||
" 8x8", " 4x16",
|
||||
"16x16", " 8x32",
|
||||
"32x32", "16x64",
|
||||
" 8x12", " 6x16", " 8x4", " 2x16",
|
||||
"16x24", "12x32", " 16x8", " 4x32",
|
||||
"32x48", "24x64", "32x16", " 8x64",
|
||||
};
|
||||
|
||||
const char* const* chromaPartStr[X265_CSP_COUNT] =
|
||||
{
|
||||
lumaPartStr,
|
||||
chromaPartStr420,
|
||||
chromaPartStr422,
|
||||
lumaPartStr
|
||||
};
|
||||
|
||||
void do_help()
|
||||
{
|
||||
printf("x265 optimized primitive testbench\n\n");
|
||||
printf("usage: TestBench [--cpuid CPU] [--testbench BENCH] [--help]\n\n");
|
||||
printf(" CPU is comma separated SIMD arch list, example: SSE4,AVX\n");
|
||||
printf(" BENCH is one of (pixel,transforms,interp,intrapred)\n\n");
|
||||
printf("By default, the test bench will test all benches on detected CPU architectures\n");
|
||||
printf("Options and testbench name may be truncated.\n");
|
||||
}
|
||||
|
||||
PixelHarness HPixel;
|
||||
MBDstHarness HMBDist;
|
||||
IPFilterHarness HIPFilter;
|
||||
IntraPredHarness HIPred;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int cpuid = X265_NS::cpu_detect();
|
||||
const char *testname = 0;
|
||||
|
||||
if (!(argc & 1))
|
||||
{
|
||||
do_help();
|
||||
return 0;
|
||||
}
|
||||
for (int i = 1; i < argc - 1; i += 2)
|
||||
{
|
||||
if (strncmp(argv[i], "--", 2))
|
||||
{
|
||||
printf("** invalid long argument: %s\n\n", argv[i]);
|
||||
do_help();
|
||||
return 1;
|
||||
}
|
||||
const char *name = argv[i] + 2;
|
||||
const char *value = argv[i + 1];
|
||||
if (!strncmp(name, "cpuid", strlen(name)))
|
||||
{
|
||||
bool bError = false;
|
||||
cpuid = parseCpuName(value, bError);
|
||||
if (bError)
|
||||
{
|
||||
printf("Invalid CPU name: %s\n", value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (!strncmp(name, "testbench", strlen(name)))
|
||||
{
|
||||
testname = value;
|
||||
printf("Testing only harnesses that match name <%s>\n", testname);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("** invalid long argument: %s\n\n", name);
|
||||
do_help();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int seed = (int)time(NULL);
|
||||
printf("Using random seed %X %dbit\n", seed, X265_DEPTH);
|
||||
srand(seed);
|
||||
|
||||
// To disable classes of tests, simply comment them out in this list
|
||||
TestHarness *harness[] =
|
||||
{
|
||||
&HPixel,
|
||||
&HMBDist,
|
||||
&HIPFilter,
|
||||
&HIPred
|
||||
};
|
||||
|
||||
EncoderPrimitives cprim;
|
||||
memset(&cprim, 0, sizeof(EncoderPrimitives));
|
||||
setupCPrimitives(cprim);
|
||||
setupAliasPrimitives(cprim);
|
||||
|
||||
struct test_arch_t
|
||||
{
|
||||
char name[12];
|
||||
int flag;
|
||||
} test_arch[] =
|
||||
{
|
||||
{ "SSE2", X265_CPU_SSE2 },
|
||||
{ "SSE3", X265_CPU_SSE3 },
|
||||
{ "SSSE3", X265_CPU_SSSE3 },
|
||||
{ "SSE4", X265_CPU_SSE4 },
|
||||
{ "AVX", X265_CPU_AVX },
|
||||
{ "XOP", X265_CPU_XOP },
|
||||
{ "AVX2", X265_CPU_AVX2 },
|
||||
{ "BMI2", X265_CPU_AVX2 | X265_CPU_BMI1 | X265_CPU_BMI2 },
|
||||
{ "", 0 },
|
||||
};
|
||||
|
||||
for (int i = 0; test_arch[i].flag; i++)
|
||||
{
|
||||
if ((test_arch[i].flag & cpuid) == test_arch[i].flag)
|
||||
{
|
||||
printf("Testing primitives: %s\n", test_arch[i].name);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
EncoderPrimitives vecprim;
|
||||
memset(&vecprim, 0, sizeof(vecprim));
|
||||
setupInstrinsicPrimitives(vecprim, test_arch[i].flag);
|
||||
setupAliasPrimitives(vecprim);
|
||||
for (size_t h = 0; h < sizeof(harness) / sizeof(TestHarness*); h++)
|
||||
{
|
||||
if (testname && strncmp(testname, harness[h]->getName(), strlen(testname)))
|
||||
continue;
|
||||
if (!harness[h]->testCorrectness(cprim, vecprim))
|
||||
{
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "\nx265: intrinsic primitive has failed. Go and fix that Right Now!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
EncoderPrimitives asmprim;
|
||||
memset(&asmprim, 0, sizeof(asmprim));
|
||||
setupAssemblyPrimitives(asmprim, test_arch[i].flag);
|
||||
setupAliasPrimitives(asmprim);
|
||||
memcpy(&primitives, &asmprim, sizeof(EncoderPrimitives));
|
||||
for (size_t h = 0; h < sizeof(harness) / sizeof(TestHarness*); h++)
|
||||
{
|
||||
if (testname && strncmp(testname, harness[h]->getName(), strlen(testname)))
|
||||
continue;
|
||||
if (!harness[h]->testCorrectness(cprim, asmprim))
|
||||
{
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "\nx265: asm primitive has failed. Go and fix that Right Now!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************* Cycle count for all primitives **********************/
|
||||
|
||||
EncoderPrimitives optprim;
|
||||
memset(&optprim, 0, sizeof(optprim));
|
||||
setupInstrinsicPrimitives(optprim, cpuid);
|
||||
setupAssemblyPrimitives(optprim, cpuid);
|
||||
|
||||
/* Note that we do not setup aliases for performance tests, that would be
|
||||
* redundant. The testbench only verifies they are correctly aliased */
|
||||
|
||||
/* some hybrid primitives may rely on other primitives in the
|
||||
* global primitive table, so set up those pointers. This is a
|
||||
* bit ugly, but I don't see a better solution */
|
||||
memcpy(&primitives, &optprim, sizeof(EncoderPrimitives));
|
||||
|
||||
printf("\nTest performance improvement with full optimizations\n");
|
||||
fflush(stdout);
|
||||
|
||||
for (size_t h = 0; h < sizeof(harness) / sizeof(TestHarness*); h++)
|
||||
{
|
||||
if (testname && strncmp(testname, harness[h]->getName(), strlen(testname)))
|
||||
continue;
|
||||
printf("== %s primitives ==\n", harness[h]->getName());
|
||||
harness[h]->measureSpeed(cprim, optprim);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
168
x265/source/test/testharness.h
Normal file
168
x265/source/test/testharness.h
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2013 x265 project
|
||||
*
|
||||
* Authors: Steve Borho <steve@borho.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
||||
*
|
||||
* This program is also available under a commercial proprietary license.
|
||||
* For more information, contact us at license @ x265.com.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _TESTHARNESS_H_
|
||||
#define _TESTHARNESS_H_ 1
|
||||
|
||||
#include "common.h"
|
||||
#include "primitives.h"
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(disable: 4324) // structure was padded due to __declspec(align())
|
||||
#endif
|
||||
|
||||
#define PIXEL_MAX ((1 << X265_DEPTH) - 1)
|
||||
#define PIXEL_MIN 0
|
||||
#define SHORT_MAX 32767
|
||||
#define SHORT_MIN -32767
|
||||
#define UNSIGNED_SHORT_MAX 65535
|
||||
|
||||
using namespace X265_NS;
|
||||
|
||||
extern const char* lumaPartStr[NUM_PU_SIZES];
|
||||
extern const char* const* chromaPartStr[X265_CSP_COUNT];
|
||||
|
||||
class TestHarness
|
||||
{
|
||||
public:
|
||||
|
||||
TestHarness() {}
|
||||
|
||||
virtual ~TestHarness() {}
|
||||
|
||||
virtual bool testCorrectness(const EncoderPrimitives& ref, const EncoderPrimitives& opt) = 0;
|
||||
|
||||
virtual void measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt) = 0;
|
||||
|
||||
virtual const char *getName() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/* Temporary variables for stack checks */
|
||||
int m_ok;
|
||||
|
||||
uint64_t m_rand;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#elif HAVE_RDTSC
|
||||
#include <intrin.h>
|
||||
#elif defined(__GNUC__)
|
||||
/* fallback for older GCC/MinGW */
|
||||
static inline uint32_t __rdtsc(void)
|
||||
{
|
||||
uint32_t a = 0;
|
||||
|
||||
asm volatile("rdtsc" : "=a" (a) ::"edx");
|
||||
return a;
|
||||
}
|
||||
|
||||
#endif // ifdef _MSC_VER
|
||||
|
||||
#define BENCH_RUNS 1000
|
||||
|
||||
// Adapted from checkasm.c, runs each optimized primitive four times, measures rdtsc
|
||||
// and discards invalid times. Repeats 1000 times to get a good average. Then measures
|
||||
// the C reference with fewer runs and reports X factor and average cycles.
|
||||
#define REPORT_SPEEDUP(RUNOPT, RUNREF, ...) \
|
||||
{ \
|
||||
uint32_t cycles = 0; int runs = 0; \
|
||||
RUNOPT(__VA_ARGS__); \
|
||||
for (int ti = 0; ti < BENCH_RUNS; ti++) { \
|
||||
uint32_t t0 = (uint32_t)__rdtsc(); \
|
||||
RUNOPT(__VA_ARGS__); \
|
||||
RUNOPT(__VA_ARGS__); \
|
||||
RUNOPT(__VA_ARGS__); \
|
||||
RUNOPT(__VA_ARGS__); \
|
||||
uint32_t t1 = (uint32_t)__rdtsc() - t0; \
|
||||
if (t1 * runs <= cycles * 4 && ti > 0) { cycles += t1; runs++; } \
|
||||
} \
|
||||
uint32_t refcycles = 0; int refruns = 0; \
|
||||
RUNREF(__VA_ARGS__); \
|
||||
for (int ti = 0; ti < BENCH_RUNS / 4; ti++) { \
|
||||
uint32_t t0 = (uint32_t)__rdtsc(); \
|
||||
RUNREF(__VA_ARGS__); \
|
||||
RUNREF(__VA_ARGS__); \
|
||||
RUNREF(__VA_ARGS__); \
|
||||
RUNREF(__VA_ARGS__); \
|
||||
uint32_t t1 = (uint32_t)__rdtsc() - t0; \
|
||||
if (t1 * refruns <= refcycles * 4 && ti > 0) { refcycles += t1; refruns++; } \
|
||||
} \
|
||||
x265_emms(); \
|
||||
float optperf = (10.0f * cycles / runs) / 4; \
|
||||
float refperf = (10.0f * refcycles / refruns) / 4; \
|
||||
printf("\t%3.2fx ", refperf / optperf); \
|
||||
printf("\t %-8.2lf \t %-8.2lf\n", optperf, refperf); \
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#if X265_ARCH_X86
|
||||
int PFX(stack_pagealign)(int (*func)(), int align);
|
||||
|
||||
/* detect when callee-saved regs aren't saved
|
||||
* needs an explicit asm check because it only sometimes crashes in normal use. */
|
||||
intptr_t PFX(checkasm_call)(intptr_t (*func)(), int *ok, ...);
|
||||
float PFX(checkasm_call_float)(float (*func)(), int *ok, ...);
|
||||
#else
|
||||
#define PFX(stack_pagealign)(func, align) func()
|
||||
#endif
|
||||
|
||||
#if X86_64
|
||||
|
||||
/* Evil hack: detect incorrect assumptions that 32-bit ints are zero-extended to 64-bit.
|
||||
* This is done by clobbering the stack with junk around the stack pointer and calling the
|
||||
* assembly function through x265_checkasm_call with added dummy arguments which forces all
|
||||
* real arguments to be passed on the stack and not in registers. For 32-bit argument the
|
||||
* upper half of the 64-bit register location on the stack will now contain junk. Note that
|
||||
* this is dependent on compiler behavior and that interrupts etc. at the wrong time may
|
||||
* overwrite the junk written to the stack so there's no guarantee that it will always
|
||||
* detect all functions that assumes zero-extension.
|
||||
*/
|
||||
void PFX(checkasm_stack_clobber)(uint64_t clobber, ...);
|
||||
#define checked(func, ...) ( \
|
||||
m_ok = 1, m_rand = (rand() & 0xffff) * 0x0001000100010001ULL, \
|
||||
PFX(checkasm_stack_clobber)(m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, \
|
||||
m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, \
|
||||
m_rand, m_rand, m_rand, m_rand, m_rand), /* max_args+6 */ \
|
||||
PFX(checkasm_call)((intptr_t(*)())func, &m_ok, 0, 0, 0, 0, __VA_ARGS__))
|
||||
|
||||
#define checked_float(func, ...) ( \
|
||||
m_ok = 1, m_rand = (rand() & 0xffff) * 0x0001000100010001ULL, \
|
||||
PFX(checkasm_stack_clobber)(m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, \
|
||||
m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, m_rand, \
|
||||
m_rand, m_rand, m_rand, m_rand, m_rand), /* max_args+6 */ \
|
||||
PFX(checkasm_call_float)((float(*)())func, &m_ok, 0, 0, 0, 0, __VA_ARGS__))
|
||||
#define reportfail() if (!m_ok) { fflush(stdout); fprintf(stderr, "stack clobber check failed at %s:%d", __FILE__, __LINE__); abort(); }
|
||||
#elif ARCH_X86
|
||||
#define checked(func, ...) PFX(checkasm_call)((intptr_t(*)())func, &m_ok, __VA_ARGS__);
|
||||
#define checked_float(func, ...) PFX(checkasm_call_float)((float(*)())func, &m_ok, __VA_ARGS__);
|
||||
|
||||
#else // if X86_64
|
||||
#define checked(func, ...) func(__VA_ARGS__)
|
||||
#define checked_float(func, ...) func(__VA_ARGS__)
|
||||
#define reportfail()
|
||||
#endif // if X86_64
|
||||
}
|
||||
|
||||
#endif // ifndef _TESTHARNESS_H_
|
Loading…
Add table
Add a link
Reference in a new issue