summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw <brettw@chromium.org>2016-03-25 10:55:15 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-25 17:56:51 +0000
commitaffa906687c76c929545f8073fffaa53ff3a1a4a (patch)
tree3755b1452b8fc4e4c722dd200a59d0998c0e162d
parent36bf097458296e86dd3054632826dc78f658856f (diff)
downloadchromium_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}
-rw-r--r--content/common/gpu/media/android_video_decode_accelerator.cc72
-rw-r--r--content/common/gpu/media/android_video_decode_accelerator.h18
-rw-r--r--content/common/gpu/media/android_video_decode_accelerator_unittest.cc8
-rw-r--r--content/common/gpu/media/dxva_video_decode_accelerator_win.cc38
-rw-r--r--content/common/gpu/media/dxva_video_decode_accelerator_win.h17
-rw-r--r--content/common/gpu/media/fake_video_decode_accelerator.cc19
-rw-r--r--content/common/gpu/media/fake_video_decode_accelerator.h14
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.cc280
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.h46
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.cc241
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h126
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator_helpers.h59
-rw-r--r--content/common/gpu/media/rendering_helper.cc8
-rw-r--r--content/common/gpu/media/rendering_helper.h5
-rw-r--r--content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc61
-rw-r--r--content/common/gpu/media/v4l2_slice_video_decode_accelerator.h29
-rw-r--r--content/common/gpu/media/v4l2_video_decode_accelerator.cc61
-rw-r--r--content/common/gpu/media/v4l2_video_decode_accelerator.h31
-rw-r--r--content/common/gpu/media/vaapi_drm_picture.cc8
-rw-r--r--content/common/gpu/media/vaapi_drm_picture.h5
-rw-r--r--content/common/gpu/media/vaapi_picture.cc6
-rw-r--r--content/common/gpu/media/vaapi_picture.h6
-rw-r--r--content/common/gpu/media/vaapi_tfp_picture.cc8
-rw-r--r--content/common/gpu/media/vaapi_tfp_picture.h5
-rw-r--r--content/common/gpu/media/vaapi_video_decode_accelerator.cc27
-rw-r--r--content/common/gpu/media/vaapi_video_decode_accelerator.h23
-rw-r--r--content/common/gpu/media/video_decode_accelerator_unittest.cc169
-rw-r--r--content/common/gpu/media/vt_video_decode_accelerator_mac.cc28
-rw-r--r--content/common/gpu/media/vt_video_decode_accelerator_mac.h15
-rw-r--r--content/content_common.gypi3
-rw-r--r--content/content_gpu.gypi2
-rw-r--r--content/public/gpu/BUILD.gn5
-rw-r--r--content/public/gpu/DEPS9
-rw-r--r--content/public/gpu/gpu_video_decode_accelerator_factory.cc68
-rw-r--r--content/public/gpu/gpu_video_decode_accelerator_factory.h96
-rw-r--r--gpu/command_buffer/service/BUILD.gn1
-rw-r--r--gpu/config/BUILD.gn1
-rw-r--r--media/video/mock_video_decode_accelerator.h4
-rw-r--r--media/video/video_decode_accelerator.cc8
-rw-r--r--media/video/video_decode_accelerator.h54
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