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