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