diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 04:52:15 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 04:52:15 +0000 |
commit | 71e43a27d4c6018a9502753566d228cbf2dc2ca5 (patch) | |
tree | 656e03e34018265e322da21c9487dec3ad41eb56 /chrome | |
parent | 463d474661abf3f3ed431eb73457efa7a6946201 (diff) | |
download | chromium_src-71e43a27d4c6018a9502753566d228cbf2dc2ca5.zip chromium_src-71e43a27d4c6018a9502753566d228cbf2dc2ca5.tar.gz chromium_src-71e43a27d4c6018a9502753566d228cbf2dc2ca5.tar.bz2 |
Move MFT H264 video decoder implementation and connect it to GpuVideoDecoder
Remove media/mf folder and move the video decode engine to media/video.
There are some temporary changes in MftH264DecodeEngine to work with
GpuVideoDecoder correctly.
Removed tests will be added later. Example program will likely be removed
permanently due to maintence problem.
This patch depends WebKit and ANGLE changes to be able to present video frames
onto screen and still have lot of bugs, those problems will be address later.
BUG=53714
TEST=Tree is green. This patch doesn't work yet.
Review URL: http://codereview.chromium.org/3432030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61918 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 | 23 | ||||
-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, 130 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..5ae7dfc 100644 --- a/chrome/gpu/gpu_video_decoder.cc +++ b/chrome/gpu/gpu_video_decoder.cc @@ -12,6 +12,12 @@ #include "media/base/data_buffer.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 +111,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 +127,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 +235,13 @@ GpuVideoDecoder::GpuVideoDecoder( // TODO(jiesun): find a better way to determine which VideoDecodeEngine // to return on current platform. +#if defined(OS_WIN) + 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 +250,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); } |