OLD | NEW |
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 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 const size_t frame_length_; | 46 const size_t frame_length_; |
47 }; | 47 }; |
48 | 48 |
49 TestLibYuv::TestLibYuv() | 49 TestLibYuv::TestLibYuv() |
50 : source_file_(NULL), | 50 : source_file_(NULL), |
51 orig_frame_(), | 51 orig_frame_(), |
52 width_(352), | 52 width_(352), |
53 height_(288), | 53 height_(288), |
54 size_y_(width_ * height_), | 54 size_y_(width_ * height_), |
55 size_uv_(((width_ + 1) / 2) * ((height_ + 1) / 2)), | 55 size_uv_(((width_ + 1) / 2) * ((height_ + 1) / 2)), |
56 frame_length_(CalcBufferSize(kI420, 352, 288)) {} | 56 frame_length_(CalcBufferSize(VideoType::kI420, 352, 288)) {} |
57 | 57 |
58 void TestLibYuv::SetUp() { | 58 void TestLibYuv::SetUp() { |
59 const std::string input_file_name = webrtc::test::ResourcePath("foreman_cif", | 59 const std::string input_file_name = webrtc::test::ResourcePath("foreman_cif", |
60 "yuv"); | 60 "yuv"); |
61 source_file_ = fopen(input_file_name.c_str(), "rb"); | 61 source_file_ = fopen(input_file_name.c_str(), "rb"); |
62 ASSERT_TRUE(source_file_ != NULL) << "Cannot read file: "<< | 62 ASSERT_TRUE(source_file_ != NULL) << "Cannot read file: "<< |
63 input_file_name << "\n"; | 63 input_file_name << "\n"; |
64 | 64 |
65 rtc::scoped_refptr<VideoFrameBuffer> buffer( | 65 rtc::scoped_refptr<VideoFrameBuffer> buffer( |
66 test::ReadI420Buffer(width_, height_, source_file_)); | 66 test::ReadI420Buffer(width_, height_, source_file_)); |
(...skipping 20 matching lines...) Expand all Loading... |
87 FILE* output_file = fopen(output_file_name.c_str(), "wb"); | 87 FILE* output_file = fopen(output_file_name.c_str(), "wb"); |
88 ASSERT_TRUE(output_file != NULL); | 88 ASSERT_TRUE(output_file != NULL); |
89 | 89 |
90 double psnr = 0.0; | 90 double psnr = 0.0; |
91 | 91 |
92 rtc::scoped_refptr<I420Buffer> res_i420_buffer = I420Buffer::Create( | 92 rtc::scoped_refptr<I420Buffer> res_i420_buffer = I420Buffer::Create( |
93 width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2); | 93 width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2); |
94 | 94 |
95 printf("\nConvert #%d I420 <-> I420 \n", j); | 95 printf("\nConvert #%d I420 <-> I420 \n", j); |
96 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); | 96 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); |
97 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kI420, 0, out_i420_buffer.get())); | 97 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kI420, 0, |
98 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, | 98 out_i420_buffer.get())); |
99 height_, 0, kVideoRotation_0, | 99 EXPECT_EQ(0, |
100 res_i420_buffer.get())); | 100 ConvertToI420(VideoType::kI420, out_i420_buffer.get(), 0, 0, width_, |
| 101 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
101 | 102 |
102 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 103 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
103 return; | 104 return; |
104 } | 105 } |
105 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 106 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); |
106 EXPECT_EQ(48.0, psnr); | 107 EXPECT_EQ(48.0, psnr); |
107 j++; | 108 j++; |
108 | 109 |
109 printf("\nConvert #%d I420 <-> RGB24\n", j); | 110 printf("\nConvert #%d I420 <-> RGB24\n", j); |
110 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]); | 111 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]); |
111 // Align the stride values for the output frame. | 112 // Align the stride values for the output frame. |
112 int stride_y = 0; | 113 int stride_y = 0; |
113 int stride_uv = 0; | 114 int stride_uv = 0; |
114 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); | 115 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); |
115 res_i420_buffer = | 116 res_i420_buffer = |
116 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv); | 117 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv); |
117 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kRGB24, 0, res_rgb_buffer2.get())); | 118 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB24, 0, |
| 119 res_rgb_buffer2.get())); |
118 | 120 |
119 EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2.get(), 0, 0, width_, | 121 EXPECT_EQ( |
120 height_, 0, kVideoRotation_0, | 122 0, ConvertToI420(VideoType::kRGB24, res_rgb_buffer2.get(), 0, 0, width_, |
121 res_i420_buffer.get())); | 123 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
122 | 124 |
123 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 125 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
124 return; | 126 return; |
125 } | 127 } |
126 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 128 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); |
127 | 129 |
128 // Optimization Speed- quality trade-off => 45 dB only (platform dependant). | 130 // Optimization Speed- quality trade-off => 45 dB only (platform dependant). |
129 EXPECT_GT(ceil(psnr), 44); | 131 EXPECT_GT(ceil(psnr), 44); |
130 j++; | 132 j++; |
131 | 133 |
132 printf("\nConvert #%d I420 <-> UYVY\n", j); | 134 printf("\nConvert #%d I420 <-> UYVY\n", j); |
133 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]); | 135 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]); |
134 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kUYVY, 0, out_uyvy_buffer.get())); | 136 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kUYVY, 0, |
135 EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer.get(), 0, 0, width_, | 137 out_uyvy_buffer.get())); |
136 height_, 0, kVideoRotation_0, | 138 EXPECT_EQ(0, |
137 res_i420_buffer.get())); | 139 ConvertToI420(VideoType::kUYVY, out_uyvy_buffer.get(), 0, 0, width_, |
| 140 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
138 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 141 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); |
139 EXPECT_EQ(48.0, psnr); | 142 EXPECT_EQ(48.0, psnr); |
140 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 143 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
141 return; | 144 return; |
142 } | 145 } |
143 j++; | 146 j++; |
144 | 147 |
145 printf("\nConvert #%d I420 <-> YUY2\n", j); | 148 printf("\nConvert #%d I420 <-> YUY2\n", j); |
146 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]); | 149 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]); |
147 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kYUY2, 0, out_yuy2_buffer.get())); | 150 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kYUY2, 0, |
| 151 out_yuy2_buffer.get())); |
148 | 152 |
149 EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer.get(), 0, 0, width_, | 153 EXPECT_EQ(0, |
150 height_, 0, | 154 ConvertToI420(VideoType::kYUY2, out_yuy2_buffer.get(), 0, 0, width_, |
151 kVideoRotation_0, res_i420_buffer.get())); | 155 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
152 | 156 |
153 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 157 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
154 return; | 158 return; |
155 } | 159 } |
156 | 160 |
157 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 161 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); |
158 EXPECT_EQ(48.0, psnr); | 162 EXPECT_EQ(48.0, psnr); |
159 | 163 |
160 printf("\nConvert #%d I420 <-> RGB565\n", j); | 164 printf("\nConvert #%d I420 <-> RGB565\n", j); |
161 std::unique_ptr<uint8_t[]> out_rgb565_buffer( | 165 std::unique_ptr<uint8_t[]> out_rgb565_buffer( |
162 new uint8_t[width_ * height_ * 2]); | 166 new uint8_t[width_ * height_ * 2]); |
163 EXPECT_EQ(0, | 167 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB565, 0, |
164 ConvertFromI420(*orig_frame_, kRGB565, 0, out_rgb565_buffer.get())); | 168 out_rgb565_buffer.get())); |
165 | 169 |
166 EXPECT_EQ(0, ConvertToI420(kRGB565, out_rgb565_buffer.get(), 0, 0, width_, | 170 EXPECT_EQ(0, ConvertToI420(VideoType::kRGB565, out_rgb565_buffer.get(), 0, 0, |
167 height_, 0, | 171 width_, height_, 0, kVideoRotation_0, |
168 kVideoRotation_0, res_i420_buffer.get())); | 172 res_i420_buffer.get())); |
169 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 173 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
170 return; | 174 return; |
171 } | 175 } |
172 j++; | 176 j++; |
173 | 177 |
174 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 178 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); |
175 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565, | 179 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565, |
176 // Another example is I420ToRGB24, the psnr is 44 | 180 // Another example is I420ToRGB24, the psnr is 44 |
177 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB. | 181 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB. |
178 EXPECT_GT(ceil(psnr), 40); | 182 EXPECT_GT(ceil(psnr), 40); |
179 | 183 |
180 printf("\nConvert #%d I420 <-> ARGB8888\n", j); | 184 printf("\nConvert #%d I420 <-> ARGB8888\n", j); |
181 std::unique_ptr<uint8_t[]> out_argb8888_buffer( | 185 std::unique_ptr<uint8_t[]> out_argb8888_buffer( |
182 new uint8_t[width_ * height_ * 4]); | 186 new uint8_t[width_ * height_ * 4]); |
183 EXPECT_EQ(0, | 187 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kARGB, 0, |
184 ConvertFromI420(*orig_frame_, kARGB, 0, out_argb8888_buffer.get())); | 188 out_argb8888_buffer.get())); |
185 | 189 |
186 EXPECT_EQ(0, ConvertToI420(kARGB, out_argb8888_buffer.get(), 0, 0, width_, | 190 EXPECT_EQ(0, ConvertToI420(VideoType::kARGB, out_argb8888_buffer.get(), 0, 0, |
187 height_, 0, kVideoRotation_0, | 191 width_, height_, 0, kVideoRotation_0, |
188 res_i420_buffer.get())); | 192 res_i420_buffer.get())); |
189 | 193 |
190 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 194 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
191 return; | 195 return; |
192 } | 196 } |
193 | 197 |
194 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 198 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); |
195 // TODO(leozwang) Investigate the right psnr should be set for | 199 // TODO(leozwang) Investigate the right psnr should be set for |
196 // I420ToARGB8888, | 200 // I420ToARGB8888, |
197 EXPECT_GT(ceil(psnr), 42); | 201 EXPECT_GT(ceil(psnr), 42); |
(...skipping 10 matching lines...) Expand all Loading... |
208 | 212 |
209 double psnr = 0.0; | 213 double psnr = 0.0; |
210 | 214 |
211 int stride_y = 0; | 215 int stride_y = 0; |
212 int stride_uv = 0; | 216 int stride_uv = 0; |
213 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); | 217 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); |
214 | 218 |
215 rtc::scoped_refptr<I420Buffer> res_i420_buffer = | 219 rtc::scoped_refptr<I420Buffer> res_i420_buffer = |
216 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv); | 220 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv); |
217 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); | 221 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); |
218 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, kI420, 0, | 222 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kI420, 0, |
219 out_i420_buffer.get())); | 223 out_i420_buffer.get())); |
220 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, | 224 EXPECT_EQ(0, |
221 height_, 0, kVideoRotation_0, | 225 ConvertToI420(VideoType::kI420, out_i420_buffer.get(), 0, 0, width_, |
222 res_i420_buffer.get())); | 226 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
223 | 227 |
224 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 228 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
225 return; | 229 return; |
226 } | 230 } |
227 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 231 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); |
228 EXPECT_EQ(48.0, psnr); | 232 EXPECT_EQ(48.0, psnr); |
229 } | 233 } |
230 | 234 |
231 TEST_F(TestLibYuv, RotateTest) { | 235 TEST_F(TestLibYuv, RotateTest) { |
232 // Use ConvertToI420 for multiple rotations - see that nothing breaks, all | 236 // Use ConvertToI420 for multiple rotations - see that nothing breaks, all |
233 // memory is properly allocated and end result is equal to the starting point. | 237 // memory is properly allocated and end result is equal to the starting point. |
234 int rotated_width = height_; | 238 int rotated_width = height_; |
235 int rotated_height = width_; | 239 int rotated_height = width_; |
236 int stride_y; | 240 int stride_y; |
237 int stride_uv; | 241 int stride_uv; |
238 | 242 |
239 // Assume compact layout, no padding. | 243 // Assume compact layout, no padding. |
240 const uint8_t *orig_buffer = orig_frame_->video_frame_buffer()->DataY(); | 244 const uint8_t *orig_buffer = orig_frame_->video_frame_buffer()->DataY(); |
241 | 245 |
242 Calc16ByteAlignedStride(rotated_width, &stride_y, &stride_uv); | 246 Calc16ByteAlignedStride(rotated_width, &stride_y, &stride_uv); |
243 rtc::scoped_refptr<I420Buffer> rotated_res_i420_buffer = I420Buffer::Create( | 247 rtc::scoped_refptr<I420Buffer> rotated_res_i420_buffer = I420Buffer::Create( |
244 rotated_width, rotated_height, stride_y, stride_uv, stride_uv); | 248 rotated_width, rotated_height, stride_y, stride_uv, stride_uv); |
245 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, 0, 0, width_, height_, | 249 EXPECT_EQ( |
246 0, kVideoRotation_90, | 250 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, |
247 rotated_res_i420_buffer.get())); | 251 kVideoRotation_90, rotated_res_i420_buffer.get())); |
248 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, 0, 0, width_, height_, | 252 EXPECT_EQ( |
249 0, kVideoRotation_270, | 253 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, |
250 rotated_res_i420_buffer.get())); | 254 kVideoRotation_270, rotated_res_i420_buffer.get())); |
251 rotated_res_i420_buffer = I420Buffer::Create( | 255 rotated_res_i420_buffer = I420Buffer::Create( |
252 width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2); | 256 width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2); |
253 EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, 0, 0, width_, height_, | 257 EXPECT_EQ( |
254 0, kVideoRotation_180, | 258 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, |
255 rotated_res_i420_buffer.get())); | 259 kVideoRotation_180, rotated_res_i420_buffer.get())); |
256 } | 260 } |
257 | 261 |
258 static uint8_t Average(int a, int b, int c, int d) { | 262 static uint8_t Average(int a, int b, int c, int d) { |
259 return (a + b + c + d + 2) / 4; | 263 return (a + b + c + d + 2) / 4; |
260 } | 264 } |
261 | 265 |
262 TEST_F(TestLibYuv, NV12Scale2x2to2x2) { | 266 TEST_F(TestLibYuv, NV12Scale2x2to2x2) { |
263 const std::vector<uint8_t> src_y = {0, 1, | 267 const std::vector<uint8_t> src_y = {0, 1, |
264 2, 3}; | 268 2, 3}; |
265 const std::vector<uint8_t> src_uv = {0, 1}; | 269 const std::vector<uint8_t> src_uv = {0, 1}; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 2, 2); | 303 2, 2); |
300 | 304 |
301 EXPECT_THAT(dst_y, ::testing::ElementsAre( | 305 EXPECT_THAT(dst_y, ::testing::ElementsAre( |
302 Average(0, 1, 4, 5), Average(2, 3, 6, 7), | 306 Average(0, 1, 4, 5), Average(2, 3, 6, 7), |
303 Average(8, 9, 12, 13), Average(10, 11, 14, 15))); | 307 Average(8, 9, 12, 13), Average(10, 11, 14, 15))); |
304 EXPECT_THAT(dst_uv, | 308 EXPECT_THAT(dst_uv, |
305 ::testing::ElementsAre(Average(0, 2, 4, 6), Average(1, 3, 5, 7))); | 309 ::testing::ElementsAre(Average(0, 2, 4, 6), Average(1, 3, 5, 7))); |
306 } | 310 } |
307 | 311 |
308 } // namespace webrtc | 312 } // namespace webrtc |
OLD | NEW |