Source code

Revision control

Copy as Markdown

Other Tools

/*
* Copyright (c) 2023 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 "test/testsupport/y4m_frame_generator.h"
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"
namespace webrtc {
namespace test {
class Y4mFrameGeneratorTest : public testing::Test {
protected:
Y4mFrameGeneratorTest() = default;
~Y4mFrameGeneratorTest() = default;
void SetUp() {
input_filepath_ = TempFilename(OutputPath(), "2x2.y4m");
FILE* y4m_file = fopen(input_filepath_.c_str(), "wb");
// Input Y4M file: 3 YUV frames of 2x2 resolution.
std::string y4m_content =
"YUV4MPEG2 W2 H2 F2:1 C420\n"
"FRAME\n"
"123456FRAME\n"
"abcdefFRAME\n"
"987654";
std::fprintf(y4m_file, "%s", y4m_content.c_str());
fclose(y4m_file);
}
void TearDown() { remove(input_filepath_.c_str()); }
std::string input_filepath_;
};
TEST_F(Y4mFrameGeneratorTest, CanReadResolutionFromFile) {
Y4mFrameGenerator generator(input_filepath_,
Y4mFrameGenerator::RepeatMode::kSingle);
FrameGeneratorInterface::Resolution res = generator.GetResolution();
EXPECT_EQ(res.width, 2u);
EXPECT_EQ(res.height, 2u);
}
TEST_F(Y4mFrameGeneratorTest, CanReadFPSFromFile) {
Y4mFrameGenerator generator(input_filepath_,
Y4mFrameGenerator::RepeatMode::kSingle);
EXPECT_EQ(*generator.fps(), 2);
}
TEST_F(Y4mFrameGeneratorTest, CanReadFPSFromFileWhenRoundingIsNeeded) {
std::string input_filepath = TempFilename(OutputPath(), "2x2_23_FPS.y4m");
FILE* y4m_file = fopen(input_filepath.c_str(), "wb");
// Input Y4M file: 3 YUV frames of 2x2 resolution.
std::string y4m_content =
"YUV4MPEG2 W2 H2 F24000:1001 C420\n"
"FRAME\n"
"123456FRAME\n"
"abcdefFRAME\n"
"987654";
std::fprintf(y4m_file, "%s", y4m_content.c_str());
fclose(y4m_file);
Y4mFrameGenerator generator(input_filepath,
Y4mFrameGenerator::RepeatMode::kSingle);
EXPECT_EQ(generator.fps(), 23);
remove(input_filepath.c_str());
}
TEST_F(Y4mFrameGeneratorTest, CanChangeResolution) {
constexpr int kNewWidth = 4;
constexpr int kNewHeight = 6;
constexpr int kFrameCount = 10;
Y4mFrameGenerator generator(input_filepath_,
Y4mFrameGenerator::RepeatMode::kLoop);
FrameGeneratorInterface::Resolution res = generator.GetResolution();
EXPECT_EQ(res.width, 2u);
EXPECT_EQ(res.height, 2u);
generator.ChangeResolution(kNewWidth, kNewHeight);
res = generator.GetResolution();
EXPECT_EQ(static_cast<int>(res.width), kNewWidth);
EXPECT_EQ(static_cast<int>(res.height), kNewHeight);
for (int i = 0; i < kFrameCount; ++i) {
FrameGeneratorInterface::VideoFrameData frame = generator.NextFrame();
EXPECT_EQ(frame.buffer->width(), kNewWidth);
EXPECT_EQ(frame.buffer->height(), kNewHeight);
}
}
TEST_F(Y4mFrameGeneratorTest, SingleRepeatMode) {
Y4mFrameGenerator generator(input_filepath_,
Y4mFrameGenerator::RepeatMode::kSingle);
std::vector<std::string> expected_frame_ys = {"123456", "abcdef", "987654"};
for (absl::string_view frame_y : expected_frame_ys) {
EXPECT_EQ(frame_y.size(), 6u);
FrameGeneratorInterface::VideoFrameData frame = generator.NextFrame();
EXPECT_EQ(memcmp(frame_y.data(), frame.buffer->GetI420()->DataY(), 6), 0);
}
FrameGeneratorInterface::VideoFrameData frame = generator.NextFrame();
EXPECT_EQ(frame.buffer, nullptr);
}
TEST_F(Y4mFrameGeneratorTest, LoopRepeatMode) {
Y4mFrameGenerator generator(input_filepath_,
Y4mFrameGenerator::RepeatMode::kLoop);
std::vector<std::string> expected_frame_ys = {"123456", "abcdef", "987654",
"123456", "abcdef", "987654"};
for (absl::string_view frame_y : expected_frame_ys) {
EXPECT_EQ(frame_y.size(), 6u);
FrameGeneratorInterface::VideoFrameData frame = generator.NextFrame();
EXPECT_EQ(memcmp(frame_y.data(), frame.buffer->GetI420()->DataY(), 6), 0);
}
}
TEST_F(Y4mFrameGeneratorTest, PingPongRepeatMode) {
Y4mFrameGenerator generator(input_filepath_,
Y4mFrameGenerator::RepeatMode::kPingPong);
std::vector<std::string> expected_frame_ys = {
"123456", "abcdef", "987654", "abcdef", "123456", "abcdef", "987654"};
for (absl::string_view frame_y : expected_frame_ys) {
EXPECT_EQ(frame_y.size(), 6u);
FrameGeneratorInterface::VideoFrameData frame = generator.NextFrame();
EXPECT_EQ(memcmp(frame_y.data(), frame.buffer->GetI420()->DataY(), 6), 0);
}
}
} // namespace test
} // namespace webrtc