| 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 "media/filters/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/cpu.h" | 9 #include "base/cpu.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 void GpuVideoDecoder::NotifyInitializeDone() { | 473 void GpuVideoDecoder::NotifyInitializeDone() { |
| 474 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; | 474 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; |
| 475 } | 475 } |
| 476 | 476 |
| 477 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, | 477 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, |
| 478 const gfx::Size& size, | 478 const gfx::Size& size, |
| 479 uint32 texture_target) { | 479 uint32 texture_target) { |
| 480 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 480 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 481 | 481 |
| 482 std::vector<uint32> texture_ids; | 482 std::vector<uint32> texture_ids; |
| 483 std::vector<gpu::Mailbox> texture_mailboxes; |
| 483 decoder_texture_target_ = texture_target; | 484 decoder_texture_target_ = texture_target; |
| 484 if (!factories_->CreateTextures( | 485 if (!factories_->CreateTextures(count, |
| 485 count, size, &texture_ids, decoder_texture_target_)) { | 486 size, |
| 487 &texture_ids, |
| 488 &texture_mailboxes, |
| 489 decoder_texture_target_)) { |
| 486 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 490 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 487 return; | 491 return; |
| 488 } | 492 } |
| 489 | 493 |
| 490 if (!vda_.get()) | 494 if (!vda_.get()) |
| 491 return; | 495 return; |
| 492 | 496 |
| 493 CHECK_EQ(available_pictures_, -1); | 497 CHECK_EQ(available_pictures_, -1); |
| 494 available_pictures_ = count; | 498 available_pictures_ = count; |
| 495 | 499 |
| 496 std::vector<PictureBuffer> picture_buffers; | 500 std::vector<PictureBuffer> picture_buffers; |
| 497 for (size_t i = 0; i < texture_ids.size(); ++i) { | 501 for (size_t i = 0; i < texture_ids.size(); ++i) { |
| 498 picture_buffers.push_back(PictureBuffer( | 502 picture_buffers.push_back(PictureBuffer( |
| 499 next_picture_buffer_id_++, size, texture_ids[i])); | 503 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); |
| 500 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair( | 504 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair( |
| 501 picture_buffers.back().id(), picture_buffers.back())).second; | 505 picture_buffers.back().id(), picture_buffers.back())).second; |
| 502 DCHECK(inserted); | 506 DCHECK(inserted); |
| 503 } | 507 } |
| 504 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 508 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 505 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, | 509 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, |
| 506 picture_buffers)); | 510 picture_buffers)); |
| 507 } | 511 } |
| 508 | 512 |
| 509 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { | 513 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 531 } | 535 } |
| 532 const PictureBuffer& pb = it->second; | 536 const PictureBuffer& pb = it->second; |
| 533 | 537 |
| 534 // Update frame's timestamp. | 538 // Update frame's timestamp. |
| 535 base::TimeDelta timestamp; | 539 base::TimeDelta timestamp; |
| 536 gfx::Rect visible_rect; | 540 gfx::Rect visible_rect; |
| 537 gfx::Size natural_size; | 541 gfx::Size natural_size; |
| 538 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, | 542 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, |
| 539 &natural_size); | 543 &natural_size); |
| 540 DCHECK(decoder_texture_target_); | 544 DCHECK(decoder_texture_target_); |
| 545 |
| 546 uint32 sync_point = factories_->ProduceTextureToMailbox( |
| 547 pb.texture_mailbox(), |
| 548 pb.texture_id(), |
| 549 decoder_texture_target_); |
| 550 |
| 541 scoped_refptr<VideoFrame> frame( | 551 scoped_refptr<VideoFrame> frame( |
| 542 VideoFrame::WrapNativeTexture( | 552 VideoFrame::WrapNativeTexture( |
| 543 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, | 553 pb.texture_mailbox(), sync_point, |
| 554 decoder_texture_target_, |
| 555 pb.size(), visible_rect, |
| 544 natural_size, timestamp, | 556 natural_size, timestamp, |
| 545 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), | 557 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), |
| 546 decoder_texture_target_, | 558 decoder_texture_target_, |
| 547 gfx::Size(visible_rect.width(), visible_rect.height())), | 559 gfx::Size(visible_rect.width(), visible_rect.height())), |
| 548 BindToCurrentLoop(base::Bind( | 560 BindToCurrentLoop(base::Bind( |
| 549 &GpuVideoDecoder::ReusePictureBuffer, weak_this_, | 561 &GpuVideoDecoder::ReusePictureBuffer, weak_this_, |
| 550 picture.picture_buffer_id())))); | 562 picture.picture_buffer_id())), |
| 563 base::Closure())); |
| 551 CHECK_GT(available_pictures_, 0); | 564 CHECK_GT(available_pictures_, 0); |
| 552 available_pictures_--; | 565 available_pictures_--; |
| 553 | 566 |
| 554 EnqueueFrameAndTriggerFrameDelivery(frame); | 567 EnqueueFrameAndTriggerFrameDelivery(frame); |
| 555 } | 568 } |
| 556 | 569 |
| 557 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 570 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( |
| 558 const scoped_refptr<VideoFrame>& frame) { | 571 const scoped_refptr<VideoFrame>& frame) { |
| 559 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 572 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 560 | 573 |
| 561 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the | 574 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the |
| 562 // floor and return. | 575 // floor and return. |
| 563 if (!pending_reset_cb_.is_null()) | 576 if (!pending_reset_cb_.is_null()) |
| 564 return; | 577 return; |
| 565 | 578 |
| 566 if (frame) | 579 if (frame) |
| 567 ready_video_frames_.push_back(frame); | 580 ready_video_frames_.push_back(frame); |
| 568 else | 581 else |
| 569 DCHECK(!ready_video_frames_.empty()); | 582 DCHECK(!ready_video_frames_.empty()); |
| 570 | 583 |
| 571 if (pending_read_cb_.is_null()) | 584 if (pending_read_cb_.is_null()) |
| 572 return; | 585 return; |
| 573 | 586 |
| 574 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); | 587 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); |
| 575 ready_video_frames_.pop_front(); | 588 ready_video_frames_.pop_front(); |
| 576 } | 589 } |
| 577 | 590 |
| 578 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { | 591 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id, |
| 592 uint32 sync_point) { |
| 579 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 593 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 580 CHECK_GE(available_pictures_, 0); | 594 CHECK_GE(available_pictures_, 0); |
| 581 available_pictures_++; | 595 available_pictures_++; |
| 582 | 596 |
| 583 if (!vda_.get()) | 597 if (!vda_.get()) |
| 584 return; | 598 return; |
| 599 |
| 600 std::map<int32, PictureBuffer>::iterator it = |
| 601 picture_buffers_in_decoder_.find(picture_buffer_id); |
| 602 if (it == picture_buffers_in_decoder_.end()) { |
| 603 NOTREACHED() << "Missing picture buffer: " << picture_buffer_id; |
| 604 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 605 return; |
| 606 } |
| 607 const PictureBuffer& pb = it->second; |
| 608 factories_->ConsumeMailboxToTexture(pb.texture_mailbox(), |
| 609 pb.texture_id(), |
| 610 decoder_texture_target_, |
| 611 sync_point); |
| 612 |
| 585 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 613 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 586 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, | 614 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, |
| 587 picture_buffer_id)); | 615 picture_buffer_id)); |
| 588 } | 616 } |
| 589 | 617 |
| 590 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { | 618 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { |
| 591 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 619 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 592 if (available_shm_segments_.empty() || | 620 if (available_shm_segments_.empty() || |
| 593 available_shm_segments_.back()->size < min_size) { | 621 available_shm_segments_.back()->size < min_size) { |
| 594 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); | 622 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 | 727 |
| 700 error_occured_ = true; | 728 error_occured_ = true; |
| 701 | 729 |
| 702 if (!pending_read_cb_.is_null()) { | 730 if (!pending_read_cb_.is_null()) { |
| 703 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 731 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 704 return; | 732 return; |
| 705 } | 733 } |
| 706 } | 734 } |
| 707 | 735 |
| 708 } // namespace media | 736 } // namespace media |
| OLD | NEW |