OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/common/gpu/media/gpu_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/gpu_video_decode_accelerator.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/location.h" | |
12 #include "base/logging.h" | 11 #include "base/logging.h" |
13 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
14 #include "base/single_thread_task_runner.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
15 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
16 #include "base/thread_task_runner_handle.h" | |
17 | 15 |
18 #include "content/common/gpu/gpu_channel.h" | 16 #include "content/common/gpu/gpu_channel.h" |
19 #include "content/common/gpu/gpu_messages.h" | 17 #include "content/common/gpu/gpu_messages.h" |
20 #include "content/common/gpu/media/gpu_video_accelerator_util.h" | 18 #include "content/common/gpu/media/gpu_video_accelerator_util.h" |
21 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
22 #include "gpu/command_buffer/common/command_buffer.h" | 20 #include "gpu/command_buffer/common/command_buffer.h" |
23 #include "ipc/ipc_message_macros.h" | 21 #include "ipc/ipc_message_macros.h" |
24 #include "ipc/ipc_message_utils.h" | 22 #include "ipc/ipc_message_utils.h" |
25 #include "ipc/message_filter.h" | 23 #include "ipc/message_filter.h" |
26 #include "media/base/limits.h" | 24 #include "media/base/limits.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 private: | 120 private: |
123 GpuVideoDecodeAccelerator* const owner_; | 121 GpuVideoDecodeAccelerator* const owner_; |
124 const int32 host_route_id_; | 122 const int32 host_route_id_; |
125 // The sender to which this filter was added. | 123 // The sender to which this filter was added. |
126 IPC::Sender* sender_; | 124 IPC::Sender* sender_; |
127 }; | 125 }; |
128 | 126 |
129 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( | 127 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( |
130 int32 host_route_id, | 128 int32 host_route_id, |
131 GpuCommandBufferStub* stub, | 129 GpuCommandBufferStub* stub, |
132 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) | 130 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) |
133 : host_route_id_(host_route_id), | 131 : host_route_id_(host_route_id), |
134 stub_(stub), | 132 stub_(stub), |
135 texture_target_(0), | 133 texture_target_(0), |
136 filter_removed_(true, false), | 134 filter_removed_(true, false), |
137 child_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 135 child_message_loop_(base::MessageLoopProxy::current()), |
138 io_task_runner_(io_task_runner), | 136 io_message_loop_(io_message_loop), |
139 weak_factory_for_io_(this) { | 137 weak_factory_for_io_(this) { |
140 DCHECK(stub_); | 138 DCHECK(stub_); |
141 stub_->AddDestructionObserver(this); | 139 stub_->AddDestructionObserver(this); |
142 make_context_current_ = | 140 make_context_current_ = |
143 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); | 141 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); |
144 } | 142 } |
145 | 143 |
146 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { | 144 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { |
147 // This class can only be self-deleted from OnWillDestroyStub(), which means | 145 // This class can only be self-deleted from OnWillDestroyStub(), which means |
148 // the VDA has already been destroyed in there. | 146 // the VDA has already been destroyed in there. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 } | 198 } |
201 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); | 199 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); |
202 uncleared_textures_.erase(picture_buffer_id); | 200 uncleared_textures_.erase(picture_buffer_id); |
203 } | 201 } |
204 | 202 |
205 void GpuVideoDecodeAccelerator::PictureReady( | 203 void GpuVideoDecodeAccelerator::PictureReady( |
206 const media::Picture& picture) { | 204 const media::Picture& picture) { |
207 // VDA may call PictureReady on IO thread. SetTextureCleared should run on | 205 // VDA may call PictureReady on IO thread. SetTextureCleared should run on |
208 // the child thread. VDA is responsible to call PictureReady on the child | 206 // the child thread. VDA is responsible to call PictureReady on the child |
209 // thread when a picture buffer is delivered the first time. | 207 // thread when a picture buffer is delivered the first time. |
210 if (child_task_runner_->BelongsToCurrentThread()) { | 208 if (child_message_loop_->BelongsToCurrentThread()) { |
211 SetTextureCleared(picture); | 209 SetTextureCleared(picture); |
212 } else { | 210 } else { |
213 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 211 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
214 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); | 212 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); |
215 DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id())); | 213 DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id())); |
216 } | 214 } |
217 | 215 |
218 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( | 216 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( |
219 host_route_id_, picture.picture_buffer_id(), | 217 host_route_id_, picture.picture_buffer_id(), |
220 picture.bitstream_buffer_id(), picture.visible_rect(), | 218 picture.bitstream_buffer_id(), picture.visible_rect(), |
221 picture.allow_overlay()))) { | 219 picture.allow_overlay()))) { |
222 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; | 220 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; |
223 } | 221 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(profiles); | 418 return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(profiles); |
421 } | 419 } |
422 | 420 |
423 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is | 421 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is |
424 // true, otherwise on the main thread. | 422 // true, otherwise on the main thread. |
425 void GpuVideoDecodeAccelerator::OnDecode( | 423 void GpuVideoDecodeAccelerator::OnDecode( |
426 base::SharedMemoryHandle handle, int32 id, uint32 size) { | 424 base::SharedMemoryHandle handle, int32 id, uint32 size) { |
427 DCHECK(video_decode_accelerator_.get()); | 425 DCHECK(video_decode_accelerator_.get()); |
428 if (id < 0) { | 426 if (id < 0) { |
429 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range"; | 427 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range"; |
430 if (child_task_runner_->BelongsToCurrentThread()) { | 428 if (child_message_loop_->BelongsToCurrentThread()) { |
431 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 429 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
432 } else { | 430 } else { |
433 child_task_runner_->PostTask( | 431 child_message_loop_->PostTask( |
434 FROM_HERE, | 432 FROM_HERE, |
435 base::Bind(&GpuVideoDecodeAccelerator::NotifyError, | 433 base::Bind(&GpuVideoDecodeAccelerator::NotifyError, |
436 base::Unretained(this), | 434 base::Unretained(this), |
437 media::VideoDecodeAccelerator::INVALID_ARGUMENT)); | 435 media::VideoDecodeAccelerator::INVALID_ARGUMENT)); |
438 } | 436 } |
439 return; | 437 return; |
440 } | 438 } |
441 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); | 439 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); |
442 } | 440 } |
443 | 441 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 | 581 |
584 stub_->channel()->RemoveRoute(host_route_id_); | 582 stub_->channel()->RemoveRoute(host_route_id_); |
585 stub_->RemoveDestructionObserver(this); | 583 stub_->RemoveDestructionObserver(this); |
586 | 584 |
587 video_decode_accelerator_.reset(); | 585 video_decode_accelerator_.reset(); |
588 delete this; | 586 delete this; |
589 } | 587 } |
590 | 588 |
591 void GpuVideoDecodeAccelerator::SetTextureCleared( | 589 void GpuVideoDecodeAccelerator::SetTextureCleared( |
592 const media::Picture& picture) { | 590 const media::Picture& picture) { |
593 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 591 DCHECK(child_message_loop_->BelongsToCurrentThread()); |
594 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); | 592 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); |
595 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it; | 593 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it; |
596 it = uncleared_textures_.find(picture.picture_buffer_id()); | 594 it = uncleared_textures_.find(picture.picture_buffer_id()); |
597 if (it == uncleared_textures_.end()) | 595 if (it == uncleared_textures_.end()) |
598 return; // the texture has been cleared | 596 return; // the texture has been cleared |
599 | 597 |
600 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; | 598 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; |
601 GLenum target = texture_ref->texture()->target(); | 599 GLenum target = texture_ref->texture()->target(); |
602 gpu::gles2::TextureManager* texture_manager = | 600 gpu::gles2::TextureManager* texture_manager = |
603 stub_->decoder()->GetContextGroup()->texture_manager(); | 601 stub_->decoder()->GetContextGroup()->texture_manager(); |
604 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); | 602 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); |
605 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); | 603 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); |
606 uncleared_textures_.erase(it); | 604 uncleared_textures_.erase(it); |
607 } | 605 } |
608 | 606 |
609 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { | 607 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { |
610 if (filter_.get() && io_task_runner_->BelongsToCurrentThread()) | 608 if (filter_.get() && io_message_loop_->BelongsToCurrentThread()) |
611 return filter_->SendOnIOThread(message); | 609 return filter_->SendOnIOThread(message); |
612 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 610 DCHECK(child_message_loop_->BelongsToCurrentThread()); |
613 return stub_->channel()->Send(message); | 611 return stub_->channel()->Send(message); |
614 } | 612 } |
615 | 613 |
616 void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message, | 614 void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message, |
617 bool succeeded) { | 615 bool succeeded) { |
618 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded); | 616 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded); |
619 Send(message); | 617 Send(message); |
620 } | 618 } |
621 | 619 |
622 } // namespace content | 620 } // namespace content |
OLD | NEW |