| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 size_uv_(((width_ + 1) / 2) * ((height_ + 1) / 2)), | 55 size_uv_(((width_ + 1) / 2) * ((height_ + 1) / 2)), |
| 56 frame_length_(CalcBufferSize(VideoType::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<I420BufferInterface> buffer( |
| 66 test::ReadI420Buffer(width_, height_, source_file_)); | 66 test::ReadI420Buffer(width_, height_, source_file_)); |
| 67 | 67 |
| 68 orig_frame_.reset(new VideoFrame(buffer, kVideoRotation_0, 0)); | 68 orig_frame_.reset(new VideoFrame(buffer, kVideoRotation_0, 0)); |
| 69 } | 69 } |
| 70 | 70 |
| 71 void TestLibYuv::TearDown() { | 71 void TestLibYuv::TearDown() { |
| 72 if (source_file_ != NULL) { | 72 if (source_file_ != NULL) { |
| 73 ASSERT_EQ(0, fclose(source_file_)); | 73 ASSERT_EQ(0, fclose(source_file_)); |
| 74 } | 74 } |
| 75 source_file_ = NULL; | 75 source_file_ = NULL; |
| 76 } | 76 } |
| 77 | 77 |
| 78 TEST_F(TestLibYuv, ConvertSanityTest) { | 78 TEST_F(TestLibYuv, ConvertSanityTest) { |
| 79 // TODO(mikhal) | 79 // TODO(mikhal) |
| 80 } | 80 } |
| 81 | 81 |
| 82 TEST_F(TestLibYuv, ConvertTest) { | 82 TEST_F(TestLibYuv, ConvertTest) { |
| 83 // Reading YUV frame - testing on the first frame of the foreman sequence | 83 // Reading YUV frame - testing on the first frame of the foreman sequence |
| 84 int j = 0; | 84 int j = 0; |
| 85 std::string output_file_name = webrtc::test::OutputPath() + | 85 std::string output_file_name = webrtc::test::OutputPath() + |
| 86 "LibYuvTest_conversion.yuv"; | 86 "LibYuvTest_conversion.yuv"; |
| 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 = |
| 93 width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2); | 93 I420Buffer::Create(width_, height_); |
| 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_, VideoType::kI420, 0, | 97 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kI420, 0, |
| 98 out_i420_buffer.get())); | 98 out_i420_buffer.get())); |
| 99 EXPECT_EQ(0, | 99 EXPECT_EQ(0, |
| 100 ConvertToI420(VideoType::kI420, out_i420_buffer.get(), 0, 0, width_, | 100 ConvertToI420(VideoType::kI420, out_i420_buffer.get(), 0, 0, width_, |
| 101 height_, 0, kVideoRotation_0, res_i420_buffer.get())); | 101 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
| 102 | 102 |
| 103 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 103 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
| 104 return; | 104 return; |
| 105 } | 105 } |
| 106 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 106 psnr = |
| 107 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer); |
| 107 EXPECT_EQ(48.0, psnr); | 108 EXPECT_EQ(48.0, psnr); |
| 108 j++; | 109 j++; |
| 109 | 110 |
| 110 printf("\nConvert #%d I420 <-> RGB24\n", j); | 111 printf("\nConvert #%d I420 <-> RGB24\n", j); |
| 111 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]); | 112 std::unique_ptr<uint8_t[]> res_rgb_buffer2(new uint8_t[width_ * height_ * 3]); |
| 112 // Align the stride values for the output frame. | 113 // Align the stride values for the output frame. |
| 113 int stride_y = 0; | 114 int stride_y = 0; |
| 114 int stride_uv = 0; | 115 int stride_uv = 0; |
| 115 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); | 116 Calc16ByteAlignedStride(width_, &stride_y, &stride_uv); |
| 116 res_i420_buffer = | 117 res_i420_buffer = |
| 117 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv); | 118 I420Buffer::Create(width_, height_, stride_y, stride_uv, stride_uv); |
| 118 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB24, 0, | 119 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB24, 0, |
| 119 res_rgb_buffer2.get())); | 120 res_rgb_buffer2.get())); |
| 120 | 121 |
| 121 EXPECT_EQ( | 122 EXPECT_EQ( |
| 122 0, ConvertToI420(VideoType::kRGB24, res_rgb_buffer2.get(), 0, 0, width_, | 123 0, ConvertToI420(VideoType::kRGB24, res_rgb_buffer2.get(), 0, 0, width_, |
| 123 height_, 0, kVideoRotation_0, res_i420_buffer.get())); | 124 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
| 124 | 125 |
| 125 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 126 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
| 126 return; | 127 return; |
| 127 } | 128 } |
| 128 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 129 psnr = |
| 130 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer); |
| 129 | 131 |
| 130 // Optimization Speed- quality trade-off => 45 dB only (platform dependant). | 132 // Optimization Speed- quality trade-off => 45 dB only (platform dependant). |
| 131 EXPECT_GT(ceil(psnr), 44); | 133 EXPECT_GT(ceil(psnr), 44); |
| 132 j++; | 134 j++; |
| 133 | 135 |
| 134 printf("\nConvert #%d I420 <-> UYVY\n", j); | 136 printf("\nConvert #%d I420 <-> UYVY\n", j); |
| 135 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]); | 137 std::unique_ptr<uint8_t[]> out_uyvy_buffer(new uint8_t[width_ * height_ * 2]); |
| 136 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kUYVY, 0, | 138 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kUYVY, 0, |
| 137 out_uyvy_buffer.get())); | 139 out_uyvy_buffer.get())); |
| 138 EXPECT_EQ(0, | 140 EXPECT_EQ(0, |
| 139 ConvertToI420(VideoType::kUYVY, out_uyvy_buffer.get(), 0, 0, width_, | 141 ConvertToI420(VideoType::kUYVY, out_uyvy_buffer.get(), 0, 0, width_, |
| 140 height_, 0, kVideoRotation_0, res_i420_buffer.get())); | 142 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
| 141 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 143 psnr = |
| 144 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer); |
| 142 EXPECT_EQ(48.0, psnr); | 145 EXPECT_EQ(48.0, psnr); |
| 143 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 146 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
| 144 return; | 147 return; |
| 145 } | 148 } |
| 146 j++; | 149 j++; |
| 147 | 150 |
| 148 printf("\nConvert #%d I420 <-> YUY2\n", j); | 151 printf("\nConvert #%d I420 <-> YUY2\n", j); |
| 149 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]); | 152 std::unique_ptr<uint8_t[]> out_yuy2_buffer(new uint8_t[width_ * height_ * 2]); |
| 150 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kYUY2, 0, | 153 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kYUY2, 0, |
| 151 out_yuy2_buffer.get())); | 154 out_yuy2_buffer.get())); |
| 152 | 155 |
| 153 EXPECT_EQ(0, | 156 EXPECT_EQ(0, |
| 154 ConvertToI420(VideoType::kYUY2, out_yuy2_buffer.get(), 0, 0, width_, | 157 ConvertToI420(VideoType::kYUY2, out_yuy2_buffer.get(), 0, 0, width_, |
| 155 height_, 0, kVideoRotation_0, res_i420_buffer.get())); | 158 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
| 156 | 159 |
| 157 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 160 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
| 158 return; | 161 return; |
| 159 } | 162 } |
| 160 | 163 |
| 161 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 164 psnr = |
| 165 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer); |
| 162 EXPECT_EQ(48.0, psnr); | 166 EXPECT_EQ(48.0, psnr); |
| 163 | 167 |
| 164 printf("\nConvert #%d I420 <-> RGB565\n", j); | 168 printf("\nConvert #%d I420 <-> RGB565\n", j); |
| 165 std::unique_ptr<uint8_t[]> out_rgb565_buffer( | 169 std::unique_ptr<uint8_t[]> out_rgb565_buffer( |
| 166 new uint8_t[width_ * height_ * 2]); | 170 new uint8_t[width_ * height_ * 2]); |
| 167 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB565, 0, | 171 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kRGB565, 0, |
| 168 out_rgb565_buffer.get())); | 172 out_rgb565_buffer.get())); |
| 169 | 173 |
| 170 EXPECT_EQ(0, ConvertToI420(VideoType::kRGB565, out_rgb565_buffer.get(), 0, 0, | 174 EXPECT_EQ(0, ConvertToI420(VideoType::kRGB565, out_rgb565_buffer.get(), 0, 0, |
| 171 width_, height_, 0, kVideoRotation_0, | 175 width_, height_, 0, kVideoRotation_0, |
| 172 res_i420_buffer.get())); | 176 res_i420_buffer.get())); |
| 173 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 177 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
| 174 return; | 178 return; |
| 175 } | 179 } |
| 176 j++; | 180 j++; |
| 177 | 181 |
| 178 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 182 psnr = |
| 183 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer); |
| 179 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565, | 184 // TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565, |
| 180 // Another example is I420ToRGB24, the psnr is 44 | 185 // Another example is I420ToRGB24, the psnr is 44 |
| 181 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB. | 186 // TODO(mikhal): Add psnr for RGB565, 1555, 4444, convert to ARGB. |
| 182 EXPECT_GT(ceil(psnr), 40); | 187 EXPECT_GT(ceil(psnr), 40); |
| 183 | 188 |
| 184 printf("\nConvert #%d I420 <-> ARGB8888\n", j); | 189 printf("\nConvert #%d I420 <-> ARGB8888\n", j); |
| 185 std::unique_ptr<uint8_t[]> out_argb8888_buffer( | 190 std::unique_ptr<uint8_t[]> out_argb8888_buffer( |
| 186 new uint8_t[width_ * height_ * 4]); | 191 new uint8_t[width_ * height_ * 4]); |
| 187 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kARGB, 0, | 192 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kARGB, 0, |
| 188 out_argb8888_buffer.get())); | 193 out_argb8888_buffer.get())); |
| 189 | 194 |
| 190 EXPECT_EQ(0, ConvertToI420(VideoType::kARGB, out_argb8888_buffer.get(), 0, 0, | 195 EXPECT_EQ(0, ConvertToI420(VideoType::kARGB, out_argb8888_buffer.get(), 0, 0, |
| 191 width_, height_, 0, kVideoRotation_0, | 196 width_, height_, 0, kVideoRotation_0, |
| 192 res_i420_buffer.get())); | 197 res_i420_buffer.get())); |
| 193 | 198 |
| 194 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 199 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
| 195 return; | 200 return; |
| 196 } | 201 } |
| 197 | 202 |
| 198 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 203 psnr = |
| 204 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer); |
| 199 // TODO(leozwang) Investigate the right psnr should be set for | 205 // TODO(leozwang) Investigate the right psnr should be set for |
| 200 // I420ToARGB8888, | 206 // I420ToARGB8888, |
| 201 EXPECT_GT(ceil(psnr), 42); | 207 EXPECT_GT(ceil(psnr), 42); |
| 202 | 208 |
| 203 ASSERT_EQ(0, fclose(output_file)); | 209 ASSERT_EQ(0, fclose(output_file)); |
| 204 } | 210 } |
| 205 | 211 |
| 206 TEST_F(TestLibYuv, ConvertAlignedFrame) { | 212 TEST_F(TestLibYuv, ConvertAlignedFrame) { |
| 207 // Reading YUV frame - testing on the first frame of the foreman sequence | 213 // Reading YUV frame - testing on the first frame of the foreman sequence |
| 208 std::string output_file_name = webrtc::test::OutputPath() + | 214 std::string output_file_name = webrtc::test::OutputPath() + |
| (...skipping 12 matching lines...) Expand all Loading... |
| 221 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); | 227 std::unique_ptr<uint8_t[]> out_i420_buffer(new uint8_t[frame_length_]); |
| 222 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kI420, 0, | 228 EXPECT_EQ(0, ConvertFromI420(*orig_frame_, VideoType::kI420, 0, |
| 223 out_i420_buffer.get())); | 229 out_i420_buffer.get())); |
| 224 EXPECT_EQ(0, | 230 EXPECT_EQ(0, |
| 225 ConvertToI420(VideoType::kI420, out_i420_buffer.get(), 0, 0, width_, | 231 ConvertToI420(VideoType::kI420, out_i420_buffer.get(), 0, 0, width_, |
| 226 height_, 0, kVideoRotation_0, res_i420_buffer.get())); | 232 height_, 0, kVideoRotation_0, res_i420_buffer.get())); |
| 227 | 233 |
| 228 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { | 234 if (PrintVideoFrame(*res_i420_buffer, output_file) < 0) { |
| 229 return; | 235 return; |
| 230 } | 236 } |
| 231 psnr = I420PSNR(*orig_frame_->video_frame_buffer(), *res_i420_buffer); | 237 psnr = |
| 238 I420PSNR(*orig_frame_->video_frame_buffer()->GetI420(), *res_i420_buffer); |
| 232 EXPECT_EQ(48.0, psnr); | 239 EXPECT_EQ(48.0, psnr); |
| 233 } | 240 } |
| 234 | 241 |
| 235 TEST_F(TestLibYuv, RotateTest) { | 242 TEST_F(TestLibYuv, RotateTest) { |
| 236 // Use ConvertToI420 for multiple rotations - see that nothing breaks, all | 243 // Use ConvertToI420 for multiple rotations - see that nothing breaks, all |
| 237 // memory is properly allocated and end result is equal to the starting point. | 244 // memory is properly allocated and end result is equal to the starting point. |
| 238 int rotated_width = height_; | 245 int rotated_width = height_; |
| 239 int rotated_height = width_; | 246 int rotated_height = width_; |
| 240 int stride_y; | 247 int stride_y; |
| 241 int stride_uv; | 248 int stride_uv; |
| 242 | 249 |
| 243 // Assume compact layout, no padding. | 250 // Assume compact layout, no padding. |
| 244 const uint8_t *orig_buffer = orig_frame_->video_frame_buffer()->DataY(); | 251 const uint8_t* orig_buffer = |
| 252 orig_frame_->video_frame_buffer()->GetI420()->DataY(); |
| 245 | 253 |
| 246 Calc16ByteAlignedStride(rotated_width, &stride_y, &stride_uv); | 254 Calc16ByteAlignedStride(rotated_width, &stride_y, &stride_uv); |
| 247 rtc::scoped_refptr<I420Buffer> rotated_res_i420_buffer = I420Buffer::Create( | 255 rtc::scoped_refptr<I420Buffer> rotated_res_i420_buffer = I420Buffer::Create( |
| 248 rotated_width, rotated_height, stride_y, stride_uv, stride_uv); | 256 rotated_width, rotated_height, stride_y, stride_uv, stride_uv); |
| 249 EXPECT_EQ( | 257 EXPECT_EQ( |
| 250 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, | 258 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, |
| 251 kVideoRotation_90, rotated_res_i420_buffer.get())); | 259 kVideoRotation_90, rotated_res_i420_buffer.get())); |
| 252 EXPECT_EQ( | 260 EXPECT_EQ( |
| 253 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, | 261 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, |
| 254 kVideoRotation_270, rotated_res_i420_buffer.get())); | 262 kVideoRotation_270, rotated_res_i420_buffer.get())); |
| 255 rotated_res_i420_buffer = I420Buffer::Create( | 263 rotated_res_i420_buffer = I420Buffer::Create(width_, height_); |
| 256 width_, height_, width_, (width_ + 1) / 2, (width_ + 1) / 2); | |
| 257 EXPECT_EQ( | 264 EXPECT_EQ( |
| 258 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, | 265 0, ConvertToI420(VideoType::kI420, orig_buffer, 0, 0, width_, height_, 0, |
| 259 kVideoRotation_180, rotated_res_i420_buffer.get())); | 266 kVideoRotation_180, rotated_res_i420_buffer.get())); |
| 260 } | 267 } |
| 261 | 268 |
| 262 static uint8_t Average(int a, int b, int c, int d) { | 269 static uint8_t Average(int a, int b, int c, int d) { |
| 263 return (a + b + c + d + 2) / 4; | 270 return (a + b + c + d + 2) / 4; |
| 264 } | 271 } |
| 265 | 272 |
| 266 TEST_F(TestLibYuv, NV12Scale2x2to2x2) { | 273 TEST_F(TestLibYuv, NV12Scale2x2to2x2) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 2, 2); | 310 2, 2); |
| 304 | 311 |
| 305 EXPECT_THAT(dst_y, ::testing::ElementsAre( | 312 EXPECT_THAT(dst_y, ::testing::ElementsAre( |
| 306 Average(0, 1, 4, 5), Average(2, 3, 6, 7), | 313 Average(0, 1, 4, 5), Average(2, 3, 6, 7), |
| 307 Average(8, 9, 12, 13), Average(10, 11, 14, 15))); | 314 Average(8, 9, 12, 13), Average(10, 11, 14, 15))); |
| 308 EXPECT_THAT(dst_uv, | 315 EXPECT_THAT(dst_uv, |
| 309 ::testing::ElementsAre(Average(0, 2, 4, 6), Average(1, 3, 5, 7))); | 316 ::testing::ElementsAre(Average(0, 2, 4, 6), Average(1, 3, 5, 7))); |
| 310 } | 317 } |
| 311 | 318 |
| 312 } // namespace webrtc | 319 } // namespace webrtc |
| OLD | NEW |