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