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

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

Issue 1853813002: Add support for writing raw encoder output to .ivf files. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix type mismatch in test Created 4 years, 8 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
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 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 "webrtc/modules/video_coding/utility/ivf_file_writer.h"
12
13 #include <memory>
14
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/base/logging.h"
17 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
18 #include "webrtc/system_wrappers/include/tick_util.h"
19
20 namespace webrtc {
21
22 namespace {
23 static const int kHeaderSize = 32;
24 static const int kFrameHeaderSize = 12;
25 static uint8_t dummy_payload[4] = {0, 1, 2, 3};
26 } // namespace
27
28 class IvfFileWriterTest : public ::testing::Test {
29 protected:
30 void SetUp() override {
31 const int64_t start_id =
32 reinterpret_cast<int64_t>(this) ^ TickTime::MicrosecondTimestamp();
33 int64_t id = start_id;
34 do {
35 std::ostringstream oss;
36 oss << "ivf_test_file_" << id++ << ".ivf";
37 file_name_ = oss.str();
38 } while (id < start_id + 100 && FileExists());
39 }
40
41 bool WriteDummyTestFrames(int width,
42 int height,
43 int num_frames,
44 bool use_capture_tims_ms) {
45 EncodedImage frame;
46 frame._buffer = dummy_payload;
47 frame._encodedWidth = width;
48 frame._encodedHeight = height;
49 for (int i = 1; i <= num_frames; ++i) {
50 frame._length = i % sizeof(dummy_payload);
51 if (use_capture_tims_ms) {
52 frame.capture_time_ms_ = i;
53 } else {
54 frame._timeStamp = i;
55 }
56 if (!file_writer_->WriteFrame(frame))
57 return false;
58 }
59 return true;
60 }
61
62 void VerifyIvfHeader(FileWrapper* file,
63 const uint8_t fourcc[4],
64 int width,
65 int height,
66 uint32_t num_frames,
67 bool use_capture_tims_ms) {
68 uint8_t data[kHeaderSize];
69 ASSERT_EQ(kHeaderSize, file->Read(data, kHeaderSize));
70
71 uint8_t dkif[4] = {'D', 'K', 'I', 'F'};
72 EXPECT_EQ(0, memcmp(dkif, data, 4));
73 EXPECT_EQ(0u, ByteReader<uint16_t>::ReadLittleEndian(&data[4]));
74 EXPECT_EQ(32u, ByteReader<uint16_t>::ReadLittleEndian(&data[6]));
75 EXPECT_EQ(0, memcmp(fourcc, &data[8], 4));
76 EXPECT_EQ(width, ByteReader<uint16_t>::ReadLittleEndian(&data[12]));
77 EXPECT_EQ(height, ByteReader<uint16_t>::ReadLittleEndian(&data[14]));
78 EXPECT_EQ(use_capture_tims_ms ? 1000u : 90000u,
79 ByteReader<uint32_t>::ReadLittleEndian(&data[16]));
80 EXPECT_EQ(1u, ByteReader<uint32_t>::ReadLittleEndian(&data[20]));
81 EXPECT_EQ(num_frames, ByteReader<uint32_t>::ReadLittleEndian(&data[24]));
82 EXPECT_EQ(0u, ByteReader<uint32_t>::ReadLittleEndian(&data[28]));
83 }
84
85 void VerifyDummyTestFrames(FileWrapper* file, uint32_t num_frames) {
86 const int kMaxFrameSize = 4;
87 for (uint32_t i = 1; i <= num_frames; ++i) {
88 uint8_t frame_header[kFrameHeaderSize];
89 ASSERT_EQ(kFrameHeaderSize, file->Read(frame_header, kFrameHeaderSize));
90 uint32_t frame_length =
91 ByteReader<uint32_t>::ReadLittleEndian(&frame_header[0]);
92 EXPECT_EQ(i % 4, frame_length);
93 uint64_t timestamp =
94 ByteReader<uint64_t>::ReadLittleEndian(&frame_header[4]);
95 EXPECT_EQ(i, timestamp);
96
97 uint8_t data[kMaxFrameSize] = {};
98 ASSERT_EQ(frame_length,
99 static_cast<uint32_t>(file->Read(data, frame_length)));
100 EXPECT_EQ(0, memcmp(data, dummy_payload, frame_length));
101 }
102 }
103
104 void RunBasicFileStructureTest(RtpVideoCodecTypes codec_type,
105 const uint8_t fourcc[4],
106 bool use_capture_tims_ms) {
107 file_writer_ = IvfFileWriter::Open(file_name_, codec_type);
108 ASSERT_TRUE(file_writer_.get());
109 const int kWidth = 320;
110 const int kHeight = 240;
111 const int kNumFrames = 257;
112 EXPECT_TRUE(
113 WriteDummyTestFrames(kWidth, kHeight, kNumFrames, use_capture_tims_ms));
114 EXPECT_TRUE(file_writer_->Close());
115
116 std::unique_ptr<FileWrapper> out_file(FileWrapper::Create());
117 ASSERT_EQ(0, out_file->OpenFile(file_name_.c_str(), true));
118 VerifyIvfHeader(out_file.get(), fourcc, kWidth, kHeight, kNumFrames,
119 use_capture_tims_ms);
120 VerifyDummyTestFrames(out_file.get(), kNumFrames);
121
122 EXPECT_EQ(0, out_file->CloseFile());
123 EXPECT_EQ(0, remove(file_name_.c_str()));
124 }
125
126 bool FileExists() {
127 std::unique_ptr<FileWrapper> file_wrapper(FileWrapper::Create());
128 return file_wrapper->OpenFile(file_name_.c_str(), true) == 0;
129 }
130
131 std::string file_name_;
132 std::unique_ptr<IvfFileWriter> file_writer_;
133 };
134
135 TEST_F(IvfFileWriterTest, RemovesUnusedFile) {
136 file_writer_ = IvfFileWriter::Open(file_name_, kRtpVideoVp8);
137 ASSERT_TRUE(file_writer_.get() != nullptr);
138 EXPECT_TRUE(FileExists());
139 EXPECT_TRUE(file_writer_->Close());
140 EXPECT_FALSE(FileExists());
141 EXPECT_FALSE(file_writer_->Close()); // Can't close twice.
142 }
143
144 TEST_F(IvfFileWriterTest, WritesBasicVP8FileNtpTimestamp) {
145 const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
146 RunBasicFileStructureTest(kRtpVideoVp8, fourcc, false);
147 }
148
149 TEST_F(IvfFileWriterTest, WritesBasicVP8FileMsTimestamp) {
150 const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
151 RunBasicFileStructureTest(kRtpVideoVp8, fourcc, true);
152 }
153
154 TEST_F(IvfFileWriterTest, WritesBasicVP9FileNtpTimestamp) {
155 const uint8_t fourcc[4] = {'V', 'P', '9', '0'};
156 RunBasicFileStructureTest(kRtpVideoVp9, fourcc, false);
157 }
158
159 TEST_F(IvfFileWriterTest, WritesBasicVP9FileMsTimestamp) {
160 const uint8_t fourcc[4] = {'V', 'P', '9', '0'};
161 RunBasicFileStructureTest(kRtpVideoVp9, fourcc, true);
162 }
163
164 TEST_F(IvfFileWriterTest, WritesBasicH264FileNtpTimestamp) {
165 const uint8_t fourcc[4] = {'H', '2', '6', '4'};
166 RunBasicFileStructureTest(kRtpVideoH264, fourcc, false);
167 }
168
169 TEST_F(IvfFileWriterTest, WritesBasicH264FileMsTimestamp) {
170 const uint8_t fourcc[4] = {'H', '2', '6', '4'};
171 RunBasicFileStructureTest(kRtpVideoH264, fourcc, true);
172 }
173
174 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698