| 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 |
| 11 #include <math.h> | 11 #include <math.h> |
| 12 #include <string.h> | 12 #include <string.h> |
| 13 | 13 |
| 14 #include <memory> |
| 15 |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 15 #include "webrtc/base/scoped_ptr.h" | |
| 16 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 17 #include "webrtc/system_wrappers/include/tick_util.h" | 18 #include "webrtc/system_wrappers/include/tick_util.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 int PrintBuffer(const uint8_t* buffer, int width, int height, int stride) { | 24 int PrintBuffer(const uint8_t* buffer, int width, int height, int stride) { |
| 24 if (buffer == NULL) | 25 if (buffer == NULL) |
| 25 return -1; | 26 return -1; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 } | 77 } |
| 77 | 78 |
| 78 class TestLibYuv : public ::testing::Test { | 79 class TestLibYuv : public ::testing::Test { |
| 79 protected: | 80 protected: |
| 80 TestLibYuv(); | 81 TestLibYuv(); |
| 81 virtual void SetUp(); | 82 virtual void SetUp(); |
| 82 virtual void TearDown(); | 83 virtual void TearDown(); |
| 83 | 84 |
| 84 FILE* source_file_; | 85 FILE* source_file_; |
| 85 VideoFrame orig_frame_; | 86 VideoFrame orig_frame_; |
| 86 rtc::scoped_ptr<uint8_t[]> orig_buffer_; | 87 std::unique_ptr<uint8_t[]> orig_buffer_; |
| 87 const int width_; | 88 const int width_; |
| 88 const int height_; | 89 const int height_; |
| 89 const int size_y_; | 90 const int size_y_; |
| 90 const int size_uv_; | 91 const int size_uv_; |
| 91 const size_t frame_length_; | 92 const size_t frame_length_; |
| 92 }; | 93 }; |
| 93 | 94 |
| 94 TestLibYuv::TestLibYuv() | 95 TestLibYuv::TestLibYuv() |
| 95 : source_file_(NULL), | 96 : source_file_(NULL), |
| 96 orig_frame_(), | 97 orig_frame_(), |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 FILE* output_file = fopen(output_file_name.c_str(), "wb"); | 141 FILE* output_file = fopen(output_file_name.c_str(), "wb"); |
| 141 ASSERT_TRUE(output_file != NULL); | 142 ASSERT_TRUE(output_file != NULL); |
| 142 | 143 |
| 143 double psnr = 0.0; | 144 double psnr = 0.0; |
| 144 | 145 |
| 145 VideoFrame res_i420_frame; | 146 VideoFrame res_i420_frame; |
| 146 res_i420_frame.CreateEmptyFrame(width_, height_, width_, | 147 res_i420_frame.CreateEmptyFrame(width_, height_, width_, |
| 147 (width_ + 1) / 2, | 148 (width_ + 1) / 2, |
| 148 (width_ + 1) / 2); | 149 (width_ + 1) / 2); |
| 149 printf("\nConvert #%d I420 <-> I420 \n", j); | 150 printf("\nConvert #%d I420 <-> I420 \n", j); |
| 150 rtc::scoped_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); | 151 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); |
| 151 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kI420, 0, | 152 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kI420, 0, |
| 152 out_i420_buffer.get())); | 153 out_i420_buffer.get())); |
| 153 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, | 154 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, |
| 154 height_, 0, kVideoRotation_0, &res_i420_frame)); | 155 height_, 0, kVideoRotation_0, &res_i420_frame)); |
| 155 | 156 |
| 156 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { | 157 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { |
| 157 return; | 158 return; |
| 158 } | 159 } |
| 159 psnr = I420PSNR(&orig_frame_, &res_i420_frame); | 160 psnr = I420PSNR(&orig_frame_, &res_i420_frame); |
| 160 EXPECT_EQ(48.0, psnr); | 161 EXPECT_EQ(48.0, psnr); |
| 161 j++; | 162 j++; |
| 162 | 163 |
| 163 printf("\nConvert #%d I420 <-> RGB24\n", j); | 164 printf("\nConvert #%d I420 <-> RGB24\n", j); |
| 164 rtc::scoped_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]); | 165 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]); |
| 165 // Align the stride values for the output frame. | 166 // Align the stride values for the output frame. |
| 166 int stride_y = 0; | 167 int stride_y = 0; |
| 167 int stride_uv = 0; | 168 int stride_uv = 0; |
| 168 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); | 169 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); |
| 169 res_i420_frame.CreateEmptyFrame(width_, height_, stride_y, | 170 res_i420_frame.CreateEmptyFrame(width_, height_, stride_y, |
| 170 stride_uv, stride_uv); | 171 stride_uv, stride_uv); |
| 171 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kRGB24, 0, res_rgb_buffer2.get())); | 172 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kRGB24, 0, res_rgb_buffer2.get())); |
| 172 | 173 |
| 173 EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2.get(), 0, 0, width_, | 174 EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2.get(), 0, 0, width_, |
| 174 height_, 0, kVideoRotation_0, &res_i420_frame)); | 175 height_, 0, kVideoRotation_0, &res_i420_frame)); |
| 175 | 176 |
| 176 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { | 177 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { |
| 177 return; | 178 return; |
| 178 } | 179 } |
| 179 psnr = I420PSNR(&orig_frame_, &res_i420_frame); | 180 psnr = I420PSNR(&orig_frame_, &res_i420_frame); |
| 180 | 181 |
| 181 // Optimization Speed- quality trade-off => 45 dB only (platform dependant). | 182 // Optimization Speed- quality trade-off => 45 dB only (platform dependant). |
| 182 EXPECT_GT(ceil(psnr), 44); | 183 EXPECT_GT(ceil(psnr), 44); |
| 183 j++; | 184 j++; |
| 184 | 185 |
| 185 printf("\nConvert #%d I420 <-> UYVY\n", j); | 186 printf("\nConvert #%d I420 <-> UYVY\n", j); |
| 186 rtc::scoped_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]); | 187 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]); |
| 187 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kUYVY, 0, out_uyvy_buffer.get())); | 188 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kUYVY, 0, out_uyvy_buffer.get())); |
| 188 EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer.get(), 0, 0, width_, | 189 EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer.get(), 0, 0, width_, |
| 189 height_, 0, kVideoRotation_0, &res_i420_frame)); | 190 height_, 0, kVideoRotation_0, &res_i420_frame)); |
| 190 psnr = I420PSNR(&orig_frame_, &res_i420_frame); | 191 psnr = I420PSNR(&orig_frame_, &res_i420_frame); |
| 191 EXPECT_EQ(48.0, psnr); | 192 EXPECT_EQ(48.0, psnr); |
| 192 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { | 193 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { |
| 193 return; | 194 return; |
| 194 } | 195 } |
| 195 j++; | 196 j++; |
| 196 | 197 |
| 197 printf("\nConvert #%d I420 <-> YV12\n", j); | 198 printf("\nConvert #%d I420 <-> YV12\n", j); |
| 198 rtc::scoped_ptr<uint8_t[]> outYV120Buffer(new uint8_t[frame_length_]); | 199 std::unique_ptr<uint8_t[]> outYV120Buffer(new uint8_t[frame_length_]); |
| 199 rtc::scoped_ptr<uint8_t[]> res_i420_buffer(new uint8_t[frame_length_]); | 200 std::unique_ptr<uint8_t[]> res_i420_buffer(new uint8_t[frame_length_]); |
| 200 VideoFrame yv12_frame; | 201 VideoFrame yv12_frame; |
| 201 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kYV12, 0, outYV120Buffer.get())); | 202 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kYV12, 0, outYV120Buffer.get())); |
| 202 yv12_frame.CreateFrame(outYV120Buffer.get(), | 203 yv12_frame.CreateFrame(outYV120Buffer.get(), |
| 203 outYV120Buffer.get() + size_y_, | 204 outYV120Buffer.get() + size_y_, |
| 204 outYV120Buffer.get() + size_y_ + size_uv_, | 205 outYV120Buffer.get() + size_y_ + size_uv_, |
| 205 width_, height_, | 206 width_, height_, |
| 206 width_, (width_ + 1) / 2, (width_ + 1) / 2, | 207 width_, (width_ + 1) / 2, (width_ + 1) / 2, |
| 207 kVideoRotation_0); | 208 kVideoRotation_0); |
| 208 EXPECT_EQ(0, ConvertFromYV12(yv12_frame, kI420, 0, res_i420_buffer.get())); | 209 EXPECT_EQ(0, ConvertFromYV12(yv12_frame, kI420, 0, res_i420_buffer.get())); |
| 209 if (fwrite(res_i420_buffer.get(), 1, frame_length_, output_file) != | 210 if (fwrite(res_i420_buffer.get(), 1, frame_length_, output_file) != |
| 210 frame_length_) { | 211 frame_length_) { |
| 211 return; | 212 return; |
| 212 } | 213 } |
| 213 | 214 |
| 214 ConvertToI420(kI420, res_i420_buffer.get(), 0, 0, width_, height_, 0, | 215 ConvertToI420(kI420, res_i420_buffer.get(), 0, 0, width_, height_, 0, |
| 215 kVideoRotation_0, &res_i420_frame); | 216 kVideoRotation_0, &res_i420_frame); |
| 216 psnr = I420PSNR(&orig_frame_, &res_i420_frame); | 217 psnr = I420PSNR(&orig_frame_, &res_i420_frame); |
| 217 EXPECT_EQ(48.0, psnr); | 218 EXPECT_EQ(48.0, psnr); |
| 218 j++; | 219 j++; |
| 219 | 220 |
| 220 printf("\nConvert #%d I420 <-> YUY2\n", j); | 221 printf("\nConvert #%d I420 <-> YUY2\n", j); |
| 221 rtc::scoped_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]); | 222 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]); |
| 222 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kYUY2, 0, out_yuy2_buffer.get())); | 223 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kYUY2, 0, out_yuy2_buffer.get())); |
| 223 | 224 |
| 224 EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer.get(), 0, 0, width_, | 225 EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer.get(), 0, 0, width_, |
| 225 height_, 0, kVideoRotation_0, &res_i420_frame)); | 226 height_, 0, kVideoRotation_0, &res_i420_frame)); |
| 226 | 227 |
| 227 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { | 228 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { |
| 228 return; | 229 return; |
| 229 } | 230 } |
| 230 | 231 |
| 231 psnr = I420PSNR(&orig_frame_, &res_i420_frame); | 232 psnr = I420PSNR(&orig_frame_, &res_i420_frame); |
| 232 EXPECT_EQ(48.0, psnr); | 233 EXPECT_EQ(48.0, psnr); |
| 233 printf("\nConvert #%d I420 <-> RGB565\n", j); | 234 printf("\nConvert #%d I420 <-> RGB565\n", j); |
| 234 rtc::scoped_ptr<uint8_t[]> out_rgb565_buffer( | 235 std::unique_ptr<uint8_t[]> out_rgb565_buffer( |
| 235 new uint8_t[width_ * height_ * 2]); | 236 new uint8_t[width_ * height_ * 2]); |
| 236 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kRGB565, 0, | 237 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kRGB565, 0, |
| 237 out_rgb565_buffer.get())); | 238 out_rgb565_buffer.get())); |
| 238 | 239 |
| 239 EXPECT_EQ(0, ConvertToI420(kRGB565, out_rgb565_buffer.get(), 0, 0, width_, | 240 EXPECT_EQ(0, ConvertToI420(kRGB565, out_rgb565_buffer.get(), 0, 0, width_, |
| 240 height_, 0, kVideoRotation_0, &res_i420_frame)); | 241 height_, 0, kVideoRotation_0, &res_i420_frame)); |
| 241 | 242 |
| 242 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { | 243 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { |
| 243 return; | 244 return; |
| 244 } | 245 } |
| 245 j++; | 246 j++; |
| 246 | 247 |
| 247 psnr = I420PSNR(&orig_frame_, &res_i420_frame); | 248 psnr = I420PSNR(&orig_frame_, &res_i420_frame); |
| 248 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565, | 249 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565, |
| 249 // Another example is I420ToRGB24, the psnr is 44 | 250 // Another example is I420ToRGB24, the psnr is 44 |
| 250 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB. | 251 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB. |
| 251 EXPECT_GT(ceil(psnr), 40); | 252 EXPECT_GT(ceil(psnr), 40); |
| 252 | 253 |
| 253 printf("\nConvert #%d I420 <-> ARGB8888\n", j); | 254 printf("\nConvert #%d I420 <-> ARGB8888\n", j); |
| 254 rtc::scoped_ptr<uint8_t[]> out_argb8888_buffer( | 255 std::unique_ptr<uint8_t[]> out_argb8888_buffer( |
| 255 new uint8_t[width_ * height_ * 4]); | 256 new uint8_t[width_ * height_ * 4]); |
| 256 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kARGB, 0, | 257 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kARGB, 0, |
| 257 out_argb8888_buffer.get())); | 258 out_argb8888_buffer.get())); |
| 258 | 259 |
| 259 EXPECT_EQ(0, ConvertToI420(kARGB, out_argb8888_buffer.get(), 0, 0, width_, | 260 EXPECT_EQ(0, ConvertToI420(kARGB, out_argb8888_buffer.get(), 0, 0, width_, |
| 260 height_, 0, kVideoRotation_0, &res_i420_frame)); | 261 height_, 0, kVideoRotation_0, &res_i420_frame)); |
| 261 | 262 |
| 262 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { | 263 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { |
| 263 return; | 264 return; |
| 264 } | 265 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 278 ASSERT_TRUE(output_file != NULL); | 279 ASSERT_TRUE(output_file != NULL); |
| 279 | 280 |
| 280 double psnr = 0.0; | 281 double psnr = 0.0; |
| 281 | 282 |
| 282 VideoFrame res_i420_frame; | 283 VideoFrame res_i420_frame; |
| 283 int stride_y = 0; | 284 int stride_y = 0; |
| 284 int stride_uv = 0; | 285 int stride_uv = 0; |
| 285 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); | 286 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); |
| 286 res_i420_frame.CreateEmptyFrame(width_, height_, | 287 res_i420_frame.CreateEmptyFrame(width_, height_, |
| 287 stride_y, stride_uv, stride_uv); | 288 stride_y, stride_uv, stride_uv); |
| 288 rtc::scoped_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); | 289 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); |
| 289 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kI420, 0, | 290 EXPECT_EQ(0, ConvertFromI420(orig_frame_, kI420, 0, |
| 290 out_i420_buffer.get())); | 291 out_i420_buffer.get())); |
| 291 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, | 292 EXPECT_EQ(0, ConvertToI420(kI420, out_i420_buffer.get(), 0, 0, width_, |
| 292 height_, 0, kVideoRotation_0, &res_i420_frame)); | 293 height_, 0, kVideoRotation_0, &res_i420_frame)); |
| 293 | 294 |
| 294 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { | 295 if (PrintVideoFrame(res_i420_frame, output_file) < 0) { |
| 295 return; | 296 return; |
| 296 } | 297 } |
| 297 psnr = I420PSNR(&orig_frame_, &res_i420_frame); | 298 psnr = I420PSNR(&orig_frame_, &res_i420_frame); |
| 298 EXPECT_EQ(48.0, psnr); | 299 EXPECT_EQ(48.0, psnr); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 Calc16ByteAlignedStride(width, &stride_y, &stride_uv); | 343 Calc16ByteAlignedStride(width, &stride_y, &stride_uv); |
| 343 EXPECT_EQ(128, stride_y); | 344 EXPECT_EQ(128, stride_y); |
| 344 EXPECT_EQ(64, stride_uv); | 345 EXPECT_EQ(64, stride_uv); |
| 345 width = 127; | 346 width = 127; |
| 346 Calc16ByteAlignedStride(width, &stride_y, &stride_uv); | 347 Calc16ByteAlignedStride(width, &stride_y, &stride_uv); |
| 347 EXPECT_EQ(128, stride_y); | 348 EXPECT_EQ(128, stride_y); |
| 348 EXPECT_EQ(64, stride_uv); | 349 EXPECT_EQ(64, stride_uv); |
| 349 } | 350 } |
| 350 | 351 |
| 351 } // namespace webrtc | 352 } // namespace webrtc |
| OLD | NEW |