diff options
author | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-28 03:14:48 +0000 |
---|---|---|
committer | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-28 03:14:48 +0000 |
commit | 6048d519459f0d665d6887c1eee07b4f15c061c4 (patch) | |
tree | 60bb7ff66c29942b0c4b63031d77493d4678121a /content | |
parent | 6b1ca19adaeab7f3089c9737cca31f5cada373eb (diff) | |
download | chromium_src-6048d519459f0d665d6887c1eee07b4f15c061c4.zip chromium_src-6048d519459f0d665d6887c1eee07b4f15c061c4.tar.gz chromium_src-6048d519459f0d665d6887c1eee07b4f15c061c4.tar.bz2 |
Move audio/video files from content/renderer into content/renderer/media.
Should reduce rubberstampage.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/9295018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119577 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/content_renderer.gypi | 28 | ||||
-rw-r--r-- | content/renderer/media/pepper_platform_video_decoder_impl.cc | 126 | ||||
-rw-r--r-- | content/renderer/media/pepper_platform_video_decoder_impl.h | 63 | ||||
-rw-r--r-- | content/renderer/media/render_audiosourceprovider.cc | 148 | ||||
-rw-r--r-- | content/renderer/media/render_audiosourceprovider.h | 88 | ||||
-rw-r--r-- | content/renderer/media/renderer_gpu_video_decoder_factories.cc | 121 | ||||
-rw-r--r-- | content/renderer/media/renderer_gpu_video_decoder_factories.h | 76 | ||||
-rw-r--r-- | content/renderer/media/renderer_webaudiodevice_impl.cc | 57 | ||||
-rw-r--r-- | content/renderer/media/renderer_webaudiodevice_impl.h | 45 | ||||
-rw-r--r-- | content/renderer/pepper_plugin_delegate_impl.cc | 2 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 4 | ||||
-rw-r--r-- | content/renderer/renderer_webkitplatformsupport_impl.cc | 2 |
12 files changed, 742 insertions, 18 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 7c12475..b79234f 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -58,12 +58,12 @@ 'renderer/geolocation_dispatcher.h', 'renderer/gpu/compositor_thread.cc', 'renderer/gpu/compositor_thread.h', - 'renderer/gpu/input_event_filter.cc', - 'renderer/gpu/input_event_filter.h', 'renderer/gpu/gpu_channel_host.cc', 'renderer/gpu/gpu_channel_host.h', 'renderer/gpu/gpu_video_decode_accelerator_host.cc', 'renderer/gpu/gpu_video_decode_accelerator_host.h', + 'renderer/gpu/input_event_filter.cc', + 'renderer/gpu/input_event_filter.h', 'renderer/gpu/renderer_gl_context.cc', 'renderer/gpu/renderer_gl_context.h', 'renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc', @@ -86,8 +86,6 @@ 'renderer/indexed_db/renderer_webidbobjectstore_impl.h', 'renderer/indexed_db/renderer_webidbtransaction_impl.cc', 'renderer/indexed_db/renderer_webidbtransaction_impl.h', - 'renderer/web_intents_host.cc', - 'renderer/web_intents_host.h', 'renderer/java/java_bridge_channel.cc', 'renderer/java/java_bridge_channel.h', 'renderer/java/java_bridge_dispatcher.cc', @@ -113,8 +111,16 @@ 'renderer/media/media_stream_dispatcher.h', 'renderer/media/media_stream_dispatcher_eventhandler.h', 'renderer/media/media_stream_impl.h', + 'renderer/media/pepper_platform_video_decoder_impl.cc', + 'renderer/media/pepper_platform_video_decoder_impl.h', + 'renderer/media/render_audiosourceprovider.cc', + 'renderer/media/render_audiosourceprovider.h', 'renderer/media/render_media_log.cc', 'renderer/media/render_media_log.h', + 'renderer/media/renderer_gpu_video_decoder_factories.cc', + 'renderer/media/renderer_gpu_video_decoder_factories.h', + 'renderer/media/renderer_webaudiodevice_impl.cc', + 'renderer/media/renderer_webaudiodevice_impl.h', 'renderer/media/rtc_video_decoder.cc', 'renderer/media/rtc_video_decoder.h', 'renderer/media/video_capture_impl.cc', @@ -135,14 +141,10 @@ 'renderer/pepper_parent_context_provider.h', 'renderer/pepper_platform_context_3d_impl.cc', 'renderer/pepper_platform_context_3d_impl.h', - 'renderer/pepper_platform_video_decoder_impl.cc', - 'renderer/pepper_platform_video_decoder_impl.h', 'renderer/pepper_plugin_delegate_impl.cc', 'renderer/pepper_plugin_delegate_impl.h', 'renderer/plugin_channel_host.cc', 'renderer/plugin_channel_host.h', - 'renderer/render_audiosourceprovider.cc', - 'renderer/render_audiosourceprovider.h', 'renderer/render_process.h', 'renderer/render_process_impl.cc', 'renderer/render_process_impl.h', @@ -163,8 +165,6 @@ 'renderer/renderer_accessibility.h', 'renderer/renderer_clipboard_client.cc', 'renderer/renderer_clipboard_client.h', - 'renderer/renderer_gpu_video_decoder_factories.cc', - 'renderer/renderer_gpu_video_decoder_factories.h', 'renderer/renderer_main.cc', 'renderer/renderer_main_platform_delegate.h', 'renderer/renderer_main_platform_delegate_linux.cc', @@ -172,8 +172,6 @@ 'renderer/renderer_main_platform_delegate_win.cc', 'renderer/renderer_webapplicationcachehost_impl.cc', 'renderer/renderer_webapplicationcachehost_impl.h', - 'renderer/renderer_webaudiodevice_impl.cc', - 'renderer/renderer_webaudiodevice_impl.h', 'renderer/renderer_webcookiejar_impl.cc', 'renderer/renderer_webcookiejar_impl.h', 'renderer/renderer_webkitplatformsupport_impl.cc', @@ -188,14 +186,16 @@ 'renderer/text_input_client_observer.h', 'renderer/v8_value_converter_impl.cc', 'renderer/v8_value_converter_impl.h', + 'renderer/web_intents_host.cc', + 'renderer/web_intents_host.h', + 'renderer/web_ui_bindings.cc', + 'renderer/web_ui_bindings.h', 'renderer/webplugin_delegate_proxy.cc', 'renderer/webplugin_delegate_proxy.h', 'renderer/websharedworker_proxy.cc', 'renderer/websharedworker_proxy.h', 'renderer/websharedworkerrepository_impl.cc', 'renderer/websharedworkerrepository_impl.h', - 'renderer/web_ui_bindings.cc', - 'renderer/web_ui_bindings.h', ], 'conditions': [ ['p2p_apis==1', { diff --git a/content/renderer/media/pepper_platform_video_decoder_impl.cc b/content/renderer/media/pepper_platform_video_decoder_impl.cc new file mode 100644 index 0000000..8f95666 --- /dev/null +++ b/content/renderer/media/pepper_platform_video_decoder_impl.cc @@ -0,0 +1,126 @@ +// Copyright (c) 2012 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/media/pepper_platform_video_decoder_impl.h" + +#include <vector> + +#include "base/bind.h" +#include "base/logging.h" +#include "content/common/child_process.h" +#include "content/renderer/gpu/gpu_channel_host.h" +#include "content/renderer/render_thread_impl.h" + +using media::BitstreamBuffer; + +PlatformVideoDecoderImpl::PlatformVideoDecoderImpl( + VideoDecodeAccelerator::Client* client, + int32 command_buffer_route_id) + : client_(client), + command_buffer_route_id_(command_buffer_route_id) { + DCHECK(client); +} + +PlatformVideoDecoderImpl::~PlatformVideoDecoderImpl() {} + +bool PlatformVideoDecoderImpl::Initialize(Profile profile) { + // TODO(vrk): Support multiple decoders. + if (decoder_) + return true; + + RenderThreadImpl* render_thread = RenderThreadImpl::current(); + + // This is not synchronous, but subsequent IPC messages will be buffered, so + // it is okay to immediately send IPC messages through the returned channel. + GpuChannelHost* channel = + render_thread->EstablishGpuChannelSync( + content::CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE); + + if (!channel) + return false; + + DCHECK_EQ(channel->state(), GpuChannelHost::kConnected); + + // Send IPC message to initialize decoder in GPU process. + decoder_ = channel->CreateVideoDecoder( + command_buffer_route_id_, profile, this); + return decoder_.get() != NULL; +} + +void PlatformVideoDecoderImpl::Decode(const BitstreamBuffer& bitstream_buffer) { + DCHECK(decoder_); + decoder_->Decode(bitstream_buffer); +} + +void PlatformVideoDecoderImpl::AssignPictureBuffers( + const std::vector<media::PictureBuffer>& buffers) { + DCHECK(decoder_); + decoder_->AssignPictureBuffers(buffers); +} + +void PlatformVideoDecoderImpl::ReusePictureBuffer( + int32 picture_buffer_id) { + DCHECK(decoder_); + decoder_->ReusePictureBuffer(picture_buffer_id); +} + +void PlatformVideoDecoderImpl::Flush() { + DCHECK(decoder_); + decoder_->Flush(); +} + +void PlatformVideoDecoderImpl::Reset() { + DCHECK(decoder_); + decoder_->Reset(); +} + +void PlatformVideoDecoderImpl::Destroy() { + DCHECK(decoder_); + decoder_->Destroy(); + client_ = NULL; + decoder_ = NULL; +} + +void PlatformVideoDecoderImpl::NotifyError( + VideoDecodeAccelerator::Error error) { + DCHECK(RenderThreadImpl::current()); + client_->NotifyError(error); +} + +void PlatformVideoDecoderImpl::ProvidePictureBuffers( + uint32 requested_num_of_buffers, + const gfx::Size& dimensions) { + DCHECK(RenderThreadImpl::current()); + client_->ProvidePictureBuffers(requested_num_of_buffers, dimensions); +} + +void PlatformVideoDecoderImpl::DismissPictureBuffer(int32 picture_buffer_id) { + DCHECK(RenderThreadImpl::current()); + client_->DismissPictureBuffer(picture_buffer_id); +} + +void PlatformVideoDecoderImpl::PictureReady(const media::Picture& picture) { + DCHECK(RenderThreadImpl::current()); + client_->PictureReady(picture); +} + +void PlatformVideoDecoderImpl::NotifyInitializeDone() { + NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; +} + +void PlatformVideoDecoderImpl::NotifyEndOfBitstreamBuffer( + int32 bitstream_buffer_id) { + DCHECK(RenderThreadImpl::current()); + client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); +} + +void PlatformVideoDecoderImpl::NotifyFlushDone() { + DCHECK(RenderThreadImpl::current()); + client_->NotifyFlushDone(); +} + +void PlatformVideoDecoderImpl::NotifyResetDone() { + DCHECK(RenderThreadImpl::current()); + client_->NotifyResetDone(); +} diff --git a/content/renderer/media/pepper_platform_video_decoder_impl.h b/content/renderer/media/pepper_platform_video_decoder_impl.h new file mode 100644 index 0000000..ac7c02a --- /dev/null +++ b/content/renderer/media/pepper_platform_video_decoder_impl.h @@ -0,0 +1,63 @@ +// Copyright (c) 2012 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_MEDIA_PEPPER_PLATFORM_VIDEO_DECODER_IMPL_H_ +#define CONTENT_RENDERER_MEDIA_PEPPER_PLATFORM_VIDEO_DECODER_IMPL_H_ + +#include <vector> + +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "media/video/video_decode_accelerator.h" +#include "webkit/plugins/ppapi/plugin_delegate.h" + +class PlatformVideoDecoderImpl + : public webkit::ppapi::PluginDelegate::PlatformVideoDecoder, + public media::VideoDecodeAccelerator::Client { + public: + PlatformVideoDecoderImpl( + media::VideoDecodeAccelerator::Client* client, + int32 command_buffer_route_id); + + // PlatformVideoDecoder (a.k.a. VideoDecodeAccelerator) implementation. + virtual bool Initialize(Profile profile) OVERRIDE; + virtual void Decode( + const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; + virtual void AssignPictureBuffers( + const std::vector<media::PictureBuffer>& buffers) OVERRIDE; + virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; + virtual void Flush() OVERRIDE; + virtual void Reset() OVERRIDE; + virtual void Destroy() OVERRIDE; + + // VideoDecodeAccelerator::Client implementation. + virtual void ProvidePictureBuffers( + uint32 requested_num_of_buffers, const gfx::Size& dimensions) OVERRIDE; + virtual void PictureReady(const media::Picture& picture) OVERRIDE; + virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; + virtual void NotifyInitializeDone() OVERRIDE; + virtual void NotifyError( + media::VideoDecodeAccelerator::Error error) OVERRIDE; + virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; + virtual void NotifyFlushDone() OVERRIDE; + virtual void NotifyResetDone() OVERRIDE; + + private: + virtual ~PlatformVideoDecoderImpl(); + + // Client lifetime must exceed lifetime of this class. + // TODO(vrk/fischman): We should take another look at the overall + // arcitecture of PPAPI Video Decode to make sure lifetime/ownership makes + // sense, including lifetime of this client. + media::VideoDecodeAccelerator::Client* client_; + + // Route ID for the command buffer associated with video decoder's context. + int32 command_buffer_route_id_; + + // Holds a GpuVideoDecodeAcceleratorHost. + scoped_refptr<media::VideoDecodeAccelerator> decoder_; + + DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl); +}; +#endif // CONTENT_RENDERER_MEDIA_PEPPER_PLATFORM_VIDEO_DECODER_IMPL_H_ diff --git a/content/renderer/media/render_audiosourceprovider.cc b/content/renderer/media/render_audiosourceprovider.cc new file mode 100644 index 0000000..39bb84c --- /dev/null +++ b/content/renderer/media/render_audiosourceprovider.cc @@ -0,0 +1,148 @@ +// Copyright (c) 2012 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/media/render_audiosourceprovider.h" + +#include "base/basictypes.h" +#include "base/logging.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebAudioSourceProviderClient.h" + +using std::vector; +using WebKit::WebVector; + +RenderAudioSourceProvider::RenderAudioSourceProvider() + : is_initialized_(false), + channels_(0), + sample_rate_(0.0), + is_running_(false), + volume_(1.0), + renderer_(NULL), + client_(NULL) { + // We create the AudioDevice here because it must be created in the + // main thread. But we don't yet know the audio format (sample-rate, etc.) + // at this point. Later, when Initialize() is called, we have + // the audio format information and call the AudioDevice::Initialize() + // method to fully initialize it. + default_sink_ = new AudioDevice(); +} + +RenderAudioSourceProvider::~RenderAudioSourceProvider() {} + +void RenderAudioSourceProvider::Start() { + base::AutoLock auto_lock(sink_lock_); + if (!client_) + default_sink_->Start(); + is_running_ = true; +} + +void RenderAudioSourceProvider::Stop() { + base::AutoLock auto_lock(sink_lock_); + if (!client_) + default_sink_->Stop(); + is_running_ = false; +} + +void RenderAudioSourceProvider::Play() { + base::AutoLock auto_lock(sink_lock_); + if (!client_) + default_sink_->Play(); + is_running_ = true; +} + +void RenderAudioSourceProvider::Pause(bool flush) { + base::AutoLock auto_lock(sink_lock_); + if (!client_) + default_sink_->Pause(flush); + is_running_ = false; +} + +bool RenderAudioSourceProvider::SetVolume(double volume) { + base::AutoLock auto_lock(sink_lock_); + if (!client_) + default_sink_->SetVolume(volume); + volume_ = volume; + return true; +} + +void RenderAudioSourceProvider::GetVolume(double* volume) { + if (!client_) + default_sink_->GetVolume(volume); + else if (volume) + *volume = volume_; +} + +void RenderAudioSourceProvider::Initialize( + size_t buffer_size, + int channels, + double sample_rate, + AudioParameters::Format latency_format, + RenderCallback* renderer) { + base::AutoLock auto_lock(sink_lock_); + CHECK(!is_initialized_); + renderer_ = renderer; + + default_sink_->Initialize(buffer_size, + channels, + sample_rate, + latency_format, + renderer); + + if (client_) { + // Inform WebKit about the audio stream format. + client_->setFormat(channels, sample_rate); + } + + // Keep track of the format in case the client hasn't yet been set. + channels_ = channels; + sample_rate_ = sample_rate; + is_initialized_ = true; +} + +void RenderAudioSourceProvider::setClient( + WebKit::WebAudioSourceProviderClient* client) { + // Synchronize with other uses of client_ and default_sink_. + base::AutoLock auto_lock(sink_lock_); + + if (client && client != client_) { + // Detach the audio renderer from normal playback. + default_sink_->Pause(true); + + // The client will now take control by calling provideInput() periodically. + client_ = client; + + if (is_initialized_) { + // The client needs to be notified of the audio format, if available. + // If the format is not yet available, we'll be notified later + // when Initialize() is called. + + // Inform WebKit about the audio stream format. + client->setFormat(channels_, sample_rate_); + } + } else if (!client && client_) { + // Restore normal playback. + client_ = NULL; + // TODO(crogers): We should call default_sink_->Play() if we're + // in the playing state. + } +} + +void RenderAudioSourceProvider::provideInput( + const WebVector<float*>& audio_data, size_t number_of_frames) { + DCHECK(client_); + + if (renderer_ && is_initialized_ && is_running_) { + // Wrap WebVector as std::vector. + vector<float*> v(audio_data.size()); + for (size_t i = 0; i < audio_data.size(); ++i) + v[i] = audio_data[i]; + + // TODO(crogers): figure out if we should volume scale here or in common + // WebAudio code. In any case we need to take care of volume. + renderer_->Render(v, number_of_frames, 0); + } else { + // Provide silence if the source is not running. + for (size_t i = 0; i < audio_data.size(); ++i) + memset(audio_data[i], 0, sizeof(float) * number_of_frames); + } +} diff --git a/content/renderer/media/render_audiosourceprovider.h b/content/renderer/media/render_audiosourceprovider.h new file mode 100644 index 0000000..abe661d --- /dev/null +++ b/content/renderer/media/render_audiosourceprovider.h @@ -0,0 +1,88 @@ +// Copyright (c) 2012 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. +// +// RenderAudioSourceProvider provides a bridge between classes: +// WebKit::WebAudioSourceProvider <---> media::AudioRendererSink +// +// RenderAudioSourceProvider is a "sink" of audio, and uses a default +// AudioDevice if a client has not explicitly been set. +// +// WebKit optionally sets a client, and then periodically calls provideInput() +// to render a certain number of audio sample-frames. provideInput() +// uses the renderer to get this data, and then massages it into the form +// required by provideInput(). In this case, the default AudioDevice +// is no longer used. +// +// THREAD SAFETY: +// It is assumed that the callers to setClient() and provideInput() +// implement appropriate locking for thread safety when making +// these calls. This happens in WebKit. + +#ifndef CONTENT_RENDERER_MEDIA_RENDER_AUDIOSOURCEPROVIDER_H_ +#define CONTENT_RENDERER_MEDIA_RENDER_AUDIOSOURCEPROVIDER_H_ + +#include <vector> + +#include "content/renderer/media/audio_device.h" +#include "media/base/audio_renderer_sink.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebAudioSourceProvider.h" + +namespace WebKit { +class WebAudioSourceProviderClient; +} + +class RenderAudioSourceProvider + : public WebKit::WebAudioSourceProvider, + public media::AudioRendererSink { + public: + RenderAudioSourceProvider(); + virtual ~RenderAudioSourceProvider(); + + // WebKit::WebAudioSourceProvider implementation. + + // WebKit calls setClient() if it desires to take control of the rendered + // audio stream. We call client's setFormat() when the audio stream format + // is known. + virtual void setClient(WebKit::WebAudioSourceProviderClient* client); + + // If setClient() has been called, then WebKit calls provideInput() + // periodically to get the rendered audio stream. + virtual void provideInput(const WebKit::WebVector<float*>& audio_data, + size_t number_of_frames); + + // AudioRendererSink implementation. + virtual void Start() OVERRIDE; + virtual void Stop() OVERRIDE; + virtual void Play() OVERRIDE; + virtual void Pause(bool flush) OVERRIDE; + virtual bool SetVolume(double volume) OVERRIDE; + virtual void GetVolume(double* volume) OVERRIDE; + virtual void Initialize(size_t buffer_size, + int channels, + double sample_rate, + AudioParameters::Format latency_format, + RenderCallback* renderer) OVERRIDE; + + private: + // Set to true when Initialize() is called. + bool is_initialized_; + int channels_; + double sample_rate_; + + bool is_running_; + double volume_; + media::AudioRendererSink::RenderCallback* renderer_; + WebKit::WebAudioSourceProviderClient* client_; + + // Protects access to sink_ + base::Lock sink_lock_; + + // default_sink_ is the default sink. + scoped_refptr<media::AudioRendererSink> default_sink_; + + DISALLOW_COPY_AND_ASSIGN(RenderAudioSourceProvider); +}; + +#endif // CONTENT_RENDERER_MEDIA_RENDER_AUDIOSOURCEPROVIDER_H_ diff --git a/content/renderer/media/renderer_gpu_video_decoder_factories.cc b/content/renderer/media/renderer_gpu_video_decoder_factories.cc new file mode 100644 index 0000000..20a32cf --- /dev/null +++ b/content/renderer/media/renderer_gpu_video_decoder_factories.cc @@ -0,0 +1,121 @@ +// Copyright (c) 2012 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/media/renderer_gpu_video_decoder_factories.h" + +#include "base/bind.h" +#include "base/synchronization/waitable_event.h" +#include "content/common/child_thread.h" +#include "content/renderer/gpu/command_buffer_proxy.h" +#include "content/renderer/gpu/gpu_channel_host.h" +#include "content/renderer/gpu/renderer_gl_context.h" +#include "gpu/command_buffer/client/gles2_implementation.h" + +RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {} +RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories( + GpuChannelHost* gpu_channel_host, base::WeakPtr<RendererGLContext> context) + : message_loop_(MessageLoop::current()), + gpu_channel_host_(gpu_channel_host), + context_(context) { +} + +media::VideoDecodeAccelerator* +RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( + media::VideoDecodeAccelerator::Profile profile, + media::VideoDecodeAccelerator::Client* client) { + media::VideoDecodeAccelerator* vda = NULL; + base::WaitableEvent waiter(false, false); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, + this, profile, client, &vda, &waiter)); + waiter.Wait(); + return vda; +} + +void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator( + media::VideoDecodeAccelerator::Profile profile, + media::VideoDecodeAccelerator::Client* client, + media::VideoDecodeAccelerator** vda, + base::WaitableEvent* waiter) { + if (context_) { + *vda = gpu_channel_host_->CreateVideoDecoder( + context_->GetCommandBufferProxy()->route_id(), profile, client); + } else { + *vda = NULL; + } + waiter->Signal(); +} + +bool RendererGpuVideoDecoderFactories::CreateTextures( + int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids) { + bool success = false; + base::WaitableEvent waiter(false, false); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, + count, size, texture_ids, &success, &waiter)); + waiter.Wait(); + return success; +} + +void RendererGpuVideoDecoderFactories::AsyncCreateTextures( + int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids, + bool* success, base::WaitableEvent* waiter) { + if (!context_) { + *success = false; + waiter->Signal(); + return; + } + gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); + texture_ids->resize(count); + gles2->GenTextures(count, &texture_ids->at(0)); + for (int i = 0; i < count; ++i) { + gles2->ActiveTexture(GL_TEXTURE0); + uint32 texture_id = texture_ids->at(i); + gles2->BindTexture(GL_TEXTURE_2D, texture_id); + gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gles2->TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gles2->TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gles2->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } + // We need a glFlush here to guarantee the decoder (in the GPU process) can + // use the texture ids we return here. Since textures are expected to be + // reused, this should not be unacceptably expensive. + gles2->Flush(); + DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); + *success = true; + waiter->Signal(); +} + +void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); +} + +void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { + DCHECK_EQ(MessageLoop::current(), message_loop_); + if (!context_) + return; + gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); + gles2->DeleteTextures(1, &texture_id); + DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); +} + +base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( + size_t size) { + base::SharedMemory* shm = NULL; + base::WaitableEvent waiter(false, false); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, + size, &shm, &waiter)); + waiter.Wait(); + return shm; +} + +void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory( + size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter) { + *shm = ChildThread::current()->AllocateSharedMemory(size); + waiter->Signal(); +} diff --git a/content/renderer/media/renderer_gpu_video_decoder_factories.h b/content/renderer/media/renderer_gpu_video_decoder_factories.h new file mode 100644 index 0000000..5e5715c --- /dev/null +++ b/content/renderer/media/renderer_gpu_video_decoder_factories.h @@ -0,0 +1,76 @@ +// Copyright (c) 2012 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_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ +#define CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" +#include "media/filters/gpu_video_decoder.h" +#include "ui/gfx/size.h" + +class GpuChannelHost; +class RendererGLContext; +namespace base { +class WaitableEvent; +} + +// Glue code to expose functionality needed by media::GpuVideoDecoder to +// RenderViewImpl. This class is entirely an implementation detail of +// RenderViewImpl and only has its own header to allow extraction of its +// implementation from render_view_impl.cc which is already far too large. +// +// The public methods of the class can be called from any thread, and are +// internally trampolined to the thread on which the class was constructed +// (de-facto, the renderer thread) if called from a different thread. +class CONTENT_EXPORT RendererGpuVideoDecoderFactories + : public media::GpuVideoDecoder::Factories { + public: + // Takes a ref on |gpu_channel_host| and tests |context| for NULL before each + // use. + RendererGpuVideoDecoderFactories(GpuChannelHost* gpu_channel_host, + base::WeakPtr<RendererGLContext> context); + + virtual media::VideoDecodeAccelerator* CreateVideoDecodeAccelerator( + media::VideoDecodeAccelerator::Profile profile, + media::VideoDecodeAccelerator::Client* client) OVERRIDE; + + virtual bool CreateTextures(int32 count, const gfx::Size& size, + std::vector<uint32>* texture_ids) OVERRIDE; + + virtual void DeleteTexture(uint32 texture_id) OVERRIDE; + + virtual base::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE; + + protected: + friend class base::RefCountedThreadSafe<RendererGpuVideoDecoderFactories>; + virtual ~RendererGpuVideoDecoderFactories(); + + private: + // Async versions of the public methods. These all run on |message_loop_| + // exclusively, and use output parameters instead of return values. Finally, + // each takes a WaitableEvent* param to signal completion (except for + // DeleteTexture, which is fire-and-forget). + void AsyncCreateVideoDecodeAccelerator( + media::VideoDecodeAccelerator::Profile profile, + media::VideoDecodeAccelerator::Client* client, + media::VideoDecodeAccelerator** vda, + base::WaitableEvent* waiter); + void AsyncCreateTextures( + int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids, + bool* success, base::WaitableEvent* waiter); + void AsyncDeleteTexture(uint32 texture_id); + void AsyncCreateSharedMemory( + size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter); + + MessageLoop* message_loop_; + scoped_refptr<GpuChannelHost> gpu_channel_host_; + base::WeakPtr<RendererGLContext> context_; + DISALLOW_IMPLICIT_CONSTRUCTORS(RendererGpuVideoDecoderFactories); +}; + +#endif // CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ diff --git a/content/renderer/media/renderer_webaudiodevice_impl.cc b/content/renderer/media/renderer_webaudiodevice_impl.cc new file mode 100644 index 0000000..a59e365 --- /dev/null +++ b/content/renderer/media/renderer_webaudiodevice_impl.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2012 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/media/renderer_webaudiodevice_impl.h" + +using WebKit::WebAudioDevice; +using WebKit::WebVector; + +RendererWebAudioDeviceImpl::RendererWebAudioDeviceImpl(size_t buffer_size, + int channels, double sample_rate, WebAudioDevice::RenderCallback* callback) + : is_running_(false), + client_callback_(callback) { + audio_device_ = new AudioDevice(buffer_size, channels, sample_rate, this); +} + +RendererWebAudioDeviceImpl::~RendererWebAudioDeviceImpl() { + stop(); +} + +void RendererWebAudioDeviceImpl::start() { + if (!is_running_) { + audio_device_->Start(); + is_running_ = true; + } +} + +void RendererWebAudioDeviceImpl::stop() { + if (is_running_) { + audio_device_->Stop(); + is_running_ = false; + } +} + +double RendererWebAudioDeviceImpl::sampleRate() { + return 44100.0; +} + +size_t RendererWebAudioDeviceImpl::Render(const std::vector<float*>& audio_data, + size_t number_of_frames, + size_t audio_delay_milliseconds) { + // Make the client callback to get rendered audio. + DCHECK(client_callback_); + if (client_callback_) { + // Wrap the pointers using WebVector. + WebVector<float*> web_audio_data(audio_data.size()); + for (size_t i = 0; i < audio_data.size(); ++i) + web_audio_data[i] = audio_data[i]; + + client_callback_->render(web_audio_data, number_of_frames); + } + return number_of_frames; +} + +void RendererWebAudioDeviceImpl::OnError() { + // TODO(crogers): implement error handling. +} diff --git a/content/renderer/media/renderer_webaudiodevice_impl.h b/content/renderer/media/renderer_webaudiodevice_impl.h new file mode 100644 index 0000000..7b5717f --- /dev/null +++ b/content/renderer/media/renderer_webaudiodevice_impl.h @@ -0,0 +1,45 @@ +// Copyright (c) 2012 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_MEDIA_MEDIA_RENDERER_WEBAUDIODEVICE_IMPL_H_ +#define CONTENT_RENDERER_MEDIA_MEDIA_RENDERER_WEBAUDIODEVICE_IMPL_H_ + +#include <vector> + +#include "base/memory/ref_counted.h" +#include "content/renderer/media/audio_device.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebAudioDevice.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" + +class RendererWebAudioDeviceImpl : public WebKit::WebAudioDevice, + public AudioDevice::RenderCallback { + public: + RendererWebAudioDeviceImpl(size_t buffer_size, + int channels, + double sample_rate, + WebKit::WebAudioDevice::RenderCallback* callback); + virtual ~RendererWebAudioDeviceImpl(); + + // WebKit::WebAudioDevice implementation. + virtual void start(); + virtual void stop(); + virtual double sampleRate(); + + // AudioDevice::RenderCallback implementation. + virtual size_t Render(const std::vector<float*>& audio_data, + size_t number_of_frames, + size_t audio_delay_milliseconds) OVERRIDE; + virtual void OnError() OVERRIDE; + + private: + scoped_refptr<AudioDevice> audio_device_; + bool is_running_; + + // Weak reference to the callback into WebKit code. + WebKit::WebAudioDevice::RenderCallback* client_callback_; + + DISALLOW_COPY_AND_ASSIGN(RendererWebAudioDeviceImpl); +}; + +#endif // CONTENT_RENDERER_MEDIA_MEDIA_RENDERER_WEBAUDIODEVICE_IMPL_H_ diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc index 063ff69..b736ef5 100644 --- a/content/renderer/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper_plugin_delegate_impl.cc @@ -38,10 +38,10 @@ #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" #include "content/renderer/media/audio_input_message_filter.h" #include "content/renderer/media/audio_message_filter.h" +#include "content/renderer/media/pepper_platform_video_decoder_impl.h" #include "content/renderer/media/video_capture_impl_manager.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_impl.h" #include "content/renderer/render_view_impl.h" #include "content/renderer/render_widget_fullscreen_pepper.h" diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index b76e2a8..e8a32e1 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -62,18 +62,18 @@ #include "content/renderer/media/media_stream_dependency_factory.h" #include "content/renderer/media/media_stream_dispatcher.h" #include "content/renderer/media/media_stream_impl.h" +#include "content/renderer/media/render_audiosourceprovider.h" #include "content/renderer/media/render_media_log.h" +#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include "content/renderer/mhtml_generator.h" #include "content/renderer/mouse_lock_dispatcher.h" #include "content/renderer/notification_provider.h" #include "content/renderer/p2p/socket_dispatcher.h" #include "content/renderer/plugin_channel_host.h" -#include "content/renderer/render_audiosourceprovider.h" #include "content/renderer/render_process.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_widget_fullscreen_pepper.h" #include "content/renderer/renderer_accessibility.h" -#include "content/renderer/renderer_gpu_video_decoder_factories.h" #include "content/renderer/renderer_webapplicationcachehost_impl.h" #include "content/renderer/renderer_webstoragenamespace_impl.h" #include "content/renderer/speech_input_dispatcher.h" diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc index 05d96c9..80bb6fa 100644 --- a/content/renderer/renderer_webkitplatformsupport_impl.cc +++ b/content/renderer/renderer_webkitplatformsupport_impl.cc @@ -25,10 +25,10 @@ #include "content/renderer/indexed_db/renderer_webidbfactory_impl.h" #include "content/renderer/media/audio_device.h" #include "content/renderer/media/audio_hardware.h" +#include "content/renderer/media/renderer_webaudiodevice_impl.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" #include "content/renderer/renderer_clipboard_client.h" -#include "content/renderer/renderer_webaudiodevice_impl.h" #include "content/renderer/renderer_webstoragenamespace_impl.h" #include "content/renderer/websharedworkerrepository_impl.h" #include "googleurl/src/gurl.h" |