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 int_denoise_test_buff1
[0][i
] = int_denoise_test_buff2
[0][i
] = (rand() & UNSIGNED_SHORT_MAX
) - (rand() & UNSIGNED_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 int_denoise_test_buff1
[1][i
] = int_denoise_test_buff2
[1][i
] = -UNSIGNED_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 int_denoise_test_buff1
[2][i
] = int_denoise_test_buff2
[2][i
] = UNSIGNED_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(int) * width
* width
;
101 for (int i
= 0; i
< ITERS
; i
++)
103 int index
= rand() % TEST_CASES
;
105 ref(short_test_buff
[index
] + j
, mintbuf3
, width
);
106 checked(opt
, short_test_buff
[index
] + j
, mintbuf4
, width
);
108 if (memcmp(mintbuf3
, mintbuf4
, 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(int_idct_test_buff
[index
] + j
, mshortbuf2
, width
);
128 checked(opt
, int_idct_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
, mintbuf3
, width
* height
, scale
, shift
);
160 checked(opt
, short_test_buff
[index
] + j
, mintbuf4
, width
* height
, scale
, shift
);
162 if (memcmp(mintbuf3
, mintbuf4
, sizeof(int) * height
* width
))
172 bool MBDstHarness::check_dequant_primitive(dequant_scaling_t ref
, dequant_scaling_t opt
)
176 for (int i
= 0; i
< ITERS
; i
++)
178 int log2TrSize
= (rand() % 4) + 2;
180 int width
= (1 << log2TrSize
);
183 int qp
= rand() % (QP_MAX_SPEC
+ QP_BD_OFFSET
+ 1);
185 int transformShift
= MAX_TR_DYNAMIC_RANGE
- X265_DEPTH
- log2TrSize
;
186 int shift
= QUANT_IQUANT_SHIFT
- QUANT_SHIFT
- transformShift
;
188 int cmp_size
= sizeof(int) * height
* width
;
189 int index1
= rand() % TEST_CASES
;
191 ref(short_test_buff
[index1
] + j
, mintbuf3
, mintbuf1
, width
* height
, per
, shift
);
192 checked(opt
, short_test_buff
[index1
] + j
, mintbuf4
, mintbuf2
, width
* height
, per
, shift
);
194 if (memcmp(mintbuf1
, mintbuf2
, cmp_size
))
204 bool MBDstHarness::check_quant_primitive(quant_t ref
, quant_t opt
)
208 for (int i
= 0; i
< ITERS
; i
++)
210 int width
= (rand() % 4 + 1) * 4;
213 uint32_t optReturnValue
= 0;
214 uint32_t refReturnValue
= 0;
216 int bits
= (rand() % 24) + 8;
217 int valueToAdd
= rand() % (1 << bits
);
218 int cmp_size
= sizeof(int) * height
* width
;
219 int cmp_size1
= sizeof(short) * height
* width
;
220 int numCoeff
= height
* width
;
222 int index1
= rand() % TEST_CASES
;
223 int index2
= rand() % TEST_CASES
;
225 refReturnValue
= ref(int_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mintbuf1
, mshortbuf2
, bits
, valueToAdd
, numCoeff
);
226 optReturnValue
= (uint32_t)checked(opt
, int_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mintbuf3
, mshortbuf3
, bits
, valueToAdd
, numCoeff
);
228 if (memcmp(mintbuf1
, mintbuf3
, cmp_size
))
231 if (memcmp(mshortbuf2
, mshortbuf3
, cmp_size1
))
234 if (optReturnValue
!= refReturnValue
)
244 bool MBDstHarness::check_nquant_primitive(nquant_t ref
, nquant_t opt
)
248 for (int i
= 0; i
< ITERS
; i
++)
250 int width
= (rand() % 4 + 1) * 4;
253 uint32_t optReturnValue
= 0;
254 uint32_t refReturnValue
= 0;
256 int bits
= rand() % 32;
257 int valueToAdd
= rand() % (1 << bits
);
258 int cmp_size
= sizeof(short) * height
* width
;
259 int numCoeff
= height
* width
;
261 int index1
= rand() % TEST_CASES
;
262 int index2
= rand() % TEST_CASES
;
264 refReturnValue
= ref(int_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mshortbuf2
, bits
, valueToAdd
, numCoeff
);
265 optReturnValue
= (uint32_t)checked(opt
, int_test_buff
[index1
] + j
, int_test_buff
[index2
] + j
, mshortbuf3
, bits
, valueToAdd
, numCoeff
);
267 if (memcmp(mshortbuf2
, mshortbuf3
, cmp_size
))
270 if (optReturnValue
!= refReturnValue
)
280 bool MBDstHarness::check_count_nonzero_primitive(count_nonzero_t ref
, count_nonzero_t opt
)
282 ALIGN_VAR_32(int16_t, qcoeff
[32 * 32]);
284 for (int i
= 0; i
< 4; i
++)
286 int log2TrSize
= i
+ 2;
287 int num
= 1 << (log2TrSize
* 2);
290 for (int n
= 0; n
<= num
; n
++)
292 memset(qcoeff
, 0, num
* sizeof(int16_t));
294 for (int j
= 0; j
< n
; j
++)
296 int k
= rand() & mask
;
302 qcoeff
[k
] = (int16_t)rand() - RAND_MAX
/ 2;
305 int refval
= ref(qcoeff
, num
);
306 int optval
= (int)checked(opt
, qcoeff
, num
);
308 if (refval
!= optval
)
318 bool MBDstHarness::check_denoise_dct_primitive(denoiseDct_t ref
, denoiseDct_t opt
)
322 for (int s
= 0; s
< 4; s
++)
324 int log2TrSize
= s
+ 2;
325 int num
= 1 << (log2TrSize
* 2);
326 int cmp_size
= sizeof(int) * num
;
328 for (int i
= 0; i
< ITERS
; i
++)
330 memset(mubuf1
, 0, num
* sizeof(uint32_t));
331 memset(mubuf2
, 0, num
* sizeof(uint32_t));
332 memset(mushortbuf1
, 0, num
* sizeof(uint16_t));
334 for (int k
= 0; k
< num
; k
++)
335 mushortbuf1
[k
] = rand() % UNSIGNED_SHORT_MAX
;
337 int index
= rand() % TEST_CASES
;
339 ref(int_denoise_test_buff1
[index
] + j
, mubuf1
, mushortbuf1
, num
);
340 checked(opt
, int_denoise_test_buff2
[index
] + j
, mubuf2
, mushortbuf1
, num
);
342 if (memcmp(int_denoise_test_buff1
[index
] + j
, int_denoise_test_buff2
[index
] + j
, cmp_size
))
345 if (memcmp(mubuf1
, mubuf2
, cmp_size
))
358 bool MBDstHarness::testCorrectness(const EncoderPrimitives
& ref
, const EncoderPrimitives
& opt
)
360 for (int i
= 0; i
< NUM_DCTS
; i
++)
364 if (!check_dct_primitive(ref
.dct
[i
], opt
.dct
[i
], dctInfo
[i
].width
))
366 printf("\n%s failed\n", dctInfo
[i
].name
);
372 for (int i
= 0; i
< NUM_IDCTS
; i
++)
376 if (!check_idct_primitive(ref
.idct
[i
], opt
.idct
[i
], idctInfo
[i
].width
))
378 printf("%s failed\n", idctInfo
[i
].name
);
384 if (opt
.dequant_normal
)
386 if (!check_dequant_primitive(ref
.dequant_normal
, opt
.dequant_normal
))
388 printf("dequant: Failed!\n");
393 if (opt
.dequant_scaling
)
395 if (!check_dequant_primitive(ref
.dequant_scaling
, opt
.dequant_scaling
))
397 printf("dequant_scaling: Failed!\n");
404 if (!check_quant_primitive(ref
.quant
, opt
.quant
))
406 printf("quant: Failed!\n");
413 if (!check_nquant_primitive(ref
.nquant
, opt
.nquant
))
415 printf("nquant: Failed!\n");
420 if (opt
.count_nonzero
)
422 if (!check_count_nonzero_primitive(ref
.count_nonzero
, opt
.count_nonzero
))
424 printf("count_nonzero: Failed!\n");
429 if (opt
.dequant_scaling
)
431 if (!check_dequant_primitive(ref
.dequant_scaling
, opt
.dequant_scaling
))
433 printf("dequant_scaling: Failed!\n");
440 if (!check_denoise_dct_primitive(ref
.denoiseDct
, opt
.denoiseDct
))
442 printf("denoiseDct: Failed!\n");
450 void MBDstHarness::measureSpeed(const EncoderPrimitives
& ref
, const EncoderPrimitives
& opt
)
452 for (int value
= 0; value
< NUM_DCTS
; value
++)
456 printf("%s\t", dctInfo
[value
].name
);
457 REPORT_SPEEDUP(opt
.dct
[value
], ref
.dct
[value
], mbuf1
, mintbuf3
, dctInfo
[value
].width
);
461 for (int value
= 0; value
< NUM_IDCTS
; value
++)
465 printf("%s\t", idctInfo
[value
].name
);
466 REPORT_SPEEDUP(opt
.idct
[value
], ref
.idct
[value
], mbufidct
, mshortbuf2
, idctInfo
[value
].width
);
470 if (opt
.dequant_normal
)
472 printf("dequant_normal\t");
473 REPORT_SPEEDUP(opt
.dequant_normal
, ref
.dequant_normal
, short_test_buff
[0], mintbuf3
, 32 * 32, 70, 1);
476 if (opt
.dequant_scaling
)
478 printf("dequant_scaling\t");
479 REPORT_SPEEDUP(opt
.dequant_scaling
, ref
.dequant_scaling
, short_test_buff
[0], mintbuf3
, mintbuf4
, 32 * 32, 5, 1);
485 REPORT_SPEEDUP(opt
.quant
, ref
.quant
, int_test_buff
[0], int_test_buff
[1], mintbuf3
, mshortbuf2
, 23, 23785, 32 * 32);
490 printf("nquant\t\t");
491 REPORT_SPEEDUP(opt
.nquant
, ref
.nquant
, int_test_buff
[0], int_test_buff
[1], mshortbuf2
, 23, 23785, 32 * 32);
494 if (opt
.count_nonzero
)
496 for (int i
= 4; i
<= 32; i
<<= 1)
498 printf("count_nonzero[%dx%d]", i
, i
);
499 REPORT_SPEEDUP(opt
.count_nonzero
, ref
.count_nonzero
, mbuf1
, i
* i
)
505 printf("denoiseDct\t");
506 REPORT_SPEEDUP(opt
.denoiseDct
, ref
.denoiseDct
, int_denoise_test_buff1
[0], mubuf1
, mushortbuf1
, 32 * 32);