Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Side by Side Diff: media/gpu/video_encode_accelerator_unittest.cc

Issue 2858193002: Refactor: Extract gpu_video_encode_accelerator_factory. (Closed)
Patch Set: address kcwu's comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698