#include "gpu/command_buffer/common/command_buffer.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/gl/gl_context.h"
#include "ui/gl/gl_surface_egl.h"
#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
#include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
#include "content/common/gpu/media/v4l2_video_device.h"
-#elif defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11)
+#elif defined(ARCH_CPU_X86_FAMILY) && (defined(USE_X11) || defined(USE_OZONE))
#include "content/common/gpu/media/vaapi_video_decode_accelerator.h"
+#if defined(USE_X11)
#include "ui/gl/gl_context_glx.h"
#include "ui/gl/gl_implementation.h"
+#endif
#elif defined(OS_ANDROID)
#include "content/common/gpu/media/android_video_decode_accelerator.h"
#endif
static bool MakeDecoderContextCurrent(
const base::WeakPtr<GpuCommandBufferStub> stub) {
- if (!stub.get()) {
+ if (!stub) {
DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
return false;
}
};
#endif
-class GpuVideoDecodeAccelerator::MessageFilter
- : public IPC::ChannelProxy::MessageFilter {
+class GpuVideoDecodeAccelerator::MessageFilter : public IPC::MessageFilter {
public:
MessageFilter(GpuVideoDecodeAccelerator* owner, int32 host_route_id)
: owner_(owner), host_route_id_(host_route_id) {}
int32 host_route_id,
GpuCommandBufferStub* stub,
const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
- : init_done_msg_(NULL),
- host_route_id_(host_route_id),
+ : host_route_id_(host_route_id),
stub_(stub),
texture_target_(0),
filter_removed_(true, false),
weak_factory_for_io_(this) {
DCHECK(stub_);
stub_->AddDestructionObserver(this);
- stub_->channel()->AddRoute(host_route_id_, this);
child_message_loop_ = base::MessageLoopProxy::current();
make_context_current_ =
base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
// This class can only be self-deleted from OnWillDestroyStub(), which means
// the VDA has already been destroyed in there.
- CHECK(!video_decode_accelerator_.get());
+ DCHECK(!video_decode_accelerator_);
}
bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
void GpuVideoDecodeAccelerator::NotifyError(
media::VideoDecodeAccelerator::Error error) {
- if (init_done_msg_) {
- // If we get an error while we're initializing, NotifyInitializeDone won't
- // be called, so we need to send the reply (with an error) here.
- GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(
- init_done_msg_, -1);
- if (!Send(init_done_msg_))
- DLOG(ERROR) << "Send(init_done_msg_) failed";
- init_done_msg_ = NULL;
- return;
- }
if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification(
host_route_id_, error))) {
DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) "
const media::VideoCodecProfile profile,
IPC::Message* init_done_msg) {
DCHECK(!video_decode_accelerator_.get());
- DCHECK(!init_done_msg_);
- DCHECK(init_done_msg);
- init_done_msg_ = init_done_msg;
+
+ if (!stub_->channel()->AddRoute(host_route_id_, this)) {
+ DLOG(ERROR) << "GpuVideoDecodeAccelerator::Initialize(): "
+ "failed to add route";
+ SendCreateDecoderReply(init_done_msg, false);
+ }
#if !defined(OS_WIN)
// Ensure we will be able to get a GL context at all before initializing
// non-Windows VDAs.
if (!make_context_current_.Run()) {
- NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
+ SendCreateDecoderReply(init_done_msg, false);
return;
}
#endif
#if defined(OS_WIN)
if (base::win::GetVersion() < base::win::VERSION_WIN7) {
NOTIMPLEMENTED() << "HW video decode acceleration not available.";
- NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
+ SendCreateDecoderReply(init_done_msg, false);
return;
}
DVLOG(0) << "Initializing DXVA HW decoder for windows.";
video_decode_accelerator_.reset(
new DXVAVideoDecodeAccelerator(make_context_current_));
#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
- scoped_ptr<V4L2Device> device = V4L2Device::Create();
+ scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
if (!device.get()) {
- NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
+ SendCreateDecoderReply(init_done_msg, false);
return;
}
- video_decode_accelerator_.reset(
- new V4L2VideoDecodeAccelerator(gfx::GLSurfaceEGL::GetHardwareDisplay(),
- weak_factory_for_io_.GetWeakPtr(),
- make_context_current_,
- device.Pass(),
- io_message_loop_));
+ video_decode_accelerator_.reset(new V4L2VideoDecodeAccelerator(
+ gfx::GLSurfaceEGL::GetHardwareDisplay(),
+ stub_->decoder()->GetGLContext()->GetHandle(),
+ weak_factory_for_io_.GetWeakPtr(),
+ make_context_current_,
+ device.Pass(),
+ io_message_loop_));
+#elif defined(ARCH_CPU_X86_FAMILY) && defined(USE_OZONE)
+ video_decode_accelerator_.reset(new VaapiVideoDecodeAccelerator(
+ make_context_current_));
#elif defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11)
if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
VLOG(1) << "HW video decode acceleration not available without "
"DesktopGL (GLX).";
- NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
+ SendCreateDecoderReply(init_done_msg, false);
return;
}
gfx::GLContextGLX* glx_context =
make_context_current_));
#else
NOTIMPLEMENTED() << "HW video decode acceleration not available.";
- NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
+ SendCreateDecoderReply(init_done_msg, false);
return;
#endif
stub_->channel()->AddFilter(filter_.get());
}
- if (!video_decode_accelerator_->Initialize(profile, this))
- NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
+ if (!video_decode_accelerator_->Initialize(profile, this)) {
+ SendCreateDecoderReply(init_done_msg, false);
+ return;
+ }
+
+ SendCreateDecoderReply(init_done_msg, true);
}
// Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is
}
}
-void GpuVideoDecodeAccelerator::NotifyInitializeDone() {
- GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(
- init_done_msg_, host_route_id_);
- if (!Send(init_done_msg_))
- DLOG(ERROR) << "Send(init_done_msg_) failed";
- init_done_msg_ = NULL;
-}
-
void GpuVideoDecodeAccelerator::NotifyFlushDone() {
if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_)))
DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed";
delete this;
}
-bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
- if (filter_.get() && io_message_loop_->BelongsToCurrentThread())
- return filter_->SendOnIOThread(message);
- DCHECK(child_message_loop_->BelongsToCurrentThread());
- return stub_->channel()->Send(message);
-}
-
void GpuVideoDecodeAccelerator::SetTextureCleared(
const media::Picture& picture) {
DCHECK(child_message_loop_->BelongsToCurrentThread());
uncleared_textures_.erase(it);
}
+bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
+ if (filter_.get() && io_message_loop_->BelongsToCurrentThread())
+ return filter_->SendOnIOThread(message);
+ DCHECK(child_message_loop_->BelongsToCurrentThread());
+ return stub_->channel()->Send(message);
+}
+
+void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message,
+ bool succeeded) {
+ GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded);
+ Send(message);
+}
+
} // namespace content