/* * 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 #include #include #include #include #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(res.width), kNewWidth); EXPECT_EQ(static_cast(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 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 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 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