198 lines
6.6 KiB
C++
198 lines
6.6 KiB
C++
// Copyright 2020 The libgav1 Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "tests/utils.h"
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "absl/strings/string_view.h"
|
|
#include "absl/time/time.h"
|
|
#include "gtest/gtest.h"
|
|
#include "src/dsp/dsp.h"
|
|
#include "src/gav1/decoder_buffer.h"
|
|
#include "src/utils/constants.h"
|
|
#include "tests/third_party/libvpx/md5_helper.h"
|
|
|
|
namespace libgav1 {
|
|
namespace test_utils {
|
|
namespace {
|
|
|
|
int CloseFile(FILE* stream) { return fclose(stream); }
|
|
|
|
bool ReadFileToString(absl::string_view file_name, std::string* const string) {
|
|
using FilePtr = std::unique_ptr<FILE, decltype(&CloseFile)>;
|
|
FilePtr file(fopen(std::string(file_name).c_str(), "rb"), &CloseFile);
|
|
if (file == nullptr) return false;
|
|
|
|
do {
|
|
int c = fgetc(file.get());
|
|
if (ferror(file.get()) != 0) return false;
|
|
|
|
if (c != EOF) {
|
|
string->append(1, static_cast<char>(c));
|
|
} else {
|
|
break;
|
|
}
|
|
} while (true);
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void ResetDspTable(const int bitdepth) {
|
|
dsp::Dsp* const dsp = dsp_internal::GetWritableDspTable(bitdepth);
|
|
ASSERT_NE(dsp, nullptr);
|
|
memset(dsp, 0, sizeof(dsp::Dsp));
|
|
}
|
|
|
|
std::string GetMd5Sum(const void* bytes, size_t size) {
|
|
libvpx_test::MD5 md5;
|
|
md5.Add(static_cast<const uint8_t*>(bytes), size);
|
|
return md5.Get();
|
|
}
|
|
|
|
template <typename Pixel>
|
|
std::string GetMd5Sum(const Pixel* block, int width, int height, int stride) {
|
|
libvpx_test::MD5 md5;
|
|
const Pixel* row = block;
|
|
for (int i = 0; i < height; ++i) {
|
|
md5.Add(reinterpret_cast<const uint8_t*>(row), width * sizeof(Pixel));
|
|
row += stride;
|
|
}
|
|
return md5.Get();
|
|
}
|
|
|
|
template std::string GetMd5Sum(const int8_t* block, int width, int height,
|
|
int stride);
|
|
template std::string GetMd5Sum(const int16_t* block, int width, int height,
|
|
int stride);
|
|
|
|
std::string GetMd5Sum(const DecoderBuffer& buffer) {
|
|
libvpx_test::MD5 md5;
|
|
const size_t pixel_size =
|
|
(buffer.bitdepth == 8) ? sizeof(uint8_t) : sizeof(uint16_t);
|
|
for (int plane = kPlaneY; plane < buffer.NumPlanes(); ++plane) {
|
|
const int height = buffer.displayed_height[plane];
|
|
const size_t width = buffer.displayed_width[plane] * pixel_size;
|
|
const int stride = buffer.stride[plane];
|
|
const uint8_t* plane_buffer = buffer.plane[plane];
|
|
for (int row = 0; row < height; ++row) {
|
|
md5.Add(plane_buffer, width);
|
|
plane_buffer += stride;
|
|
}
|
|
}
|
|
return md5.Get();
|
|
}
|
|
|
|
void CheckMd5Digest(const char name[], const char function_name[],
|
|
const char expected_digest[], const void* data, size_t size,
|
|
absl::Duration elapsed_time) {
|
|
const std::string digest = test_utils::GetMd5Sum(data, size);
|
|
printf("Mode %s[%31s]: %5d us MD5: %s\n", name, function_name,
|
|
static_cast<int>(absl::ToInt64Microseconds(elapsed_time)),
|
|
digest.c_str());
|
|
EXPECT_STREQ(expected_digest, digest.c_str());
|
|
}
|
|
|
|
template <typename Pixel>
|
|
void CheckMd5Digest(const char name[], const char function_name[],
|
|
const char expected_digest[], const Pixel* block, int width,
|
|
int height, int stride, absl::Duration elapsed_time) {
|
|
const std::string digest =
|
|
test_utils::GetMd5Sum(block, width, height, stride);
|
|
printf("Mode %s[%31s]: %5d us MD5: %s\n", name, function_name,
|
|
static_cast<int>(absl::ToInt64Microseconds(elapsed_time)),
|
|
digest.c_str());
|
|
EXPECT_STREQ(expected_digest, digest.c_str());
|
|
}
|
|
|
|
template void CheckMd5Digest(const char name[], const char function_name[],
|
|
const char expected_digest[], const int8_t* block,
|
|
int width, int height, int stride,
|
|
absl::Duration elapsed_time);
|
|
template void CheckMd5Digest(const char name[], const char function_name[],
|
|
const char expected_digest[], const int16_t* block,
|
|
int width, int height, int stride,
|
|
absl::Duration elapsed_time);
|
|
|
|
void CheckMd5Digest(const char name[], const char function_name[],
|
|
const char expected_digest[], const char actual_digest[],
|
|
absl::Duration elapsed_time) {
|
|
printf("Mode %s[%31s]: %5d us MD5: %s\n", name, function_name,
|
|
static_cast<int>(absl::ToInt64Microseconds(elapsed_time)),
|
|
actual_digest);
|
|
EXPECT_STREQ(expected_digest, actual_digest);
|
|
}
|
|
|
|
namespace {
|
|
|
|
std::string GetSourceDir() {
|
|
#if defined(__ANDROID__)
|
|
// Test files must be manually supplied. This path is frequently
|
|
// available on development devices.
|
|
return std::string("/data/local/tmp/tests/data");
|
|
#elif defined(LIBGAV1_FLAGS_SRCDIR)
|
|
return std::string(LIBGAV1_FLAGS_SRCDIR) + "/tests/data";
|
|
#else
|
|
return std::string(".");
|
|
#endif // defined(__ANDROID__)
|
|
}
|
|
|
|
std::string GetTempDir() {
|
|
const char* path = getenv("TMPDIR");
|
|
if (path == nullptr || path[0] == '\0') path = getenv("TEMP");
|
|
if (path != nullptr && path[0] != '\0') return std::string(path);
|
|
|
|
#if defined(__ANDROID__)
|
|
return std::string("/data/local/tmp");
|
|
#elif defined(LIBGAV1_FLAGS_TMPDIR)
|
|
return std::string(LIBGAV1_FLAGS_TMPDIR);
|
|
#else
|
|
return std::string(".");
|
|
#endif // defined(__ANDROID__)
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::string GetTestInputFilePath(absl::string_view file_name) {
|
|
const char* const path = getenv("LIBGAV1_TEST_DATA_PATH");
|
|
if (path != nullptr && path[0] != '\0') {
|
|
return std::string(path) + "/" + std::string(file_name);
|
|
}
|
|
return GetSourceDir() + "/" + std::string(file_name);
|
|
}
|
|
|
|
std::string GetTestOutputFilePath(absl::string_view file_name) {
|
|
return GetTempDir() + "/" + std::string(file_name);
|
|
}
|
|
|
|
void GetTestData(absl::string_view file_name, const bool is_output_file,
|
|
std::string* const output) {
|
|
ASSERT_NE(output, nullptr);
|
|
const std::string absolute_file_path = is_output_file
|
|
? GetTestOutputFilePath(file_name)
|
|
: GetTestInputFilePath(file_name);
|
|
|
|
ASSERT_TRUE(ReadFileToString(absolute_file_path, output));
|
|
}
|
|
|
|
} // namespace test_utils
|
|
} // namespace libgav1
|