| 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 |