| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <inttypes.h> | 5 #include <inttypes.h> |
| 6 #include <stddef.h> | 6 #include <stddef.h> |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "media/base/decoder_buffer.h" | 41 #include "media/base/decoder_buffer.h" |
| 42 #include "media/base/media_log.h" | 42 #include "media/base/media_log.h" |
| 43 #include "media/base/media_util.h" | 43 #include "media/base/media_util.h" |
| 44 #include "media/base/test_data_util.h" | 44 #include "media/base/test_data_util.h" |
| 45 #include "media/base/video_decoder.h" | 45 #include "media/base/video_decoder.h" |
| 46 #include "media/base/video_frame.h" | 46 #include "media/base/video_frame.h" |
| 47 #include "media/filters/ffmpeg_glue.h" | 47 #include "media/filters/ffmpeg_glue.h" |
| 48 #include "media/filters/ffmpeg_video_decoder.h" | 48 #include "media/filters/ffmpeg_video_decoder.h" |
| 49 #include "media/filters/h264_parser.h" | 49 #include "media/filters/h264_parser.h" |
| 50 #include "media/filters/ivf_parser.h" | 50 #include "media/filters/ivf_parser.h" |
| 51 #include "media/gpu/gpu_video_encode_accelerator_factory.h" |
| 51 #include "media/gpu/video_accelerator_unittest_helpers.h" | 52 #include "media/gpu/video_accelerator_unittest_helpers.h" |
| 52 #include "media/video/fake_video_encode_accelerator.h" | 53 #include "media/video/fake_video_encode_accelerator.h" |
| 53 #include "media/video/video_encode_accelerator.h" | 54 #include "media/video/video_encode_accelerator.h" |
| 54 #include "testing/gtest/include/gtest/gtest.h" | 55 #include "testing/gtest/include/gtest/gtest.h" |
| 55 | 56 |
| 56 #if defined(OS_CHROMEOS) | 57 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
| 57 #if defined(USE_V4L2_CODEC) | |
| 58 #include "base/threading/thread_task_runner_handle.h" | |
| 59 #include "media/gpu/v4l2_video_encode_accelerator.h" | |
| 60 #endif | |
| 61 #if defined(ARCH_CPU_X86_FAMILY) | |
| 62 #include "media/gpu/vaapi_video_encode_accelerator.h" | |
| 63 #include "media/gpu/vaapi_wrapper.h" | 58 #include "media/gpu/vaapi_wrapper.h" |
| 64 // Status has been defined as int in Xlib.h. | |
| 65 #undef Status | |
| 66 #endif // defined(ARCH_CPU_X86_FAMILY) | |
| 67 #elif defined(OS_MACOSX) | |
| 68 #include "media/gpu/vt_video_encode_accelerator_mac.h" | |
| 69 #elif defined(OS_WIN) | |
| 70 #include "media/gpu/media_foundation_video_encode_accelerator_win.h" | |
| 71 #else | |
| 72 #error The VideoEncodeAcceleratorUnittest is not supported on this platform. | |
| 73 #endif | 59 #endif |
| 74 | 60 |
| 75 namespace media { | 61 namespace media { |
| 76 namespace { | 62 namespace { |
| 77 | 63 |
| 78 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420; | 64 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420; |
| 79 | 65 |
| 80 // The absolute differences between original frame and decoded frame usually | 66 // The absolute differences between original frame and decoded frame usually |
| 81 // ranges aroud 1 ~ 7. So we pick 10 as an extreme value to detect abnormal | 67 // ranges aroud 1 ~ 7. So we pick 10 as an extreme value to detect abnormal |
| 82 // decoded frames. | 68 // decoded frames. |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 } | 421 } |
| 436 | 422 |
| 437 if (fields.size() >= 9 && !fields[8].empty()) { | 423 if (fields.size() >= 9 && !fields[8].empty()) { |
| 438 LOG_ASSERT(base::StringToUint( | 424 LOG_ASSERT(base::StringToUint( |
| 439 fields[8], &test_stream->requested_subsequent_framerate)); | 425 fields[8], &test_stream->requested_subsequent_framerate)); |
| 440 } | 426 } |
| 441 test_streams->push_back(test_stream); | 427 test_streams->push_back(test_stream); |
| 442 } | 428 } |
| 443 } | 429 } |
| 444 | 430 |
| 445 static std::unique_ptr<VideoEncodeAccelerator> CreateFakeVEA() { | |
| 446 std::unique_ptr<VideoEncodeAccelerator> encoder; | |
| 447 if (g_fake_encoder) { | |
| 448 encoder.reset(new FakeVideoEncodeAccelerator( | |
| 449 scoped_refptr<base::SingleThreadTaskRunner>( | |
| 450 base::ThreadTaskRunnerHandle::Get()))); | |
| 451 } | |
| 452 return encoder; | |
| 453 } | |
| 454 | |
| 455 static std::unique_ptr<VideoEncodeAccelerator> CreateV4L2VEA() { | |
| 456 std::unique_ptr<VideoEncodeAccelerator> encoder; | |
| 457 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) | |
| 458 scoped_refptr<V4L2Device> device = V4L2Device::Create(); | |
| 459 if (device) | |
| 460 encoder.reset(new V4L2VideoEncodeAccelerator(device)); | |
| 461 #endif | |
| 462 return encoder; | |
| 463 } | |
| 464 | |
| 465 static std::unique_ptr<VideoEncodeAccelerator> CreateVaapiVEA() { | |
| 466 std::unique_ptr<VideoEncodeAccelerator> encoder; | |
| 467 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | |
| 468 encoder.reset(new VaapiVideoEncodeAccelerator()); | |
| 469 #endif | |
| 470 return encoder; | |
| 471 } | |
| 472 | |
| 473 static std::unique_ptr<VideoEncodeAccelerator> CreateVTVEA() { | |
| 474 std::unique_ptr<VideoEncodeAccelerator> encoder; | |
| 475 #if defined(OS_MACOSX) | |
| 476 encoder.reset(new VTVideoEncodeAccelerator()); | |
| 477 #endif | |
| 478 return encoder; | |
| 479 } | |
| 480 | |
| 481 static std::unique_ptr<VideoEncodeAccelerator> CreateMFVEA() { | |
| 482 std::unique_ptr<VideoEncodeAccelerator> encoder; | |
| 483 #if defined(OS_WIN) | |
| 484 MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); | |
| 485 encoder.reset(new MediaFoundationVideoEncodeAccelerator()); | |
| 486 #endif | |
| 487 return encoder; | |
| 488 } | |
| 489 | |
| 490 // Basic test environment shared across multiple test cases. We only need to | 431 // Basic test environment shared across multiple test cases. We only need to |
| 491 // setup it once for all test cases. | 432 // setup it once for all test cases. |
| 492 // It helps | 433 // It helps |
| 493 // - maintain test stream data and other test settings. | 434 // - maintain test stream data and other test settings. |
| 494 // - clean up temporary aligned files. | 435 // - clean up temporary aligned files. |
| 495 // - output log to file. | 436 // - output log to file. |
| 496 class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { | 437 class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { |
| 497 public: | 438 public: |
| 498 VideoEncodeAcceleratorTestEnvironment( | 439 VideoEncodeAcceleratorTestEnvironment( |
| 499 std::unique_ptr<base::FilePath::StringType> data, | 440 std::unique_ptr<base::FilePath::StringType> data, |
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 // Without it, AppendToFile() will not work. | 1156 // Without it, AppendToFile() will not work. |
| 1216 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); | 1157 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); |
| 1217 } | 1158 } |
| 1218 | 1159 |
| 1219 // Initialize the parameters of the test streams. | 1160 // Initialize the parameters of the test streams. |
| 1220 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); | 1161 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); |
| 1221 | 1162 |
| 1222 thread_checker_.DetachFromThread(); | 1163 thread_checker_.DetachFromThread(); |
| 1223 } | 1164 } |
| 1224 | 1165 |
| 1166 // Helper function to create VEA. |
| 1167 static std::unique_ptr<VideoEncodeAccelerator> CreateVideoEncodeAccelerator( |
| 1168 VideoPixelFormat input_format, |
| 1169 const gfx::Size& input_visible_size, |
| 1170 VideoCodecProfile output_profile, |
| 1171 uint32_t initial_bitrate, |
| 1172 VideoEncodeAccelerator::Client* client, |
| 1173 const gpu::GpuPreferences& gpu_preferences) { |
| 1174 if (g_fake_encoder) { |
| 1175 std::unique_ptr<VideoEncodeAccelerator> encoder( |
| 1176 new FakeVideoEncodeAccelerator( |
| 1177 scoped_refptr<base::SingleThreadTaskRunner>( |
| 1178 base::ThreadTaskRunnerHandle::Get()))); |
| 1179 if (encoder->Initialize(input_format, input_visible_size, output_profile, |
| 1180 initial_bitrate, client)) |
| 1181 return encoder; |
| 1182 return nullptr; |
| 1183 } else { |
| 1184 return GpuVideoEncodeAcceleratorFactory::CreateVEA( |
| 1185 input_format, input_visible_size, output_profile, initial_bitrate, |
| 1186 client, gpu_preferences); |
| 1187 } |
| 1188 } |
| 1189 |
| 1225 void VEAClient::CreateEncoder() { | 1190 void VEAClient::CreateEncoder() { |
| 1226 DCHECK(thread_checker_.CalledOnValidThread()); | 1191 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1227 LOG_ASSERT(!has_encoder()); | 1192 LOG_ASSERT(!has_encoder()); |
| 1228 | 1193 |
| 1229 vea_client_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 1194 vea_client_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 1230 encode_task_runner_ = vea_client_task_runner_; | 1195 encode_task_runner_ = vea_client_task_runner_; |
| 1231 | 1196 |
| 1232 std::unique_ptr<VideoEncodeAccelerator> encoders[] = { | |
| 1233 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(), | |
| 1234 CreateMFVEA()}; | |
| 1235 | |
| 1236 DVLOG(1) << "Profile: " << test_stream_->requested_profile | 1197 DVLOG(1) << "Profile: " << test_stream_->requested_profile |
| 1237 << ", initial bitrate: " << requested_bitrate_; | 1198 << ", initial bitrate: " << requested_bitrate_; |
| 1238 | 1199 |
| 1239 for (size_t i = 0; i < arraysize(encoders); ++i) { | 1200 encoder_ = CreateVideoEncodeAccelerator( |
| 1240 if (!encoders[i]) | 1201 kInputFormat, test_stream_->visible_size, test_stream_->requested_profile, |
| 1241 continue; | 1202 requested_bitrate_, this, gpu::GpuPreferences()); |
| 1242 encoder_ = std::move(encoders[i]); | 1203 if (!encoder_) { |
| 1243 if (encoder_->Initialize(kInputFormat, test_stream_->visible_size, | 1204 LOG(ERROR) << "Failed creating a VideoEncodeAccelerator."; |
| 1244 test_stream_->requested_profile, | 1205 SetState(CS_ERROR); |
| 1245 requested_bitrate_, this)) { | 1206 return; |
| 1246 encoder_weak_factory_.reset( | 1207 } |
| 1247 new base::WeakPtrFactory<VideoEncodeAccelerator>(encoder_.get())); | 1208 encoder_weak_factory_.reset( |
| 1248 TryToSetupEncodeOnSeparateThread(); | 1209 new base::WeakPtrFactory<VideoEncodeAccelerator>(encoder_.get())); |
| 1249 SetStreamParameters(requested_bitrate_, requested_framerate_); | 1210 TryToSetupEncodeOnSeparateThread(); |
| 1250 SetState(CS_INITIALIZED); | 1211 SetStreamParameters(requested_bitrate_, requested_framerate_); |
| 1212 SetState(CS_INITIALIZED); |
| 1251 | 1213 |
| 1252 if (verify_output_ && !g_fake_encoder) | 1214 if (verify_output_ && !g_fake_encoder) |
| 1253 quality_validator_.reset(new VideoFrameQualityValidator( | 1215 quality_validator_.reset(new VideoFrameQualityValidator( |
| 1254 test_stream_->requested_profile, | 1216 test_stream_->requested_profile, |
| 1255 base::Bind(&VEAClient::DecodeCompleted, base::Unretained(this)), | 1217 base::Bind(&VEAClient::DecodeCompleted, base::Unretained(this)), |
| 1256 base::Bind(&VEAClient::DecodeFailed, base::Unretained(this)))); | 1218 base::Bind(&VEAClient::DecodeFailed, base::Unretained(this)))); |
| 1257 return; | |
| 1258 } | |
| 1259 } | |
| 1260 encoder_.reset(); | |
| 1261 LOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; | |
| 1262 SetState(CS_ERROR); | |
| 1263 } | 1219 } |
| 1264 | 1220 |
| 1265 void VEAClient::DecodeCompleted() { | 1221 void VEAClient::DecodeCompleted() { |
| 1266 DCHECK(thread_checker_.CalledOnValidThread()); | 1222 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1267 | 1223 |
| 1268 SetState(CS_VALIDATED); | 1224 SetState(CS_VALIDATED); |
| 1269 } | 1225 } |
| 1270 | 1226 |
| 1271 void VEAClient::TryToSetupEncodeOnSeparateThread() { | 1227 void VEAClient::TryToSetupEncodeOnSeparateThread() { |
| 1272 DCHECK(thread_checker_.CalledOnValidThread()); | 1228 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 bitrate_(200000), | 1805 bitrate_(200000), |
| 1850 fps_(30) { | 1806 fps_(30) { |
| 1851 thread_checker_.DetachFromThread(); | 1807 thread_checker_.DetachFromThread(); |
| 1852 } | 1808 } |
| 1853 | 1809 |
| 1854 void SimpleVEAClientBase::CreateEncoder() { | 1810 void SimpleVEAClientBase::CreateEncoder() { |
| 1855 DCHECK(thread_checker_.CalledOnValidThread()); | 1811 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1856 LOG_ASSERT(!has_encoder()); | 1812 LOG_ASSERT(!has_encoder()); |
| 1857 LOG_ASSERT(g_env->test_streams_.size()); | 1813 LOG_ASSERT(g_env->test_streams_.size()); |
| 1858 | 1814 |
| 1859 std::unique_ptr<VideoEncodeAccelerator> encoders[] = { | |
| 1860 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(), | |
| 1861 CreateMFVEA()}; | |
| 1862 | |
| 1863 gfx::Size visible_size(width_, height_); | 1815 gfx::Size visible_size(width_, height_); |
| 1864 for (auto& encoder : encoders) { | 1816 encoder_ = CreateVideoEncodeAccelerator( |
| 1865 if (!encoder) | 1817 kInputFormat, visible_size, g_env->test_streams_[0]->requested_profile, |
| 1866 continue; | 1818 bitrate_, this, gpu::GpuPreferences()); |
| 1867 encoder_ = std::move(encoder); | 1819 if (!encoder_) { |
| 1868 if (encoder_->Initialize(kInputFormat, visible_size, | 1820 LOG(ERROR) << "Failed creating a VideoEncodeAccelerator."; |
| 1869 g_env->test_streams_[0]->requested_profile, | 1821 SetState(CS_ERROR); |
| 1870 bitrate_, this)) { | 1822 return; |
| 1871 encoder_->RequestEncodingParametersChange(bitrate_, fps_); | |
| 1872 SetState(CS_INITIALIZED); | |
| 1873 return; | |
| 1874 } | |
| 1875 } | 1823 } |
| 1876 encoder_.reset(); | 1824 encoder_->RequestEncodingParametersChange(bitrate_, fps_); |
| 1877 LOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; | 1825 SetState(CS_INITIALIZED); |
| 1878 SetState(CS_ERROR); | |
| 1879 } | 1826 } |
| 1880 | 1827 |
| 1881 void SimpleVEAClientBase::DestroyEncoder() { | 1828 void SimpleVEAClientBase::DestroyEncoder() { |
| 1882 DCHECK(thread_checker_.CalledOnValidThread()); | 1829 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1883 if (!has_encoder()) | 1830 if (!has_encoder()) |
| 1884 return; | 1831 return; |
| 1885 // Clear the objects that should be destroyed on the same thread as creation. | 1832 // Clear the objects that should be destroyed on the same thread as creation. |
| 1886 encoder_.reset(); | 1833 encoder_.reset(); |
| 1887 } | 1834 } |
| 1888 | 1835 |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2367 | 2314 |
| 2368 if (needs_encode_latency && !run_at_fps) { | 2315 if (needs_encode_latency && !run_at_fps) { |
| 2369 // Encode latency can only be measured with --run_at_fps. Otherwise, we get | 2316 // Encode latency can only be measured with --run_at_fps. Otherwise, we get |
| 2370 // skewed results since it may queue too many frames at once with the same | 2317 // skewed results since it may queue too many frames at once with the same |
| 2371 // encode start time. | 2318 // encode start time. |
| 2372 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; | 2319 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; |
| 2373 } | 2320 } |
| 2374 | 2321 |
| 2375 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 2322 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
| 2376 media::VaapiWrapper::PreSandboxInitialization(); | 2323 media::VaapiWrapper::PreSandboxInitialization(); |
| 2324 #elif defined(OS_WIN) |
| 2325 MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); |
| 2377 #endif | 2326 #endif |
| 2378 | 2327 |
| 2379 media::g_env = | 2328 media::g_env = |
| 2380 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( | 2329 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( |
| 2381 testing::AddGlobalTestEnvironment( | 2330 testing::AddGlobalTestEnvironment( |
| 2382 new media::VideoEncodeAcceleratorTestEnvironment( | 2331 new media::VideoEncodeAcceleratorTestEnvironment( |
| 2383 std::move(test_stream_data), log_path, run_at_fps, | 2332 std::move(test_stream_data), log_path, run_at_fps, |
| 2384 needs_encode_latency, verify_all_output))); | 2333 needs_encode_latency, verify_all_output))); |
| 2385 | 2334 |
| 2386 return RUN_ALL_TESTS(); | 2335 return RUN_ALL_TESTS(); |
| 2387 } | 2336 } |
| OLD | NEW |