blob: ba4627dc3b884ef05b16fa95f6e3e6dac73a2060 [file] [log] [blame]
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +00001/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <stdio.h>
kwibergbfefb032016-05-01 14:53:46 -070012
13#include <memory>
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000014#include <string>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "test/frame_generator.h"
17#include "test/gtest.h"
18#include "test/testsupport/fileutils.h"
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000019
20namespace webrtc {
21namespace test {
22
23static const int kFrameWidth = 4;
24static const int kFrameHeight = 4;
25
26class FrameGeneratorTest : public ::testing::Test {
27 public:
28 void SetUp() override {
29 two_frame_filename_ =
30 test::TempFilename(test::OutputPath(), "2_frame_yuv_file");
31 one_frame_filename_ =
32 test::TempFilename(test::OutputPath(), "1_frame_yuv_file");
33
34 FILE* file = fopen(two_frame_filename_.c_str(), "wb");
35 WriteYuvFile(file, 0, 0, 0);
36 WriteYuvFile(file, 127, 127, 127);
37 fclose(file);
38 file = fopen(one_frame_filename_.c_str(), "wb");
39 WriteYuvFile(file, 255, 255, 255);
40 fclose(file);
41 }
42 void TearDown() override {
43 remove(one_frame_filename_.c_str());
44 remove(two_frame_filename_.c_str());
45 }
46
47 protected:
48 void WriteYuvFile(FILE* file, uint8_t y, uint8_t u, uint8_t v) {
49 assert(file);
kwibergbfefb032016-05-01 14:53:46 -070050 std::unique_ptr<uint8_t[]> plane_buffer(new uint8_t[y_size]);
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000051 memset(plane_buffer.get(), y, y_size);
52 fwrite(plane_buffer.get(), 1, y_size, file);
53 memset(plane_buffer.get(), u, uv_size);
54 fwrite(plane_buffer.get(), 1, uv_size, file);
55 memset(plane_buffer.get(), v, uv_size);
56 fwrite(plane_buffer.get(), 1, uv_size, file);
57 }
58
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070059 void CheckFrameAndMutate(VideoFrame* frame, uint8_t y, uint8_t u, uint8_t v) {
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000060 // Check that frame is valid, has the correct color and timestamp are clean.
61 ASSERT_NE(nullptr, frame);
Magnus Jedvert90e31902017-06-07 11:32:50 +020062 rtc::scoped_refptr<I420BufferInterface> i420_buffer =
63 frame->video_frame_buffer()->ToI420();
nissec9c142f2016-05-17 04:05:47 -070064 const uint8_t* buffer;
Magnus Jedvert90e31902017-06-07 11:32:50 +020065 buffer = i420_buffer->DataY();
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000066 for (int i = 0; i < y_size; ++i)
67 ASSERT_EQ(y, buffer[i]);
Magnus Jedvert90e31902017-06-07 11:32:50 +020068 buffer = i420_buffer->DataU();
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000069 for (int i = 0; i < uv_size; ++i)
70 ASSERT_EQ(u, buffer[i]);
Magnus Jedvert90e31902017-06-07 11:32:50 +020071 buffer = i420_buffer->DataV();
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000072 for (int i = 0; i < uv_size; ++i)
73 ASSERT_EQ(v, buffer[i]);
74 EXPECT_EQ(0, frame->ntp_time_ms());
75 EXPECT_EQ(0, frame->render_time_ms());
76 EXPECT_EQ(0u, frame->timestamp());
77
78 // Mutate to something arbitrary non-zero.
79 frame->set_ntp_time_ms(11);
nisse1c0dea82017-01-30 02:43:18 -080080 frame->set_timestamp_us(12);
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +000081 frame->set_timestamp(13);
82 }
83
erikvarga579de6f2017-08-29 09:12:57 -070084 uint64_t Hash(VideoFrame* frame) {
85 // Generate a 64-bit hash from the frame's buffer.
86 uint64_t hash = 19;
87 rtc::scoped_refptr<I420BufferInterface> i420_buffer =
88 frame->video_frame_buffer()->ToI420();
89 const uint8_t* buffer = i420_buffer->DataY();
90 for (int i = 0; i < y_size; ++i) {
91 hash = (37 * hash) + buffer[i];
92 }
93 buffer = i420_buffer->DataU();
94 for (int i = 0; i < uv_size; ++i) {
95 hash = (37 * hash) + buffer[i];
96 }
97 buffer = i420_buffer->DataV();
98 for (int i = 0; i < uv_size; ++i) {
99 hash = (37 * hash) + buffer[i];
100 }
101 return hash;
102 }
103
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000104 std::string two_frame_filename_;
105 std::string one_frame_filename_;
106 const int y_size = kFrameWidth * kFrameHeight;
107 const int uv_size = ((kFrameHeight + 1) / 2) * ((kFrameWidth + 1) / 2);
108};
109
110TEST_F(FrameGeneratorTest, SingleFrameFile) {
kwibergbfefb032016-05-01 14:53:46 -0700111 std::unique_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000112 std::vector<std::string>(1, one_frame_filename_), kFrameWidth,
113 kFrameHeight, 1));
114 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
115 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
116}
117
118TEST_F(FrameGeneratorTest, TwoFrameFile) {
kwibergbfefb032016-05-01 14:53:46 -0700119 std::unique_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000120 std::vector<std::string>(1, two_frame_filename_), kFrameWidth,
121 kFrameHeight, 1));
122 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
123 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
124 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
125}
126
127TEST_F(FrameGeneratorTest, MultipleFrameFiles) {
128 std::vector<std::string> files;
129 files.push_back(two_frame_filename_);
130 files.push_back(one_frame_filename_);
131
kwibergbfefb032016-05-01 14:53:46 -0700132 std::unique_ptr<FrameGenerator> generator(
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000133 FrameGenerator::CreateFromYuvFile(files, kFrameWidth, kFrameHeight, 1));
134 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
135 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
136 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
137 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
138}
139
140TEST_F(FrameGeneratorTest, TwoFrameFileWithRepeat) {
141 const int kRepeatCount = 3;
kwibergbfefb032016-05-01 14:53:46 -0700142 std::unique_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000143 std::vector<std::string>(1, two_frame_filename_), kFrameWidth,
144 kFrameHeight, kRepeatCount));
145 for (int i = 0; i < kRepeatCount; ++i)
146 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
147 for (int i = 0; i < kRepeatCount; ++i)
148 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
149 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
150}
151
152TEST_F(FrameGeneratorTest, MultipleFrameFilesWithRepeat) {
153 const int kRepeatCount = 3;
154 std::vector<std::string> files;
155 files.push_back(two_frame_filename_);
156 files.push_back(one_frame_filename_);
kwibergbfefb032016-05-01 14:53:46 -0700157 std::unique_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000158 files, kFrameWidth, kFrameHeight, kRepeatCount));
159 for (int i = 0; i < kRepeatCount; ++i)
160 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
161 for (int i = 0; i < kRepeatCount; ++i)
162 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
163 for (int i = 0; i < kRepeatCount; ++i)
164 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
165 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
166}
167
erikvarga579de6f2017-08-29 09:12:57 -0700168TEST_F(FrameGeneratorTest, SlideGenerator) {
169 const int kGenCount = 9;
170 const int kRepeatCount = 3;
171 std::unique_ptr<FrameGenerator> generator(
172 FrameGenerator::CreateSlideGenerator(
173 kFrameWidth, kFrameHeight, kRepeatCount));
174 uint64_t hashes[kGenCount];
175 for (int i = 0; i < kGenCount; ++i) {
176 hashes[i] = Hash(generator->NextFrame());
177 }
178 // Check that the buffer changes only every |kRepeatCount| frames.
179 for (int i = 1; i < kGenCount; ++i) {
180 if (i % kRepeatCount == 0) {
181 EXPECT_NE(hashes[i-1], hashes[i]);
182 } else {
183 EXPECT_EQ(hashes[i-1], hashes[i]);
184 }
185 }
186}
187
sprang@webrtc.org25dd1db2015-03-02 11:55:45 +0000188} // namespace test
189} // namespace webrtc