diff options
author | brettw <brettw@chromium.org> | 2016-03-25 10:55:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-25 17:56:51 +0000 |
commit | affa906687c76c929545f8073fffaa53ff3a1a4a (patch) | |
tree | 3755b1452b8fc4e4c722dd200a59d0998c0e162d | |
parent | 36bf097458296e86dd3054632826dc78f658856f (diff) | |
download | chromium_src-lkcr.zip chromium_src-lkcr.tar.gz chromium_src-lkcr.tar.bz2 |
Revert of Introduce GpuVideoDecodeAcceleratorFactory. (patchset #22 id:600001 of https://codereview.chromium.org/1745903002/ )lkcr
Reason for revert:
Too many problems: Android, Win64 linking, component linking (duplicate code die to incorrect visibility)
Original issue's description:
> Introduce GpuVideoDecodeAcceleratorFactory.
>
> - Move platform-specific code from GpuVideoDecodeAccelerator to
> GpuVideoDecodeAcceleratorFactory.
>
> - Make GVDAFactory a content/public interface, to provide the ability to
> instantiate VDAs from outside content/.
>
> - Unify how we obtain access to various GL functionality/classes from VDAs
> by introducing a set of callbacks provided by the client.
>
> - Replace VDA::CanDecodeOnIOThread() with
> VDA::TryInitializeDecodeOnSeparateThread(). This allows us to remove
> additional client/taskrunner arguments from VDA constructors, and give client
> the option to use a separate thread to decode, instead of having to make this
> decision in the factory, and enforcing these arguments in the constructors.
>
> - Deduplicate VDA creation code across users (currently GVDA and vdaunittest).
>
> BUG=b/27687678
> TEST=compile/run various VDA impls
> CQ_INCLUDE_TRYBOTS=tryserver.chromium.win:win_optional_gpu_tests_rel
>
> Committed: https://crrev.com/6977e5243786901a766a38c2c291464875dffbd6
> Cr-Commit-Position: refs/heads/master@{#383256}
TBR=jochen@chromium.org,ananta@chromium.org,fsamuel@chromium.org,kcwu@chromium.org,liberato@chromium.org,owenlin@chromium.org,sandersd@chromium.org,jam@chromium.org,boliu@chromium.org,posciak@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=b/27687678
Review URL: https://codereview.chromium.org/1832123002
Cr-Commit-Position: refs/heads/master@{#383300}
40 files changed, 581 insertions, 1103 deletions
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc index 13b54ee..e4d7802 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.cc +++ b/content/common/gpu/media/android_video_decode_accelerator.cc @@ -251,22 +251,35 @@ static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = LAZY_INSTANCE_INITIALIZER; AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( - const MakeGLContextCurrentCallback& make_context_current_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb) + const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, + const base::Callback<bool(void)>& make_context_current) : client_(NULL), - make_context_current_cb_(make_context_current_cb), - get_gles2_decoder_cb_(get_gles2_decoder_cb), + make_context_current_(make_context_current), codec_(media::kCodecH264), is_encrypted_(false), needs_protected_surface_(false), state_(NO_ERROR), picturebuffers_requested_(false), + gl_decoder_(decoder), media_drm_bridge_cdm_context_(nullptr), cdm_registration_id_(0), pending_input_buf_index_(-1), error_sequence_token_(0), defer_errors_(false), - weak_this_factory_(this) {} + weak_this_factory_(this) { + const gpu::GpuPreferences& gpu_preferences = + gl_decoder_->GetContextGroup()->gpu_preferences(); + if (UseDeferredRenderingStrategy(gpu_preferences)) { + // TODO(liberato, watk): Figure out what we want to do about zero copy for + // fullscreen external SurfaceView in WebView. http://crbug.com/582170. + DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync()); + DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; + strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); + } else { + DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; + strategy_.reset(new AndroidCopyingBackingStrategy(this)); + } +} AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { DCHECK(thread_checker_.CalledOnValidThread()); @@ -289,11 +302,6 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); - if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) { - NOTREACHED() << "GL callbacks are required for this VDA"; - return false; - } - DCHECK(client); client_ = client; codec_ = VideoCodecProfileToVideoCodec(config.profile); @@ -316,28 +324,13 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, codec_, media::MEDIA_CODEC_DECODER)); } - auto gles_decoder = get_gles2_decoder_cb_.Run(); - if (!gles_decoder) { - LOG(ERROR) << "Failed to get gles2 decoder instance."; + if (!make_context_current_.Run()) { + LOG(ERROR) << "Failed to make this decoder's GL context current."; return false; } - const gpu::GpuPreferences& gpu_preferences = - gles_decoder->GetContextGroup()->gpu_preferences(); - - if (UseDeferredRenderingStrategy(gpu_preferences)) { - // TODO(liberato, watk): Figure out what we want to do about zero copy for - // fullscreen external SurfaceView in WebView. http://crbug.com/582170. - DCHECK(!gles_decoder->GetContextGroup()->mailbox_manager()->UsesSync()); - DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; - strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); - } else { - DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; - strategy_.reset(new AndroidCopyingBackingStrategy(this)); - } - - if (!make_context_current_cb_.Run()) { - LOG(ERROR) << "Failed to make this decoder's GL context current."; + if (!gl_decoder_) { + LOG(ERROR) << "Failed to get gles2 decoder instance."; return false; } @@ -721,7 +714,7 @@ void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( DCHECK(!free_picture_ids_.empty()); TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); - if (!make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); return; } @@ -999,7 +992,7 @@ void AndroidVideoDecodeAccelerator::Reset() { void AndroidVideoDecodeAccelerator::Destroy() { DCHECK(thread_checker_.CalledOnValidThread()); - bool have_context = make_context_current_cb_.Run(); + bool have_context = make_context_current_.Run(); if (!have_context) LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; @@ -1019,9 +1012,7 @@ void AndroidVideoDecodeAccelerator::Destroy() { delete this; } -bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { +bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { return false; } @@ -1036,19 +1027,18 @@ const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() base::WeakPtr<gpu::gles2::GLES2Decoder> AndroidVideoDecodeAccelerator::GetGlDecoder() const { - return get_gles2_decoder_cb_.Run(); + return gl_decoder_; } gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( const media::PictureBuffer& picture_buffer) { - auto gles_decoder = GetGlDecoder(); - RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder", - ILLEGAL_STATE, nullptr); - RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(), - "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE, + RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE, + nullptr); + RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(), + "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE, nullptr); gpu::gles2::TextureManager* texture_manager = - gles_decoder->GetContextGroup()->texture_manager(); + gl_decoder_->GetContextGroup()->texture_manager(); RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", ILLEGAL_STATE, nullptr); gpu::gles2::TextureRef* texture_ref = diff --git a/content/common/gpu/media/android_video_decode_accelerator.h b/content/common/gpu/media/android_video_decode_accelerator.h index badb64c..9e6645b 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.h +++ b/content/common/gpu/media/android_video_decode_accelerator.h @@ -18,7 +18,6 @@ #include "base/timer/timer.h" #include "content/common/content_export.h" #include "content/common/gpu/media/avda_state_provider.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gpu_preferences.h" #include "media/base/android/media_drm_bridge_cdm_context.h" @@ -111,8 +110,8 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator }; AndroidVideoDecodeAccelerator( - const MakeGLContextCurrentCallback& make_context_current_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb); + const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, + const base::Callback<bool(void)>& make_context_current); ~AndroidVideoDecodeAccelerator() override; @@ -126,10 +125,7 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator void Flush() override; void Reset() override; void Destroy() override; - bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) - override; + bool CanDecodeOnIOThread() override; // AVDAStateProvider implementation: const gfx::Size& GetSize() const override; @@ -245,10 +241,7 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator Client* client_; // Callback to set the correct gl context. - MakeGLContextCurrentCallback make_context_current_cb_; - - // Callback to get the GLES2Decoder instance. - GetGLES2DecoderCallback get_gles2_decoder_cb_; + base::Callback<bool(void)> make_context_current_; // Codec type. Used when we configure media codec. media::VideoCodec codec_; @@ -306,6 +299,9 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. std::list<int32_t> bitstreams_notified_in_advance_; + // Owner of the GL context. Used to restore the context state. + base::WeakPtr<gpu::gles2::GLES2Decoder> gl_decoder_; + // Backing strategy that we'll use to connect PictureBuffers to frames. scoped_ptr<BackingStrategy> strategy_; diff --git a/content/common/gpu/media/android_video_decode_accelerator_unittest.cc b/content/common/gpu/media/android_video_decode_accelerator_unittest.cc index f050044..751933a 100644 --- a/content/common/gpu/media/android_video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/android_video_decode_accelerator_unittest.cc @@ -27,11 +27,6 @@ bool MockMakeContextCurrent() { return true; } -static base::WeakPtr<gpu::gles2::GLES2Decoder> MockGetGLES2Decoder( - const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder) { - return decoder; -} - } // namespace namespace content { @@ -72,8 +67,7 @@ class AndroidVideoDecodeAcceleratorTest : public testing::Test { scoped_ptr<MockVideoDecodeAcceleratorClient> client( new MockVideoDecodeAcceleratorClient()); accelerator_.reset(new AndroidVideoDecodeAccelerator( - base::Bind(&MockMakeContextCurrent), - base::Bind(&MockGetGLES2Decoder, decoder->AsWeakPtr()))); + decoder->AsWeakPtr(), base::Bind(&MockMakeContextCurrent))); } bool Configure(media::VideoCodec codec) { diff --git a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc index e42159b..8557bcc 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator_win.cc +++ b/content/common/gpu/media/dxva_video_decode_accelerator_win.cc @@ -814,8 +814,8 @@ DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)>& make_context_current, + gfx::GLContext* gl_context, bool enable_accelerated_vpx_decode) : client_(NULL), dev_manager_reset_token_(0), @@ -825,14 +825,14 @@ DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( pictures_requested_(false), inputs_before_decode_(0), sent_drain_message_(false), - get_gl_context_cb_(get_gl_context_cb), - make_context_current_cb_(make_context_current_cb), + make_context_current_(make_context_current), codec_(media::kUnknownVideoCodec), decoder_thread_("DXVAVideoDecoderThread"), pending_flush_(false), use_dx11_(false), use_keyed_mutex_(false), dx11_video_format_converter_media_type_needs_init_(true), + gl_context_(gl_context), using_angle_device_(false), enable_accelerated_vpx_decode_(enable_accelerated_vpx_decode), weak_this_factory_(this) { @@ -847,11 +847,6 @@ DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { bool DXVAVideoDecodeAccelerator::Initialize(const Config& config, Client* client) { - if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) { - NOTREACHED() << "GL callbacks are required for this VDA"; - return false; - } - if (config.is_encrypted) { NOTREACHED() << "Encrypted streams are not supported for this VDA"; return false; @@ -1216,7 +1211,7 @@ void DXVAVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) { base::Unretained(this))); } } else { - RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), + RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), "Failed to make context current", PLATFORM_FAILURE, ); it->second->ResetReuseFence(); @@ -1238,7 +1233,7 @@ void DXVAVideoDecodeAccelerator::WaitForOutputBuffer(int32_t picture_buffer_id, DCHECK(picture_buffer->waiting_to_reuse()); gfx::GLFence* fence = picture_buffer->reuse_fence(); - RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), + RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), "Failed to make context current", PLATFORM_FAILURE, ); if (count <= kMaxIterationsForANGLEReuseFlush && !fence->HasCompleted()) { @@ -1332,9 +1327,7 @@ void DXVAVideoDecodeAccelerator::Destroy() { delete this; } -bool DXVAVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { +bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { return false; } @@ -1518,16 +1511,15 @@ bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { DVLOG(1) << "Failed to set Low latency mode on decoder. Error: " << hr; } - auto gl_context = get_gl_context_cb_.Run(); - RETURN_ON_FAILURE(gl_context, "Couldn't get GL context", false); - // The decoder should use DX11 iff // 1. The underlying H/W decoder supports it. // 2. We have a pointer to the MFCreateDXGIDeviceManager function needed for // this. This should always be true for Windows 8+. // 3. ANGLE is using DX11. + DCHECK(gl_context_); if (create_dxgi_device_manager_ && - (gl_context->GetGLRenderer().find("Direct3D11") != std::string::npos)) { + (gl_context_->GetGLRenderer().find("Direct3D11") != + std::string::npos)) { UINT32 dx11_aware = 0; attributes->GetUINT32(MF_SA_D3D11_AWARE, &dx11_aware); use_dx11_ = !!dx11_aware; @@ -1729,9 +1721,8 @@ void DXVAVideoDecodeAccelerator::ProcessPendingSamples() { if (!output_picture_buffers_.size()) return; - RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), - "Failed to make context current", - PLATFORM_FAILURE, ); + RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), + "Failed to make context current", PLATFORM_FAILURE,); OutputBuffers::iterator index; @@ -2252,9 +2243,8 @@ void DXVAVideoDecodeAccelerator::CopySurfaceComplete( if (picture_buffer->available()) return; - RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), - "Failed to make context current", - PLATFORM_FAILURE, ); + RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), + "Failed to make context current", PLATFORM_FAILURE,); DCHECK(!output_picture_buffers_.empty()); diff --git a/content/common/gpu/media/dxva_video_decode_accelerator_win.h b/content/common/gpu/media/dxva_video_decode_accelerator_win.h index f4f474a..56087b3 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator_win.h +++ b/content/common/gpu/media/dxva_video_decode_accelerator_win.h @@ -29,7 +29,6 @@ #include "base/threading/thread.h" #include "base/win/scoped_comptr.h" #include "content/common/content_export.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "media/video/video_decode_accelerator.h" interface IMFSample; @@ -98,8 +97,8 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator // Does not take ownership of |client| which must outlive |*this|. DXVAVideoDecodeAccelerator( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)>& make_context_current, + gfx::GLContext* gl_context, bool enable_accelerated_vpx_decode); ~DXVAVideoDecodeAccelerator() override; @@ -112,10 +111,7 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator void Flush() override; void Reset() override; void Destroy() override; - bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) - override; + bool CanDecodeOnIOThread() override; GLenum GetSurfaceInternalFormat() const override; static media::VideoDecodeAccelerator::SupportedProfiles @@ -395,10 +391,8 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator typedef std::list<base::win::ScopedComPtr<IMFSample>> PendingInputs; PendingInputs pending_input_buffers_; - // Callback to get current GLContext. - GetGLContextCallback get_gl_context_cb_; // Callback to set the correct gl context. - MakeGLContextCurrentCallback make_context_current_cb_; + base::Callback<bool(void)> make_context_current_; // Which codec we are decoding with hardware acceleration. media::VideoCodec codec_; @@ -438,6 +432,9 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator // be initialized. Defaults to true. bool dx11_video_format_converter_media_type_needs_init_; + // The GLContext to be used by the decoder. + scoped_refptr<gfx::GLContext> gl_context_; + // Set to true if we are sharing ANGLE's device. bool using_angle_device_; diff --git a/content/common/gpu/media/fake_video_decode_accelerator.cc b/content/common/gpu/media/fake_video_decode_accelerator.cc index 48e7925..230c4f3 100644 --- a/content/common/gpu/media/fake_video_decode_accelerator.cc +++ b/content/common/gpu/media/fake_video_decode_accelerator.cc @@ -29,14 +29,17 @@ static const unsigned int kNumBuffers = media::limits::kMaxVideoFrames + (media::limits::kMaxVideoFrames & 1u); FakeVideoDecodeAccelerator::FakeVideoDecodeAccelerator( - const gfx::Size& size, - const MakeGLContextCurrentCallback& make_context_current_cb) + gfx::GLContext* gl, + gfx::Size size, + const base::Callback<bool(void)>& make_context_current) : child_task_runner_(base::ThreadTaskRunnerHandle::Get()), client_(NULL), - make_context_current_cb_(make_context_current_cb), + make_context_current_(make_context_current), + gl_(gl), frame_buffer_size_(size), flushing_(false), - weak_this_factory_(this) {} + weak_this_factory_(this) { +} FakeVideoDecodeAccelerator::~FakeVideoDecodeAccelerator() { } @@ -100,7 +103,7 @@ void FakeVideoDecodeAccelerator::AssignPictureBuffers( memset(black_data.get(), 0, frame_buffer_size_.width() * frame_buffer_size_.height() * 4); - if (!make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { LOG(ERROR) << "ReusePictureBuffer(): could not make context current"; return; } @@ -159,10 +162,8 @@ void FakeVideoDecodeAccelerator::Destroy() { delete this; } -bool FakeVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { - return false; +bool FakeVideoDecodeAccelerator::CanDecodeOnIOThread() { + return true; } void FakeVideoDecodeAccelerator::DoPictureReady() { diff --git a/content/common/gpu/media/fake_video_decode_accelerator.h b/content/common/gpu/media/fake_video_decode_accelerator.h index 10d4782..7dcbfda 100644 --- a/content/common/gpu/media/fake_video_decode_accelerator.h +++ b/content/common/gpu/media/fake_video_decode_accelerator.h @@ -13,7 +13,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/common/content_export.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "media/video/video_decode_accelerator.h" #include "ui/gfx/geometry/size_f.h" #include "ui/gl/gl_context.h" @@ -24,8 +23,9 @@ class CONTENT_EXPORT FakeVideoDecodeAccelerator : public media::VideoDecodeAccelerator { public: FakeVideoDecodeAccelerator( - const gfx::Size& size, - const MakeGLContextCurrentCallback& make_context_current_cb); + gfx::GLContext* gl, + gfx::Size size, + const base::Callback<bool(void)>& make_context_current); ~FakeVideoDecodeAccelerator() override; bool Initialize(const Config& config, Client* client) override; @@ -36,10 +36,7 @@ class CONTENT_EXPORT FakeVideoDecodeAccelerator void Flush() override; void Reset() override; void Destroy() override; - bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) - override; + bool CanDecodeOnIOThread() override; private: void DoPictureReady(); @@ -52,7 +49,8 @@ class CONTENT_EXPORT FakeVideoDecodeAccelerator Client* client_; // Make our context current before running any GL entry points. - MakeGLContextCurrentCallback make_context_current_cb_; + base::Callback<bool(void)> make_context_current_; + gfx::GLContext* gl_; // Output picture size. gfx::Size frame_buffer_size_; diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index 3f96e0d..daa096a 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc @@ -18,32 +18,42 @@ #include "content/common/gpu/gpu_channel.h" #include "content/common/gpu/gpu_channel_manager.h" #include "content/common/gpu/media/gpu_video_accelerator_util.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h" #include "content/common/gpu/media/media_messages.h" #include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/command_buffer/service/gpu_preferences.h" #include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_utils.h" #include "ipc/message_filter.h" #include "media/base/limits.h" -#include "ui/gfx/geometry/size.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(OS_ANDROID) +#include "content/common/gpu/media/android_video_decode_accelerator.h" +#endif -namespace content { - -namespace { -static gfx::GLContext* GetGLContext( - const base::WeakPtr<GpuCommandBufferStub>& stub) { - if (!stub) { - DLOG(ERROR) << "Stub is gone; no GLContext."; - return nullptr; - } +#include "ui/gfx/geometry/size.h" - return stub->decoder()->GetGLContext(); -} +namespace content { 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; @@ -57,43 +67,6 @@ static bool MakeDecoderContextCurrent( return true; } -#if (defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)) || defined(OS_MACOSX) -static bool BindImage(const base::WeakPtr<GpuCommandBufferStub>& stub, - uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image, - bool can_bind_to_sampler) { - 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(), - can_bind_to_sampler - ? gpu::gles2::Texture::BOUND - : gpu::gles2::Texture::UNBOUND); - } - - return true; -} -#endif - -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() @@ -165,13 +138,8 @@ GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( weak_factory_for_io_(this) { DCHECK(stub_); stub_->AddDestructionObserver(this); - get_gl_context_cb_ = base::Bind(&GetGLContext, stub_->AsWeakPtr()); - make_context_current_cb_ = + make_context_current_ = base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); -#if (defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)) || defined(OS_MACOSX) - bind_image_cb_ = base::Bind(&BindImage, stub_->AsWeakPtr()); -#endif - get_gles2_decoder_cb_ = base::Bind(&GetGLES2Decoder, stub_->AsWeakPtr()); } GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { @@ -184,8 +152,40 @@ GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { gpu::VideoDecodeAcceleratorCapabilities GpuVideoDecodeAccelerator::GetCapabilities( const gpu::GpuPreferences& gpu_preferences) { - return GpuVideoDecodeAcceleratorFactoryImpl::GetDecoderCapabilities( - gpu_preferences); + media::VideoDecodeAccelerator::Capabilities capabilities; + if (gpu_preferences.disable_accelerated_video_decode) + 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(gpu_preferences); +#endif + return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities( + capabilities); } bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { @@ -328,6 +328,11 @@ bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { bool GpuVideoDecodeAccelerator::Initialize( const media::VideoDecodeAccelerator::Config& config) { + const gpu::GpuPreferences& gpu_preferences = + stub_->channel()->gpu_channel_manager()->gpu_preferences(); + if (gpu_preferences.disable_accelerated_video_decode) + return false; + DCHECK(!video_decode_accelerator_); if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) { @@ -338,48 +343,159 @@ 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_cb_.Run()) + if (!make_context_current_.Run()) { return false; + } #endif - scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> vda_factory = - GpuVideoDecodeAcceleratorFactoryImpl::CreateWithGLES2Decoder( - get_gl_context_cb_, make_context_current_cb_, bind_image_cb_, - get_gles2_decoder_cb_); + // 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[] = { +#if defined(OS_WIN) + &GpuVideoDecodeAccelerator::CreateDXVAVDA, +#endif +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) + &GpuVideoDecodeAccelerator::CreateV4L2VDA, + &GpuVideoDecodeAccelerator::CreateV4L2SliceVDA, +#endif +#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) + &GpuVideoDecodeAccelerator::CreateVaapiVDA, +#endif +#if defined(OS_MACOSX) + &GpuVideoDecodeAccelerator::CreateVTVDA, +#endif +#if defined(OS_ANDROID) + &GpuVideoDecodeAccelerator::CreateAndroidVDA, +#endif + }; - if (!vda_factory) { - LOG(ERROR) << "Failed creating the VDA factory"; - return false; + 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; +} +#if defined(OS_WIN) +scoped_ptr<media::VideoDecodeAccelerator> +GpuVideoDecodeAccelerator::CreateDXVAVDA() { + scoped_ptr<media::VideoDecodeAccelerator> decoder; const gpu::GpuPreferences& gpu_preferences = stub_->channel()->gpu_channel_manager()->gpu_preferences(); - video_decode_accelerator_ = - vda_factory->CreateVDA(this, config, gpu_preferences); - if (!video_decode_accelerator_) { - LOG(ERROR) << "HW video decode not available for profile " << config.profile - << (config.is_encrypted ? " with encryption" : ""); - return false; + 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(), + gpu_preferences.enable_accelerated_vpx_decode)); + } else { + NOTIMPLEMENTED() << "HW video decode acceleration not available."; } + return decoder; +} +#endif - // Attempt to set up performing decoding tasks on IO thread, if supported by - // the VDA. - if (video_decode_accelerator_->TryToSetupDecodeOnSeparateThread( - weak_factory_for_io_.GetWeakPtr(), io_task_runner_)) { - filter_ = new MessageFilter(this, host_route_id_); - stub_->channel()->AddFilter(filter_.get()); +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) +scoped_ptr<media::VideoDecodeAccelerator> +GpuVideoDecodeAccelerator::CreateV4L2VDA() { + scoped_ptr<media::VideoDecodeAccelerator> decoder; + 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_)); } + return decoder; +} - return true; +scoped_ptr<media::VideoDecodeAccelerator> +GpuVideoDecodeAccelerator::CreateV4L2SliceVDA() { + scoped_ptr<media::VideoDecodeAccelerator> decoder; + 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_)); + } + return decoder; } +#endif + +#if (defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)) || defined(OS_MACOSX) +void GpuVideoDecodeAccelerator::BindImage(uint32_t client_texture_id, + uint32_t texture_target, + scoped_refptr<gl::GLImage> image, + bool can_bind_to_sampler) { + 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(), + can_bind_to_sampler + ? gpu::gles2::Texture::BOUND + : gpu::gles2::Texture::UNBOUND); + } +} +#endif + +#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) +scoped_ptr<media::VideoDecodeAccelerator> +GpuVideoDecodeAccelerator::CreateVaapiVDA() { + return make_scoped_ptr<media::VideoDecodeAccelerator>( + new VaapiVideoDecodeAccelerator( + make_context_current_, + base::Bind(&GpuVideoDecodeAccelerator::BindImage, + base::Unretained(this)))); +} +#endif + +#if defined(OS_MACOSX) +scoped_ptr<media::VideoDecodeAccelerator> +GpuVideoDecodeAccelerator::CreateVTVDA() { + return make_scoped_ptr<media::VideoDecodeAccelerator>( + new VTVideoDecodeAccelerator( + make_context_current_, + base::Bind(&GpuVideoDecodeAccelerator::BindImage, + base::Unretained(this)))); +} +#endif + +#if defined(OS_ANDROID) +scoped_ptr<media::VideoDecodeAccelerator> +GpuVideoDecodeAccelerator::CreateAndroidVDA() { + return make_scoped_ptr<media::VideoDecodeAccelerator>( + new AndroidVideoDecodeAccelerator(stub_->decoder()->AsWeakPtr(), + make_context_current_)); +} +#endif void GpuVideoDecodeAccelerator::OnSetCdm(int cdm_id) { DCHECK(video_decode_accelerator_); video_decode_accelerator_->SetCdm(cdm_id); } -// Runs on IO thread if VDA::TryToSetupDecodeOnSeparateThread() succeeded, -// otherwise on the main thread. +// Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is +// true, otherwise on the main thread. void GpuVideoDecodeAccelerator::OnDecode( const media::BitstreamBuffer& bitstream_buffer) { DCHECK(video_decode_accelerator_); diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h index 8b4b74e..ddfe884 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.h +++ b/content/common/gpu/media/gpu_video_decode_accelerator.h @@ -16,7 +16,6 @@ #include "base/memory/shared_memory.h" #include "base/synchronization/waitable_event.h" #include "content/common/gpu/gpu_command_buffer_stub.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/config/gpu_info.h" #include "ipc/ipc_listener.h" @@ -78,8 +77,31 @@ class GpuVideoDecodeAccelerator bool Initialize(const media::VideoDecodeAccelerator::Config& config); private: + typedef scoped_ptr<media::VideoDecodeAccelerator> ( + GpuVideoDecodeAccelerator::*CreateVDAFp)(); + class MessageFilter; +#if defined(OS_WIN) + scoped_ptr<media::VideoDecodeAccelerator> CreateDXVAVDA(); +#endif +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) + scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2VDA(); + scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2SliceVDA(); +#endif +#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) + scoped_ptr<media::VideoDecodeAccelerator> CreateVaapiVDA(); +#endif +#if defined(OS_MACOSX) + scoped_ptr<media::VideoDecodeAccelerator> CreateVTVDA(); +#endif +#if !defined(OS_CHROMEOS) && defined(USE_OZONE) + scoped_ptr<media::VideoDecodeAccelerator> CreateOzoneVDA(); +#endif +#if defined(OS_ANDROID) + scoped_ptr<media::VideoDecodeAccelerator> CreateAndroidVDA(); +#endif + // We only allow self-delete, from OnWillDestroyStub(), after cleanup there. ~GpuVideoDecodeAccelerator() override; @@ -99,6 +121,16 @@ class GpuVideoDecodeAccelerator // Sets the texture to cleared. void SetTextureCleared(const media::Picture& picture); +#if (defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)) || defined(OS_MACOSX) + // Helper to bind |image| to the texture specified by |client_texture_id|. If + // |can_bind_to_sampler| is true, then the image may be used as a sampler + // directly, otherwise a copy to a staging buffer is required. + void BindImage(uint32_t client_texture_id, + uint32_t texture_target, + scoped_refptr<gl::GLImage> image, + bool can_bind_to_sampler); +#endif + // Route ID to communicate with the host. const int32_t host_route_id_; @@ -110,17 +142,9 @@ class GpuVideoDecodeAccelerator // The underlying VideoDecodeAccelerator. scoped_ptr<media::VideoDecodeAccelerator> video_decode_accelerator_; - // Callback to return current GLContext, if available. - GetGLContextCallback get_gl_context_cb_; - // Callback for making the relevant context current for GL calls. - MakeGLContextCurrentCallback make_context_current_cb_; - - // Callback to bind a GLImage to a given texture id and target. - BindGLImageCallback bind_image_cb_; - - // Callback to return a WeakPtr to GLES2Decoder. - GetGLES2DecoderCallback get_gles2_decoder_cb_; + // Returns false if failed. + base::Callback<bool(void)> make_context_current_; // The texture dimensions as requested by ProvidePictureBuffers(). gfx::Size texture_dimensions_; diff --git a/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc b/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc deleted file mode 100644 index 04ab770..0000000 --- a/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/gpu/media/gpu_video_accelerator_util.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h" -#include "gpu/command_buffer/service/gpu_preferences.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" -#include "ui/gl/gl_surface_egl.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(OS_ANDROID) -#include "content/common/gpu/media/android_video_decode_accelerator.h" -#endif - -namespace content { - -namespace { -static base::WeakPtr<gpu::gles2::GLES2Decoder> GetEmptyGLES2Decoder() { - NOTREACHED() << "VDA requests a GLES2Decoder, but client did not provide it"; - return base::WeakPtr<gpu::gles2::GLES2Decoder>(); -} -} - -// static -scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> -GpuVideoDecodeAcceleratorFactoryImpl::Create( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb) { - return make_scoped_ptr(new GpuVideoDecodeAcceleratorFactoryImpl( - get_gl_context_cb, make_context_current_cb, bind_image_cb, - base::Bind(&GetEmptyGLES2Decoder))); -} - -// static -scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> -GpuVideoDecodeAcceleratorFactoryImpl::CreateWithGLES2Decoder( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb) { - return make_scoped_ptr(new GpuVideoDecodeAcceleratorFactoryImpl( - get_gl_context_cb, make_context_current_cb, bind_image_cb, - get_gles2_decoder_cb)); -} - -// static -gpu::VideoDecodeAcceleratorCapabilities -GpuVideoDecodeAcceleratorFactoryImpl::GetDecoderCapabilities( - const gpu::GpuPreferences& gpu_preferences) { - media::VideoDecodeAccelerator::Capabilities capabilities; - if (gpu_preferences.disable_accelerated_video_decode) - return gpu::VideoDecodeAcceleratorCapabilities(); - - // Query VDAs for their capabilities and construct a set of supported - // profiles for current platform. This must be done in the same order as in - // CreateVDA(), as we currently preserve additional capabilities (such as - // resolutions supported) only for the first VDA supporting the given codec - // profile (instead of calculating a superset). - // TODO(posciak,henryhsu): improve this so that we choose a superset of - // resolutions and other supported profile parameters. -#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( - gpu_preferences); -#endif - return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities( - capabilities); -} - -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactoryImpl::CreateVDA( - media::VideoDecodeAccelerator::Client* client, - const media::VideoDecodeAccelerator::Config& config, - const gpu::GpuPreferences& gpu_preferences) { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (gpu_preferences.disable_accelerated_video_decode) - return nullptr; - - // Array of Create..VDA() function pointers, potentially usable on current - // platform. This list is ordered by priority, from most to least preferred, - // if applicable. This list must be in the same order as the querying order - // in GetDecoderCapabilities() above. - using CreateVDAFp = scoped_ptr<media::VideoDecodeAccelerator> ( - GpuVideoDecodeAcceleratorFactoryImpl::*)(const gpu::GpuPreferences&) - const; - const CreateVDAFp create_vda_fps[] = { -#if defined(OS_WIN) - &GpuVideoDecodeAcceleratorFactoryImpl::CreateDXVAVDA, -#endif -#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) - &GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2VDA, - &GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2SVDA, -#endif -#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) - &GpuVideoDecodeAcceleratorFactoryImpl::CreateVaapiVDA, -#endif -#if defined(OS_MACOSX) - &GpuVideoDecodeAcceleratorFactoryImpl::CreateVTVDA, -#endif -#if defined(OS_ANDROID) - &GpuVideoDecodeAcceleratorFactoryImpl::CreateAndroidVDA, -#endif - }; - - scoped_ptr<media::VideoDecodeAccelerator> vda; - - for (const auto& create_vda_function : create_vda_fps) { - vda = (this->*create_vda_function)(gpu_preferences); - if (vda && vda->Initialize(config, client)) - return vda; - } - - return nullptr; -} - -#if defined(OS_WIN) -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactoryImpl::CreateDXVAVDA( - const gpu::GpuPreferences& gpu_preferences) const { - scoped_ptr<media::VideoDecodeAccelerator> decoder; - if (base::win::GetVersion() >= base::win::VERSION_WIN7) { - DVLOG(0) << "Initializing DXVA HW decoder for windows."; - decoder.reset(new DXVAVideoDecodeAccelerator( - get_gl_context_cb_, make_context_current_cb_, - gpu_preferences.enable_accelerated_vpx_decode)); - } - return decoder; -} -#endif - -#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2VDA( - const gpu::GpuPreferences& gpu_preferences) const { - scoped_ptr<media::VideoDecodeAccelerator> decoder; - scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); - if (device.get()) { - decoder.reset(new V4L2VideoDecodeAccelerator( - gfx::GLSurfaceEGL::GetHardwareDisplay(), get_gl_context_cb_, - make_context_current_cb_, device)); - } - return decoder; -} - -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactoryImpl::CreateV4L2SVDA( - const gpu::GpuPreferences& gpu_preferences) const { - scoped_ptr<media::VideoDecodeAccelerator> decoder; - scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); - if (device.get()) { - decoder.reset(new V4L2SliceVideoDecodeAccelerator( - device, gfx::GLSurfaceEGL::GetHardwareDisplay(), get_gl_context_cb_, - make_context_current_cb_)); - } - return decoder; -} -#endif - -#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactoryImpl::CreateVaapiVDA( - const gpu::GpuPreferences& gpu_preferences) const { - scoped_ptr<media::VideoDecodeAccelerator> decoder; - decoder.reset(new VaapiVideoDecodeAccelerator(make_context_current_cb_, - bind_image_cb_)); - return decoder; -} -#endif - -#if defined(OS_MACOSX) -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactoryImpl::CreateVTVDA( - const gpu::GpuPreferences& gpu_preferences) const { - scoped_ptr<media::VideoDecodeAccelerator> decoder; - decoder.reset( - new VTVideoDecodeAccelerator(make_context_current_cb_, bind_image_cb_)); - return decoder; -} -#endif - -#if defined(OS_ANDROID) -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactoryImpl::CreateAndroidVDA( - const gpu::GpuPreferences& gpu_preferences) const { - scoped_ptr<media::VideoDecodeAccelerator> decoder; - decoder.reset(new AndroidVideoDecodeAccelerator(make_context_current_cb_, - get_gles2_decoder_cb_)); - return decoder; -} -#endif - -GpuVideoDecodeAcceleratorFactoryImpl::GpuVideoDecodeAcceleratorFactoryImpl( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb) - : get_gl_context_cb_(get_gl_context_cb), - make_context_current_cb_(make_context_current_cb), - bind_image_cb_(bind_image_cb), - get_gles2_decoder_cb_(get_gles2_decoder_cb) {} - -GpuVideoDecodeAcceleratorFactoryImpl::~GpuVideoDecodeAcceleratorFactoryImpl() {} - -} // namespace content diff --git a/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h b/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h deleted file mode 100644 index de3db4c..0000000 --- a/content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_IMPL_H_ -#define CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_IMPL_H_ - -#include "base/callback.h" -#include "base/threading/thread_checker.h" -#include "gpu/command_buffer/service/gpu_preferences.h" -#include "gpu/config/gpu_info.h" -#include "media/video/video_decode_accelerator.h" - -namespace gfx { -class GLContext; -} - -namespace gl { -class GLImage; -} - -namespace gpu { -struct GpuPreferences; - -namespace gles2 { -class GLES2Decoder; -} -} - -namespace content { - -// TODO(posciak): this class should be an implementation of -// content::GpuVideoDecodeAcceleratorFactory, however that can only be achieved -// once this is moved out of content/common, see crbug.com/597150 and related. -class GpuVideoDecodeAcceleratorFactoryImpl { - public: - ~GpuVideoDecodeAcceleratorFactoryImpl(); - - // Return current GLContext. - using GetGLContextCallback = base::Callback<gfx::GLContext*(void)>; - - // Make the applicable GL context current. To be called by VDAs before - // executing any GL calls. Return true on success, false otherwise. - using MakeGLContextCurrentCallback = base::Callback<bool(void)>; - - // Bind |image| to |client_texture_id| given |texture_target|. If - // |can_bind_to_sampler| is true, then the image may be used as a sampler - // directly, otherwise a copy to a staging buffer is required. - // Return true on success, false otherwise. - using BindGLImageCallback = - base::Callback<bool(uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image, - bool can_bind_to_sampler)>; - - // Return a WeakPtr to a GLES2Decoder, if one is available. - using GetGLES2DecoderCallback = - base::Callback<base::WeakPtr<gpu::gles2::GLES2Decoder>(void)>; - - static scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> Create( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb); - - static scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> - CreateWithGLES2Decoder( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb); - - static gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilities( - const gpu::GpuPreferences& gpu_preferences); - - scoped_ptr<media::VideoDecodeAccelerator> CreateVDA( - media::VideoDecodeAccelerator::Client* client, - const media::VideoDecodeAccelerator::Config& config, - const gpu::GpuPreferences& gpu_preferences); - - private: - GpuVideoDecodeAcceleratorFactoryImpl( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb); - -#if defined(OS_WIN) - scoped_ptr<media::VideoDecodeAccelerator> CreateDXVAVDA( - const gpu::GpuPreferences& gpu_preferences) const; -#endif -#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) - scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2VDA( - const gpu::GpuPreferences& gpu_preferences) const; - scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2SVDA( - const gpu::GpuPreferences& gpu_preferences) const; -#endif -#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) - scoped_ptr<media::VideoDecodeAccelerator> CreateVaapiVDA( - const gpu::GpuPreferences& gpu_preferences) const; -#endif -#if defined(OS_MACOSX) - scoped_ptr<media::VideoDecodeAccelerator> CreateVTVDA( - const gpu::GpuPreferences& gpu_preferences) const; -#endif -#if !defined(OS_CHROMEOS) && defined(USE_OZONE) - scoped_ptr<media::VideoDecodeAccelerator> CreateOzoneVDA( - const gpu::GpuPreferences& gpu_preferences) const; -#endif -#if defined(OS_ANDROID) - scoped_ptr<media::VideoDecodeAccelerator> CreateAndroidVDA( - const gpu::GpuPreferences& gpu_preferences) const; -#endif - - const GetGLContextCallback get_gl_context_cb_; - const MakeGLContextCurrentCallback make_context_current_cb_; - const BindGLImageCallback bind_image_cb_; - const GetGLES2DecoderCallback get_gles2_decoder_cb_; - - base::ThreadChecker thread_checker_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(GpuVideoDecodeAcceleratorFactoryImpl); -}; - -} // namespace content - -#endif // CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_IMPL_H_ diff --git a/content/common/gpu/media/gpu_video_decode_accelerator_helpers.h b/content/common/gpu/media/gpu_video_decode_accelerator_helpers.h deleted file mode 100644 index 1717f59..0000000 --- a/content/common/gpu/media/gpu_video_decode_accelerator_helpers.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_HELPERS_H_ -#define CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_HELPERS_H_ - -#include "base/callback.h" -#include "base/memory/weak_ptr.h" - -namespace gfx { -class GLContext; -} - -namespace gl { -class GLImage; -} - -namespace gpu { -namespace gles2 { -class GLES2Decoder; -} -} - -namespace content { - -// Helpers/defines for specific VideoDecodeAccelerator implementations in GPU -// process. Which callbacks are required depends on the implementation. -// -// Note that these callbacks may be called more than once, and so must own/share -// ownership of any objects bound to them. -// -// Unless specified otherwise, these callbacks must be executed on the GPU Child -// thread (i.e. the thread which the VDAs are initialized on). - -// Return current GLContext. -using GetGLContextCallback = base::Callback<gfx::GLContext*(void)>; - -// Make the applicable GL context current. To be called by VDAs before -// executing any GL calls. Return true on success, false otherwise. -using MakeGLContextCurrentCallback = base::Callback<bool(void)>; - -// Bind |image| to |client_texture_id| given |texture_target|. If -// |can_bind_to_sampler| is true, then the image may be used as a sampler -// directly, otherwise a copy to a staging buffer is required. -// Return true on success, false otherwise. -using BindGLImageCallback = - base::Callback<bool(uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image, - bool can_bind_to_sampler)>; - -// Return a WeakPtr to a GLES2Decoder, if one is available. -using GetGLES2DecoderCallback = - base::Callback<base::WeakPtr<gpu::gles2::GLES2Decoder>(void)>; - -} // namespace content - -#endif // CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_DECODE_ACCELERATOR_HELPERS_H_ diff --git a/content/common/gpu/media/rendering_helper.cc b/content/common/gpu/media/rendering_helper.cc index b3bde44..85bfe0a 100644 --- a/content/common/gpu/media/rendering_helper.cc +++ b/content/common/gpu/media/rendering_helper.cc @@ -665,8 +665,12 @@ void RenderingHelper::DeleteTexture(uint32_t texture_id) { CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); } -gfx::GLContext* RenderingHelper::GetGLContext() { - return gl_context_.get(); +scoped_refptr<gfx::GLContext> RenderingHelper::GetGLContext() { + return gl_context_; +} + +void* RenderingHelper::GetGLContextHandle() { + return gl_context_->GetHandle(); } void* RenderingHelper::GetGLDisplay() { diff --git a/content/common/gpu/media/rendering_helper.h b/content/common/gpu/media/rendering_helper.h index ad178f5..8a6c28b 100644 --- a/content/common/gpu/media/rendering_helper.h +++ b/content/common/gpu/media/rendering_helper.h @@ -135,7 +135,10 @@ class RenderingHelper { void* GetGLDisplay(); // Get the GL context. - gfx::GLContext* GetGLContext(); + scoped_refptr<gfx::GLContext> GetGLContext(); + + // Get the platform specific handle to the OpenGL context. + void* GetGLContextHandle(); // Get rendered thumbnails as RGB. // Sets alpha_solid to true if the alpha channel is entirely 0xff. diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc index 1e0943d..a338cc2 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc @@ -23,7 +23,6 @@ #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" #include "media/base/bind_to_current_loop.h" #include "media/base/media_switches.h" -#include "ui/gl/gl_context.h" #include "ui/gl/scoped_binders.h" #define LOGF(level) LOG(level) << __FUNCTION__ << "(): " @@ -380,11 +379,15 @@ V4L2VP8Picture::~V4L2VP8Picture() { V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator( const scoped_refptr<V4L2Device>& device, EGLDisplay egl_display, - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb) + EGLContext egl_context, + const base::WeakPtr<Client>& io_client, + const base::Callback<bool(void)>& make_context_current, + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) : input_planes_count_(0), output_planes_count_(0), child_task_runner_(base::ThreadTaskRunnerHandle::Get()), + io_task_runner_(io_task_runner), + io_client_(io_client), device_(device), decoder_thread_("V4L2SliceVideoDecodeAcceleratorThread"), device_poll_thread_("V4L2SliceVideoDecodeAcceleratorDevicePollThread"), @@ -399,9 +402,9 @@ V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator( decoder_resetting_(false), surface_set_change_pending_(false), picture_clearing_count_(0), + make_context_current_(make_context_current), egl_display_(egl_display), - get_gl_context_cb_(get_gl_context_cb), - make_context_current_cb_(make_context_current_cb), + egl_context_(egl_context), weak_this_factory_(this) { weak_this_ = weak_this_factory_.GetWeakPtr(); } @@ -437,11 +440,6 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config, DCHECK(child_task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kUninitialized); - if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) { - NOTREACHED() << "GL callbacks are required for this VDA"; - return false; - } - if (config.is_encrypted) { NOTREACHED() << "Encrypted streams are not supported for this VDA"; return false; @@ -457,14 +455,6 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config, client_ptr_factory_.reset( new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client)); client_ = client_ptr_factory_->GetWeakPtr(); - // If we haven't been set up to decode on separate thread via - // TryToSetupDecodeOnSeparateThread(), use the main thread/client for - // decode tasks. - if (!decode_task_runner_) { - decode_task_runner_ = child_task_runner_; - DCHECK(!decode_client_); - decode_client_ = client_; - } video_profile_ = config.profile; @@ -491,7 +481,7 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config, } // We need the context to be initialized to query extensions. - if (!make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { LOG(ERROR) << "Initialize(): could not make context current"; return false; } @@ -1195,7 +1185,7 @@ void V4L2SliceVideoDecodeAccelerator::Decode( const media::BitstreamBuffer& bitstream_buffer) { DVLOGF(3) << "input_id=" << bitstream_buffer.id() << ", size=" << bitstream_buffer.size(); - DCHECK(decode_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->BelongsToCurrentThread()); if (bitstream_buffer.id() < 0) { LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); @@ -1217,7 +1207,7 @@ void V4L2SliceVideoDecodeAccelerator::DecodeTask( DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( - decode_client_, decode_task_runner_, + io_client_, io_task_runner_, new SharedMemoryRegion(bitstream_buffer, true), bitstream_buffer.id())); if (!bitstream_record->shm->Map()) { LOGF(ERROR) << "Could not map bitstream_buffer"; @@ -1498,9 +1488,8 @@ void V4L2SliceVideoDecodeAccelerator::CreateEGLImages( DVLOGF(3); DCHECK(child_task_runner_->BelongsToCurrentThread()); - gfx::GLContext* gl_context = get_gl_context_cb_.Run(); - if (!gl_context || !make_context_current_cb_.Run()) { - DLOG(ERROR) << "No GL context"; + if (!make_context_current_.Run()) { + DLOG(ERROR) << "could not make context current"; NOTIFY_ERROR(PLATFORM_FAILURE); return; } @@ -1510,7 +1499,7 @@ void V4L2SliceVideoDecodeAccelerator::CreateEGLImages( std::vector<EGLImageKHR> egl_images; for (size_t i = 0; i < buffers.size(); ++i) { EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, - gl_context->GetHandle(), + egl_context_, buffers[i].texture_id(), buffers[i].size(), i, @@ -1576,7 +1565,7 @@ void V4L2SliceVideoDecodeAccelerator::ReusePictureBuffer( DCHECK(child_task_runner_->BelongsToCurrentThread()); DVLOGF(4) << "picture_buffer_id=" << picture_buffer_id; - if (!make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { LOGF(ERROR) << "could not make context current"; NOTIFY_ERROR(PLATFORM_FAILURE); return; @@ -1652,7 +1641,7 @@ void V4L2SliceVideoDecodeAccelerator::FlushTask() { // which - when reached - will trigger flush sequence. decoder_input_queue_.push( linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( - decode_client_, decode_task_runner_, nullptr, kFlushBufferId))); + io_client_, io_task_runner_, nullptr, kFlushBufferId))); return; } @@ -2563,14 +2552,12 @@ void V4L2SliceVideoDecodeAccelerator::SendPictureReady() { bool cleared = pending_picture_ready_.front().cleared; const media::Picture& picture = pending_picture_ready_.front().picture; if (cleared && picture_clearing_count_ == 0) { - DVLOGF(4) << "Posting picture ready to decode task runner for: " + DVLOGF(4) << "Posting picture ready to IO for: " << picture.picture_buffer_id(); - // This picture is cleared. It can be posted to a thread different than - // the main GPU thread to reduce latency. This should be the case after - // all pictures are cleared at the beginning. - decode_task_runner_->PostTask( - FROM_HERE, - base::Bind(&Client::PictureReady, decode_client_, picture)); + // This picture is cleared. Post it to IO thread to reduce latency. This + // should be the case after all pictures are cleared at the beginning. + io_task_runner_->PostTask( + FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); pending_picture_ready_.pop(); } else if (!cleared || resetting_or_flushing) { DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared @@ -2608,11 +2595,7 @@ void V4L2SliceVideoDecodeAccelerator::PictureCleared() { SendPictureReady(); } -bool V4L2SliceVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { - decode_client_ = decode_client_; - decode_task_runner_ = decode_task_runner; +bool V4L2SliceVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h index 9171e44..87fe196 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h @@ -19,7 +19,6 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "content/common/content_export.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "content/common/gpu/media/h264_decoder.h" #include "content/common/gpu/media/v4l2_device.h" #include "content/common/gpu/media/vp8_decoder.h" @@ -39,8 +38,10 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator V4L2SliceVideoDecodeAccelerator( const scoped_refptr<V4L2Device>& device, EGLDisplay egl_display, - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb); + EGLContext egl_context, + const base::WeakPtr<Client>& io_client_, + const base::Callback<bool(void)>& make_context_current, + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); ~V4L2SliceVideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation. @@ -52,10 +53,7 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator void Flush() override; void Reset() override; void Destroy() override; - bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) - override; + bool CanDecodeOnIOThread() override; static media::VideoDecodeAccelerator::SupportedProfiles GetSupportedProfiles(); @@ -305,8 +303,8 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator // GPU Child thread task runner. const scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; - // Task runner Decode() and PictureReady() run on. - scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_; + // IO thread task runner. + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or // device worker threads back to the child thread. @@ -318,8 +316,8 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator scoped_ptr<base::WeakPtrFactory<VideoDecodeAccelerator::Client>> client_ptr_factory_; base::WeakPtr<VideoDecodeAccelerator::Client> client_; - // Callbacks to |decode_client_| must be executed on |decode_task_runner_|. - base::WeakPtr<Client> decode_client_; + // Callbacks to |io_client_| must be executed on |io_task_runner_|. + base::WeakPtr<Client> io_client_; // V4L2 device in use. scoped_refptr<V4L2Device> device_; @@ -400,13 +398,12 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator // The number of pictures that are sent to PictureReady and will be cleared. int picture_clearing_count_; + // Make the GL context current callback. + base::Callback<bool(void)> make_context_current_; + // EGL state EGLDisplay egl_display_; - - // Callback to get current GLContext. - GetGLContextCallback get_gl_context_cb_; - // Callback to set the correct gl context. - MakeGLContextCurrentCallback make_context_current_cb_; + EGLContext egl_context_; // The WeakPtrFactory for |weak_this_|. base::WeakPtrFactory<V4L2SliceVideoDecodeAccelerator> weak_this_factory_; diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc index 3deddf0..3554be5 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc @@ -25,7 +25,6 @@ #include "media/base/media_switches.h" #include "media/filters/h264_parser.h" #include "ui/gfx/geometry/rect.h" -#include "ui/gl/gl_context.h" #include "ui/gl/scoped_binders.h" #define NOTIFY_ERROR(x) \ @@ -154,10 +153,14 @@ V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {} V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( EGLDisplay egl_display, - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const scoped_refptr<V4L2Device>& device) + EGLContext egl_context, + const base::WeakPtr<Client>& io_client, + const base::Callback<bool(void)>& make_context_current, + const scoped_refptr<V4L2Device>& device, + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) : child_task_runner_(base::ThreadTaskRunnerHandle::Get()), + io_task_runner_(io_task_runner), + io_client_(io_client), decoder_thread_("V4L2DecoderThread"), decoder_state_(kUninitialized), device_(device), @@ -177,9 +180,9 @@ V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( picture_clearing_count_(0), pictures_assigned_(false, false), device_poll_thread_("V4L2DevicePollThread"), + make_context_current_(make_context_current), egl_display_(egl_display), - get_gl_context_cb_(get_gl_context_cb), - make_context_current_cb_(make_context_current_cb), + egl_context_(egl_context), video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), output_format_fourcc_(0), weak_this_factory_(this) { @@ -205,11 +208,6 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, DCHECK(child_task_runner_->BelongsToCurrentThread()); DCHECK_EQ(decoder_state_, kUninitialized); - if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) { - NOTREACHED() << "GL callbacks are required for this VDA"; - return false; - } - if (config.is_encrypted) { NOTREACHED() << "Encrypted streams are not supported for this VDA"; return false; @@ -224,14 +222,6 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); client_ = client_ptr_factory_->GetWeakPtr(); - // If we haven't been set up to decode on separate thread via - // TryToSetupDecodeOnSeparateThread(), use the main thread/client for - // decode tasks. - if (!decode_task_runner_) { - decode_task_runner_ = child_task_runner_; - DCHECK(!decode_client_); - decode_client_ = client_; - } video_profile_ = config.profile; @@ -241,7 +231,7 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, } // We need the context to be initialized to query extensions. - if (!make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { LOG(ERROR) << "Initialize(): could not make context current"; return false; } @@ -302,7 +292,7 @@ void V4L2VideoDecodeAccelerator::Decode( const media::BitstreamBuffer& bitstream_buffer) { DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() << ", size=" << bitstream_buffer.size(); - DCHECK(decode_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->BelongsToCurrentThread()); if (bitstream_buffer.id() < 0) { LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id(); @@ -334,8 +324,7 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers( return; } - gfx::GLContext* gl_context = get_gl_context_cb_.Run(); - if (!gl_context || !make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { LOG(ERROR) << "AssignPictureBuffers(): could not make context current"; NOTIFY_ERROR(PLATFORM_FAILURE); return; @@ -375,7 +364,7 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers( DCHECK_EQ(output_record.cleared, false); EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_, - gl_context->GetHandle(), + egl_context_, buffers[i].texture_id(), coded_size_, i, @@ -405,7 +394,7 @@ void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) { // Must be run on child thread, as we'll insert a sync in the EGL context. DCHECK(child_task_runner_->BelongsToCurrentThread()); - if (!make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { LOG(ERROR) << "ReusePictureBuffer(): could not make context current"; NOTIFY_ERROR(PLATFORM_FAILURE); return; @@ -466,13 +455,7 @@ void V4L2VideoDecodeAccelerator::Destroy() { delete this; } -bool V4L2VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { - decode_client_ = decode_client_; - decode_task_runner_ = decode_task_runner; - return true; -} +bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } // static media::VideoDecodeAccelerator::SupportedProfiles @@ -494,7 +477,7 @@ void V4L2VideoDecodeAccelerator::DecodeTask( bitstream_buffer.id()); scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( - decode_client_, decode_task_runner_, + io_client_, io_task_runner_, scoped_ptr<SharedMemoryRegion>( new SharedMemoryRegion(bitstream_buffer, true)), bitstream_buffer.id())); @@ -1287,7 +1270,7 @@ void V4L2VideoDecodeAccelerator::FlushTask() { // Queue up an empty buffer -- this triggers the flush. decoder_input_queue_.push( linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( - decode_client_, decode_task_runner_, nullptr, kFlushBufferId))); + io_client_, io_task_runner_, nullptr, kFlushBufferId))); decoder_flushing_ = true; SendPictureReady(); // Send all pending PictureReady. @@ -2010,12 +1993,10 @@ void V4L2VideoDecodeAccelerator::SendPictureReady() { bool cleared = pending_picture_ready_.front().cleared; const media::Picture& picture = pending_picture_ready_.front().picture; if (cleared && picture_clearing_count_ == 0) { - // This picture is cleared. It can be posted to a thread different than - // the main GPU thread to reduce latency. This should be the case after - // all pictures are cleared at the beginning. - decode_task_runner_->PostTask( - FROM_HERE, - base::Bind(&Client::PictureReady, decode_client_, picture)); + // This picture is cleared. Post it to IO thread to reduce latency. This + // should be the case after all pictures are cleared at the beginning. + io_task_runner_->PostTask( + FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); pending_picture_ready_.pop(); } else if (!cleared || resetting_or_flushing) { DVLOG(3) << "SendPictureReady()" diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.h b/content/common/gpu/media/v4l2_video_decode_accelerator.h index cb74956..3d06665 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.h @@ -23,7 +23,6 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "content/common/content_export.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "content/common/gpu/media/v4l2_device.h" #include "media/base/limits.h" #include "media/base/video_decoder_config.h" @@ -79,9 +78,11 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator public: V4L2VideoDecodeAccelerator( EGLDisplay egl_display, - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const scoped_refptr<V4L2Device>& device); + EGLContext egl_context, + const base::WeakPtr<Client>& io_client_, + const base::Callback<bool(void)>& make_context_current, + const scoped_refptr<V4L2Device>& device, + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); ~V4L2VideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation. @@ -94,10 +95,7 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator void Flush() override; void Reset() override; void Destroy() override; - bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) - override; + bool CanDecodeOnIOThread() override; static media::VideoDecodeAccelerator::SupportedProfiles GetSupportedProfiles(); @@ -318,8 +316,8 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator // Our original calling task runner for the child thread. scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; - // Task runner Decode() and PictureReady() run on. - scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_; + // Task runner of the IO thread. + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or // device worker threads back to the child thread. Because the worker threads @@ -334,8 +332,8 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator // child_task_runner_. scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; base::WeakPtr<Client> client_; - // Callbacks to |decode_client_| must be executed on |decode_task_runner_|. - base::WeakPtr<Client> decode_client_; + // Callbacks to |io_client_| must be executed on |io_task_runner_|. + base::WeakPtr<Client> io_client_; // // Decoder state, owned and operated by decoder_thread_. @@ -440,13 +438,12 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator // Other state, held by the child (main) thread. // + // Make our context current before running any EGL entry points. + base::Callback<bool(void)> make_context_current_; + // EGL state EGLDisplay egl_display_; - - // Callback to get current GLContext. - GetGLContextCallback get_gl_context_cb_; - // Callback to set the correct gl context. - MakeGLContextCurrentCallback make_context_current_cb_; + EGLContext egl_context_; // The codec we'll be decoding for. media::VideoCodecProfile video_profile_; diff --git a/content/common/gpu/media/vaapi_drm_picture.cc b/content/common/gpu/media/vaapi_drm_picture.cc index ab5a4f2..f207164 100644 --- a/content/common/gpu/media/vaapi_drm_picture.cc +++ b/content/common/gpu/media/vaapi_drm_picture.cc @@ -27,16 +27,16 @@ namespace content { VaapiDrmPicture::VaapiDrmPicture( const scoped_refptr<VaapiWrapper>& vaapi_wrapper, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)>& make_context_current, int32_t picture_buffer_id, uint32_t texture_id, const gfx::Size& size) : VaapiPicture(picture_buffer_id, texture_id, size), vaapi_wrapper_(vaapi_wrapper), - make_context_current_cb_(make_context_current_cb) {} + make_context_current_(make_context_current) {} VaapiDrmPicture::~VaapiDrmPicture() { - if (gl_image_ && make_context_current_cb_.Run()) { + if (gl_image_ && make_context_current_.Run()) { gl_image_->ReleaseTexImage(GL_TEXTURE_EXTERNAL_OES); gl_image_->Destroy(true); @@ -67,7 +67,7 @@ bool VaapiDrmPicture::Initialize() { pixmap_->SetProcessingCallback( base::Bind(&VaapiWrapper::ProcessPixmap, vaapi_wrapper_)); - if (!make_context_current_cb_.Run()) + if (!make_context_current_.Run()) return false; gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, diff --git a/content/common/gpu/media/vaapi_drm_picture.h b/content/common/gpu/media/vaapi_drm_picture.h index 7f5fc8a..066192b 100644 --- a/content/common/gpu/media/vaapi_drm_picture.h +++ b/content/common/gpu/media/vaapi_drm_picture.h @@ -11,6 +11,7 @@ #include <stdint.h> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -34,7 +35,7 @@ class VaapiWrapper; class VaapiDrmPicture : public VaapiPicture { public: VaapiDrmPicture(const scoped_refptr<VaapiWrapper>& vaapi_wrapper, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)>& make_context_current, int32_t picture_buffer_id, uint32_t texture_id, const gfx::Size& size); @@ -51,7 +52,7 @@ class VaapiDrmPicture : public VaapiPicture { private: scoped_refptr<VaapiWrapper> vaapi_wrapper_; - MakeGLContextCurrentCallback make_context_current_cb_; + base::Callback<bool(void)> make_context_current_; // Ozone buffer, the storage of the EGLImage and the VASurface. scoped_refptr<ui::NativePixmap> pixmap_; diff --git a/content/common/gpu/media/vaapi_picture.cc b/content/common/gpu/media/vaapi_picture.cc index cdf8c35..5222bd2 100644 --- a/content/common/gpu/media/vaapi_picture.cc +++ b/content/common/gpu/media/vaapi_picture.cc @@ -18,16 +18,16 @@ namespace content { // static linked_ptr<VaapiPicture> VaapiPicture::CreatePicture( const scoped_refptr<VaapiWrapper>& vaapi_wrapper, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)> make_context_current, int32_t picture_buffer_id, uint32_t texture_id, const gfx::Size& size) { linked_ptr<VaapiPicture> picture; #if defined(USE_X11) - picture.reset(new VaapiTFPPicture(vaapi_wrapper, make_context_current_cb, + picture.reset(new VaapiTFPPicture(vaapi_wrapper, make_context_current, picture_buffer_id, texture_id, size)); #elif defined(USE_OZONE) - picture.reset(new VaapiDrmPicture(vaapi_wrapper, make_context_current_cb, + picture.reset(new VaapiDrmPicture(vaapi_wrapper, make_context_current, picture_buffer_id, texture_id, size)); #endif // USE_X11 diff --git a/content/common/gpu/media/vaapi_picture.h b/content/common/gpu/media/vaapi_picture.h index 4bd51e1..921f803 100644 --- a/content/common/gpu/media/vaapi_picture.h +++ b/content/common/gpu/media/vaapi_picture.h @@ -12,11 +12,11 @@ #include <stdint.h> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/threading/non_thread_safe.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "ui/gfx/geometry/size.h" namespace gl { @@ -52,10 +52,10 @@ class VaapiPicture : public base::NonThreadSafe { // Create a VaapiPicture of |size| to be associated with // |picture_buffer_id| and bound to |texture_id|. - // |make_context_current_cb| is provided for the GL operations. + // |make_context_current| is provided for the GL operations. static linked_ptr<VaapiPicture> CreatePicture( const scoped_refptr<VaapiWrapper>& vaapi_wrapper, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)> make_context_current, int32_t picture_buffer_id, uint32_t texture_id, const gfx::Size& size); diff --git a/content/common/gpu/media/vaapi_tfp_picture.cc b/content/common/gpu/media/vaapi_tfp_picture.cc index 074ba98..3de593b 100644 --- a/content/common/gpu/media/vaapi_tfp_picture.cc +++ b/content/common/gpu/media/vaapi_tfp_picture.cc @@ -14,18 +14,18 @@ namespace content { VaapiTFPPicture::VaapiTFPPicture( const scoped_refptr<VaapiWrapper>& vaapi_wrapper, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)> make_context_current, int32_t picture_buffer_id, uint32_t texture_id, const gfx::Size& size) : VaapiPicture(picture_buffer_id, texture_id, size), vaapi_wrapper_(vaapi_wrapper), - make_context_current_cb_(make_context_current_cb), + make_context_current_(make_context_current), x_display_(gfx::GetXDisplay()), x_pixmap_(0) {} VaapiTFPPicture::~VaapiTFPPicture() { - if (glx_image_.get() && make_context_current_cb_.Run()) { + if (glx_image_.get() && make_context_current_.Run()) { glx_image_->ReleaseTexImage(GL_TEXTURE_2D); glx_image_->Destroy(true); DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR)); @@ -36,7 +36,7 @@ VaapiTFPPicture::~VaapiTFPPicture() { } bool VaapiTFPPicture::Initialize() { - if (!make_context_current_cb_.Run()) + if (!make_context_current_.Run()) return false; XWindowAttributes win_attr; diff --git a/content/common/gpu/media/vaapi_tfp_picture.h b/content/common/gpu/media/vaapi_tfp_picture.h index 5ef3565..3b66e10 100644 --- a/content/common/gpu/media/vaapi_tfp_picture.h +++ b/content/common/gpu/media/vaapi_tfp_picture.h @@ -11,6 +11,7 @@ #include <stdint.h> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "content/common/gpu/media/vaapi_picture.h" @@ -33,7 +34,7 @@ class VaapiWrapper; class VaapiTFPPicture : public VaapiPicture { public: VaapiTFPPicture(const scoped_refptr<VaapiWrapper>& vaapi_wrapper, - const MakeGLContextCurrentCallback& make_context_current_cb, + const base::Callback<bool(void)> make_context_current, int32_t picture_buffer_id, uint32_t texture_id, const gfx::Size& size); @@ -49,7 +50,7 @@ class VaapiTFPPicture : public VaapiPicture { private: scoped_refptr<VaapiWrapper> vaapi_wrapper_; - MakeGLContextCurrentCallback make_context_current_cb_; + base::Callback<bool(void)> make_context_current_; Display* x_display_; Pixmap x_pixmap_; diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index 18d3b9a..2ede678 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc @@ -292,9 +292,10 @@ VaapiPicture* VaapiVideoDecodeAccelerator::PictureById( } VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb) - : state_(kUninitialized), + const MakeContextCurrentCallback& make_context_current, + const BindImageCallback& bind_image) + : make_context_current_(make_context_current), + state_(kUninitialized), input_ready_(&lock_), surfaces_available_(&lock_), message_loop_(base::MessageLoop::current()), @@ -304,8 +305,7 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( finish_flush_pending_(false), awaiting_va_surfaces_recycle_(false), requested_num_pics_(0), - make_context_current_cb_(make_context_current_cb), - bind_image_cb_(bind_image_cb), + bind_image_(bind_image), weak_this_factory_(this) { weak_this_ = weak_this_factory_.GetWeakPtr(); va_surface_release_cb_ = media::BindToCurrentLoop( @@ -320,11 +320,6 @@ bool VaapiVideoDecodeAccelerator::Initialize(const Config& config, Client* client) { DCHECK_EQ(message_loop_, base::MessageLoop::current()); - if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) { - NOTREACHED() << "GL callbacks are required for this VDA"; - return false; - } - if (config.is_encrypted) { NOTREACHED() << "Encrypted streams are not supported for this VDA"; return false; @@ -746,15 +741,13 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers( << " VASurfaceID: " << va_surface_ids[i]; linked_ptr<VaapiPicture> picture(VaapiPicture::CreatePicture( - vaapi_wrapper_, make_context_current_cb_, buffers[i].id(), + vaapi_wrapper_, make_context_current_, buffers[i].id(), buffers[i].texture_id(), requested_pic_size_)); scoped_refptr<gl::GLImage> image = picture->GetImageToBind(); if (image) { - RETURN_AND_NOTIFY_ON_FAILURE( - bind_image_cb_.Run(buffers[i].internal_texture_id(), - VaapiPicture::GetGLTextureTarget(), image, true), - "Failed to bind image", PLATFORM_FAILURE, ); + bind_image_.Run(buffers[i].internal_texture_id(), + VaapiPicture::GetGLTextureTarget(), image, true); } RETURN_AND_NOTIFY_ON_FAILURE( @@ -969,9 +962,7 @@ void VaapiVideoDecodeAccelerator::Destroy() { delete this; } -bool VaapiVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { +bool VaapiVideoDecodeAccelerator::CanDecodeOnIOThread() { return false; } diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index f9cfb90..d14b06a 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h @@ -26,7 +26,6 @@ #include "base/synchronization/lock.h" #include "base/threading/thread.h" #include "content/common/content_export.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "content/common/gpu/media/shared_memory_region.h" #include "content/common/gpu/media/vaapi_wrapper.h" #include "media/base/bitstream_buffer.h" @@ -56,9 +55,8 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator class VaapiDecodeSurface; VaapiVideoDecodeAccelerator( - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb); - + const MakeContextCurrentCallback& make_context_current, + const BindImageCallback& bind_image); ~VaapiVideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation. @@ -70,10 +68,7 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator void Flush() override; void Reset() override; void Destroy() override; - bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) - override; + bool CanDecodeOnIOThread() override; static media::VideoDecodeAccelerator::SupportedProfiles GetSupportedProfiles(); @@ -184,6 +179,10 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator // available. scoped_refptr<VaapiDecodeSurface> CreateSurface(); + + // Client-provided GL state. + MakeContextCurrentCallback make_context_current_; + // VAVDA state. enum State { // Initialize() not called yet or failed. @@ -304,11 +303,9 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator size_t requested_num_pics_; gfx::Size requested_pic_size_; - // Callback to make GL context current. - MakeGLContextCurrentCallback make_context_current_cb_; - - // Callback to bind a GLImage to a given texture. - BindGLImageCallback bind_image_cb_; + // Binds the provided GLImage to a givenr client texture ID & texture target + // combination in GLES. + BindImageCallback bind_image_; // The WeakPtrFactory for |weak_this_|. base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_; diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc index a04e7c8..c7ca0d2 100644 --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc @@ -47,10 +47,8 @@ #include "base/threading/thread.h" #include "build/build_config.h" #include "content/common/gpu/media/fake_video_decode_accelerator.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h" #include "content/common/gpu/media/rendering_helper.h" #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" -#include "gpu/command_buffer/service/gpu_preferences.h" #include "media/filters/h264_parser.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/codec/png_codec.h" @@ -360,6 +358,17 @@ class GLRenderingVDAClient private: typedef std::map<int32_t, scoped_refptr<TextureRef>> TextureRefMap; + scoped_ptr<media::VideoDecodeAccelerator> CreateFakeVDA(); + scoped_ptr<media::VideoDecodeAccelerator> CreateDXVAVDA(); + scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2VDA(); + scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2SliceVDA(); + scoped_ptr<media::VideoDecodeAccelerator> CreateVaapiVDA(); + + void BindImage(uint32_t client_texture_id, + uint32_t texture_target, + scoped_refptr<gl::GLImage> image, + bool can_bind_as_sampler); + void SetState(ClientState new_state); void FinishInitialization(); void ReturnPicture(int32_t picture_buffer_id); @@ -392,10 +401,8 @@ class GLRenderingVDAClient int next_bitstream_buffer_id_; ClientStateNotification<ClientState>* note_; scoped_ptr<VideoDecodeAccelerator> decoder_; - base::WeakPtr<VideoDecodeAccelerator> weak_vda_; - scoped_ptr<base::WeakPtrFactory<VideoDecodeAccelerator>> - weak_vda_ptr_factory_; - scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> vda_factory_; + scoped_ptr<base::WeakPtrFactory<VideoDecodeAccelerator> > + weak_decoder_factory_; int remaining_play_throughs_; int reset_after_frame_num_; int delete_decoder_state_; @@ -433,23 +440,9 @@ class GLRenderingVDAClient int32_t next_picture_buffer_id_; - base::WeakPtr<GLRenderingVDAClient> weak_this_; - base::WeakPtrFactory<GLRenderingVDAClient> weak_this_factory_; - DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); }; -static bool DoNothingReturnTrue() { - return true; -} - -static bool DummyBindImage(uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image, - bool can_bind_to_sampler) { - return true; -} - GLRenderingVDAClient::GLRenderingVDAClient( size_t window_id, RenderingHelper* rendering_helper, @@ -490,8 +483,7 @@ GLRenderingVDAClient::GLRenderingVDAClient( delay_reuse_after_frame_num_(delay_reuse_after_frame_num), decode_calls_per_second_(decode_calls_per_second), render_as_thumbnails_(render_as_thumbnails), - next_picture_buffer_id_(1), - weak_this_factory_(this) { + next_picture_buffer_id_(1) { LOG_ASSERT(num_in_flight_decodes > 0); LOG_ASSERT(num_play_throughs > 0); // |num_in_flight_decodes_| is unsupported if |decode_calls_per_second_| > 0. @@ -502,8 +494,6 @@ GLRenderingVDAClient::GLRenderingVDAClient( profile_ = (profile != media::VIDEO_CODEC_PROFILE_UNKNOWN ? profile : media::H264PROFILE_BASELINE); - - weak_this_ = weak_this_factory_.GetWeakPtr(); } GLRenderingVDAClient::~GLRenderingVDAClient() { @@ -512,35 +502,114 @@ GLRenderingVDAClient::~GLRenderingVDAClient() { SetState(CS_DESTROYED); } -void GLRenderingVDAClient::CreateAndStartDecoder() { - LOG_ASSERT(decoder_deleted()); - LOG_ASSERT(!decoder_.get()); +static bool DoNothingReturnTrue() { return true; } +scoped_ptr<media::VideoDecodeAccelerator> +GLRenderingVDAClient::CreateFakeVDA() { + scoped_ptr<media::VideoDecodeAccelerator> decoder; if (fake_decoder_) { - decoder_.reset(new FakeVideoDecodeAccelerator( - frame_size_, base::Bind(&DoNothingReturnTrue))); - LOG_ASSERT(decoder_->Initialize(profile_, this)); - } else { - if (!vda_factory_) { - vda_factory_ = GpuVideoDecodeAcceleratorFactoryImpl::Create( - base::Bind(&RenderingHelper::GetGLContext, - base::Unretained(rendering_helper_)), - base::Bind(&DoNothingReturnTrue), base::Bind(&DummyBindImage)); - LOG_ASSERT(vda_factory_); - } + decoder.reset(new FakeVideoDecodeAccelerator( + static_cast<gfx::GLContext*> (rendering_helper_->GetGLContextHandle()), + frame_size_, + base::Bind(&DoNothingReturnTrue))); + } + return decoder; +} - VideoDecodeAccelerator::Config config(profile_); - gpu::GpuPreferences gpu_preferences; - decoder_ = vda_factory_->CreateVDA(this, config, gpu_preferences); +scoped_ptr<media::VideoDecodeAccelerator> +GLRenderingVDAClient::CreateDXVAVDA() { + scoped_ptr<media::VideoDecodeAccelerator> decoder; +#if defined(OS_WIN) + if (base::win::GetVersion() >= base::win::VERSION_WIN7) { + const bool enable_accelerated_vpx_decode = false; + decoder.reset(new DXVAVideoDecodeAccelerator( + base::Bind(&DoNothingReturnTrue), + rendering_helper_->GetGLContext().get(), + enable_accelerated_vpx_decode)); } +#endif + return decoder; +} - LOG_ASSERT(decoder_) << "Failed creating a VDA"; +scoped_ptr<media::VideoDecodeAccelerator> +GLRenderingVDAClient::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()) { + base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); + decoder.reset(new V4L2VideoDecodeAccelerator( + static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()), + static_cast<EGLContext>(rendering_helper_->GetGLContextHandle()), + weak_client, base::Bind(&DoNothingReturnTrue), device, + base::ThreadTaskRunnerHandle::Get())); + } +#endif + return decoder; +} - decoder_->TryToSetupDecodeOnSeparateThread( - weak_this_, base::ThreadTaskRunnerHandle::Get()); +scoped_ptr<media::VideoDecodeAccelerator> +GLRenderingVDAClient::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()) { + base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); + decoder.reset(new V4L2SliceVideoDecodeAccelerator( + device, static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()), + static_cast<EGLContext>(rendering_helper_->GetGLContextHandle()), + weak_client, base::Bind(&DoNothingReturnTrue), + base::ThreadTaskRunnerHandle::Get())); + } +#endif + return decoder; +} - SetState(CS_DECODER_SET); - FinishInitialization(); +scoped_ptr<media::VideoDecodeAccelerator> +GLRenderingVDAClient::CreateVaapiVDA() { + scoped_ptr<media::VideoDecodeAccelerator> decoder; +#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) + decoder.reset(new VaapiVideoDecodeAccelerator( + base::Bind(&DoNothingReturnTrue), + base::Bind(&GLRenderingVDAClient::BindImage, base::Unretained(this)))); +#endif + return decoder; +} + +void GLRenderingVDAClient::BindImage(uint32_t client_texture_id, + uint32_t texture_target, + scoped_refptr<gl::GLImage> image, + bool can_bind_to_sampler) {} + +void GLRenderingVDAClient::CreateAndStartDecoder() { + LOG_ASSERT(decoder_deleted()); + LOG_ASSERT(!decoder_.get()); + + VideoDecodeAccelerator::Client* client = this; + + scoped_ptr<media::VideoDecodeAccelerator> decoders[] = { + CreateFakeVDA(), + CreateDXVAVDA(), + CreateV4L2VDA(), + CreateV4L2SliceVDA(), + CreateVaapiVDA(), + }; + + for (size_t i = 0; i < arraysize(decoders); ++i) { + if (!decoders[i]) + continue; + decoder_ = std::move(decoders[i]); + weak_decoder_factory_.reset( + new base::WeakPtrFactory<VideoDecodeAccelerator>(decoder_.get())); + if (decoder_->Initialize(profile_, client)) { + SetState(CS_DECODER_SET); + FinishInitialization(); + return; + } + } + // Decoders are all initialize failed. + LOG(ERROR) << "VideoDecodeAccelerator::Initialize() failed"; + LOG_ASSERT(false); } void GLRenderingVDAClient::ProvidePictureBuffers( @@ -644,8 +713,10 @@ void GLRenderingVDAClient::ReturnPicture(int32_t picture_buffer_id) { if (num_decoded_frames_ > delay_reuse_after_frame_num_) { base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, - weak_vda_, picture_buffer_id), + FROM_HERE, + base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, + weak_decoder_factory_->GetWeakPtr(), + picture_buffer_id), kReuseDelay); } else { decoder_->ReusePictureBuffer(picture_buffer_id); @@ -767,7 +838,7 @@ void GLRenderingVDAClient::FinishInitialization() { void GLRenderingVDAClient::DeleteDecoder() { if (decoder_deleted()) return; - weak_vda_ptr_factory_.reset(); + weak_decoder_factory_.reset(); decoder_.reset(); STLClearObject(&encoded_data_); active_textures_.clear(); diff --git a/content/common/gpu/media/vt_video_decode_accelerator_mac.cc b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc index 69e1517..50e144b 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator_mac.cc +++ b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc @@ -283,10 +283,10 @@ bool VTVideoDecodeAccelerator::FrameOrder::operator()( } VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb) - : make_context_current_cb_(make_context_current_cb), - bind_image_cb_(bind_image_cb), + const MakeContextCurrentCallback& make_context_current, + const BindImageCallback& bind_image) + : make_context_current_(make_context_current), + bind_image_(bind_image), client_(nullptr), state_(STATE_DECODING), format_(nullptr), @@ -298,6 +298,7 @@ VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), decoder_thread_("VTDecoderThread"), weak_this_factory_(this) { + DCHECK(!make_context_current_.is_null()); callback_.decompressionOutputCallback = OutputThunk; callback_.decompressionOutputRefCon = this; weak_this_ = weak_this_factory_.GetWeakPtr(); @@ -311,11 +312,6 @@ bool VTVideoDecodeAccelerator::Initialize(const Config& config, Client* client) { DCHECK(gpu_thread_checker_.CalledOnValidThread()); - if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) { - NOTREACHED() << "GL callbacks are required for this VDA"; - return false; - } - if (config.is_encrypted) { NOTREACHED() << "Encrypted streams are not supported for this VDA"; return false; @@ -1026,7 +1022,7 @@ bool VTVideoDecodeAccelerator::SendFrame(const Frame& frame) { DCHECK(!picture_info->cv_image); DCHECK(!picture_info->gl_image); - if (!make_context_current_cb_.Run()) { + if (!make_context_current_.Run()) { DLOG(ERROR) << "Failed to make GL context current"; NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); return false; @@ -1045,12 +1041,8 @@ bool VTVideoDecodeAccelerator::SendFrame(const Frame& frame) { // Mark that the image is not bound for sampling. 4:2:0 images need to // undergo a separate copy to be displayed. - if (!bind_image_cb_.Run(picture_info->client_texture_id, - GL_TEXTURE_RECTANGLE_ARB, gl_image, false)) { - DLOG(ERROR) << "Failed to bind image"; - NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); - return false; - } + bind_image_.Run(picture_info->client_texture_id, GL_TEXTURE_RECTANGLE_ARB, + gl_image, false); // Assign the new image(s) to the the picture info. picture_info->gl_image = gl_image; @@ -1126,9 +1118,7 @@ void VTVideoDecodeAccelerator::Destroy() { QueueFlush(TASK_DESTROY); } -bool VTVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { +bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { return false; } diff --git a/content/common/gpu/media/vt_video_decode_accelerator_mac.h b/content/common/gpu/media/vt_video_decode_accelerator_mac.h index 031b46a..c3e75e9 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator_mac.h +++ b/content/common/gpu/media/vt_video_decode_accelerator_mac.h @@ -17,7 +17,6 @@ #include "base/message_loop/message_loop.h" #include "base/threading/thread.h" #include "base/threading/thread_checker.h" -#include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" #include "content/common/gpu/media/vt_mac.h" #include "media/filters/h264_parser.h" #include "media/video/h264_poc.h" @@ -36,9 +35,8 @@ bool InitializeVideoToolbox(); class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator { public: explicit VTVideoDecodeAccelerator( - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb); - + const MakeContextCurrentCallback& make_context_current, + const BindImageCallback& bind_image); ~VTVideoDecodeAccelerator() override; // VideoDecodeAccelerator implementation. @@ -50,10 +48,7 @@ class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator { void Flush() override; void Reset() override; void Destroy() override; - bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) - override; + bool CanDecodeOnIOThread() override; // Called by OutputThunk() when VideoToolbox finishes decoding a frame. void Output( @@ -193,8 +188,8 @@ class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator { // // GPU thread state. // - MakeGLContextCurrentCallback make_context_current_cb_; - BindGLImageCallback bind_image_cb_; + MakeContextCurrentCallback make_context_current_; + BindImageCallback bind_image_; media::VideoDecodeAccelerator::Client* client_; State state_; diff --git a/content/content_common.gypi b/content/content_common.gypi index d449b45..5550b37 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -407,9 +407,6 @@ 'common/gpu/media/gpu_video_accelerator_util.h', 'common/gpu/media/gpu_video_decode_accelerator.cc', 'common/gpu/media/gpu_video_decode_accelerator.h', - 'common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc', - 'common/gpu/media/gpu_video_decode_accelerator_factory_impl.h', - 'common/gpu/media/gpu_video_decode_accelerator_helpers.h', 'common/gpu/media/gpu_video_encode_accelerator.cc', 'common/gpu/media/gpu_video_encode_accelerator.h', 'common/gpu/media/media_channel.cc', diff --git a/content/content_gpu.gypi b/content/content_gpu.gypi index 47599e7..f134890 100644 --- a/content/content_gpu.gypi +++ b/content/content_gpu.gypi @@ -23,8 +23,6 @@ 'gpu/in_process_gpu_thread.cc', 'gpu/in_process_gpu_thread.h', 'public/gpu/content_gpu_client.h', - 'public/gpu/gpu_video_decode_accelerator_factory.cc', - 'public/gpu/gpu_video_decode_accelerator_factory.h', ], 'include_dirs': [ '..', diff --git a/content/public/gpu/BUILD.gn b/content/public/gpu/BUILD.gn index 2b6668f..3bca008 100644 --- a/content/public/gpu/BUILD.gn +++ b/content/public/gpu/BUILD.gn @@ -20,8 +20,6 @@ source_set("gpu_sources") { sources = [ "content_gpu_client.h", - "gpu_video_decode_accelerator_factory.cc", - "gpu_video_decode_accelerator_factory.h", ] deps = [ @@ -29,8 +27,5 @@ source_set("gpu_sources") { "//content:export", "//content/gpu:gpu_sources", "//content/public/common:common_sources", - "//gpu/command_buffer/service:service_sources", - "//gpu/config:config_sources", - "//media:media", ] } diff --git a/content/public/gpu/DEPS b/content/public/gpu/DEPS deleted file mode 100644 index 3059074..0000000 --- a/content/public/gpu/DEPS +++ /dev/null @@ -1,9 +0,0 @@ -specific_include_rules = { - ".*\.cc": [ - "+content/common", - ], - "gpu_video_decode_accelerator_factory.h": [ - "+gpu", - "+media", - ], -} diff --git a/content/public/gpu/gpu_video_decode_accelerator_factory.cc b/content/public/gpu/gpu_video_decode_accelerator_factory.cc deleted file mode 100644 index 57b46a8..0000000 --- a/content/public/gpu/gpu_video_decode_accelerator_factory.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h" -#include "content/public/gpu/gpu_video_decode_accelerator_factory.h" - -namespace content { - -GpuVideoDecodeAcceleratorFactory::~GpuVideoDecodeAcceleratorFactory() {} - -// static -scoped_ptr<GpuVideoDecodeAcceleratorFactory> -GpuVideoDecodeAcceleratorFactory::Create( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb) { - auto gvdafactory_impl = GpuVideoDecodeAcceleratorFactoryImpl::Create( - get_gl_context_cb, make_context_current_cb, bind_image_cb); - if (!gvdafactory_impl) - return nullptr; - - return make_scoped_ptr( - new GpuVideoDecodeAcceleratorFactory(std::move(gvdafactory_impl))); -} - -// static -scoped_ptr<GpuVideoDecodeAcceleratorFactory> -GpuVideoDecodeAcceleratorFactory::CreateWithGLES2Decoder( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb) { - auto gvdafactory_impl = - GpuVideoDecodeAcceleratorFactoryImpl::CreateWithGLES2Decoder( - get_gl_context_cb, make_context_current_cb, bind_image_cb, - get_gles2_decoder_cb); - if (!gvdafactory_impl) - return nullptr; - - return make_scoped_ptr( - new GpuVideoDecodeAcceleratorFactory(std::move(gvdafactory_impl))); -} - -// static -gpu::VideoDecodeAcceleratorCapabilities -GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities( - const gpu::GpuPreferences& gpu_preferences) { - return GpuVideoDecodeAcceleratorFactoryImpl::GetDecoderCapabilities( - gpu_preferences); -} - -scoped_ptr<media::VideoDecodeAccelerator> -GpuVideoDecodeAcceleratorFactory::CreateVDA( - media::VideoDecodeAccelerator::Client* client, - const media::VideoDecodeAccelerator::Config& config, - const gpu::GpuPreferences& gpu_preferences) { - if (!gvdafactory_impl_) - return nullptr; - - return gvdafactory_impl_->CreateVDA(client, config, gpu_preferences); -} - -GpuVideoDecodeAcceleratorFactory::GpuVideoDecodeAcceleratorFactory( - scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> gvdafactory_impl) - : gvdafactory_impl_(std::move(gvdafactory_impl)) {} - -} // namespace content diff --git a/content/public/gpu/gpu_video_decode_accelerator_factory.h b/content/public/gpu/gpu_video_decode_accelerator_factory.h deleted file mode 100644 index b02ceea..0000000 --- a/content/public/gpu/gpu_video_decode_accelerator_factory.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_PUBLIC_GPU_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_H_ -#define CONTENT_PUBLIC_GPU_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_H_ - -#include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "content/common/content_export.h" -#include "gpu/command_buffer/service/gpu_preferences.h" -#include "gpu/config/gpu_info.h" -#include "media/video/video_decode_accelerator.h" - -namespace gfx { -class GLContext; -} - -namespace gl { -class GLImage; -} - -namespace gpu { -namespace gles2 { -class GLES2Decoder; -} -} - -namespace content { - -class GpuVideoDecodeAcceleratorFactoryImpl; - -// This factory allows creation of VideoDecodeAccelerator implementations, -// providing the most applicable VDA for current platform and given -// configuration. To be used in GPU process only. -class CONTENT_EXPORT GpuVideoDecodeAcceleratorFactory { - public: - virtual ~GpuVideoDecodeAcceleratorFactory(); - - // Return current GLContext. - using GetGLContextCallback = base::Callback<gfx::GLContext*(void)>; - - // Make the applicable GL context current. To be called by VDAs before - // executing any GL calls. Return true on success, false otherwise. - using MakeGLContextCurrentCallback = base::Callback<bool(void)>; - - // Bind |image| to |client_texture_id| given |texture_target|. If - // |can_bind_to_sampler| is true, then the image may be used as a sampler - // directly, otherwise a copy to a staging buffer is required. - // Return true on success, false otherwise. - using BindGLImageCallback = - base::Callback<bool(uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image, - bool can_bind_to_sampler)>; - - // Return a WeakPtr to a GLES2Decoder, if one is available. - using GetGLES2DecoderCallback = - base::Callback<base::WeakPtr<gpu::gles2::GLES2Decoder>(void)>; - - // Create a factory capable of producing VDA instances for current platform. - static scoped_ptr<GpuVideoDecodeAcceleratorFactory> Create( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb); - - static scoped_ptr<GpuVideoDecodeAcceleratorFactory> CreateWithGLES2Decoder( - const GetGLContextCallback& get_gl_context_cb, - const MakeGLContextCurrentCallback& make_context_current_cb, - const BindGLImageCallback& bind_image_cb, - const GetGLES2DecoderCallback& get_gles2_decoder_cb); - - // Return decoder capabilities supported on the current platform. - static gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilities( - const gpu::GpuPreferences& gpu_preferences); - - // Create a VDA for the current platform for |client| with the given |config| - // and for given |gpu_preferences|. Return nullptr on failure. - virtual scoped_ptr<media::VideoDecodeAccelerator> CreateVDA( - media::VideoDecodeAccelerator::Client* client, - const media::VideoDecodeAccelerator::Config& config, - const gpu::GpuPreferences& gpu_preferences); - - private: - // TODO(posciak): This is temporary and will not be needed once - // GpuVideoDecodeAcceleratorFactoryImpl implements - // GpuVideoDecodeAcceleratorFactory, see crbug.com/597150 and related. - GpuVideoDecodeAcceleratorFactory( - scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> gvdafactory_impl); - - scoped_ptr<GpuVideoDecodeAcceleratorFactoryImpl> gvdafactory_impl_; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_GPU_GPU_VIDEO_DECODE_ACCELERATOR_FACTORY_H_ diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index fc8ad968..7ad6816 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn @@ -19,7 +19,6 @@ group("service") { source_set("service_sources") { visibility = [ - "//content/public/gpu/*", "//gpu/*", "//mojo/gles2:gles2", ] diff --git a/gpu/config/BUILD.gn b/gpu/config/BUILD.gn index fa9a972..3ca9edf 100644 --- a/gpu/config/BUILD.gn +++ b/gpu/config/BUILD.gn @@ -25,7 +25,6 @@ group("config") { source_set("config_sources") { visibility = [ "//components/mus/gles2:*", - "//content/public/gpu/*", "//gpu/*", ] diff --git a/media/video/mock_video_decode_accelerator.h b/media/video/mock_video_decode_accelerator.h index 89978987..63aeaad 100644 --- a/media/video/mock_video_decode_accelerator.h +++ b/media/video/mock_video_decode_accelerator.h @@ -34,9 +34,7 @@ class MockVideoDecodeAccelerator : public VideoDecodeAccelerator { MOCK_METHOD0(Flush, void()); MOCK_METHOD0(Reset, void()); MOCK_METHOD0(Destroy, void()); - MOCK_METHOD2(TryToSetupDecodeOnSeparateThread, - bool(const base::WeakPtr<Client>&, - const scoped_refptr<base::SingleThreadTaskRunner>&)); + MOCK_METHOD0(CanDecodeOnIOThread, bool()); private: void DeleteThis(); diff --git a/media/video/video_decode_accelerator.cc b/media/video/video_decode_accelerator.cc index 00ae88c..f99787a 100644 --- a/media/video/video_decode_accelerator.cc +++ b/media/video/video_decode_accelerator.cc @@ -34,11 +34,9 @@ void VideoDecodeAccelerator::SetCdm(int cdm_id) { NOTREACHED() << "By default CDM is not supported."; } -bool VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { - // Implementations in the process that VDA runs in must override this. - LOG(FATAL) << "This may only be called in the same process as VDA impl."; +bool VideoDecodeAccelerator::CanDecodeOnIOThread() { + // GPU process subclasses must override this. + LOG(FATAL) << "This should only get called in the GPU process"; return false; // not reached } diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index 4552973..a840750 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h @@ -10,20 +10,15 @@ #include <memory> #include <vector> -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" #include "media/base/bitstream_buffer.h" #include "media/base/surface_manager.h" #include "media/base/video_decoder_config.h" #include "media/video/picture.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/gl_image.h" typedef unsigned int GLenum; -namespace base { -class SingleThreadTaskRunner; -} - namespace media { // Video decoder interface. @@ -43,6 +38,10 @@ class MEDIA_EXPORT VideoDecodeAccelerator { }; using SupportedProfiles = std::vector<SupportedProfile>; + using MakeContextCurrentCallback = base::Callback<bool(void)>; + using BindImageCallback = base::Callback< + void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>, bool)>; + struct MEDIA_EXPORT Capabilities { Capabilities(); Capabilities(const Capabilities& other); @@ -230,39 +229,16 @@ class MEDIA_EXPORT VideoDecodeAccelerator { // unconditionally, so make sure to drop all pointers to it! virtual void Destroy() = 0; - // TO BE CALLED IN THE SAME PROCESS AS THE VDA IMPLEMENTATION ONLY. - // - // A decode "task" is a sequence that includes a Decode() call from Client, - // as well as corresponding callbacks to return the input BitstreamBuffer - // after use, and the resulting output Picture(s). - // - // If the Client can support running these three calls on a separate thread, - // it may call this method to try to set up the VDA implementation to do so. - // If the VDA can support this as well, return true, otherwise return false. - // If true is returned, the client may submit each Decode() call (but no other - // calls) on |decode_task_runner|, and should then expect that - // NotifyEndOfBitstreamBuffer() and PictureReady() callbacks may come on - // |decode_task_runner| as well, called on |decode_client|, instead of client - // provided to Initialize(). - // - // This method may be called at any time. - // - // NOTE 1: some callbacks may still have to come on the main thread and the - // Client should handle both callbacks coming on main and |decode_task_runner| - // thread. - // - // NOTE 2: VDA implementations of Decode() must return as soon as possible and - // never block, as |decode_task_runner| may be a latency critical thread - // (such as the GPU IO thread). - // - // One application of this is offloading the GPU Child thread. In general, - // calls to VDA in GPU process have to be done on the GPU Child thread, as - // they may require GL context to be current. However, some VDAs may be able - // to run decode operations without GL context, which helps reduce latency and - // offloads the GPU Child thread. - virtual bool TryToSetupDecodeOnSeparateThread( - const base::WeakPtr<Client>& decode_client, - const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner); + // GPU PROCESS ONLY. Implementations of this interface in the + // content/common/gpu/media should implement this, and implementations in + // other processes should not override the default implementation. + // Returns true if VDA::Decode and VDA::Client callbacks can run on the IO + // thread. Otherwise they will run on the GPU child thread. The purpose of + // running Decode on the IO thread is to reduce decode latency. Note Decode + // should return as soon as possible and not block on the IO thread. Also, + // PictureReady should be run on the child thread if a picture is delivered + // the first time so it can be cleared. + virtual bool CanDecodeOnIOThread(); // Windows creates a BGRA texture. // TODO(dshwang): after moving to D3D11, remove this. crbug.com/438691 |