Source code

Revision control

Copy as Markdown

Other Tools

/*
* Copyright 2025 The WebRTC project authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "video/corruption_detection/evaluation/utils.h"
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "api/scoped_refptr.h"
#include "api/video/i420_buffer.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"
#include "test/testsupport/frame_reader.h"
namespace webrtc {
namespace {
using ::testing::HasSubstr;
using ::testing::Not;
// Dimension for the test frames.
constexpr int kWidth = 4;
constexpr int kHeight = 4;
constexpr int kChromaWidth = 2;
constexpr int kChromaHeight = 2;
constexpr int kFrameRate = 30;
// An arbitrary 4x4 raw YUV420 frame.
constexpr uint8_t kFrameYContent[kWidth * kHeight] = {
12, 5, 7, 11, //
159, 15, 11, 0, //
4, 240, 131, 59, //
61, 87, 11, 0 //
};
constexpr uint8_t kFrameUContent[kChromaWidth * kChromaHeight] = {
248, 184, //
139, 229 //
};
constexpr uint8_t kFrameVContent[kChromaWidth * kChromaHeight] = {
32, 69, //
7, 193 //
};
// Concatenates and returns Y, U and V content into a single vector.
std::vector<uint8_t> ConcatenateVideoChannels() {
std::vector<uint8_t> file_content_flattened;
file_content_flattened.insert(file_content_flattened.end(), kFrameYContent,
kFrameYContent + kWidth * kHeight);
file_content_flattened.insert(file_content_flattened.end(), kFrameUContent,
kFrameUContent + kChromaWidth * kChromaHeight);
file_content_flattened.insert(file_content_flattened.end(), kFrameVContent,
kFrameVContent + kChromaWidth * kChromaHeight);
return file_content_flattened;
}
TEST(TempY4mFileCreatorTest, CheckIfY4mFileIsCreated) {
std::vector<uint8_t> file_content_flattened = ConcatenateVideoChannels();
TempY4mFileCreator temp_y4m_file_creator(kWidth, kHeight, kFrameRate);
temp_y4m_file_creator.CreateTempY4mFile(file_content_flattened);
EXPECT_TRUE(test::FileExists(temp_y4m_file_creator.y4m_filepath()));
}
TEST(TempY4mFileCreatorTest, CanCreateMultipleFiles) {
std::vector<uint8_t> file_content_flattened = ConcatenateVideoChannels();
TempY4mFileCreator temp_y4m_file_creator_1(kWidth, kHeight, kFrameRate);
TempY4mFileCreator temp_y4m_file_creator_2(kWidth, kHeight, kFrameRate);
temp_y4m_file_creator_1.CreateTempY4mFile(file_content_flattened);
temp_y4m_file_creator_2.CreateTempY4mFile(file_content_flattened);
// Check that the files are created.
ASSERT_TRUE(test::FileExists(temp_y4m_file_creator_1.y4m_filepath()));
ASSERT_TRUE(test::FileExists(temp_y4m_file_creator_2.y4m_filepath()));
// Check that the created files have different paths.
EXPECT_THAT(temp_y4m_file_creator_1.y4m_filepath(),
Not(temp_y4m_file_creator_2.y4m_filepath()));
}
TEST(TempY4mFileCreatorTest, CheckIfY4mFileHasCorrectContent) {
std::vector<uint8_t> file_content_flattened = ConcatenateVideoChannels();
TempY4mFileCreator temp_y4m_file_creator(kWidth, kHeight, kFrameRate);
temp_y4m_file_creator.CreateTempY4mFile(file_content_flattened);
std::unique_ptr<test::FrameReader> frame_generator =
CreateY4mFrameReader(std::string(temp_y4m_file_creator.y4m_filepath()),
test::YuvFrameReaderImpl::RepeatMode::kSingle);
scoped_refptr<I420Buffer> i420_buffer = frame_generator->PullFrame();
ASSERT_EQ(i420_buffer->width(), kWidth);
ASSERT_EQ(i420_buffer->height(), kHeight);
for (int i = 0; i < kWidth * kHeight; ++i) {
EXPECT_EQ(i420_buffer->DataY()[i], kFrameYContent[i]);
}
for (int i = 0; i < kChromaWidth * kChromaHeight; ++i) {
EXPECT_EQ(i420_buffer->DataU()[i], kFrameUContent[i]);
EXPECT_EQ(i420_buffer->DataV()[i], kFrameVContent[i]);
}
// No more frames.
EXPECT_THAT(frame_generator->PullFrame(), nullptr);
}
#if GTEST_HAS_DEATH_TEST
TEST(TempY4mFileCreatorTest, ContentEndInMiddleError) {
std::vector<uint8_t> file_content_flattened = ConcatenateVideoChannels();
std::vector<uint8_t> only_luma_content(
file_content_flattened.begin(),
file_content_flattened.begin() + kWidth * kHeight);
TempY4mFileCreator temp_y4m_file_creator(kWidth, kHeight, kFrameRate);
EXPECT_DEATH(temp_y4m_file_creator.CreateTempY4mFile(only_luma_content),
HasSubstr("Content size is not a multiple of frame size."));
}
#endif // GTEST_HAS_DEATH_TEST
TEST(ReadMetadataFromY4mHeaderTest, ReadMetadataFromY4mHeader) {
std::vector<uint8_t> file_content_flattened = ConcatenateVideoChannels();
TempY4mFileCreator temp_y4m_file_creator(kWidth, kHeight, kFrameRate);
temp_y4m_file_creator.CreateTempY4mFile(file_content_flattened);
Y4mMetadata y4m_metadata =
ReadMetadataFromY4mHeader(temp_y4m_file_creator.y4m_filepath());
EXPECT_EQ(y4m_metadata.width, kWidth);
EXPECT_EQ(y4m_metadata.height, kHeight);
EXPECT_EQ(y4m_metadata.framerate, kFrameRate);
}
} // namespace
} // namespace webrtc