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