blob: 2a7992865ab171159a607b79704404bf2003005a [file] [log] [blame]
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +00001/*
stefan@webrtc.org0fe21712012-02-22 11:21:18 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +00003 *
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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "third_party/libyuv/include/libyuv.h"
12
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000013#include <math.h>
14#include <string.h>
15
kwibergc891eb42016-03-02 03:41:34 -080016#include <memory>
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/video/i420_buffer.h"
19#include "api/video/video_frame.h"
20#include "common_video/libyuv/include/webrtc_libyuv.h"
21#include "test/frame_utils.h"
22#include "test/gmock.h"
23#include "test/gtest.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "test/testsupport/file_utils.h"
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000025
26namespace webrtc {
27
nisse69adc9c2016-06-02 00:58:35 -070028namespace {
29void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) {
30 *stride_y = 16 * ((width + 15) / 16);
31 *stride_uv = 16 * ((width + 31) / 32);
32}
33
34} // Anonymous namespace
35
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000036class TestLibYuv : public ::testing::Test {
37 protected:
38 TestLibYuv();
Mirko Bonadeid93a51d2018-07-17 15:47:51 +020039 void SetUp() override;
40 void TearDown() override;
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000041
42 FILE* source_file_;
nisse115bd152016-09-30 04:14:07 -070043 std::unique_ptr<VideoFrame> orig_frame_;
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000044 const int width_;
45 const int height_;
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +000046 const int size_y_;
47 const int size_uv_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000048 const size_t frame_length_;
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000049};
50
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000051TestLibYuv::TestLibYuv()
52 : source_file_(NULL),
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +000053 orig_frame_(),
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000054 width_(352),
55 height_(288),
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +000056 size_y_(width_ * height_),
jbauch0f2e9392015-12-10 03:11:42 -080057 size_uv_(((width_ + 1) / 2) * ((height_ + 1) / 2)),
nisseeb44b392017-04-28 07:18:05 -070058 frame_length_(CalcBufferSize(VideoType::kI420, 352, 288)) {}
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000059
60void TestLibYuv::SetUp() {
Yves Gerey665174f2018-06-19 15:03:05 +020061 const std::string input_file_name =
62 webrtc::test::ResourcePath("foreman_cif", "yuv");
63 source_file_ = fopen(input_file_name.c_str(), "rb");
64 ASSERT_TRUE(source_file_ != NULL)
65 << "Cannot read file: " << input_file_name << "\n";
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +000066
magjed3f075492017-06-01 10:02:26 -070067 rtc::scoped_refptr<I420BufferInterface> buffer(
nisse115bd152016-09-30 04:14:07 -070068 test::ReadI420Buffer(width_, height_, source_file_));
69
Artem Titov1ebfb6a2019-01-03 23:49:37 +010070 orig_frame_ =
Mirko Bonadei317a1f02019-09-17 17:06:18 +020071 std::make_unique<VideoFrame>(VideoFrame::Builder()
72 .set_video_frame_buffer(buffer)
73 .set_rotation(webrtc::kVideoRotation_0)
74 .set_timestamp_us(0)
75 .build());
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000076}
77
78void TestLibYuv::TearDown() {
79 if (source_file_ != NULL) {
80 ASSERT_EQ(0, fclose(source_file_));
81 }
82 source_file_ = NULL;
83}
84
85TEST_F(TestLibYuv, ConvertSanityTest) {
86 // TODO(mikhal)
87}
88
89TEST_F(TestLibYuv, ConvertTest) {
90 // Reading YUV frame - testing on the first frame of the foreman sequence
91 int j = 0;
Yves Gerey665174f2018-06-19 15:03:05 +020092 std::string output_file_name =
93 webrtc::test::OutputPath() + "LibYuvTest_conversion.yuv";
94 FILE* output_file = fopen(output_file_name.c_str(), "wb");
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000095 ASSERT_TRUE(output_file != NULL);
96
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +000097 double psnr = 0.0;
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +000098
magjed3f075492017-06-01 10:02:26 -070099 rtc::scoped_refptr<I420Buffer> res_i420_buffer =
100 I420Buffer::Create(width_, height_);
nisse64ec8f82016-09-27 00:17:25 -0700101
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +0000102 printf("\nConvert #%d I420 <-> I420 \n", j);
kwibergc891eb42016-03-02 03:41:34 -0800103 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]);
nisseeb44b392017-04-28 07:18:05 -0700104 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kI420, 0,
105 out_i420_buffer.get()));
mallikarjun8212e555b2017-11-15 14:35:56 +0530106 int y_size = width_ * height_;
107 int u_size = res_i420_buffer->ChromaWidth() * res_i420_buffer->ChromaHeight();
108 int ret = libyuv::I420Copy(
109 out_i420_buffer.get(), width_, out_i420_buffer.get() + y_size,
110 width_ >> 1, out_i420_buffer.get() + y_size + u_size, width_ >> 1,
111 res_i420_buffer.get()->MutableDataY(), res_i420_buffer.get()->StrideY(),
112 res_i420_buffer.get()->MutableDataU(), res_i420_buffer.get()->StrideU(),
113 res_i420_buffer.get()->MutableDataV(), res_i420_buffer.get()->StrideV(),
114 width_, height_);
115 EXPECT_EQ(0, ret);
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +0000116
nisse64ec8f82016-09-27 00:17:25 -0700117 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +0000118 return;
119 }
magjed3f075492017-06-01 10:02:26 -0700120 psnr =
121 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +0000122 EXPECT_EQ(48.0, psnr);
123 j++;
124
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000125 printf("\nConvert #%d I420 <-> RGB24\n", j);
kwibergc891eb42016-03-02 03:41:34 -0800126 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]);
mikhal@webrtc.org91a03402012-10-30 19:19:32 +0000127 // Align the stride values for the output frame.
128 int stride_y = 0;
129 int stride_uv = 0;
130 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv);
nisse64ec8f82016-09-27 00:17:25 -0700131 res_i420_buffer =
132 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv);
nisseeb44b392017-04-28 07:18:05 -0700133 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB24, 0,
134 res_rgb_buffer2.get()));
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000135
mallikarjun8212e555b2017-11-15 14:35:56 +0530136 ret = libyuv::ConvertToI420(
137 res_rgb_buffer2.get(), 0, res_i420_buffer.get()->MutableDataY(),
138 res_i420_buffer.get()->StrideY(), res_i420_buffer.get()->MutableDataU(),
139 res_i420_buffer.get()->StrideU(), res_i420_buffer.get()->MutableDataV(),
140 res_i420_buffer.get()->StrideV(), 0, 0, width_, height_,
141 res_i420_buffer->width(), res_i420_buffer->height(), libyuv::kRotate0,
142 ConvertVideoType(VideoType::kRGB24));
mikhal@webrtc.orge2642492011-12-28 21:21:40 +0000143
mallikarjun8212e555b2017-11-15 14:35:56 +0530144 EXPECT_EQ(0, ret);
nisse64ec8f82016-09-27 00:17:25 -0700145 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
leozwang@webrtc.org2fc6e382012-05-29 17:33:13 +0000146 return;
147 }
magjed3f075492017-06-01 10:02:26 -0700148 psnr =
149 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000150
mikhal@webrtc.orge2642492011-12-28 21:21:40 +0000151 // Optimization Speed- quality trade-off => 45 dB only (platform dependant).
stefan@webrtc.org0fe21712012-02-22 11:21:18 +0000152 EXPECT_GT(ceil(psnr), 44);
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000153 j++;
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000154
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000155 printf("\nConvert #%d I420 <-> UYVY\n", j);
kwibergc891eb42016-03-02 03:41:34 -0800156 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]);
nisseeb44b392017-04-28 07:18:05 -0700157 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kUYVY, 0,
158 out_uyvy_buffer.get()));
mallikarjun8212e555b2017-11-15 14:35:56 +0530159
160 ret = libyuv::ConvertToI420(
161 out_uyvy_buffer.get(), 0, res_i420_buffer.get()->MutableDataY(),
162 res_i420_buffer.get()->StrideY(), res_i420_buffer.get()->MutableDataU(),
163 res_i420_buffer.get()->StrideU(), res_i420_buffer.get()->MutableDataV(),
164 res_i420_buffer.get()->StrideV(), 0, 0, width_, height_,
165 res_i420_buffer->width(), res_i420_buffer->height(), libyuv::kRotate0,
166 ConvertVideoType(VideoType::kUYVY));
167
168 EXPECT_EQ(0, ret);
magjed3f075492017-06-01 10:02:26 -0700169 psnr =
170 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000171 EXPECT_EQ(48.0, psnr);
nisse64ec8f82016-09-27 00:17:25 -0700172 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000173 return;
174 }
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000175 j++;
176
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000177 printf("\nConvert #%d I420 <-> YUY2\n", j);
kwibergc891eb42016-03-02 03:41:34 -0800178 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]);
nisseeb44b392017-04-28 07:18:05 -0700179 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kYUY2, 0,
180 out_yuy2_buffer.get()));
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000181
mallikarjun8212e555b2017-11-15 14:35:56 +0530182 ret = libyuv::ConvertToI420(
183 out_yuy2_buffer.get(), 0, res_i420_buffer.get()->MutableDataY(),
184 res_i420_buffer.get()->StrideY(), res_i420_buffer.get()->MutableDataU(),
185 res_i420_buffer.get()->StrideU(), res_i420_buffer.get()->MutableDataV(),
186 res_i420_buffer.get()->StrideV(), 0, 0, width_, height_,
187 res_i420_buffer->width(), res_i420_buffer->height(), libyuv::kRotate0,
188 ConvertVideoType(VideoType::kYUY2));
189
190 EXPECT_EQ(0, ret);
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000191
nisse64ec8f82016-09-27 00:17:25 -0700192 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +0000193 return;
leozwang@webrtc.org2fc6e382012-05-29 17:33:13 +0000194 }
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000195
magjed3f075492017-06-01 10:02:26 -0700196 psnr =
197 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000198 EXPECT_EQ(48.0, psnr);
nisse64ec8f82016-09-27 00:17:25 -0700199
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000200 printf("\nConvert #%d I420 <-> RGB565\n", j);
kwibergc891eb42016-03-02 03:41:34 -0800201 std::unique_ptr<uint8_t[]> out_rgb565_buffer(
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000202 new uint8_t[width_ * height_ * 2]);
nisseeb44b392017-04-28 07:18:05 -0700203 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB565, 0,
204 out_rgb565_buffer.get()));
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000205
mallikarjun8212e555b2017-11-15 14:35:56 +0530206 ret = libyuv::ConvertToI420(
207 out_rgb565_buffer.get(), 0, res_i420_buffer.get()->MutableDataY(),
208 res_i420_buffer.get()->StrideY(), res_i420_buffer.get()->MutableDataU(),
209 res_i420_buffer.get()->StrideU(), res_i420_buffer.get()->MutableDataV(),
210 res_i420_buffer.get()->StrideV(), 0, 0, width_, height_,
211 res_i420_buffer->width(), res_i420_buffer->height(), libyuv::kRotate0,
212 ConvertVideoType(VideoType::kRGB565));
213
214 EXPECT_EQ(0, ret);
nisse64ec8f82016-09-27 00:17:25 -0700215 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +0000216 return;
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000217 }
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000218 j++;
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000219
magjed3f075492017-06-01 10:02:26 -0700220 psnr =
221 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
leozwang@webrtc.org1ea25b42012-05-04 17:55:57 +0000222 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565,
223 // Another example is I420ToRGB24, the psnr is 44
mikhal@webrtc.org737ed3b2012-11-01 15:45:38 +0000224 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB.
leozwang@webrtc.org1ea25b42012-05-04 17:55:57 +0000225 EXPECT_GT(ceil(psnr), 40);
leozwang@webrtc.org83958df2012-05-04 17:07:45 +0000226
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000227 printf("\nConvert #%d I420 <-> ARGB8888\n", j);
kwibergc891eb42016-03-02 03:41:34 -0800228 std::unique_ptr<uint8_t[]> out_argb8888_buffer(
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000229 new uint8_t[width_ * height_ * 4]);
nisseeb44b392017-04-28 07:18:05 -0700230 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kARGB, 0,
231 out_argb8888_buffer.get()));
leozwang@webrtc.org83958df2012-05-04 17:07:45 +0000232
mallikarjun8212e555b2017-11-15 14:35:56 +0530233 ret = libyuv::ConvertToI420(
234 out_argb8888_buffer.get(), 0, res_i420_buffer.get()->MutableDataY(),
235 res_i420_buffer.get()->StrideY(), res_i420_buffer.get()->MutableDataU(),
236 res_i420_buffer.get()->StrideU(), res_i420_buffer.get()->MutableDataV(),
237 res_i420_buffer.get()->StrideV(), 0, 0, width_, height_,
238 res_i420_buffer->width(), res_i420_buffer->height(), libyuv::kRotate0,
239 ConvertVideoType(VideoType::kARGB));
240
241 EXPECT_EQ(0, ret);
leozwang@webrtc.org83958df2012-05-04 17:07:45 +0000242
nisse64ec8f82016-09-27 00:17:25 -0700243 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
leozwang@webrtc.org2fc6e382012-05-29 17:33:13 +0000244 return;
245 }
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000246
magjed3f075492017-06-01 10:02:26 -0700247 psnr =
248 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
nisse64ec8f82016-09-27 00:17:25 -0700249 // TODO(leozwang) Investigate the right psnr should be set for
250 // I420ToARGB8888,
leozwang@webrtc.org329fcbb2012-05-04 21:31:22 +0000251 EXPECT_GT(ceil(psnr), 42);
leozwang@webrtc.org83958df2012-05-04 17:07:45 +0000252
kjellander@webrtc.org94558d82012-01-04 13:51:50 +0000253 ASSERT_EQ(0, fclose(output_file));
mikhal@webrtc.org6f7fbc72011-12-20 17:38:28 +0000254}
255
mikhal@webrtc.org32b3f402012-11-20 23:52:50 +0000256TEST_F(TestLibYuv, ConvertAlignedFrame) {
257 // Reading YUV frame - testing on the first frame of the foreman sequence
Yves Gerey665174f2018-06-19 15:03:05 +0200258 std::string output_file_name =
259 webrtc::test::OutputPath() + "LibYuvTest_conversion.yuv";
260 FILE* output_file = fopen(output_file_name.c_str(), "wb");
mikhal@webrtc.org32b3f402012-11-20 23:52:50 +0000261 ASSERT_TRUE(output_file != NULL);
262
263 double psnr = 0.0;
264
mikhal@webrtc.org32b3f402012-11-20 23:52:50 +0000265 int stride_y = 0;
266 int stride_uv = 0;
267 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv);
nisse64ec8f82016-09-27 00:17:25 -0700268
269 rtc::scoped_refptr<I420Buffer> res_i420_buffer =
270 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv);
kwibergc891eb42016-03-02 03:41:34 -0800271 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]);
nisseeb44b392017-04-28 07:18:05 -0700272 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kI420, 0,
mikhal@webrtc.org32b3f402012-11-20 23:52:50 +0000273 out_i420_buffer.get()));
mallikarjun8212e555b2017-11-15 14:35:56 +0530274 int y_size = width_ * height_;
275 int u_size = res_i420_buffer->ChromaWidth() * res_i420_buffer->ChromaHeight();
276 int ret = libyuv::I420Copy(
277 out_i420_buffer.get(), width_, out_i420_buffer.get() + y_size,
278 width_ >> 1, out_i420_buffer.get() + y_size + u_size, width_ >> 1,
279 res_i420_buffer.get()->MutableDataY(), res_i420_buffer.get()->StrideY(),
280 res_i420_buffer.get()->MutableDataU(), res_i420_buffer.get()->StrideU(),
281 res_i420_buffer.get()->MutableDataV(), res_i420_buffer.get()->StrideV(),
282 width_, height_);
283
284 EXPECT_EQ(0, ret);
mikhal@webrtc.org32b3f402012-11-20 23:52:50 +0000285
nisse64ec8f82016-09-27 00:17:25 -0700286 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) {
mikhal@webrtc.org32b3f402012-11-20 23:52:50 +0000287 return;
288 }
magjed3f075492017-06-01 10:02:26 -0700289 psnr =
290 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer);
mikhal@webrtc.org32b3f402012-11-20 23:52:50 +0000291 EXPECT_EQ(48.0, psnr);
292}
293
magjed5a872452016-10-20 03:34:29 -0700294static uint8_t Average(int a, int b, int c, int d) {
295 return (a + b + c + d + 2) / 4;
296}
297
298TEST_F(TestLibYuv, NV12Scale2x2to2x2) {
Yves Gerey665174f2018-06-19 15:03:05 +0200299 const std::vector<uint8_t> src_y = {0, 1, 2, 3};
magjed5a872452016-10-20 03:34:29 -0700300 const std::vector<uint8_t> src_uv = {0, 1};
301 std::vector<uint8_t> dst_y(4);
302 std::vector<uint8_t> dst_uv(2);
303
Anders Carlssonbfe45c22017-06-19 16:46:31 +0200304 uint8_t* tmp_buffer = nullptr;
305
Yves Gerey665174f2018-06-19 15:03:05 +0200306 NV12Scale(tmp_buffer, src_y.data(), 2, src_uv.data(), 2, 2, 2, dst_y.data(),
307 2, dst_uv.data(), 2, 2, 2);
magjed5a872452016-10-20 03:34:29 -0700308
309 EXPECT_THAT(dst_y, ::testing::ContainerEq(src_y));
310 EXPECT_THAT(dst_uv, ::testing::ContainerEq(src_uv));
311}
312
313TEST_F(TestLibYuv, NV12Scale4x4to2x2) {
Yves Gerey665174f2018-06-19 15:03:05 +0200314 const uint8_t src_y[] = {0, 1, 2, 3, 4, 5, 6, 7,
315 8, 9, 10, 11, 12, 13, 14, 15};
316 const uint8_t src_uv[] = {0, 1, 2, 3, 4, 5, 6, 7};
magjed5a872452016-10-20 03:34:29 -0700317 std::vector<uint8_t> dst_y(4);
318 std::vector<uint8_t> dst_uv(2);
319
320 std::vector<uint8_t> tmp_buffer;
Anders Carlssonbfe45c22017-06-19 16:46:31 +0200321 const int src_chroma_width = (4 + 1) / 2;
322 const int src_chroma_height = (4 + 1) / 2;
323 const int dst_chroma_width = (2 + 1) / 2;
324 const int dst_chroma_height = (2 + 1) / 2;
325 tmp_buffer.resize(src_chroma_width * src_chroma_height * 2 +
326 dst_chroma_width * dst_chroma_height * 2);
327 tmp_buffer.shrink_to_fit();
328
Yves Gerey665174f2018-06-19 15:03:05 +0200329 NV12Scale(tmp_buffer.data(), src_y, 4, src_uv, 4, 4, 4, dst_y.data(), 2,
330 dst_uv.data(), 2, 2, 2);
magjed5a872452016-10-20 03:34:29 -0700331
332 EXPECT_THAT(dst_y, ::testing::ElementsAre(
333 Average(0, 1, 4, 5), Average(2, 3, 6, 7),
334 Average(8, 9, 12, 13), Average(10, 11, 14, 15)));
335 EXPECT_THAT(dst_uv,
336 ::testing::ElementsAre(Average(0, 2, 4, 6), Average(1, 3, 5, 7)));
337}
338
jbauch0f2e9392015-12-10 03:11:42 -0800339} // namespace webrtc