blob: 7d9a3a434dc203856216090ae7a64a04c41c5553 [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>
12#include <string>
13
14#include "testing/gtest/include/gtest/gtest.h"
15#include "webrtc/base/scoped_ptr.h"
16#include "webrtc/test/frame_generator.h"
17#include "webrtc/test/testsupport/fileutils.h"
18
19namespace webrtc {
20namespace test {
21
22static const int kFrameWidth = 4;
23static const int kFrameHeight = 4;
24
25class FrameGeneratorTest : public ::testing::Test {
26 public:
27 void SetUp() override {
28 two_frame_filename_ =
29 test::TempFilename(test::OutputPath(), "2_frame_yuv_file");
30 one_frame_filename_ =
31 test::TempFilename(test::OutputPath(), "1_frame_yuv_file");
32
33 FILE* file = fopen(two_frame_filename_.c_str(), "wb");
34 WriteYuvFile(file, 0, 0, 0);
35 WriteYuvFile(file, 127, 127, 127);
36 fclose(file);
37 file = fopen(one_frame_filename_.c_str(), "wb");
38 WriteYuvFile(file, 255, 255, 255);
39 fclose(file);
40 }
41 void TearDown() override {
42 remove(one_frame_filename_.c_str());
43 remove(two_frame_filename_.c_str());
44 }
45
46 protected:
47 void WriteYuvFile(FILE* file, uint8_t y, uint8_t u, uint8_t v) {
48 assert(file);
49 rtc::scoped_ptr<uint8_t[]> plane_buffer(new uint8_t[y_size]);
50 memset(plane_buffer.get(), y, y_size);
51 fwrite(plane_buffer.get(), 1, y_size, file);
52 memset(plane_buffer.get(), u, uv_size);
53 fwrite(plane_buffer.get(), 1, uv_size, file);
54 memset(plane_buffer.get(), v, uv_size);
55 fwrite(plane_buffer.get(), 1, uv_size, file);
56 }
57
58 void CheckFrameAndMutate(I420VideoFrame* frame,
59 uint8_t y,
60 uint8_t u,
61 uint8_t v) {
62 // Check that frame is valid, has the correct color and timestamp are clean.
63 ASSERT_NE(nullptr, frame);
64 uint8_t* buffer;
65 ASSERT_EQ(y_size, frame->allocated_size(PlaneType::kYPlane));
66 buffer = frame->buffer(PlaneType::kYPlane);
67 for (int i = 0; i < y_size; ++i)
68 ASSERT_EQ(y, buffer[i]);
69 ASSERT_EQ(uv_size, frame->allocated_size(PlaneType::kUPlane));
70 buffer = frame->buffer(PlaneType::kUPlane);
71 for (int i = 0; i < uv_size; ++i)
72 ASSERT_EQ(u, buffer[i]);
73 ASSERT_EQ(uv_size, frame->allocated_size(PlaneType::kVPlane));
74 buffer = frame->buffer(PlaneType::kVPlane);
75 for (int i = 0; i < uv_size; ++i)
76 ASSERT_EQ(v, buffer[i]);
77 EXPECT_EQ(0, frame->ntp_time_ms());
78 EXPECT_EQ(0, frame->render_time_ms());
79 EXPECT_EQ(0u, frame->timestamp());
80
81 // Mutate to something arbitrary non-zero.
82 frame->set_ntp_time_ms(11);
83 frame->set_render_time_ms(12);
84 frame->set_timestamp(13);
85 }
86
87 std::string two_frame_filename_;
88 std::string one_frame_filename_;
89 const int y_size = kFrameWidth * kFrameHeight;
90 const int uv_size = ((kFrameHeight + 1) / 2) * ((kFrameWidth + 1) / 2);
91};
92
93TEST_F(FrameGeneratorTest, SingleFrameFile) {
94 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
95 std::vector<std::string>(1, one_frame_filename_), kFrameWidth,
96 kFrameHeight, 1));
97 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
98 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
99}
100
101TEST_F(FrameGeneratorTest, TwoFrameFile) {
102 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
103 std::vector<std::string>(1, two_frame_filename_), kFrameWidth,
104 kFrameHeight, 1));
105 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
106 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
107 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
108}
109
110TEST_F(FrameGeneratorTest, MultipleFrameFiles) {
111 std::vector<std::string> files;
112 files.push_back(two_frame_filename_);
113 files.push_back(one_frame_filename_);
114
115 rtc::scoped_ptr<FrameGenerator> generator(
116 FrameGenerator::CreateFromYuvFile(files, kFrameWidth, kFrameHeight, 1));
117 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
118 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
119 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
120 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
121}
122
123TEST_F(FrameGeneratorTest, TwoFrameFileWithRepeat) {
124 const int kRepeatCount = 3;
125 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
126 std::vector<std::string>(1, two_frame_filename_), kFrameWidth,
127 kFrameHeight, kRepeatCount));
128 for (int i = 0; i < kRepeatCount; ++i)
129 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
130 for (int i = 0; i < kRepeatCount; ++i)
131 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
132 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
133}
134
135TEST_F(FrameGeneratorTest, MultipleFrameFilesWithRepeat) {
136 const int kRepeatCount = 3;
137 std::vector<std::string> files;
138 files.push_back(two_frame_filename_);
139 files.push_back(one_frame_filename_);
140 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile(
141 files, kFrameWidth, kFrameHeight, kRepeatCount));
142 for (int i = 0; i < kRepeatCount; ++i)
143 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
144 for (int i = 0; i < kRepeatCount; ++i)
145 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127);
146 for (int i = 0; i < kRepeatCount; ++i)
147 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255);
148 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0);
149}
150
151} // namespace test
152} // namespace webrtc