1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
4 * Authors: Steve Borho <steve@borho.org>
5 * Min Chen <min.chen@multicorewareinc.com>
6 * Praveen Kumar Tiwari <praveen@multicorewareinc.com>
7 * Nabajit Deka <nabajit@multicorewareinc.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
23 * This program is also available under a commercial proprietary license.
24 * For more information, contact us at license @ x265.com.
25 *****************************************************************************/
28 #include "mbdstharness.h"
38 const DctConf dctInfo
[] =
47 const DctConf idctInfo
[] =
56 MBDstHarness::MBDstHarness()
58 const int idct_max
= (1 << (BIT_DEPTH
+ 4)) - 1;
60 /* [0] --- Random values
63 for (int i
= 0; i
< TEST_BUF_SIZE
; i
++)
65 short_test_buff
[0][i
] = (rand() & PIXEL_MAX
) - (rand() & PIXEL_MAX
);
66 int_test_buff
[0][i
] = rand() % PIXEL_MAX
;
67 int_idct_test_buff
[0][i
] = (rand() % (SHORT_MAX
- SHORT_MIN
)) - SHORT_MAX
;
68 short_denoise_test_buff1
[0][i
] = short_denoise_test_buff2
[0][i
] = (rand() & SHORT_MAX
) - (rand() & SHORT_MAX
);
70 short_test_buff
[1][i
] = -PIXEL_MAX
;
71 int_test_buff
[1][i
] = -PIXEL_MAX
;
72 int_idct_test_buff
[1][i
] = SHORT_MIN
;
73 short_denoise_test_buff1
[1][i
] = short_denoise_test_buff2
[1][i
] = -SHORT_MAX
;
75 short_test_buff
[2][i
] = PIXEL_MAX
;
76 int_test_buff
[2][i
] = PIXEL_MAX
;
77 int_idct_test_buff
[2][i
] = SHORT_MAX
;
78 short_denoise_test_buff1
[2][i
] = short_denoise_test_buff2
[2][i
] = SHORT_MAX
;
80 mbuf1
[i
] = rand() & PIXEL_MAX
;
81 mbufdct
[i
] = (rand() & PIXEL_MAX
) - (rand() & PIXEL_MAX
);
82 mbufidct
[i
] = (rand() & idct_max
);
86 memset(mshortbuf2
, 0, MAX_TU_SIZE
* sizeof(int16_t));
87 memset(mshortbuf3
, 0, MAX_TU_SIZE
* sizeof(int16_t));
89 memset(mintbuf1
, 0, MAX_TU_SIZE
* sizeof(int));
90 memset(mintbuf2
, 0, MAX_TU_SIZE
* sizeof(int));
91 memset(mintbuf3
, 0, MAX_TU_SIZE
* sizeof(int));
92 memset(mintbuf4
, 0, MAX_TU_SIZE
* sizeof(int));
96 bool MBDstHarness::check_dct_primitive(dct_t ref
, dct_t opt
, intptr_t width
)
99 intptr_t cmp_size
= sizeof(short) * width
* width
;
101 for (int i
= 0; i
< ITERS
; i
++)
103 int index
= rand() % TEST_CASES
;
105 ref(short_test_buff
[index
] + j
, mshortbuf2
, width
);
106 checked(opt
, short_test_buff
[index
] + j
, mshortbuf3
, width
);
108 if (memcmp(mshortbuf2
, mshortbuf3
, cmp_size
))
118 bool MBDstHarness::check_idct_primitive(idct_t ref
, idct_t opt
, intptr_t width
)
121 intptr_t cmp_size
= sizeof(int16_t) * width
* width
;
123 for (int i
= 0; i
< ITERS
; i
++)
125 int index
= rand() % TEST_CASES
;
127 ref(short_test_buff
[index
] + j
, mshortbuf2
, width
);
128 checked(opt
, short_test_buff
[index
] + j
, mshortbuf3
, width
);
130 if (memcmp(mshortbuf2
, mshortbuf3
, cmp_size
))
140 bool MBDstHarness::check_dequant_primitive(dequant_normal_t ref
, dequant_normal_t opt
)
144 for (int i
= 0; i
< ITERS
; i
++)
146 int index
= rand() % TEST_CASES
;
147 int log2TrSize
= (rand() % 4) + 2;
149 int width
= (1 << log2TrSize
);
151 int qp
= rand() % (QP_MAX_SPEC
+ QP_BD_OFFSET
+ 1);
154 static const int invQuantScales
[6] = { 40, 45, 51, 57, 64, 72 };
155 int scale
= invQuantScales
[rem
] << per
;
156 int transformShift
= MAX_TR_DYNAMIC_RANGE
- X265_DEPTH
- log2TrSize
;
157 int shift
= QUANT_IQUANT_SHIFT
- QUANT_SHIFT
- transformShift
;
159 ref(short_test_buff
[index
] + j
, mshortbuf2
, width
* height
, scale
, shift
);
160 checked(opt
, short_test_buff
[index
] + j
, mshortbuf3
, width
* height
, scale
, shift
);
162 if (memcmp(mshortbuf2
, mshortbuf3
, sizeof(int16_t) * height
* width
))
172 bool MBDstHarness::check_dequant_primitive(dequant_scaling_t ref
, dequant_scaling_t opt
)
176 for (int i
= 0; i
< ITERS
; i
++)
179 memset(mshortbuf2
, 0, MAX_TU_SIZE
* sizeof(int16_t));
180 memset(mshortbuf3
, 0, MAX_TU_SIZE
* sizeof(int16_t));
182 int log2TrSize
= (rand() % 4) + 2;
184 int width
= (1 << log2TrSize
);
187 int qp
= rand() % (QP_MAX_SPEC
+ QP_BD_OFFSET
+ 1);
189 int transformShift
= MAX_TR_DYNAMIC_RANGE
- X265_DEPTH
- log2TrSize
;
190 int shift
= QUANT_IQUANT_SHIFT
- QUANT_SHIFT
- transformShift
;
192 int cmp_size
= sizeof(int16_t) * height
* width
;
193 int index1
= rand() % TEST_CASES
;
195 ref(short_test_buff
[index1
] + j
, int_test_buff
[index1
] + j
, mshortbuf2
, width
* height
, per
, shift
);
196 checked(opt
, short_test_buff
[index1
] + j
, int_test_buff
[index1
] + j
, mshortbuf3
, width
* height
, per
, shift
);
198 if (memcmp(mshortbuf2
, mshortbuf3
, cmp_size
))
208 bool MBDstHarness::check_quant_primitive(quant_t ref
, quant_t opt
)
212 for (int i
= 0; i
< ITERS
; i
++)
214 int width
= (rand() % 4 + 1) * 4;
217 uint32_t optReturnValue
= 0;
218 uint32_t refReturnValue
= 0;
220 int bits
= (rand() % 24) + 8;
221 int valueToAdd
= rand() % (1 << bits
);
222 int cmp_size
= sizeof(int) * height
* width
;
223 int cmp_size1
= sizeof(short) * height
* width
;
224 int numCoeff
= height
* width
;
226 int index1
= rand() % TEST_CASES
;
227 int index2
= rand() % TEST_CASES
;
229 refReturnValue
= ref(short_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mintbuf1
, mshortbuf2
, bits
, valueToAdd
, numCoeff
);
230 optReturnValue
= (uint32_t)checked(opt
, short_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mintbuf3
, mshortbuf3
, bits
, valueToAdd
, numCoeff
);
232 if (memcmp(mintbuf1
, mintbuf3
, cmp_size
))
235 if (memcmp(mshortbuf2
, mshortbuf3
, cmp_size1
))
238 if (optReturnValue
!= refReturnValue
)
248 bool MBDstHarness::check_nquant_primitive(nquant_t ref
, nquant_t opt
)
252 for (int i
= 0; i
< ITERS
; i
++)
254 int width
= (rand() % 4 + 1) * 4;
257 uint32_t optReturnValue
= 0;
258 uint32_t refReturnValue
= 0;
260 int bits
= rand() % 32;
261 int valueToAdd
= rand() % (1 << bits
);
262 int cmp_size
= sizeof(short) * height
* width
;
263 int numCoeff
= height
* width
;
265 int index1
= rand() % TEST_CASES
;
266 int index2
= rand() % TEST_CASES
;
268 refReturnValue
= ref(short_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mshortbuf2
, bits
, valueToAdd
, numCoeff
);
269 optReturnValue
= (uint32_t)checked(opt
, short_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mshortbuf3
, bits
, valueToAdd
, numCoeff
);
271 if (memcmp(mshortbuf2
, mshortbuf3
, cmp_size
))
274 if (optReturnValue
!= refReturnValue
)
284 bool MBDstHarness::check_count_nonzero_primitive(count_nonzero_t ref
, count_nonzero_t opt
)
286 ALIGN_VAR_32(int16_t, qcoeff
[32 * 32]);
288 for (int i
= 0; i
< 4; i
++)
290 int log2TrSize
= i
+ 2;
291 int num
= 1 << (log2TrSize
* 2);
294 for (int n
= 0; n
<= num
; n
++)
296 memset(qcoeff
, 0, num
* sizeof(int16_t));
298 for (int j
= 0; j
< n
; j
++)
300 int k
= rand() & mask
;
306 qcoeff
[k
] = (int16_t)rand() - RAND_MAX
/ 2;
309 int refval
= ref(qcoeff
, num
);
310 int optval
= (int)checked(opt
, qcoeff
, num
);
312 if (refval
!= optval
)
322 bool MBDstHarness::check_denoise_dct_primitive(denoiseDct_t ref
, denoiseDct_t opt
)
326 for (int s
= 0; s
< 4; s
++)
328 int log2TrSize
= s
+ 2;
329 int num
= 1 << (log2TrSize
* 2);
330 int cmp_size
= sizeof(int) * num
;
331 int cmp_short
= sizeof(short) * num
;
333 for (int i
= 0; i
< ITERS
; i
++)
335 memset(mubuf1
, 0, num
* sizeof(uint32_t));
336 memset(mubuf2
, 0, num
* sizeof(uint32_t));
337 memset(mushortbuf1
, 0, num
* sizeof(uint16_t));
339 for (int k
= 0; k
< num
; k
++)
340 mushortbuf1
[k
] = rand() % UNSIGNED_SHORT_MAX
;
342 int index
= rand() % TEST_CASES
;
344 ref(short_denoise_test_buff1
[index
] + j
, mubuf1
, mushortbuf1
, num
);
345 checked(opt
, short_denoise_test_buff2
[index
] + j
, mubuf2
, mushortbuf1
, num
);
347 if (memcmp(short_denoise_test_buff1
[index
] + j
, short_denoise_test_buff2
[index
] + j
, cmp_short
))
350 if (memcmp(mubuf1
, mubuf2
, cmp_size
))
363 bool MBDstHarness::testCorrectness(const EncoderPrimitives
& ref
, const EncoderPrimitives
& opt
)
365 for (int i
= 0; i
< NUM_DCTS
; i
++)
369 if (!check_dct_primitive(ref
.dct
[i
], opt
.dct
[i
], dctInfo
[i
].width
))
371 printf("\n%s failed\n", dctInfo
[i
].name
);
377 for (int i
= 0; i
< NUM_IDCTS
; i
++)
381 if (!check_idct_primitive(ref
.idct
[i
], opt
.idct
[i
], idctInfo
[i
].width
))
383 printf("%s failed\n", idctInfo
[i
].name
);
389 if (opt
.dequant_normal
)
391 if (!check_dequant_primitive(ref
.dequant_normal
, opt
.dequant_normal
))
393 printf("dequant: Failed!\n");
398 if (opt
.dequant_scaling
)
400 if (!check_dequant_primitive(ref
.dequant_scaling
, opt
.dequant_scaling
))
402 printf("dequant_scaling: Failed!\n");
409 if (!check_quant_primitive(ref
.quant
, opt
.quant
))
411 printf("quant: Failed!\n");
418 if (!check_nquant_primitive(ref
.nquant
, opt
.nquant
))
420 printf("nquant: Failed!\n");
425 if (opt
.count_nonzero
)
427 if (!check_count_nonzero_primitive(ref
.count_nonzero
, opt
.count_nonzero
))
429 printf("count_nonzero: Failed!\n");
434 if (opt
.dequant_scaling
)
436 if (!check_dequant_primitive(ref
.dequant_scaling
, opt
.dequant_scaling
))
438 printf("dequant_scaling: Failed!\n");
445 if (!check_denoise_dct_primitive(ref
.denoiseDct
, opt
.denoiseDct
))
447 printf("denoiseDct: Failed!\n");
455 void MBDstHarness::measureSpeed(const EncoderPrimitives
& ref
, const EncoderPrimitives
& opt
)
457 for (int value
= 0; value
< NUM_DCTS
; value
++)
461 printf("%s\t", dctInfo
[value
].name
);
462 REPORT_SPEEDUP(opt
.dct
[value
], ref
.dct
[value
], mbuf1
, mshortbuf2
, dctInfo
[value
].width
);
466 for (int value
= 0; value
< NUM_IDCTS
; value
++)
470 printf("%s\t", idctInfo
[value
].name
);
471 REPORT_SPEEDUP(opt
.idct
[value
], ref
.idct
[value
], mshortbuf3
, mshortbuf2
, idctInfo
[value
].width
);
475 if (opt
.dequant_normal
)
477 printf("dequant_normal\t");
478 REPORT_SPEEDUP(opt
.dequant_normal
, ref
.dequant_normal
, short_test_buff
[0], mshortbuf2
, 32 * 32, 70, 1);
481 if (opt
.dequant_scaling
)
483 printf("dequant_scaling\t");
484 REPORT_SPEEDUP(opt
.dequant_scaling
, ref
.dequant_scaling
, short_test_buff
[0], mintbuf3
, mshortbuf2
, 32 * 32, 5, 1);
490 REPORT_SPEEDUP(opt
.quant
, ref
.quant
, short_test_buff
[0], int_test_buff
[1], mintbuf3
, mshortbuf2
, 23, 23785, 32 * 32);
495 printf("nquant\t\t");
496 REPORT_SPEEDUP(opt
.nquant
, ref
.nquant
, short_test_buff
[0], int_test_buff
[1], mshortbuf2
, 23, 23785, 32 * 32);
499 if (opt
.count_nonzero
)
501 for (int i
= 4; i
<= 32; i
<<= 1)
503 printf("count_nonzero[%dx%d]", i
, i
);
504 REPORT_SPEEDUP(opt
.count_nonzero
, ref
.count_nonzero
, mbuf1
, i
* i
)
510 printf("denoiseDct\t");
511 REPORT_SPEEDUP(opt
.denoiseDct
, ref
.denoiseDct
, short_denoise_test_buff1
[0], mubuf1
, mushortbuf1
, 32 * 32);