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