1 /*
2 * Copyright (c) 2018 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 "rtc_tools/video_file_writer.h"
12
13 #include <stdint.h>
14
15 #include <cstdio>
16 #include <string>
17
18 #include "api/video/video_frame_buffer.h"
19 #include "rtc_tools/video_file_reader.h"
20 #include "test/gtest.h"
21 #include "test/testsupport/file_utils.h"
22
23 namespace webrtc {
24 namespace test {
25
26 class VideoFileWriterTest : public ::testing::Test {
27 public:
SetUp()28 void SetUp() override {
29 video_filename_ =
30 TempFilename(webrtc::test::OutputPath(), "test_video_file.y4m");
31
32 // Create simple test video of size 6x4.
33 FILE* file = fopen(video_filename_.c_str(), "wb");
34 ASSERT_TRUE(file != nullptr);
35 fprintf(file, "YUV4MPEG2 W6 H4 F60:1 C420 dummyParam\n");
36 fprintf(file, "FRAME\n");
37
38 const int i420_size = width * height * 3 / 2;
39 // First frame.
40 for (int i = 0; i < i420_size; ++i)
41 fputc(static_cast<char>(i), file);
42 fprintf(file, "FRAME\n");
43 // Second frame.
44 for (int i = 0; i < i420_size; ++i)
45 fputc(static_cast<char>(i + i420_size), file);
46 fclose(file);
47
48 // Open the newly created file.
49 video_ = webrtc::test::OpenY4mFile(video_filename_);
50 ASSERT_TRUE(video_);
51 ASSERT_EQ(video_->number_of_frames(), 2u);
52 }
53
TearDown()54 void TearDown() override {
55 if (!video_filename_.empty()) {
56 RemoveFile(video_filename_);
57 }
58 if (!written_video_filename_.empty()) {
59 RemoveFile(written_video_filename_);
60 }
61 }
62
63 // Write and read Y4M file.
WriteVideoY4m()64 void WriteVideoY4m() {
65 // Cleanup existing file if any.
66 if (!written_video_filename_.empty()) {
67 RemoveFile(written_video_filename_);
68 }
69 // Create an unique filename, e.g. test_video_file2.y4mZapata.
70 written_video_filename_ =
71 TempFilename(webrtc::test::OutputPath(), "test_video_file2.y4m");
72 webrtc::test::WriteY4mVideoToFile(video_, written_video_filename_, fps);
73 written_video_ = webrtc::test::OpenY4mFile(written_video_filename_);
74 ASSERT_TRUE(written_video_);
75 }
76
77 // Write and read YUV file.
WriteVideoYuv()78 void WriteVideoYuv() {
79 // Cleanup existing file if any.
80 if (!written_video_filename_.empty()) {
81 RemoveFile(written_video_filename_);
82 }
83 // Create an unique filename, e.g. test_video_file2.yuvZapata.
84 written_video_filename_ =
85 TempFilename(webrtc::test::OutputPath(), "test_video_file2.yuv");
86 webrtc::test::WriteYuvVideoToFile(video_, written_video_filename_, fps);
87 written_video_ =
88 webrtc::test::OpenYuvFile(written_video_filename_, width, height);
89 ASSERT_TRUE(written_video_);
90 }
91
92 const int width = 6;
93 const int height = 4;
94 const int fps = 60;
95 rtc::scoped_refptr<webrtc::test::Video> video_;
96 rtc::scoped_refptr<webrtc::test::Video> written_video_;
97 // Each video object must be backed by file!
98 std::string video_filename_;
99 std::string written_video_filename_;
100 };
101
TEST_F(VideoFileWriterTest,TestParsingFileHeaderY4m)102 TEST_F(VideoFileWriterTest, TestParsingFileHeaderY4m) {
103 WriteVideoY4m();
104 EXPECT_EQ(video_->width(), written_video_->width());
105 EXPECT_EQ(video_->height(), written_video_->height());
106 }
107
TEST_F(VideoFileWriterTest,TestParsingFileHeaderYuv)108 TEST_F(VideoFileWriterTest, TestParsingFileHeaderYuv) {
109 WriteVideoYuv();
110 EXPECT_EQ(video_->width(), written_video_->width());
111 EXPECT_EQ(video_->height(), written_video_->height());
112 }
113
TEST_F(VideoFileWriterTest,TestParsingNumberOfFramesY4m)114 TEST_F(VideoFileWriterTest, TestParsingNumberOfFramesY4m) {
115 WriteVideoY4m();
116 EXPECT_EQ(video_->number_of_frames(), written_video_->number_of_frames());
117 }
118
TEST_F(VideoFileWriterTest,TestParsingNumberOfFramesYuv)119 TEST_F(VideoFileWriterTest, TestParsingNumberOfFramesYuv) {
120 WriteVideoYuv();
121 EXPECT_EQ(video_->number_of_frames(), written_video_->number_of_frames());
122 }
123
TEST_F(VideoFileWriterTest,TestPixelContentY4m)124 TEST_F(VideoFileWriterTest, TestPixelContentY4m) {
125 WriteVideoY4m();
126 int cnt = 0;
127 for (const rtc::scoped_refptr<I420BufferInterface> frame : *written_video_) {
128 for (int i = 0; i < width * height; ++i, ++cnt)
129 EXPECT_EQ(cnt, frame->DataY()[i]);
130 for (int i = 0; i < width / 2 * height / 2; ++i, ++cnt)
131 EXPECT_EQ(cnt, frame->DataU()[i]);
132 for (int i = 0; i < width / 2 * height / 2; ++i, ++cnt)
133 EXPECT_EQ(cnt, frame->DataV()[i]);
134 }
135 }
136
TEST_F(VideoFileWriterTest,TestPixelContentYuv)137 TEST_F(VideoFileWriterTest, TestPixelContentYuv) {
138 WriteVideoYuv();
139 int cnt = 0;
140 for (const rtc::scoped_refptr<I420BufferInterface> frame : *written_video_) {
141 for (int i = 0; i < width * height; ++i, ++cnt)
142 EXPECT_EQ(cnt, frame->DataY()[i]);
143 for (int i = 0; i < width / 2 * height / 2; ++i, ++cnt)
144 EXPECT_EQ(cnt, frame->DataU()[i]);
145 for (int i = 0; i < width / 2 * height / 2; ++i, ++cnt)
146 EXPECT_EQ(cnt, frame->DataV()[i]);
147 }
148 }
149
150 } // namespace test
151 } // namespace webrtc
152