| Index: webrtc/modules/video_coding/utility/ivf_file_writer_unittest.cc
|
| diff --git a/webrtc/modules/video_coding/utility/ivf_file_writer_unittest.cc b/webrtc/modules/video_coding/utility/ivf_file_writer_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ded7627fd9a98f674b465d34ec1f058edaf5e2eb
|
| --- /dev/null
|
| +++ b/webrtc/modules/video_coding/utility/ivf_file_writer_unittest.cc
|
| @@ -0,0 +1,140 @@
|
| +/*
|
| + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license
|
| + * that can be found in the LICENSE file in the root of the source
|
| + * tree. An additional intellectual property rights grant can be found
|
| + * in the file PATENTS. All contributing project authors may
|
| + * be found in the AUTHORS file in the root of the source tree.
|
| + */
|
| +
|
| +#include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "webrtc/base/fileutils.h"
|
| +#include "webrtc/base/logging.h"
|
| +#include "webrtc/base/pathutils.h"
|
| +#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
| +
|
| +namespace webrtc {
|
| +
|
| +namespace {
|
| +static const size_t kHeaderSize = 32;
|
| +const size_t kFrameHeaderSize = 12;
|
| +uint8_t dummy_payload[4] = {0, 1, 2, 3};
|
| +} // namespace
|
| +
|
| +class IvfFileWriterTest : public ::testing::Test {
|
| + protected:
|
| + void SetUp() override {
|
| + ASSERT_TRUE(rtc::CreateUniqueFile(file_name_, false));
|
| + }
|
| +
|
| + bool WriteDummyTestFrames(int width, int height, int num_frames) {
|
| + EncodedImage frame;
|
| + frame._buffer = dummy_payload;
|
| + frame._encodedWidth = width;
|
| + frame._encodedHeight = height;
|
| + for (int i = 0; i < num_frames; ++i) {
|
| + frame._length = i % sizeof(dummy_payload);
|
| + frame.ntp_time_ms_ = i;
|
| + if (!file_writer_->WriteFrame(frame))
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + void VerifyIvfHeader(const uint8_t* data,
|
| + const uint8_t fourcc[4],
|
| + int width,
|
| + int height,
|
| + uint32_t num_frames) {
|
| + uint8_t dkif[4] = {'D', 'K', 'I', 'F'};
|
| + EXPECT_EQ(0, memcmp(dkif, data, 4));
|
| + EXPECT_EQ(0, ByteReader<uint16_t>::ReadLittleEndian(&data[4]));
|
| + EXPECT_EQ(32, ByteReader<uint16_t>::ReadLittleEndian(&data[6]));
|
| + EXPECT_EQ(0, memcmp(fourcc, &data[8], 4));
|
| + EXPECT_EQ(width, ByteReader<uint16_t>::ReadLittleEndian(&data[12]));
|
| + EXPECT_EQ(height, ByteReader<uint16_t>::ReadLittleEndian(&data[14]));
|
| + EXPECT_EQ(1000u, ByteReader<uint32_t>::ReadLittleEndian(&data[16]));
|
| + EXPECT_EQ(1u, ByteReader<uint32_t>::ReadLittleEndian(&data[20]));
|
| + EXPECT_EQ(num_frames, ByteReader<uint32_t>::ReadLittleEndian(&data[24]));
|
| + EXPECT_EQ(0u, ByteReader<uint32_t>::ReadLittleEndian(&data[28]));
|
| + }
|
| +
|
| + void VerifyDummyTestFrames(const uint8_t* data,
|
| + size_t size,
|
| + uint32_t num_frames) {
|
| + size_t bytes_read = 0;
|
| + for (uint32_t i = 0; i < num_frames; ++i) {
|
| + ASSERT_LE(bytes_read + kFrameHeaderSize, size);
|
| + uint32_t frame_length =
|
| + ByteReader<uint32_t>::ReadLittleEndian(&data[bytes_read]);
|
| + EXPECT_EQ(i % 4, frame_length);
|
| + uint64_t timestamp =
|
| + ByteReader<uint64_t>::ReadLittleEndian(&data[bytes_read + 4]);
|
| + EXPECT_EQ(i, timestamp);
|
| + bytes_read += kFrameHeaderSize;
|
| +
|
| + ASSERT_LE(bytes_read + frame_length, size);
|
| + EXPECT_EQ(0, memcmp(&data[bytes_read], dummy_payload, frame_length));
|
| + bytes_read += frame_length;
|
| + }
|
| + }
|
| +
|
| + void RunBasicFileStructureTest(RtpVideoCodecTypes codec_type,
|
| + const uint8_t fourcc[4]) {
|
| + rtc::MemoryStream* out_stream = new rtc::MemoryStream();
|
| + file_writer_ = IvfFileWriter::Open(out_stream, codec_type);
|
| + ASSERT_TRUE(file_writer_.get());
|
| + const int kWidth = 320;
|
| + const int kHeight = 240;
|
| + const int kNumFrames = 257;
|
| + EXPECT_TRUE(WriteDummyTestFrames(kWidth, kHeight, kNumFrames));
|
| +
|
| + size_t size = 0;
|
| + ASSERT_TRUE(out_stream->GetSize(&size));
|
| + ASSERT_GE(size, kHeaderSize);
|
| + EXPECT_TRUE(file_writer_->Close());
|
| +
|
| + const uint8_t* out_buffer =
|
| + reinterpret_cast<const uint8_t*>(out_stream->GetBuffer());
|
| + VerifyIvfHeader(out_buffer, fourcc, kWidth, kHeight, kNumFrames);
|
| + VerifyDummyTestFrames(&out_buffer[kHeaderSize], size - kHeaderSize,
|
| + kNumFrames);
|
| +
|
| + EXPECT_TRUE(file_writer_->Close());
|
| + }
|
| +
|
| + rtc::Pathname file_name_;
|
| + std::unique_ptr<IvfFileWriter> file_writer_;
|
| +};
|
| +
|
| +TEST_F(IvfFileWriterTest, RemovesUnusedFile) {
|
| + file_writer_ = IvfFileWriter::Open(file_name_, kRtpVideoVp8);
|
| + ASSERT_TRUE(file_writer_.get());
|
| + rtc::FilesystemInterface* file_system = rtc::Filesystem::default_filesystem();
|
| + EXPECT_FALSE(file_system->IsAbsent(file_name_));
|
| + EXPECT_TRUE(file_writer_->Close());
|
| + EXPECT_TRUE(file_system->IsAbsent(file_name_));
|
| + EXPECT_FALSE(file_writer_->Close()); // Can't close twice.
|
| +}
|
| +
|
| +TEST_F(IvfFileWriterTest, WritesBasicVP8File) {
|
| + const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
|
| + RunBasicFileStructureTest(kRtpVideoVp8, fourcc);
|
| +}
|
| +
|
| +TEST_F(IvfFileWriterTest, WritesBasicVP9File) {
|
| + const uint8_t fourcc[4] = {'V', 'P', '9', '0'};
|
| + RunBasicFileStructureTest(kRtpVideoVp9, fourcc);
|
| +}
|
| +
|
| +TEST_F(IvfFileWriterTest, WritesBasicH264File) {
|
| + const uint8_t fourcc[4] = {'H', '2', '6', '4'};
|
| + RunBasicFileStructureTest(kRtpVideoH264, fourcc);
|
| +}
|
| +
|
| +} // namespace webrtc
|
|
|