diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-29 02:23:31 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-29 02:23:31 +0000 |
commit | f37619e85e12e0692fe106e1f6b3a8ac6267fc74 (patch) | |
tree | bc9b9737feaea32c90d3e137c787ce7661b43e77 /chrome/gpu | |
parent | 91bfaaef281c73e3792a3c96df37920c8a5370a5 (diff) | |
download | chromium_src-f37619e85e12e0692fe106e1f6b3a8ac6267fc74.zip chromium_src-f37619e85e12e0692fe106e1f6b3a8ac6267fc74.tar.gz chromium_src-f37619e85e12e0692fe106e1f6b3a8ac6267fc74.tar.bz2 |
Implement video frame exchange in GpuVideoDecoder and tests
Implement ProduceVideoFrame() in GpuVideoDecoder and unit tests for testing
the loginc in GpuVideoDecoder.
BUG=53714
TEST=unit_tests --gtest_filter=GpuVideoDecoder*
Review URL: http://codereview.chromium.org/3414003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60902 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/gpu')
-rw-r--r-- | chrome/gpu/gpu_video_decoder.cc | 109 | ||||
-rw-r--r-- | chrome/gpu/gpu_video_decoder.h | 31 | ||||
-rw-r--r-- | chrome/gpu/gpu_video_decoder_unittest.cc | 267 | ||||
-rw-r--r-- | chrome/gpu/gpu_video_service.cc | 3 |
4 files changed, 349 insertions, 61 deletions
diff --git a/chrome/gpu/gpu_video_decoder.cc b/chrome/gpu/gpu_video_decoder.cc index 91758e0..71ce991 100644 --- a/chrome/gpu/gpu_video_decoder.cc +++ b/chrome/gpu/gpu_video_decoder.cc @@ -28,10 +28,10 @@ void GpuVideoDecoder::OnMessageReceived(const IPC::Message& msg) { OnFlush) IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_EmptyThisBuffer, OnEmptyThisBuffer) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_FillThisBuffer, - OnFillThisBuffer) - IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_FillThisBufferDoneACK, - OnFillThisBufferDoneACK) + IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_ProduceVideoFrame, + OnProduceVideoFrame) + IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_VideoFrameAllocated, + OnVideoFrameAllocated) IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() } @@ -103,12 +103,19 @@ void GpuVideoDecoder::ProduceVideoSample(scoped_refptr<Buffer> buffer) { } void GpuVideoDecoder::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { - GpuVideoDecoderOutputBufferParam output_param; - output_param.timestamp = frame->GetTimestamp().InMicroseconds(); - output_param.duration = frame->GetDuration().InMicroseconds(); - output_param.flags = frame->IsEndOfStream() ? - GpuVideoDecoderOutputBufferParam::kFlagsEndOfStream : 0; - SendFillBufferDone(output_param); + int32 frame_id = -1; + for (VideoFrameMap::iterator i = video_frame_map_.begin(); + i != video_frame_map_.end(); ++i) { + if (i->second == frame) { + frame_id = i->first; + break; + } + } + DCHECK_NE(-1, frame_id) << "VideoFrame not recognized"; + + SendConsumeVideoFrame(frame_id, frame->GetTimestamp().InMicroseconds(), + frame->GetDuration().InMicroseconds(), + frame->IsEndOfStream() ? kGpuVideoEndOfStream : 0); } void* GpuVideoDecoder::GetDevice() { @@ -192,14 +199,23 @@ void GpuVideoDecoder::Destroy(Task* task) { // TODO(hclam): I still need to think what I should do here. } +void GpuVideoDecoder::SetVideoDecodeEngine(media::VideoDecodeEngine* engine) { + decode_engine_.reset(engine); +} + +void GpuVideoDecoder::SetGpuVideoDevice(GpuVideoDevice* device) { + video_device_.reset(device); +} + GpuVideoDecoder::GpuVideoDecoder( + MessageLoop* message_loop, const GpuVideoDecoderInfoParam* param, - GpuChannel* channel, + IPC::Message::Sender* sender, base::ProcessHandle handle, gpu::gles2::GLES2Decoder* decoder) - : decoder_host_route_id_(param->decoder_host_route_id), - pending_output_requests_(0), - channel_(channel), + : message_loop_(message_loop), + decoder_host_route_id_(param->decoder_host_route_id), + sender_(sender), renderer_handle_(handle), gles2_decoder_(decoder) { memset(&config_, 0, sizeof(config_)); @@ -212,7 +228,6 @@ GpuVideoDecoder::GpuVideoDecoder( } void GpuVideoDecoder::OnInitialize(const GpuVideoDecoderInitParam& param) { - // TODO(hclam): Initialize the VideoDecodeContext first. // TODO(jiesun): codec id should come from |param|. config_.codec = media::kCodecH264; config_.width = param.width; @@ -226,8 +241,6 @@ void GpuVideoDecoder::OnUninitialize() { } void GpuVideoDecoder::OnFlush() { - pending_output_requests_ = 0; - decode_engine_->Flush(); } @@ -243,32 +256,25 @@ void GpuVideoDecoder::OnEmptyThisBuffer( memcpy(dst, src, buffer.size); SendEmptyBufferACK(); + // Delegate the method call to VideoDecodeEngine. decode_engine_->ConsumeVideoSample(input_buffer); } -void GpuVideoDecoder::OnFillThisBuffer( - const GpuVideoDecoderOutputBufferParam& param) { - // Switch context before calling to the decode engine. - bool ret = gles2_decoder_->MakeCurrent(); - DCHECK(ret) << "Failed to switch context"; - - if (info_.stream_info.surface_type == VideoFrame::TYPE_SYSTEM_MEMORY) { - pending_output_requests_++; - } else { +void GpuVideoDecoder::OnProduceVideoFrame(int32 frame_id) { + VideoFrameMap::iterator i = video_frame_map_.find(frame_id); + if (i == video_frame_map_.end()) { + NOTREACHED() << "Received a request of unknown frame ID."; } -} -void GpuVideoDecoder::OnFillThisBufferDoneACK() { - if (info_.stream_info.surface_type == VideoFrame::TYPE_SYSTEM_MEMORY) { - pending_output_requests_--; - if (pending_output_requests_) { - decode_engine_->ProduceVideoFrame(frame_); - } - } + // Delegate the method call to VideoDecodeEngine. + decode_engine_->ProduceVideoFrame(i->second); } void GpuVideoDecoder::OnVideoFrameAllocated(int32 frame_id, std::vector<uint32> textures) { + bool ret = gles2_decoder_->MakeCurrent(); + DCHECK(ret) << "Failed to switch context"; + // This method is called in response to a video frame allocation request sent // to the Renderer process. // We should use the textures to generate a VideoFrame by using @@ -278,13 +284,15 @@ void GpuVideoDecoder::OnVideoFrameAllocated(int32 frame_id, for (size_t i = 0; i < textures.size(); ++i) { media::VideoFrame::GlTexture gl_texture; // Translate the client texture id to service texture id. - bool ret = gles2_decoder_->GetServiceTextureId(textures[i], &gl_texture); + ret = gles2_decoder_->GetServiceTextureId(textures[i], &gl_texture); DCHECK(ret) << "Cannot translate client texture ID to service ID"; textures[i] = gl_texture; } + // Use GpuVideoDevice to allocate VideoFrame objects. scoped_refptr<media::VideoFrame> frame; - bool ret = video_device_->CreateVideoFrameFromGlTextures( + + ret = video_device_->CreateVideoFrameFromGlTextures( pending_allocation_->width, pending_allocation_->height, pending_allocation_->format, textures, &frame); @@ -301,53 +309,58 @@ void GpuVideoDecoder::OnVideoFrameAllocated(int32 frame_id, void GpuVideoDecoder::SendInitializeDone( const GpuVideoDecoderInitDoneParam& param) { - if (!channel_->Send( + if (!sender_->Send( new GpuVideoDecoderHostMsg_InitializeACK(route_id(), param))) { LOG(ERROR) << "GpuVideoDecoderMsg_InitializeACK failed"; } } void GpuVideoDecoder::SendUninitializeDone() { - if (!channel_->Send(new GpuVideoDecoderHostMsg_DestroyACK(route_id()))) { + if (!sender_->Send(new GpuVideoDecoderHostMsg_DestroyACK(route_id()))) { LOG(ERROR) << "GpuVideoDecoderMsg_DestroyACK failed"; } } void GpuVideoDecoder::SendFlushDone() { - if (!channel_->Send(new GpuVideoDecoderHostMsg_FlushACK(route_id()))) { + if (!sender_->Send(new GpuVideoDecoderHostMsg_FlushACK(route_id()))) { LOG(ERROR) << "GpuVideoDecoderMsg_FlushACK failed"; } } void GpuVideoDecoder::SendEmptyBufferDone() { - if (!channel_->Send( + if (!sender_->Send( new GpuVideoDecoderHostMsg_EmptyThisBufferDone(route_id()))) { LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBufferDone failed"; } } void GpuVideoDecoder::SendEmptyBufferACK() { - if (!channel_->Send( + if (!sender_->Send( new GpuVideoDecoderHostMsg_EmptyThisBufferACK(route_id()))) { LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBufferACK failed"; } } -void GpuVideoDecoder::SendFillBufferDone( - const GpuVideoDecoderOutputBufferParam& param) { - if (!channel_->Send( - new GpuVideoDecoderHostMsg_FillThisBufferDone(route_id(), param))) { - LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBufferDone failed"; +void GpuVideoDecoder::SendConsumeVideoFrame( + int32 frame_id, int64 timestamp, int64 duration, int32 flags) { + if (!sender_->Send( + new GpuVideoDecoderHostMsg_ConsumeVideoFrame( + route_id(), frame_id, timestamp, duration, flags))) { + LOG(ERROR) << "GpuVideoDecodeHostMsg_ConsumeVideoFrame failed."; } } void GpuVideoDecoder::SendAllocateVideoFrames( int n, size_t width, size_t height, media::VideoFrame::Format format) { - // TODO(hclam): Actually send the message. + if (!sender_->Send( + new GpuVideoDecoderHostMsg_AllocateVideoFrames( + route_id(), n, width, height, static_cast<int32>(format)))) { + LOG(ERROR) << "GpuVideoDecoderMsg_AllocateVideoFrames failed"; + } } void GpuVideoDecoder::SendReleaseAllVideoFrames() { - if (!channel_->Send( + if (!sender_->Send( new GpuVideoDecoderHostMsg_ReleaseAllVideoFrames(route_id()))) { LOG(ERROR) << "GpuVideoDecoderMsg_ReleaseAllVideoFrames failed"; } diff --git a/chrome/gpu/gpu_video_decoder.h b/chrome/gpu/gpu_video_decoder.h index d4c9b09..f975eb8 100644 --- a/chrome/gpu/gpu_video_decoder.h +++ b/chrome/gpu/gpu_video_decoder.h @@ -90,8 +90,15 @@ class GpuVideoDecoder public IPC::Channel::Listener, public media::VideoDecodeEngine::EventHandler, public media::VideoDecodeContext { - public: + // Constructor and destructor. + GpuVideoDecoder(MessageLoop* message_loop, + const GpuVideoDecoderInfoParam* param, + IPC::Message::Sender* sender, + base::ProcessHandle handle, + gpu::gles2::GLES2Decoder* decoder); + virtual ~GpuVideoDecoder() {} + // IPC::Channel::Listener implementation. virtual void OnChannelConnected(int32 peer_pid); virtual void OnChannelError(); @@ -118,12 +125,9 @@ class GpuVideoDecoder Task* task); virtual void Destroy(Task* task); - // Constructor and destructor. - GpuVideoDecoder(const GpuVideoDecoderInfoParam* param, - GpuChannel* channel_, - base::ProcessHandle handle, - gpu::gles2::GLES2Decoder* decoder); - virtual ~GpuVideoDecoder() {} + // These methods are used in unit test only. + void SetVideoDecodeEngine(media::VideoDecodeEngine* engine); + void SetGpuVideoDevice(GpuVideoDevice* device); private: struct PendingAllocation { @@ -146,8 +150,7 @@ class GpuVideoDecoder void OnUninitialize(); void OnFlush(); void OnEmptyThisBuffer(const GpuVideoDecoderInputBufferParam& buffer); - void OnFillThisBuffer(const GpuVideoDecoderOutputBufferParam& param); - void OnFillThisBufferDoneACK(); + void OnProduceVideoFrame(int32 frame_id); void OnVideoFrameAllocated(int32 frame_id, std::vector<uint32> textures); // Helper methods for sending messages to the Renderer process. @@ -156,18 +159,21 @@ class GpuVideoDecoder void SendFlushDone(); void SendEmptyBufferDone(); void SendEmptyBufferACK(); - void SendFillBufferDone(const GpuVideoDecoderOutputBufferParam& param); + void SendConsumeVideoFrame(int32 frame_id, int64 timestamp, int64 duration, + int32 flags); void SendAllocateVideoFrames( int n, size_t width, size_t height, media::VideoFrame::Format format); void SendReleaseAllVideoFrames(); + // The message loop that this object should run on. + MessageLoop* message_loop_; + int32 decoder_host_route_id_; // Used only in system memory path. i.e. Remove this later. scoped_refptr<VideoFrame> frame_; - int32 pending_output_requests_; - GpuChannel* channel_; + IPC::Message::Sender* sender_; base::ProcessHandle renderer_handle_; // The GLES2 decoder has the context associated with this decoder. This object @@ -189,6 +195,7 @@ class GpuVideoDecoder // Contains the mapping between a |frame_id| and VideoFrame generated by // GpuVideoDevice from the associated GL textures. + // TODO(hclam): Using a faster data structure than map. typedef std::map<int32, scoped_refptr<media::VideoFrame> > VideoFrameMap; VideoFrameMap video_frame_map_; diff --git a/chrome/gpu/gpu_video_decoder_unittest.cc b/chrome/gpu/gpu_video_decoder_unittest.cc new file mode 100644 index 0000000..4548807 --- /dev/null +++ b/chrome/gpu/gpu_video_decoder_unittest.cc @@ -0,0 +1,267 @@ +// 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 "base/process.h" +#include "chrome/common/gpu_messages.h" +#include "chrome/gpu/gpu_video_decoder.h" +#include "gpu/command_buffer/service/context_group.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" +#include "ipc/ipc_message_utils.h" +#include "media/video/mock_objects.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::DoAll; +using testing::NotNull; +using testing::Return; +using testing::SetArgumentPointee; + +static const int32 kFrameId = 10; +static const media::VideoFrame::GlTexture kClientTexture = 101; +static const media::VideoFrame::GlTexture kServiceTexture = 102; +static const size_t kWidth = 320; +static const size_t kHeight = 240; + +class MockGpuVideoDevice : public GpuVideoDevice { + public: + MockGpuVideoDevice() {} + virtual ~MockGpuVideoDevice() {} + + MOCK_METHOD0(GetDevice, void*()); + MOCK_METHOD5(CreateVideoFrameFromGlTextures, + bool(size_t, size_t, media::VideoFrame::Format, + const std::vector<media::VideoFrame::GlTexture>&, + scoped_refptr<media::VideoFrame>*)); + MOCK_METHOD1(ReleaseVideoFrame, + void(const scoped_refptr<media::VideoFrame>& frame)); + MOCK_METHOD2(UploadToVideoFrame, + bool(void* buffer, scoped_refptr<media::VideoFrame> frame)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockGpuVideoDevice); +}; + +ACTION_P(InitializationDone, handler) { + media::VideoCodecInfo info; + info.success = true; + info.provides_buffers = false; + info.stream_info.surface_format = media::VideoFrame::RGBA; + info.stream_info.surface_type = media::VideoFrame::TYPE_SYSTEM_MEMORY; + info.stream_info.surface_width = kWidth; + info.stream_info.surface_height = kHeight; + handler->OnInitializeComplete(info); +} + +ACTION_P(SendVideoFrameAllocated, handler) { + std::vector<media::VideoFrame::GlTexture> textures; + textures.push_back(kClientTexture); + GpuVideoDecoderMsg_VideoFrameAllocated msg(0, kFrameId, textures); + handler->OnMessageReceived(msg); +} + +ACTION_P2(SendConsumeVideoFrame, handler, frame) { + handler->ConsumeVideoFrame(frame); +} + +class GpuVideoDecoderTest : public testing::Test, + public IPC::Message::Sender { + public: + GpuVideoDecoderTest() { + // Create the mock objects. + gles2_decoder_.reset(new gpu::gles2::MockGLES2Decoder(&group_)); + + // Initialize GpuVideoDecoder with the default params. + GpuVideoDecoderInfoParam param; + memset(¶m, 0, sizeof(param)); + gpu_video_decoder_ = new GpuVideoDecoder( + &message_loop_, ¶m, this, base::kNullProcessHandle, + gles2_decoder_.get()); + + // Create the mock objects. + mock_engine_ = new media::MockVideoDecodeEngine(); + mock_device_ = new MockGpuVideoDevice(); + + // Inject the mock objects. + gpu_video_decoder_->SetVideoDecodeEngine(mock_engine_); + gpu_video_decoder_->SetGpuVideoDevice(mock_device_); + + // VideoFrame for GpuVideoDevice. + media::VideoFrame::GlTexture textures[] = { kServiceTexture, 0, 0 }; + media::VideoFrame::CreateFrameGlTexture(media::VideoFrame::RGBA, + kWidth, kHeight, textures, + base::TimeDelta(), + base::TimeDelta(), + &device_frame_); + } + + ~GpuVideoDecoderTest() { + gpu_video_decoder_->SetVideoDecodeEngine(NULL); + gpu_video_decoder_->SetGpuVideoDevice(NULL); + } + + // This method is used to dispatch IPC messages to mock methods. + virtual bool Send(IPC::Message* msg) { + EXPECT_TRUE(msg); + if (!msg) + return false; + + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(GpuVideoDecoderTest, *msg) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_InitializeACK, + OnInitializeDone) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_DestroyACK, + OnUninitializeDone) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_FlushACK, + OnFlushDone) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_EmptyThisBufferACK, + OnEmptyThisBufferACK) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_EmptyThisBufferDone, + OnEmptyThisBufferDone) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_AllocateVideoFrames, + OnAllocateVideoFrames) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_ReleaseAllVideoFrames, + OnReleaseAllVideoFrames) + IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_ConsumeVideoFrame, + OnConsumeVideoFrame) + IPC_MESSAGE_UNHANDLED_ERROR() + IPC_END_MESSAGE_MAP() + EXPECT_TRUE(handled); + delete msg; + return true; + } + + // Mock methods for handling output IPC messages. + MOCK_METHOD1(OnInitializeDone, + void(const GpuVideoDecoderInitDoneParam& param)); + MOCK_METHOD0(OnUninitializeDone, void()); + MOCK_METHOD0(OnFlushDone, void()); + MOCK_METHOD0(OnEmptyThisBufferDone, void()); + MOCK_METHOD4(OnConsumeVideoFrame, void(int32 device_frame_id, int64 timestamp, + int64 duration, int32 flags)); + MOCK_METHOD0(OnEmptyThisBufferACK, void()); + MOCK_METHOD4(OnAllocateVideoFrames, void(int32 n, uint32 width, + uint32 height, int32 format)); + MOCK_METHOD0(OnReleaseAllVideoFrames, void()); + + // Receive events from GpuVideoDecoder. + MOCK_METHOD0(VideoFramesAllocated, void()); + + void Initialize() { + // VideoDecodeEngine is called. + EXPECT_CALL(*mock_engine_, Initialize(_, _, _, _)) + .WillOnce(InitializationDone(gpu_video_decoder_)); + + // Expect that initialization is completed. + EXPECT_CALL(*this, OnInitializeDone(_)); + + // Send an initialiaze message to GpuVideoDecoder. + GpuVideoDecoderInitParam param; + param.width = kWidth; + param.height = kHeight; + + GpuVideoDecoderMsg_Initialize msg(0, param); + gpu_video_decoder_->OnMessageReceived(msg); + } + + void AllocateVideoFrames() { + // Expect that IPC messages are sent. We'll reply with some GL textures. + EXPECT_CALL(*this, OnAllocateVideoFrames( + 1, kWidth, kHeight, static_cast<int32>(media::VideoFrame::RGBA))) + .WillOnce(SendVideoFrameAllocated(gpu_video_decoder_)); + + // Expect that MakeCurrent() is called. + EXPECT_CALL(*gles2_decoder_.get(), MakeCurrent()) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + + // Expect that translate method is called. + EXPECT_CALL(*gles2_decoder_.get(), + GetServiceTextureId(kClientTexture, NotNull())) + .WillOnce(DoAll(SetArgumentPointee<1>(kServiceTexture), Return(true))); + + // And then GpuVideoDevice is called to create VideoFrame from GL textures. + EXPECT_CALL(*mock_device_, + CreateVideoFrameFromGlTextures(kWidth, kHeight, + media::VideoFrame::RGBA, _, + NotNull())) + .WillOnce(DoAll(SetArgumentPointee<4>(device_frame_), Return(true))); + + // Finally the task is called. + EXPECT_CALL(*this, VideoFramesAllocated()); + + // Pretend calling GpuVideoDecoder for allocating frames. + gpu_video_decoder_->AllocateVideoFrames( + 1, kWidth, kHeight, media::VideoFrame::RGBA, &decoder_frames_, + NewRunnableMethod(this, &GpuVideoDecoderTest::VideoFramesAllocated)); + } + + void ReleaseVideoFrames() { + // Expect that MakeCurrent() is called. + EXPECT_CALL(*gles2_decoder_.get(), MakeCurrent()) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + + // Expect that video frame is released. + EXPECT_CALL(*mock_device_, ReleaseVideoFrame(device_frame_)); + + // Expect that IPC message is send to release video frame. + EXPECT_CALL(*this, OnReleaseAllVideoFrames()); + + // Call to GpuVideoDecoder to release all video frames. + gpu_video_decoder_->ReleaseAllVideoFrames(); + } + + void BufferExchange() { + // Expect that we call to produce video frame. + EXPECT_CALL(*mock_engine_, ProduceVideoFrame(device_frame_)) + .WillOnce(SendConsumeVideoFrame(gpu_video_decoder_, device_frame_)) + .RetiresOnSaturation(); + + // Expect that consume video frame is called. + EXPECT_CALL(*this, OnConsumeVideoFrame(kFrameId, 0, 0, 0)) + .RetiresOnSaturation(); + + // Ask the GpuVideoDecoder to produce a video frame. + GpuVideoDecoderMsg_ProduceVideoFrame msg(0, kFrameId); + gpu_video_decoder_->OnMessageReceived(msg); + } + + private: + scoped_refptr<GpuVideoDecoder> gpu_video_decoder_; + MockGpuVideoDevice* mock_device_; + media::MockVideoDecodeEngine* mock_engine_; + gpu::gles2::ContextGroup group_; + scoped_ptr<gpu::gles2::MockGLES2Decoder> gles2_decoder_; + std::vector<scoped_refptr<media::VideoFrame> > decoder_frames_; + scoped_refptr<media::VideoFrame> device_frame_; + + MessageLoop message_loop_; + + DISALLOW_COPY_AND_ASSIGN(GpuVideoDecoderTest); +}; + +TEST_F(GpuVideoDecoderTest, Initialize) { + Initialize(); +} + +TEST_F(GpuVideoDecoderTest, AllocateVideoFrames) { + Initialize(); + AllocateVideoFrames(); +} + +TEST_F(GpuVideoDecoderTest, ReleaseVideoFrames) { + Initialize(); + AllocateVideoFrames(); + ReleaseVideoFrames(); +} + +TEST_F(GpuVideoDecoderTest, BufferExchange) { + Initialize(); + AllocateVideoFrames(); + BufferExchange(); + BufferExchange(); + ReleaseVideoFrames(); +} + +DISABLE_RUNNABLE_METHOD_REFCOUNT(GpuVideoDecoderTest); diff --git a/chrome/gpu/gpu_video_service.cc b/chrome/gpu/gpu_video_service.cc index 8d1ca4e..6ff2e81 100644 --- a/chrome/gpu/gpu_video_service.cc +++ b/chrome/gpu/gpu_video_service.cc @@ -49,7 +49,8 @@ bool GpuVideoService::CreateVideoDecoder( int32 decoder_id = GetNextAvailableDecoderID(); param->decoder_id = decoder_id; base::ProcessHandle handle = channel->renderer_handle(); - decoder_info.decoder_ = new GpuVideoDecoder(param, channel, handle, + decoder_info.decoder_ = new GpuVideoDecoder(MessageLoop::current(), + param, channel, handle, gles2_decoder); decoder_info.channel_ = channel; decoder_info.param = *param; |