diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-03 18:57:24 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-03 18:57:24 +0000 |
commit | 1cfb7420fb7ea2fa5a6360bbee5424918e84a027 (patch) | |
tree | 6ca1fd441d8675a06370fc54ac06bcbeb099b5fa /chrome/renderer | |
parent | 6b723128f5c6b090b87949875dcc4e55304a4461 (diff) | |
download | chromium_src-1cfb7420fb7ea2fa5a6360bbee5424918e84a027.zip chromium_src-1cfb7420fb7ea2fa5a6360bbee5424918e84a027.tar.gz chromium_src-1cfb7420fb7ea2fa5a6360bbee5424918e84a027.tar.bz2 |
Complete initializing a GPU video decoder in a GLES2 context
In this patch a ggl::Context is connected to the GpuVideoDecoderHost in the
renderer process. In the GPU process the GpuVideoDecoder is connected to a
gles2::GLES2Decoder.
These changes will be used in the future to switch context before issuing
video decode commands. This is also needed by the GPU process to translate
a client texture ID to a service texture ID in the GPU video decoder.
BUG=53714
TEST=none
Review URL: http://codereview.chromium.org/3266008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58518 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/gpu_video_decoder_host.cc | 3 | ||||
-rw-r--r-- | chrome/renderer/gpu_video_decoder_host.h | 6 | ||||
-rw-r--r-- | chrome/renderer/media/ipc_video_decoder.cc | 92 | ||||
-rw-r--r-- | chrome/renderer/media/ipc_video_decoder.h | 63 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 7 |
5 files changed, 92 insertions, 79 deletions
diff --git a/chrome/renderer/gpu_video_decoder_host.cc b/chrome/renderer/gpu_video_decoder_host.cc index c24d074..7c81e61 100644 --- a/chrome/renderer/gpu_video_decoder_host.cc +++ b/chrome/renderer/gpu_video_decoder_host.cc @@ -55,6 +55,7 @@ bool GpuVideoDecoderHost::Initialize(EventHandler* event_handler, // TODO(hclam): Pass the context route ID here. // TODO(hclam): This create video decoder operation is synchronous, need to // make it asynchronous. + decoder_info_.context_id = context_route_id_; if (!channel_host_->Send( new GpuChannelMsg_CreateVideoDecoder(&decoder_info_))) { LOG(ERROR) << "GpuChannelMsg_CreateVideoDecoder failed"; @@ -79,6 +80,8 @@ bool GpuVideoDecoderHost::Uninitialize() { LOG(ERROR) << "GpuVideoDecoderMsg_Destroy failed"; return false; } + + gpu_video_service_host_->RemoveRoute(my_route_id()); return true; } diff --git a/chrome/renderer/gpu_video_decoder_host.h b/chrome/renderer/gpu_video_decoder_host.h index 8360461..02f8fc8 100644 --- a/chrome/renderer/gpu_video_decoder_host.h +++ b/chrome/renderer/gpu_video_decoder_host.h @@ -53,9 +53,9 @@ class GpuVideoDecoderHost void FillThisBuffer(scoped_refptr<VideoFrame> frame); bool Flush(); - int32 decoder_id() { return decoder_info_.decoder_id_; } - int32 route_id() { return decoder_info_.decoder_route_id_; } - int32 my_route_id() { return decoder_info_.decoder_host_route_id_; } + int32 decoder_id() { return decoder_info_.decoder_id; } + int32 route_id() { return decoder_info_.decoder_route_id; } + int32 my_route_id() { return decoder_info_.decoder_host_route_id; } virtual ~GpuVideoDecoderHost() {} diff --git a/chrome/renderer/media/ipc_video_decoder.cc b/chrome/renderer/media/ipc_video_decoder.cc index 205e857..94f506b 100644 --- a/chrome/renderer/media/ipc_video_decoder.cc +++ b/chrome/renderer/media/ipc_video_decoder.cc @@ -2,7 +2,6 @@ // source code is governed by a BSD-style license that can be found in the // LICENSE file. - #include "chrome/renderer/media/ipc_video_decoder.h" #include "base/task.h" @@ -17,22 +16,22 @@ #include "media/ffmpeg/ffmpeg_util.h" #include "media/filters/ffmpeg_interfaces.h" -namespace media { - -IpcVideoDecoder::IpcVideoDecoder(MessageLoop* message_loop) +IpcVideoDecoder::IpcVideoDecoder(MessageLoop* message_loop, + ggl::Context* ggl_context) : width_(0), height_(0), state_(kUnInitialized), pending_reads_(0), pending_requests_(0), - renderer_thread_message_loop_(message_loop) { + renderer_thread_message_loop_(message_loop), + ggl_context_(ggl_context) { } IpcVideoDecoder::~IpcVideoDecoder() { } -void IpcVideoDecoder::Initialize(DemuxerStream* demuxer_stream, - FilterCallback* callback) { +void IpcVideoDecoder::Initialize(media::DemuxerStream* demuxer_stream, + media::FilterCallback* callback) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -43,7 +42,7 @@ void IpcVideoDecoder::Initialize(DemuxerStream* demuxer_stream, return; } - CHECK(!demuxer_stream_); + DCHECK(!demuxer_stream_); demuxer_stream_ = demuxer_stream; initialize_callback_.reset(callback); @@ -53,7 +52,7 @@ void IpcVideoDecoder::Initialize(DemuxerStream* demuxer_stream, demuxer_stream->EnableBitstreamConverter(); // Get the AVStream by querying for the provider interface. - AVStreamProvider* av_stream_provider; + media::AVStreamProvider* av_stream_provider; if (!demuxer_stream->QueryInterface(&av_stream_provider)) { GpuVideoDecoderInitDoneParam param; OnInitializeDone(false, param); @@ -89,25 +88,25 @@ void IpcVideoDecoder::OnInitializeDone( return; } - AutoCallbackRunner done_runner(initialize_callback_.release()); + media::AutoCallbackRunner done_runner(initialize_callback_.release()); if (success) { - media_format_.SetAsString(MediaFormat::kMimeType, - mime_type::kUncompressedVideo); - media_format_.SetAsInteger(MediaFormat::kWidth, width_); - media_format_.SetAsInteger(MediaFormat::kHeight, height_); - media_format_.SetAsInteger(MediaFormat::kSurfaceType, + media_format_.SetAsString(media::MediaFormat::kMimeType, + media::mime_type::kUncompressedVideo); + media_format_.SetAsInteger(media::MediaFormat::kWidth, width_); + media_format_.SetAsInteger(media::MediaFormat::kHeight, height_); + media_format_.SetAsInteger(media::MediaFormat::kSurfaceType, static_cast<int>(param.surface_type_)); - media_format_.SetAsInteger(MediaFormat::kSurfaceFormat, + media_format_.SetAsInteger(media::MediaFormat::kSurfaceFormat, static_cast<int>(param.format_)); state_ = kPlaying; } else { LOG(ERROR) << "IpcVideoDecoder initialization failed!"; - host()->SetError(PIPELINE_ERROR_DECODE); + host()->SetError(media::PIPELINE_ERROR_DECODE); } } -void IpcVideoDecoder::Stop(FilterCallback* callback) { +void IpcVideoDecoder::Stop(media::FilterCallback* callback) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -133,16 +132,16 @@ void IpcVideoDecoder::OnUninitializeDone() { return; } - AutoCallbackRunner done_runner(stop_callback_.release()); + media::AutoCallbackRunner done_runner(stop_callback_.release()); state_ = kStopped; } -void IpcVideoDecoder::Pause(FilterCallback* callback) { +void IpcVideoDecoder::Pause(media::FilterCallback* callback) { Flush(callback); // TODO(jiesun): move this to flush(). } -void IpcVideoDecoder::Flush(FilterCallback* callback) { +void IpcVideoDecoder::Flush(media::FilterCallback* callback) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -177,7 +176,8 @@ void IpcVideoDecoder::OnFlushDone() { } } -void IpcVideoDecoder::Seek(base::TimeDelta time, FilterCallback* callback) { +void IpcVideoDecoder::Seek(base::TimeDelta time, + media::FilterCallback* callback) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -191,7 +191,7 @@ void IpcVideoDecoder::Seek(base::TimeDelta time, FilterCallback* callback) { OnSeekComplete(callback); } -void IpcVideoDecoder::OnSeekComplete(FilterCallback* callback) { +void IpcVideoDecoder::OnSeekComplete(media::FilterCallback* callback) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -201,7 +201,7 @@ void IpcVideoDecoder::OnSeekComplete(FilterCallback* callback) { return; } - AutoCallbackRunner done_runner(callback); + media::AutoCallbackRunner done_runner(callback); state_ = kPlaying; @@ -213,12 +213,13 @@ void IpcVideoDecoder::OnSeekComplete(FilterCallback* callback) { } } -void IpcVideoDecoder::OnReadComplete(Buffer* buffer) { - scoped_refptr<Buffer> buffer_ref = buffer; +void IpcVideoDecoder::OnReadComplete(media::Buffer* buffer) { + scoped_refptr<media::Buffer> buffer_ref = buffer; ReadCompleteTask(buffer_ref); } -void IpcVideoDecoder::ReadCompleteTask(scoped_refptr<Buffer> buffer) { +void IpcVideoDecoder::ReadCompleteTask( + scoped_refptr<media::Buffer> buffer) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -238,7 +239,6 @@ void IpcVideoDecoder::ReadCompleteTask(scoped_refptr<Buffer> buffer) { if (state_ == kFlushing) { if (pending_reads_ == 0 && pending_requests_ == 0) { - CHECK(flush_callback_.get()); flush_callback_->Run(); flush_callback_.reset(); state_ = kPlaying; @@ -253,7 +253,8 @@ void IpcVideoDecoder::ReadCompleteTask(scoped_refptr<Buffer> buffer) { gpu_video_decoder_host_->EmptyThisBuffer(buffer); } -void IpcVideoDecoder::FillThisBuffer(scoped_refptr<VideoFrame> video_frame) { +void IpcVideoDecoder::FillThisBuffer( + scoped_refptr<media::VideoFrame> video_frame) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -264,14 +265,15 @@ void IpcVideoDecoder::FillThisBuffer(scoped_refptr<VideoFrame> video_frame) { } // Synchronized flushing before stop should prevent this. - CHECK_NE(state_, kStopped); + DCHECK_NE(state_, kStopped); // Notify decode engine the available of new frame. ++pending_requests_; gpu_video_decoder_host_->FillThisBuffer(video_frame); } -void IpcVideoDecoder::OnFillBufferDone(scoped_refptr<VideoFrame> video_frame) { +void IpcVideoDecoder::OnFillBufferDone( + scoped_refptr<media::VideoFrame> video_frame) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -296,14 +298,14 @@ void IpcVideoDecoder::OnFillBufferDone(scoped_refptr<VideoFrame> video_frame) { // When in kFlushCodec, any errored decode, or a 0-lengthed frame, // is taken as a signal to stop decoding. state_ = kEnded; - scoped_refptr<VideoFrame> video_frame; - VideoFrame::CreateEmptyFrame(&video_frame); + scoped_refptr<media::VideoFrame> video_frame; + media::VideoFrame::CreateEmptyFrame(&video_frame); fill_buffer_done_callback()->Run(video_frame); } } } -void IpcVideoDecoder::OnEmptyBufferDone(scoped_refptr<Buffer> buffer) { +void IpcVideoDecoder::OnEmptyBufferDone(scoped_refptr<media::Buffer> buffer) { if (MessageLoop::current() != renderer_thread_message_loop_) { renderer_thread_message_loop_->PostTask( FROM_HERE, @@ -319,7 +321,7 @@ void IpcVideoDecoder::OnEmptyBufferDone(scoped_refptr<Buffer> buffer) { } void IpcVideoDecoder::OnDeviceError() { - host()->SetError(PIPELINE_ERROR_DECODE); + host()->SetError(media::PIPELINE_ERROR_DECODE); } bool IpcVideoDecoder::ProvidesBuffer() { @@ -327,22 +329,24 @@ bool IpcVideoDecoder::ProvidesBuffer() { } // static -FilterFactory* IpcVideoDecoder::CreateFactory(MessageLoop* message_loop) { - return new FilterFactoryImpl1<IpcVideoDecoder, MessageLoop*>(message_loop); +media::FilterFactory* IpcVideoDecoder::CreateFactory( + MessageLoop* message_loop, ggl::Context* ggl_context) { + return new media::FilterFactoryImpl2<IpcVideoDecoder, + MessageLoop*, + ggl::Context*>( + message_loop, ggl_context); } // static -bool IpcVideoDecoder::IsMediaFormatSupported(const MediaFormat& format) { +bool IpcVideoDecoder::IsMediaFormatSupported(const media::MediaFormat& format) { std::string mime_type; - if (!format.GetAsString(MediaFormat::kMimeType, &mime_type) && - mime_type::kFFmpegVideo != mime_type) + if (!format.GetAsString(media::MediaFormat::kMimeType, &mime_type) && + media::mime_type::kFFmpegVideo != mime_type) return false; // TODO(jiesun): Although we current only support H264 hardware decoding, // in the future, we should query GpuVideoService for capabilities. int codec_id; - return format.GetAsInteger(MediaFormat::kFFmpegCodecID, &codec_id) && - codec_id == CODEC_ID_H264; + return format.GetAsInteger(media::MediaFormat::kFFmpegCodecID, &codec_id) && + codec_id == CODEC_ID_H264; } - -} // namespace media diff --git a/chrome/renderer/media/ipc_video_decoder.h b/chrome/renderer/media/ipc_video_decoder.h index 55393ab..b82f605 100644 --- a/chrome/renderer/media/ipc_video_decoder.h +++ b/chrome/renderer/media/ipc_video_decoder.h @@ -13,29 +13,31 @@ struct AVRational; -namespace media { +namespace ggl { +class Context; +} // namespace ggl -class VideoDecodeEngine; - -class IpcVideoDecoder : public VideoDecoder, +class IpcVideoDecoder : public media::VideoDecoder, public GpuVideoDecoderHost::EventHandler { public: - explicit IpcVideoDecoder(MessageLoop* message_loop); + explicit IpcVideoDecoder(MessageLoop* message_loop, + ggl::Context* ggl_context); virtual ~IpcVideoDecoder(); - static FilterFactory* CreateFactory(MessageLoop* message_loop); - static bool IsMediaFormatSupported(const MediaFormat& media_format); + static media::FilterFactory* CreateFactory(MessageLoop* message_loop, + ggl::Context* ggl_context); + static bool IsMediaFormatSupported(const media::MediaFormat& media_format); // MediaFilter implementation. - virtual void Stop(FilterCallback* callback); - virtual void Seek(base::TimeDelta time, FilterCallback* callback); - virtual void Pause(FilterCallback* callback); - virtual void Flush(FilterCallback* callback); + virtual void Stop(media::FilterCallback* callback); + virtual void Seek(base::TimeDelta time, media::FilterCallback* callback); + virtual void Pause(media::FilterCallback* callback); + virtual void Flush(media::FilterCallback* callback); // Decoder implementation. - virtual void Initialize(DemuxerStream* demuxer_stream, - FilterCallback* callback); - virtual const MediaFormat& media_format() { return media_format_; } + virtual void Initialize(media::DemuxerStream* demuxer_stream, + media::FilterCallback* callback); + virtual const media::MediaFormat& media_format() { return media_format_; } virtual void FillThisBuffer(scoped_refptr<VideoFrame> video_frame); // GpuVideoDecoderHost::EventHandler. @@ -43,17 +45,13 @@ class IpcVideoDecoder : public VideoDecoder, const GpuVideoDecoderInitDoneParam& param); virtual void OnUninitializeDone(); virtual void OnFlushDone(); - virtual void OnEmptyBufferDone(scoped_refptr<Buffer> buffer); - virtual void OnFillBufferDone(scoped_refptr<VideoFrame> frame); + virtual void OnEmptyBufferDone(scoped_refptr<media::Buffer> buffer); + virtual void OnFillBufferDone(scoped_refptr<media::VideoFrame> frame); virtual void OnDeviceError(); virtual bool ProvidesBuffer(); private: - friend class FilterFactoryImpl2<IpcVideoDecoder, - VideoDecodeEngine*, - MessageLoop*>; - enum DecoderState { kUnInitialized, kPlaying, @@ -64,17 +62,17 @@ class IpcVideoDecoder : public VideoDecoder, kStopped, }; - void OnSeekComplete(FilterCallback* callback); - void OnReadComplete(Buffer* buffer); - void ReadCompleteTask(scoped_refptr<Buffer> buffer); + void OnSeekComplete(media::FilterCallback* callback); + void OnReadComplete(media::Buffer* buffer); + void ReadCompleteTask(scoped_refptr<media::Buffer> buffer); int32 width_; int32 height_; - MediaFormat media_format_; + media::MediaFormat media_format_; - scoped_ptr<FilterCallback> flush_callback_; - scoped_ptr<FilterCallback> initialize_callback_; - scoped_ptr<FilterCallback> stop_callback_; + scoped_ptr<media::FilterCallback> flush_callback_; + scoped_ptr<media::FilterCallback> initialize_callback_; + scoped_ptr<media::FilterCallback> stop_callback_; DecoderState state_; @@ -85,14 +83,19 @@ class IpcVideoDecoder : public VideoDecoder, size_t pending_requests_; // Pointer to the demuxer stream that will feed us compressed buffers. - scoped_refptr<DemuxerStream> demuxer_stream_; + scoped_refptr<media::DemuxerStream> demuxer_stream_; MessageLoop* renderer_thread_message_loop_; + + // A context for allocating textures and issuing GLES2 commands. + // TODO(hclam): A ggl::Context lives on the Render Thread while this object + // lives on the Video Decoder Thread, we need to take care of context lost + // and destruction of the context. + ggl::Context* ggl_context_; + scoped_refptr<GpuVideoDecoderHost> gpu_video_decoder_host_; DISALLOW_COPY_AND_ASSIGN(IpcVideoDecoder); }; -} // namespace media - #endif // CHROME_RENDERER_MEDIA_IPC_VIDEO_DECODER_H_ diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 4a9c4e2..7fa91bc 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -72,6 +72,7 @@ #include "chrome/renderer/spellchecker/spellcheck.h" #include "chrome/renderer/user_script_slave.h" #include "chrome/renderer/visitedlink_slave.h" +#include "chrome/renderer/webgles2context_impl.h" #include "chrome/renderer/webplugin_delegate_pepper.h" #include "chrome/renderer/webplugin_delegate_proxy.h" #include "chrome/renderer/websharedworker_proxy.h" @@ -2421,8 +2422,10 @@ WebMediaPlayer* RenderView::createMediaPlayer( if (cmd_line->HasSwitch(switches::kEnableAcceleratedDecoding) && cmd_line->HasSwitch(switches::kEnableAcceleratedCompositing)) { // Add the hardware video decoder factory. - factory->AddFactory( - media::IpcVideoDecoder::CreateFactory(MessageLoop::current())); + factory->AddFactory(IpcVideoDecoder::CreateFactory( + MessageLoop::current(), + reinterpret_cast<WebGLES2ContextImpl*>( + webview()->gles2Context())->context())); } WebApplicationCacheHostImpl* appcache_host = |