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