xref: /aosp_15_r20/external/libgav1/tests/utils.h (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1 /*
2  * Copyright 2020 The libgav1 Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LIBGAV1_TESTS_UTILS_H_
18 #define LIBGAV1_TESTS_UTILS_H_
19 
20 #include <cstddef>
21 #include <new>
22 #include <string>
23 
24 #include "absl/base/config.h"
25 #include "absl/strings/string_view.h"
26 #include "absl/time/time.h"
27 #include "src/gav1/decoder_buffer.h"
28 #include "src/utils/compiler_attributes.h"
29 #include "src/utils/memory.h"
30 #include "tests/third_party/libvpx/acm_random.h"
31 
32 #ifdef ABSL_HAVE_EXCEPTIONS
33 #include <exception>
34 #endif
35 
36 namespace libgav1 {
37 namespace test_utils {
38 
39 enum { kAlternateDeterministicSeed = 0x9571 };
40 static_assert(kAlternateDeterministicSeed !=
41                   libvpx_test::ACMRandom::DeterministicSeed(),
42               "");
43 
44 // Similar to libgav1::MaxAlignedAllocable, but retains the throwing versions
45 // of new to support googletest allocations.
46 // Note when building the source as C++17 or greater, gcc 11.2.0 may issue a
47 // warning of the form:
48 //   warning: 'void operator delete [](void*, std::align_val_t)' called on
49 //     pointer returned from a mismatched allocation function
50 //   note: returned from 'static void*
51 //     libgav1::test_utils::MaxAlignedAllocable::operator new [](size_t)'
52 // This is a false positive as this function calls
53 // libgav1::MaxAlignedAllocable::operator new[](size, std::nothrow) which in
54 // turn calls
55 // void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&).
56 // This is due to unbalanced inlining of the functions, so we force them to be
57 // inlined.
58 // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103993
59 struct MaxAlignedAllocable {
60   // Class-specific allocation functions.
newMaxAlignedAllocable61   static LIBGAV1_ALWAYS_INLINE void* operator new(size_t size) {
62     void* const p =
63         libgav1::MaxAlignedAllocable::operator new(size, std::nothrow);
64 #ifdef ABSL_HAVE_EXCEPTIONS
65     if (p == nullptr) throw std::bad_alloc();
66 #endif
67     return p;
68   }
69   static LIBGAV1_ALWAYS_INLINE void* operator new[](size_t size) {
70     void* const p =
71         libgav1::MaxAlignedAllocable::operator new[](size, std::nothrow);
72 #ifdef ABSL_HAVE_EXCEPTIONS
73     if (p == nullptr) throw std::bad_alloc();
74 #endif
75     return p;
76   }
77 
78   // Class-specific non-throwing allocation functions
newMaxAlignedAllocable79   static LIBGAV1_ALWAYS_INLINE void* operator new(
80       size_t size, const std::nothrow_t& tag) noexcept {
81     return libgav1::MaxAlignedAllocable::operator new(size, tag);
82   }
83   static LIBGAV1_ALWAYS_INLINE void* operator new[](
84       size_t size, const std::nothrow_t& tag) noexcept {
85     return libgav1::MaxAlignedAllocable::operator new[](size, tag);
86   }
87 
88   // Class-specific deallocation functions.
deleteMaxAlignedAllocable89   static LIBGAV1_ALWAYS_INLINE void operator delete(void* ptr) noexcept {
90     libgav1::MaxAlignedAllocable::operator delete(ptr);
91   }
92   static LIBGAV1_ALWAYS_INLINE void operator delete[](void* ptr) noexcept {
93     libgav1::MaxAlignedAllocable::operator delete[](ptr);
94   }
95 
96   // Only called if new (std::nothrow) is used and the constructor throws an
97   // exception.
deleteMaxAlignedAllocable98   static LIBGAV1_ALWAYS_INLINE void operator delete(
99       void* ptr, const std::nothrow_t& tag) noexcept {
100     libgav1::MaxAlignedAllocable::operator delete(ptr, tag);
101   }
102   // Only called if new[] (std::nothrow) is used and the constructor throws an
103   // exception.
104   static LIBGAV1_ALWAYS_INLINE void operator delete[](
105       void* ptr, const std::nothrow_t& tag) noexcept {
106     libgav1::MaxAlignedAllocable::operator delete[](ptr, tag);
107   }
108 };
109 
110 // Clears dsp table entries for |bitdepth|. This function is not thread safe.
111 void ResetDspTable(int bitdepth);
112 
113 //------------------------------------------------------------------------------
114 // Gets human readable hexadecimal encoded MD5 sum from given data, block, or
115 // frame buffer.
116 
117 std::string GetMd5Sum(const void* bytes, size_t size);
118 template <typename Pixel>
119 std::string GetMd5Sum(const Pixel* block, int width, int height, int stride);
120 std::string GetMd5Sum(const DecoderBuffer& buffer);
121 
122 //------------------------------------------------------------------------------
123 // Compares the md5 digest of |size| bytes of |data| with |expected_digest|.
124 // Prints a log message with |name|, |function_name|, md5 digest and
125 // |elapsed_time|. |name| and |function_name| are merely tags used for logging
126 // and can be any meaningful string depending on the caller's context.
127 
128 void CheckMd5Digest(const char name[], const char function_name[],
129                     const char expected_digest[], const void* data, size_t size,
130                     absl::Duration elapsed_time);
131 
132 //------------------------------------------------------------------------------
133 // Compares the md5 digest of |block| with |expected_digest|. The width, height,
134 // and stride of |block| are |width|, |height|, and |stride|, respectively.
135 // Prints a log message with |name|, |function_name|, md5 digest and
136 // |elapsed_time|. |name| and |function_name| are merely tags used for logging
137 // and can be any meaningful string depending on the caller's context.
138 
139 template <typename Pixel>
140 void CheckMd5Digest(const char name[], const char function_name[],
141                     const char expected_digest[], const Pixel* block, int width,
142                     int height, int stride, absl::Duration elapsed_time);
143 
144 //------------------------------------------------------------------------------
145 // Compares |actual_digest| with |expected_digest|. Prints a log message with
146 // |name|, |function_name|, md5 digest and |elapsed_time|. |name| and
147 // |function_name| are merely tags used for logging and can be any meaningful
148 // string depending on the caller's context.
149 
150 void CheckMd5Digest(const char name[], const char function_name[],
151                     const char expected_digest[], const char actual_digest[],
152                     absl::Duration elapsed_time);
153 
154 //------------------------------------------------------------------------------
155 // Reads the test data from |file_name| as a string into |output|. The
156 // |is_output_file| argument controls the expansion of |file_name| to its full
157 // path. When |is_output_file| is true GetTestData() reads from
158 // utils.cc::GetTempDir(), and when it is false the file is read from
159 // utils.cc::GetSourceDir().
160 void GetTestData(absl::string_view file_name, bool is_output_file,
161                  std::string* output);
162 
163 //------------------------------------------------------------------------------
164 // Returns the full path to |file_name| from libgav1/tests/data.
165 std::string GetTestInputFilePath(absl::string_view file_name);
166 
167 //------------------------------------------------------------------------------
168 // Returns the full path to |file_name| in a location where the file can be
169 // opened for writing.
170 std::string GetTestOutputFilePath(absl::string_view file_name);
171 
172 }  // namespace test_utils
173 }  // namespace libgav1
174 
175 #endif  // LIBGAV1_TESTS_UTILS_H_
176