1 /* 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 19 namespace webrtc { 20 namespace test { 21 22 static const int kFrameWidth = 4; 23 static const int kFrameHeight = 4; 24 25 class FrameGeneratorTest : public ::testing::Test { 26 public: SetUp()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 } TearDown()41 void TearDown() override { 42 remove(one_frame_filename_.c_str()); 43 remove(two_frame_filename_.c_str()); 44 } 45 46 protected: WriteYuvFile(FILE * file,uint8_t y,uint8_t u,uint8_t v)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 CheckFrameAndMutate(VideoFrame * frame,uint8_t y,uint8_t u,uint8_t v)58 void CheckFrameAndMutate(VideoFrame* frame, uint8_t y, uint8_t u, uint8_t v) { 59 // Check that frame is valid, has the correct color and timestamp are clean. 60 ASSERT_NE(nullptr, frame); 61 uint8_t* buffer; 62 ASSERT_EQ(y_size, frame->allocated_size(PlaneType::kYPlane)); 63 buffer = frame->buffer(PlaneType::kYPlane); 64 for (int i = 0; i < y_size; ++i) 65 ASSERT_EQ(y, buffer[i]); 66 ASSERT_EQ(uv_size, frame->allocated_size(PlaneType::kUPlane)); 67 buffer = frame->buffer(PlaneType::kUPlane); 68 for (int i = 0; i < uv_size; ++i) 69 ASSERT_EQ(u, buffer[i]); 70 ASSERT_EQ(uv_size, frame->allocated_size(PlaneType::kVPlane)); 71 buffer = frame->buffer(PlaneType::kVPlane); 72 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); 80 frame->set_render_time_ms(12); 81 frame->set_timestamp(13); 82 } 83 84 std::string two_frame_filename_; 85 std::string one_frame_filename_; 86 const int y_size = kFrameWidth * kFrameHeight; 87 const int uv_size = ((kFrameHeight + 1) / 2) * ((kFrameWidth + 1) / 2); 88 }; 89 TEST_F(FrameGeneratorTest,SingleFrameFile)90 TEST_F(FrameGeneratorTest, SingleFrameFile) { 91 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile( 92 std::vector<std::string>(1, one_frame_filename_), kFrameWidth, 93 kFrameHeight, 1)); 94 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255); 95 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255); 96 } 97 TEST_F(FrameGeneratorTest,TwoFrameFile)98 TEST_F(FrameGeneratorTest, TwoFrameFile) { 99 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile( 100 std::vector<std::string>(1, two_frame_filename_), kFrameWidth, 101 kFrameHeight, 1)); 102 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 103 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127); 104 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 105 } 106 TEST_F(FrameGeneratorTest,MultipleFrameFiles)107 TEST_F(FrameGeneratorTest, MultipleFrameFiles) { 108 std::vector<std::string> files; 109 files.push_back(two_frame_filename_); 110 files.push_back(one_frame_filename_); 111 112 rtc::scoped_ptr<FrameGenerator> generator( 113 FrameGenerator::CreateFromYuvFile(files, kFrameWidth, kFrameHeight, 1)); 114 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 115 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127); 116 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255); 117 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 118 } 119 TEST_F(FrameGeneratorTest,TwoFrameFileWithRepeat)120 TEST_F(FrameGeneratorTest, TwoFrameFileWithRepeat) { 121 const int kRepeatCount = 3; 122 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile( 123 std::vector<std::string>(1, two_frame_filename_), kFrameWidth, 124 kFrameHeight, kRepeatCount)); 125 for (int i = 0; i < kRepeatCount; ++i) 126 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 127 for (int i = 0; i < kRepeatCount; ++i) 128 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127); 129 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 130 } 131 TEST_F(FrameGeneratorTest,MultipleFrameFilesWithRepeat)132 TEST_F(FrameGeneratorTest, MultipleFrameFilesWithRepeat) { 133 const int kRepeatCount = 3; 134 std::vector<std::string> files; 135 files.push_back(two_frame_filename_); 136 files.push_back(one_frame_filename_); 137 rtc::scoped_ptr<FrameGenerator> generator(FrameGenerator::CreateFromYuvFile( 138 files, kFrameWidth, kFrameHeight, kRepeatCount)); 139 for (int i = 0; i < kRepeatCount; ++i) 140 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 141 for (int i = 0; i < kRepeatCount; ++i) 142 CheckFrameAndMutate(generator->NextFrame(), 127, 127, 127); 143 for (int i = 0; i < kRepeatCount; ++i) 144 CheckFrameAndMutate(generator->NextFrame(), 255, 255, 255); 145 CheckFrameAndMutate(generator->NextFrame(), 0, 0, 0); 146 } 147 148 } // namespace test 149 } // namespace webrtc 150