Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: webrtc/modules/video_coding/utility/ivf_file_writer_unittest.cc

Issue 2303273002: Expose Ivf logging through the native API (Closed)
Patch Set: Nit Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/video_coding/utility/ivf_file_writer.cc ('k') | webrtc/test/fake_encoder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 11 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
12 12
13 #include <memory> 13 #include <memory>
14 14
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/base/helpers.h" 16 #include "webrtc/base/helpers.h"
17 #include "webrtc/base/logging.h" 17 #include "webrtc/base/logging.h"
18 #include "webrtc/base/thread.h" 18 #include "webrtc/base/thread.h"
19 #include "webrtc/base/timeutils.h" 19 #include "webrtc/base/timeutils.h"
20 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 20 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
21 #include "webrtc/test/testsupport/fileutils.h" 21 #include "webrtc/test/testsupport/fileutils.h"
22 22
23 namespace webrtc { 23 namespace webrtc {
24 24
25 namespace { 25 namespace {
26 static const int kHeaderSize = 32; 26 static const int kHeaderSize = 32;
27 static const int kFrameHeaderSize = 12; 27 static const int kFrameHeaderSize = 12;
28 static uint8_t dummy_payload[4] = {0, 1, 2, 3}; 28 static uint8_t dummy_payload[4] = {0, 1, 2, 3};
29 static const int kMaxFileRetries = 5;
30 } // namespace 29 } // namespace
31 30
32 class IvfFileWriterTest : public ::testing::Test { 31 class IvfFileWriterTest : public ::testing::Test {
33 protected: 32 protected:
34 void SetUp() override { 33 void SetUp() override {
35 const uint64_t start_id = rtc::CreateRandomId64(); 34 file_name_ =
36 uint64_t id = start_id; 35 webrtc::test::TempFilename(webrtc::test::OutputPath(), "test_file");
37 do {
38 std::ostringstream oss;
39 oss << test::OutputPath() << "ivf_test_file_" << id++ << ".ivf";
40 file_name_ = oss.str();
41 } while ((id - start_id) < 100u && FileExists(false));
42 ASSERT_LT(id - start_id, 100u);
43 } 36 }
37 void TearDown() override { rtc::RemoveFile(file_name_); }
44 38
45 bool WriteDummyTestFrames(int width, 39 bool WriteDummyTestFrames(VideoCodecType codec_type,
40 int width,
46 int height, 41 int height,
47 int num_frames, 42 int num_frames,
48 bool use_capture_tims_ms) { 43 bool use_capture_tims_ms) {
49 EncodedImage frame; 44 EncodedImage frame;
50 frame._buffer = dummy_payload; 45 frame._buffer = dummy_payload;
51 frame._encodedWidth = width; 46 frame._encodedWidth = width;
52 frame._encodedHeight = height; 47 frame._encodedHeight = height;
53 for (int i = 1; i <= num_frames; ++i) { 48 for (int i = 1; i <= num_frames; ++i) {
54 frame._length = i % sizeof(dummy_payload); 49 frame._length = i % sizeof(dummy_payload);
55 if (use_capture_tims_ms) { 50 if (use_capture_tims_ms) {
56 frame.capture_time_ms_ = i; 51 frame.capture_time_ms_ = i;
57 } else { 52 } else {
58 frame._timeStamp = i; 53 frame._timeStamp = i;
59 } 54 }
60 if (!file_writer_->WriteFrame(frame)) 55 if (!file_writer_->WriteFrame(frame, codec_type))
61 return false; 56 return false;
62 } 57 }
63 return true; 58 return true;
64 } 59 }
65 60
66 void VerifyIvfHeader(FileWrapper* file, 61 void VerifyIvfHeader(rtc::File* file,
67 const uint8_t fourcc[4], 62 const uint8_t fourcc[4],
68 int width, 63 int width,
69 int height, 64 int height,
70 uint32_t num_frames, 65 uint32_t num_frames,
71 bool use_capture_tims_ms) { 66 bool use_capture_tims_ms) {
72 ASSERT_TRUE(file->is_open()); 67 ASSERT_TRUE(file->IsOpen());
73 uint8_t data[kHeaderSize]; 68 uint8_t data[kHeaderSize];
74 ASSERT_EQ(kHeaderSize, file->Read(data, kHeaderSize)); 69 ASSERT_EQ(static_cast<size_t>(kHeaderSize), file->Read(data, kHeaderSize));
75 70
76 uint8_t dkif[4] = {'D', 'K', 'I', 'F'}; 71 uint8_t dkif[4] = {'D', 'K', 'I', 'F'};
77 EXPECT_EQ(0, memcmp(dkif, data, 4)); 72 EXPECT_EQ(0, memcmp(dkif, data, 4));
78 EXPECT_EQ(0u, ByteReader<uint16_t>::ReadLittleEndian(&data[4])); 73 EXPECT_EQ(0u, ByteReader<uint16_t>::ReadLittleEndian(&data[4]));
79 EXPECT_EQ(32u, ByteReader<uint16_t>::ReadLittleEndian(&data[6])); 74 EXPECT_EQ(32u, ByteReader<uint16_t>::ReadLittleEndian(&data[6]));
80 EXPECT_EQ(0, memcmp(fourcc, &data[8], 4)); 75 EXPECT_EQ(0, memcmp(fourcc, &data[8], 4));
81 EXPECT_EQ(width, ByteReader<uint16_t>::ReadLittleEndian(&data[12])); 76 EXPECT_EQ(width, ByteReader<uint16_t>::ReadLittleEndian(&data[12]));
82 EXPECT_EQ(height, ByteReader<uint16_t>::ReadLittleEndian(&data[14])); 77 EXPECT_EQ(height, ByteReader<uint16_t>::ReadLittleEndian(&data[14]));
83 EXPECT_EQ(use_capture_tims_ms ? 1000u : 90000u, 78 EXPECT_EQ(use_capture_tims_ms ? 1000u : 90000u,
84 ByteReader<uint32_t>::ReadLittleEndian(&data[16])); 79 ByteReader<uint32_t>::ReadLittleEndian(&data[16]));
85 EXPECT_EQ(1u, ByteReader<uint32_t>::ReadLittleEndian(&data[20])); 80 EXPECT_EQ(1u, ByteReader<uint32_t>::ReadLittleEndian(&data[20]));
86 EXPECT_EQ(num_frames, ByteReader<uint32_t>::ReadLittleEndian(&data[24])); 81 EXPECT_EQ(num_frames, ByteReader<uint32_t>::ReadLittleEndian(&data[24]));
87 EXPECT_EQ(0u, ByteReader<uint32_t>::ReadLittleEndian(&data[28])); 82 EXPECT_EQ(0u, ByteReader<uint32_t>::ReadLittleEndian(&data[28]));
88 } 83 }
89 84
90 void VerifyDummyTestFrames(FileWrapper* file, uint32_t num_frames) { 85 void VerifyDummyTestFrames(rtc::File* file, uint32_t num_frames) {
91 const int kMaxFrameSize = 4; 86 const int kMaxFrameSize = 4;
92 for (uint32_t i = 1; i <= num_frames; ++i) { 87 for (uint32_t i = 1; i <= num_frames; ++i) {
93 uint8_t frame_header[kFrameHeaderSize]; 88 uint8_t frame_header[kFrameHeaderSize];
94 ASSERT_EQ(kFrameHeaderSize, file->Read(frame_header, kFrameHeaderSize)); 89 ASSERT_EQ(static_cast<unsigned int>(kFrameHeaderSize),
90 file->Read(frame_header, kFrameHeaderSize));
95 uint32_t frame_length = 91 uint32_t frame_length =
96 ByteReader<uint32_t>::ReadLittleEndian(&frame_header[0]); 92 ByteReader<uint32_t>::ReadLittleEndian(&frame_header[0]);
97 EXPECT_EQ(i % 4, frame_length); 93 EXPECT_EQ(i % 4, frame_length);
98 uint64_t timestamp = 94 uint64_t timestamp =
99 ByteReader<uint64_t>::ReadLittleEndian(&frame_header[4]); 95 ByteReader<uint64_t>::ReadLittleEndian(&frame_header[4]);
100 EXPECT_EQ(i, timestamp); 96 EXPECT_EQ(i, timestamp);
101 97
102 uint8_t data[kMaxFrameSize] = {}; 98 uint8_t data[kMaxFrameSize] = {};
103 ASSERT_EQ(frame_length, 99 ASSERT_EQ(frame_length,
104 static_cast<uint32_t>(file->Read(data, frame_length))); 100 static_cast<uint32_t>(file->Read(data, frame_length)));
105 EXPECT_EQ(0, memcmp(data, dummy_payload, frame_length)); 101 EXPECT_EQ(0, memcmp(data, dummy_payload, frame_length));
106 } 102 }
107 } 103 }
108 104
109 void RunBasicFileStructureTest(VideoCodecType codec_type, 105 void RunBasicFileStructureTest(VideoCodecType codec_type,
110 const uint8_t fourcc[4], 106 const uint8_t fourcc[4],
111 bool use_capture_tims_ms) { 107 bool use_capture_tims_ms) {
112 file_writer_ = IvfFileWriter::Open(file_name_, codec_type); 108 file_writer_ = IvfFileWriter::Wrap(rtc::File::Open(file_name_), 0);
113 ASSERT_TRUE(file_writer_.get()); 109 ASSERT_TRUE(file_writer_.get());
114 const int kWidth = 320; 110 const int kWidth = 320;
115 const int kHeight = 240; 111 const int kHeight = 240;
116 const int kNumFrames = 257; 112 const int kNumFrames = 257;
117 EXPECT_TRUE( 113 ASSERT_TRUE(WriteDummyTestFrames(codec_type, kWidth, kHeight, kNumFrames,
118 WriteDummyTestFrames(kWidth, kHeight, kNumFrames, use_capture_tims_ms)); 114 use_capture_tims_ms));
119 EXPECT_TRUE(file_writer_->Close()); 115 EXPECT_TRUE(file_writer_->Close());
120 116
121 std::unique_ptr<FileWrapper> out_file(FileWrapper::Create()); 117 rtc::File out_file = rtc::File::Open(file_name_);
122 ASSERT_TRUE(out_file->OpenFile(file_name_.c_str(), true)); 118 VerifyIvfHeader(&out_file, fourcc, kWidth, kHeight, kNumFrames,
123 VerifyIvfHeader(out_file.get(), fourcc, kWidth, kHeight, kNumFrames,
124 use_capture_tims_ms); 119 use_capture_tims_ms);
125 VerifyDummyTestFrames(out_file.get(), kNumFrames); 120 VerifyDummyTestFrames(&out_file, kNumFrames);
126 121
127 out_file->CloseFile(); 122 out_file.Close();
128
129 bool file_removed = false;
130 for (int i = 0; i < kMaxFileRetries; ++i) {
131 file_removed = remove(file_name_.c_str()) == 0;
132 if (file_removed)
133 break;
134
135 // Couldn't remove file for some reason, wait a sec and try again.
136 rtc::Thread::SleepMs(1000);
137 }
138 EXPECT_TRUE(file_removed);
139 }
140
141 // Check whether file exists or not, and if it does not meet expectation,
142 // wait a bit and check again, up to kMaxFileRetries times. This is an ugly
143 // hack to avoid flakiness on certain operating systems where antivirus
144 // software may unexpectedly lock files and keep them from disappearing or
145 // being reused.
146 bool FileExists(bool expected) {
147 bool file_exists = expected;
148 std::unique_ptr<FileWrapper> file_wrapper;
149 int iterations = 0;
150 do {
151 if (file_wrapper.get() != nullptr)
152 rtc::Thread::SleepMs(1000);
153 file_wrapper.reset(FileWrapper::Create());
154 file_exists = file_wrapper->OpenFile(file_name_.c_str(), true);
155 file_wrapper->CloseFile();
156 } while (file_exists != expected && ++iterations < kMaxFileRetries);
157 return file_exists;
158 } 123 }
159 124
160 std::string file_name_; 125 std::string file_name_;
161 std::unique_ptr<IvfFileWriter> file_writer_; 126 std::unique_ptr<IvfFileWriter> file_writer_;
162 }; 127 };
163 128
164 TEST_F(IvfFileWriterTest, RemovesUnusedFile) {
165 file_writer_ = IvfFileWriter::Open(file_name_, kVideoCodecVP8);
166 ASSERT_TRUE(file_writer_.get() != nullptr);
167 EXPECT_TRUE(FileExists(true));
168 EXPECT_TRUE(file_writer_->Close());
169 EXPECT_FALSE(FileExists(false));
170 EXPECT_FALSE(file_writer_->Close()); // Can't close twice.
171 }
172
173 TEST_F(IvfFileWriterTest, WritesBasicVP8FileNtpTimestamp) { 129 TEST_F(IvfFileWriterTest, WritesBasicVP8FileNtpTimestamp) {
174 const uint8_t fourcc[4] = {'V', 'P', '8', '0'}; 130 const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
175 RunBasicFileStructureTest(kVideoCodecVP8, fourcc, false); 131 RunBasicFileStructureTest(kVideoCodecVP8, fourcc, false);
176 } 132 }
177 133
178 TEST_F(IvfFileWriterTest, WritesBasicVP8FileMsTimestamp) { 134 TEST_F(IvfFileWriterTest, WritesBasicVP8FileMsTimestamp) {
179 const uint8_t fourcc[4] = {'V', 'P', '8', '0'}; 135 const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
180 RunBasicFileStructureTest(kVideoCodecVP8, fourcc, true); 136 RunBasicFileStructureTest(kVideoCodecVP8, fourcc, true);
181 } 137 }
182 138
(...skipping 10 matching lines...) Expand all
193 TEST_F(IvfFileWriterTest, WritesBasicH264FileNtpTimestamp) { 149 TEST_F(IvfFileWriterTest, WritesBasicH264FileNtpTimestamp) {
194 const uint8_t fourcc[4] = {'H', '2', '6', '4'}; 150 const uint8_t fourcc[4] = {'H', '2', '6', '4'};
195 RunBasicFileStructureTest(kVideoCodecH264, fourcc, false); 151 RunBasicFileStructureTest(kVideoCodecH264, fourcc, false);
196 } 152 }
197 153
198 TEST_F(IvfFileWriterTest, WritesBasicH264FileMsTimestamp) { 154 TEST_F(IvfFileWriterTest, WritesBasicH264FileMsTimestamp) {
199 const uint8_t fourcc[4] = {'H', '2', '6', '4'}; 155 const uint8_t fourcc[4] = {'H', '2', '6', '4'};
200 RunBasicFileStructureTest(kVideoCodecH264, fourcc, true); 156 RunBasicFileStructureTest(kVideoCodecH264, fourcc, true);
201 } 157 }
202 158
159 TEST_F(IvfFileWriterTest, ClosesWhenReachesLimit) {
160 const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
161 const int kWidth = 320;
162 const int kHeight = 240;
163 const int kNumFramesToWrite = 2;
164 const int kNumFramesToFit = 1;
165
166 file_writer_ = IvfFileWriter::Wrap(
167 rtc::File::Open(file_name_),
168 kHeaderSize +
169 kNumFramesToFit * (kFrameHeaderSize + sizeof(dummy_payload)));
170 ASSERT_TRUE(file_writer_.get());
171
172 ASSERT_FALSE(WriteDummyTestFrames(kVideoCodecVP8, kWidth, kHeight,
173 kNumFramesToWrite, true));
174 ASSERT_FALSE(file_writer_->Close());
175
176 rtc::File out_file = rtc::File::Open(file_name_);
177 VerifyIvfHeader(&out_file, fourcc, kWidth, kHeight, kNumFramesToFit, true);
178 VerifyDummyTestFrames(&out_file, kNumFramesToFit);
179
180 out_file.Close();
181 }
182
203 } // namespace webrtc 183 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/utility/ivf_file_writer.cc ('k') | webrtc/test/fake_encoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698