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(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" | |
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 | |
74 | |
75 namespace media { | 57 namespace media { |
76 namespace { | 58 namespace { |
77 | 59 |
78 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420; | 60 const VideoPixelFormat kInputFormat = PIXEL_FORMAT_I420; |
79 | 61 |
80 // The absolute differences between original frame and decoded frame usually | 62 // 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 | 63 // ranges aroud 1 ~ 7. So we pick 10 as an extreme value to detect abnormal |
82 // decoded frames. | 64 // decoded frames. |
83 const double kDecodeSimilarityThreshold = 10.0; | 65 const double kDecodeSimilarityThreshold = 10.0; |
84 | 66 |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 } | 417 } |
436 | 418 |
437 if (fields.size() >= 9 && !fields[8].empty()) { | 419 if (fields.size() >= 9 && !fields[8].empty()) { |
438 LOG_ASSERT(base::StringToUint( | 420 LOG_ASSERT(base::StringToUint( |
439 fields[8], &test_stream->requested_subsequent_framerate)); | 421 fields[8], &test_stream->requested_subsequent_framerate)); |
440 } | 422 } |
441 test_streams->push_back(test_stream); | 423 test_streams->push_back(test_stream); |
442 } | 424 } |
443 } | 425 } |
444 | 426 |
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 | 427 // Basic test environment shared across multiple test cases. We only need to |
491 // setup it once for all test cases. | 428 // setup it once for all test cases. |
492 // It helps | 429 // It helps |
493 // - maintain test stream data and other test settings. | 430 // - maintain test stream data and other test settings. |
494 // - clean up temporary aligned files. | 431 // - clean up temporary aligned files. |
495 // - output log to file. | 432 // - output log to file. |
496 class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { | 433 class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { |
497 public: | 434 public: |
498 VideoEncodeAcceleratorTestEnvironment( | 435 VideoEncodeAcceleratorTestEnvironment( |
499 std::unique_ptr<base::FilePath::StringType> data, | 436 std::unique_ptr<base::FilePath::StringType> data, |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1190 requested_bitrate_(0), | 1127 requested_bitrate_(0), |
1191 requested_framerate_(0), | 1128 requested_framerate_(0), |
1192 requested_subsequent_bitrate_(0), | 1129 requested_subsequent_bitrate_(0), |
1193 requested_subsequent_framerate_(0), | 1130 requested_subsequent_framerate_(0), |
1194 io_thread_("IOThread"), | 1131 io_thread_("IOThread"), |
1195 client_weak_factory_for_io_(this) { | 1132 client_weak_factory_for_io_(this) { |
1196 if (keyframe_period_) | 1133 if (keyframe_period_) |
1197 LOG_ASSERT(kMaxKeyframeDelay < keyframe_period_); | 1134 LOG_ASSERT(kMaxKeyframeDelay < keyframe_period_); |
1198 | 1135 |
1199 // Fake encoder produces an invalid stream, so skip validating it. | 1136 // Fake encoder produces an invalid stream, so skip validating it. |
1200 if (!g_fake_encoder) { | 1137 if (!g_fake_encoder) { |
Pawel Osciak
2017/05/15 01:28:51
I'm wondering if this should also use be using the
Owen Lin
2017/05/16 07:35:05
I would prefer to do it in another CL, it is not r
Pawel Osciak
2017/05/18 04:33:37
Acknowledged.
| |
1201 stream_validator_ = StreamValidator::Create( | 1138 stream_validator_ = StreamValidator::Create( |
1202 test_stream_->requested_profile, | 1139 test_stream_->requested_profile, |
1203 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this))); | 1140 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this))); |
1204 CHECK(stream_validator_); | 1141 CHECK(stream_validator_); |
1205 } | 1142 } |
1206 | 1143 |
1207 if (save_to_file_) { | 1144 if (save_to_file_) { |
1208 LOG_ASSERT(!test_stream_->out_filename.empty()); | 1145 LOG_ASSERT(!test_stream_->out_filename.empty()); |
1209 #if defined(OS_POSIX) | 1146 #if defined(OS_POSIX) |
1210 base::FilePath out_filename(test_stream_->out_filename); | 1147 base::FilePath out_filename(test_stream_->out_filename); |
1211 #elif defined(OS_WIN) | 1148 #elif defined(OS_WIN) |
1212 base::FilePath out_filename(base::UTF8ToWide(test_stream_->out_filename)); | 1149 base::FilePath out_filename(base::UTF8ToWide(test_stream_->out_filename)); |
1213 #endif | 1150 #endif |
1214 // This creates or truncates out_filename. | 1151 // This creates or truncates out_filename. |
1215 // Without it, AppendToFile() will not work. | 1152 // Without it, AppendToFile() will not work. |
1216 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); | 1153 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); |
1217 } | 1154 } |
1218 | 1155 |
1219 // Initialize the parameters of the test streams. | 1156 // Initialize the parameters of the test streams. |
1220 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); | 1157 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); |
1221 | 1158 |
1222 thread_checker_.DetachFromThread(); | 1159 thread_checker_.DetachFromThread(); |
1223 } | 1160 } |
1224 | 1161 |
1162 // Helper function to create VEA | |
Pawel Osciak
2017/05/15 01:28:52
Nit: dot at the end of sentence.
Owen Lin
2017/05/16 07:35:05
Done.
| |
1163 static std::unique_ptr<VideoEncodeAccelerator> CreateVideoEncodeAccelerator( | |
1164 VideoPixelFormat input_format, | |
1165 const gfx::Size& input_visible_size, | |
1166 VideoCodecProfile output_profile, | |
1167 uint32_t initial_bitrate, | |
1168 VideoEncodeAccelerator::Client* client, | |
1169 const gpu::GpuPreferences& gpu_perferences) { | |
Pawel Osciak
2017/05/15 01:28:52
s/gpu_perferences/gpu_preferences/
Owen Lin
2017/05/16 07:35:05
Done.
| |
1170 if (g_fake_encoder) { | |
1171 std::unique_ptr<VideoEncodeAccelerator> encoder( | |
1172 new FakeVideoEncodeAccelerator( | |
1173 scoped_refptr<base::SingleThreadTaskRunner>( | |
1174 base::ThreadTaskRunnerHandle::Get()))); | |
1175 return encoder->Initialize(input_format, input_visible_size, output_profile, | |
Pawel Osciak
2017/05/15 01:28:51
Would this perhaps be a bit more readable?
if (en
Owen Lin
2017/05/16 07:35:05
Done.
| |
1176 initial_bitrate, client) | |
1177 ? std::move(encoder) | |
1178 : nullptr; | |
1179 } else { | |
1180 GpuVideoEncodeAcceleratorFactory factory; | |
1181 return factory.CreateVEA(input_format, input_visible_size, output_profile, | |
1182 initial_bitrate, client, gpu_perferences); | |
1183 } | |
1184 } | |
1185 | |
1225 void VEAClient::CreateEncoder() { | 1186 void VEAClient::CreateEncoder() { |
1226 DCHECK(thread_checker_.CalledOnValidThread()); | 1187 DCHECK(thread_checker_.CalledOnValidThread()); |
1227 LOG_ASSERT(!has_encoder()); | 1188 LOG_ASSERT(!has_encoder()); |
1228 | 1189 |
1229 vea_client_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 1190 vea_client_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
1230 encode_task_runner_ = vea_client_task_runner_; | 1191 encode_task_runner_ = vea_client_task_runner_; |
1231 | 1192 |
1232 std::unique_ptr<VideoEncodeAccelerator> encoders[] = { | |
1233 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(), | |
1234 CreateMFVEA()}; | |
1235 | |
1236 DVLOG(1) << "Profile: " << test_stream_->requested_profile | 1193 DVLOG(1) << "Profile: " << test_stream_->requested_profile |
1237 << ", initial bitrate: " << requested_bitrate_; | 1194 << ", initial bitrate: " << requested_bitrate_; |
1238 | 1195 |
1239 for (size_t i = 0; i < arraysize(encoders); ++i) { | 1196 encoder_ = CreateVideoEncodeAccelerator( |
1240 if (!encoders[i]) | 1197 kInputFormat, test_stream_->visible_size, test_stream_->requested_profile, |
1241 continue; | 1198 requested_bitrate_, this, gpu::GpuPreferences()); |
1242 encoder_ = std::move(encoders[i]); | 1199 if (!encoder_) { |
1243 if (encoder_->Initialize(kInputFormat, test_stream_->visible_size, | 1200 LOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; |
Pawel Osciak
2017/05/15 01:28:52
Failed creating a VideoEncodeAccelerator.
Owen Lin
2017/05/16 07:35:05
Done.
| |
1244 test_stream_->requested_profile, | 1201 SetState(CS_ERROR); |
1245 requested_bitrate_, this)) { | 1202 return; |
1246 encoder_weak_factory_.reset( | 1203 } |
1247 new base::WeakPtrFactory<VideoEncodeAccelerator>(encoder_.get())); | 1204 encoder_weak_factory_.reset( |
1248 TryToSetupEncodeOnSeparateThread(); | 1205 new base::WeakPtrFactory<VideoEncodeAccelerator>(encoder_.get())); |
1249 SetStreamParameters(requested_bitrate_, requested_framerate_); | 1206 TryToSetupEncodeOnSeparateThread(); |
1250 SetState(CS_INITIALIZED); | 1207 SetStreamParameters(requested_bitrate_, requested_framerate_); |
1208 SetState(CS_INITIALIZED); | |
1251 | 1209 |
1252 if (verify_output_ && !g_fake_encoder) | 1210 if (verify_output_ && !g_fake_encoder) |
Pawel Osciak
2017/05/15 01:28:51
I'm wondering if we should move this to be in the
Owen Lin
2017/05/16 07:35:05
Will do in another CL.
| |
1253 quality_validator_.reset(new VideoFrameQualityValidator( | 1211 quality_validator_.reset(new VideoFrameQualityValidator( |
1254 test_stream_->requested_profile, | 1212 test_stream_->requested_profile, |
1255 base::Bind(&VEAClient::DecodeCompleted, base::Unretained(this)), | 1213 base::Bind(&VEAClient::DecodeCompleted, base::Unretained(this)), |
1256 base::Bind(&VEAClient::DecodeFailed, base::Unretained(this)))); | 1214 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 } | 1215 } |
1264 | 1216 |
1265 void VEAClient::DecodeCompleted() { | 1217 void VEAClient::DecodeCompleted() { |
1266 DCHECK(thread_checker_.CalledOnValidThread()); | 1218 DCHECK(thread_checker_.CalledOnValidThread()); |
1267 | 1219 |
1268 SetState(CS_VALIDATED); | 1220 SetState(CS_VALIDATED); |
1269 } | 1221 } |
1270 | 1222 |
1271 void VEAClient::TryToSetupEncodeOnSeparateThread() { | 1223 void VEAClient::TryToSetupEncodeOnSeparateThread() { |
1272 DCHECK(thread_checker_.CalledOnValidThread()); | 1224 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1849 bitrate_(200000), | 1801 bitrate_(200000), |
1850 fps_(30) { | 1802 fps_(30) { |
1851 thread_checker_.DetachFromThread(); | 1803 thread_checker_.DetachFromThread(); |
1852 } | 1804 } |
1853 | 1805 |
1854 void SimpleVEAClientBase::CreateEncoder() { | 1806 void SimpleVEAClientBase::CreateEncoder() { |
1855 DCHECK(thread_checker_.CalledOnValidThread()); | 1807 DCHECK(thread_checker_.CalledOnValidThread()); |
1856 LOG_ASSERT(!has_encoder()); | 1808 LOG_ASSERT(!has_encoder()); |
1857 LOG_ASSERT(g_env->test_streams_.size()); | 1809 LOG_ASSERT(g_env->test_streams_.size()); |
1858 | 1810 |
1859 std::unique_ptr<VideoEncodeAccelerator> encoders[] = { | |
1860 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(), | |
1861 CreateMFVEA()}; | |
1862 | |
1863 gfx::Size visible_size(width_, height_); | 1811 gfx::Size visible_size(width_, height_); |
1864 for (auto& encoder : encoders) { | 1812 encoder_ = CreateVideoEncodeAccelerator( |
1865 if (!encoder) | 1813 kInputFormat, visible_size, g_env->test_streams_[0]->requested_profile, |
1866 continue; | 1814 bitrate_, this, gpu::GpuPreferences()); |
1867 encoder_ = std::move(encoder); | 1815 if (!encoder_) { |
1868 if (encoder_->Initialize(kInputFormat, visible_size, | 1816 LOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; |
Pawel Osciak
2017/05/15 01:28:51
Failed creating a VideoEncodeAccelerator.
Owen Lin
2017/05/16 07:35:05
Done.
| |
1869 g_env->test_streams_[0]->requested_profile, | 1817 SetState(CS_ERROR); |
1870 bitrate_, this)) { | 1818 return; |
1871 encoder_->RequestEncodingParametersChange(bitrate_, fps_); | |
1872 SetState(CS_INITIALIZED); | |
1873 return; | |
1874 } | |
1875 } | 1819 } |
1876 encoder_.reset(); | 1820 encoder_->RequestEncodingParametersChange(bitrate_, fps_); |
1877 LOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; | 1821 SetState(CS_INITIALIZED); |
1878 SetState(CS_ERROR); | |
1879 } | 1822 } |
1880 | 1823 |
1881 void SimpleVEAClientBase::DestroyEncoder() { | 1824 void SimpleVEAClientBase::DestroyEncoder() { |
1882 DCHECK(thread_checker_.CalledOnValidThread()); | 1825 DCHECK(thread_checker_.CalledOnValidThread()); |
1883 if (!has_encoder()) | 1826 if (!has_encoder()) |
1884 return; | 1827 return; |
1885 // Clear the objects that should be destroyed on the same thread as creation. | 1828 // Clear the objects that should be destroyed on the same thread as creation. |
1886 encoder_.reset(); | 1829 encoder_.reset(); |
1887 } | 1830 } |
1888 | 1831 |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2367 | 2310 |
2368 if (needs_encode_latency && !run_at_fps) { | 2311 if (needs_encode_latency && !run_at_fps) { |
2369 // Encode latency can only be measured with --run_at_fps. Otherwise, we get | 2312 // 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 | 2313 // skewed results since it may queue too many frames at once with the same |
2371 // encode start time. | 2314 // encode start time. |
2372 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; | 2315 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; |
2373 } | 2316 } |
2374 | 2317 |
2375 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 2318 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
2376 media::VaapiWrapper::PreSandboxInitialization(); | 2319 media::VaapiWrapper::PreSandboxInitialization(); |
2320 #elif defined(OS_WIN) | |
2321 MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); | |
2377 #endif | 2322 #endif |
2378 | 2323 |
2379 media::g_env = | 2324 media::g_env = |
2380 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( | 2325 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( |
2381 testing::AddGlobalTestEnvironment( | 2326 testing::AddGlobalTestEnvironment( |
2382 new media::VideoEncodeAcceleratorTestEnvironment( | 2327 new media::VideoEncodeAcceleratorTestEnvironment( |
2383 std::move(test_stream_data), log_path, run_at_fps, | 2328 std::move(test_stream_data), log_path, run_at_fps, |
2384 needs_encode_latency, verify_all_output))); | 2329 needs_encode_latency, verify_all_output))); |
2385 | 2330 |
2386 return RUN_ALL_TESTS(); | 2331 return RUN_ALL_TESTS(); |
2387 } | 2332 } |
OLD | NEW |