Chromium Code Reviews

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: Added checks Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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/fileutils.h"
17 #include "webrtc/base/logging.h"
18 #include "webrtc/base/pathutils.h"
19 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
20
21 namespace webrtc {
22
23 namespace {
24 static const size_t kHeaderSize = 32;
25 const size_t kFrameHeaderSize = 12;
26 uint8_t dummy_payload[4] = {0, 1, 2, 3};
27 } // namespace
28
29 class IvfFileWriterTest : public ::testing::Test {
30 protected:
31 void SetUp() override {
32 ASSERT_TRUE(rtc::CreateUniqueFile(file_name_, false));
33 }
34
35 bool WriteDummyTestFrames(int width, int height, int num_frames) {
36 EncodedImage frame;
37 frame._buffer = dummy_payload;
38 frame._encodedWidth = width;
39 frame._encodedHeight = height;
40 for (int i = 0; i < num_frames; ++i) {
41 frame._length = i % sizeof(dummy_payload);
42 frame.ntp_time_ms_ = i;
43 if (!file_writer_->WriteFrame(frame))
44 return false;
45 }
46 return true;
47 }
48
49 void VerifyIvfHeader(const uint8_t* data,
50 const uint8_t fourcc[4],
51 int width,
52 int height,
53 uint32_t num_frames) {
54 uint8_t dkif[4] = {'D', 'K', 'I', 'F'};
55 EXPECT_EQ(0, memcmp(dkif, data, 4));
56 EXPECT_EQ(0, ByteReader<uint16_t>::ReadLittleEndian(&data[4]));
57 EXPECT_EQ(32, ByteReader<uint16_t>::ReadLittleEndian(&data[6]));
58 EXPECT_EQ(0, memcmp(fourcc, &data[8], 4));
59 EXPECT_EQ(width, ByteReader<uint16_t>::ReadLittleEndian(&data[12]));
60 EXPECT_EQ(height, ByteReader<uint16_t>::ReadLittleEndian(&data[14]));
61 EXPECT_EQ(1000u, ByteReader<uint32_t>::ReadLittleEndian(&data[16]));
62 EXPECT_EQ(1u, ByteReader<uint32_t>::ReadLittleEndian(&data[20]));
63 EXPECT_EQ(num_frames, ByteReader<uint32_t>::ReadLittleEndian(&data[24]));
64 EXPECT_EQ(0u, ByteReader<uint32_t>::ReadLittleEndian(&data[28]));
65 }
66
67 void VerifyDummyTestFrames(const uint8_t* data,
68 size_t size,
69 uint32_t num_frames) {
70 size_t bytes_read = 0;
71 for (uint32_t i = 0; i < num_frames; ++i) {
72 ASSERT_LE(bytes_read + kFrameHeaderSize, size);
73 uint32_t frame_length =
74 ByteReader<uint32_t>::ReadLittleEndian(&data[bytes_read]);
75 EXPECT_EQ(i % 4, frame_length);
76 uint64_t timestamp =
77 ByteReader<uint64_t>::ReadLittleEndian(&data[bytes_read + 4]);
78 EXPECT_EQ(i, timestamp);
79 bytes_read += kFrameHeaderSize;
80
81 ASSERT_LE(bytes_read + frame_length, size);
82 EXPECT_EQ(0, memcmp(&data[bytes_read], dummy_payload, frame_length));
83 bytes_read += frame_length;
84 }
85 }
86
87 void RunBasicFileStructureTest(RtpVideoCodecTypes codec_type,
88 const uint8_t fourcc[4]) {
89 rtc::MemoryStream* out_stream = new rtc::MemoryStream();
90 file_writer_ = IvfFileWriter::Open(out_stream, codec_type);
91 ASSERT_TRUE(file_writer_.get());
92 const int kWidth = 320;
93 const int kHeight = 240;
94 const int kNumFrames = 257;
95 EXPECT_TRUE(WriteDummyTestFrames(kWidth, kHeight, kNumFrames));
96
97 size_t size = 0;
98 ASSERT_TRUE(out_stream->GetSize(&size));
99 ASSERT_GE(size, kHeaderSize);
100 EXPECT_TRUE(file_writer_->Close());
101
102 const uint8_t* out_buffer =
103 reinterpret_cast<const uint8_t*>(out_stream->GetBuffer());
104 VerifyIvfHeader(out_buffer, fourcc, kWidth, kHeight, kNumFrames);
105 VerifyDummyTestFrames(&out_buffer[kHeaderSize], size - kHeaderSize,
106 kNumFrames);
107
108 EXPECT_TRUE(file_writer_->Close());
109 }
110
111 rtc::Pathname file_name_;
112 std::unique_ptr<IvfFileWriter> file_writer_;
113 };
114
115 TEST_F(IvfFileWriterTest, RemovesUnusedFile) {
116 file_writer_ = IvfFileWriter::Open(file_name_, kRtpVideoVp8);
117 ASSERT_TRUE(file_writer_.get());
118 rtc::FilesystemInterface* file_system = rtc::Filesystem::default_filesystem();
119 EXPECT_FALSE(file_system->IsAbsent(file_name_));
120 EXPECT_TRUE(file_writer_->Close());
121 EXPECT_TRUE(file_system->IsAbsent(file_name_));
122 EXPECT_FALSE(file_writer_->Close()); // Can't close twice.
123 }
124
125 TEST_F(IvfFileWriterTest, WritesBasicVP8File) {
126 const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
127 RunBasicFileStructureTest(kRtpVideoVp8, fourcc);
128 }
129
130 TEST_F(IvfFileWriterTest, WritesBasicVP9File) {
131 const uint8_t fourcc[4] = {'V', 'P', '9', '0'};
132 RunBasicFileStructureTest(kRtpVideoVp9, fourcc);
133 }
134
135 TEST_F(IvfFileWriterTest, WritesBasicH264File) {
136 const uint8_t fourcc[4] = {'H', '2', '6', '4'};
137 RunBasicFileStructureTest(kRtpVideoH264, fourcc);
138 }
139
140 } // namespace webrtc
OLDNEW

Powered by Google App Engine