blob: 72182de109685b0d933ae0c449eae9568f36d65f [file] [log] [blame]
Ronald S. Bultjea742a732012-06-25 09:58:09 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Ronald S. Bultjea742a732012-06-25 09:58:09 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Johann123e8a62017-12-28 14:40:49 -080010 */
Ronald S. Bultjea742a732012-06-25 09:58:09 -070011
Daniel Kang26641c72012-06-28 16:26:31 -070012#include <math.h>
13#include <stdlib.h>
14#include <string.h>
15
Tom Finegan7a07ece2017-02-07 17:14:05 -080016#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
Daniel Kang26641c72012-06-28 16:26:31 -070017
Jingning Han097d59c2015-07-29 14:51:36 -070018#include "test/acm_random.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070019#include "aom/aom_integer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020#include "aom_dsp/bitreader.h"
21#include "aom_dsp/bitwriter.h"
Ronald S. Bultjea742a732012-06-25 09:58:09 -070022
Yaowu Xuc27fc142016-08-22 16:08:15 -070023using libaom_test::ACMRandom;
Daniel Kang26641c72012-06-28 16:26:31 -070024
Ronald S. Bultjea742a732012-06-25 09:58:09 -070025namespace {
26const int num_tests = 10;
Ronald S. Bultjea742a732012-06-25 09:58:09 -070027} // namespace
28
Yaowu Xuf883b422016-08-30 14:01:10 -070029TEST(AV1, TestBitIO) {
Ronald S. Bultjea742a732012-06-25 09:58:09 -070030 ACMRandom rnd(ACMRandom::DeterministicSeed());
31 for (int n = 0; n < num_tests; ++n) {
clang-format3a826f12016-08-11 17:46:05 -070032 for (int method = 0; method <= 7; ++method) { // we generate various proba
Yaowu Xuafffa3d2013-09-05 08:45:56 -070033 const int kBitsToTest = 1000;
34 uint8_t probas[kBitsToTest];
Ronald S. Bultjea742a732012-06-25 09:58:09 -070035
Yaowu Xuafffa3d2013-09-05 08:45:56 -070036 for (int i = 0; i < kBitsToTest; ++i) {
Ronald S. Bultjea742a732012-06-25 09:58:09 -070037 const int parity = i & 1;
clang-format3a826f12016-08-11 17:46:05 -070038 /* clang-format off */
Ronald S. Bultjea742a732012-06-25 09:58:09 -070039 probas[i] =
John Koleszarc6b90392012-07-13 15:21:29 -070040 (method == 0) ? 0 : (method == 1) ? 255 :
41 (method == 2) ? 128 :
42 (method == 3) ? rnd.Rand8() :
43 (method == 4) ? (parity ? 0 : 255) :
Ronald S. Bultjea742a732012-06-25 09:58:09 -070044 // alternate between low and high proba:
45 (method == 5) ? (parity ? rnd(128) : 255 - rnd(128)) :
46 (method == 6) ?
John Koleszarc6b90392012-07-13 15:21:29 -070047 (parity ? rnd(64) : 255 - rnd(64)) :
48 (parity ? rnd(32) : 255 - rnd(32));
clang-format3a826f12016-08-11 17:46:05 -070049 /* clang-format on */
Ronald S. Bultjea742a732012-06-25 09:58:09 -070050 }
51 for (int bit_method = 0; bit_method <= 3; ++bit_method) {
52 const int random_seed = 6432;
Yaowu Xuafffa3d2013-09-05 08:45:56 -070053 const int kBufferSize = 10000;
Ronald S. Bultjea742a732012-06-25 09:58:09 -070054 ACMRandom bit_rnd(random_seed);
Yaowu Xuf883b422016-08-30 14:01:10 -070055 aom_writer bw;
Yaowu Xuafffa3d2013-09-05 08:45:56 -070056 uint8_t bw_buffer[kBufferSize];
Yaowu Xuf883b422016-08-30 14:01:10 -070057 aom_start_encode(&bw, bw_buffer);
Ronald S. Bultjea742a732012-06-25 09:58:09 -070058
59 int bit = (bit_method == 0) ? 0 : (bit_method == 1) ? 1 : 0;
Yaowu Xuafffa3d2013-09-05 08:45:56 -070060 for (int i = 0; i < kBitsToTest; ++i) {
Ronald S. Bultjea742a732012-06-25 09:58:09 -070061 if (bit_method == 2) {
62 bit = (i & 1);
63 } else if (bit_method == 3) {
64 bit = bit_rnd(2);
65 }
Yaowu Xuf883b422016-08-30 14:01:10 -070066 aom_write(&bw, bit, static_cast<int>(probas[i]));
Ronald S. Bultjea742a732012-06-25 09:58:09 -070067 }
68
Yaowu Xuf883b422016-08-30 14:01:10 -070069 aom_stop_encode(&bw);
Ronald S. Bultjea742a732012-06-25 09:58:09 -070070
Yaowu Xuf883b422016-08-30 14:01:10 -070071 aom_reader br;
Sebastien Alaiwan2b1ec182017-12-21 09:38:27 +010072 aom_reader_init(&br, bw_buffer, bw.pos);
Ronald S. Bultjea742a732012-06-25 09:58:09 -070073 bit_rnd.Reset(random_seed);
Yaowu Xuafffa3d2013-09-05 08:45:56 -070074 for (int i = 0; i < kBitsToTest; ++i) {
Ronald S. Bultjea742a732012-06-25 09:58:09 -070075 if (bit_method == 2) {
76 bit = (i & 1);
77 } else if (bit_method == 3) {
78 bit = bit_rnd(2);
79 }
Michael Bebenita6048d052016-08-25 14:40:54 -070080 GTEST_ASSERT_EQ(aom_read(&br, probas[i], NULL), bit)
Yaowu Xuafffa3d2013-09-05 08:45:56 -070081 << "pos: " << i << " / " << kBitsToTest
clang-format3a826f12016-08-11 17:46:05 -070082 << " bit_method: " << bit_method << " method: " << method;
Ronald S. Bultjea742a732012-06-25 09:58:09 -070083 }
84 }
85 }
86 }
87}
Michael Bebenitad7baf452016-08-25 11:27:56 -070088
Angie Chiangde849bd2017-12-20 16:59:30 -080089#define FRAC_DIFF_TOTAL_ERROR 0.18
Michael Bebenitad7baf452016-08-25 11:27:56 -070090
91TEST(AV1, TestTell) {
92 const int kBufferSize = 10000;
93 aom_writer bw;
94 uint8_t bw_buffer[kBufferSize];
95 const int kSymbols = 1024;
96 // Coders are noisier at low probabilities, so we start at p = 4.
Yushin Cho3e4fcb42016-11-04 15:39:55 -070097 for (int p = 4; p < 256; p++) {
Michael Bebenitad7baf452016-08-25 11:27:56 -070098 double probability = p / 256.;
99 aom_start_encode(&bw, bw_buffer);
100 for (int i = 0; i < kSymbols; i++) {
101 aom_write(&bw, 0, p);
102 }
103 aom_stop_encode(&bw);
104 aom_reader br;
Sebastien Alaiwan2b1ec182017-12-21 09:38:27 +0100105 aom_reader_init(&br, bw_buffer, bw.pos);
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400106 uint32_t last_tell = aom_reader_tell(&br);
107 uint32_t last_tell_frac = aom_reader_tell_frac(&br);
Michael Bebenitad7baf452016-08-25 11:27:56 -0700108 double frac_diff_total = 0;
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400109 GTEST_ASSERT_GE(aom_reader_tell(&br), 0u);
110 GTEST_ASSERT_LE(aom_reader_tell(&br), 1u);
Michael Bebenitad7baf452016-08-25 11:27:56 -0700111 for (int i = 0; i < kSymbols; i++) {
Michael Bebenita6048d052016-08-25 14:40:54 -0700112 aom_read(&br, p, NULL);
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400113 uint32_t tell = aom_reader_tell(&br);
114 uint32_t tell_frac = aom_reader_tell_frac(&br);
clang-format4eafefe2017-09-04 12:51:20 -0700115 GTEST_ASSERT_GE(tell, last_tell)
116 << "tell: " << tell << ", last_tell: " << last_tell;
Michael Bebenitad7baf452016-08-25 11:27:56 -0700117 GTEST_ASSERT_GE(tell_frac, last_tell_frac)
118 << "tell_frac: " << tell_frac
119 << ", last_tell_frac: " << last_tell_frac;
120 // Frac tell should round up to tell.
121 GTEST_ASSERT_EQ(tell, (tell_frac + 7) >> 3);
122 last_tell = tell;
123 frac_diff_total +=
124 fabs(((tell_frac - last_tell_frac) / 8.0) + log2(probability));
125 last_tell_frac = tell_frac;
126 }
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400127 const uint32_t expected = (uint32_t)(-kSymbols * log2(probability));
Michael Bebenitad7baf452016-08-25 11:27:56 -0700128 // Last tell should be close to the expected value.
Peter de Rivazf9948552016-10-20 16:21:20 +0100129 GTEST_ASSERT_LE(last_tell, expected + 20) << " last_tell: " << last_tell;
Michael Bebenitad7baf452016-08-25 11:27:56 -0700130 // The average frac_diff error should be pretty small.
131 GTEST_ASSERT_LE(frac_diff_total / kSymbols, FRAC_DIFF_TOTAL_ERROR)
132 << " frac_diff_total: " << frac_diff_total;
133 }
134}