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) | 59 #elif defined(OS_WIN) |
70 #include "media/gpu/media_foundation_video_encode_accelerator_win.h" | 60 #include "media/gpu/media_foundation_video_encode_accelerator_win.h" |
71 #else | |
72 #error The VideoEncodeAcceleratorUnittest is not supported on this platform. | |
73 #endif | 61 #endif |
74 | 62 |
75 namespace media { | 63 namespace media { |
76 namespace { | 64 namespace { |
77 | 65 |
78 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420; | 66 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420; |
79 | 67 |
80 // The absolute differences between original frame and decoded frame usually | 68 // 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 | 69 // ranges aroud 1 ~ 7. So we pick 10 as an extreme value to detect abnormal |
82 // decoded frames. | 70 // decoded frames. |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 } | 423 } |
436 | 424 |
437 if (fields.size() >= 9 && !fields[8].empty()) { | 425 if (fields.size() >= 9 && !fields[8].empty()) { |
438 LOG_ASSERT(base::StringToUint( | 426 LOG_ASSERT(base::StringToUint( |
439 fields[8], &test_stream->requested_subsequent_framerate)); | 427 fields[8], &test_stream->requested_subsequent_framerate)); |
440 } | 428 } |
441 test_streams->push_back(test_stream); | 429 test_streams->push_back(test_stream); |
442 } | 430 } |
443 } | 431 } |
444 | 432 |
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 | 433 // Basic test environment shared across multiple test cases. We only need to |
491 // setup it once for all test cases. | 434 // setup it once for all test cases. |
492 // It helps | 435 // It helps |
493 // - maintain test stream data and other test settings. | 436 // - maintain test stream data and other test settings. |
494 // - clean up temporary aligned files. | 437 // - clean up temporary aligned files. |
495 // - output log to file. | 438 // - output log to file. |
496 class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { | 439 class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { |
497 public: | 440 public: |
498 VideoEncodeAcceleratorTestEnvironment( | 441 VideoEncodeAcceleratorTestEnvironment( |
499 std::unique_ptr<base::FilePath::StringType> data, | 442 std::unique_ptr<base::FilePath::StringType> data, |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 // Without it, AppendToFile() will not work. | 1163 // Without it, AppendToFile() will not work. |
1221 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); | 1164 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); |
1222 } | 1165 } |
1223 | 1166 |
1224 // Initialize the parameters of the test streams. | 1167 // Initialize the parameters of the test streams. |
1225 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); | 1168 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); |
1226 | 1169 |
1227 thread_checker_.DetachFromThread(); | 1170 thread_checker_.DetachFromThread(); |
1228 } | 1171 } |
1229 | 1172 |
| 1173 // Helper function to create VEA. |
| 1174 static std::unique_ptr<VideoEncodeAccelerator> CreateVideoEncodeAccelerator( |
| 1175 VideoPixelFormat input_format, |
| 1176 const gfx::Size& input_visible_size, |
| 1177 VideoCodecProfile output_profile, |
| 1178 uint32_t initial_bitrate, |
| 1179 VideoEncodeAccelerator::Client* client, |
| 1180 const gpu::GpuPreferences& gpu_preferences) { |
| 1181 if (g_fake_encoder) { |
| 1182 std::unique_ptr<VideoEncodeAccelerator> encoder( |
| 1183 new FakeVideoEncodeAccelerator( |
| 1184 scoped_refptr<base::SingleThreadTaskRunner>( |
| 1185 base::ThreadTaskRunnerHandle::Get()))); |
| 1186 if (encoder->Initialize(input_format, input_visible_size, output_profile, |
| 1187 initial_bitrate, client)) |
| 1188 return encoder; |
| 1189 return nullptr; |
| 1190 } else { |
| 1191 return GpuVideoEncodeAcceleratorFactory::CreateVEA( |
| 1192 input_format, input_visible_size, output_profile, initial_bitrate, |
| 1193 client, gpu_preferences); |
| 1194 } |
| 1195 } |
| 1196 |
1230 void VEAClient::CreateEncoder() { | 1197 void VEAClient::CreateEncoder() { |
1231 DCHECK(thread_checker_.CalledOnValidThread()); | 1198 DCHECK(thread_checker_.CalledOnValidThread()); |
1232 LOG_ASSERT(!has_encoder()); | 1199 LOG_ASSERT(!has_encoder()); |
1233 | 1200 |
1234 vea_client_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 1201 vea_client_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
1235 encode_task_runner_ = vea_client_task_runner_; | 1202 encode_task_runner_ = vea_client_task_runner_; |
1236 | 1203 |
1237 std::unique_ptr<VideoEncodeAccelerator> encoders[] = { | |
1238 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(), | |
1239 CreateMFVEA()}; | |
1240 | |
1241 DVLOG(1) << "Profile: " << test_stream_->requested_profile | 1204 DVLOG(1) << "Profile: " << test_stream_->requested_profile |
1242 << ", initial bitrate: " << requested_bitrate_; | 1205 << ", initial bitrate: " << requested_bitrate_; |
1243 | 1206 |
1244 for (size_t i = 0; i < arraysize(encoders); ++i) { | 1207 encoder_ = CreateVideoEncodeAccelerator( |
1245 if (!encoders[i]) | 1208 kInputFormat, test_stream_->visible_size, test_stream_->requested_profile, |
1246 continue; | 1209 requested_bitrate_, this, gpu::GpuPreferences()); |
1247 encoder_ = std::move(encoders[i]); | 1210 if (!encoder_) { |
1248 if (encoder_->Initialize(kInputFormat, test_stream_->visible_size, | 1211 LOG(ERROR) << "Failed creating a VideoEncodeAccelerator."; |
1249 test_stream_->requested_profile, | 1212 SetState(CS_ERROR); |
1250 requested_bitrate_, this)) { | 1213 return; |
1251 encoder_weak_factory_.reset( | |
1252 new base::WeakPtrFactory<VideoEncodeAccelerator>(encoder_.get())); | |
1253 TryToSetupEncodeOnSeparateThread(); | |
1254 SetStreamParameters(requested_bitrate_, requested_framerate_); | |
1255 SetState(CS_INITIALIZED); | |
1256 return; | |
1257 } | |
1258 } | 1214 } |
1259 encoder_.reset(); | 1215 encoder_weak_factory_.reset( |
1260 LOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; | 1216 new base::WeakPtrFactory<VideoEncodeAccelerator>(encoder_.get())); |
1261 SetState(CS_ERROR); | 1217 TryToSetupEncodeOnSeparateThread(); |
| 1218 SetStreamParameters(requested_bitrate_, requested_framerate_); |
| 1219 SetState(CS_INITIALIZED); |
1262 } | 1220 } |
1263 | 1221 |
1264 void VEAClient::DecodeCompleted() { | 1222 void VEAClient::DecodeCompleted() { |
1265 DCHECK(thread_checker_.CalledOnValidThread()); | 1223 DCHECK(thread_checker_.CalledOnValidThread()); |
1266 | 1224 |
1267 SetState(CS_VALIDATED); | 1225 SetState(CS_VALIDATED); |
1268 } | 1226 } |
1269 | 1227 |
1270 void VEAClient::TryToSetupEncodeOnSeparateThread() { | 1228 void VEAClient::TryToSetupEncodeOnSeparateThread() { |
1271 DCHECK(thread_checker_.CalledOnValidThread()); | 1229 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 bitrate_(200000), | 1808 bitrate_(200000), |
1851 fps_(30) { | 1809 fps_(30) { |
1852 thread_checker_.DetachFromThread(); | 1810 thread_checker_.DetachFromThread(); |
1853 } | 1811 } |
1854 | 1812 |
1855 void SimpleVEAClientBase::CreateEncoder() { | 1813 void SimpleVEAClientBase::CreateEncoder() { |
1856 DCHECK(thread_checker_.CalledOnValidThread()); | 1814 DCHECK(thread_checker_.CalledOnValidThread()); |
1857 LOG_ASSERT(!has_encoder()); | 1815 LOG_ASSERT(!has_encoder()); |
1858 LOG_ASSERT(g_env->test_streams_.size()); | 1816 LOG_ASSERT(g_env->test_streams_.size()); |
1859 | 1817 |
1860 std::unique_ptr<VideoEncodeAccelerator> encoders[] = { | |
1861 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(), | |
1862 CreateMFVEA()}; | |
1863 | |
1864 gfx::Size visible_size(width_, height_); | 1818 gfx::Size visible_size(width_, height_); |
1865 for (auto& encoder : encoders) { | 1819 encoder_ = CreateVideoEncodeAccelerator( |
1866 if (!encoder) | 1820 kInputFormat, visible_size, g_env->test_streams_[0]->requested_profile, |
1867 continue; | 1821 bitrate_, this, gpu::GpuPreferences()); |
1868 encoder_ = std::move(encoder); | 1822 if (!encoder_) { |
1869 if (encoder_->Initialize(kInputFormat, visible_size, | 1823 LOG(ERROR) << "Failed creating a VideoEncodeAccelerator."; |
1870 g_env->test_streams_[0]->requested_profile, | 1824 SetState(CS_ERROR); |
1871 bitrate_, this)) { | 1825 return; |
1872 encoder_->RequestEncodingParametersChange(bitrate_, fps_); | |
1873 SetState(CS_INITIALIZED); | |
1874 return; | |
1875 } | |
1876 } | 1826 } |
1877 encoder_.reset(); | 1827 encoder_->RequestEncodingParametersChange(bitrate_, fps_); |
1878 LOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; | 1828 SetState(CS_INITIALIZED); |
1879 SetState(CS_ERROR); | |
1880 } | 1829 } |
1881 | 1830 |
1882 void SimpleVEAClientBase::DestroyEncoder() { | 1831 void SimpleVEAClientBase::DestroyEncoder() { |
1883 DCHECK(thread_checker_.CalledOnValidThread()); | 1832 DCHECK(thread_checker_.CalledOnValidThread()); |
1884 if (!has_encoder()) | 1833 if (!has_encoder()) |
1885 return; | 1834 return; |
1886 // Clear the objects that should be destroyed on the same thread as creation. | 1835 // Clear the objects that should be destroyed on the same thread as creation. |
1887 encoder_.reset(); | 1836 encoder_.reset(); |
1888 } | 1837 } |
1889 | 1838 |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2368 | 2317 |
2369 if (needs_encode_latency && !run_at_fps) { | 2318 if (needs_encode_latency && !run_at_fps) { |
2370 // Encode latency can only be measured with --run_at_fps. Otherwise, we get | 2319 // Encode latency can only be measured with --run_at_fps. Otherwise, we get |
2371 // skewed results since it may queue too many frames at once with the same | 2320 // skewed results since it may queue too many frames at once with the same |
2372 // encode start time. | 2321 // encode start time. |
2373 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; | 2322 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; |
2374 } | 2323 } |
2375 | 2324 |
2376 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 2325 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
2377 media::VaapiWrapper::PreSandboxInitialization(); | 2326 media::VaapiWrapper::PreSandboxInitialization(); |
| 2327 #elif defined(OS_WIN) |
| 2328 media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); |
2378 #endif | 2329 #endif |
2379 | 2330 |
2380 media::g_env = | 2331 media::g_env = |
2381 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( | 2332 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( |
2382 testing::AddGlobalTestEnvironment( | 2333 testing::AddGlobalTestEnvironment( |
2383 new media::VideoEncodeAcceleratorTestEnvironment( | 2334 new media::VideoEncodeAcceleratorTestEnvironment( |
2384 std::move(test_stream_data), log_path, run_at_fps, | 2335 std::move(test_stream_data), log_path, run_at_fps, |
2385 needs_encode_latency, verify_all_output))); | 2336 needs_encode_latency, verify_all_output))); |
2386 | 2337 |
2387 return RUN_ALL_TESTS(); | 2338 return RUN_ALL_TESTS(); |
2388 } | 2339 } |
OLD | NEW |