Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1018)

Side by Side Diff: webrtc/common_video/libyuv/libyuv_unittest.cc

Issue 2362683002: New helper function test::ReadI420Buffer, refactor FrameReader to use it. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <math.h> 11 #include <math.h>
12 #include <string.h> 12 #include <string.h>
13 13
14 #include <memory> 14 #include <memory>
15 15
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
18 #include "webrtc/test/frame_utils.h"
18 #include "webrtc/test/testsupport/fileutils.h" 19 #include "webrtc/test/testsupport/fileutils.h"
19 #include "webrtc/video_frame.h" 20 #include "webrtc/video_frame.h"
20 21
21 namespace webrtc { 22 namespace webrtc {
22 23
23 namespace { 24 namespace {
24 void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) { 25 void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) {
25 *stride_y = 16 * ((width + 15) / 16); 26 *stride_y = 16 * ((width + 15) / 16);
26 *stride_uv = 16 * ((width + 31) / 32); 27 *stride_uv = 16 * ((width + 31) / 32);
27 } 28 }
28 29
29 } // Anonymous namespace 30 } // Anonymous namespace
30 31
31 class TestLibYuv : public ::testing::Test { 32 class TestLibYuv : public ::testing::Test {
32 protected: 33 protected:
33 TestLibYuv(); 34 TestLibYuv();
34 virtual void SetUp(); 35 virtual void SetUp();
35 virtual void TearDown(); 36 virtual void TearDown();
36 37
37 FILE* source_file_; 38 FILE* source_file_;
38 VideoFrame orig_frame_; 39 std::unique_ptr<VideoFrame> orig_frame_;
39 std::unique_ptr<uint8_t[]> orig_buffer_;
40 const int width_; 40 const int width_;
41 const int height_; 41 const int height_;
42 const int size_y_; 42 const int size_y_;
43 const int size_uv_; 43 const int size_uv_;
44 const size_t frame_length_; 44 const size_t frame_length_;
45 }; 45 };
46 46
47 TestLibYuv::TestLibYuv() 47 TestLibYuv::TestLibYuv()
48 : source_file_(NULL), 48 : source_file_(NULL),
49 orig_frame_(), 49 orig_frame_(),
50 width_(352), 50 width_(352),
51 height_(288), 51 height_(288),
52 size_y_(width_ * height_), 52 size_y_(width_ * height_),
53 size_uv_(((width_ + 1) / 2) * ((height_ + 1) / 2)), 53 size_uv_(((width_ + 1) / 2) * ((height_ + 1) / 2)),
54 frame_length_(CalcBufferSize(kI420, 352, 288)) { 54 frame_length_(CalcBufferSize(kI420, 352, 288)) {}
55 orig_buffer_.reset(new uint8_t[frame_length_]);
56 }
57 55
58 void TestLibYuv::SetUp() { 56 void TestLibYuv::SetUp() {
59 const std::string input_file_name = webrtc::test::ResourcePath("foreman_cif", 57 const std::string input_file_name = webrtc::test::ResourcePath("foreman_cif",
60 "yuv"); 58 "yuv");
61 source_file_ = fopen(input_file_name.c_str(), "rb"); 59 source_file_ = fopen(input_file_name.c_str(), "rb");
62 ASSERT_TRUE(source_file_ != NULL) << "Cannot read file: "<< 60 ASSERT_TRUE(source_file_ != NULL) << "Cannot read file: "<<
63 input_file_name << "\n"; 61 input_file_name << "\n";
64 62
65 EXPECT_EQ(frame_length_, 63 rtc::scoped_refptr<VideoFrameBuffer> buffer(
66 fread(orig_buffer_.get(), 1, frame_length_, source_file_)); 64 test::ReadI420Buffer(width_, height_, source_file_));
67 orig_frame_.CreateFrame(orig_buffer_.get(), 65
68 orig_buffer_.get() + size_y_, 66 orig_frame_.reset(new VideoFrame(buffer, kVideoRotation_0, 0));
69 orig_buffer_.get() +
70 size_y_ + size_uv_,
71 width_, height_,
72 width_, (width_ + 1) / 2,
73 (width_ + 1) / 2,
74 kVideoRotation_0);
75 } 67 }
76 68
77 void TestLibYuv::TearDown() { 69 void TestLibYuv::TearDown() {
78 if (source_file_ != NULL) { 70 if (source_file_ != NULL) {
79 ASSERT_EQ(0, fclose(source_file_)); 71 ASSERT_EQ(0, fclose(source_file_));
80 } 72 }
81 source_file_ = NULL; 73 source_file_ = NULL;
82 } 74 }
83 75
84 TEST_F(TestLibYuv, ConvertSanityTest) { 76 TEST_F(TestLibYuv, ConvertSanityTest) {
85 // TODO(mikhal) 77 // TODO(mikhal)
86 } 78 }
87 79
88 TEST_F(TestLibYuv, ConvertTest) { 80 TEST_F(TestLibYuv, ConvertTest) {
89 // Reading YUV frame - testing on the first frame of the foreman sequence 81 // Reading YUV frame - testing on the first frame of the foreman sequence
90 int j = 0; 82 int j = 0;
91 std::string output_file_name = webrtc::test::OutputPath() + 83 std::string output_file_name = webrtc::test::OutputPath() +
92 "LibYuvTest_conversion.yuv"; 84 "LibYuvTest_conversion.yuv";
93 FILE* output_file = fopen(output_file_name.c_str(), "wb"); 85 FILE* output_file = fopen(output_file_name.c_str(), "wb");
94 ASSERT_TRUE(output_file != NULL); 86 ASSERT_TRUE(output_file != NULL);
95 87
96 double psnr = 0.0; 88 double psnr = 0.0;
97 89
98 VideoFrame res_i420_frame; 90 VideoFrame res_i420_frame;
99 res_i420_frame.CreateEmptyFrame(width_, height_, width_, 91 res_i420_frame.CreateEmptyFrame(width_, height_, width_,
100 (width_ + 1) / 2, 92 (width_ + 1) / 2,
101 (width_ + 1) / 2); 93 (width_ + 1) / 2);
102 printf("\nConvert #%d I420 <-> I420 \n", j); 94 printf("\nConvert #%d I420 <-> I420 \n", j);
103 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); 95 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]);
104 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kI420, 0, 96 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kI420, 0,
105 out_i420_buffer.get())); 97 out_i420_buffer.get()));
106 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, 98 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_,
107 height_, 0, kVideoRotation_0, &res_i420_frame)); 99 height_, 0, kVideoRotation_0, &res_i420_frame));
108 100
109 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { 101 if (PrintVideoFrame(res_i420_frame, output_file) < 0) {
110 return; 102 return;
111 } 103 }
112 psnr = I420PSNR(&orig_frame_, &res_i420_frame); 104 psnr = I420PSNR(orig_frame_.get(), &res_i420_frame);
113 EXPECT_EQ(48.0, psnr); 105 EXPECT_EQ(48.0, psnr);
114 j++; 106 j++;
115 107
116 printf("\nConvert #%d I420 <-> RGB24\n", j); 108 printf("\nConvert #%d I420 <-> RGB24\n", j);
117 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]); 109 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]);
118 // Align the stride values for the output frame. 110 // Align the stride values for the output frame.
119 int stride_y = 0; 111 int stride_y = 0;
120 int stride_uv = 0; 112 int stride_uv = 0;
121 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); 113 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv);
122 res_i420_frame.CreateEmptyFrame(width_, height_, stride_y, 114 res_i420_frame.CreateEmptyFrame(width_, height_, stride_y,
123 stride_uv, stride_uv); 115 stride_uv, stride_uv);
124 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kRGB24, 0, res_rgb_buffer2.get())); 116 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kRGB24, 0, res_rgb_buffer2.get()));
125 117
126 EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2.get(), 0, 0, width_, 118 EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2.get(), 0, 0, width_,
127 height_, 0, kVideoRotation_0, &res_i420_frame)); 119 height_, 0, kVideoRotation_0, &res_i420_frame));
128 120
129 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { 121 if (PrintVideoFrame(res_i420_frame, output_file) < 0) {
130 return; 122 return;
131 } 123 }
132 psnr = I420PSNR(&orig_frame_, &res_i420_frame); 124 psnr = I420PSNR(orig_frame_.get(), &res_i420_frame);
133 125
134 // Optimization Speed- quality trade-off => 45 dB only (platform dependant). 126 // Optimization Speed- quality trade-off => 45 dB only (platform dependant).
135 EXPECT_GT(ceil(psnr), 44); 127 EXPECT_GT(ceil(psnr), 44);
136 j++; 128 j++;
137 129
138 printf("\nConvert #%d I420 <-> UYVY\n", j); 130 printf("\nConvert #%d I420 <-> UYVY\n", j);
139 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]); 131 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]);
140 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kUYVY, 0, out_uyvy_buffer.get())); 132 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kUYVY, 0, out_uyvy_buffer.get()));
141 EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer.get(), 0, 0, width_, 133 EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer.get(), 0, 0, width_,
142 height_, 0, kVideoRotation_0, &res_i420_frame)); 134 height_, 0, kVideoRotation_0, &res_i420_frame));
143 psnr = I420PSNR(&orig_frame_, &res_i420_frame); 135 psnr = I420PSNR(orig_frame_.get(), &res_i420_frame);
144 EXPECT_EQ(48.0, psnr); 136 EXPECT_EQ(48.0, psnr);
145 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { 137 if (PrintVideoFrame(res_i420_frame, output_file) < 0) {
146 return; 138 return;
147 } 139 }
148 j++; 140 j++;
149 141
150 printf("\nConvert #%d I420 <-> YUY2\n", j); 142 printf("\nConvert #%d I420 <-> YUY2\n", j);
151 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]); 143 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]);
152 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kYUY2, 0, out_yuy2_buffer.get())); 144 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kYUY2, 0, out_yuy2_buffer.get()));
153 145
154 EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer.get(), 0, 0, width_, 146 EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer.get(), 0, 0, width_,
155 height_, 0, kVideoRotation_0, &res_i420_frame)); 147 height_, 0, kVideoRotation_0, &res_i420_frame));
156 148
157 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { 149 if (PrintVideoFrame(res_i420_frame, output_file) < 0) {
158 return; 150 return;
159 } 151 }
160 152
161 psnr = I420PSNR(&orig_frame_, &res_i420_frame); 153 psnr = I420PSNR(orig_frame_.get(), &res_i420_frame);
162 EXPECT_EQ(48.0, psnr); 154 EXPECT_EQ(48.0, psnr);
163 printf("\nConvert #%d I420 <-> RGB565\n", j); 155 printf("\nConvert #%d I420 <-> RGB565\n", j);
164 std::unique_ptr<uint8_t[]> out_rgb565_buffer( 156 std::unique_ptr<uint8_t[]> out_rgb565_buffer(
165 new uint8_t[width_ * height_ * 2]); 157 new uint8_t[width_ * height_ * 2]);
166 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kRGB565, 0, 158 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kRGB565, 0,
167 out_rgb565_buffer.get())); 159 out_rgb565_buffer.get()));
168 160
169 EXPECT_EQ(0, ConvertToI420(kRGB565, out_rgb565_buffer.get(), 0, 0, width_, 161 EXPECT_EQ(0, ConvertToI420(kRGB565, out_rgb565_buffer.get(), 0, 0, width_,
170 height_, 0, kVideoRotation_0, &res_i420_frame)); 162 height_, 0, kVideoRotation_0, &res_i420_frame));
171 163
172 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { 164 if (PrintVideoFrame(res_i420_frame, output_file) < 0) {
173 return; 165 return;
174 } 166 }
175 j++; 167 j++;
176 168
177 psnr = I420PSNR(&orig_frame_, &res_i420_frame); 169 psnr = I420PSNR(orig_frame_.get(), &res_i420_frame);
178 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565, 170 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565,
179 // Another example is I420ToRGB24, the psnr is 44 171 // Another example is I420ToRGB24, the psnr is 44
180 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB. 172 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB.
181 EXPECT_GT(ceil(psnr), 40); 173 EXPECT_GT(ceil(psnr), 40);
182 174
183 printf("\nConvert #%d I420 <-> ARGB8888\n", j); 175 printf("\nConvert #%d I420 <-> ARGB8888\n", j);
184 std::unique_ptr<uint8_t[]> out_argb8888_buffer( 176 std::unique_ptr<uint8_t[]> out_argb8888_buffer(
185 new uint8_t[width_ * height_ * 4]); 177 new uint8_t[width_ * height_ * 4]);
186 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kARGB, 0, 178 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kARGB, 0,
187 out_argb8888_buffer.get())); 179 out_argb8888_buffer.get()));
188 180
189 EXPECT_EQ(0, ConvertToI420(kARGB, out_argb8888_buffer.get(), 0, 0, width_, 181 EXPECT_EQ(0, ConvertToI420(kARGB, out_argb8888_buffer.get(), 0, 0, width_,
190 height_, 0, kVideoRotation_0, &res_i420_frame)); 182 height_, 0, kVideoRotation_0, &res_i420_frame));
191 183
192 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { 184 if (PrintVideoFrame(res_i420_frame, output_file) < 0) {
193 return; 185 return;
194 } 186 }
195 187
196 psnr = I420PSNR(&orig_frame_, &res_i420_frame); 188 psnr = I420PSNR(orig_frame_.get(), &res_i420_frame);
197 // TODO(leozwang) Investigate the right psnr should be set for I420ToARGB8888, 189 // TODO(leozwang) Investigate the right psnr should be set for I420ToARGB8888,
198 EXPECT_GT(ceil(psnr), 42); 190 EXPECT_GT(ceil(psnr), 42);
199 191
200 ASSERT_EQ(0, fclose(output_file)); 192 ASSERT_EQ(0, fclose(output_file));
201 } 193 }
202 194
203 TEST_F(TestLibYuv, ConvertAlignedFrame) { 195 TEST_F(TestLibYuv, ConvertAlignedFrame) {
204 // Reading YUV frame - testing on the first frame of the foreman sequence 196 // Reading YUV frame - testing on the first frame of the foreman sequence
205 std::string output_file_name = webrtc::test::OutputPath() + 197 std::string output_file_name = webrtc::test::OutputPath() +
206 "LibYuvTest_conversion.yuv"; 198 "LibYuvTest_conversion.yuv";
207 FILE* output_file = fopen(output_file_name.c_str(), "wb"); 199 FILE* output_file = fopen(output_file_name.c_str(), "wb");
208 ASSERT_TRUE(output_file != NULL); 200 ASSERT_TRUE(output_file != NULL);
209 201
210 double psnr = 0.0; 202 double psnr = 0.0;
211 203
212 VideoFrame res_i420_frame; 204 VideoFrame res_i420_frame;
213 int stride_y = 0; 205 int stride_y = 0;
214 int stride_uv = 0; 206 int stride_uv = 0;
215 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); 207 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv);
216 res_i420_frame.CreateEmptyFrame(width_, height_, 208 res_i420_frame.CreateEmptyFrame(width_, height_,
217 stride_y, stride_uv, stride_uv); 209 stride_y, stride_uv, stride_uv);
218 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); 210 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]);
219 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kI420, 0, 211 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kI420, 0,
220 out_i420_buffer.get())); 212 out_i420_buffer.get()));
221 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, 213 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_,
222 height_, 0, kVideoRotation_0, &res_i420_frame)); 214 height_, 0, kVideoRotation_0, &res_i420_frame));
223 215
224 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { 216 if (PrintVideoFrame(res_i420_frame, output_file) < 0) {
225 return; 217 return;
226 } 218 }
227 psnr = I420PSNR(&orig_frame_, &res_i420_frame); 219 psnr = I420PSNR(orig_frame_.get(), &res_i420_frame);
228 EXPECT_EQ(48.0, psnr); 220 EXPECT_EQ(48.0, psnr);
229 } 221 }
230 222
231
232 TEST_F(TestLibYuv, RotateTest) { 223 TEST_F(TestLibYuv, RotateTest) {
233 // Use ConvertToI420 for multiple roatations - see that nothing breaks, all 224 // Use ConvertToI420 for multiple roatations - see that nothing breaks, all
234 // memory is properly allocated and end result is equal to the starting point. 225 // memory is properly allocated and end result is equal to the starting point.
235 VideoFrame rotated_res_i420_frame; 226 VideoFrame rotated_res_i420_frame;
236 int rotated_width = height_; 227 int rotated_width = height_;
237 int rotated_height = width_; 228 int rotated_height = width_;
238 int stride_y; 229 int stride_y;
239 int stride_uv; 230 int stride_uv;
231
232 // Assume compact layout, no padding.
233 const uint8_t *orig_buffer = orig_frame_->video_frame_buffer()->DataY();
234
240 Calc16ByteAlignedStride(rotated_width, &stride_y, &stride_uv); 235 Calc16ByteAlignedStride(rotated_width, &stride_y, &stride_uv);
241 rotated_res_i420_frame.CreateEmptyFrame(rotated_width, 236 rotated_res_i420_frame.CreateEmptyFrame(rotated_width,
242 rotated_height, 237 rotated_height,
243 stride_y, 238 stride_y,
244 stride_uv, 239 stride_uv,
245 stride_uv); 240 stride_uv);
246 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer_.get(), 0, 0, width_, height_, 241 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, 0, 0, width_, height_,
247 0, kVideoRotation_90, &rotated_res_i420_frame)); 242 0, kVideoRotation_90, &rotated_res_i420_frame));
248 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer_.get(), 0, 0, width_, height_, 243 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, 0, 0, width_, height_,
249 0, kVideoRotation_270, &rotated_res_i420_frame)); 244 0, kVideoRotation_270, &rotated_res_i420_frame));
250 rotated_res_i420_frame.CreateEmptyFrame(width_, height_, 245 rotated_res_i420_frame.CreateEmptyFrame(width_, height_,
251 width_, (width_ + 1) / 2, 246 width_, (width_ + 1) / 2,
252 (width_ + 1) / 2); 247 (width_ + 1) / 2);
253 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer_.get(), 0, 0, width_, height_, 248 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, 0, 0, width_, height_,
254 0, kVideoRotation_180, &rotated_res_i420_frame)); 249 0, kVideoRotation_180, &rotated_res_i420_frame));
255 } 250 }
256 251
257 } // namespace webrtc 252 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/video_coding/codecs/test/videoprocessor.h » ('j') | webrtc/test/testsupport/frame_reader.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698