diff options
author | vrk@google.com <vrk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-10 18:40:29 +0000 |
---|---|---|
committer | vrk@google.com <vrk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-10 18:40:29 +0000 |
commit | d2f777617b4c8873e6b72dcd3a0fd6809f7e4dbb (patch) | |
tree | 811d79f44b066d8ac7e837d287b2304a81774b6c | |
parent | 484372884fa6236934471d00e84b23c26e1a22a7 (diff) | |
download | chromium_src-d2f777617b4c8873e6b72dcd3a0fd6809f7e4dbb.zip chromium_src-d2f777617b4c8873e6b72dcd3a0fd6809f7e4dbb.tar.gz chromium_src-d2f777617b4c8873e6b72dcd3a0fd6809f7e4dbb.tar.bz2 |
Implement AssignGLESBuffers for VideoDecode PPAPI
Fills in implementation for AssignGLESBuffers where it was missing. Also
updates OmxVideoDecodeAccelerator to reflect the changes.
BUG=NONE
TEST=NONE
Review URL: http://codereview.chromium.org/6965010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@88698 0039d316-1c4b-4281-b951-d872f2087c98
34 files changed, 440 insertions, 161 deletions
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc index 72d822b..b7a8349 100644 --- a/content/common/gpu/gpu_channel.cc +++ b/content/common/gpu/gpu_channel.cc @@ -18,6 +18,7 @@ #include "content/common/gpu/gpu_messages.h" #include "content/common/gpu/gpu_video_service.h" #include "content/common/gpu/transport_texture.h" +#include "ui/gfx/gl/gl_context.h" #include "ui/gfx/gl/gl_surface.h" #if defined(OS_POSIX) @@ -205,6 +206,8 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { OnDestroyVideoDecoder) IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture, OnCreateTransportTexture) + IPC_MESSAGE_HANDLER(GpuChannelMsg_AssignTexturesToVideoDecoder, + OnAssignTexturesToVideoDecoder) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() DCHECK(handled); @@ -295,24 +298,26 @@ void GpuChannel::OnDestroySurface(int route_id) { #endif } -void GpuChannel::OnCreateVideoDecoder( - int32 decoder_host_id, const std::vector<uint32>& configs) { -// TODO(cevans): do NOT re-enable this until GpuVideoService has been checked -// for integer overflows, including the classic "width * height" overflow. -#if 0 - VLOG(1) << "GpuChannel::OnCreateVideoDecoder"; +void GpuChannel::OnCreateVideoDecoder(int32 decoder_host_id, + uint32 command_buffer_route_id, + const std::vector<uint32>& configs) { GpuVideoService* service = GpuVideoService::GetInstance(); if (service == NULL) { // TODO(hclam): Need to send a failure message. return; } + GpuCommandBufferStub* stub = stubs_.Lookup(command_buffer_route_id); + // TODO(vrk): Need to notify renderer that given route is invalid. + if (!stub) + return; + int32 decoder_id = GenerateRouteID(); bool ret = service->CreateVideoDecoder( - this, &router_, decoder_host_id, decoder_id, configs); + this, &router_, decoder_host_id, decoder_id, stub->scheduler()->decoder(), + configs); DCHECK(ret) << "Failed to create a GpuVideoDecodeAccelerator"; -#endif } void GpuChannel::OnDestroyVideoDecoder(int32 decoder_id) { @@ -341,7 +346,16 @@ void GpuChannel::OnCreateTransportTexture(int32 context_route_id, host_id, route_id); Send(msg); #endif - } +} + +void GpuChannel::OnAssignTexturesToVideoDecoder( + int32 decoder_id, + const std::vector<int32>& buffer_ids, + const std::vector<uint32>& texture_ids, + const std::vector<gfx::Size>& sizes) { + GpuVideoService* service = GpuVideoService::GetInstance(); + service->AssignTexturesToDecoder(decoder_id, buffer_ids, texture_ids, sizes); +} bool GpuChannel::Init(base::MessageLoopProxy* io_message_loop, base::WaitableEvent* shutdown_event) { diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h index d0632bd..a7bf112 100644 --- a/content/common/gpu/gpu_channel.h +++ b/content/common/gpu/gpu_channel.h @@ -127,10 +127,16 @@ class GpuChannel : public IPC::Channel::Listener, void OnDestroySurface(int route_id); void OnCreateVideoDecoder(int32 decoder_host_id, + uint32 command_buffer_route_id, const std::vector<uint32>& configs); void OnDestroyVideoDecoder(int32 decoder_id); void OnCreateTransportTexture(int32 context_route_id, int32 host_id); + void OnAssignTexturesToVideoDecoder(int32 decoder_id, + const std::vector<int32>& buffer_ids, + const std::vector<uint32>& texture_ids, + const std::vector<gfx::Size>& sizes); + // The lifetime of objects of this class is managed by a GpuChannelManager. // The GpuChannelManager destroy all the GpuChannels that they own when they // are destroyed. So a raw pointer is safe. diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 98f838e..bd390c2 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -261,8 +261,9 @@ IPC_MESSAGE_CONTROL1(GpuChannelMsg_DestroySurface, // Create hardware video decoder && associate it with the output |decoder_id|; // We need this to be control message because we had to map the GpuChannel and // |decoder_id|. -IPC_MESSAGE_CONTROL2(GpuChannelMsg_CreateVideoDecoder, +IPC_MESSAGE_CONTROL3(GpuChannelMsg_CreateVideoDecoder, int32, /* decoder_id */ + uint32, /* command buffer route id*/ std::vector<uint32>) /* configs */ // Release all resource of the hardware video decoder which was assocaited @@ -276,6 +277,13 @@ IPC_MESSAGE_CONTROL2(GpuChannelMsg_CreateTransportTexture, int32, /* context_route_id */ int32 /* host_id */) +// Sent from Renderer process to the GPU process to give the texture IDs for +// the textures the decoder will use for output. +IPC_MESSAGE_CONTROL4(GpuChannelMsg_AssignTexturesToVideoDecoder, + int32, /* Decoder ID */ + std::vector<int32>, /* Picture buffer ID */ + std::vector<uint32>, /* Texture ID */ + std::vector<gfx::Size>) /* Size */ //------------------------------------------------------------------------------ // GPU Command Buffer Messages // These are messages between a renderer process to the GPU process relating to @@ -416,14 +424,6 @@ IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderMsg_Decode, base::SharedMemoryHandle, /* input_buffer_handle */ int32) /* size */ -// Sent from Renderer process to the GPU process to give the texture IDs for -// the textures the decoder will use for output. -IPC_MESSAGE_ROUTED4(AcceleratedVideoDecoderMsg_AssignGLESBuffers, - std::vector<int32>, /* Picture buffer ID */ - std::vector<uint32>, /* Texture ID */ - std::vector<uint32>, /* Context ID */ - std::vector<gfx::Size>) /* Size */ - // Sent from Renderer process to the GPU process to give the system memory // buffers that the decoder will use for output. // diff --git a/content/common/gpu/gpu_video_decode_accelerator.cc b/content/common/gpu/gpu_video_decode_accelerator.cc index 646fd57..5a19b8a 100644 --- a/content/common/gpu/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/gpu_video_decode_accelerator.cc @@ -32,8 +32,6 @@ bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode) IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignSysmemBuffers, OnAssignSysmemBuffers) - IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignGLESBuffers, - OnAssignGLESBuffers) IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer, OnReusePictureBuffer) IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, OnFlush) @@ -122,13 +120,11 @@ void GpuVideoDecodeAccelerator::OnDecode(int32 id, video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); } -void GpuVideoDecodeAccelerator::OnAssignGLESBuffers( - const std::vector<int32> buffer_ids, - const std::vector<uint32> texture_ids, - const std::vector<uint32> context_ids, - const std::vector<gfx::Size> sizes) { - // TODO(vrk): Implement. - NOTIMPLEMENTED(); +void GpuVideoDecodeAccelerator::AssignGLESBuffers( + const std::vector<media::GLESBuffer>& buffers) { + if (!video_decode_accelerator_.get()) + return; + video_decode_accelerator_->AssignGLESBuffers(buffers); } void GpuVideoDecodeAccelerator::OnAssignSysmemBuffers( diff --git a/content/common/gpu/gpu_video_decode_accelerator.h b/content/common/gpu/gpu_video_decode_accelerator.h index 383cbc9..ffa855a 100644 --- a/content/common/gpu/gpu_video_decode_accelerator.h +++ b/content/common/gpu/gpu_video_decode_accelerator.h @@ -50,16 +50,14 @@ class GpuVideoDecodeAccelerator video_decode_accelerator_.reset(accelerator); } + void AssignGLESBuffers(const std::vector<media::GLESBuffer>& buffers); + private: // Handlers for IPC messages. void OnGetConfigs(const std::vector<uint32>& config, std::vector<uint32>* configs); void OnInitialize(const std::vector<uint32>& configs); void OnDecode(int32 id, base::SharedMemoryHandle handle, int32 size); - void OnAssignGLESBuffers(const std::vector<int32> buffer_ids, - const std::vector<uint32> texture_ids, - const std::vector<uint32> context_ids, - const std::vector<gfx::Size> sizes); void OnAssignSysmemBuffers(const std::vector<int32> buffer_ids, const std::vector<base::SharedMemoryHandle> data, const std::vector<gfx::Size> sizes); diff --git a/content/common/gpu/gpu_video_service.cc b/content/common/gpu/gpu_video_service.cc index 26814f5..9b5c0e6 100644 --- a/content/common/gpu/gpu_video_service.cc +++ b/content/common/gpu/gpu_video_service.cc @@ -7,9 +7,11 @@ #include "content/common/gpu/gpu_channel.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/gpu/gpu_video_decode_accelerator.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) #include "content/common/gpu/omx_video_decode_accelerator.h" +#include "ui/gfx/gl/gl_surface_egl.h" #endif // defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) GpuVideoService::GpuVideoService() { @@ -57,16 +59,23 @@ bool GpuVideoService::CreateVideoDecoder( MessageRouter* router, int32 decoder_host_id, int32 decoder_id, + gpu::gles2::GLES2Decoder* command_decoder, const std::vector<uint32>& configs) { // Create GpuVideoDecodeAccelerator and add to map. scoped_refptr<GpuVideoDecodeAccelerator> decoder = new GpuVideoDecodeAccelerator(channel, decoder_host_id); + #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) - decoder->set_video_decode_accelerator( - new OmxVideoDecodeAccelerator(decoder, MessageLoop::current())); + OmxVideoDecodeAccelerator* omx_decoder = + new OmxVideoDecodeAccelerator(decoder, MessageLoop::current()); + omx_decoder->SetEglState(gfx::GLSurfaceEGL::GetDisplay(), + command_decoder->GetGLContext()->GetHandle()); + decoder->set_video_decode_accelerator(omx_decoder); + #endif // defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) - bool result = decoder_map_.insert(std::make_pair(decoder_id, decoder)).second; + bool result = decoder_map_.insert(std::make_pair( + decoder_id, VideoDecoderInfo(decoder, command_decoder))).second; // Decoder ID is a unique ID determined by GpuVideoServiceHost. // We should always be adding entries here. @@ -88,3 +97,35 @@ void GpuVideoService::DestroyVideoDecoder( router->RemoveRoute(decoder_id); decoder_map_.erase(decoder_id); } + +void GpuVideoService::AssignTexturesToDecoder( + int32 decoder_id, + const std::vector<int32>& buffer_ids, + const std::vector<uint32>& texture_ids, + const std::vector<gfx::Size>& sizes) { + std::vector<media::GLESBuffer> buffers; + for (uint32 i = 0; i < buffer_ids.size(); ++i) { + uint32 service_texture_id; + bool result = TranslateTextureForDecoder( + decoder_id, texture_ids[i], &service_texture_id); + // TODO(vrk): Send an error for invalid GLES buffers. + if (!result) + return; + buffers.push_back( + media::GLESBuffer(buffer_ids[i], sizes[i], service_texture_id)); + } + + DecoderMap::iterator it = decoder_map_.find(decoder_id); + DCHECK(it != decoder_map_.end()); + it->second.video_decoder->AssignGLESBuffers(buffers); +} + +bool GpuVideoService::TranslateTextureForDecoder( + int32 decoder_id, uint32 client_texture_id, uint32* service_texture_id) { + DecoderMap::iterator it = decoder_map_.find(decoder_id); + if (it == decoder_map_.end()) + return false; + it->second.command_decoder->MakeCurrent(); + return it->second.command_decoder->GetServiceTextureId( + client_texture_id, service_texture_id); +} diff --git a/content/common/gpu/gpu_video_service.h b/content/common/gpu/gpu_video_service.h index 44090c4..43e5833 100644 --- a/content/common/gpu/gpu_video_service.h +++ b/content/common/gpu/gpu_video_service.h @@ -12,6 +12,12 @@ #include "content/common/gpu/gpu_video_decode_accelerator.h" #include "ipc/ipc_channel.h" +namespace gpu { +namespace gles2 { +class GLES2Decoder; +} // namespace gles2 +} // namespace gpu + class GpuChannel; class MessageRouter; @@ -29,20 +35,43 @@ class GpuVideoService : public IPC::Channel::Listener { MessageRouter* router, int32 decoder_host_id, int32 decoder_id, + gpu::gles2::GLES2Decoder* command_decoder, const std::vector<uint32>& configs); void DestroyVideoDecoder(MessageRouter* router, int32 decoder_id); + // Passes given GLES textures to the decoder indicated by id. + void AssignTexturesToDecoder(int32 decoder_id, + const std::vector<int32>& buffer_ids, + const std::vector<uint32>& texture_ids, + const std::vector<gfx::Size>& sizes); + private: + struct VideoDecoderInfo { + VideoDecoderInfo(scoped_refptr<GpuVideoDecodeAccelerator> g_v_d_a, + gpu::gles2::GLES2Decoder* g_d) + : video_decoder(g_v_d_a), + command_decoder(g_d) {} + scoped_refptr<GpuVideoDecodeAccelerator> video_decoder; + gpu::gles2::GLES2Decoder* command_decoder; + }; + // Map of video and command buffer decoders, indexed by video decoder id. + typedef std::map<int32, VideoDecoderInfo> DecoderMap; + GpuVideoService(); virtual ~GpuVideoService(); - std::map<int32, scoped_refptr<GpuVideoDecodeAccelerator> > decoder_map_; - // Specialize video service on different platform will override. virtual bool IntializeGpuVideoService(); virtual bool UnintializeGpuVideoService(); + // Translates a given client texture id to the "real" texture id as recognized + // in the GPU process. + bool TranslateTextureForDecoder( + int32 decoder_id, uint32 client_texture_id, uint32* service_texture_id); + + DecoderMap decoder_map_; + friend struct DefaultSingletonTraits<GpuVideoService>; DISALLOW_COPY_AND_ASSIGN(GpuVideoService); }; diff --git a/content/common/gpu/omx_video_decode_accelerator_unittest.cc b/content/common/gpu/omx_video_decode_accelerator_unittest.cc index 691d6da..fb358bc 100644 --- a/content/common/gpu/omx_video_decode_accelerator_unittest.cc +++ b/content/common/gpu/omx_video_decode_accelerator_unittest.cc @@ -495,10 +495,8 @@ void EglRenderingVDAClient::ProvidePictureBuffers( base::WaitableEvent done(false, false); rendering_helper_->CreateTexture(rendering_window_id_, &texture_id, &done); done.Wait(); - // TODO(fischman): context_id is always 0. Can it be removed from the API? - // (since it's always inferrable from context). media::GLESBuffer* buffer = - new media::GLESBuffer(id, dimensions, texture_id, 0 /* context_id */); + new media::GLESBuffer(id, dimensions, texture_id); CHECK(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second); buffers.push_back(*buffer); } diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc index 4ca5ca6..8a03cda 100644 --- a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc +++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc @@ -19,11 +19,13 @@ GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( MessageRouter* router, IPC::Message::Sender* ipc_sender, int32 decoder_host_id, + uint32 command_buffer_route_id, VideoDecodeAccelerator::Client* client) : router_(router), ipc_sender_(ipc_sender), decoder_host_id_(decoder_host_id), decoder_id_(0), + command_buffer_route_id_(command_buffer_route_id), client_(client) { } @@ -79,7 +81,7 @@ bool GpuVideoDecodeAcceleratorHost::Initialize( configs_ = configs; if (!ipc_sender_->Send(new GpuChannelMsg_CreateVideoDecoder( - decoder_id_, configs))) { + decoder_id_, command_buffer_route_id_, configs))) { LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed"; return false; } @@ -103,17 +105,15 @@ void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers( // Rearrange data for IPC command. std::vector<int32> buffer_ids; std::vector<uint32> texture_ids; - std::vector<uint32> context_ids; std::vector<gfx::Size> sizes; for (uint32 i = 0; i < buffers.size(); i++) { const media::GLESBuffer& buffer = buffers[i]; texture_ids.push_back(buffer.texture_id()); - context_ids.push_back(buffer.context_id()); buffer_ids.push_back(buffer.id()); sizes.push_back(buffer.size()); } - if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_AssignGLESBuffers( - decoder_id_, buffer_ids, texture_ids, context_ids, sizes))) { + if (!ipc_sender_->Send(new GpuChannelMsg_AssignTexturesToVideoDecoder( + decoder_id_, buffer_ids, texture_ids, sizes))) { LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_AssignGLESBuffers) failed"; } } diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.h b/content/renderer/gpu/gpu_video_decode_accelerator_host.h index a7ac98f..8b4a4c3 100644 --- a/content/renderer/gpu/gpu_video_decode_accelerator_host.h +++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.h @@ -25,6 +25,7 @@ class GpuVideoDecodeAcceleratorHost : public IPC::Channel::Listener, GpuVideoDecodeAcceleratorHost(MessageRouter* router, IPC::Message::Sender* ipc_sender, int32 decoder_host_id, + uint32 command_buffer_route_id, media::VideoDecodeAccelerator::Client* client); virtual ~GpuVideoDecodeAcceleratorHost(); @@ -75,6 +76,10 @@ class GpuVideoDecodeAcceleratorHost : public IPC::Channel::Listener, // ID of VideoDecodeAccelerator in the Gpu process. int32 decoder_id_; + // Route ID for the command buffer associated with the context the GPU Video + // Decoder uses. + uint32 command_buffer_route_id_; + // Temporarily store configs here in between Create and Initialize phase. std::vector<uint32> configs_; diff --git a/content/renderer/gpu/gpu_video_service_host.cc b/content/renderer/gpu/gpu_video_service_host.cc index 0c629f8..9b3fe22 100644 --- a/content/renderer/gpu/gpu_video_service_host.cc +++ b/content/renderer/gpu/gpu_video_service_host.cc @@ -71,9 +71,11 @@ void GpuVideoServiceHost::SetOnInitialized( } GpuVideoDecodeAcceleratorHost* GpuVideoServiceHost::CreateVideoAccelerator( - media::VideoDecodeAccelerator::Client* client) { + media::VideoDecodeAccelerator::Client* client, + int command_buffer_route_id) { base::AutoLock auto_lock(lock_); DCHECK(channel_); return new GpuVideoDecodeAcceleratorHost( - &router_, channel_, next_decoder_host_id_++, client); + &router_, channel_, next_decoder_host_id_++, + command_buffer_route_id, client); } diff --git a/content/renderer/gpu/gpu_video_service_host.h b/content/renderer/gpu/gpu_video_service_host.h index be3e44b..83028c11 100644 --- a/content/renderer/gpu/gpu_video_service_host.h +++ b/content/renderer/gpu/gpu_video_service_host.h @@ -37,7 +37,8 @@ class GpuVideoServiceHost : public IPC::ChannelProxy::MessageFilter { // Called on RenderThread to create a hardware accelerated video decoder // in the GPU process. GpuVideoDecodeAcceleratorHost* CreateVideoAccelerator( - media::VideoDecodeAccelerator::Client* client); + media::VideoDecodeAccelerator::Client* client, + int command_buffer_route_id); private: // Guards all members other than |router_|. diff --git a/content/renderer/pepper_platform_context_3d_impl.cc b/content/renderer/pepper_platform_context_3d_impl.cc index 5b7a59a..acd19f6 100644 --- a/content/renderer/pepper_platform_context_3d_impl.cc +++ b/content/renderer/pepper_platform_context_3d_impl.cc @@ -103,8 +103,13 @@ gpu::CommandBuffer* PlatformContext3DImpl::GetCommandBuffer() { return command_buffer_; } +int PlatformContext3DImpl::GetCommandBufferRouteId() { + DCHECK(command_buffer_); + return command_buffer_->route_id(); +} + void PlatformContext3DImpl::SetContextLostCallback(Callback0::Type* callback) { - context_lost_callback_.reset(callback); + context_lost_callback_.reset(callback); } void PlatformContext3DImpl::OnContextLost() { diff --git a/content/renderer/pepper_platform_context_3d_impl.h b/content/renderer/pepper_platform_context_3d_impl.h index 9968217..c1a34aa 100644 --- a/content/renderer/pepper_platform_context_3d_impl.h +++ b/content/renderer/pepper_platform_context_3d_impl.h @@ -32,6 +32,7 @@ class PlatformContext3DImpl virtual void SetSwapBuffersCallback(Callback0::Type* callback); virtual unsigned GetBackingTextureId(); virtual gpu::CommandBuffer* GetCommandBuffer(); + virtual int GetCommandBufferRouteId(); virtual void SetContextLostCallback(Callback0::Type* callback); private: diff --git a/content/renderer/pepper_platform_video_decoder_impl.cc b/content/renderer/pepper_platform_video_decoder_impl.cc index 7873bcf..27fd963 100644 --- a/content/renderer/pepper_platform_video_decoder_impl.cc +++ b/content/renderer/pepper_platform_video_decoder_impl.cc @@ -17,9 +17,11 @@ using media::BitstreamBuffer; PlatformVideoDecoderImpl::PlatformVideoDecoderImpl( - VideoDecodeAccelerator::Client* client) + VideoDecodeAccelerator::Client* client, uint32 command_buffer_route_id) : client_(client), - decoder_(NULL) { + command_buffer_route_id_(command_buffer_route_id), + decoder_(NULL), + message_loop_(NULL) { DCHECK(client); } @@ -39,6 +41,8 @@ bool PlatformVideoDecoderImpl::Initialize(const std::vector<uint32>& config) { RenderThread* render_thread = RenderThread::current(); DCHECK(render_thread); + message_loop_ = MessageLoop::current(); + DCHECK(message_loop_); channel_ = render_thread->EstablishGpuChannelSync( content::CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE); @@ -72,7 +76,8 @@ void PlatformVideoDecoderImpl::InitializeDecoder( return; } GpuVideoServiceHost* video_service = channel_->gpu_video_service_host(); - decoder_.reset(video_service->CreateVideoAccelerator(this)); + decoder_.reset(video_service->CreateVideoAccelerator( + this, command_buffer_route_id_)); // Send IPC message to initialize decoder in GPU process. decoder_->Initialize(configs); @@ -136,6 +141,13 @@ void PlatformVideoDecoderImpl::PictureReady(const media::Picture& picture) { } void PlatformVideoDecoderImpl::NotifyInitializeDone() { + if (message_loop_ != MessageLoop::current() ) { + message_loop_-> + PostTask(FROM_HERE, base::Bind( + &PlatformVideoDecoderImpl::NotifyInitializeDone, + base::Unretained(this))); + return; + } client_->NotifyInitializeDone(); } diff --git a/content/renderer/pepper_platform_video_decoder_impl.h b/content/renderer/pepper_platform_video_decoder_impl.h index 4588ea7..eb8bf4e 100644 --- a/content/renderer/pepper_platform_video_decoder_impl.h +++ b/content/renderer/pepper_platform_video_decoder_impl.h @@ -9,6 +9,7 @@ #include "base/scoped_ptr.h" #include "base/memory/ref_counted.h" +#include "base/message_loop.h" #include "media/video/video_decode_accelerator.h" #include "webkit/plugins/ppapi/plugin_delegate.h" @@ -20,7 +21,8 @@ class PlatformVideoDecoderImpl public base::RefCountedThreadSafe<PlatformVideoDecoderImpl> { public: explicit PlatformVideoDecoderImpl( - media::VideoDecodeAccelerator::Client* client); + media::VideoDecodeAccelerator::Client* client, + uint32 command_buffer_route_id); virtual ~PlatformVideoDecoderImpl(); // PlatformVideoDecoder implementation. @@ -59,12 +61,18 @@ class PlatformVideoDecoderImpl // Client lifetime must exceed lifetime of this class. media::VideoDecodeAccelerator::Client* client_; + // Route ID for the command buffer associated with video decoder's context. + uint32 command_buffer_route_id_; + // Host for GpuVideoDecodeAccelerator. scoped_ptr<media::VideoDecodeAccelerator> decoder_; // Host for Gpu Channel. scoped_refptr<GpuChannelHost> channel_; + // Message loop on which plugin is initialized. + MessageLoop* message_loop_; + DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl); }; diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc index 918ec5b..4367c4e 100644 --- a/content/renderer/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper_plugin_delegate_impl.cc @@ -828,8 +828,9 @@ webkit::ppapi::PluginDelegate::PlatformContext3D* webkit::ppapi::PluginDelegate::PlatformVideoDecoder* PepperPluginDelegateImpl::CreateVideoDecoder( - media::VideoDecodeAccelerator::Client* client) { - return new PlatformVideoDecoderImpl(client); + media::VideoDecodeAccelerator::Client* client, + int command_buffer_route_id) { + return new PlatformVideoDecoderImpl(client, command_buffer_route_id); } void PepperPluginDelegateImpl::NumberOfFindResultsChanged(int identifier, diff --git a/content/renderer/pepper_plugin_delegate_impl.h b/content/renderer/pepper_plugin_delegate_impl.h index 8f66680..2c7bf47 100644 --- a/content/renderer/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper_plugin_delegate_impl.h @@ -179,7 +179,8 @@ class PepperPluginDelegateImpl virtual PlatformImage2D* CreateImage2D(int width, int height); virtual PlatformContext3D* CreateContext3D(); virtual PlatformVideoDecoder* CreateVideoDecoder( - media::VideoDecodeAccelerator::Client* client); + media::VideoDecodeAccelerator::Client* client, + int command_buffer_route_id); virtual PpapiBroker* ConnectToPpapiBroker( webkit::ppapi::PPB_Broker_Impl* client); virtual void NumberOfFindResultsChanged(int identifier, diff --git a/media/video/picture.cc b/media/video/picture.cc index f2d6632..60fd3f5 100644 --- a/media/video/picture.cc +++ b/media/video/picture.cc @@ -15,9 +15,9 @@ BaseBuffer::~BaseBuffer() {} BaseBuffer::BaseBuffer(int32 id, gfx::Size size) : id_(id), size_(size) { } -GLESBuffer::GLESBuffer( - int32 id, gfx::Size size, uint32 texture_id, uint32 context_id) - : BaseBuffer(id, size), texture_id_(texture_id), context_id_(context_id) { +GLESBuffer::GLESBuffer(int32 id, gfx::Size size, uint32 texture_id) + : BaseBuffer(id, size), + texture_id_(texture_id) { } SysmemBuffer::SysmemBuffer(int32 id, gfx::Size size, void* data) diff --git a/media/video/picture.h b/media/video/picture.h index e268c51..e28a5c4 100644 --- a/media/video/picture.h +++ b/media/video/picture.h @@ -6,6 +6,7 @@ #define MEDIA_VIDEO_PICTURE_H_ #include "base/basictypes.h" +#include "ui/gfx/gl/gl_context.h" #include "ui/gfx/size.h" struct PP_BufferInfo_Dev; @@ -42,24 +43,18 @@ class BaseBuffer { // This is the media-namespace equivalent of PP_GLESBuffer_Dev. class GLESBuffer : public BaseBuffer { public: - GLESBuffer(int32 id, gfx::Size size, uint32 texture_id, uint32 context_id); + GLESBuffer(int32 id, gfx::Size size, uint32 texture_id); GLESBuffer(const PP_GLESBuffer_Dev& buffer); // Returns the id of the texture. + // NOTE: The texture id in the renderer process corresponds to a different + // texture id in the GPU process. uint32 texture_id() const { return texture_id_; } - // Returns the id of the context in which this texture lives. - // TODO(vrk): I'm not sure if "id" is what we want, or some reference to the - // PPB_Context3D_Dev. Not sure how this eventually gets used. - uint32 context_id() const { - return context_id_; - } - private: uint32 texture_id_; - uint32 context_id_; }; // A picture buffer that lives in system memory. diff --git a/ppapi/c/dev/pp_video_dev.h b/ppapi/c/dev/pp_video_dev.h index 4bf1cf3..8833818 100644 --- a/ppapi/c/dev/pp_video_dev.h +++ b/ppapi/c/dev/pp_video_dev.h @@ -201,9 +201,6 @@ struct PP_BufferInfo_Dev { // Struct for specifying texture-backed picture data. struct PP_GLESBuffer_Dev { - // Context allocated using PPB_Context3D_Dev. - PP_Resource context; - // Texture ID in the given context where picture is stored. GLuint texture_id; diff --git a/ppapi/c/dev/ppb_video_decoder_dev.h b/ppapi/c/dev/ppb_video_decoder_dev.h index 4ec65df..7f59df1 100644 --- a/ppapi/c/dev/ppb_video_decoder_dev.h +++ b/ppapi/c/dev/ppb_video_decoder_dev.h @@ -9,8 +9,8 @@ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_var.h" -#define PPB_VIDEODECODER_DEV_INTERFACE_0_8 "PPB_VideoDecoder(Dev);0.8" -#define PPB_VIDEODECODER_DEV_INTERFACE PPB_VIDEODECODER_DEV_INTERFACE_0_8 +#define PPB_VIDEODECODER_DEV_INTERFACE_0_9 "PPB_VideoDecoder(Dev);0.9" +#define PPB_VIDEODECODER_DEV_INTERFACE PPB_VIDEODECODER_DEV_INTERFACE_0_9 // Video decoder interface. // @@ -139,11 +139,14 @@ struct PPB_VideoDecoder_Dev { // // Parameters: // |video_decoder| is the previously created handle to the decoder resource. + // |context| the GL context in which decoding will happen. This should be a + // resource of type PPB_Context3D_Dev. // |decoder_config| the configuration to use to initialize the decoder. // |callback| called after initialization is complete. // // Returns an error code from pp_errors.h. int32_t (*Initialize)(PP_Resource video_decoder, + PP_Resource context, const PP_VideoConfigElement* decoder_config, struct PP_CompletionCallback callback); diff --git a/ppapi/c/dev/ppp_video_decoder_dev.h b/ppapi/c/dev/ppp_video_decoder_dev.h index af5eaaf..e18146d 100644 --- a/ppapi/c/dev/ppp_video_decoder_dev.h +++ b/ppapi/c/dev/ppp_video_decoder_dev.h @@ -5,9 +5,11 @@ #ifndef PPAPI_C_DEV_PPP_VIDEO_DECODER_DEV_H_ #define PPAPI_C_DEV_PPP_VIDEO_DECODER_DEV_H_ +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" #include "ppapi/c/dev/pp_video_dev.h" -#define PPP_VIDEODECODER_DEV_INTERFACE "PPP_VideoDecoder(Dev);0.3" +#define PPP_VIDEODECODER_DEV_INTERFACE "PPP_VideoDecoder(Dev);0.4" // PPP_VideoDecoder_Dev structure contains the function pointers that the // plugin MUST implement to provide services needed by the video decoder @@ -21,11 +23,13 @@ struct PPP_VideoDecoder_Dev { // Decoding will not proceed until buffers have been provided. // // Parameters: - // |decoder| is pointer to the Pepper Video Decoder instance. + // |instance| the plugin instance to which the callback is responding. + // |decoder| is pointer to the Pepper Video Decoder resource. // |req_num_of_bufs| tells how many buffers are needed by the decoder. // |dimensions| tells the dimensions of the buffer to allocate. // |type| specifies whether the buffer lives in system memory or GL texture. void (*ProvidePictureBuffers)( + PP_Instance instance, PP_Resource decoder, uint32_t req_num_of_bufs, struct PP_Size dimensions, @@ -35,9 +39,11 @@ struct PPP_VideoDecoder_Dev { // the plugin. // // Parameters: - // |decoder| is pointer to the Pepper Video Decoder instance. + // |instance| the plugin instance to which the callback is responding. + // |decoder| is pointer to the Pepper Video Decoder resource. // |picture_buffer| points to the picture buffer that is no longer needed. - void (*DismissPictureBuffer)(PP_Resource decoder, + void (*DismissPictureBuffer)(PP_Instance instance, + PP_Resource decoder, int32_t picture_buffer_id); // Callback function for decoder to deliver decoded pictures ready to be @@ -45,9 +51,11 @@ struct PPP_VideoDecoder_Dev { // decoder through ReusePictureBuffer function in PPB Video Decoder API. // // Parameters: - // |decoder| is pointer to the Pepper Video Decoder instance. + // |instance| the plugin instance to which the callback is responding. + // |decoder| is pointer to the Pepper Video Decoder resource. // |picture| is the picture that is ready. - void (*PictureReady)(PP_Resource decoder, + void (*PictureReady)(PP_Instance instance, + PP_Resource decoder, struct PP_Picture_Dev picture); // Callback function to tell the plugin that decoder has decoded end of stream @@ -55,8 +63,9 @@ struct PPP_VideoDecoder_Dev { // stream. // // Parameters: - // |decoder| is pointer to the Pepper Video Decoder instance. - void (*EndOfStream)(PP_Resource decoder); + // |instance| the plugin instance to which the callback is responding. + // |decoder| is pointer to the Pepper Video Decoder resource. + void (*EndOfStream)(PP_Instance instance, PP_Resource decoder); // Error handler callback for decoder to deliver information about detected // errors to the plugin. @@ -64,9 +73,12 @@ struct PPP_VideoDecoder_Dev { // TODO(vmr): Fill out error result codes and corresponding actions. // // Parameters: - // |decoder| is pointer to the Pepper Video Decoder instance. + // |instance| the plugin instance to which the callback is responding. + // |decoder| is pointer to the Pepper Video Decoder resource. // |error| error is the enumeration specifying the error. - void (*NotifyError)(PP_Resource decoder, enum PP_VideoDecodeError_Dev error); + void (*NotifyError)(PP_Instance instance, + PP_Resource decoder, + enum PP_VideoDecodeError_Dev error); }; #endif /* PPAPI_C_DEV_PPP_VIDEO_DECODER_DEV_H_ */ diff --git a/ppapi/cpp/dev/video_decoder_client_dev.cc b/ppapi/cpp/dev/video_decoder_client_dev.cc new file mode 100644 index 0000000..aa00c6f --- /dev/null +++ b/ppapi/cpp/dev/video_decoder_client_dev.cc @@ -0,0 +1,98 @@ +// Copyright (c) 2011 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 "ppapi/cpp/dev/video_decoder_client_dev.h" + +#include "ppapi/c/dev/ppp_video_decoder_dev.h" +#include "ppapi/cpp/dev/video_decoder_dev.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +const char kPPPVideoDecoderInterface[] = PPP_VIDEODECODER_DEV_INTERFACE; + +// Callback to provide buffers for the decoded output pictures. +void ProvidePictureBuffers(PP_Instance instance, + PP_Resource decoder_id, + uint32_t req_num_of_bufs, + struct PP_Size dimensions, + enum PP_PictureBufferType_Dev type) { + void* object = pp::Instance::GetPerInstanceObject( + instance, kPPPVideoDecoderInterface); + if (!object) + return; + static_cast<VideoDecoderClient_Dev*>(object)->ProvidePictureBuffers( + VideoDecoder_Dev(decoder_id), req_num_of_bufs, dimensions, type); +} + +void DismissPictureBuffer(PP_Instance instance, + PP_Resource decoder_id, + int32_t picture_buffer_id) { + void* object = pp::Instance::GetPerInstanceObject( + instance, kPPPVideoDecoderInterface); + if (!object) + return; + static_cast<VideoDecoderClient_Dev*>(object)->DismissPictureBuffer( + VideoDecoder_Dev(decoder_id), picture_buffer_id); +} + +void PictureReady(PP_Instance instance, + PP_Resource decoder_id, + PP_Picture_Dev picture) { + void* object = pp::Instance::GetPerInstanceObject( + instance, kPPPVideoDecoderInterface); + if (!object) + return; + static_cast<VideoDecoderClient_Dev*>(object)->PictureReady( + VideoDecoder_Dev(decoder_id), picture); +} + +void EndOfStream(PP_Instance instance, PP_Resource decoder_id) { + void* object = pp::Instance::GetPerInstanceObject( + instance, kPPPVideoDecoderInterface); + if (!object) + return; + static_cast<VideoDecoderClient_Dev*>(object)->EndOfStream( + VideoDecoder_Dev(decoder_id)); +} + +void NotifyError(PP_Instance instance, + PP_Resource decoder_id, + PP_VideoDecodeError_Dev error) { + void* object = pp::Instance::GetPerInstanceObject( + instance, kPPPVideoDecoderInterface); + if (!object) + return; + static_cast<VideoDecoderClient_Dev*>(object)->NotifyError( + VideoDecoder_Dev(decoder_id), error); +} + +static PPP_VideoDecoder_Dev videodecoder_interface = { + &ProvidePictureBuffers, + &DismissPictureBuffer, + &PictureReady, + &EndOfStream, + &NotifyError, +}; + +} // namespace + +VideoDecoderClient_Dev::VideoDecoderClient_Dev(Instance* instance) + : associated_instance_(instance) { + pp::Module::Get()->AddPluginInterface(kPPPVideoDecoderInterface, + &videodecoder_interface); + associated_instance_->AddPerInstanceObject( + kPPPVideoDecoderInterface, this); +} + +VideoDecoderClient_Dev::~VideoDecoderClient_Dev() { + associated_instance_->RemovePerInstanceObject( + kPPPVideoDecoderInterface, this); +} + +} // namespace pp diff --git a/ppapi/cpp/dev/video_decoder_client_dev.h b/ppapi/cpp/dev/video_decoder_client_dev.h new file mode 100644 index 0000000..776d54b --- /dev/null +++ b/ppapi/cpp/dev/video_decoder_client_dev.h @@ -0,0 +1,57 @@ +// Copyright (c) 2011 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 PPAPI_CPP_DEV_VIDEO_DECODER_CLIENT_DEV_H_ +#define PPAPI_CPP_DEV_VIDEO_DECODER_CLIENT_DEV_H_ + +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/dev/pp_video_dev.h" + +namespace pp { + +class Instance; +class VideoDecoder_Dev; + +// This class provides a C++ interface for callbacks related to video decoding. +// It is the C++ counterpart to PPP_VideoDecoder_Dev. +// You would normally use multiple inheritance to derive from this class in your +// instance. +class VideoDecoderClient_Dev { + public: + VideoDecoderClient_Dev(Instance* instance); + virtual ~VideoDecoderClient_Dev(); + + // Callback to provide buffers for the decoded output pictures. + virtual void ProvidePictureBuffers( + VideoDecoder_Dev decoder, + uint32_t req_num_of_bufs, + struct PP_Size dimensions, + enum PP_PictureBufferType_Dev type) = 0; + + // Callback for decoder to delivered unneeded picture buffers back to the + // plugin. + virtual void DismissPictureBuffer( + VideoDecoder_Dev decoder, + int32_t picture_buffer_id) = 0; + + // Callback to deliver decoded pictures ready to be displayed. + virtual void PictureReady( + VideoDecoder_Dev decoder, + const PP_Picture_Dev& picture) = 0; + + // Callback to notify that decoder has decoded end of stream marker and has + // outputted all displayable pictures. + virtual void EndOfStream(VideoDecoder_Dev decoder) = 0; + + // Callback to notify about decoding errors. + virtual void NotifyError( + VideoDecoder_Dev decoder, PP_VideoDecodeError_Dev error) = 0; + + private: + Instance* associated_instance_; +}; + +} // namespace pp + +#endif // PPAPI_CPP_DEV_VIDEO_DECODER_CLIENT_DEV_H_ diff --git a/ppapi/cpp/dev/video_decoder_dev.cc b/ppapi/cpp/dev/video_decoder_dev.cc index b1ebcfb..c8d6ff4 100644 --- a/ppapi/cpp/dev/video_decoder_dev.cc +++ b/ppapi/cpp/dev/video_decoder_dev.cc @@ -8,6 +8,7 @@ #include "ppapi/c/dev/ppp_video_decoder_dev.h" #include "ppapi/c/pp_errors.h" #include "ppapi/cpp/common.h" +#include "ppapi/cpp/dev/context_3d_dev.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" #include "ppapi/cpp/module_impl.h" @@ -22,37 +23,41 @@ template <> const char* interface_name<PPB_VideoDecoder_Dev>() { } // namespace -VideoDecoder::VideoDecoder(const Instance* instance, Client* client) - : client_(client) { +VideoDecoder_Dev::VideoDecoder_Dev(const Instance& instance) { if (!has_interface<PPB_VideoDecoder_Dev>()) return; PassRefFromConstructor(get_interface<PPB_VideoDecoder_Dev>()->Create( - instance->pp_instance())); + instance.pp_instance())); } -VideoDecoder::~VideoDecoder() {} +VideoDecoder_Dev::VideoDecoder_Dev(PP_Resource resource) : Resource(resource) { +} + +VideoDecoder_Dev::~VideoDecoder_Dev() {} -int32_t VideoDecoder::Initialize(const PP_VideoConfigElement* config, - CompletionCallback callback) { +int32_t VideoDecoder_Dev::Initialize(const PP_VideoConfigElement* config, + const Context3D_Dev& context, + CompletionCallback callback) { if (!has_interface<PPB_VideoDecoder_Dev>()) return PP_ERROR_NOINTERFACE; return get_interface<PPB_VideoDecoder_Dev>()->Initialize( - pp_resource(), config, callback.pp_completion_callback()); + pp_resource(), context.pp_resource(), config, + callback.pp_completion_callback()); } -bool VideoDecoder::GetConfigs(Instance* instance, - const PP_VideoConfigElement* prototype_config, - PP_VideoConfigElement* matching_configs, - uint32_t matching_configs_size, - uint32_t* num_of_matching_configs) { +bool VideoDecoder_Dev::GetConfigs(Instance* instance, + const PP_VideoConfigElement* prototype_config, + PP_VideoConfigElement* matching_configs, + uint32_t matching_configs_size, + uint32_t* num_of_matching_configs) { if (!has_interface<PPB_VideoDecoder_Dev>()) return false; return PPBoolToBool(get_interface<PPB_VideoDecoder_Dev>()->GetConfigs( - instance->pp_instance(), prototype_config, matching_configs, - matching_configs_size, num_of_matching_configs)); + instance->pp_instance(), prototype_config, matching_configs, + matching_configs_size, num_of_matching_configs)); } -void VideoDecoder::AssignGLESBuffers( +void VideoDecoder_Dev::AssignGLESBuffers( const std::vector<PP_GLESBuffer_Dev>& buffers) { if (!has_interface<PPB_VideoDecoder_Dev>() || !pp_resource()) return; @@ -60,7 +65,7 @@ void VideoDecoder::AssignGLESBuffers( pp_resource(), buffers.size(), &buffers[0]); } -void VideoDecoder::AssignSysmemBuffers( +void VideoDecoder_Dev::AssignSysmemBuffers( const std::vector<PP_SysmemBuffer_Dev>& buffers) { if (!has_interface<PPB_VideoDecoder_Dev>() || !pp_resource()) return; @@ -68,7 +73,7 @@ void VideoDecoder::AssignSysmemBuffers( pp_resource(), buffers.size(), &buffers[0]); } -int32_t VideoDecoder::Decode( +int32_t VideoDecoder_Dev::Decode( const PP_VideoBitstreamBuffer_Dev& bitstream_buffer, CompletionCallback callback) { if (!has_interface<PPB_VideoDecoder_Dev>()) @@ -79,14 +84,14 @@ int32_t VideoDecoder::Decode( pp_resource(), &bitstream_buffer, callback.pp_completion_callback()); } -void VideoDecoder::ReusePictureBuffer(int32_t picture_buffer_id) { +void VideoDecoder_Dev::ReusePictureBuffer(int32_t picture_buffer_id) { if (!has_interface<PPB_VideoDecoder_Dev>() || !pp_resource()) return; get_interface<PPB_VideoDecoder_Dev>()->ReusePictureBuffer( pp_resource(), picture_buffer_id); } -int32_t VideoDecoder::Flush(CompletionCallback callback) { +int32_t VideoDecoder_Dev::Flush(CompletionCallback callback) { if (!has_interface<PPB_VideoDecoder_Dev>()) return PP_ERROR_NOINTERFACE; if (!pp_resource()) @@ -95,7 +100,7 @@ int32_t VideoDecoder::Flush(CompletionCallback callback) { pp_resource(), callback.pp_completion_callback()); } -int32_t VideoDecoder::Abort(CompletionCallback callback) { +int32_t VideoDecoder_Dev::Abort(CompletionCallback callback) { if (!has_interface<PPB_VideoDecoder_Dev>()) return PP_ERROR_NOINTERFACE; if (!pp_resource()) diff --git a/ppapi/cpp/dev/video_decoder_dev.h b/ppapi/cpp/dev/video_decoder_dev.h index e6558b1..326604f 100644 --- a/ppapi/cpp/dev/video_decoder_dev.h +++ b/ppapi/cpp/dev/video_decoder_dev.h @@ -14,59 +14,33 @@ namespace pp { +class Context3D_Dev; class Instance; // C++ wrapper for the Pepper Video Decoder interface. For more detailed -// documentation refer to PPB_VideoDecoder_Dev and PPP_VideoDecoder_Dev -// interfaces. +// documentation refer to the C interfaces. // // C++ version of the PPB_VideoDecoder_Dev interface. -class VideoDecoder : public Resource { +class VideoDecoder_Dev : public Resource { public: - // C++ version of PPP_VideoDecoder_Dev interface. - class Client { - public: - virtual ~Client(); - - // Callback to provide buffers for the decoded output pictures. - virtual void ProvidePictureBuffers( - uint32_t req_num_of_bufs, - struct PP_Size dimensions, - enum PP_PictureBufferType_Dev type); - - // Callback for decoder to delivered unneeded picture buffers back to the - // plugin. - virtual void DismissPictureBuffer(int32_t picture_buffer_id) = 0; - - // Callback to deliver decoded pictures ready to be displayed. - virtual void PictureReady(const PP_Picture_Dev& picture) = 0; - - // Callback to notify that decoder has decoded end of stream marker and has - // outputted all displayable pictures. - virtual void EndOfStream() = 0; - - // Callback to notify about decoding errors. - virtual void NotifyError(PP_VideoDecodeError_Dev error) = 0; - }; - // Constructor for the video decoder. Calls the Create on the // PPB_VideoDecoder_Dev interface. // // Parameters: // |instance| is the pointer to the plug-in instance. - // |callback| will be called when decoder is initialized. - // |client| is the pointer to the client object. Ownership of the object is - // not transferred and it must outlive the lifetime of this class. - VideoDecoder(const Instance* instance, Client* client); - ~VideoDecoder(); + explicit VideoDecoder_Dev(const Instance& instance); + explicit VideoDecoder_Dev(PP_Resource resource); + virtual ~VideoDecoder_Dev(); // Initializates the video decoder with a requested configuration. // Calls Init() on PPB_VideoDecoder_Dev interface. // // Parameters: // |config| is the configuration on which the decoder should be initialized. + // |context| GL context in which video decoder decodes frames. // |callback| will be called when decoder is initialized. int32_t Initialize(const PP_VideoConfigElement* config, + const Context3D_Dev& context, CompletionCallback callback); // GetConfigs returns supported configurations that are subsets of given @@ -98,15 +72,6 @@ class VideoDecoder : public Resource { // Dispatches abortion request to the decoder to abort decoding as soon as // possible. |callback| will be called as soon as abortion has been finished. int32_t Abort(CompletionCallback callback); - - private: - // Pointer to the plugin's video decoder support interface for providing the - // buffers for video decoding. - Client* client_; - - // Suppress compiler-generated copy constructors. - VideoDecoder(const VideoDecoder&); - void operator=(const VideoDecoder&); }; } // namespace pp diff --git a/ppapi/ppapi_cpp.gypi b/ppapi/ppapi_cpp.gypi index 74dc1f6..9933d7c 100644 --- a/ppapi/ppapi_cpp.gypi +++ b/ppapi/ppapi_cpp.gypi @@ -201,6 +201,8 @@ 'cpp/dev/surface_3d_dev.h', 'cpp/dev/url_util_dev.cc', 'cpp/dev/url_util_dev.h', + 'cpp/dev/video_decoder_client_dev.cc', + 'cpp/dev/video_decoder_client_dev.h', 'cpp/dev/video_decoder_dev.cc', 'cpp/dev/video_decoder_dev.h', 'cpp/dev/widget_client_dev.cc', diff --git a/ppapi/tests/test_video_decoder.cc b/ppapi/tests/test_video_decoder.cc index 82f99c7..f4f2678 100644 --- a/ppapi/tests/test_video_decoder.cc +++ b/ppapi/tests/test_video_decoder.cc @@ -35,7 +35,7 @@ std::string TestVideoDecoder::TestCreateAndInitialize() { return "Create: error creating the decoder"; int32_t pp_error = video_decoder_interface_->Initialize( - decoder, NULL, PP_BlockUntilComplete()); + decoder, 0, NULL, PP_BlockUntilComplete()); pp::Module::Get()->core()->ReleaseResource(decoder); if (pp_error != PP_ERROR_BADARGUMENT) return "Initialize: error detecting null callback"; diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc index 9905791..476d4c9 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.cc +++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc @@ -45,7 +45,8 @@ MockPluginDelegate::PlatformContext3D* MockPluginDelegate::CreateContext3D() { MockPluginDelegate::PlatformVideoDecoder* MockPluginDelegate::CreateVideoDecoder( - media::VideoDecodeAccelerator::Client* client) { + media::VideoDecodeAccelerator::Client* client, + int command_buffer_route_id) { return NULL; } diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h index 940dece..0b91348 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.h +++ b/webkit/plugins/ppapi/mock_plugin_delegate.h @@ -23,7 +23,8 @@ class MockPluginDelegate : public PluginDelegate { virtual PlatformImage2D* CreateImage2D(int width, int height); virtual PlatformContext3D* CreateContext3D(); virtual PlatformVideoDecoder* CreateVideoDecoder( - media::VideoDecodeAccelerator::Client* client); + media::VideoDecodeAccelerator::Client* client, + int command_buffer_route_id); virtual PlatformAudio* CreateAudio(uint32_t sample_rate, uint32_t sample_count, PlatformAudio::Client* client); diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index 931a39d..c72eaaa 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -174,6 +174,10 @@ class PluginDelegate { // destroyed. virtual ::gpu::CommandBuffer* GetCommandBuffer() = 0; + // If the command buffer is routed in the GPU channel, return the route id. + // Otherwise return 0. + virtual int GetCommandBufferRouteId() = 0; + // Set an optional callback that will be invoked when the context is lost // (e.g. gpu process crash). Takes ownership of the callback. virtual void SetContextLostCallback(Callback0::Type* callback) = 0; @@ -258,7 +262,8 @@ class PluginDelegate { // The caller will own the pointer returned from this. virtual PlatformVideoDecoder* CreateVideoDecoder( - media::VideoDecodeAccelerator::Client* client) = 0; + media::VideoDecodeAccelerator::Client* client, + int command_buffer_route_id) = 0; // The caller is responsible for calling Shutdown() on the returned pointer // to clean up the corresponding resources allocated during this call. diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc index 5fd318a..47777c4 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc @@ -7,6 +7,7 @@ #include <string> #include "base/logging.h" +#include "base/message_loop.h" #include "media/video/picture.h" #include "ppapi/c/dev/pp_video_dev.h" #include "ppapi/c/dev/ppb_video_decoder_dev.h" @@ -18,6 +19,7 @@ #include "webkit/plugins/ppapi/plugin_module.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppb_buffer_impl.h" +#include "webkit/plugins/ppapi/ppb_context_3d_impl.h" #include "webkit/plugins/ppapi/resource_tracker.h" #include "webkit/plugins/ppapi/var.h" @@ -54,6 +56,7 @@ PP_Resource Create(PP_Instance instance_id) { } int32_t Initialize(PP_Resource video_decoder, + PP_Resource context_id, const PP_VideoConfigElement* decoder_config, struct PP_CompletionCallback callback) { scoped_refptr<PPB_VideoDecoder_Impl> decoder( @@ -61,7 +64,7 @@ int32_t Initialize(PP_Resource video_decoder, if (!decoder) return PP_ERROR_BADRESOURCE; - return decoder->Initialize(decoder_config, callback); + return decoder->Initialize(context_id, decoder_config, callback); } PP_Bool IsVideoDecoder(PP_Resource resource) { @@ -220,15 +223,29 @@ bool PPB_VideoDecoder_Impl::GetConfigs( } int32_t PPB_VideoDecoder_Impl::Initialize( + PP_Resource context_id, const PP_VideoConfigElement* decoder_config, PP_CompletionCallback callback) { if (!callback.func) return PP_ERROR_BADARGUMENT; + if (!instance()) return PP_ERROR_FAILED; + scoped_refptr<webkit::ppapi::PPB_Context3D_Impl> context3d = + webkit::ppapi::Resource::GetAs<webkit::ppapi::PPB_Context3D_Impl>( + context_id); + if (!context3d) + return PP_ERROR_BADRESOURCE; + + int command_buffer_route_id = + context3d->platform_context()->GetCommandBufferRouteId(); + if (command_buffer_route_id == 0) + return PP_ERROR_FAILED; + platform_video_decoder_.reset( - instance()->delegate()->CreateVideoDecoder(this)); + instance()->delegate()->CreateVideoDecoder( + this, command_buffer_route_id)); if (!platform_video_decoder_.get()) return PP_ERROR_FAILED; @@ -348,7 +365,8 @@ void PPB_VideoDecoder_Impl::ProvidePictureBuffers( PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); ScopedResourceId resource(this); ppp_videodecoder_->ProvidePictureBuffers( - resource.id, requested_num_of_buffers, out_dim, out_type); + instance()->pp_instance(), resource.id, requested_num_of_buffers, + out_dim, out_type); } void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { @@ -358,7 +376,8 @@ void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { ScopedResourceId resource(this); PP_Picture_Dev out_pic; CopyToPictureDev(picture, &out_pic); - ppp_videodecoder_->PictureReady(resource.id, out_pic); + ppp_videodecoder_->PictureReady( + instance()->pp_instance(), resource.id, out_pic); } void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { @@ -366,7 +385,8 @@ void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { return; ScopedResourceId resource(this); - ppp_videodecoder_->DismissPictureBuffer(resource.id, picture_buffer_id); + ppp_videodecoder_->DismissPictureBuffer( + instance()->pp_instance(), resource.id, picture_buffer_id); } void PPB_VideoDecoder_Impl::NotifyEndOfStream() { @@ -374,7 +394,7 @@ void PPB_VideoDecoder_Impl::NotifyEndOfStream() { return; ScopedResourceId resource(this); - ppp_videodecoder_->EndOfStream(resource.id); + ppp_videodecoder_->EndOfStream(instance()->pp_instance(), resource.id); } void PPB_VideoDecoder_Impl::NotifyError( @@ -387,7 +407,7 @@ void PPB_VideoDecoder_Impl::NotifyError( // PP_VideoDecodeError_Dev have identical enum values. There is no compiler // assert to guarantee this. We either need to add such asserts or // merge these two enums. - ppp_videodecoder_->NotifyError(resource.id, + ppp_videodecoder_->NotifyError(instance()->pp_instance(), resource.id, static_cast<PP_VideoDecodeError_Dev>(error)); } @@ -429,18 +449,17 @@ void PPB_VideoDecoder_Impl::NotifyInitializeDone() { // These functions are declared in picture.h but are defined here because of // dependencies (we can't depend on ppapi types from media). +// TODO(fischman/vrk): Find a way to clean this up as it violates the spirit of +// checkdeps. namespace media { BaseBuffer::BaseBuffer(const PP_BufferInfo_Dev& info) : id_(info.id), size_(info.size.width, info.size.height) { } -// TODO(vrk): This assigns the PP_Resource context to be -// the context_id. Not sure what it's actually supposed to be. GLESBuffer::GLESBuffer(const PP_GLESBuffer_Dev& buffer) : BaseBuffer(buffer.info), - texture_id_(buffer.texture_id), - context_id_(buffer.context) { + texture_id_(buffer.texture_id) { } SysmemBuffer::SysmemBuffer(const PP_SysmemBuffer_Dev& buffer) diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.h b/webkit/plugins/ppapi/ppb_video_decoder_impl.h index f67aa83..7af31a0 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.h +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.h @@ -46,7 +46,8 @@ class PPB_VideoDecoder_Impl : public Resource, PP_VideoConfigElement* matching_configs, uint32_t matching_configs_size, uint32_t* num_of_matching_configs); - int32_t Initialize(const PP_VideoConfigElement* dec_config, + int32_t Initialize(PP_Resource context_id, + const PP_VideoConfigElement* dec_config, PP_CompletionCallback callback); int32_t Decode(const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, PP_CompletionCallback callback); |