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" | |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
13 #include "base/message_loop/message_loop_proxy.h" | 14 #include "base/single_thread_task_runner.h" |
14 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
16 #include "base/thread_task_runner_handle.h" | |
15 | 17 |
16 #include "content/common/gpu/gpu_channel.h" | 18 #include "content/common/gpu/gpu_channel.h" |
17 #include "content/common/gpu/gpu_messages.h" | 19 #include "content/common/gpu/gpu_messages.h" |
18 #include "content/common/gpu/media/gpu_video_accelerator_util.h" | 20 #include "content/common/gpu/media/gpu_video_accelerator_util.h" |
19 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
20 #include "gpu/command_buffer/common/command_buffer.h" | 22 #include "gpu/command_buffer/common/command_buffer.h" |
21 #include "ipc/ipc_message_macros.h" | 23 #include "ipc/ipc_message_macros.h" |
22 #include "ipc/ipc_message_utils.h" | 24 #include "ipc/ipc_message_utils.h" |
23 #include "ipc/message_filter.h" | 25 #include "ipc/message_filter.h" |
24 #include "media/base/limits.h" | 26 #include "media/base/limits.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 private: | 122 private: |
121 GpuVideoDecodeAccelerator* const owner_; | 123 GpuVideoDecodeAccelerator* const owner_; |
122 const int32 host_route_id_; | 124 const int32 host_route_id_; |
123 // The sender to which this filter was added. | 125 // The sender to which this filter was added. |
124 IPC::Sender* sender_; | 126 IPC::Sender* sender_; |
125 }; | 127 }; |
126 | 128 |
127 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( | 129 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( |
128 int32 host_route_id, | 130 int32 host_route_id, |
129 GpuCommandBufferStub* stub, | 131 GpuCommandBufferStub* stub, |
130 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) | 132 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) |
131 : host_route_id_(host_route_id), | 133 : host_route_id_(host_route_id), |
132 stub_(stub), | 134 stub_(stub), |
133 texture_target_(0), | 135 texture_target_(0), |
134 filter_removed_(true, false), | 136 filter_removed_(true, false), |
135 child_message_loop_(base::MessageLoopProxy::current()), | 137 child_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
136 io_message_loop_(io_message_loop), | 138 io_task_runner_(io_task_runner), |
137 weak_factory_for_io_(this) { | 139 weak_factory_for_io_(this) { |
138 DCHECK(stub_); | 140 DCHECK(stub_); |
139 stub_->AddDestructionObserver(this); | 141 stub_->AddDestructionObserver(this); |
140 make_context_current_ = | 142 make_context_current_ = |
141 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); | 143 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); |
142 } | 144 } |
143 | 145 |
144 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { | 146 GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { |
145 // This class can only be self-deleted from OnWillDestroyStub(), which means | 147 // This class can only be self-deleted from OnWillDestroyStub(), which means |
146 // the VDA has already been destroyed in there. | 148 // the VDA has already been destroyed in there. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 } | 200 } |
199 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); | 201 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); |
200 uncleared_textures_.erase(picture_buffer_id); | 202 uncleared_textures_.erase(picture_buffer_id); |
201 } | 203 } |
202 | 204 |
203 void GpuVideoDecodeAccelerator::PictureReady( | 205 void GpuVideoDecodeAccelerator::PictureReady( |
204 const media::Picture& picture) { | 206 const media::Picture& picture) { |
205 // VDA may call PictureReady on IO thread. SetTextureCleared should run on | 207 // VDA may call PictureReady on IO thread. SetTextureCleared should run on |
206 // the child thread. VDA is responsible to call PictureReady on the child | 208 // the child thread. VDA is responsible to call PictureReady on the child |
207 // thread when a picture buffer is delivered the first time. | 209 // thread when a picture buffer is delivered the first time. |
208 if (child_message_loop_->BelongsToCurrentThread()) { | 210 if (child_task_runner_->BelongsToCurrentThread()) { |
209 SetTextureCleared(picture); | 211 SetTextureCleared(picture); |
210 } else { | 212 } else { |
211 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 213 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
212 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); | 214 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); |
213 DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id())); | 215 DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id())); |
214 } | 216 } |
215 | 217 |
216 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( | 218 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( |
217 host_route_id_, picture.picture_buffer_id(), | 219 host_route_id_, picture.picture_buffer_id(), |
218 picture.bitstream_buffer_id(), picture.visible_rect(), | 220 picture.bitstream_buffer_id(), picture.visible_rect(), |
219 picture.allow_overlay()))) { | 221 picture.allow_overlay()))) { |
220 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; | 222 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; |
221 } | 223 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
299 scoped_ptr<media::VideoDecodeAccelerator> decoder; | 301 scoped_ptr<media::VideoDecodeAccelerator> decoder; |
300 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) | 302 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) |
301 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 303 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
302 if (device.get()) { | 304 if (device.get()) { |
303 decoder.reset(new V4L2VideoDecodeAccelerator( | 305 decoder.reset(new V4L2VideoDecodeAccelerator( |
304 gfx::GLSurfaceEGL::GetHardwareDisplay(), | 306 gfx::GLSurfaceEGL::GetHardwareDisplay(), |
305 stub_->decoder()->GetGLContext()->GetHandle(), | 307 stub_->decoder()->GetGLContext()->GetHandle(), |
306 weak_factory_for_io_.GetWeakPtr(), | 308 weak_factory_for_io_.GetWeakPtr(), |
307 make_context_current_, | 309 make_context_current_, |
308 device, | 310 device, |
309 io_message_loop_)); | 311 io_message_loop_)); |
Evan Stade
2015/05/13 22:01:28
this also seems to break the build for USE_V4L2_CO
| |
310 } | 312 } |
311 #endif | 313 #endif |
312 return decoder.Pass(); | 314 return decoder.Pass(); |
313 } | 315 } |
314 | 316 |
315 scoped_ptr<media::VideoDecodeAccelerator> | 317 scoped_ptr<media::VideoDecodeAccelerator> |
316 GpuVideoDecodeAccelerator::CreateV4L2SliceVDA() { | 318 GpuVideoDecodeAccelerator::CreateV4L2SliceVDA() { |
317 scoped_ptr<media::VideoDecodeAccelerator> decoder; | 319 scoped_ptr<media::VideoDecodeAccelerator> decoder; |
318 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) | 320 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) |
319 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 321 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(profiles); | 420 return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(profiles); |
419 } | 421 } |
420 | 422 |
421 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is | 423 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is |
422 // true, otherwise on the main thread. | 424 // true, otherwise on the main thread. |
423 void GpuVideoDecodeAccelerator::OnDecode( | 425 void GpuVideoDecodeAccelerator::OnDecode( |
424 base::SharedMemoryHandle handle, int32 id, uint32 size) { | 426 base::SharedMemoryHandle handle, int32 id, uint32 size) { |
425 DCHECK(video_decode_accelerator_.get()); | 427 DCHECK(video_decode_accelerator_.get()); |
426 if (id < 0) { | 428 if (id < 0) { |
427 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range"; | 429 DLOG(ERROR) << "BitstreamBuffer id " << id << " out of range"; |
428 if (child_message_loop_->BelongsToCurrentThread()) { | 430 if (child_task_runner_->BelongsToCurrentThread()) { |
429 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 431 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
430 } else { | 432 } else { |
431 child_message_loop_->PostTask( | 433 child_task_runner_->PostTask( |
432 FROM_HERE, | 434 FROM_HERE, |
433 base::Bind(&GpuVideoDecodeAccelerator::NotifyError, | 435 base::Bind(&GpuVideoDecodeAccelerator::NotifyError, |
434 base::Unretained(this), | 436 base::Unretained(this), |
435 media::VideoDecodeAccelerator::INVALID_ARGUMENT)); | 437 media::VideoDecodeAccelerator::INVALID_ARGUMENT)); |
436 } | 438 } |
437 return; | 439 return; |
438 } | 440 } |
439 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); | 441 video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size)); |
440 } | 442 } |
441 | 443 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 | 583 |
582 stub_->channel()->RemoveRoute(host_route_id_); | 584 stub_->channel()->RemoveRoute(host_route_id_); |
583 stub_->RemoveDestructionObserver(this); | 585 stub_->RemoveDestructionObserver(this); |
584 | 586 |
585 video_decode_accelerator_.reset(); | 587 video_decode_accelerator_.reset(); |
586 delete this; | 588 delete this; |
587 } | 589 } |
588 | 590 |
589 void GpuVideoDecodeAccelerator::SetTextureCleared( | 591 void GpuVideoDecodeAccelerator::SetTextureCleared( |
590 const media::Picture& picture) { | 592 const media::Picture& picture) { |
591 DCHECK(child_message_loop_->BelongsToCurrentThread()); | 593 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
592 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); | 594 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); |
593 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it; | 595 std::map<int32, scoped_refptr<gpu::gles2::TextureRef> >::iterator it; |
594 it = uncleared_textures_.find(picture.picture_buffer_id()); | 596 it = uncleared_textures_.find(picture.picture_buffer_id()); |
595 if (it == uncleared_textures_.end()) | 597 if (it == uncleared_textures_.end()) |
596 return; // the texture has been cleared | 598 return; // the texture has been cleared |
597 | 599 |
598 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; | 600 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; |
599 GLenum target = texture_ref->texture()->target(); | 601 GLenum target = texture_ref->texture()->target(); |
600 gpu::gles2::TextureManager* texture_manager = | 602 gpu::gles2::TextureManager* texture_manager = |
601 stub_->decoder()->GetContextGroup()->texture_manager(); | 603 stub_->decoder()->GetContextGroup()->texture_manager(); |
602 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); | 604 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); |
603 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); | 605 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); |
604 uncleared_textures_.erase(it); | 606 uncleared_textures_.erase(it); |
605 } | 607 } |
606 | 608 |
607 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { | 609 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { |
608 if (filter_.get() && io_message_loop_->BelongsToCurrentThread()) | 610 if (filter_.get() && io_task_runner_->BelongsToCurrentThread()) |
609 return filter_->SendOnIOThread(message); | 611 return filter_->SendOnIOThread(message); |
610 DCHECK(child_message_loop_->BelongsToCurrentThread()); | 612 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
611 return stub_->channel()->Send(message); | 613 return stub_->channel()->Send(message); |
612 } | 614 } |
613 | 615 |
614 void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message, | 616 void GpuVideoDecodeAccelerator::SendCreateDecoderReply(IPC::Message* message, |
615 bool succeeded) { | 617 bool succeeded) { |
616 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded); | 618 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(message, succeeded); |
617 Send(message); | 619 Send(message); |
618 } | 620 } |
619 | 621 |
620 } // namespace content | 622 } // namespace content |
OLD | NEW |