1 /* 2 * Copyright (c) 2012 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 <stdlib.h> 13 14 #include <fstream> 15 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 18 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 19 #include "webrtc/test/testsupport/fileutils.h" 20 #include "webrtc/tools/frame_editing/frame_editing_lib.h" 21 22 namespace webrtc { 23 namespace test { 24 25 const int kWidth = 352; 26 const int kHeight = 288; 27 const int kFrameSize = CalcBufferSize(kI420, kWidth, kHeight); 28 29 class FrameEditingTest : public ::testing::Test { 30 protected: 31 virtual void SetUp() { 32 reference_video_ = ResourcePath("foreman_cif", "yuv"); 33 test_video_ = OutputPath() + "testvideo.yuv"; 34 35 original_fid_ = fopen(reference_video_.c_str(), "rb"); 36 ASSERT_TRUE(original_fid_ != NULL); 37 38 // Ensure the output file exists on disk. 39 std::ofstream(test_video_.c_str(), std::ios::out); 40 // Open the output file for reading. 41 // TODO(holmer): Figure out why this file has to be opened here (test fails 42 // if it's opened after the write operation performed in EditFrames). 43 edited_fid_ = fopen(test_video_.c_str(), "rb"); 44 ASSERT_TRUE(edited_fid_ != NULL); 45 46 original_buffer_.reset(new int[kFrameSize]); 47 edited_buffer_.reset(new int[kFrameSize]); 48 num_frames_read_ = 0; 49 } 50 virtual void TearDown() { 51 fclose(original_fid_); 52 fclose(edited_fid_); 53 } 54 // Compares the frames in both streams to the end of one of the streams. 55 void CompareToTheEnd(FILE* test_video_fid, FILE* ref_video_fid, 56 scoped_ptr<int[]>* ref_buffer, 57 scoped_ptr<int[]>* test_buffer) { 58 while (!feof(test_video_fid) && !feof(ref_video_fid)) { 59 num_bytes_read_ = fread(ref_buffer->get(), 1, kFrameSize, ref_video_fid); 60 if (!feof(ref_video_fid)) { 61 EXPECT_EQ(kFrameSize, num_bytes_read_); 62 } 63 num_bytes_read_ = fread(test_buffer->get(), 1, kFrameSize, 64 test_video_fid); 65 if (!feof(test_video_fid)) { 66 EXPECT_EQ(kFrameSize, num_bytes_read_); 67 } 68 if (!feof(test_video_fid) && !feof(test_video_fid)) { 69 EXPECT_EQ(0, memcmp(ref_buffer->get(), test_buffer->get(), 70 kFrameSize)); 71 } 72 } 73 // There should not be anything left in either stream. 74 EXPECT_EQ(!feof(test_video_fid), !feof(ref_video_fid)); 75 } 76 std::string reference_video_; 77 std::string test_video_; 78 FILE* original_fid_; 79 FILE* edited_fid_; 80 int num_bytes_read_; 81 scoped_ptr<int[]> original_buffer_; 82 scoped_ptr<int[]> edited_buffer_; 83 int num_frames_read_; 84 }; 85 86 TEST_F(FrameEditingTest, ValidInPath) { 87 const int kFirstFrameToProcess = 160; 88 const int kInterval = -1; 89 const int kLastFrameToProcess = 240; 90 91 int result = EditFrames(reference_video_, kWidth, kHeight, 92 kFirstFrameToProcess, kInterval, kLastFrameToProcess, 93 test_video_); 94 EXPECT_EQ(0, result); 95 96 for (int i = 1; i < kFirstFrameToProcess; ++i) { 97 num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize, 98 original_fid_); 99 EXPECT_EQ(kFrameSize, num_bytes_read_); 100 101 num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_); 102 EXPECT_EQ(kFrameSize, num_bytes_read_); 103 104 EXPECT_EQ(0, memcmp(original_buffer_.get(), edited_buffer_.get(), 105 kFrameSize)); 106 } 107 // Do not compare the frames that have been cut. 108 for (int i = kFirstFrameToProcess; i <= kLastFrameToProcess; ++i) { 109 num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize, 110 original_fid_); 111 EXPECT_EQ(kFrameSize, num_bytes_read_); 112 } 113 CompareToTheEnd(edited_fid_, original_fid_, &original_buffer_, 114 &edited_buffer_); 115 } 116 117 TEST_F(FrameEditingTest, EmptySetToCut) { 118 const int kFirstFrameToProcess = 2; 119 const int kInterval = -1; 120 const int kLastFrameToProcess = 1; 121 122 int result = EditFrames(reference_video_, kWidth, kHeight, 123 kFirstFrameToProcess, kInterval, kLastFrameToProcess, 124 test_video_); 125 EXPECT_EQ(-10, result); 126 } 127 128 TEST_F(FrameEditingTest, InValidInPath) { 129 const std::string kRefVideo_ = "PATH/THAT/DOES/NOT/EXIST"; 130 131 const int kFirstFrameToProcess = 30; 132 const int kInterval = 1; 133 const int kLastFrameToProcess = 120; 134 135 int result = EditFrames(kRefVideo_, kWidth, kHeight, kFirstFrameToProcess, 136 kInterval, kLastFrameToProcess, test_video_); 137 EXPECT_EQ(-11, result); 138 } 139 140 TEST_F(FrameEditingTest, DeletingEverySecondFrame) { 141 const int kFirstFrameToProcess = 1; 142 const int kInterval = -2; 143 const int kLastFrameToProcess = 10000; 144 // Set kLastFrameToProcess to a large value so that all frame are processed. 145 int result = EditFrames(reference_video_, kWidth, kHeight, 146 kFirstFrameToProcess, kInterval, kLastFrameToProcess, 147 test_video_); 148 EXPECT_EQ(0, result); 149 150 while (!feof(original_fid_) && !feof(edited_fid_)) { 151 num_bytes_read_ = 152 fread(original_buffer_.get(), 1, kFrameSize, original_fid_); 153 if (!feof(original_fid_)) { 154 EXPECT_EQ(kFrameSize, num_bytes_read_); 155 num_frames_read_++; 156 } 157 // We want to compare every second frame of the original to the edited. 158 // kInterval=-2 and (num_frames_read_ - 1) % kInterval will be -1 for 159 // every second frame. 160 // num_frames_read_ - 1 because we have deleted frame number 2, 4 , 6 etc. 161 if ((num_frames_read_ - 1) % kInterval == -1) { 162 num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, 163 edited_fid_); 164 if (!feof(edited_fid_)) { 165 EXPECT_EQ(kFrameSize, num_bytes_read_); 166 } 167 if (!feof(original_fid_) && !feof(edited_fid_)) { 168 EXPECT_EQ(0, memcmp(original_buffer_.get(), 169 edited_buffer_.get(), kFrameSize)); 170 } 171 } 172 } 173 } 174 175 TEST_F(FrameEditingTest, RepeatFrames) { 176 const int kFirstFrameToProcess = 160; 177 const int kInterval = 2; 178 const int kLastFrameToProcess = 240; 179 180 int result = EditFrames(reference_video_, kWidth, kHeight, 181 kFirstFrameToProcess, kInterval, kLastFrameToProcess, 182 test_video_); 183 EXPECT_EQ(0, result); 184 185 for (int i = 1; i < kFirstFrameToProcess; ++i) { 186 num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize, 187 original_fid_); 188 EXPECT_EQ(kFrameSize, num_bytes_read_); 189 190 num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_); 191 EXPECT_EQ(kFrameSize, num_bytes_read_); 192 193 EXPECT_EQ(0, memcmp(original_buffer_.get(), edited_buffer_.get(), 194 kFrameSize)); 195 } 196 // Do not compare the frames that have been repeated. 197 for (int i = kFirstFrameToProcess; i <= kLastFrameToProcess; ++i) { 198 num_bytes_read_ = fread(original_buffer_.get(), 1, kFrameSize, 199 original_fid_); 200 EXPECT_EQ(kFrameSize, num_bytes_read_); 201 for (int i = 1; i <= kInterval; ++i) { 202 num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, 203 edited_fid_); 204 EXPECT_EQ(kFrameSize, num_bytes_read_); 205 EXPECT_EQ(0, memcmp(original_buffer_.get(), edited_buffer_.get(), 206 kFrameSize)); 207 } 208 } 209 CompareToTheEnd(edited_fid_, original_fid_, &original_buffer_, 210 &edited_buffer_); 211 } 212 } // namespace test 213 } // namespace webrtc 214