Index: content/common/gpu/media/gpu_video_decode_accelerator.cc |
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc |
index 2be88e228f726c0d0838518a6696a804e2e93536..4aa5c34976b01385b6e24bb2bb6b73b0e8d1c056 100644 |
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc |
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc |
@@ -20,6 +20,7 @@ |
#include "content/common/gpu/media/gpu_video_accelerator_util.h" |
#include "content/common/gpu/media_messages.h" |
#include "content/public/common/content_switches.h" |
+#include "content/public/common/gpu_video_decode_accelerator_factory.h" |
#include "gpu/command_buffer/common/command_buffer.h" |
#include "ipc/ipc_message_macros.h" |
#include "ipc/ipc_message_utils.h" |
@@ -27,35 +28,23 @@ |
#include "media/base/limits.h" |
#include "ui/gl/gl_context.h" |
#include "ui/gl/gl_image.h" |
-#include "ui/gl/gl_surface_egl.h" |
- |
-#if defined(OS_WIN) |
-#include "base/win/windows_version.h" |
-#include "content/common/gpu/media/dxva_video_decode_accelerator_win.h" |
-#elif defined(OS_MACOSX) |
-#include "content/common/gpu/media/vt_video_decode_accelerator_mac.h" |
-#elif defined(OS_CHROMEOS) |
-#if defined(USE_V4L2_CODEC) |
-#include "content/common/gpu/media/v4l2_device.h" |
-#include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" |
-#include "content/common/gpu/media/v4l2_video_decode_accelerator.h" |
-#endif |
-#if defined(ARCH_CPU_X86_FAMILY) |
-#include "content/common/gpu/media/vaapi_video_decode_accelerator.h" |
-#include "ui/gl/gl_implementation.h" |
-#endif |
-#elif defined(USE_OZONE) |
-#include "media/ozone/media_ozone_platform.h" |
-#elif defined(OS_ANDROID) |
-#include "content/common/gpu/media/android_video_decode_accelerator.h" |
-#endif |
- |
#include "ui/gfx/geometry/size.h" |
namespace content { |
+namespace { |
+static gfx::GLContext* GetGLContext( |
+ const base::WeakPtr<GpuCommandBufferStub>& stub) { |
+ if (!stub) { |
+ DLOG(ERROR) << "Stub is gone; no GLContext."; |
+ return nullptr; |
+ } |
+ |
+ return stub->decoder()->GetGLContext(); |
+} |
+ |
static bool MakeDecoderContextCurrent( |
- const base::WeakPtr<GpuCommandBufferStub> stub) { |
+ const base::WeakPtr<GpuCommandBufferStub>& stub) { |
if (!stub) { |
DLOG(ERROR) << "Stub is gone; won't MakeCurrent()."; |
return false; |
@@ -69,6 +58,38 @@ static bool MakeDecoderContextCurrent( |
return true; |
} |
+static bool BindImage(const base::WeakPtr<GpuCommandBufferStub>& stub, |
+ uint32_t client_texture_id, |
+ uint32_t texture_target, |
+ const scoped_refptr<gl::GLImage>& image) { |
+ if (!stub) { |
+ DLOG(ERROR) << "Stub is gone; won't BindImage()."; |
+ return false; |
+ } |
+ |
+ gpu::gles2::GLES2Decoder* command_decoder = stub->decoder(); |
+ gpu::gles2::TextureManager* texture_manager = |
+ command_decoder->GetContextGroup()->texture_manager(); |
+ gpu::gles2::TextureRef* ref = texture_manager->GetTexture(client_texture_id); |
+ if (ref) { |
+ texture_manager->SetLevelImage(ref, texture_target, 0, image.get(), |
+ gpu::gles2::Texture::BOUND); |
+ } |
+ |
+ return true; |
+} |
+ |
+static base::WeakPtr<gpu::gles2::GLES2Decoder> GetGLES2Decoder( |
+ const base::WeakPtr<GpuCommandBufferStub>& stub) { |
+ if (!stub) { |
+ DLOG(ERROR) << "Stub is gone; no GLES2Decoder."; |
+ return base::WeakPtr<gpu::gles2::GLES2Decoder>(); |
+ } |
+ |
+ return stub->decoder()->AsWeakPtr(); |
+} |
+} // anonymous namespace |
+ |
// DebugAutoLock works like AutoLock but only acquires the lock when |
// DCHECK is on. |
#if DCHECK_IS_ON() |
@@ -140,8 +161,11 @@ GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( |
weak_factory_for_io_(this) { |
DCHECK(stub_); |
stub_->AddDestructionObserver(this); |
- make_context_current_ = |
+ get_gl_context_cb_ = base::Bind(&GetGLContext, stub_->AsWeakPtr()); |
+ make_context_current_cb_ = |
base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); |
+ bind_image_cb_ = base::Bind(&BindImage, stub_->AsWeakPtr()); |
+ get_gles2_decoder_cb_ = base::Bind(&GetGLES2Decoder, stub_->AsWeakPtr()); |
} |
GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { |
@@ -153,40 +177,7 @@ GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { |
// static |
gpu::VideoDecodeAcceleratorCapabilities |
GpuVideoDecodeAccelerator::GetCapabilities() { |
- media::VideoDecodeAccelerator::Capabilities capabilities; |
- const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
- if (cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) |
- return gpu::VideoDecodeAcceleratorCapabilities(); |
- |
- // Query supported profiles for each VDA. The order of querying VDAs should |
- // be the same as the order of initializing VDAs. Then the returned profile |
- // can be initialized by corresponding VDA successfully. |
-#if defined(OS_WIN) |
- capabilities.supported_profiles = |
- DXVAVideoDecodeAccelerator::GetSupportedProfiles(); |
-#elif defined(OS_CHROMEOS) |
- media::VideoDecodeAccelerator::SupportedProfiles vda_profiles; |
-#if defined(USE_V4L2_CODEC) |
- vda_profiles = V4L2VideoDecodeAccelerator::GetSupportedProfiles(); |
- GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles( |
- vda_profiles, &capabilities.supported_profiles); |
- vda_profiles = V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles(); |
- GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles( |
- vda_profiles, &capabilities.supported_profiles); |
-#endif |
-#if defined(ARCH_CPU_X86_FAMILY) |
- vda_profiles = VaapiVideoDecodeAccelerator::GetSupportedProfiles(); |
- GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles( |
- vda_profiles, &capabilities.supported_profiles); |
-#endif |
-#elif defined(OS_MACOSX) |
- capabilities.supported_profiles = |
- VTVideoDecodeAccelerator::GetSupportedProfiles(); |
-#elif defined(OS_ANDROID) |
- capabilities = AndroidVideoDecodeAccelerator::GetCapabilities(); |
-#endif |
- return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities( |
- capabilities); |
+ return GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities(); |
} |
bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { |
@@ -339,146 +330,36 @@ bool GpuVideoDecodeAccelerator::Initialize( |
#if !defined(OS_WIN) |
// Ensure we will be able to get a GL context at all before initializing |
// non-Windows VDAs. |
- if (!make_context_current_.Run()) { |
+ if (!make_context_current_cb_.Run()) |
return false; |
- } |
#endif |
- // Array of Create..VDA() function pointers, maybe applicable to the current |
- // platform. This list is ordered by priority of use and it should be the |
- // same as the order of querying supported profiles of VDAs. |
- const GpuVideoDecodeAccelerator::CreateVDAFp create_vda_fps[] = { |
- &GpuVideoDecodeAccelerator::CreateDXVAVDA, |
- &GpuVideoDecodeAccelerator::CreateV4L2VDA, |
- &GpuVideoDecodeAccelerator::CreateV4L2SliceVDA, |
- &GpuVideoDecodeAccelerator::CreateVaapiVDA, |
- &GpuVideoDecodeAccelerator::CreateVTVDA, |
- &GpuVideoDecodeAccelerator::CreateOzoneVDA, |
- &GpuVideoDecodeAccelerator::CreateAndroidVDA}; |
- |
- for (const auto& create_vda_function : create_vda_fps) { |
- video_decode_accelerator_ = (this->*create_vda_function)(); |
- if (!video_decode_accelerator_ || |
- !video_decode_accelerator_->Initialize(config, this)) |
- continue; |
- |
- if (video_decode_accelerator_->CanDecodeOnIOThread()) { |
- filter_ = new MessageFilter(this, host_route_id_); |
- stub_->channel()->AddFilter(filter_.get()); |
- } |
- return true; |
- } |
- video_decode_accelerator_.reset(); |
- LOG(ERROR) << "HW video decode not available for profile " << config.profile |
- << (config.is_encrypted ? " with encryption" : ""); |
- return false; |
-} |
- |
-scoped_ptr<media::VideoDecodeAccelerator> |
-GpuVideoDecodeAccelerator::CreateDXVAVDA() { |
- scoped_ptr<media::VideoDecodeAccelerator> decoder; |
-#if defined(OS_WIN) |
- if (base::win::GetVersion() >= base::win::VERSION_WIN7) { |
- DVLOG(0) << "Initializing DXVA HW decoder for windows."; |
- decoder.reset(new DXVAVideoDecodeAccelerator(make_context_current_, |
- stub_->decoder()->GetGLContext())); |
- } else { |
- NOTIMPLEMENTED() << "HW video decode acceleration not available."; |
- } |
-#endif |
- return decoder; |
-} |
+ scoped_ptr<GpuVideoDecodeAcceleratorFactory> vda_factory = |
+ GpuVideoDecodeAcceleratorFactory::CreateWithGLES2Decoder( |
+ get_gl_context_cb_, make_context_current_cb_, bind_image_cb_, |
+ get_gles2_decoder_cb_); |
-scoped_ptr<media::VideoDecodeAccelerator> |
-GpuVideoDecodeAccelerator::CreateV4L2VDA() { |
- scoped_ptr<media::VideoDecodeAccelerator> decoder; |
-#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) |
- scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
- if (device.get()) { |
- decoder.reset(new V4L2VideoDecodeAccelerator( |
- gfx::GLSurfaceEGL::GetHardwareDisplay(), |
- stub_->decoder()->GetGLContext()->GetHandle(), |
- weak_factory_for_io_.GetWeakPtr(), |
- make_context_current_, |
- device, |
- io_task_runner_)); |
+ if (!vda_factory) { |
+ LOG(ERROR) << "Failed creating the VDA factory"; |
+ return false; |
} |
-#endif |
- return decoder; |
-} |
-scoped_ptr<media::VideoDecodeAccelerator> |
-GpuVideoDecodeAccelerator::CreateV4L2SliceVDA() { |
- scoped_ptr<media::VideoDecodeAccelerator> decoder; |
-#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) |
- scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
- if (device.get()) { |
- decoder.reset(new V4L2SliceVideoDecodeAccelerator( |
- device, |
- gfx::GLSurfaceEGL::GetHardwareDisplay(), |
- stub_->decoder()->GetGLContext()->GetHandle(), |
- weak_factory_for_io_.GetWeakPtr(), |
- make_context_current_, |
- io_task_runner_)); |
+ video_decode_accelerator_ = vda_factory->CreateVDA(this, config); |
+ if (!video_decode_accelerator_) { |
+ LOG(ERROR) << "HW video decode not available for profile " << config.profile |
+ << (config.is_encrypted ? " with encryption" : ""); |
+ return false; |
} |
-#endif |
- return decoder; |
-} |
-void GpuVideoDecodeAccelerator::BindImage(uint32_t client_texture_id, |
- uint32_t texture_target, |
- scoped_refptr<gl::GLImage> image) { |
- gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder(); |
- gpu::gles2::TextureManager* texture_manager = |
- command_decoder->GetContextGroup()->texture_manager(); |
- gpu::gles2::TextureRef* ref = texture_manager->GetTexture(client_texture_id); |
- if (ref) { |
- texture_manager->SetLevelImage(ref, texture_target, 0, image.get(), |
- gpu::gles2::Texture::BOUND); |
+ // Attempt to set up performing decoding tasks on IO thread, if supported by |
+ // the VDA. |
+ if (video_decode_accelerator_->TryInitializeDecodeOnSeparateThread( |
+ weak_factory_for_io_.GetWeakPtr(), io_task_runner_)) { |
+ filter_ = new MessageFilter(this, host_route_id_); |
+ stub_->channel()->AddFilter(filter_.get()); |
} |
-} |
- |
-scoped_ptr<media::VideoDecodeAccelerator> |
-GpuVideoDecodeAccelerator::CreateVaapiVDA() { |
- scoped_ptr<media::VideoDecodeAccelerator> decoder; |
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
- decoder.reset(new VaapiVideoDecodeAccelerator( |
- make_context_current_, base::Bind(&GpuVideoDecodeAccelerator::BindImage, |
- base::Unretained(this)))); |
-#endif |
- return decoder; |
-} |
-scoped_ptr<media::VideoDecodeAccelerator> |
-GpuVideoDecodeAccelerator::CreateVTVDA() { |
- scoped_ptr<media::VideoDecodeAccelerator> decoder; |
-#if defined(OS_MACOSX) |
- decoder.reset(new VTVideoDecodeAccelerator( |
- make_context_current_, base::Bind(&GpuVideoDecodeAccelerator::BindImage, |
- base::Unretained(this)))); |
-#endif |
- return decoder; |
-} |
- |
-scoped_ptr<media::VideoDecodeAccelerator> |
-GpuVideoDecodeAccelerator::CreateOzoneVDA() { |
- scoped_ptr<media::VideoDecodeAccelerator> decoder; |
-#if !defined(OS_CHROMEOS) && defined(USE_OZONE) |
- media::MediaOzonePlatform* platform = |
- media::MediaOzonePlatform::GetInstance(); |
- decoder.reset(platform->CreateVideoDecodeAccelerator(make_context_current_)); |
-#endif |
- return decoder; |
-} |
- |
-scoped_ptr<media::VideoDecodeAccelerator> |
-GpuVideoDecodeAccelerator::CreateAndroidVDA() { |
- scoped_ptr<media::VideoDecodeAccelerator> decoder; |
-#if defined(OS_ANDROID) |
- decoder.reset(new AndroidVideoDecodeAccelerator(stub_->decoder()->AsWeakPtr(), |
- make_context_current_)); |
-#endif |
- return decoder; |
+ return true; |
} |
void GpuVideoDecodeAccelerator::OnSetCdm(int cdm_id) { |
@@ -486,8 +367,8 @@ void GpuVideoDecodeAccelerator::OnSetCdm(int cdm_id) { |
video_decode_accelerator_->SetCdm(cdm_id); |
} |
-// Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is |
-// true, otherwise on the main thread. |
+// Runs on IO thread if VDA::TryInitializeDecodeOnSeparateThread() succeeded, |
+// otherwise on the main thread. |
void GpuVideoDecodeAccelerator::OnDecode( |
const media::BitstreamBuffer& bitstream_buffer) { |
DCHECK(video_decode_accelerator_); |