| 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/location.h" | 10 #include "base/location.h" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 IPC::Sender* sender_; | 127 IPC::Sender* sender_; |
| 128 }; | 128 }; |
| 129 | 129 |
| 130 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( | 130 GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( |
| 131 int32_t host_route_id, | 131 int32_t host_route_id, |
| 132 GpuCommandBufferStub* stub, | 132 GpuCommandBufferStub* stub, |
| 133 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) | 133 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) |
| 134 : host_route_id_(host_route_id), | 134 : host_route_id_(host_route_id), |
| 135 stub_(stub), | 135 stub_(stub), |
| 136 texture_target_(0), | 136 texture_target_(0), |
| 137 textures_per_buffer_(0), |
| 137 filter_removed_(true, false), | 138 filter_removed_(true, false), |
| 138 child_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 139 child_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 139 io_task_runner_(io_task_runner), | 140 io_task_runner_(io_task_runner), |
| 140 weak_factory_for_io_(this) { | 141 weak_factory_for_io_(this) { |
| 141 DCHECK(stub_); | 142 DCHECK(stub_); |
| 142 stub_->AddDestructionObserver(this); | 143 stub_->AddDestructionObserver(this); |
| 143 make_context_current_ = | 144 make_context_current_ = |
| 144 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); | 145 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); |
| 145 } | 146 } |
| 146 | 147 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 } | 212 } |
| 212 | 213 |
| 213 void GpuVideoDecodeAccelerator::NotifyCdmAttached(bool success) { | 214 void GpuVideoDecodeAccelerator::NotifyCdmAttached(bool success) { |
| 214 if (!Send(new AcceleratedVideoDecoderHostMsg_CdmAttached(host_route_id_, | 215 if (!Send(new AcceleratedVideoDecoderHostMsg_CdmAttached(host_route_id_, |
| 215 success))) | 216 success))) |
| 216 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_CdmAttached) failed"; | 217 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_CdmAttached) failed"; |
| 217 } | 218 } |
| 218 | 219 |
| 219 void GpuVideoDecodeAccelerator::ProvidePictureBuffers( | 220 void GpuVideoDecodeAccelerator::ProvidePictureBuffers( |
| 220 uint32_t requested_num_of_buffers, | 221 uint32_t requested_num_of_buffers, |
| 222 uint32_t textures_per_buffer, |
| 221 const gfx::Size& dimensions, | 223 const gfx::Size& dimensions, |
| 222 uint32_t texture_target) { | 224 uint32_t texture_target) { |
| 223 if (dimensions.width() > media::limits::kMaxDimension || | 225 if (dimensions.width() > media::limits::kMaxDimension || |
| 224 dimensions.height() > media::limits::kMaxDimension || | 226 dimensions.height() > media::limits::kMaxDimension || |
| 225 dimensions.GetArea() > media::limits::kMaxCanvas) { | 227 dimensions.GetArea() > media::limits::kMaxCanvas) { |
| 226 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 228 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 227 return; | 229 return; |
| 228 } | 230 } |
| 229 if (!Send(new AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers( | 231 if (!Send(new AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers( |
| 230 host_route_id_, | 232 host_route_id_, requested_num_of_buffers, textures_per_buffer, |
| 231 requested_num_of_buffers, | 233 dimensions, texture_target))) { |
| 232 dimensions, | |
| 233 texture_target))) { | |
| 234 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers) " | 234 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers) " |
| 235 << "failed"; | 235 << "failed"; |
| 236 } | 236 } |
| 237 texture_dimensions_ = dimensions; | 237 texture_dimensions_ = dimensions; |
| 238 textures_per_buffer_ = textures_per_buffer; |
| 238 texture_target_ = texture_target; | 239 texture_target_ = texture_target; |
| 239 } | 240 } |
| 240 | 241 |
| 241 void GpuVideoDecodeAccelerator::DismissPictureBuffer( | 242 void GpuVideoDecodeAccelerator::DismissPictureBuffer( |
| 242 int32_t picture_buffer_id) { | 243 int32_t picture_buffer_id) { |
| 243 // Notify client that picture buffer is now unused. | 244 // Notify client that picture buffer is now unused. |
| 244 if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer( | 245 if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer( |
| 245 host_route_id_, picture_buffer_id))) { | 246 host_route_id_, picture_buffer_id))) { |
| 246 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) " | 247 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) " |
| 247 << "failed"; | 248 << "failed"; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is | 513 // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is |
| 513 // true, otherwise on the main thread. | 514 // true, otherwise on the main thread. |
| 514 void GpuVideoDecodeAccelerator::OnDecode( | 515 void GpuVideoDecodeAccelerator::OnDecode( |
| 515 const media::BitstreamBuffer& bitstream_buffer) { | 516 const media::BitstreamBuffer& bitstream_buffer) { |
| 516 DCHECK(video_decode_accelerator_); | 517 DCHECK(video_decode_accelerator_); |
| 517 video_decode_accelerator_->Decode(bitstream_buffer); | 518 video_decode_accelerator_->Decode(bitstream_buffer); |
| 518 } | 519 } |
| 519 | 520 |
| 520 void GpuVideoDecodeAccelerator::OnAssignPictureBuffers( | 521 void GpuVideoDecodeAccelerator::OnAssignPictureBuffers( |
| 521 const std::vector<int32_t>& buffer_ids, | 522 const std::vector<int32_t>& buffer_ids, |
| 522 const std::vector<uint32_t>& texture_ids) { | 523 const std::vector<media::PictureBuffer::TextureIds>& texture_ids) { |
| 523 if (buffer_ids.size() != texture_ids.size()) { | 524 if (buffer_ids.size() != texture_ids.size()) { |
| 524 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 525 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
| 525 return; | 526 return; |
| 526 } | 527 } |
| 527 | 528 |
| 528 gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder(); | 529 gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder(); |
| 529 gpu::gles2::TextureManager* texture_manager = | 530 gpu::gles2::TextureManager* texture_manager = |
| 530 command_decoder->GetContextGroup()->texture_manager(); | 531 command_decoder->GetContextGroup()->texture_manager(); |
| 531 | 532 |
| 532 std::vector<media::PictureBuffer> buffers; | 533 std::vector<media::PictureBuffer> buffers; |
| 533 std::vector<scoped_refptr<gpu::gles2::TextureRef> > textures; | 534 std::vector<scoped_refptr<gpu::gles2::TextureRef> > textures; |
| 534 for (uint32_t i = 0; i < buffer_ids.size(); ++i) { | 535 for (uint32_t i = 0; i < buffer_ids.size(); ++i) { |
| 535 if (buffer_ids[i] < 0) { | 536 if (buffer_ids[i] < 0) { |
| 536 DLOG(ERROR) << "Buffer id " << buffer_ids[i] << " out of range"; | 537 DLOG(ERROR) << "Buffer id " << buffer_ids[i] << " out of range"; |
| 537 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 538 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
| 538 return; | 539 return; |
| 539 } | 540 } |
| 540 gpu::gles2::TextureRef* texture_ref = texture_manager->GetTexture( | 541 media::PictureBuffer::TextureIds buffer_texture_ids = texture_ids[i]; |
| 541 texture_ids[i]); | 542 media::PictureBuffer::TextureIds service_ids; |
| 542 if (!texture_ref) { | 543 if (buffer_texture_ids.size() < textures_per_buffer_) { |
| 543 DLOG(ERROR) << "Failed to find texture id " << texture_ids[i]; | 544 DLOG(ERROR) << "Not enough textures per picture buffer"; |
| 544 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 545 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
| 545 return; | 546 return; |
| 546 } | 547 } |
| 547 gpu::gles2::Texture* info = texture_ref->texture(); | 548 for (size_t j = 0; j < textures_per_buffer_; j++) { |
| 548 if (info->target() != texture_target_) { | 549 gpu::gles2::TextureRef* texture_ref = |
| 549 DLOG(ERROR) << "Texture target mismatch for texture id " | 550 texture_manager->GetTexture(buffer_texture_ids[j]); |
| 550 << texture_ids[i]; | 551 if (!texture_ref) { |
| 551 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 552 DLOG(ERROR) << "Failed to find texture id " << buffer_texture_ids[j]; |
| 552 return; | |
| 553 } | |
| 554 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES || | |
| 555 texture_target_ == GL_TEXTURE_RECTANGLE_ARB) { | |
| 556 // These textures have their dimensions defined by the underlying storage. | |
| 557 // Use |texture_dimensions_| for this size. | |
| 558 texture_manager->SetLevelInfo( | |
| 559 texture_ref, texture_target_, 0, GL_RGBA, texture_dimensions_.width(), | |
| 560 texture_dimensions_.height(), 1, 0, GL_RGBA, 0, gfx::Rect()); | |
| 561 } else { | |
| 562 // For other targets, texture dimensions should already be defined. | |
| 563 GLsizei width = 0, height = 0; | |
| 564 info->GetLevelSize(texture_target_, 0, &width, &height, nullptr); | |
| 565 if (width != texture_dimensions_.width() || | |
| 566 height != texture_dimensions_.height()) { | |
| 567 DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i]; | |
| 568 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 553 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
| 569 return; | 554 return; |
| 570 } | 555 } |
| 556 gpu::gles2::Texture* info = texture_ref->texture(); |
| 557 if (info->target() != texture_target_) { |
| 558 DLOG(ERROR) << "Texture target mismatch for texture id " |
| 559 << buffer_texture_ids[j]; |
| 560 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
| 561 return; |
| 562 } |
| 563 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES || |
| 564 texture_target_ == GL_TEXTURE_RECTANGLE_ARB) { |
| 565 // These textures have their dimensions defined by the underlying |
| 566 // storage. |
| 567 // Use |texture_dimensions_| for this size. |
| 568 texture_manager->SetLevelInfo(texture_ref, texture_target_, 0, GL_RGBA, |
| 569 texture_dimensions_.width(), |
| 570 texture_dimensions_.height(), 1, 0, |
| 571 GL_RGBA, 0, gfx::Rect()); |
| 572 } else { |
| 573 // For other targets, texture dimensions should already be defined. |
| 574 GLsizei width = 0, height = 0; |
| 575 info->GetLevelSize(texture_target_, 0, &width, &height, nullptr); |
| 576 if (width != texture_dimensions_.width() || |
| 577 height != texture_dimensions_.height()) { |
| 578 DLOG(ERROR) << "Size mismatch for texture id " |
| 579 << buffer_texture_ids[j]; |
| 580 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
| 581 return; |
| 582 } |
| 571 | 583 |
| 572 // TODO(dshwang): after moving to D3D11, remove this. crbug.com/438691 | 584 // TODO(dshwang): after moving to D3D11, remove this. crbug.com/438691 |
| 573 GLenum format = | 585 GLenum format = |
| 574 video_decode_accelerator_.get()->GetSurfaceInternalFormat(); | 586 video_decode_accelerator_.get()->GetSurfaceInternalFormat(); |
| 575 if (format != GL_RGBA) { | 587 if (format != GL_RGBA) { |
| 576 texture_manager->SetLevelInfo(texture_ref, texture_target_, 0, format, | 588 texture_manager->SetLevelInfo(texture_ref, texture_target_, 0, format, |
| 577 width, height, 1, 0, format, 0, | 589 width, height, 1, 0, format, 0, |
| 578 gfx::Rect()); | 590 gfx::Rect()); |
| 591 } |
| 579 } | 592 } |
| 593 service_ids.push_back(texture_ref->service_id()); |
| 594 textures.push_back(texture_ref); |
| 580 } | 595 } |
| 581 buffers.push_back(media::PictureBuffer(buffer_ids[i], texture_dimensions_, | 596 buffers.push_back(media::PictureBuffer(buffer_ids[i], texture_dimensions_, |
| 582 texture_ref->service_id(), | 597 service_ids, buffer_texture_ids)); |
| 583 texture_ids[i])); | |
| 584 textures.push_back(texture_ref); | |
| 585 } | 598 } |
| 586 video_decode_accelerator_->AssignPictureBuffers(buffers); | 599 video_decode_accelerator_->AssignPictureBuffers(buffers); |
| 587 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); | 600 DebugAutoLock auto_lock(debug_uncleared_textures_lock_); |
| 588 for (uint32_t i = 0; i < buffer_ids.size(); ++i) | 601 for (uint32_t i = 0; i < buffer_ids.size(); ++i) |
| 589 uncleared_textures_[buffer_ids[i]] = textures[i]; | 602 uncleared_textures_[buffer_ids[i]] = textures[i]; |
| 590 } | 603 } |
| 591 | 604 |
| 592 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( | 605 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( |
| 593 int32_t picture_buffer_id) { | 606 int32_t picture_buffer_id) { |
| 594 DCHECK(video_decode_accelerator_); | 607 DCHECK(video_decode_accelerator_); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; | 641 scoped_refptr<gpu::gles2::TextureRef> texture_ref = it->second; |
| 629 GLenum target = texture_ref->texture()->target(); | 642 GLenum target = texture_ref->texture()->target(); |
| 630 gpu::gles2::TextureManager* texture_manager = | 643 gpu::gles2::TextureManager* texture_manager = |
| 631 stub_->decoder()->GetContextGroup()->texture_manager(); | 644 stub_->decoder()->GetContextGroup()->texture_manager(); |
| 632 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); | 645 DCHECK(!texture_ref->texture()->IsLevelCleared(target, 0)); |
| 633 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); | 646 texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); |
| 634 uncleared_textures_.erase(it); | 647 uncleared_textures_.erase(it); |
| 635 } | 648 } |
| 636 | 649 |
| 637 } // namespace content | 650 } // namespace content |
| OLD | NEW |