1*09537850SAkhilesh Sanikop // Copyright 2021 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop // http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop
15*09537850SAkhilesh Sanikop #include "examples/file_writer.h"
16*09537850SAkhilesh Sanikop
17*09537850SAkhilesh Sanikop #include <cstddef>
18*09537850SAkhilesh Sanikop #include <cstdint>
19*09537850SAkhilesh Sanikop #include <cstring>
20*09537850SAkhilesh Sanikop #include <memory>
21*09537850SAkhilesh Sanikop #include <new>
22*09537850SAkhilesh Sanikop #include <ostream>
23*09537850SAkhilesh Sanikop #include <string>
24*09537850SAkhilesh Sanikop #include <utility>
25*09537850SAkhilesh Sanikop
26*09537850SAkhilesh Sanikop #include "absl/memory/memory.h"
27*09537850SAkhilesh Sanikop #include "gav1/decoder_buffer.h"
28*09537850SAkhilesh Sanikop #include "gtest/gtest.h"
29*09537850SAkhilesh Sanikop #include "tests/utils.h"
30*09537850SAkhilesh Sanikop
31*09537850SAkhilesh Sanikop namespace libgav1 {
32*09537850SAkhilesh Sanikop namespace {
33*09537850SAkhilesh Sanikop
34*09537850SAkhilesh Sanikop const char kExpectedY4mHeader8bit[] = "YUV4MPEG2 W352 H288 F30:1 Ip C420jpeg\n";
35*09537850SAkhilesh Sanikop const char kExpectedY4mHeader10bit[] = "YUV4MPEG2 W352 H288 F30:1 Ip C420p10\n";
36*09537850SAkhilesh Sanikop const char kExpectedY4mHeader8bitMonochrome[] =
37*09537850SAkhilesh Sanikop "YUV4MPEG2 W352 H288 F30:1 Ip Cmono\n";
38*09537850SAkhilesh Sanikop const char kExpectedY4mHeader10bitMonochrome[] =
39*09537850SAkhilesh Sanikop "YUV4MPEG2 W352 H288 F30:1 Ip Cmono10\n";
40*09537850SAkhilesh Sanikop
41*09537850SAkhilesh Sanikop // Note: These are non-const because DecoderBuffer.plane is non-const.
42*09537850SAkhilesh Sanikop char fake_plane0[] = "PLANE0\n";
43*09537850SAkhilesh Sanikop char fake_plane1[] = "PLANE1\n";
44*09537850SAkhilesh Sanikop char fake_plane2[] = "PLANE2\n";
45*09537850SAkhilesh Sanikop
46*09537850SAkhilesh Sanikop constexpr size_t kExpectedRawDataBufferCount = 3;
47*09537850SAkhilesh Sanikop const char* kExpectedRawData[kExpectedRawDataBufferCount] = {
48*09537850SAkhilesh Sanikop fake_plane0, fake_plane1, fake_plane2};
49*09537850SAkhilesh Sanikop
50*09537850SAkhilesh Sanikop const char* const kExpectedRawDataMonochrome = fake_plane0;
51*09537850SAkhilesh Sanikop
52*09537850SAkhilesh Sanikop constexpr size_t kExpectedY4mDataBufferCount = 5;
53*09537850SAkhilesh Sanikop const char* const kExpectedY4mFileData8bit[kExpectedY4mDataBufferCount] = {
54*09537850SAkhilesh Sanikop kExpectedY4mHeader8bit, "FRAME\n", fake_plane0, fake_plane1, fake_plane2};
55*09537850SAkhilesh Sanikop const char* const kExpectedY4mFileData10bit[kExpectedY4mDataBufferCount] = {
56*09537850SAkhilesh Sanikop kExpectedY4mHeader10bit, "FRAME\n", fake_plane0, fake_plane1, fake_plane2};
57*09537850SAkhilesh Sanikop
58*09537850SAkhilesh Sanikop constexpr size_t kExpectedY4mDataBufferCountMonochrome = 3;
59*09537850SAkhilesh Sanikop const char* const
60*09537850SAkhilesh Sanikop kExpectedY4mFileData8bitMonochrome[kExpectedY4mDataBufferCountMonochrome] =
61*09537850SAkhilesh Sanikop {kExpectedY4mHeader8bitMonochrome, "FRAME\n", fake_plane0};
62*09537850SAkhilesh Sanikop const char* const
63*09537850SAkhilesh Sanikop kExpectedY4mFileData10bitMonochrome[kExpectedY4mDataBufferCountMonochrome] =
64*09537850SAkhilesh Sanikop {kExpectedY4mHeader10bitMonochrome, "FRAME\n", fake_plane0};
65*09537850SAkhilesh Sanikop
66*09537850SAkhilesh Sanikop // TODO(tomfinegan): Add a bitdepth arg, and test writing 10 bit frame buffers.
GetFakeDecoderBuffer(ImageFormat image_format)67*09537850SAkhilesh Sanikop std::unique_ptr<DecoderBuffer> GetFakeDecoderBuffer(ImageFormat image_format) {
68*09537850SAkhilesh Sanikop auto buffer = absl::WrapUnique(new (std::nothrow) DecoderBuffer);
69*09537850SAkhilesh Sanikop if (buffer == nullptr) return nullptr;
70*09537850SAkhilesh Sanikop buffer->chroma_sample_position = kChromaSamplePositionUnknown;
71*09537850SAkhilesh Sanikop buffer->image_format = image_format;
72*09537850SAkhilesh Sanikop buffer->bitdepth = 8;
73*09537850SAkhilesh Sanikop buffer->displayed_width[0] = static_cast<int>(strlen(fake_plane0));
74*09537850SAkhilesh Sanikop buffer->displayed_width[1] = static_cast<int>(strlen(fake_plane1));
75*09537850SAkhilesh Sanikop buffer->displayed_width[2] = static_cast<int>(strlen(fake_plane2));
76*09537850SAkhilesh Sanikop buffer->displayed_height[0] = 1;
77*09537850SAkhilesh Sanikop buffer->displayed_height[1] = 1;
78*09537850SAkhilesh Sanikop buffer->displayed_height[2] = 1;
79*09537850SAkhilesh Sanikop buffer->stride[0] = static_cast<int>(strlen(fake_plane0));
80*09537850SAkhilesh Sanikop buffer->stride[1] = static_cast<int>(strlen(fake_plane1));
81*09537850SAkhilesh Sanikop buffer->stride[2] = static_cast<int>(strlen(fake_plane2));
82*09537850SAkhilesh Sanikop buffer->plane[0] = reinterpret_cast<uint8_t*>(fake_plane0);
83*09537850SAkhilesh Sanikop buffer->plane[1] = reinterpret_cast<uint8_t*>(fake_plane1);
84*09537850SAkhilesh Sanikop buffer->plane[2] = reinterpret_cast<uint8_t*>(fake_plane2);
85*09537850SAkhilesh Sanikop buffer->user_private_data = 0;
86*09537850SAkhilesh Sanikop buffer->buffer_private_data = nullptr;
87*09537850SAkhilesh Sanikop return buffer;
88*09537850SAkhilesh Sanikop }
89*09537850SAkhilesh Sanikop
TEST(FileWriterTest,FailOpen)90*09537850SAkhilesh Sanikop TEST(FileWriterTest, FailOpen) {
91*09537850SAkhilesh Sanikop EXPECT_EQ(FileWriter::Open(test_utils::GetTestOutputFilePath("fail_open"),
92*09537850SAkhilesh Sanikop static_cast<FileWriter::FileType>(3), nullptr),
93*09537850SAkhilesh Sanikop nullptr);
94*09537850SAkhilesh Sanikop EXPECT_EQ(FileWriter::Open(test_utils::GetTestOutputFilePath("fail_open"),
95*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m, nullptr),
96*09537850SAkhilesh Sanikop nullptr);
97*09537850SAkhilesh Sanikop }
98*09537850SAkhilesh Sanikop
99*09537850SAkhilesh Sanikop struct FileWriterY4mHeaderTestParameters {
100*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters() = default;
101*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters(const FileWriterY4mHeaderTestParameters&) =
102*09537850SAkhilesh Sanikop default;
103*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters& operator=(
104*09537850SAkhilesh Sanikop const FileWriterY4mHeaderTestParameters&) = default;
105*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters(FileWriterY4mHeaderTestParameters&&) =
106*09537850SAkhilesh Sanikop default;
107*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters& operator=(
108*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters&&) = default;
109*09537850SAkhilesh Sanikop ~FileWriterY4mHeaderTestParameters() = default;
110*09537850SAkhilesh Sanikop
FileWriterY4mHeaderTestParameterslibgav1::__anon51d469d90111::FileWriterY4mHeaderTestParameters111*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters(std::string file_name,
112*09537850SAkhilesh Sanikop ChromaSamplePosition chroma_sample_position,
113*09537850SAkhilesh Sanikop ImageFormat image_format, int bitdepth,
114*09537850SAkhilesh Sanikop const char* expected_header_string)
115*09537850SAkhilesh Sanikop : file_name(std::move(file_name)),
116*09537850SAkhilesh Sanikop chroma_sample_position(chroma_sample_position),
117*09537850SAkhilesh Sanikop image_format(image_format),
118*09537850SAkhilesh Sanikop bitdepth(bitdepth),
119*09537850SAkhilesh Sanikop expected_header_string(expected_header_string) {}
120*09537850SAkhilesh Sanikop std::string file_name;
121*09537850SAkhilesh Sanikop ChromaSamplePosition chroma_sample_position = kChromaSamplePositionUnknown;
122*09537850SAkhilesh Sanikop ImageFormat image_format = kImageFormatMonochrome400;
123*09537850SAkhilesh Sanikop int bitdepth = 8;
124*09537850SAkhilesh Sanikop const char* expected_header_string = nullptr;
125*09537850SAkhilesh Sanikop };
126*09537850SAkhilesh Sanikop
operator <<(std::ostream & stream,const FileWriterY4mHeaderTestParameters & parameters)127*09537850SAkhilesh Sanikop std::ostream& operator<<(std::ostream& stream,
128*09537850SAkhilesh Sanikop const FileWriterY4mHeaderTestParameters& parameters) {
129*09537850SAkhilesh Sanikop stream << "file_name=" << parameters.file_name << "\n"
130*09537850SAkhilesh Sanikop << "chroma_sample_position=" << parameters.chroma_sample_position
131*09537850SAkhilesh Sanikop << "\n"
132*09537850SAkhilesh Sanikop << "image_format=" << parameters.image_format << "\n"
133*09537850SAkhilesh Sanikop << "bitdepth=" << parameters.bitdepth << "\n"
134*09537850SAkhilesh Sanikop << "expected_header_string=" << parameters.expected_header_string
135*09537850SAkhilesh Sanikop << "\n";
136*09537850SAkhilesh Sanikop return stream;
137*09537850SAkhilesh Sanikop }
138*09537850SAkhilesh Sanikop
139*09537850SAkhilesh Sanikop class FileWriterY4mHeaderTest
140*09537850SAkhilesh Sanikop : public testing::TestWithParam<FileWriterY4mHeaderTestParameters> {
141*09537850SAkhilesh Sanikop public:
FileWriterY4mHeaderTest()142*09537850SAkhilesh Sanikop FileWriterY4mHeaderTest() {
143*09537850SAkhilesh Sanikop test_parameters_ = GetParam();
144*09537850SAkhilesh Sanikop y4m_parameters_.width = 352;
145*09537850SAkhilesh Sanikop y4m_parameters_.height = 288;
146*09537850SAkhilesh Sanikop y4m_parameters_.frame_rate_numerator = 30;
147*09537850SAkhilesh Sanikop y4m_parameters_.frame_rate_denominator = 1;
148*09537850SAkhilesh Sanikop y4m_parameters_.chroma_sample_position =
149*09537850SAkhilesh Sanikop test_parameters_.chroma_sample_position;
150*09537850SAkhilesh Sanikop y4m_parameters_.image_format = test_parameters_.image_format;
151*09537850SAkhilesh Sanikop y4m_parameters_.bitdepth = test_parameters_.bitdepth;
152*09537850SAkhilesh Sanikop }
153*09537850SAkhilesh Sanikop FileWriterY4mHeaderTest(const FileWriterY4mHeaderTest&) = delete;
154*09537850SAkhilesh Sanikop FileWriterY4mHeaderTest& operator=(const FileWriterY4mHeaderTest&) = delete;
155*09537850SAkhilesh Sanikop ~FileWriterY4mHeaderTest() override = default;
156*09537850SAkhilesh Sanikop
157*09537850SAkhilesh Sanikop protected:
158*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters test_parameters_;
159*09537850SAkhilesh Sanikop FileWriter::Y4mParameters y4m_parameters_;
160*09537850SAkhilesh Sanikop };
161*09537850SAkhilesh Sanikop
TEST_P(FileWriterY4mHeaderTest,WriteY4mHeader)162*09537850SAkhilesh Sanikop TEST_P(FileWriterY4mHeaderTest, WriteY4mHeader) {
163*09537850SAkhilesh Sanikop const std::string file_name =
164*09537850SAkhilesh Sanikop test_utils::GetTestOutputFilePath(test_parameters_.file_name);
165*09537850SAkhilesh Sanikop EXPECT_NE(
166*09537850SAkhilesh Sanikop FileWriter::Open(file_name, FileWriter::kFileTypeY4m, &y4m_parameters_),
167*09537850SAkhilesh Sanikop nullptr);
168*09537850SAkhilesh Sanikop std::string y4m_header_string;
169*09537850SAkhilesh Sanikop test_utils::GetTestData(test_parameters_.file_name, true, &y4m_header_string);
170*09537850SAkhilesh Sanikop EXPECT_STREQ(y4m_header_string.c_str(),
171*09537850SAkhilesh Sanikop test_parameters_.expected_header_string);
172*09537850SAkhilesh Sanikop }
173*09537850SAkhilesh Sanikop
174*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(
175*09537850SAkhilesh Sanikop WriteY4mHeader, FileWriterY4mHeaderTest,
176*09537850SAkhilesh Sanikop testing::Values(
177*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters(
178*09537850SAkhilesh Sanikop "y4m_header_8bit", kChromaSamplePositionUnknown, kImageFormatYuv420,
179*09537850SAkhilesh Sanikop /*bitdepth=*/8, kExpectedY4mHeader8bit),
180*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters("y4m_header_10bit",
181*09537850SAkhilesh Sanikop kChromaSamplePositionUnknown,
182*09537850SAkhilesh Sanikop kImageFormatYuv420, /*bitdepth=*/10,
183*09537850SAkhilesh Sanikop kExpectedY4mHeader10bit),
184*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters("y4m_header_8bit_monochrome",
185*09537850SAkhilesh Sanikop kChromaSamplePositionUnknown,
186*09537850SAkhilesh Sanikop kImageFormatMonochrome400,
187*09537850SAkhilesh Sanikop /*bitdepth=*/8,
188*09537850SAkhilesh Sanikop kExpectedY4mHeader8bitMonochrome),
189*09537850SAkhilesh Sanikop FileWriterY4mHeaderTestParameters("y4m_header_10bit_monochrome",
190*09537850SAkhilesh Sanikop kChromaSamplePositionUnknown,
191*09537850SAkhilesh Sanikop kImageFormatMonochrome400,
192*09537850SAkhilesh Sanikop /*bitdepth=*/10,
193*09537850SAkhilesh Sanikop kExpectedY4mHeader10bitMonochrome)));
194*09537850SAkhilesh Sanikop
195*09537850SAkhilesh Sanikop struct FileWriterTestParameters {
196*09537850SAkhilesh Sanikop FileWriterTestParameters() = default;
197*09537850SAkhilesh Sanikop FileWriterTestParameters(const FileWriterTestParameters&) = default;
198*09537850SAkhilesh Sanikop FileWriterTestParameters& operator=(const FileWriterTestParameters&) =
199*09537850SAkhilesh Sanikop default;
200*09537850SAkhilesh Sanikop FileWriterTestParameters(FileWriterTestParameters&&) = default;
201*09537850SAkhilesh Sanikop FileWriterTestParameters& operator=(FileWriterTestParameters&&) = default;
202*09537850SAkhilesh Sanikop ~FileWriterTestParameters() = default;
203*09537850SAkhilesh Sanikop
FileWriterTestParameterslibgav1::__anon51d469d90111::FileWriterTestParameters204*09537850SAkhilesh Sanikop FileWriterTestParameters(std::string file_name,
205*09537850SAkhilesh Sanikop FileWriter::FileType file_type,
206*09537850SAkhilesh Sanikop const FileWriter::Y4mParameters* y4m_parameters,
207*09537850SAkhilesh Sanikop size_t num_frames)
208*09537850SAkhilesh Sanikop : file_name(std::move(file_name)),
209*09537850SAkhilesh Sanikop file_type(file_type),
210*09537850SAkhilesh Sanikop y4m_parameters(y4m_parameters),
211*09537850SAkhilesh Sanikop num_frames(num_frames) {}
212*09537850SAkhilesh Sanikop std::string file_name;
213*09537850SAkhilesh Sanikop FileWriter::FileType file_type = FileWriter::kFileTypeRaw;
214*09537850SAkhilesh Sanikop const FileWriter::Y4mParameters* y4m_parameters = nullptr;
215*09537850SAkhilesh Sanikop size_t num_frames = 1;
216*09537850SAkhilesh Sanikop };
217*09537850SAkhilesh Sanikop
operator <<(std::ostream & stream,const ChromaSamplePosition & position)218*09537850SAkhilesh Sanikop std::ostream& operator<<(std::ostream& stream,
219*09537850SAkhilesh Sanikop const ChromaSamplePosition& position) {
220*09537850SAkhilesh Sanikop switch (position) {
221*09537850SAkhilesh Sanikop case kChromaSamplePositionUnknown:
222*09537850SAkhilesh Sanikop stream << "kCromaSamplePositionUnknown";
223*09537850SAkhilesh Sanikop break;
224*09537850SAkhilesh Sanikop case kChromaSamplePositionVertical:
225*09537850SAkhilesh Sanikop stream << "kChromaSamplePositionVertical";
226*09537850SAkhilesh Sanikop break;
227*09537850SAkhilesh Sanikop case kChromaSamplePositionColocated:
228*09537850SAkhilesh Sanikop stream << "kChromaSamplePositionColocated";
229*09537850SAkhilesh Sanikop break;
230*09537850SAkhilesh Sanikop case kChromaSamplePositionReserved:
231*09537850SAkhilesh Sanikop stream << "kChromaSamplePositionReserved";
232*09537850SAkhilesh Sanikop break;
233*09537850SAkhilesh Sanikop }
234*09537850SAkhilesh Sanikop return stream;
235*09537850SAkhilesh Sanikop }
236*09537850SAkhilesh Sanikop
operator <<(std::ostream & stream,const ImageFormat & image_format)237*09537850SAkhilesh Sanikop std::ostream& operator<<(std::ostream& stream,
238*09537850SAkhilesh Sanikop const ImageFormat& image_format) {
239*09537850SAkhilesh Sanikop switch (image_format) {
240*09537850SAkhilesh Sanikop case kImageFormatMonochrome400:
241*09537850SAkhilesh Sanikop stream << "kImageFormatMonochrome400";
242*09537850SAkhilesh Sanikop break;
243*09537850SAkhilesh Sanikop case kImageFormatYuv420:
244*09537850SAkhilesh Sanikop stream << "kImageFormatYuv420";
245*09537850SAkhilesh Sanikop break;
246*09537850SAkhilesh Sanikop case kImageFormatYuv422:
247*09537850SAkhilesh Sanikop stream << "kImageFormatYuv422";
248*09537850SAkhilesh Sanikop break;
249*09537850SAkhilesh Sanikop case kImageFormatYuv444:
250*09537850SAkhilesh Sanikop stream << "kImageFormatYuv444";
251*09537850SAkhilesh Sanikop break;
252*09537850SAkhilesh Sanikop }
253*09537850SAkhilesh Sanikop return stream;
254*09537850SAkhilesh Sanikop }
255*09537850SAkhilesh Sanikop
operator <<(std::ostream & stream,const FileWriter::Y4mParameters & parameters)256*09537850SAkhilesh Sanikop std::ostream& operator<<(std::ostream& stream,
257*09537850SAkhilesh Sanikop const FileWriter::Y4mParameters& parameters) {
258*09537850SAkhilesh Sanikop stream << "y4m_parameters:\n"
259*09537850SAkhilesh Sanikop << " width=" << parameters.width << "\n"
260*09537850SAkhilesh Sanikop << " height=" << parameters.height << "\n"
261*09537850SAkhilesh Sanikop << " frame_rate_numerator=" << parameters.frame_rate_numerator << "\n"
262*09537850SAkhilesh Sanikop << " frame_rate_denominator=" << parameters.frame_rate_denominator
263*09537850SAkhilesh Sanikop << "\n"
264*09537850SAkhilesh Sanikop << " chroma_sample_position=" << parameters.chroma_sample_position
265*09537850SAkhilesh Sanikop << "\n"
266*09537850SAkhilesh Sanikop << " image_format=" << parameters.image_format << "\n"
267*09537850SAkhilesh Sanikop << " bitdepth=" << parameters.bitdepth << "\n";
268*09537850SAkhilesh Sanikop
269*09537850SAkhilesh Sanikop return stream;
270*09537850SAkhilesh Sanikop }
271*09537850SAkhilesh Sanikop
operator <<(std::ostream & stream,const FileWriterTestParameters & parameters)272*09537850SAkhilesh Sanikop std::ostream& operator<<(std::ostream& stream,
273*09537850SAkhilesh Sanikop const FileWriterTestParameters& parameters) {
274*09537850SAkhilesh Sanikop stream << "file_name=" << parameters.file_name << "\n"
275*09537850SAkhilesh Sanikop << "file_type="
276*09537850SAkhilesh Sanikop << (parameters.file_type == FileWriter::kFileTypeRaw ? "kFileTypeRaw"
277*09537850SAkhilesh Sanikop : "kFileTypeY4m")
278*09537850SAkhilesh Sanikop << "\n";
279*09537850SAkhilesh Sanikop if (parameters.y4m_parameters != nullptr) {
280*09537850SAkhilesh Sanikop stream << *parameters.y4m_parameters;
281*09537850SAkhilesh Sanikop } else {
282*09537850SAkhilesh Sanikop stream << "y4m_parameters: <nullptr>\n";
283*09537850SAkhilesh Sanikop }
284*09537850SAkhilesh Sanikop stream << "num_frames=" << parameters.num_frames << "\n";
285*09537850SAkhilesh Sanikop return stream;
286*09537850SAkhilesh Sanikop }
287*09537850SAkhilesh Sanikop
288*09537850SAkhilesh Sanikop class FileWriterTestBase
289*09537850SAkhilesh Sanikop : public testing::TestWithParam<FileWriterTestParameters> {
290*09537850SAkhilesh Sanikop public:
291*09537850SAkhilesh Sanikop FileWriterTestBase() = default;
292*09537850SAkhilesh Sanikop FileWriterTestBase(const FileWriterTestBase&) = delete;
293*09537850SAkhilesh Sanikop FileWriterTestBase& operator=(const FileWriterTestBase&) = delete;
294*09537850SAkhilesh Sanikop ~FileWriterTestBase() override = default;
295*09537850SAkhilesh Sanikop
296*09537850SAkhilesh Sanikop protected:
SetUp()297*09537850SAkhilesh Sanikop void SetUp() override { OpenWriter(GetParam()); }
298*09537850SAkhilesh Sanikop
OpenWriter(const FileWriterTestParameters & parameters)299*09537850SAkhilesh Sanikop void OpenWriter(const FileWriterTestParameters& parameters) {
300*09537850SAkhilesh Sanikop parameters_ = parameters;
301*09537850SAkhilesh Sanikop parameters_.file_name = parameters.file_name;
302*09537850SAkhilesh Sanikop file_writer_ = FileWriter::Open(
303*09537850SAkhilesh Sanikop test_utils::GetTestOutputFilePath(parameters.file_name),
304*09537850SAkhilesh Sanikop parameters_.file_type, parameters_.y4m_parameters);
305*09537850SAkhilesh Sanikop ASSERT_NE(file_writer_, nullptr);
306*09537850SAkhilesh Sanikop }
307*09537850SAkhilesh Sanikop
WriteFramesAndCloseFile()308*09537850SAkhilesh Sanikop void WriteFramesAndCloseFile() {
309*09537850SAkhilesh Sanikop if (parameters_.y4m_parameters != nullptr) {
310*09537850SAkhilesh Sanikop image_format_ = parameters_.y4m_parameters->image_format;
311*09537850SAkhilesh Sanikop }
312*09537850SAkhilesh Sanikop decoder_buffer_ = GetFakeDecoderBuffer(image_format_);
313*09537850SAkhilesh Sanikop for (size_t frame_num = 0; frame_num < parameters_.num_frames;
314*09537850SAkhilesh Sanikop ++frame_num) {
315*09537850SAkhilesh Sanikop ASSERT_TRUE(file_writer_->WriteFrame(*decoder_buffer_));
316*09537850SAkhilesh Sanikop }
317*09537850SAkhilesh Sanikop file_writer_ = nullptr;
318*09537850SAkhilesh Sanikop }
319*09537850SAkhilesh Sanikop
320*09537850SAkhilesh Sanikop ImageFormat image_format_ = kImageFormatYuv420;
321*09537850SAkhilesh Sanikop FileWriterTestParameters parameters_;
322*09537850SAkhilesh Sanikop std::unique_ptr<FileWriter> file_writer_;
323*09537850SAkhilesh Sanikop std::unique_ptr<DecoderBuffer> decoder_buffer_;
324*09537850SAkhilesh Sanikop };
325*09537850SAkhilesh Sanikop
326*09537850SAkhilesh Sanikop class FileWriterTestRaw : public FileWriterTestBase {
327*09537850SAkhilesh Sanikop public:
328*09537850SAkhilesh Sanikop FileWriterTestRaw() = default;
329*09537850SAkhilesh Sanikop FileWriterTestRaw(const FileWriterTestRaw&) = delete;
330*09537850SAkhilesh Sanikop FileWriterTestRaw& operator=(const FileWriterTestRaw&) = delete;
331*09537850SAkhilesh Sanikop ~FileWriterTestRaw() override = default;
332*09537850SAkhilesh Sanikop
333*09537850SAkhilesh Sanikop protected:
SetUp()334*09537850SAkhilesh Sanikop void SetUp() override { FileWriterTestBase::SetUp(); }
335*09537850SAkhilesh Sanikop };
336*09537850SAkhilesh Sanikop
337*09537850SAkhilesh Sanikop class FileWriterTestY4m : public FileWriterTestBase {
338*09537850SAkhilesh Sanikop public:
339*09537850SAkhilesh Sanikop FileWriterTestY4m() = default;
340*09537850SAkhilesh Sanikop FileWriterTestY4m(const FileWriterTestY4m&) = delete;
341*09537850SAkhilesh Sanikop FileWriterTestY4m& operator=(const FileWriterTestY4m&) = delete;
342*09537850SAkhilesh Sanikop ~FileWriterTestY4m() override = default;
343*09537850SAkhilesh Sanikop
344*09537850SAkhilesh Sanikop protected:
SetUp()345*09537850SAkhilesh Sanikop void SetUp() override { FileWriterTestBase::SetUp(); }
346*09537850SAkhilesh Sanikop };
347*09537850SAkhilesh Sanikop
TEST_P(FileWriterTestRaw,WriteRawFrames)348*09537850SAkhilesh Sanikop TEST_P(FileWriterTestRaw, WriteRawFrames) {
349*09537850SAkhilesh Sanikop WriteFramesAndCloseFile();
350*09537850SAkhilesh Sanikop
351*09537850SAkhilesh Sanikop std::string actual_file_data;
352*09537850SAkhilesh Sanikop test_utils::GetTestData(parameters_.file_name, true, &actual_file_data);
353*09537850SAkhilesh Sanikop
354*09537850SAkhilesh Sanikop std::string expected_file_data;
355*09537850SAkhilesh Sanikop for (size_t frame_num = 0; frame_num < parameters_.num_frames; ++frame_num) {
356*09537850SAkhilesh Sanikop if (image_format_ == kImageFormatMonochrome400) {
357*09537850SAkhilesh Sanikop expected_file_data += kExpectedRawDataMonochrome;
358*09537850SAkhilesh Sanikop } else {
359*09537850SAkhilesh Sanikop for (const auto& buffer : kExpectedRawData) {
360*09537850SAkhilesh Sanikop expected_file_data += buffer;
361*09537850SAkhilesh Sanikop }
362*09537850SAkhilesh Sanikop }
363*09537850SAkhilesh Sanikop }
364*09537850SAkhilesh Sanikop
365*09537850SAkhilesh Sanikop ASSERT_EQ(actual_file_data, expected_file_data);
366*09537850SAkhilesh Sanikop }
367*09537850SAkhilesh Sanikop
TEST_P(FileWriterTestY4m,WriteY4mFrames)368*09537850SAkhilesh Sanikop TEST_P(FileWriterTestY4m, WriteY4mFrames) {
369*09537850SAkhilesh Sanikop WriteFramesAndCloseFile();
370*09537850SAkhilesh Sanikop
371*09537850SAkhilesh Sanikop std::string actual_file_data;
372*09537850SAkhilesh Sanikop test_utils::GetTestData(parameters_.file_name, true, &actual_file_data);
373*09537850SAkhilesh Sanikop
374*09537850SAkhilesh Sanikop std::string expected_file_data;
375*09537850SAkhilesh Sanikop for (size_t frame_num = 0; frame_num < parameters_.num_frames; ++frame_num) {
376*09537850SAkhilesh Sanikop if (image_format_ == kImageFormatMonochrome400) {
377*09537850SAkhilesh Sanikop const char* const* expected_data_planes =
378*09537850SAkhilesh Sanikop (parameters_.y4m_parameters->bitdepth == 8)
379*09537850SAkhilesh Sanikop ? kExpectedY4mFileData8bitMonochrome
380*09537850SAkhilesh Sanikop : kExpectedY4mFileData10bitMonochrome;
381*09537850SAkhilesh Sanikop // Skip the Y4M file header "plane" after frame 0.
382*09537850SAkhilesh Sanikop for (size_t buffer_num = (frame_num == 0) ? 0 : 1;
383*09537850SAkhilesh Sanikop buffer_num < kExpectedY4mDataBufferCountMonochrome; ++buffer_num) {
384*09537850SAkhilesh Sanikop expected_file_data += expected_data_planes[buffer_num];
385*09537850SAkhilesh Sanikop }
386*09537850SAkhilesh Sanikop } else {
387*09537850SAkhilesh Sanikop const char* const* expected_data_planes =
388*09537850SAkhilesh Sanikop (parameters_.y4m_parameters->bitdepth == 8)
389*09537850SAkhilesh Sanikop ? kExpectedY4mFileData8bit
390*09537850SAkhilesh Sanikop : kExpectedY4mFileData10bit;
391*09537850SAkhilesh Sanikop
392*09537850SAkhilesh Sanikop // Skip the Y4M file header "plane" after frame 0.
393*09537850SAkhilesh Sanikop for (size_t buffer_num = (frame_num == 0) ? 0 : 1;
394*09537850SAkhilesh Sanikop buffer_num < kExpectedY4mDataBufferCount; ++buffer_num) {
395*09537850SAkhilesh Sanikop expected_file_data += expected_data_planes[buffer_num];
396*09537850SAkhilesh Sanikop }
397*09537850SAkhilesh Sanikop }
398*09537850SAkhilesh Sanikop }
399*09537850SAkhilesh Sanikop
400*09537850SAkhilesh Sanikop ASSERT_EQ(actual_file_data, expected_file_data);
401*09537850SAkhilesh Sanikop }
402*09537850SAkhilesh Sanikop
403*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(
404*09537850SAkhilesh Sanikop WriteRawFrames, FileWriterTestRaw,
405*09537850SAkhilesh Sanikop testing::Values(
406*09537850SAkhilesh Sanikop FileWriterTestParameters("raw_frames_test_1frame",
407*09537850SAkhilesh Sanikop FileWriter::kFileTypeRaw,
408*09537850SAkhilesh Sanikop /*y4m_parameters=*/nullptr,
409*09537850SAkhilesh Sanikop /*num_frames=*/1),
410*09537850SAkhilesh Sanikop FileWriterTestParameters("raw_frames_test_5frames",
411*09537850SAkhilesh Sanikop FileWriter::kFileTypeRaw,
412*09537850SAkhilesh Sanikop /*y4m_parameters=*/nullptr,
413*09537850SAkhilesh Sanikop /*num_frames=*/5),
414*09537850SAkhilesh Sanikop FileWriterTestParameters("raw_frames_test_1frame_monochrome",
415*09537850SAkhilesh Sanikop FileWriter::kFileTypeRaw,
416*09537850SAkhilesh Sanikop /*y4m_parameters=*/nullptr,
417*09537850SAkhilesh Sanikop /*num_frames=*/1),
418*09537850SAkhilesh Sanikop FileWriterTestParameters("raw_frames_test_5frames_monochrome",
419*09537850SAkhilesh Sanikop FileWriter::kFileTypeRaw,
420*09537850SAkhilesh Sanikop /*y4m_parameters=*/nullptr,
421*09537850SAkhilesh Sanikop /*num_frames=*/5)));
422*09537850SAkhilesh Sanikop
423*09537850SAkhilesh Sanikop const FileWriter::Y4mParameters kY4mParameters8Bit = {
424*09537850SAkhilesh Sanikop 352, // width
425*09537850SAkhilesh Sanikop 288, // height
426*09537850SAkhilesh Sanikop 30, // frame_rate_numerator
427*09537850SAkhilesh Sanikop 1, // frame_rate_denominator
428*09537850SAkhilesh Sanikop kChromaSamplePositionUnknown,
429*09537850SAkhilesh Sanikop kImageFormatYuv420,
430*09537850SAkhilesh Sanikop 8 // bitdepth
431*09537850SAkhilesh Sanikop };
432*09537850SAkhilesh Sanikop
433*09537850SAkhilesh Sanikop const FileWriter::Y4mParameters kY4mParameters10Bit = {
434*09537850SAkhilesh Sanikop 352, // width
435*09537850SAkhilesh Sanikop 288, // height
436*09537850SAkhilesh Sanikop 30, // frame_rate_numerator
437*09537850SAkhilesh Sanikop 1, // frame_rate_denominator
438*09537850SAkhilesh Sanikop kChromaSamplePositionUnknown,
439*09537850SAkhilesh Sanikop kImageFormatYuv420,
440*09537850SAkhilesh Sanikop 10 // bitdepth
441*09537850SAkhilesh Sanikop };
442*09537850SAkhilesh Sanikop
443*09537850SAkhilesh Sanikop const FileWriter::Y4mParameters kY4mParameters8BitMonochrome = {
444*09537850SAkhilesh Sanikop 352, // width
445*09537850SAkhilesh Sanikop 288, // height
446*09537850SAkhilesh Sanikop 30, // frame_rate_numerator
447*09537850SAkhilesh Sanikop 1, // frame_rate_denominator
448*09537850SAkhilesh Sanikop kChromaSamplePositionUnknown,
449*09537850SAkhilesh Sanikop kImageFormatMonochrome400,
450*09537850SAkhilesh Sanikop 8 // bitdepth
451*09537850SAkhilesh Sanikop };
452*09537850SAkhilesh Sanikop
453*09537850SAkhilesh Sanikop const FileWriter::Y4mParameters kY4mParameters10BitMonochrome = {
454*09537850SAkhilesh Sanikop 352, // width
455*09537850SAkhilesh Sanikop 288, // height
456*09537850SAkhilesh Sanikop 30, // frame_rate_numerator
457*09537850SAkhilesh Sanikop 1, // frame_rate_denominator
458*09537850SAkhilesh Sanikop kChromaSamplePositionUnknown,
459*09537850SAkhilesh Sanikop kImageFormatMonochrome400,
460*09537850SAkhilesh Sanikop 10 // bitdepth
461*09537850SAkhilesh Sanikop };
462*09537850SAkhilesh Sanikop
463*09537850SAkhilesh Sanikop INSTANTIATE_TEST_SUITE_P(
464*09537850SAkhilesh Sanikop WriteY4mFrames, FileWriterTestY4m,
465*09537850SAkhilesh Sanikop testing::Values(
466*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_8bit_1frame",
467*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m, &kY4mParameters8Bit,
468*09537850SAkhilesh Sanikop /*num_frames=*/1),
469*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_8bit_5frames",
470*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m, &kY4mParameters8Bit,
471*09537850SAkhilesh Sanikop /*num_frames=*/5),
472*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_10bit_1frame",
473*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m, &kY4mParameters10Bit,
474*09537850SAkhilesh Sanikop /*num_frames=*/1),
475*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_10bit_5frames",
476*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m, &kY4mParameters10Bit,
477*09537850SAkhilesh Sanikop /*num_frames=*/5),
478*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_8bit_1frame_monochrome",
479*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m,
480*09537850SAkhilesh Sanikop &kY4mParameters8BitMonochrome,
481*09537850SAkhilesh Sanikop /*num_frames=*/1),
482*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_8bit_5frames_monochrome",
483*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m,
484*09537850SAkhilesh Sanikop &kY4mParameters8BitMonochrome,
485*09537850SAkhilesh Sanikop /*num_frames=*/5),
486*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_10bit_1frame_monochrome",
487*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m,
488*09537850SAkhilesh Sanikop &kY4mParameters10BitMonochrome,
489*09537850SAkhilesh Sanikop /*num_frames=*/1),
490*09537850SAkhilesh Sanikop FileWriterTestParameters("y4m_frames_test_10bit_5frames_monochrome",
491*09537850SAkhilesh Sanikop FileWriter::kFileTypeY4m,
492*09537850SAkhilesh Sanikop &kY4mParameters10BitMonochrome,
493*09537850SAkhilesh Sanikop /*num_frames=*/5)));
494*09537850SAkhilesh Sanikop
495*09537850SAkhilesh Sanikop } // namespace
496*09537850SAkhilesh Sanikop } // namespace libgav1
497