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

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: Try Again. Fix compiling errors on Windows. 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 input_visible_size.height() > limits::kMaxDimension || 156 input_visible_size.height() > limits::kMaxDimension ||
210 input_visible_size.GetArea() > limits::kMaxCanvas) { 157 input_visible_size.GetArea() > limits::kMaxCanvas) {
211 DLOG(ERROR) << __func__ << "too large input_visible_size " 158 DLOG(ERROR) << __func__ << "too large input_visible_size "
212 << input_visible_size.ToString(); 159 << input_visible_size.ToString();
213 return false; 160 return false;
214 } 161 }
215 162
216 const gpu::GpuPreferences& gpu_preferences = 163 const gpu::GpuPreferences& gpu_preferences =
217 stub_->channel()->gpu_channel_manager()->gpu_preferences(); 164 stub_->channel()->gpu_channel_manager()->gpu_preferences();
218 165
219 // Try all possible encoders and use the first successful encoder. 166 encoder_ = GpuVideoEncodeAcceleratorFactory::CreateVEA(
220 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) { 167 input_format, input_visible_size, output_profile, initial_bitrate, this,
221 encoder_ = factory_function.Run(); 168 gpu_preferences);
222 if (encoder_ && 169 if (!encoder_) {
223 encoder_->Initialize(input_format, input_visible_size, output_profile, 170 DLOG(ERROR) << __func__ << " Could not create VEA";
224 initial_bitrate, this)) { 171 return false;
225 input_format_ = input_format; 172 }
226 input_visible_size_ = input_visible_size; 173 input_format_ = input_format;
227 // Attempt to set up performing encoding tasks on IO thread, if supported 174 input_visible_size_ = input_visible_size;
228 // by the VEA. 175 // Attempt to set up performing encoding tasks on IO thread, if supported
229 if (encoder_->TryToSetupEncodeOnSeparateThread(weak_this_, 176 // by the VEA.
230 io_task_runner_)) { 177 if (encoder_->TryToSetupEncodeOnSeparateThread(weak_this_, io_task_runner_)) {
231 filter_ = new MessageFilter(this, host_route_id_); 178 filter_ = new MessageFilter(this, host_route_id_);
232 stub_->channel()->AddFilter(filter_.get()); 179 stub_->channel()->AddFilter(filter_.get());
233 encode_task_runner_ = io_task_runner_; 180 encode_task_runner_ = io_task_runner_;
234 } 181 }
235 182
236 if (!encoder_worker_thread_.Start()) { 183 if (!encoder_worker_thread_.Start()) {
237 DLOG(ERROR) << "Failed spawning encoder worker thread."; 184 DLOG(ERROR) << "Failed spawning encoder worker thread.";
238 return false; 185 return false;
239 }
240 encoder_worker_task_runner_ = encoder_worker_thread_.task_runner();
241
242 return true;
243 }
244 } 186 }
245 encoder_.reset(); 187 encoder_worker_task_runner_ = encoder_worker_thread_.task_runner();
246 DLOG(ERROR) << __func__ << " VEA initialization failed"; 188 return true;
247 return false;
248 } 189 }
249 190
250 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { 191 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
251 bool handled = true; 192 bool handled = true;
252 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) 193 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
253 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) 194 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
254 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, 195 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
255 OnUseOutputBitstreamBuffer) 196 OnUseOutputBitstreamBuffer)
256 IPC_MESSAGE_HANDLER( 197 IPC_MESSAGE_HANDLER(
257 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, 198 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 stub_->channel()->RemoveRoute(host_route_id_); 276 stub_->channel()->RemoveRoute(host_route_id_);
336 stub_->RemoveDestructionObserver(this); 277 stub_->RemoveDestructionObserver(this);
337 encoder_.reset(); 278 encoder_.reset();
338 delete this; 279 delete this;
339 } 280 }
340 281
341 // static 282 // static
342 gpu::VideoEncodeAcceleratorSupportedProfiles 283 gpu::VideoEncodeAcceleratorSupportedProfiles
343 GpuVideoEncodeAccelerator::GetSupportedProfiles( 284 GpuVideoEncodeAccelerator::GetSupportedProfiles(
344 const gpu::GpuPreferences& gpu_preferences) { 285 const gpu::GpuPreferences& gpu_preferences) {
345 VideoEncodeAccelerator::SupportedProfiles profiles; 286 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(
346 287 GpuVideoEncodeAcceleratorFactory::GetSupportedProfiles(gpu_preferences));
347 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) {
348 std::unique_ptr<VideoEncodeAccelerator> encoder = factory_function.Run();
349 if (!encoder)
350 continue;
351 VideoEncodeAccelerator::SupportedProfiles vea_profiles =
352 encoder->GetSupportedProfiles();
353 GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles,
354 &profiles);
355 }
356 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles);
357 }
358
359 // static
360 std::vector<GpuVideoEncodeAccelerator::VEAFactoryFunction>
361 GpuVideoEncodeAccelerator::GetVEAFactoryFunctions(
362 const gpu::GpuPreferences& gpu_preferences) {
363 std::vector<VEAFactoryFunction> vea_factory_functions;
364 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
365 vea_factory_functions.push_back(base::Bind(&CreateV4L2VEA));
366 #endif
367 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
368 if (!gpu_preferences.disable_vaapi_accelerated_video_encode)
369 vea_factory_functions.push_back(base::Bind(&CreateVaapiVEA));
370 #endif
371 #if defined(OS_ANDROID) && BUILDFLAG(ENABLE_WEBRTC)
372 if (!gpu_preferences.disable_web_rtc_hw_encoding)
373 vea_factory_functions.push_back(base::Bind(&CreateAndroidVEA));
374 #endif
375 #if defined(OS_MACOSX)
376 vea_factory_functions.push_back(base::Bind(&CreateVTVEA));
377 #endif
378 #if defined(OS_WIN)
379 if (base::FeatureList::IsEnabled(kMediaFoundationH264Encoding))
380 vea_factory_functions.push_back(base::Bind(&CreateMediaFoundationVEA));
381 #endif
382 return vea_factory_functions;
383 } 288 }
384 289
385 void GpuVideoEncodeAccelerator::OnFilterRemoved() { 290 void GpuVideoEncodeAccelerator::OnFilterRemoved() {
386 DVLOG(2) << __func__; 291 DVLOG(2) << __func__;
387 DCHECK(io_task_runner_->BelongsToCurrentThread()); 292 DCHECK(io_task_runner_->BelongsToCurrentThread());
388 293
389 // We're destroying; cancel all callbacks. 294 // We're destroying; cancel all callbacks.
390 weak_this_factory_.InvalidateWeakPtrs(); 295 weak_this_factory_.InvalidateWeakPtrs();
391 filter_removed_.Signal(); 296 filter_removed_.Signal();
392 } 297 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 DLOG(ERROR) << __func__ << " failed."; 451 DLOG(ERROR) << __func__ << " failed.";
547 } 452 }
548 } 453 }
549 454
550 bool GpuVideoEncodeAccelerator::CheckIfCalledOnCorrectThread() { 455 bool GpuVideoEncodeAccelerator::CheckIfCalledOnCorrectThread() {
551 return (filter_ && io_task_runner_->BelongsToCurrentThread()) || 456 return (filter_ && io_task_runner_->BelongsToCurrentThread()) ||
552 (!filter_ && main_task_runner_->BelongsToCurrentThread()); 457 (!filter_ && main_task_runner_->BelongsToCurrentThread());
553 } 458 }
554 459
555 } // namespace media 460 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/gpu_video_encode_accelerator_factory.cc ('k') | media/gpu/video_encode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698