| 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 |