diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 07:30:18 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 07:30:18 +0000 |
commit | b6e4b4f99f9b1833d6b1d11ae03da42158549670 (patch) | |
tree | a9f67c65ec2bd94a8165b9b40b369bc2178dc5aa /chrome | |
parent | 9ba0d9f42d948e925dee89b9f1f4b6d061ab2dc1 (diff) | |
download | chromium_src-b6e4b4f99f9b1833d6b1d11ae03da42158549670.zip chromium_src-b6e4b4f99f9b1833d6b1d11ae03da42158549670.tar.gz chromium_src-b6e4b4f99f9b1833d6b1d11ae03da42158549670.tar.bz2 |
Resubmit - move MFT h264 code to media/video and connect to gpu video decoder.
TBR=scherkus
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/3591020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61925 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/chrome.gyp | 4 | ||||
-rw-r--r-- | chrome/common/gpu_messages_internal.h | 4 | ||||
-rw-r--r-- | chrome/common/gpu_video_common.cc | 2 | ||||
-rw-r--r-- | chrome/common/gpu_video_common.h | 3 | ||||
-rw-r--r-- | chrome/gpu/gpu_video_decoder.cc | 28 | ||||
-rw-r--r-- | chrome/gpu/media/mft_angle_video_device.cc | 52 | ||||
-rw-r--r-- | chrome/gpu/media/mft_angle_video_device.h | 42 | ||||
-rw-r--r-- | chrome/renderer/gpu_video_decoder_host.cc | 4 | ||||
-rw-r--r-- | chrome/renderer/media/gles2_video_decode_context.cc | 6 |
9 files changed, 135 insertions, 10 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 4e2a038..3ccc202 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -787,6 +787,10 @@ ], }, ], + 'sources': [ + 'gpu/media/mft_angle_video_device.cc', + 'gpu/media/mft_angle_video_device.h', + ], }], ['OS=="linux" and target_arch!="arm"', { 'sources': [ diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h index f61be25b1..b95a534 100644 --- a/chrome/common/gpu_messages_internal.h +++ b/chrome/common/gpu_messages_internal.h @@ -348,8 +348,8 @@ IPC_BEGIN_MESSAGES(GpuVideoDecoderHost) // GpuVideoDecoder reports that a video frame is ready to be consumed. IPC_MESSAGE_ROUTED4(GpuVideoDecoderHostMsg_ConsumeVideoFrame, int32, /* Video Frame ID */ - int64, /* Timestamp in ms */ - int64, /* Duration in ms */ + int64, /* Timestamp in microseconds */ + int64, /* Duration in microseconds */ int32) /* Flags */ // Allocate video frames for output of the hardware video decoder. diff --git a/chrome/common/gpu_video_common.cc b/chrome/common/gpu_video_common.cc index e0279de..67466b9 100644 --- a/chrome/common/gpu_video_common.cc +++ b/chrome/common/gpu_video_common.cc @@ -4,6 +4,8 @@ #include "chrome/common/gpu_video_common.h" +const int32 kGpuVideoInvalidFrameId = -1; + namespace IPC { /////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/common/gpu_video_common.h b/chrome/common/gpu_video_common.h index 17d5498..d5a2ced 100644 --- a/chrome/common/gpu_video_common.h +++ b/chrome/common/gpu_video_common.h @@ -10,6 +10,9 @@ #include "chrome/common/common_param_traits.h" #include "media/base/video_frame.h" +// This is used in messages when only buffer flag is meaningful. +extern const int32 kGpuVideoInvalidFrameId; + // Flags assigned to a video buffer for both input and output. enum GpuVideoBufferFlag { kGpuVideoEndOfStream = 1 << 0, diff --git a/chrome/gpu/gpu_video_decoder.cc b/chrome/gpu/gpu_video_decoder.cc index 86bcd04..466e85b 100644 --- a/chrome/gpu/gpu_video_decoder.cc +++ b/chrome/gpu/gpu_video_decoder.cc @@ -4,14 +4,22 @@ #include "chrome/gpu/gpu_video_decoder.h" +#include "base/command_line.h" #include "chrome/common/child_thread.h" #include "chrome/common/gpu_messages.h" #include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/media/fake_gl_video_decode_engine.h" #include "chrome/gpu/media/fake_gl_video_device.h" #include "media/base/data_buffer.h" +#include "media/base/media_switches.h" #include "media/base/video_frame.h" +#if defined(OS_WIN) +#include "chrome/gpu/media/mft_angle_video_device.h" +#include "media/video/mft_h264_decode_engine.h" +#include <d3d9.h> +#endif + void GpuVideoDecoder::OnChannelConnected(int32 peer_pid) { } @@ -105,7 +113,12 @@ void GpuVideoDecoder::ProduceVideoSample(scoped_refptr<Buffer> buffer) { } void GpuVideoDecoder::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { - int32 frame_id = -1; + if (frame->IsEndOfStream()) { + SendConsumeVideoFrame(kGpuVideoInvalidFrameId, 0, 0, kGpuVideoEndOfStream); + return; + } + + int32 frame_id = kGpuVideoInvalidFrameId; for (VideoFrameMap::iterator i = video_frame_map_.begin(); i != video_frame_map_.end(); ++i) { if (i->second == frame) { @@ -116,8 +129,7 @@ void GpuVideoDecoder::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { DCHECK_NE(-1, frame_id) << "VideoFrame not recognized"; SendConsumeVideoFrame(frame_id, frame->GetTimestamp().InMicroseconds(), - frame->GetDuration().InMicroseconds(), - frame->IsEndOfStream() ? kGpuVideoEndOfStream : 0); + frame->GetDuration().InMicroseconds(), 0); } void* GpuVideoDecoder::GetDevice() { @@ -225,8 +237,16 @@ GpuVideoDecoder::GpuVideoDecoder( // TODO(jiesun): find a better way to determine which VideoDecodeEngine // to return on current platform. +#if defined(OS_WIN) + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kEnableAcceleratedDecoding)) { + decode_engine_.reset(new media::MftH264DecodeEngine(true)); + video_device_.reset(new MftAngleVideoDevice()); + } +#else decode_engine_.reset(new FakeGlVideoDecodeEngine()); video_device_.reset(new FakeGlVideoDevice()); +#endif } void GpuVideoDecoder::OnInitialize(const GpuVideoDecoderInitParam& param) { @@ -235,7 +255,7 @@ void GpuVideoDecoder::OnInitialize(const GpuVideoDecoderInitParam& param) { config_.width = param.width; config_.height = param.height; config_.opaque_context = NULL; - decode_engine_->Initialize(NULL, this, this, config_); + decode_engine_->Initialize(message_loop_, this, this, config_); } void GpuVideoDecoder::OnUninitialize() { diff --git a/chrome/gpu/media/mft_angle_video_device.cc b/chrome/gpu/media/mft_angle_video_device.cc new file mode 100644 index 0000000..1faf9dc --- /dev/null +++ b/chrome/gpu/media/mft_angle_video_device.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2010 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 "chrome/gpu/media/mft_angle_video_device.h" + +#include <d3d9.h> + +#include "media/base/video_frame.h" +#include "third_party/angle/src/libGLESv2/main.h" + +MftAngleVideoDevice::MftAngleVideoDevice() + : device_(reinterpret_cast<egl::Display*>( + eglGetCurrentDisplay())->getDevice()) { +} + +void* MftAngleVideoDevice::GetDevice() { + return device_; +} + +bool MftAngleVideoDevice::CreateVideoFrameFromGlTextures( + size_t width, size_t height, media::VideoFrame::Format format, + const std::vector<media::VideoFrame::GlTexture>& textures, + scoped_refptr<media::VideoFrame>* frame) { + media::VideoFrame::GlTexture texture_array[media::VideoFrame::kMaxPlanes]; + memset(texture_array, 0, sizeof(texture_array)); + + for (size_t i = 0; i < textures.size(); ++i) { + texture_array[i] = textures[i]; + } + + media::VideoFrame::CreateFrameGlTexture(format, + width, + height, + texture_array, + frame); + return *frame != NULL; +} + +void MftAngleVideoDevice::ReleaseVideoFrame( + const scoped_refptr<media::VideoFrame>& frame) { + // We didn't need to anything here because we didn't allocate any resources + // for the VideoFrame(s) generated. +} + +bool MftAngleVideoDevice::UploadToVideoFrame( + void* buffer, scoped_refptr<media::VideoFrame> frame) { + gl::Context* context = (gl::Context*)eglGetCurrentContext(); + // TODO(hclam): Connect ANGLE to upload the surface to texture when changes + // to ANGLE is done. + return true; +} diff --git a/chrome/gpu/media/mft_angle_video_device.h b/chrome/gpu/media/mft_angle_video_device.h new file mode 100644 index 0000000..fb1e0e8 --- /dev/null +++ b/chrome/gpu/media/mft_angle_video_device.h @@ -0,0 +1,42 @@ +// Copyright (c) 2010 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 CHROME_GPU_MEDIA_MFT_ANGLE_VIDEO_DEVICE_H_ +#define CHROME_GPU_MEDIA_MFT_ANGLE_VIDEO_DEVICE_H_ + +#include "base/scoped_comptr_win.h" +#include "chrome/gpu/media/gpu_video_device.h" + +struct IDirect3DDevice9; +extern "C" const GUID IID_IDirect3DDevice9; + +namespace media { +class VideoFrame; +} // namespace media + +// This class is used to provide hardware video device, video frames and +// allow video frames to be uploaded to their final render target. +// +// This specifically serves MftH264DecodeEngine in the context of ANGLE. +class MftAngleVideoDevice : public GpuVideoDevice { + public: + MftAngleVideoDevice(); + virtual ~MftAngleVideoDevice() {} + + // GpuVideoDevice implementation. + virtual void* GetDevice(); + virtual bool CreateVideoFrameFromGlTextures( + size_t width, size_t height, media::VideoFrame::Format format, + const std::vector<media::VideoFrame::GlTexture>& textures, + scoped_refptr<media::VideoFrame>* frame); + virtual void ReleaseVideoFrame( + const scoped_refptr<media::VideoFrame>& frame); + virtual bool UploadToVideoFrame(void* buffer, + scoped_refptr<media::VideoFrame> frame); + + private: + ScopedComPtr<IDirect3DDevice9, &IID_IDirect3DDevice9> device_; +}; + +#endif // CHROME_GPU_MEDIA_MFT_ANGLE_VIDEO_DEVICE_H_ diff --git a/chrome/renderer/gpu_video_decoder_host.cc b/chrome/renderer/gpu_video_decoder_host.cc index ad81004..bf6c79f 100644 --- a/chrome/renderer/gpu_video_decoder_host.cc +++ b/chrome/renderer/gpu_video_decoder_host.cc @@ -272,8 +272,8 @@ void GpuVideoDecoderHost::OnConsumeVideoFrame(int32 frame_id, int64 timestamp, frame = video_frame_map_[frame_id]; DCHECK(frame) << "Invalid frame ID received"; - frame->SetDuration(base::TimeDelta::FromMilliseconds(duration)); - frame->SetTimestamp(base::TimeDelta::FromMilliseconds(timestamp)); + frame->SetDuration(base::TimeDelta::FromMicroseconds(duration)); + frame->SetTimestamp(base::TimeDelta::FromMicroseconds(timestamp)); } event_handler_->ConsumeVideoFrame(frame); diff --git a/chrome/renderer/media/gles2_video_decode_context.cc b/chrome/renderer/media/gles2_video_decode_context.cc index bd60ea1..e32e22b 100644 --- a/chrome/renderer/media/gles2_video_decode_context.cc +++ b/chrome/renderer/media/gles2_video_decode_context.cc @@ -56,8 +56,10 @@ void Gles2VideoDecodeContext::AllocateVideoFrames( glGenTextures(planes, textures); for (int j = 0; j < planes; ++j) { glBindTexture(GL_TEXTURE_2D, textures[j]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, gl_format, width, height, 0, gl_format, GL_UNSIGNED_BYTE, NULL); } |