Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 14199002: Send hardware video frames with mailboxes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: video-mailbox: virtualandroid Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/media.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 // Discards the sync point returned here since PictureReady will imply that
500 count, size, &texture_ids, decoder_texture_target_)) { 501 // the produce has already happened, and the texture is ready for use.
502 if (!factories_->CreateTextures(count,
503 size,
504 &texture_ids,
505 &texture_mailboxes,
506 decoder_texture_target_)) {
501 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 507 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
502 return; 508 return;
503 } 509 }
504 DCHECK_EQ(count, texture_ids.size()); 510 DCHECK_EQ(count, texture_ids.size());
511 DCHECK_EQ(count, texture_mailboxes.size());
505 512
506 if (!vda_) 513 if (!vda_)
507 return; 514 return;
508 515
509 std::vector<PictureBuffer> picture_buffers; 516 std::vector<PictureBuffer> picture_buffers;
510 for (size_t i = 0; i < texture_ids.size(); ++i) { 517 for (size_t i = 0; i < texture_ids.size(); ++i) {
511 picture_buffers.push_back(PictureBuffer( 518 picture_buffers.push_back(PictureBuffer(
512 next_picture_buffer_id_++, size, texture_ids[i])); 519 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i]));
513 bool inserted = assigned_picture_buffers_.insert(std::make_pair( 520 bool inserted = assigned_picture_buffers_.insert(std::make_pair(
514 picture_buffers.back().id(), picture_buffers.back())).second; 521 picture_buffers.back().id(), picture_buffers.back())).second;
515 DCHECK(inserted); 522 DCHECK(inserted);
516 } 523 }
517 524
518 available_pictures_ += count; 525 available_pictures_ += count;
519 526
520 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 527 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
521 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, 528 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_,
522 picture_buffers)); 529 picture_buffers));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 } 570 }
564 const PictureBuffer& pb = it->second; 571 const PictureBuffer& pb = it->second;
565 572
566 // Update frame's timestamp. 573 // Update frame's timestamp.
567 base::TimeDelta timestamp; 574 base::TimeDelta timestamp;
568 gfx::Rect visible_rect; 575 gfx::Rect visible_rect;
569 gfx::Size natural_size; 576 gfx::Size natural_size;
570 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect, 577 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect,
571 &natural_size); 578 &natural_size);
572 DCHECK(decoder_texture_target_); 579 DCHECK(decoder_texture_target_);
580
573 scoped_refptr<VideoFrame> frame( 581 scoped_refptr<VideoFrame> frame(
574 VideoFrame::WrapNativeTexture( 582 VideoFrame::WrapNativeTexture(
575 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, 583 new VideoFrame::MailboxHolder(
584 pb.texture_mailbox(),
585 0, // sync_point
586 BindToCurrentLoop(base::Bind(
587 &GpuVideoDecoder::ReusePictureBuffer, weak_this_,
588 picture.picture_buffer_id()))),
589 decoder_texture_target_,
590 pb.size(), visible_rect,
576 natural_size, timestamp, 591 natural_size, timestamp,
577 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), 592 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(),
578 decoder_texture_target_, 593 decoder_texture_target_,
579 gfx::Size(visible_rect.width(), visible_rect.height())), 594 gfx::Size(visible_rect.width(), visible_rect.height())),
580 BindToCurrentLoop(base::Bind( 595 base::Closure()));
581 &GpuVideoDecoder::ReusePictureBuffer, weak_this_,
582 picture.picture_buffer_id()))));
583 CHECK_GT(available_pictures_, 0); 596 CHECK_GT(available_pictures_, 0);
584 --available_pictures_; 597 --available_pictures_;
585 bool inserted = 598 bool inserted =
586 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second; 599 picture_buffers_at_display_.insert(picture.picture_buffer_id()).second;
587 DCHECK(inserted); 600 DCHECK(inserted);
588 601
589 EnqueueFrameAndTriggerFrameDelivery(frame); 602 EnqueueFrameAndTriggerFrameDelivery(frame);
590 } 603 }
591 604
592 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 605 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery(
(...skipping 10 matching lines...) Expand all
603 else 616 else
604 DCHECK(!ready_video_frames_.empty()); 617 DCHECK(!ready_video_frames_.empty());
605 618
606 if (pending_read_cb_.is_null()) 619 if (pending_read_cb_.is_null())
607 return; 620 return;
608 621
609 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); 622 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front());
610 ready_video_frames_.pop_front(); 623 ready_video_frames_.pop_front();
611 } 624 }
612 625
613 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { 626 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id,
627 uint32 sync_point) {
614 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 628 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
615 629
616 if (!vda_) 630 if (!vda_)
617 return; 631 return;
618 632
619 CHECK(!picture_buffers_at_display_.empty()); 633 CHECK(!picture_buffers_at_display_.empty());
620 634
621 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); 635 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id);
622 DCHECK(num_erased); 636 DCHECK(num_erased);
623 637
624 std::map<int32, PictureBuffer>::iterator it = 638 std::map<int32, PictureBuffer>::iterator it =
625 assigned_picture_buffers_.find(picture_buffer_id); 639 assigned_picture_buffers_.find(picture_buffer_id);
626 640
627 if (it == assigned_picture_buffers_.end()) { 641 if (it == assigned_picture_buffers_.end()) {
628 // This picture was dismissed while in display, so we postponed deletion. 642 // This picture was dismissed while in display, so we postponed deletion.
629 it = dismissed_picture_buffers_.find(picture_buffer_id); 643 it = dismissed_picture_buffers_.find(picture_buffer_id);
630 DCHECK(it != dismissed_picture_buffers_.end()); 644 DCHECK(it != dismissed_picture_buffers_.end());
631 factories_->DeleteTexture(it->second.texture_id()); 645 factories_->DeleteTexture(it->second.texture_id());
632 dismissed_picture_buffers_.erase(it); 646 dismissed_picture_buffers_.erase(it);
633 return; 647 return;
634 } 648 }
635 649
650 factories_->WaitSyncPoint(sync_point);
651
636 ++available_pictures_; 652 ++available_pictures_;
637 653
638 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 654 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
639 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, 655 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_,
640 picture_buffer_id)); 656 picture_buffer_id));
641 } 657 }
642 658
643 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 659 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) {
644 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 660 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
645 if (available_shm_segments_.empty() || 661 if (available_shm_segments_.empty() ||
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 768
753 state_ = kError; 769 state_ = kError;
754 770
755 if (!pending_read_cb_.is_null()) { 771 if (!pending_read_cb_.is_null()) {
756 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 772 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
757 return; 773 return;
758 } 774 }
759 } 775 }
760 776
761 } // namespace media 777 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698