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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 void GpuVideoDecoder::NotifyInitializeDone() { | 488 void GpuVideoDecoder::NotifyInitializeDone() { |
489 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; | 489 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; |
490 } | 490 } |
491 | 491 |
492 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, | 492 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, |
493 const gfx::Size& size, | 493 const gfx::Size& size, |
494 uint32 texture_target) { | 494 uint32 texture_target) { |
495 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 495 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
496 | 496 |
497 std::vector<uint32> texture_ids; | 497 std::vector<uint32> texture_ids; |
498 std::vector<gpu::Mailbox> texture_mailboxes; | |
498 decoder_texture_target_ = texture_target; | 499 decoder_texture_target_ = texture_target; |
499 if (!factories_->CreateTextures( | 500 if (!factories_->CreateTextures(count, |
500 count, size, &texture_ids, decoder_texture_target_)) { | 501 size, |
502 &texture_ids, | |
503 &texture_mailboxes, | |
504 decoder_texture_target_)) { | |
501 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 505 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
502 return; | 506 return; |
503 } | 507 } |
504 DCHECK_EQ(count, texture_ids.size()); | 508 DCHECK_EQ(count, texture_ids.size()); |
509 DCHECK_EQ(count, texture_mailboxes.size()); | |
510 | |
511 for (size_t i = 0; i < count; ++i) { | |
512 // Discards the sync point returned here since PictureReady will imply that | |
513 // the produce has already happened, and the texture is ready for use. | |
514 factories_->ProduceTexturesToMailboxes( | |
piman
2013/06/14 22:55:28
Why not do that directly inside of CreateTextures?
danakj
2013/06/15 00:12:58
It seemed more flexible for the future and stuff t
piman
2013/06/15 00:42:19
My thinking is that, we already know we're associa
| |
515 texture_mailboxes, | |
516 texture_ids, | |
517 decoder_texture_target_); | |
518 } | |
505 | 519 |
506 if (!vda_) | 520 if (!vda_) |
507 return; | 521 return; |
508 | 522 |
509 std::vector<PictureBuffer> picture_buffers; | 523 std::vector<PictureBuffer> picture_buffers; |
510 for (size_t i = 0; i < texture_ids.size(); ++i) { | 524 for (size_t i = 0; i < texture_ids.size(); ++i) { |
511 picture_buffers.push_back(PictureBuffer( | 525 picture_buffers.push_back(PictureBuffer( |
512 next_picture_buffer_id_++, size, texture_ids[i])); | 526 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); |
513 bool inserted = assigned_picture_buffers_.insert(std::make_pair( | 527 bool inserted = assigned_picture_buffers_.insert(std::make_pair( |
514 picture_buffers.back().id(), picture_buffers.back())).second; | 528 picture_buffers.back().id(), picture_buffers.back())).second; |
515 DCHECK(inserted); | 529 DCHECK(inserted); |
516 } | 530 } |
517 | 531 |
518 available_pictures_ += count; | 532 available_pictures_ += count; |
519 | 533 |
520 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 534 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
521 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, | 535 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, |
522 picture_buffers)); | 536 picture_buffers)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 } | 577 } |
564 const PictureBuffer& pb = it->second; | 578 const PictureBuffer& pb = it->second; |
565 | 579 |
566 // Update frame's timestamp. | 580 // Update frame's timestamp. |
567 base::TimeDelta timestamp; | 581 base::TimeDelta timestamp; |
568 gfx::Rect visible_rect; | 582 gfx::Rect visible_rect; |
569 gfx::Size natural_size; | 583 gfx::Size natural_size; |
570 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, | 584 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, |
571 &natural_size); | 585 &natural_size); |
572 DCHECK(decoder_texture_target_); | 586 DCHECK(decoder_texture_target_); |
587 | |
573 scoped_refptr<VideoFrame> frame( | 588 scoped_refptr<VideoFrame> frame( |
574 VideoFrame::WrapNativeTexture( | 589 VideoFrame::WrapNativeTexture( |
575 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, | 590 pb.texture_mailbox(), 0, |
591 decoder_texture_target_, | |
592 pb.size(), visible_rect, | |
576 natural_size, timestamp, | 593 natural_size, timestamp, |
577 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), | 594 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), |
578 decoder_texture_target_, | 595 decoder_texture_target_, |
579 gfx::Size(visible_rect.width(), visible_rect.height())), | 596 gfx::Size(visible_rect.width(), visible_rect.height())), |
580 BindToCurrentLoop(base::Bind( | 597 BindToCurrentLoop(base::Bind( |
581 &GpuVideoDecoder::ReusePictureBuffer, weak_this_, | 598 &GpuVideoDecoder::ReusePictureBuffer, weak_this_, |
582 picture.picture_buffer_id())))); | 599 picture.picture_buffer_id())), |
600 base::Closure())); | |
583 CHECK_GT(available_pictures_, 0); | 601 CHECK_GT(available_pictures_, 0); |
584 --available_pictures_; | 602 --available_pictures_; |
585 bool inserted = | 603 bool inserted = |
586 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; | 604 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; |
587 DCHECK(inserted); | 605 DCHECK(inserted); |
588 | 606 |
589 EnqueueFrameAndTriggerFrameDelivery(frame); | 607 EnqueueFrameAndTriggerFrameDelivery(frame); |
590 } | 608 } |
591 | 609 |
592 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 610 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( |
(...skipping 10 matching lines...) Expand all Loading... | |
603 else | 621 else |
604 DCHECK(!ready_video_frames_.empty()); | 622 DCHECK(!ready_video_frames_.empty()); |
605 | 623 |
606 if (pending_read_cb_.is_null()) | 624 if (pending_read_cb_.is_null()) |
607 return; | 625 return; |
608 | 626 |
609 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); | 627 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); |
610 ready_video_frames_.pop_front(); | 628 ready_video_frames_.pop_front(); |
611 } | 629 } |
612 | 630 |
613 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { | 631 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id, |
632 uint32 sync_point) { | |
614 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 633 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
615 | 634 |
616 if (!vda_) | 635 if (!vda_) |
617 return; | 636 return; |
618 | 637 |
619 CHECK(!picture_buffers_at_display_.empty()); | 638 CHECK(!picture_buffers_at_display_.empty()); |
620 | 639 |
621 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); | 640 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); |
622 DCHECK(num_erased); | 641 DCHECK(num_erased); |
623 | 642 |
624 std::map<int32, PictureBuffer>::iterator it = | 643 std::map<int32, PictureBuffer>::iterator it = |
625 assigned_picture_buffers_.find(picture_buffer_id); | 644 assigned_picture_buffers_.find(picture_buffer_id); |
626 | 645 |
627 if (it == assigned_picture_buffers_.end()) { | 646 if (it == assigned_picture_buffers_.end()) { |
628 // This picture was dismissed while in display, so we postponed deletion. | 647 // This picture was dismissed while in display, so we postponed deletion. |
629 it = dismissed_picture_buffers_.find(picture_buffer_id); | 648 it = dismissed_picture_buffers_.find(picture_buffer_id); |
630 DCHECK(it != dismissed_picture_buffers_.end()); | 649 DCHECK(it != dismissed_picture_buffers_.end()); |
631 factories_->DeleteTexture(it->second.texture_id()); | 650 factories_->DeleteTexture(it->second.texture_id()); |
632 dismissed_picture_buffers_.erase(it); | 651 dismissed_picture_buffers_.erase(it); |
633 return; | 652 return; |
634 } | 653 } |
635 | 654 |
655 factories_->WaitSyncPoint(sync_point); | |
656 | |
636 ++available_pictures_; | 657 ++available_pictures_; |
637 | 658 |
659 | |
638 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 660 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
639 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, | 661 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, |
640 picture_buffer_id)); | 662 picture_buffer_id)); |
641 } | 663 } |
642 | 664 |
643 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { | 665 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { |
644 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 666 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
645 if (available_shm_segments_.empty() || | 667 if (available_shm_segments_.empty() || |
646 available_shm_segments_.back()->size < min_size) { | 668 available_shm_segments_.back()->size < min_size) { |
647 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); | 669 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
752 | 774 |
753 state_ = kError; | 775 state_ = kError; |
754 | 776 |
755 if (!pending_read_cb_.is_null()) { | 777 if (!pending_read_cb_.is_null()) { |
756 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 778 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
757 return; | 779 return; |
758 } | 780 } |
759 } | 781 } |
760 | 782 |
761 } // namespace media | 783 } // namespace media |
OLD | NEW |