summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-03 18:57:24 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-03 18:57:24 +0000
commit1cfb7420fb7ea2fa5a6360bbee5424918e84a027 (patch)
tree6ca1fd441d8675a06370fc54ac06bcbeb099b5fa /chrome/renderer
parent6b723128f5c6b090b87949875dcc4e55304a4461 (diff)
downloadchromium_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.cc3
-rw-r--r--chrome/renderer/gpu_video_decoder_host.h6
-rw-r--r--chrome/renderer/media/ipc_video_decoder.cc92
-rw-r--r--chrome/renderer/media/ipc_video_decoder.h63
-rw-r--r--chrome/renderer/render_view.cc7
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 =