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

Side by Side Diff: media/gpu/ipc/service/gpu_video_encode_accelerator.cc

Issue 2858193002: Refactor: Extract gpu_video_encode_accelerator_factory. (Closed)
Patch Set: 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 "media/gpu/ipc/service/gpu_video_encode_accelerator.h" 5 #include "media/gpu/ipc/service/gpu_video_encode_accelerator.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/memory/shared_memory.h" 13 #include "base/memory/shared_memory.h"
14 #include "base/numerics/safe_math.h" 14 #include "base/numerics/safe_math.h"
15 #include "base/sys_info.h" 15 #include "base/sys_info.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "build/build_config.h" 17 #include "build/build_config.h"
18 #include "gpu/ipc/service/gpu_channel.h" 18 #include "gpu/ipc/service/gpu_channel.h"
19 #include "gpu/ipc/service/gpu_channel_manager.h" 19 #include "gpu/ipc/service/gpu_channel_manager.h"
20 #include "ipc/ipc_message_macros.h" 20 #include "ipc/ipc_message_macros.h"
21 #include "media/base/bind_to_current_loop.h" 21 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/limits.h" 22 #include "media/base/limits.h"
23 #include "media/base/video_frame.h" 23 #include "media/base/video_frame.h"
24 #include "media/gpu/gpu_video_accelerator_util.h" 24 #include "media/gpu/gpu_video_accelerator_util.h"
25 #include "media/gpu/gpu_video_encode_accelerator_factory.h"
25 #include "media/gpu/ipc/common/media_messages.h" 26 #include "media/gpu/ipc/common/media_messages.h"
26 #include "media/media_features.h" 27 #include "media/media_features.h"
27 28
28 #if defined(OS_CHROMEOS)
29 #if defined(USE_V4L2_CODEC)
30 #include "media/gpu/v4l2_video_encode_accelerator.h"
31 #endif
32 #if defined(ARCH_CPU_X86_FAMILY)
33 #include "media/gpu/vaapi_video_encode_accelerator.h"
34 #endif
35 #elif defined(OS_ANDROID) && BUILDFLAG(ENABLE_WEBRTC)
36 #include "media/gpu/android_video_encode_accelerator.h"
37 #elif defined(OS_MACOSX)
38 #include "media/gpu/vt_video_encode_accelerator_mac.h"
39 #elif defined(OS_WIN)
40 #include "base/feature_list.h"
41 #include "media/base/media_switches.h"
42 #include "media/gpu/media_foundation_video_encode_accelerator_win.h"
43 #endif
44 29
45 namespace media { 30 namespace media {
46 31
47 namespace { 32 namespace {
48 33
49 bool MakeDecoderContextCurrent( 34 bool MakeDecoderContextCurrent(
50 const base::WeakPtr<gpu::GpuCommandBufferStub> stub) { 35 const base::WeakPtr<gpu::GpuCommandBufferStub> stub) {
51 if (!stub) { 36 if (!stub) {
52 DLOG(ERROR) << "Stub is gone; won't MakeCurrent()."; 37 DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
53 return false; 38 return false;
54 } 39 }
55 40
56 if (!stub->decoder()->MakeCurrent()) { 41 if (!stub->decoder()->MakeCurrent()) {
57 DLOG(ERROR) << "Failed to MakeCurrent()"; 42 DLOG(ERROR) << "Failed to MakeCurrent()";
58 return false; 43 return false;
59 } 44 }
60 45
61 return true; 46 return true;
62 } 47 }
63 48
64 void DropSharedMemory(std::unique_ptr<base::SharedMemory> shm) { 49 void DropSharedMemory(std::unique_ptr<base::SharedMemory> shm) {
65 // Just let |shm| fall out of scope. 50 // Just let |shm| fall out of scope.
66 } 51 }
67 52
68 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
69 std::unique_ptr<VideoEncodeAccelerator> CreateV4L2VEA() {
70 scoped_refptr<V4L2Device> device = V4L2Device::Create();
71 if (!device)
72 return nullptr;
73 return base::WrapUnique<VideoEncodeAccelerator>(
74 new V4L2VideoEncodeAccelerator(device));
75 }
76 #endif
77
78 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
79 std::unique_ptr<VideoEncodeAccelerator> CreateVaapiVEA() {
80 return base::WrapUnique<VideoEncodeAccelerator>(
81 new VaapiVideoEncodeAccelerator());
82 }
83 #endif
84
85 #if defined(OS_ANDROID) && BUILDFLAG(ENABLE_WEBRTC)
86 std::unique_ptr<VideoEncodeAccelerator> CreateAndroidVEA() {
87 return base::WrapUnique<VideoEncodeAccelerator>(
88 new AndroidVideoEncodeAccelerator());
89 }
90 #endif
91
92 #if defined(OS_MACOSX)
93 std::unique_ptr<VideoEncodeAccelerator> CreateVTVEA() {
94 return base::WrapUnique<VideoEncodeAccelerator>(
95 new VTVideoEncodeAccelerator());
96 }
97 #endif
98
99 #if defined(OS_WIN)
100 std::unique_ptr<VideoEncodeAccelerator> CreateMediaFoundationVEA() {
101 return base::WrapUnique<media::VideoEncodeAccelerator>(
102 new MediaFoundationVideoEncodeAccelerator());
103 }
104 #endif
105
106 } // anonymous namespace 53 } // anonymous namespace
107 54
108 class GpuVideoEncodeAccelerator::MessageFilter : public IPC::MessageFilter { 55 class GpuVideoEncodeAccelerator::MessageFilter : public IPC::MessageFilter {
109 public: 56 public:
110 MessageFilter(GpuVideoEncodeAccelerator* owner, int32_t host_route_id) 57 MessageFilter(GpuVideoEncodeAccelerator* owner, int32_t host_route_id)
111 : owner_(owner), host_route_id_(host_route_id) {} 58 : owner_(owner), host_route_id_(host_route_id) {}
112 59
113 void OnChannelError() override { sender_ = nullptr; } 60 void OnChannelError() override { sender_ = nullptr; }
114 61
115 void OnChannelClosing() override { sender_ = nullptr; } 62 void OnChannelClosing() override { sender_ = nullptr; }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 input_visible_size.height() > limits::kMaxDimension || 159 input_visible_size.height() > limits::kMaxDimension ||
213 input_visible_size.GetArea() > limits::kMaxCanvas) { 160 input_visible_size.GetArea() > limits::kMaxCanvas) {
214 DLOG(ERROR) << __func__ << "too large input_visible_size " 161 DLOG(ERROR) << __func__ << "too large input_visible_size "
215 << input_visible_size.ToString(); 162 << input_visible_size.ToString();
216 return false; 163 return false;
217 } 164 }
218 165
219 const gpu::GpuPreferences& gpu_preferences = 166 const gpu::GpuPreferences& gpu_preferences =
220 stub_->channel()->gpu_channel_manager()->gpu_preferences(); 167 stub_->channel()->gpu_channel_manager()->gpu_preferences();
221 168
222 // Try all possible encoders and use the first successful encoder. 169 // Try all possible encoders and use the first successful encoder.
kcwu 2017/05/05 09:31:17 Remove this out of date comment.
Owen Lin 2017/05/11 08:09:29 Done.
223 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) { 170 GpuVideoEncodeAcceleratorFactory factory;
224 encoder_ = factory_function.Run(); 171 encoder_ = factory.CreateVEA(input_format, input_visible_size, output_profile,
225 if (encoder_ && 172 initial_bitrate, this, gpu_preferences);
226 encoder_->Initialize(input_format, input_visible_size, output_profile, 173 if (!encoder_) {
227 initial_bitrate, this)) { 174 DLOG(ERROR) << __func__ << " VEA initialization failed";
228 input_format_ = input_format; 175 return false;
229 input_visible_size_ = input_visible_size; 176 }
230 // Attempt to set up performing encoding tasks on IO thread, if supported 177 input_format_ = input_format;
231 // by the VEA. 178 input_visible_size_ = input_visible_size;
232 if (encoder_->TryToSetupEncodeOnSeparateThread( 179 // Attempt to set up performing encoding tasks on IO thread, if supported
233 weak_this_factory_.GetWeakPtr(), io_task_runner_)) { 180 // by the VEA.
234 filter_ = new MessageFilter(this, host_route_id_); 181 if (encoder_->TryToSetupEncodeOnSeparateThread(
235 stub_->channel()->AddFilter(filter_.get()); 182 weak_this_factory_.GetWeakPtr(), io_task_runner_)) {
236 encode_task_runner_ = io_task_runner_; 183 filter_ = new MessageFilter(this, host_route_id_);
237 } 184 stub_->channel()->AddFilter(filter_.get());
185 encode_task_runner_ = io_task_runner_;
186 }
238 187
239 if (!encoder_worker_thread_.Start()) { 188 if (!encoder_worker_thread_.Start()) {
240 DLOG(ERROR) << "Failed spawning encoder worker thread."; 189 DLOG(ERROR) << "Failed spawning encoder worker thread.";
241 return false; 190 return false;
242 }
243 encoder_worker_task_runner_ = encoder_worker_thread_.task_runner();
244
245 return true;
246 }
247 } 191 }
248 encoder_.reset(); 192 encoder_worker_task_runner_ = encoder_worker_thread_.task_runner();
249 DLOG(ERROR) << __func__ << " VEA initialization failed"; 193 return true;
250 return false;
251 } 194 }
252 195
253 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { 196 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
254 bool handled = true; 197 bool handled = true;
255 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) 198 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
256 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) 199 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
257 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, 200 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
258 OnUseOutputBitstreamBuffer) 201 OnUseOutputBitstreamBuffer)
259 IPC_MESSAGE_HANDLER( 202 IPC_MESSAGE_HANDLER(
260 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, 203 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 stub_->channel()->RemoveRoute(host_route_id_); 271 stub_->channel()->RemoveRoute(host_route_id_);
329 stub_->RemoveDestructionObserver(this); 272 stub_->RemoveDestructionObserver(this);
330 encoder_.reset(); 273 encoder_.reset();
331 delete this; 274 delete this;
332 } 275 }
333 276
334 // static 277 // static
335 gpu::VideoEncodeAcceleratorSupportedProfiles 278 gpu::VideoEncodeAcceleratorSupportedProfiles
336 GpuVideoEncodeAccelerator::GetSupportedProfiles( 279 GpuVideoEncodeAccelerator::GetSupportedProfiles(
337 const gpu::GpuPreferences& gpu_preferences) { 280 const gpu::GpuPreferences& gpu_preferences) {
338 VideoEncodeAccelerator::SupportedProfiles profiles; 281 GpuVideoEncodeAcceleratorFactory factory;
339 282 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(
340 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) { 283 factory.GetSupportedProfiles(gpu_preferences));
341 std::unique_ptr<VideoEncodeAccelerator> encoder = factory_function.Run();
342 if (!encoder)
343 continue;
344 VideoEncodeAccelerator::SupportedProfiles vea_profiles =
345 encoder->GetSupportedProfiles();
346 GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles,
347 &profiles);
348 }
349 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles);
350 }
351
352 // static
353 std::vector<GpuVideoEncodeAccelerator::VEAFactoryFunction>
354 GpuVideoEncodeAccelerator::GetVEAFactoryFunctions(
355 const gpu::GpuPreferences& gpu_preferences) {
356 std::vector<VEAFactoryFunction> vea_factory_functions;
357 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
358 vea_factory_functions.push_back(base::Bind(&CreateV4L2VEA));
359 #endif
360 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
361 if (!gpu_preferences.disable_vaapi_accelerated_video_encode)
362 vea_factory_functions.push_back(base::Bind(&CreateVaapiVEA));
363 #endif
364 #if defined(OS_ANDROID) && BUILDFLAG(ENABLE_WEBRTC)
365 if (!gpu_preferences.disable_web_rtc_hw_encoding)
366 vea_factory_functions.push_back(base::Bind(&CreateAndroidVEA));
367 #endif
368 #if defined(OS_MACOSX)
369 vea_factory_functions.push_back(base::Bind(&CreateVTVEA));
370 #endif
371 #if defined(OS_WIN)
372 if (base::FeatureList::IsEnabled(kMediaFoundationH264Encoding))
373 vea_factory_functions.push_back(base::Bind(&CreateMediaFoundationVEA));
374 #endif
375 return vea_factory_functions;
376 } 284 }
377 285
378 void GpuVideoEncodeAccelerator::OnFilterRemoved() { 286 void GpuVideoEncodeAccelerator::OnFilterRemoved() {
379 DVLOG(2) << __func__; 287 DVLOG(2) << __func__;
380 DCHECK(io_task_runner_->BelongsToCurrentThread()); 288 DCHECK(io_task_runner_->BelongsToCurrentThread());
381 289
382 // We're destroying; cancel all callbacks. 290 // We're destroying; cancel all callbacks.
383 weak_this_factory_.InvalidateWeakPtrs(); 291 weak_this_factory_.InvalidateWeakPtrs();
384 filter_removed_.Signal(); 292 filter_removed_.Signal();
385 } 293 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 DLOG(ERROR) << __func__ << " failed."; 444 DLOG(ERROR) << __func__ << " failed.";
537 } 445 }
538 } 446 }
539 447
540 bool GpuVideoEncodeAccelerator::CheckIfCalledOnCorrectThread() { 448 bool GpuVideoEncodeAccelerator::CheckIfCalledOnCorrectThread() {
541 return (filter_ && io_task_runner_->BelongsToCurrentThread()) || 449 return (filter_ && io_task_runner_->BelongsToCurrentThread()) ||
542 (!filter_ && main_task_runner_->BelongsToCurrentThread()); 450 (!filter_ && main_task_runner_->BelongsToCurrentThread());
543 } 451 }
544 452
545 } // namespace media 453 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698