diff options
36 files changed, 812 insertions, 914 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 8a08004..31a267f 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1908,7 +1908,6 @@ '../content/common/font_descriptor_mac_unittest.mm', '../content/common/gpu/gpu_feature_flags_unittest.cc', '../content/common/gpu/gpu_info_unittest.cc', - '../content/common/gpu/gpu_video_decoder_unittest.cc', '../content/common/notification_service_unittest.cc', '../content/common/process_watcher_unittest.cc', '../content/common/property_bag_unittest.cc', @@ -1924,7 +1923,6 @@ '../content/gpu/gpu_info_collector_unittest_win.cc', '../content/renderer/active_notification_tracker_unittest.cc', '../content/renderer/audio_message_filter_unittest.cc', - '../content/renderer/gpu_video_decoder_host_unittest.cc', '../content/renderer/media/audio_renderer_impl_unittest.cc', '../content/renderer/paint_aggregator_unittest.cc', '../content/renderer/video_capture_message_filter_unittest.cc', diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc index a922d0c..94c2c06 100644 --- a/content/common/gpu/gpu_channel.cc +++ b/content/common/gpu/gpu_channel.cc @@ -18,7 +18,7 @@ #include "content/common/gpu/gpu_messages.h" #include "content/common/gpu/gpu_video_service.h" #include "content/common/gpu/transport_texture.h" - + #if defined(OS_POSIX) #include "ipc/ipc_channel_posix.h" #endif @@ -250,8 +250,8 @@ void GpuChannel::OnDestroyCommandBuffer(int32 route_id) { #endif } -void GpuChannel::OnCreateVideoDecoder(int32 context_route_id, - int32 decoder_host_id) { +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 @@ -262,16 +262,11 @@ void GpuChannel::OnCreateVideoDecoder(int32 context_route_id, return; } - // The context ID corresponds to the command buffer used. - GpuCommandBufferStub* stub = stubs_.Lookup(context_route_id); int32 decoder_id = GenerateRouteID(); - // TODO(hclam): Need to be careful about the lifetime of the command buffer - // decoder. bool ret = service->CreateVideoDecoder( - this, &router_, decoder_host_id, decoder_id, - stub->scheduler()->decoder()); - DCHECK(ret) << "Failed to create a GpuVideoDecoder"; + this, &router_, decoder_host_id, decoder_id, configs); + DCHECK(ret) << "Failed to create a GpuVideoDecodeAccelerator"; #endif } @@ -290,7 +285,7 @@ void GpuChannel::OnCreateTransportTexture(int32 context_route_id, #if defined(ENABLE_GPU) GpuCommandBufferStub* stub = stubs_.Lookup(context_route_id); int32 route_id = GenerateRouteID(); - + scoped_ptr<TransportTexture> transport( new TransportTexture(this, channel_.get(), stub->scheduler()->decoder(), host_id, route_id)); diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h index dafd53e..d4025ae 100644 --- a/content/common/gpu/gpu_channel.h +++ b/content/common/gpu/gpu_channel.h @@ -24,7 +24,7 @@ class GpuChannelManager; struct GPUCreateCommandBufferConfig; class GpuWatchdog; class TransportTexture; - + namespace base { class MessageLoopProxy; class WaitableEvent; @@ -112,11 +112,11 @@ class GpuChannel : public IPC::Channel::Listener, int32* route_id); void OnDestroyCommandBuffer(int32 route_id); - void OnCreateVideoDecoder(int32 context_route_id, - int32 decoder_host_id); + void OnCreateVideoDecoder(int32 decoder_host_id, + const std::vector<uint32>& configs); void OnDestroyVideoDecoder(int32 decoder_id); void OnCreateTransportTexture(int32 context_route_id, int32 host_id); - + // 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 60f4f74..9c31376 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -311,8 +311,8 @@ IPC_SYNC_MESSAGE_CONTROL1_0(GpuChannelMsg_DestroyCommandBuffer, // We need this to be control message because we had to map the GpuChannel and // |decoder_id|. IPC_MESSAGE_CONTROL2(GpuChannelMsg_CreateVideoDecoder, - int32, /* context_route_id */ - int32) /* decoder_id */ + int32, /* decoder_id */ + std::vector<uint32>) /* configs */ // Release all resource of the hardware video decoder which was assocaited // with the input |decoder_id|. @@ -534,23 +534,34 @@ IPC_SYNC_MESSAGE_CONTROL1_1(AcceleratedVideoDecoderMsg_GetConfigs, std::vector<uint32>, /* Proto config */ std::vector<uint32>) /* Matching configs */ -// Message to create the accelerated video decoder. -IPC_SYNC_MESSAGE_CONTROL1_1(AcceleratedVideoDecoderMsg_Create, - std::vector<uint32>, /* Config */ - int32) /* Decoder ID, -1 equals failure */ +// Message to initialize the accelerated video decoder. +IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_Initialize, + std::vector<uint32>) /* Config */ // Send input buffer for decoding. IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderMsg_Decode, + int32, /* bitstream_buffer_id */ base::SharedMemoryHandle, /* input_buffer_handle */ - int32, /* offset */ int32) /* size */ // Sent from Renderer process to the GPU process to give the texture IDs for -// generated GL textures. -IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderMsg_AssignPictureBuffer, - int32, /* Picture buffer ID */ - base::SharedMemoryHandle, /* Pointer to sysmem output */ - std::vector<uint32>) /* TextureIDs for pictures */ +// 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. +// +// The length of the list of SharedMemoryHandles cannot exceed +// FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE; see +// ipc/file_descriptor_set_posix. +IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderMsg_AssignSysmemBuffers, + std::vector<int32>, /* Picture buffer ID */ + std::vector<base::SharedMemoryHandle>, /* Sysmem buffer */ + std::vector<gfx::Size>) /* Size */ // Send from Renderer process to the GPU process to recycle the given picture // buffer for further decoding. @@ -574,13 +585,17 @@ IPC_SYNC_MESSAGE_CONTROL0_0(AcceleratedVideoDecoderMsg_Destroy) // Accelerated video decoder has consumed input buffer from transfer buffer. IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed, - base::SharedMemoryHandle) /* Processed buffer handle */ + int32) /* Processed buffer ID */ // Allocate video frames for output of the hardware video decoder. -IPC_MESSAGE_ROUTED2(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, +IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, int32, /* Number of video frames to generate */ - std::vector<uint32>) /* Vector containing the dictionary - for buffer config */ + gfx::Size, /* Requested size of buffer */ + int32) /* Type of buffer */ + +// Decoder has been created and is ready for initialization. +IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_CreateDone, + int32) /* Decoder ID */ // Decoder reports that a picture is ready and buffer does not need to be passed // back to the decoder. @@ -588,8 +603,11 @@ IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer, int32) /* Picture buffer ID */ // Decoder reports that a picture is ready. -IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_PictureReady, - int32) /* Picture buffer ID */ +IPC_MESSAGE_ROUTED4(AcceleratedVideoDecoderHostMsg_PictureReady, + int32, /* Picture buffer ID */ + int32, /* Bitstream buffer ID */ + gfx::Size, /* Visible size */ + gfx::Size) /* Decoded size */ // Confirm decoder has been flushed. IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_FlushDone) diff --git a/content/common/gpu/gpu_process_launch_causes.h b/content/common/gpu/gpu_process_launch_causes.h index b4ce88b..e9b3970 100644 --- a/content/common/gpu/gpu_process_launch_causes.h +++ b/content/common/gpu/gpu_process_launch_causes.h @@ -16,6 +16,7 @@ enum CauseForGpuLaunch { CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED, CAUSE_FOR_GPU_LAUNCH_RENDERWIDGETFULLSCREENPEPPER_CREATECONTEXT, CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE, + CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE, CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, CAUSE_FOR_GPU_LAUNCH_MAX_ENUM }; diff --git a/content/common/gpu/gpu_video_decode_accelerator.cc b/content/common/gpu/gpu_video_decode_accelerator.cc new file mode 100644 index 0000000..35d0a0b --- /dev/null +++ b/content/common/gpu/gpu_video_decode_accelerator.cc @@ -0,0 +1,184 @@ +// 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 "content/common/gpu/gpu_video_decode_accelerator.h" + +#include <vector> + +#include "base/bind.h" +#include "base/logging.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_message_utils.h" +#include "content/common/gpu/gpu_channel.h" +#include "content/common/gpu/gpu_messages.h" +#include "ui/gfx/size.h" + +GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( + IPC::Message::Sender* sender, + int32 host_route_id) + : sender_(sender), + route_id_(host_route_id), + video_decode_accelerator_(NULL) { +} + +GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {} + +bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_GetConfigs, OnGetConfigs) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Initialize, OnInitialize) + 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) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Abort, OnAbort) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void GpuVideoDecodeAccelerator::OnChannelConnected(int32 peer_pid) { + // TODO(vmr): Do we have to react on channel connections? +} + +void GpuVideoDecodeAccelerator::OnChannelError() { + // TODO(vmr): Do we have to react on channel errors? +} + +void GpuVideoDecodeAccelerator::ProvidePictureBuffers( + uint32 requested_num_of_buffers, + const gfx::Size& dimensions, + media::VideoDecodeAccelerator::MemoryType type) { + if (!Send(new AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers( + route_id_, requested_num_of_buffers, dimensions, type))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers) " + << "failed"; + } +} + +void GpuVideoDecodeAccelerator::DismissPictureBuffer( + int32 picture_buffer_id) { + // TODO(vrk): Unmap picture buffer. + NOTIMPLEMENTED(); + + // Notify client that picture buffer is now unused. + if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer( + route_id_, picture_buffer_id))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) " + << "failed"; + } +} + +void GpuVideoDecodeAccelerator::PictureReady( + const media::Picture& picture) { + if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( + route_id_, + picture.picture_buffer_id(), + picture.bitstream_buffer_id(), + picture.visible_size(), + picture.decoded_size()))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; + } +} + +void GpuVideoDecodeAccelerator::NotifyEndOfStream() { + Send(new AcceleratedVideoDecoderHostMsg_EndOfStream(route_id_)); +} + +void GpuVideoDecodeAccelerator::NotifyError( + media::VideoDecodeAccelerator::Error error) { + if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification( + route_id_, error))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) " + << "failed"; + } +} + +void GpuVideoDecodeAccelerator::OnGetConfigs( + const std::vector<uint32>& requested, std::vector<uint32>* matched) { + // TODO(vrk): Need to rethink GetConfigs. + NOTIMPLEMENTED(); +} + +void GpuVideoDecodeAccelerator::OnInitialize( + const std::vector<uint32>& configs) { + if (!video_decode_accelerator_) + return; + + video_decode_accelerator_->Initialize(configs); +} + +void GpuVideoDecodeAccelerator::OnDecode(int32 id, + base::SharedMemoryHandle handle, + int32 size) { + // TODO(vrk): Implement. + NOTIMPLEMENTED(); +} + +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::OnAssignSysmemBuffers( + const std::vector<int32> buffer_ids, + const std::vector<base::SharedMemoryHandle> data, + const std::vector<gfx::Size> sizes) { + // TODO(vrk): Implement. + NOTIMPLEMENTED(); +} + +void GpuVideoDecodeAccelerator::OnReusePictureBuffer(int32 picture_buffer_id) { + if (!video_decode_accelerator_) + return; + + video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id); +} + +void GpuVideoDecodeAccelerator::OnFlush() { + if (!video_decode_accelerator_) + return; + + if (!video_decode_accelerator_->Flush()) { + NotifyError( + media::VideoDecodeAccelerator::VIDEODECODERERROR_UNEXPECTED_FLUSH); + } +} + +void GpuVideoDecodeAccelerator::OnAbort() { + if (!video_decode_accelerator_) + return; + + video_decode_accelerator_->Abort(); +} + +void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( + int32 bitstream_buffer_id) { + // TODO(vrk): Implement. + NOTIMPLEMENTED(); +} + +void GpuVideoDecodeAccelerator::NotifyFlushDone() { + if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(route_id_))) + LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed"; +} + +void GpuVideoDecodeAccelerator::NotifyAbortDone() { + if (!Send(new AcceleratedVideoDecoderHostMsg_AbortDone(route_id_))) + LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_AbortDone) failed"; +} + +bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { + DCHECK(sender_); + return sender_->Send(message); +} diff --git a/content/gpu/gpu_video_decode_accelerator.h b/content/common/gpu/gpu_video_decode_accelerator.h index d06f6f1..584e3de 100644 --- a/content/gpu/gpu_video_decode_accelerator.h +++ b/content/common/gpu/gpu_video_decode_accelerator.h @@ -5,11 +5,9 @@ #ifndef CONTENT_GPU_GPU_VIDEO_DECODE_ACCELERATOR_H_ #define CONTENT_GPU_GPU_VIDEO_DECODE_ACCELERATOR_H_ -#include <deque> #include <vector> #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_callback_factory.h" #include "base/shared_memory.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message.h" @@ -32,13 +30,15 @@ class GpuVideoDecodeAccelerator // media::VideoDecodeAccelerator::Client implementation. virtual void ProvidePictureBuffers( uint32 requested_num_of_buffers, - const std::vector<uint32>& buffer_properties) OVERRIDE; - virtual void DismissPictureBuffer( - media::VideoDecodeAccelerator::PictureBuffer* picture_buffer) OVERRIDE; - virtual void PictureReady( - media::VideoDecodeAccelerator::Picture* picture) OVERRIDE; - virtual void NotifyEndOfStream(); - virtual void NotifyError(media::VideoDecodeAccelerator::Error error); + const gfx::Size& dimensions, + media::VideoDecodeAccelerator::MemoryType type) OVERRIDE; + virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; + virtual void PictureReady(const media::Picture& picture) OVERRIDE; + virtual void NotifyEndOfStream() OVERRIDE; + virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE; + virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; + virtual void NotifyFlushDone() OVERRIDE; + virtual void NotifyAbortDone() OVERRIDE; // Function to delegate sending to actual sender. virtual bool Send(IPC::Message* message); @@ -50,32 +50,29 @@ class GpuVideoDecodeAccelerator private: // Handlers for IPC messages. - void OnGetConfigs(std::vector<uint32> config, std::vector<uint32>* configs); - void OnCreate(std::vector<uint32> config, int32* decoder_id); - void OnDecode(base::SharedMemoryHandle handle, int32 offset, int32 size); - void OnAssignPictureBuffer(int32 picture_buffer_id, - base::SharedMemoryHandle handle, - std::vector<uint32> texture_ids); + 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); void OnReusePictureBuffer(int32 picture_buffer_id); void OnFlush(); void OnAbort(); - // One-time callbacks from the accelerator. - void OnBitstreamBufferProcessed(); - void OnFlushDone(); - void OnAbortDone(); - // Pointer to the IPC message sender. IPC::Message::Sender* sender_; + // Route ID to communicate with the host. int32 route_id_; + // Pointer to the underlying VideoDecodeAccelerator. media::VideoDecodeAccelerator* video_decode_accelerator_; - // Callback factory to generate one-time callbacks. - base::ScopedCallbackFactory<GpuVideoDecodeAccelerator> cb_factory_; - // Container to hold shared memory blocks so that we can return the - // information about their consumption to renderer. - std::deque<base::SharedMemory*> shm_in_; DISALLOW_IMPLICIT_CONSTRUCTORS(GpuVideoDecodeAccelerator); }; diff --git a/content/common/gpu/gpu_video_service.cc b/content/common/gpu/gpu_video_service.cc index f6d0ba1..095ef23 100644 --- a/content/common/gpu/gpu_video_service.cc +++ b/content/common/gpu/gpu_video_service.cc @@ -2,16 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/gpu/gpu_channel.h" -#include "content/common/gpu/gpu_messages.h" -#include "content/common/gpu/gpu_video_decoder.h" #include "content/common/gpu/gpu_video_service.h" -struct GpuVideoService::GpuVideoDecoderInfo { - scoped_refptr<GpuVideoDecoder> decoder; - GpuChannel* channel; -}; - +#include "content/common/gpu/gpu_channel.h" +#include "content/common/gpu/gpu_messages.h" +#include "content/common/gpu/gpu_video_decode_accelerator.h" GpuVideoService::GpuVideoService() { // TODO(jiesun): move this time consuming stuff out of here. @@ -58,19 +53,24 @@ bool GpuVideoService::CreateVideoDecoder( MessageRouter* router, int32 decoder_host_id, int32 decoder_id, - gpu::gles2::GLES2Decoder* gles2_decoder) { - GpuVideoDecoderInfo decoder_info; - decoder_info.decoder = new GpuVideoDecoder(MessageLoop::current(), - decoder_host_id, - channel, - channel->renderer_process(), - gles2_decoder); - decoder_info.channel = channel; - decoder_map_[decoder_id] = decoder_info; - router->AddRoute(decoder_id, decoder_info.decoder); - - channel->Send(new GpuVideoDecoderHostMsg_CreateVideoDecoderDone( - decoder_host_id, decoder_id)); + const std::vector<uint32>& configs) { + // Create GpuVideoDecodeAccelerator and add to map. + scoped_refptr<GpuVideoDecodeAccelerator> decoder = + new GpuVideoDecodeAccelerator(channel, decoder_host_id); + + bool result = decoder_map_.insert(std::make_pair(decoder_id, decoder)).second; + + // Decoder ID is a unique ID determined by GpuVideoServiceHost. + // We should always be adding entries here. + DCHECK(result); + + router->AddRoute(decoder_id, decoder); + + // Tell client that initialization is complete. + channel->Send( + new AcceleratedVideoDecoderHostMsg_CreateDone( + decoder_host_id, decoder_id)); + return true; } diff --git a/content/common/gpu/gpu_video_service.h b/content/common/gpu/gpu_video_service.h index 8c39db3..44090c4 100644 --- a/content/common/gpu/gpu_video_service.h +++ b/content/common/gpu/gpu_video_service.h @@ -9,10 +9,11 @@ #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" -#include "content/common/gpu/gpu_video_decoder.h" +#include "content/common/gpu/gpu_video_decode_accelerator.h" #include "ipc/ipc_channel.h" class GpuChannel; +class MessageRouter; class GpuVideoService : public IPC::Channel::Listener { public: @@ -28,17 +29,15 @@ class GpuVideoService : public IPC::Channel::Listener { MessageRouter* router, int32 decoder_host_id, int32 decoder_id, - gpu::gles2::GLES2Decoder* gles2_decoder); + const std::vector<uint32>& configs); void DestroyVideoDecoder(MessageRouter* router, int32 decoder_id); private: - struct GpuVideoDecoderInfo; - GpuVideoService(); virtual ~GpuVideoService(); - std::map<int32, GpuVideoDecoderInfo> decoder_map_; + std::map<int32, scoped_refptr<GpuVideoDecodeAccelerator> > decoder_map_; // Specialize video service on different platform will override. virtual bool IntializeGpuVideoService(); diff --git a/content/content_common.gypi b/content/content_common.gypi index ad21ae5..9b01698 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -116,8 +116,8 @@ 'common/gpu/gpu_info.h', 'common/gpu/gpu_messages.h', 'common/gpu/gpu_process_launch_casues.h', - 'common/gpu/gpu_video_decoder.cc', - 'common/gpu/gpu_video_decoder.h', + 'common/gpu/gpu_video_decode_accelerator.cc', + 'common/gpu/gpu_video_decode_accelerator.h', 'common/gpu/gpu_video_service.cc', 'common/gpu/gpu_video_service.h', 'common/gpu/gpu_watchdog.h', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 8271e75..7205199 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -46,8 +46,8 @@ 'renderer/geolocation_dispatcher.h', 'renderer/gpu_channel_host.cc', 'renderer/gpu_channel_host.h', - 'renderer/gpu_video_decoder_host.cc', - 'renderer/gpu_video_decoder_host.h', + 'renderer/gpu_video_decode_accelerator_host.cc', + 'renderer/gpu_video_decode_accelerator_host.h', 'renderer/gpu_video_service_host.cc', 'renderer/gpu_video_service_host.h', 'renderer/indexed_db_dispatcher.cc', @@ -136,8 +136,6 @@ 'renderer/v8_value_converter.h', 'renderer/video_capture_message_filter.cc', 'renderer/video_capture_message_filter.h', - 'renderer/video_decode_accelerator_host.cc', - 'renderer/video_decode_accelerator_host.h', 'renderer/webgraphicscontext3d_command_buffer_impl.cc', 'renderer/webgraphicscontext3d_command_buffer_impl.h', 'renderer/webplugin_delegate_proxy.cc', diff --git a/content/gpu/gpu_video_decode_accelerator.cc b/content/gpu/gpu_video_decode_accelerator.cc deleted file mode 100644 index 17b5441..0000000 --- a/content/gpu/gpu_video_decode_accelerator.cc +++ /dev/null @@ -1,211 +0,0 @@ -// 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 "content/gpu/gpu_video_decode_accelerator.h" - -#include <vector> - -#include "base/shared_memory.h" -#include "content/common/gpu/gpu_messages.h" -#include "ipc/ipc_message_macros.h" -#include "ipc/ipc_message_utils.h" -#include "media/video/picture.h" -#include "ui/gfx/size.h" - -GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( - IPC::Message::Sender* sender, - int32 host_route_id) - : sender_(sender), - route_id_(host_route_id), - cb_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { -} - -GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {} - -bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg) - IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_GetConfigs, - OnGetConfigs) - IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, - OnDecode) - IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffer, - OnAssignPictureBuffer) - IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer, - OnReusePictureBuffer) - IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Flush, - OnFlush) - IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Abort, - OnAbort) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void GpuVideoDecodeAccelerator::OnChannelConnected(int32 peer_pid) { - // TODO(vmr): Do we have to react on channel connections? -} - -void GpuVideoDecodeAccelerator::OnChannelError() { - // TODO(vmr): Do we have to react on channel errors? -} - -void GpuVideoDecodeAccelerator::ProvidePictureBuffers( - uint32 requested_num_of_buffers, - const std::vector<uint32>& buffer_properties) { - Send(new AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers( - route_id_, - requested_num_of_buffers, - buffer_properties)); -} - -void GpuVideoDecodeAccelerator::DismissPictureBuffer( - media::VideoDecodeAccelerator::PictureBuffer* picture_buffer) { - DCHECK(picture_buffer); - // TODO(vmr): Unmap system memory here. - Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer( - route_id_, - picture_buffer->GetId())); -} - -void GpuVideoDecodeAccelerator::PictureReady( - media::VideoDecodeAccelerator::Picture* picture) { - Send(new AcceleratedVideoDecoderHostMsg_PictureReady( - route_id_, - picture->picture_buffer()->GetId())); -} - -void GpuVideoDecodeAccelerator::NotifyEndOfStream() { - Send(new AcceleratedVideoDecoderHostMsg_EndOfStream(route_id_)); -} - -void GpuVideoDecodeAccelerator::NotifyError( - media::VideoDecodeAccelerator::Error error) { - Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification(route_id_, - error)); -} - -void GpuVideoDecodeAccelerator::OnGetConfigs(std::vector<uint32> config, - std::vector<uint32>* configs) { - DCHECK(configs); - *configs = video_decode_accelerator_->GetConfig(config); -} - -void GpuVideoDecodeAccelerator::OnCreate(std::vector<uint32> config, - int32* decoder_id) { -} - -void GpuVideoDecodeAccelerator::OnDecode(base::SharedMemoryHandle handle, - int32 offset, - int32 size) { - if (offset < 0 || size <= 0) { - NotifyError(media::VideoDecodeAccelerator::VIDEODECODERERROR_INVALIDINPUT); - return; - } - if (!base::SharedMemory::IsHandleValid(handle)) { - NotifyError(media::VideoDecodeAccelerator::VIDEODECODERERROR_MEMFAILURE); - return; - } - base::SharedMemory* shm = new base::SharedMemory(handle, true); - if (!shm || !shm->Map(offset + size)) { - NotifyError(media::VideoDecodeAccelerator::VIDEODECODERERROR_MEMFAILURE); - return; - } - // Set the freshly mapped memory address to the bitstream buffer. - uint8* mem_ptr = static_cast<uint8*>(shm->memory()); - media::BitstreamBuffer bitstream(mem_ptr + offset, size, NULL); - // Store the SHM in our FIFO queue. We need to do this before Decode because - // it is legal to call BitstreamBufferProcessed callback from the Decode - // context. - shm_in_.push_back(shm); - video_decode_accelerator_->Decode( - &bitstream, - cb_factory_.NewCallback( - &GpuVideoDecodeAccelerator::OnBitstreamBufferProcessed)); -} - -void GpuVideoDecodeAccelerator::OnAssignPictureBuffer( - int32 picture_buffer_id, - base::SharedMemoryHandle handle, - std::vector<uint32> textures) { - // TODO(vmr): Get the right size for picture buffers from config. - gfx::Size size(320, 240); - uint32 bits_per_pixel = 32; - media::VideoDecodeAccelerator::PictureBuffer::MemoryType memory_type; - std::vector<media::VideoDecodeAccelerator::PictureBuffer::DataPlaneHandle> - planes; - if (handle == base::SharedMemory::NULLHandle()) { - // TODO(vmr): Handle GLES textures here. - memory_type = media::VideoDecodeAccelerator::PictureBuffer:: - PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE; - } else { - // Input buffer provided is in system memory in one plane. - memory_type = media::VideoDecodeAccelerator::PictureBuffer:: - PICTUREBUFFER_MEMORYTYPE_SYSTEM; - if (!base::SharedMemory::IsHandleValid(handle)) { - NotifyError(media::VideoDecodeAccelerator::VIDEODECODERERROR_MEMFAILURE); - return; - } - base::SharedMemory* shm = new base::SharedMemory(handle, true); - if (!shm || !shm->Map(size.width() * size.height() * bits_per_pixel)) { - NotifyError(media::VideoDecodeAccelerator::VIDEODECODERERROR_MEMFAILURE); - return; - } - media::VideoDecodeAccelerator::PictureBuffer::DataPlaneHandle sysmem_plane; - sysmem_plane.sysmem = shm; - planes.push_back(sysmem_plane); - } - std::vector<media::VideoDecodeAccelerator::PictureBuffer*> bufs; - std::vector<uint32> color_format; - media::VideoDecodeAccelerator::PictureBuffer* picture_buffer = - new media::PictureBuffer(picture_buffer_id, - size, - color_format, - memory_type, - planes); - bufs.push_back(picture_buffer); - video_decode_accelerator_->AssignPictureBuffer(bufs); -} - -void GpuVideoDecodeAccelerator::OnReusePictureBuffer( - int32 picture_buffer_id) { - // TODO(vmr): Get the picture buffer with the id. - media::VideoDecodeAccelerator::PictureBuffer* picture_buffer = NULL; - video_decode_accelerator_->ReusePictureBuffer(picture_buffer); -} - -void GpuVideoDecodeAccelerator::OnFlush() { - if (!video_decode_accelerator_->Flush(cb_factory_.NewCallback( - &GpuVideoDecodeAccelerator::OnFlushDone))) { - NotifyError( - media::VideoDecodeAccelerator::VIDEODECODERERROR_UNEXPECTED_FLUSH); - } -} - -void GpuVideoDecodeAccelerator::OnAbort() { - video_decode_accelerator_->Abort(cb_factory_.NewCallback( - &GpuVideoDecodeAccelerator::OnAbortDone)); -} - -void GpuVideoDecodeAccelerator::OnBitstreamBufferProcessed() { - base::SharedMemory* shm = shm_in_.front(); - DCHECK(shm); // Shared memory should always be non-NULL. - Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed( - 0, shm->handle())); - shm_in_.pop_front(); -} - -void GpuVideoDecodeAccelerator::OnFlushDone() { - Send(new AcceleratedVideoDecoderHostMsg_FlushDone(0)); -} - -void GpuVideoDecodeAccelerator::OnAbortDone() { - Send(new AcceleratedVideoDecoderHostMsg_AbortDone(0)); -} - -bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { - DCHECK(sender_); - return sender_->Send(message); -} - diff --git a/content/renderer/gpu_video_decode_accelerator_host.cc b/content/renderer/gpu_video_decode_accelerator_host.cc new file mode 100644 index 0000000..bfc66ad --- /dev/null +++ b/content/renderer/gpu_video_decode_accelerator_host.cc @@ -0,0 +1,196 @@ +// 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 "content/renderer/gpu_video_decode_accelerator_host.h" + +#include "base/logging.h" +#include "base/shared_memory.h" +#include "base/task.h" +#include "content/common/gpu/gpu_messages.h" +#include "content/common/view_messages.h" +#include "content/renderer/render_thread.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_message_utils.h" + +using media::VideoDecodeAccelerator; +using media::VideoDecodeAcceleratorCallback; + +GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( + MessageRouter* router, + IPC::Message::Sender* ipc_sender, + int32 decoder_host_id, + VideoDecodeAccelerator::Client* client) + : router_(router), + ipc_sender_(ipc_sender), + decoder_host_id_(decoder_host_id), + decoder_id_(0), + client_(client) { +} + +GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {} + +void GpuVideoDecodeAcceleratorHost::OnChannelConnected(int32 peer_pid) { +} + +void GpuVideoDecodeAcceleratorHost::OnChannelError() { + ipc_sender_ = NULL; +} + +bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed, + OnBitstreamBufferProcessed) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers, + OnProvidePictureBuffer) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_CreateDone, + OnCreateDone) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_PictureReady, + OnPictureReady) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_FlushDone, + OnFlushDone) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_AbortDone, + OnAbortDone) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_EndOfStream, + OnEndOfStream) + IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification, + OnErrorNotification) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + DCHECK(handled); + return handled; +} + +void GpuVideoDecodeAcceleratorHost::GetConfigs( + const std::vector<uint32>& requested_configs, + std::vector<uint32>* matched_configs) { + // TODO(vrk): Need to rethink GetConfigs. + NOTIMPLEMENTED(); +} + +bool GpuVideoDecodeAcceleratorHost::Initialize( + const std::vector<uint32>& configs) { + router_->AddRoute(decoder_host_id_, this); + + // Temporarily save configs for after create is done and we're + // ready to initialize. + configs_ = configs; + + if (!ipc_sender_->Send(new GpuChannelMsg_CreateVideoDecoder( + decoder_id_, configs))) { + LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed"; + return false; + } + return true; +} + +bool GpuVideoDecodeAcceleratorHost::Decode( + const media::BitstreamBuffer& bitstream_buffer) { + // TODO(vrk): Implement. + NOTIMPLEMENTED(); + return false; +} + +void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers( + const std::vector<media::GLESBuffer>& buffers) { + // 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::BufferInfo& info = buffers[i].buffer_info(); + texture_ids.push_back(buffers[i].texture_id()); + context_ids.push_back(buffers[i].context_id()); + buffer_ids.push_back(info.id()); + sizes.push_back(info.size()); + } + if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_AssignGLESBuffers( + decoder_id_, buffer_ids, texture_ids, context_ids, sizes))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_AssignGLESBuffers) failed"; + } +} + +void GpuVideoDecodeAcceleratorHost::AssignSysmemBuffers( + const std::vector<media::SysmemBuffer>& buffers) { + // TODO(vrk): Implement. + NOTIMPLEMENTED(); +} + +void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( + int32 picture_buffer_id) { + if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer( + decoder_id_, picture_buffer_id))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_ReusePictureBuffer) failed"; + } +} + +bool GpuVideoDecodeAcceleratorHost::Flush() { + if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Flush(decoder_id_))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Flush) failed"; + return false; + } + return true; +} + +bool GpuVideoDecodeAcceleratorHost::Abort() { + if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Abort(decoder_id_))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Abort) failed"; + return false; + } + return true; +} + +void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( + int32 bitstream_buffer_id) { + client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); +} + +void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer( + uint32 num_requested_buffers, + const gfx::Size& buffer_size, + int32 mem_type) { + media::VideoDecodeAccelerator::MemoryType converted_mem_type = + static_cast<media::VideoDecodeAccelerator::MemoryType>(mem_type); + client_->ProvidePictureBuffers( + num_requested_buffers, buffer_size, converted_mem_type); +} + +void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer( + int32 picture_buffer_id) { + client_->DismissPictureBuffer(picture_buffer_id); +} + +void GpuVideoDecodeAcceleratorHost::OnCreateDone(int32 decoder_id) { + decoder_id_ = decoder_id; + if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Initialize( + decoder_id_, configs_))) { + LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Initialize) failed"; + } +} + +void GpuVideoDecodeAcceleratorHost::OnPictureReady( + int32 picture_buffer_id, int32 bitstream_buffer_id, + const gfx::Size& visible_size, const gfx::Size& decoded_size) { + media::Picture picture( + picture_buffer_id, bitstream_buffer_id, visible_size, decoded_size); + client_->PictureReady(picture); +} + +void GpuVideoDecodeAcceleratorHost::OnFlushDone() { + client_->NotifyFlushDone(); +} + +void GpuVideoDecodeAcceleratorHost::OnAbortDone() { + client_->NotifyAbortDone(); +} + +void GpuVideoDecodeAcceleratorHost::OnEndOfStream() { + client_->NotifyEndOfStream(); +} + +void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) { + client_->NotifyError( + static_cast<media::VideoDecodeAccelerator::Error>(error)); +} diff --git a/content/renderer/gpu_video_decode_accelerator_host.h b/content/renderer/gpu_video_decode_accelerator_host.h new file mode 100644 index 0000000..4503f55 --- /dev/null +++ b/content/renderer/gpu_video_decode_accelerator_host.h @@ -0,0 +1,86 @@ +// 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 CONTENT_RENDERER_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_ +#define CONTENT_RENDERER_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_ + +#include <vector> + +#include "base/memory/scoped_ptr.h" +#include "base/shared_memory.h" +#include "ipc/ipc_channel.h" +#include "media/video/video_decode_accelerator.h" + +class MessageLoop; +class MessageRouter; + +// This class is used to talk to VideoDecodeAccelerator in the Gpu process +// through IPC messages. +class GpuVideoDecodeAcceleratorHost : public IPC::Channel::Listener, + public media::VideoDecodeAccelerator { + public: + // |router| is used to dispatch IPC messages to this object. + // |ipc_sender| is used to send IPC messages to Gpu process. + GpuVideoDecodeAcceleratorHost(MessageRouter* router, + IPC::Message::Sender* ipc_sender, + int32 decoder_host_id, + media::VideoDecodeAccelerator::Client* client); + virtual ~GpuVideoDecodeAcceleratorHost(); + + // IPC::Channel::Listener implementation. + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + virtual void OnChannelError() OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + // media::VideoDecodeAccelerator implementation. + virtual void GetConfigs( + const std::vector<uint32>& requested_configs, + std::vector<uint32>* matched_configs) OVERRIDE; + virtual bool Initialize(const std::vector<uint32>& configs) OVERRIDE; + virtual bool Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; + virtual void AssignGLESBuffers( + const std::vector<media::GLESBuffer>& buffers) OVERRIDE; + virtual void AssignSysmemBuffers( + const std::vector<media::SysmemBuffer>& buffers) OVERRIDE; + virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; + virtual bool Flush() OVERRIDE; + virtual bool Abort() OVERRIDE; + + private: + void OnBitstreamBufferProcessed(int32 bitstream_buffer_id); + void OnProvidePictureBuffer( + uint32 num_requested_buffers, const gfx::Size& buffer_size, int32 mem_type); + void OnDismissPictureBuffer(int32 picture_buffer_id); + void OnCreateDone(int32 decoder_id); + void OnPictureReady(int32 picture_buffer_id, + int32 bitstream_buffer_id, + const gfx::Size& visible_size, + const gfx::Size& decoded_size); + void OnFlushDone(); + void OnAbortDone(); + void OnEndOfStream(); + void OnErrorNotification(uint32 error); + + // A router used to send us IPC messages. + MessageRouter* router_; + + // Sends IPC messages to the Gpu process. + IPC::Message::Sender* ipc_sender_; + + // ID of this GpuVideoDecodeAcceleratorHost. + int32 decoder_host_id_; + + // ID of VideoDecodeAccelerator in the Gpu process. + int32 decoder_id_; + + // Temporarily store configs here in between Create and Initialize phase. + std::vector<uint32> configs_; + + // Reference to the client that will receive callbacks from the decoder. + media::VideoDecodeAccelerator::Client* client_; + + DISALLOW_COPY_AND_ASSIGN(GpuVideoDecodeAcceleratorHost); +}; + +#endif // CONTENT_RENDERER_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_ diff --git a/content/renderer/gpu_video_decoder_host_unittest.cc b/content/renderer/gpu_video_decoder_host_unittest.cc deleted file mode 100644 index 8c96cb4..0000000 --- a/content/renderer/gpu_video_decoder_host_unittest.cc +++ /dev/null @@ -1,265 +0,0 @@ -// 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 "base/message_loop.h" -#include "content/common/gpu/gpu_messages.h" -#include "content/common/message_router.h" -#include "content/renderer/gpu_video_decoder_host.h" -#include "media/base/pipeline.h" -#include "media/video/video_mock_objects.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::DoAll; -using testing::NotNull; -using testing::Return; -using testing::SetArgumentPointee; - -static const int kContextRouteId = 50; -static const int kDecoderHostId = 51; -static const int kDecoderId = 51; -static const int kVideoFrames = 3; -static const int kWidth = 320; -static const int kHeight = 240; -static const int kFrameRateNumerator = 25; -static const int kFrameRateDenominator = 1; -static const int kTransportBufferSize = 1024; - -ACTION_P(SimulateAllocateVideoFrames, frames) { - // Fake some texture IDs here. - media::VideoFrame::GlTexture textures[] = {4, 5, 6}; - for (int i = 0; i < kVideoFrames; ++i) { - scoped_refptr<media::VideoFrame> frame; - media::VideoFrame::CreateFrameGlTexture(media::VideoFrame::YV12, - kWidth, kHeight, textures, - &frame); - frames->push_back(frame); - arg4->push_back(frame); - } - - // Execute the callback to complete the task. - arg5->Run(); - delete arg5; -} - -ACTION_P2(SendMessage, handler, msg) { - handler->OnMessageReceived(msg); -} - -class GpuVideoDecoderHostTest : public testing::Test, - public IPC::Message::Sender, - public media::VideoDecodeEngine::EventHandler { - public: - // This method is used to dispatch IPC messages to mock methods. - virtual bool Send(IPC::Message* msg) { - EXPECT_TRUE(msg); - if (!msg) - return false; - - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(GpuVideoDecoderHostTest, *msg) - IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateVideoDecoder, - OnCreateVideoDecoder) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_Initialize, - OnInitialize) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_Destroy, - OnDestroy) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_Flush, - OnFlush) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_EmptyThisBuffer, - OnEmptyThisBuffer) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_VideoFrameAllocated, - OnVideoFrameAllocated) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_ProduceVideoFrame, - OnProduceVideoFrame) - IPC_MESSAGE_UNHANDLED_ERROR() - IPC_END_MESSAGE_MAP() - EXPECT_TRUE(handled); - delete msg; - return true; - } - - // Mock methods for outgoing messages. - MOCK_METHOD1(OnInitialize, void(GpuVideoDecoderInitParam param)); - MOCK_METHOD0(OnDestroy, void()); - MOCK_METHOD0(OnFlush, void()); - MOCK_METHOD1(OnEmptyThisBuffer, - void(GpuVideoDecoderInputBufferParam param)); - MOCK_METHOD1(OnProduceVideoFrame, void(int32 frame_id)); - MOCK_METHOD2(OnVideoFrameAllocated, - void(int32 frame_id, std::vector<uint32> textures)); - MOCK_METHOD2(OnCreateVideoDecoder, - void(int32 context_route_id, int32 decoder_host_id)); - - // Mock methods for VideoDecodeEngine::EventHandler. - MOCK_METHOD1(ProduceVideoSample, - void(scoped_refptr<media::Buffer> buffer)); - MOCK_METHOD2(ConsumeVideoFrame, - void(scoped_refptr<media::VideoFrame> frame, - const media::PipelineStatistics& statistics)); - MOCK_METHOD1(OnInitializeComplete, - void(const media::VideoCodecInfo& info)); - MOCK_METHOD0(OnUninitializeComplete, void()); - MOCK_METHOD0(OnFlushComplete, void()); - MOCK_METHOD0(OnSeekComplete, void()); - MOCK_METHOD0(OnError, void()); - MOCK_METHOD1(OnFormatChange, - void(media::VideoStreamInfo stream_info)); - - void Initialize() { - decoder_host_.reset( - new GpuVideoDecoderHost(&router_, this, kContextRouteId, - kDecoderHostId)); - shared_memory_.reset(new base::SharedMemory()); - shared_memory_->CreateAnonymous(kTransportBufferSize); - - GpuVideoDecoderHostMsg_CreateVideoDecoderDone msg1(kDecoderHostId, - kDecoderId); - EXPECT_CALL(*this, OnCreateVideoDecoder(kContextRouteId, kDecoderHostId)) - .WillOnce(SendMessage(decoder_host_.get(), msg1)); - - GpuVideoDecoderInitDoneParam param; - param.success = true; - param.input_buffer_size = kTransportBufferSize; - param.input_buffer_handle = shared_memory_->handle(); - - GpuVideoDecoderHostMsg_InitializeACK msg2(kDecoderHostId, param); - EXPECT_CALL(*this, OnInitialize(_)) - .WillOnce(SendMessage(decoder_host_.get(), msg2)); - EXPECT_CALL(*this, OnInitializeComplete(_)); - - media::VideoDecoderConfig config( - media::kCodecH264, - kWidth, - kHeight, - kFrameRateNumerator, - kFrameRateDenominator, - NULL, - 0); - decoder_host_->Initialize(&message_loop_, this, &context_, config); - message_loop_.RunAllPending(); - } - - void Uninitialize() { - // A message is sent to GPU process to destroy the decoder. - GpuVideoDecoderHostMsg_DestroyACK msg(kDecoderHostId); - EXPECT_CALL(*this, OnDestroy()) - .WillOnce(SendMessage(decoder_host_.get(), msg)); - EXPECT_CALL(context_, ReleaseAllVideoFrames()); - EXPECT_CALL(*this, OnUninitializeComplete()); - decoder_host_->Uninitialize(); - } - - void AllocateVideoFrames() { - // Expect context is called to allocate video frames. - EXPECT_CALL(context_, - AllocateVideoFrames(kVideoFrames, kWidth, kHeight, - media::VideoFrame::YV12, - NotNull(), NotNull())) - .WillOnce(SimulateAllocateVideoFrames(&frames_)) - .RetiresOnSaturation(); - - // Expect that we send the video frames to the GPU process. - EXPECT_CALL(*this, OnVideoFrameAllocated(_, _)) - .Times(kVideoFrames) - .RetiresOnSaturation(); - - // Pretend that a message is sent to GpuVideoDecoderHost to allocate - // video frames. - GpuVideoDecoderHostMsg_AllocateVideoFrames msg( - kDecoderHostId, kVideoFrames, kWidth, kHeight, - static_cast<int32>(media::VideoFrame::YV12)); - decoder_host_->OnMessageReceived(msg); - } - - void ReleaseVideoFrames() { - // Expect that context is called to release all video frames. - EXPECT_CALL(context_, ReleaseAllVideoFrames()) - .RetiresOnSaturation(); - - // Pretend a message is sent to release all video frames. - GpuVideoDecoderHostMsg_ReleaseAllVideoFrames msg(kDecoderHostId); - decoder_host_->OnMessageReceived(msg); - - // Clear the list of video frames allocated. - frames_.clear(); - } - - void ProduceVideoFrame(int first_frame_id) { - for (int i = 0; i < kVideoFrames; ++i) { - // Expect that a request is received to produce a video frame. - GpuVideoDecoderHostMsg_ConsumeVideoFrame msg( - kDecoderHostId, first_frame_id + i, 0, 0, 0); - EXPECT_CALL(*this, OnProduceVideoFrame(first_frame_id + i)) - .WillOnce(SendMessage(decoder_host_.get(), msg)) - .RetiresOnSaturation(); - - // Expect that a reply is made when a video frame is ready. - EXPECT_CALL(*this, ConsumeVideoFrame(frames_[i], _)) - .RetiresOnSaturation(); - - // Use the allocated video frames to make a request. - decoder_host_->ProduceVideoFrame(frames_[i]); - } - } - - private: - MessageLoop message_loop_; - MessageRouter router_; - media::MockVideoDecodeContext context_; - - scoped_ptr<GpuVideoDecoderHost> decoder_host_; - scoped_ptr<base::SharedMemory> shared_memory_; - - // Keeps the video frames allocated. - std::vector<scoped_refptr<media::VideoFrame> > frames_; -}; - -// Test that when we initialize GpuVideoDecoderHost the corresponding -// IPC messages are sent and at the end OnInitializeComplete() is -// called with the right parameters. -TEST_F(GpuVideoDecoderHostTest, Initialize) { - Initialize(); -} - -// Test that the sequence of method calls and IPC messages is correct. -// And at the end OnUninitializeComplete() is called. -TEST_F(GpuVideoDecoderHostTest, Uninitialize) { - Initialize(); - Uninitialize(); -} - -// Test that IPC messages are sent to GpuVideoDecoderHost and it -// calls VideoDecodeContext to allocate textures and send these -// textures back to the GPU process by IPC messages. -TEST_F(GpuVideoDecoderHostTest, AllocateVideoFrames) { - Initialize(); - AllocateVideoFrames(); - Uninitialize(); -} - -// Test that IPC messages are sent to GpuVideoDecoderHost to -// release textures and VideoDecodeContext is called correctly. -TEST_F(GpuVideoDecoderHostTest, ReleaseVideoFrames) { - Initialize(); - AllocateVideoFrames(); - ReleaseVideoFrames(); - AllocateVideoFrames(); - ReleaseVideoFrames(); - Uninitialize(); -} - -// Test the sequence of IPC messages and methods calls for a decode -// routine. This tests the output port only. -TEST_F(GpuVideoDecoderHostTest, ProduceVideoFrame) { - Initialize(); - AllocateVideoFrames(); - ProduceVideoFrame(0); - ReleaseVideoFrames(); - AllocateVideoFrames(); - ProduceVideoFrame(kVideoFrames); - ReleaseVideoFrames(); - Uninitialize(); -} diff --git a/content/renderer/gpu_video_service_host.cc b/content/renderer/gpu_video_service_host.cc index 7af2a8e..78f2dcc 100644 --- a/content/renderer/gpu_video_service_host.cc +++ b/content/renderer/gpu_video_service_host.cc @@ -5,13 +5,10 @@ #include "content/renderer/gpu_video_service_host.h" #include "content/common/gpu/gpu_messages.h" -#include "content/renderer/gpu_video_decoder_host.h" +#include "content/renderer/gpu_video_decode_accelerator_host.h" #include "content/renderer/render_thread.h" -#include "content/renderer/video_decode_accelerator_host.h" #include "media/video/video_decode_accelerator.h" -using media::VideoDecodeAccelerator; - GpuVideoServiceHost::GpuVideoServiceHost() : channel_(NULL), next_decoder_host_id_(0) { @@ -42,20 +39,18 @@ void GpuVideoServiceHost::OnChannelClosing() { bool GpuVideoServiceHost::OnMessageReceived(const IPC::Message& msg) { switch (msg.type()) { - case GpuVideoDecoderHostMsg_CreateVideoDecoderDone::ID: - case GpuVideoDecoderHostMsg_InitializeACK::ID: - case GpuVideoDecoderHostMsg_DestroyACK::ID: - case GpuVideoDecoderHostMsg_FlushACK::ID: - case GpuVideoDecoderHostMsg_PrerollDone::ID: - case GpuVideoDecoderHostMsg_EmptyThisBufferACK::ID: - case GpuVideoDecoderHostMsg_EmptyThisBufferDone::ID: - case GpuVideoDecoderHostMsg_ConsumeVideoFrame::ID: - case GpuVideoDecoderHostMsg_AllocateVideoFrames::ID: - case GpuVideoDecoderHostMsg_ReleaseAllVideoFrames::ID: - if (!router_.RouteMessage(msg)) { - LOG(ERROR) << "GpuVideoDecoderHostMsg cannot be dispatched."; - } - return true; + case AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed::ID: + case AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers::ID: + case AcceleratedVideoDecoderHostMsg_CreateDone::ID: + case AcceleratedVideoDecoderHostMsg_DismissPictureBuffer::ID: + case AcceleratedVideoDecoderHostMsg_PictureReady::ID: + case AcceleratedVideoDecoderHostMsg_FlushDone::ID: + case AcceleratedVideoDecoderHostMsg_AbortDone::ID: + case AcceleratedVideoDecoderHostMsg_EndOfStream::ID: + case AcceleratedVideoDecoderHostMsg_ErrorNotification::ID: + if (router_.RouteMessage(msg)) + return true; + LOG(ERROR) << "AcceleratedVideoDecoderHostMsg cannot be dispatched."; default: return false; } @@ -76,15 +71,14 @@ void GpuVideoServiceHost::SetOnInitialized( GpuVideoDecoderHost* GpuVideoServiceHost::CreateVideoDecoder( int context_route_id) { - base::AutoLock auto_lock(lock_); - DCHECK(channel_); - return new GpuVideoDecoderHost( - &router_, channel_, context_route_id, ++next_decoder_host_id_); + // TODO(vrk): Delete all references to GpuVideoDecoder (deprecated). + return NULL; } -VideoDecodeAccelerator* GpuVideoServiceHost::CreateVideoAccelerator() { +GpuVideoDecodeAcceleratorHost* GpuVideoServiceHost::CreateVideoAccelerator( + media::VideoDecodeAccelerator::Client* client) { base::AutoLock auto_lock(lock_); - DCHECK(channel_); - return new VideoDecodeAcceleratorHost( - &router_, channel_, next_decoder_host_id_); + DCHECK(channel_); + return new GpuVideoDecodeAcceleratorHost( + &router_, channel_, next_decoder_host_id_++, client); } diff --git a/content/renderer/gpu_video_service_host.h b/content/renderer/gpu_video_service_host.h index 799be5e..eaec14da 100644 --- a/content/renderer/gpu_video_service_host.h +++ b/content/renderer/gpu_video_service_host.h @@ -11,10 +11,9 @@ #include "ipc/ipc_channel.h" #include "media/base/buffers.h" #include "media/base/video_frame.h" +#include "media/video/video_decode_accelerator.h" -namespace media { -class VideoDecodeAccelerator; -} // namespace media +class GpuVideoDecodeAcceleratorHost; // GpuVideoServiceHost lives on IO thread and is used to dispatch IPC messages // to GpuVideoDecoderHost objects. @@ -52,12 +51,15 @@ class GpuVideoServiceHost : public IPC::ChannelProxy::MessageFilter { // Note: OnFilterAdded() MUST be called before these methods are called, // because they require |channel_| to be non-NULL. GpuVideoDecoderHost* CreateVideoDecoder(int context_route_id); - media::VideoDecodeAccelerator* CreateVideoAccelerator(); + + GpuVideoDecodeAcceleratorHost* CreateVideoAccelerator( + media::VideoDecodeAccelerator::Client* client); private: // Guards all members other than |router_|. base::Lock lock_; + // Reference to the channel that the service listens to. IPC::Channel* channel_; // Router to send messages to a GpuVideoDecoderHost. diff --git a/content/renderer/pepper_platform_video_decoder_impl.cc b/content/renderer/pepper_platform_video_decoder_impl.cc index 89a75ce..7d46cf4 100644 --- a/content/renderer/pepper_platform_video_decoder_impl.cc +++ b/content/renderer/pepper_platform_video_decoder_impl.cc @@ -6,16 +6,22 @@ #include <vector> +#include "base/bind.h" #include "base/logging.h" -#include "content/renderer/video_decode_accelerator_host.h" +#include "content/common/child_process.h" +#include "content/renderer/gpu_channel_host.h" +#include "content/renderer/gpu_video_decode_accelerator_host.h" +#include "content/renderer/gpu_video_service_host.h" +#include "content/renderer/render_thread.h" using media::BitstreamBuffer; using media::VideoDecodeAcceleratorCallback; PlatformVideoDecoderImpl::PlatformVideoDecoderImpl( - VideoDecodeAccelerator* video_decode_accelerator) - : client_(NULL), - video_decode_accelerator_(video_decode_accelerator) { + VideoDecodeAccelerator::Client* client) + : client_(client), + decoder_(NULL) { + DCHECK(client); } PlatformVideoDecoderImpl::~PlatformVideoDecoderImpl() {} @@ -23,80 +29,125 @@ PlatformVideoDecoderImpl::~PlatformVideoDecoderImpl() {} void PlatformVideoDecoderImpl::GetConfigs( const std::vector<uint32>& requested_configs, std::vector<uint32>* matched_configs) { + // TODO(vrk): Implement. NOTIMPLEMENTED(); } bool PlatformVideoDecoderImpl::Initialize(const std::vector<uint32>& config) { - // TODO(vmr): Create video decoder in GPU process. + // TODO(vrk): Support multiple decoders. + if (decoder_.get()) + return true; + RenderThread* render_thread = RenderThread::current(); + DCHECK(render_thread); + + channel_ = render_thread->EstablishGpuChannelSync( + content::CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE); + + if (!channel_.get()) + return false; + + DCHECK_EQ(channel_->state(), GpuChannelHost::kConnected); + + // Set a callback to ensure decoder is only initialized after channel is + // connected and GpuVidoServiceHost message filter is added to channel. + // + // TODO(vrk): Initialize should take a callback to be called (on the + // renderer's thread) when initialization is completed. + base::Closure initialize = base::Bind( + &PlatformVideoDecoderImpl::InitializeDecoder, + base::Unretained(this), + config); + + GpuVideoServiceHost* video_service = channel_->gpu_video_service_host(); + video_service->SetOnInitialized(initialize); return true; } -bool PlatformVideoDecoderImpl::Decode( - const BitstreamBuffer& bitstream_buffer, - VideoDecodeAcceleratorCallback* callback) { - // TODO(vmr): Implement me! - NOTIMPLEMENTED(); - // Put the incoming buffer into bitstream_buffer queue - return false; +void PlatformVideoDecoderImpl::InitializeDecoder( + const std::vector<uint32>& configs) { + // Only create GpuVideoDecodeAcceleratorHost on IO thread. + if (ChildProcess::current()->io_message_loop() != MessageLoop::current() ) { + ChildProcess::current()->io_message_loop()-> + PostTask(FROM_HERE, base::Bind( + &PlatformVideoDecoderImpl::InitializeDecoder, + base::Unretained(this), + configs)); + return; + } + GpuVideoServiceHost* video_service = channel_->gpu_video_service_host(); + decoder_.reset(video_service->CreateVideoAccelerator(this)); + + // Send IPC message to initialize decoder in GPU process. + decoder_->Initialize(configs); +} + +bool PlatformVideoDecoderImpl::Decode(const BitstreamBuffer& bitstream_buffer) { + DCHECK(decoder_.get()); + return decoder_->Decode(bitstream_buffer); } void PlatformVideoDecoderImpl::AssignGLESBuffers( const std::vector<media::GLESBuffer>& buffers) { - // TODO(vmr): Implement me! - NOTIMPLEMENTED(); + DCHECK(decoder_.get()); + decoder_->AssignGLESBuffers(buffers); } void PlatformVideoDecoderImpl::AssignSysmemBuffers( const std::vector<media::SysmemBuffer>& buffers) { - // TODO(vmr): Implement me! - NOTIMPLEMENTED(); + DCHECK(decoder_.get()); + decoder_->AssignSysmemBuffers(buffers); } -void PlatformVideoDecoderImpl::ReusePictureBuffer(uint32 picture_buffer_id) { - // TODO(vmr): Implement me! - NOTIMPLEMENTED(); +void PlatformVideoDecoderImpl::ReusePictureBuffer( + int32 picture_buffer_id) { + DCHECK(decoder_.get()); + decoder_->ReusePictureBuffer(picture_buffer_id); } -bool PlatformVideoDecoderImpl::Flush( - VideoDecodeAcceleratorCallback* callback) { - // TODO(vmr): Implement me! - NOTIMPLEMENTED(); - - // Call GPU video decoder to flush. - return video_decode_accelerator_->Flush(callback); +bool PlatformVideoDecoderImpl::Flush() { + DCHECK(decoder_.get()); + return decoder_->Flush(); } -bool PlatformVideoDecoderImpl::Abort( - VideoDecodeAcceleratorCallback* callback) { - // TODO(vmr): Implement me! - NOTIMPLEMENTED(); - - // Call GPU video decoder to abort. - return video_decode_accelerator_->Abort(callback); +bool PlatformVideoDecoderImpl::Abort() { + DCHECK(decoder_.get()); + return decoder_->Abort(); } void PlatformVideoDecoderImpl::NotifyEndOfStream() { - // TODO(vmr): Implement. - NOTIMPLEMENTED(); + client_->NotifyEndOfStream(); } void PlatformVideoDecoderImpl::NotifyError( VideoDecodeAccelerator::Error error) { - // TODO(vmr): Implement. - NOTIMPLEMENTED(); + client_->NotifyError(error); } void PlatformVideoDecoderImpl::ProvidePictureBuffers( uint32 requested_num_of_buffers, - gfx::Size dimensions, + const gfx::Size& dimensions, media::VideoDecodeAccelerator::MemoryType type) { - // TODO(vmr): Implement. - NOTIMPLEMENTED(); + client_->ProvidePictureBuffers(requested_num_of_buffers, dimensions, type); } -void PlatformVideoDecoderImpl::PictureReady( - const media::Picture& picture) { - // TODO(vmr): Implement. - NOTIMPLEMENTED(); +void PlatformVideoDecoderImpl::DismissPictureBuffer(int32 picture_buffer_id) { + client_->DismissPictureBuffer(picture_buffer_id); +} + +void PlatformVideoDecoderImpl::PictureReady(const media::Picture& picture) { + client_->PictureReady(picture); +} + +void PlatformVideoDecoderImpl::NotifyEndOfBitstreamBuffer( + int32 bitstream_buffer_id) { + client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); +} + +void PlatformVideoDecoderImpl::NotifyFlushDone() { + client_->NotifyFlushDone(); +} + +void PlatformVideoDecoderImpl::NotifyAbortDone() { + client_->NotifyAbortDone(); } diff --git a/content/renderer/pepper_platform_video_decoder_impl.h b/content/renderer/pepper_platform_video_decoder_impl.h index d067cff..dd04b80 100644 --- a/content/renderer/pepper_platform_video_decoder_impl.h +++ b/content/renderer/pepper_platform_video_decoder_impl.h @@ -8,15 +8,19 @@ #include <vector> #include "base/scoped_ptr.h" +#include "base/memory/ref_counted.h" #include "media/video/video_decode_accelerator.h" #include "webkit/plugins/ppapi/plugin_delegate.h" +class GpuChannelHost; + class PlatformVideoDecoderImpl : public webkit::ppapi::PluginDelegate::PlatformVideoDecoder, - public media::VideoDecodeAccelerator::Client { + public media::VideoDecodeAccelerator::Client, + public base::RefCountedThreadSafe<PlatformVideoDecoderImpl> { public: explicit PlatformVideoDecoderImpl( - media::VideoDecodeAccelerator* video_decode_accelerator); + media::VideoDecodeAccelerator::Client* client); virtual ~PlatformVideoDecoderImpl(); // PlatformVideoDecoder implementation. @@ -25,35 +29,50 @@ class PlatformVideoDecoderImpl std::vector<uint32>* matched_configs) OVERRIDE; virtual bool Initialize(const std::vector<uint32>& config) OVERRIDE; virtual bool Decode( - const media::BitstreamBuffer& bitstream_buffer, - media::VideoDecodeAcceleratorCallback* callback) OVERRIDE; + const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; virtual void AssignGLESBuffers( const std::vector<media::GLESBuffer>& buffers) OVERRIDE; virtual void AssignSysmemBuffers( const std::vector<media::SysmemBuffer>& buffers) OVERRIDE; - virtual void ReusePictureBuffer(uint32 picture_buffer_id) OVERRIDE; - virtual bool Flush(media::VideoDecodeAcceleratorCallback* callback) OVERRIDE; - virtual bool Abort(media::VideoDecodeAcceleratorCallback* callback) OVERRIDE; + virtual void ReusePictureBuffer(int32 picture_buffer_id); + virtual bool Flush() OVERRIDE; + virtual bool Abort() OVERRIDE; // VideoDecodeAccelerator::Client implementation. virtual void ProvidePictureBuffers( uint32 requested_num_of_buffers, - gfx::Size dimensions, + const gfx::Size& dimensions, media::VideoDecodeAccelerator::MemoryType type) OVERRIDE; - virtual void PictureReady( - const media::Picture& picture) OVERRIDE; + virtual void PictureReady(const media::Picture& picture) OVERRIDE; + virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; virtual void NotifyEndOfStream() OVERRIDE; virtual void NotifyError( media::VideoDecodeAccelerator::Error error) OVERRIDE; + virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; + virtual void NotifyFlushDone() OVERRIDE; + virtual void NotifyAbortDone() OVERRIDE; private: - // EventHandler lifetime must exceed lifetime of this class. + void InitializeDecoder(const std::vector<uint32>& configs); + + // Client lifetime must exceed lifetime of this class. media::VideoDecodeAccelerator::Client* client_; - scoped_ptr<media::VideoDecodeAccelerator> video_decode_accelerator_; - std::vector<uint32> configs; + // Host for GpuVideoDecodeAccelerator. + scoped_ptr<media::VideoDecodeAccelerator> decoder_; + + // Host for Gpu Channel. + scoped_refptr<GpuChannelHost> channel_; DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl); }; +// PlatformVideoDecoderImpl must extend RefCountedThreadSafe in order to post +// tasks on the IO loop. However, it is not actually ref counted: +// PPB_VideoDecode_Impl is the only thing that holds reference to +// PlatformVideoDecoderImpl, so ref counting is unnecessary. +// +// TODO(vrk): Not sure if this is the right thing to do. Talk with fischman. +DISABLE_RUNNABLE_METHOD_REFCOUNT(PlatformVideoDecoderImpl); + #endif // CONTENT_RENDERER_PEPPER_PLATFORM_VIDEO_DECODER_IMPL_H_ diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc index 6c77825..7a94c0e 100644 --- a/content/renderer/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper_plugin_delegate_impl.cc @@ -32,6 +32,7 @@ #include "content/renderer/gpu_channel_host.h" #include "content/renderer/p2p/p2p_transport_impl.h" #include "content/renderer/pepper_platform_context_3d_impl.h" +#include "content/renderer/pepper_platform_video_decoder_impl.h" #include "content/renderer/render_thread.h" #include "content/renderer/render_view.h" #include "content/renderer/render_widget_fullscreen_pepper.h" @@ -814,11 +815,8 @@ webkit::ppapi::PluginDelegate::PlatformContext3D* webkit::ppapi::PluginDelegate::PlatformVideoDecoder* PepperPluginDelegateImpl::CreateVideoDecoder( - PP_VideoConfigElement* decoder_config, media::VideoDecodeAccelerator::Client* client) { - // TODO(vmr): Implement. - NOTIMPLEMENTED(); - return NULL; + return new PlatformVideoDecoderImpl(client); } void PepperPluginDelegateImpl::NumberOfFindResultsChanged(int identifier, diff --git a/content/renderer/pepper_plugin_delegate_impl.h b/content/renderer/pepper_plugin_delegate_impl.h index ab862f2..84240b6 100644 --- a/content/renderer/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper_plugin_delegate_impl.h @@ -175,7 +175,6 @@ class PepperPluginDelegateImpl virtual PlatformImage2D* CreateImage2D(int width, int height); virtual PlatformContext3D* CreateContext3D(); virtual PlatformVideoDecoder* CreateVideoDecoder( - PP_VideoConfigElement* decoder_config, media::VideoDecodeAccelerator::Client* client); virtual PpapiBroker* ConnectToPpapiBroker( webkit::ppapi::PPB_Broker_Impl* client); diff --git a/content/renderer/video_decode_accelerator_host.cc b/content/renderer/video_decode_accelerator_host.cc deleted file mode 100644 index b95ebe7..0000000 --- a/content/renderer/video_decode_accelerator_host.cc +++ /dev/null @@ -1,92 +0,0 @@ -// 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 "content/renderer/video_decode_accelerator_host.h" - -#include "base/logging.h" -#include "base/task.h" - -using media::VideoDecodeAccelerator; -using media::VideoDecodeAcceleratorCallback; - -VideoDecodeAcceleratorHost::VideoDecodeAcceleratorHost( - MessageRouter* router, - IPC::Message::Sender* ipc_sender, - int32 decoder_host_id) - : message_loop_(NULL), - router_(router), - ipc_sender_(ipc_sender), - context_route_id_(0), - decoder_host_id_(decoder_host_id), - decoder_id_(0) { -} - -VideoDecodeAcceleratorHost::~VideoDecodeAcceleratorHost() {} - -void VideoDecodeAcceleratorHost::OnChannelConnected(int32 peer_pid) {} - -void VideoDecodeAcceleratorHost::OnChannelError() { - ipc_sender_ = NULL; -} - -bool VideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - DCHECK(handled); - return handled; -} - -void VideoDecodeAcceleratorHost::GetConfigs( - const std::vector<uint32>& requested_configs, - std::vector<uint32>* matched_configs) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); -} - -bool VideoDecodeAcceleratorHost::Initialize( - const std::vector<uint32>& config) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); - return false; -} - -bool VideoDecodeAcceleratorHost::Decode( - const media::BitstreamBuffer& bitstream_buffer, - VideoDecodeAcceleratorCallback* callback) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); - return false; -} - -void VideoDecodeAcceleratorHost::AssignGLESBuffers( - const std::vector<media::GLESBuffer>& buffers) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); -} - -void VideoDecodeAcceleratorHost::AssignSysmemBuffers( - const std::vector<media::SysmemBuffer>& buffers) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); -} - -void VideoDecodeAcceleratorHost::ReusePictureBuffer(uint32 picture_buffer_id) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); -} - -bool VideoDecodeAcceleratorHost::Flush( - VideoDecodeAcceleratorCallback* callback) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); - return false; -} - -bool VideoDecodeAcceleratorHost::Abort( - VideoDecodeAcceleratorCallback* callback) { - // TODO(vmr): implement. - NOTIMPLEMENTED(); - return false; -} - -DISABLE_RUNNABLE_METHOD_REFCOUNT(VideoDecodeAcceleratorHost); diff --git a/content/renderer/video_decode_accelerator_host.h b/content/renderer/video_decode_accelerator_host.h deleted file mode 100644 index 7d7c3dc..0000000 --- a/content/renderer/video_decode_accelerator_host.h +++ /dev/null @@ -1,78 +0,0 @@ -// 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 CONTENT_RENDERER_VIDEO_DECODE_ACCELERATOR_HOST_H_ -#define CONTENT_RENDERER_VIDEO_DECODE_ACCELERATOR_HOST_H_ - -#include <vector> - -#include "base/memory/scoped_ptr.h" -#include "base/shared_memory.h" -#include "ipc/ipc_channel.h" -#include "media/video/video_decode_accelerator.h" - -class MessageLoop; -class MessageRouter; - -// This class is used to talk to VideoDecodeAccelerator in the GPU process -// through IPC messages. -class VideoDecodeAcceleratorHost : public IPC::Channel::Listener, - public media::VideoDecodeAccelerator { - public: - // |router| is used to dispatch IPC messages to this object. - // |ipc_sender| is used to send IPC messages to GPU process. - VideoDecodeAcceleratorHost(MessageRouter* router, - IPC::Message::Sender* ipc_sender, - int32 decoder_host_id); - virtual ~VideoDecodeAcceleratorHost(); - - // IPC::Channel::Listener implementation. - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; - virtual void OnChannelError() OVERRIDE; - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - - // media::VideoDecodeAccelerator implementation. - virtual void GetConfigs( - const std::vector<uint32>& requested_configs, - std::vector<uint32>* matched_configs) OVERRIDE; - virtual bool Initialize( - const std::vector<uint32>& config) OVERRIDE; - virtual bool Decode( - const media::BitstreamBuffer& bitstream_buffer, - media::VideoDecodeAcceleratorCallback* callback) OVERRIDE; - virtual void AssignGLESBuffers( - const std::vector<media::GLESBuffer>& buffers) OVERRIDE; - virtual void AssignSysmemBuffers( - const std::vector<media::SysmemBuffer>& buffers) OVERRIDE; - virtual void ReusePictureBuffer(uint32 picture_buffer_id) OVERRIDE; - virtual bool Flush(media::VideoDecodeAcceleratorCallback* callback) OVERRIDE; - virtual bool Abort(media::VideoDecodeAcceleratorCallback* callback) OVERRIDE; - - private: - // Message loop that this object runs on. - MessageLoop* message_loop_; - - // A router used to send us IPC messages. - MessageRouter* router_; - - // Sends IPC messages to the GPU process. - IPC::Message::Sender* ipc_sender_; - - // Route ID of the GLES2 context in the GPU process. - int context_route_id_; - - // ID of this VideoDecodeAcceleratorHost. - int32 decoder_host_id_; - - // ID of VideoDecodeAccelerator in the GPU process. - int32 decoder_id_; - - // Transfer buffers for both input and output. - // TODO(vmr): move into plugin provided IPC buffers. - scoped_ptr<base::SharedMemory> input_transfer_buffer_; - - DISALLOW_COPY_AND_ASSIGN(VideoDecodeAcceleratorHost); -}; - -#endif // CONTENT_RENDERER_VIDEO_DECODE_ACCELERATOR_HOST_H_ diff --git a/media/base/bitstream_buffer.h b/media/base/bitstream_buffer.h index 9a68efb..bd9b843 100644 --- a/media/base/bitstream_buffer.h +++ b/media/base/bitstream_buffer.h @@ -11,24 +11,23 @@ namespace media { // Class for passing bitstream buffers around. Ownership of the bitstream // pointer remains with whoever uses this class. +// This is media-namespace equivalent of PP_BitstreamBuffer_Dev. class BitstreamBuffer { public: - BitstreamBuffer(uint8* bitstream, size_t bitstream_size, void* user_handle) - : bitstream_(bitstream), - bitstream_size_(bitstream_size), - user_handle_(user_handle) { + BitstreamBuffer(int32 id, uint8* data, size_t size) + : id_(id), + data_(data), + size_(size) { } - ~BitstreamBuffer() {} - - uint8* bitstream() { return bitstream_; } - size_t bitstream_size() { return bitstream_size_; } - void* user_handle() { return user_handle_; } + int32 id() const { return id_; } + uint8* data() const { return data_; } + size_t size() const { return size_; } private: - uint8* bitstream_; - size_t bitstream_size_; - void* user_handle_; + int32 id_; + uint8* data_; + size_t size_; DISALLOW_IMPLICIT_CONSTRUCTORS(BitstreamBuffer); }; diff --git a/media/video/picture.cc b/media/video/picture.cc index a312eea..581e3c9 100644 --- a/media/video/picture.cc +++ b/media/video/picture.cc @@ -27,4 +27,12 @@ SysmemBuffer::SysmemBuffer(int32 id, gfx::Size size, void* data) info_(id, size) { } +Picture::Picture(int32 picture_buffer_id, int32 bitstream_buffer_id, + gfx::Size visible_size, gfx::Size decoded_size) + : picture_buffer_id_(picture_buffer_id), + bitstream_buffer_id_(bitstream_buffer_id), + visible_size_(visible_size), + decoded_size_(decoded_size) { +} + } // namespace media diff --git a/media/video/picture.h b/media/video/picture.h index 465f3f5..f9611bd 100644 --- a/media/video/picture.h +++ b/media/video/picture.h @@ -93,6 +93,8 @@ class SysmemBuffer { // This is the media-namespace equivalent of PP_Picture_Dev. class Picture { public: + Picture(int32 picture_buffer_id, int32 bitstream_buffer_id, + gfx::Size visible_size, gfx::Size decoded_size); Picture(const PP_Picture_Dev& picture); // Returns the id of the picture buffer where this picture is contained. @@ -100,11 +102,10 @@ class Picture { return picture_buffer_id_; } - // Returns the handle associated with the bitstream buffer from which this - // picture was decoded. + // Returns the id of the bitstream buffer from which this frame was decoded. // TODO(vrk): Handle the case where a picture can span multiple buffers. - void* user_handle() const { - return user_handle_; + int32 bitstream_buffer_id() const { + return bitstream_buffer_id_; } // Returns the visible size of the decoded picture in pixels. @@ -119,7 +120,7 @@ class Picture { private: int32 picture_buffer_id_; - void* user_handle_; + int32 bitstream_buffer_id_; gfx::Size visible_size_; gfx::Size decoded_size_; }; diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index 20ebdd9..807f923 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h @@ -190,7 +190,7 @@ class VideoDecodeAccelerator { // buffer to the decoder. virtual void ProvidePictureBuffers( uint32 requested_num_of_buffers, - gfx::Size dimensions, + const gfx::Size& dimensions, MemoryType type) = 0; // Callback to dismiss picture buffer that was assigned earlier. @@ -203,6 +203,16 @@ class VideoDecodeAccelerator { // outputted all displayable pictures. virtual void NotifyEndOfStream() = 0; + // Callback to notify that decoded has decoded the end of the current + // bitstream buffer. + virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) = 0; + + // Callback to notify that the outstanding flush has finished. + virtual void NotifyFlushDone() = 0; + + // Callback to notify that the outstanding abort has finished. + virtual void NotifyAbortDone() = 0; + // Callback to notify about decoding errors. virtual void NotifyError(Error error) = 0; }; @@ -227,15 +237,13 @@ class VideoDecodeAccelerator { virtual bool Initialize(const std::vector<uint32>& config) = 0; // Decodes given bitstream buffer. Once decoder is done with processing - // |bitstream_buffer| is will call |callback|. + // |bitstream_buffer| it will call NotifyEndOfBitstreamBuffer() with the + // bitstream buffer id. // Parameters: // |bitstream_buffer| is the input bitstream that is sent for decoding. - // |callback| contains the callback function pointer for informing about - // finished processing for |bitstream_buffer|. // // Returns true when command successfully accepted. Otherwise false. - virtual bool Decode(const BitstreamBuffer& bitstream_buffer, - VideoDecodeAcceleratorCallback* callback) = 0; + virtual bool Decode(const BitstreamBuffer& bitstream_buffer) = 0; // Assigns a set of picture buffers to the video decoder. // AssignGLESBuffers assigns texture-backed buffers. @@ -257,29 +265,23 @@ class VideoDecodeAccelerator { // // Parameters: // |picture_buffer_id| id of the picture buffer that is to be reused. - virtual void ReusePictureBuffer(uint32 picture_buffer_id) = 0; + virtual void ReusePictureBuffer(int32 picture_buffer_id) = 0; // Flushes the decoder. Flushing will result in output of the // pictures and buffers held inside the decoder and returning of bitstream // buffers using the callbacks implemented by the plug-in. Once done with - // flushing, the decode will call the |callback|. - // - // Parameters: - // |callback| contains the callback function pointer. + // flushing, the decode will call NotifyFlushDone(). // // Returns true when command successfully accepted. Otherwise false. - virtual bool Flush(VideoDecodeAcceleratorCallback* callback) = 0; + virtual bool Flush() = 0; // Aborts the decoder. Decode will abort the decoding as soon as possible and - // will not output anything. |callback| will be called as soon as abort has + // will not output anything. NotifyAbortDone() is called as soon as abort has // been finished. After abort all buffers can be considered dismissed, even // when there has not been callbacks to dismiss them. // - // Parameters: - // |callback| contains the callback function pointer. - // // Returns true when command successfully accepted. Otherwise false. - virtual bool Abort(VideoDecodeAcceleratorCallback* callback) = 0; + virtual bool Abort() = 0; }; } // namespace media diff --git a/ppapi/c/dev/pp_video_dev.h b/ppapi/c/dev/pp_video_dev.h index 7c4c73b..49eec11 100644 --- a/ppapi/c/dev/pp_video_dev.h +++ b/ppapi/c/dev/pp_video_dev.h @@ -165,15 +165,15 @@ PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_PictureBufferType_Dev, 4); // The data structure for video bitstream buffer. struct PP_VideoBitstreamBuffer_Dev { + // Client-specified identifier for the bitstream buffer. + int32_t id; + // Buffer to hold the bitstream data. Should be allocated using the PPB_Buffer // interface for consistent interprocess behaviour. - PP_Resource bitstream; + PP_Resource data; // Size of the bitstream contained in buffer (in bytes). - int32_t bitstream_size; - - // Handle to identify the bitstream buffer. - void* user_handle; + int32_t size; }; // Struct for specifying data about buffer. @@ -216,6 +216,9 @@ struct PP_Picture_Dev { // ID of the picture buffer where the picture is stored. int32_t picture_buffer_id; + // ID of the bitstream from which this data was decoded. + int32_t bitstream_buffer_id; + // Visible size of the picture. // This describes the dimensions of the picture that is intended to be // displayed from the decoded output. @@ -227,10 +230,6 @@ struct PP_Picture_Dev { // the width of the output. The plugin should handle rendering the frame // appropriately with respect to the sizes. struct PP_Size decoded_size; - - // Handle to identify the bitstream buffer from which this picture was - // decoded. - void* bitstream_user_handle; }; // Enumeration for error events that may be reported through diff --git a/ppapi/c/dev/ppb_video_decoder_dev.h b/ppapi/c/dev/ppb_video_decoder_dev.h index 53869a0..4927c2c 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_6 "PPB_VideoDecoder(Dev);0.6" -#define PPB_VIDEODECODER_DEV_INTERFACE PPB_VIDEODECODER_DEV_INTERFACE_0_6 +#define PPB_VIDEODECODER_DEV_INTERFACE_0_7 "PPB_VideoDecoder(Dev);0.7" +#define PPB_VIDEODECODER_DEV_INTERFACE PPB_VIDEODECODER_DEV_INTERFACE_0_7 // Video decoder interface. // @@ -163,7 +163,7 @@ struct PPB_VideoDecoder_Dev { // // Parameters: // |video_decoder| is the previously created handle to the decoder instance. - // |picture_buffer| contains the reference to the picture buffer that was + // |picture_buffer_id| contains the id of the picture buffer that was // processed. void (*ReusePictureBuffer)(PP_Resource video_decoder, int32_t picture_buffer_id); diff --git a/ppapi/c/dev/ppp_video_decoder_dev.h b/ppapi/c/dev/ppp_video_decoder_dev.h index 7ae8c55..af5eaaf 100644 --- a/ppapi/c/dev/ppp_video_decoder_dev.h +++ b/ppapi/c/dev/ppp_video_decoder_dev.h @@ -7,7 +7,7 @@ #include "ppapi/c/dev/pp_video_dev.h" -#define PPP_VIDEODECODER_DEV_INTERFACE "PPP_VideoDecoder(Dev);0.2" +#define PPP_VIDEODECODER_DEV_INTERFACE "PPP_VideoDecoder(Dev);0.3" // PPP_VideoDecoder_Dev structure contains the function pointers that the // plugin MUST implement to provide services needed by the video decoder diff --git a/ppapi/tests/arch_dependent_sizes_64.h b/ppapi/tests/arch_dependent_sizes_64.h index 80cc7b2..de68721 100644 --- a/ppapi/tests/arch_dependent_sizes_64.h +++ b/ppapi/tests/arch_dependent_sizes_64.h @@ -17,8 +17,8 @@ PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_CompletionCallback_Func, 8); PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_URLLoaderTrusted_StatusCallback, 8); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_CompletionCallback, 16); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_FileChooserOptions_Dev, 16); -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_Picture_Dev, 32); -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoBitstreamBuffer_Dev, 16); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_Picture_Dev, 24); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoBitstreamBuffer_Dev, 12); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PPB_VideoDecoder_Dev, 72); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PPP_VideoDecoder_Dev, 40); diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc index d4e2296..8103a09 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.cc +++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc @@ -41,7 +41,6 @@ MockPluginDelegate::PlatformContext3D* MockPluginDelegate::CreateContext3D() { MockPluginDelegate::PlatformVideoDecoder* MockPluginDelegate::CreateVideoDecoder( - PP_VideoConfigElement* decoder_config, media::VideoDecodeAccelerator::Client* client) { return NULL; } diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h index 1259d36..ac3664a 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.h +++ b/webkit/plugins/ppapi/mock_plugin_delegate.h @@ -22,7 +22,6 @@ class MockPluginDelegate : public PluginDelegate { virtual PlatformImage2D* CreateImage2D(int width, int height); virtual PlatformContext3D* CreateContext3D(); virtual PlatformVideoDecoder* CreateVideoDecoder( - PP_VideoConfigElement* decoder_config, media::VideoDecodeAccelerator::Client* client); virtual PlatformAudio* CreateAudio(uint32_t sample_rate, uint32_t sample_count, diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index d05e8e9..cd714296 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -251,7 +251,6 @@ class PluginDelegate { // The caller will own the pointer returned from this. virtual PlatformVideoDecoder* CreateVideoDecoder( - PP_VideoConfigElement* decoder_config, media::VideoDecodeAccelerator::Client* client) = 0; // The caller is responsible for calling Shutdown() on the returned pointer diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc index 6f0c723..5c317ee 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc @@ -138,8 +138,9 @@ const PPB_VideoDecoder_Dev ppb_videodecoder = { // Utility methods to convert data to and from the ppapi C-types and their // C++ media-namespace equivalents. void CopyToPictureDev(const media::Picture& input, PP_Picture_Dev* output) { + DCHECK(output); output->picture_buffer_id = input.picture_buffer_id(); - output->bitstream_user_handle = input.user_handle(); + output->bitstream_buffer_id = input.bitstream_buffer_id(); output->visible_size = PP_MakeSize(input.visible_size().width(), input.visible_size().height()); output->decoded_size = @@ -148,6 +149,8 @@ void CopyToPictureDev(const media::Picture& input, PP_Picture_Dev* output) { void CopyToConfigList( const PP_VideoConfigElement* configs, std::vector<uint32>* output) { + DCHECK(configs); + DCHECK(output); // TODO(vrk): This is assuming PP_VideoAttributeDictionary and // VideoAttributeKey have identical enum values. There is no compiler // assert to guarantee this. We either need to add such asserts or @@ -214,7 +217,12 @@ bool PPB_VideoDecoder_Impl::Init(PP_VideoConfigElement* decoder_config) { return false; platform_video_decoder_.reset( - instance()->delegate()->CreateVideoDecoder(decoder_config, this)); + instance()->delegate()->CreateVideoDecoder(this)); + + std::vector<uint32> copied; + // TODO(vrk): Validate configs before copy. + CopyToConfigList(decoder_config, &copied); + platform_video_decoder_->Initialize(copied); return platform_video_decoder_.get()? true : false; } @@ -226,20 +234,17 @@ bool PPB_VideoDecoder_Impl::Decode( return false; scoped_refptr<PPB_Buffer_Impl> pepper_buffer = - Resource::GetAs<PPB_Buffer_Impl>(bitstream_buffer->bitstream); + Resource::GetAs<PPB_Buffer_Impl>(bitstream_buffer->data); - media::BitstreamBuffer decode_buffer(pepper_buffer->mapped_buffer(), - bitstream_buffer->bitstream_size, - bitstream_buffer->user_handle); + media::BitstreamBuffer decode_buffer(bitstream_buffer->id, + pepper_buffer->mapped_buffer(), + bitstream_buffer->size); // Store the callback to inform when bitstream buffer has been processed. // TODO(vmr): handle simultaneous decodes + callbacks. bitstream_buffer_callback_ = callback; - return platform_video_decoder_->Decode( - decode_buffer, - callback_factory_.NewCallback( - &PPB_VideoDecoder_Impl::OnBitstreamBufferProcessed)); + return platform_video_decoder_->Decode(decode_buffer); } void PPB_VideoDecoder_Impl::AssignGLESBuffers( @@ -286,9 +291,7 @@ bool PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { // TODO(vmr): Check for current flush/abort operations. flush_callback_ = callback; - return platform_video_decoder_->Flush( - callback_factory_.NewCallback( - &PPB_VideoDecoder_Impl::OnFlushComplete)); + return platform_video_decoder_->Flush(); } bool PPB_VideoDecoder_Impl::Abort(PP_CompletionCallback callback) { @@ -299,14 +302,12 @@ bool PPB_VideoDecoder_Impl::Abort(PP_CompletionCallback callback) { // TODO(vmr): Check for current flush/abort operations. abort_callback_ = callback; - return platform_video_decoder_->Abort( - callback_factory_.NewCallback( - &PPB_VideoDecoder_Impl::OnAbortComplete)); + return platform_video_decoder_->Abort(); } void PPB_VideoDecoder_Impl::ProvidePictureBuffers( uint32 requested_num_of_buffers, - gfx::Size dimensions, + const gfx::Size& dimensions, media::VideoDecodeAccelerator::MemoryType type) { if (!ppp_videodecoder_) return; @@ -321,8 +322,7 @@ void PPB_VideoDecoder_Impl::ProvidePictureBuffers( resource.id, requested_num_of_buffers, out_dim, out_type); } -void PPB_VideoDecoder_Impl::PictureReady( - const media::Picture& picture) { +void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { if (!ppp_videodecoder_) return; @@ -362,7 +362,7 @@ void PPB_VideoDecoder_Impl::NotifyError( static_cast<PP_VideoDecodeError_Dev>(error)); } -void PPB_VideoDecoder_Impl::OnAbortComplete() { +void PPB_VideoDecoder_Impl::NotifyAbortDone() { if (abort_callback_.func == NULL) return; @@ -372,7 +372,8 @@ void PPB_VideoDecoder_Impl::OnAbortComplete() { PP_RunCompletionCallback(&callback, PP_OK); } -void PPB_VideoDecoder_Impl::OnBitstreamBufferProcessed() { +void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( + int32 bitstream_buffer_id) { if (bitstream_buffer_callback_.func == NULL) return; @@ -383,7 +384,7 @@ void PPB_VideoDecoder_Impl::OnBitstreamBufferProcessed() { PP_RunCompletionCallback(&callback, PP_OK); } -void PPB_VideoDecoder_Impl::OnFlushComplete() { +void PPB_VideoDecoder_Impl::NotifyFlushDone() { if (flush_callback_.func == NULL) return; @@ -400,8 +401,8 @@ void PPB_VideoDecoder_Impl::OnFlushComplete() { // dependencies (we can't depend on ppapi types from media). namespace media { BufferInfo::BufferInfo(const PP_BufferInfo_Dev& info) - : id_(info.id) { - size_ = gfx::Size(info.size.width, info.size.height); + : id_(info.id), + size_(info.size.width, info.size.height) { } // TODO(vrk): This assigns the PP_Resource context to be @@ -423,7 +424,7 @@ SysmemBuffer::SysmemBuffer(const PP_SysmemBuffer_Dev& buffer) Picture::Picture(const PP_Picture_Dev& picture) : picture_buffer_id_(picture.picture_buffer_id), - user_handle_(picture.bitstream_user_handle), + bitstream_buffer_id_(picture.bitstream_buffer_id), visible_size_(picture.visible_size.width, picture.visible_size.height), decoded_size_(picture.decoded_size.width, picture.decoded_size.height) { } diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.h b/webkit/plugins/ppapi/ppb_video_decoder_impl.h index 8442c92..85ae9bb 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.h +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.h @@ -16,6 +16,10 @@ #include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/resource.h" +struct PP_GLESBuffer_Dev; +struct PP_SysmemBuffer_Dev; +struct PP_VideoDecoderConfig_Dev; +struct PP_VideoBitstreamBuffer_Dev; struct PPB_VideoDecoder_Dev; struct PPP_VideoDecoder_Dev; @@ -56,20 +60,18 @@ class PPB_VideoDecoder_Impl : public Resource, // media::VideoDecodeAccelerator::Client implementation. virtual void ProvidePictureBuffers( uint32 requested_num_of_buffers, - gfx::Size dimensions, + const gfx::Size& dimensions, media::VideoDecodeAccelerator::MemoryType type) OVERRIDE; virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; - virtual void PictureReady( - const media::Picture& picture) OVERRIDE; + virtual void PictureReady(const media::Picture& picture) OVERRIDE; virtual void NotifyEndOfStream() OVERRIDE; virtual void NotifyError( media::VideoDecodeAccelerator::Error error) OVERRIDE; + virtual void NotifyFlushDone() OVERRIDE; + virtual void NotifyEndOfBitstreamBuffer(int32 buffer_id) OVERRIDE; + virtual void NotifyAbortDone() OVERRIDE; private: - void OnAbortComplete(); - void OnBitstreamBufferProcessed(); - void OnFlushComplete(); - // This is NULL before initialization, and if this PPB_VideoDecoder_Impl is // swapped with another. scoped_ptr<PluginDelegate::PlatformVideoDecoder> platform_video_decoder_; |